aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.env.swpbin0 -> 12351 bytes
-rw-r--r--.eslintrc.json74
-rw-r--r--.gitignore1
-rw-r--r--.vscode/launch.json5
-rw-r--r--deploy/assets/pdf.worker.2.4.456.min.js22
-rw-r--r--deploy/assets/pdf.worker.js22
-rw-r--r--deploy/loader.js10
-rw-r--r--eslint.config.mjs6
-rw-r--r--package-lock.json6788
-rw-r--r--package.json64
-rw-r--r--report.20231129.000028.55430.0.001.json1343
-rw-r--r--src/.DS_Storebin10244 -> 10244 bytes
-rw-r--r--src/ClientUtils.ts721
-rw-r--r--src/ServerUtils.ts27
-rw-r--r--src/Utils.ts897
-rw-r--r--src/client/DocServer.ts280
-rw-r--r--src/client/Network.ts11
-rw-r--r--src/client/apis/GoogleAuthenticationManager.tsx119
-rw-r--r--src/client/apis/google_docs/GoogleApiClientUtils.ts164
-rw-r--r--src/client/apis/google_docs/GooglePhotosClientUtils.ts93
-rw-r--r--src/client/apis/gpt/GPT.ts88
-rw-r--r--src/client/apis/gpt/customization.ts133
-rw-r--r--src/client/apis/gpt/setup.ts30
-rw-r--r--src/client/apis/youtube/YoutubeBox.scss126
-rw-r--r--src/client/apis/youtube/YoutubeBox.tsx369
-rw-r--r--src/client/cognitive_services/CognitiveServices.ts70
-rw-r--r--src/client/documents/DocFromField.ts31
-rw-r--r--src/client/documents/DocUtils.ts875
-rw-r--r--src/client/documents/DocumentTypes.ts10
-rw-r--r--src/client/documents/Documents.ts1289
-rw-r--r--src/client/goldenLayout.d.ts3
-rw-r--r--src/client/util/BranchingTrailManager.tsx46
-rw-r--r--src/client/util/CalendarManager.tsx58
-rw-r--r--src/client/util/CaptureManager.tsx31
-rw-r--r--src/client/util/CurrentUserUtils.ts471
-rw-r--r--src/client/util/DictationManager.ts123
-rw-r--r--src/client/util/DocumentManager.ts240
-rw-r--r--src/client/util/DragManager.ts207
-rw-r--r--src/client/util/DropActionTypes.ts9
-rw-r--r--src/client/util/DropConverter.ts90
-rw-r--r--src/client/util/GroupManager.tsx113
-rw-r--r--src/client/util/GroupMemberView.tsx36
-rw-r--r--src/client/util/History.ts38
-rw-r--r--src/client/util/HypothesisUtils.ts37
-rw-r--r--src/client/util/Import & Export/DirectoryImportBox.tsx1
-rw-r--r--src/client/util/Import & Export/ImageUtils.ts12
-rw-r--r--src/client/util/Import & Export/ImportMetadataEntry.tsx40
-rw-r--r--src/client/util/InteractionUtils.tsx317
-rw-r--r--src/client/util/KeyCodes.ts2
-rw-r--r--src/client/util/LinkFollower.ts70
-rw-r--r--src/client/util/LinkManager.ts128
-rw-r--r--src/client/util/PingManager.ts8
-rw-r--r--src/client/util/RTFMarkup.tsx55
-rw-r--r--src/client/util/ReplayMovements.ts79
-rw-r--r--src/client/util/ScriptManager.ts10
-rw-r--r--src/client/util/Scripting.ts74
-rw-r--r--src/client/util/ScriptingGlobals.ts48
-rw-r--r--src/client/util/SearchUtil.ts26
-rw-r--r--src/client/util/SelectionManager.ts45
-rw-r--r--src/client/util/SerializationHelper.ts33
-rw-r--r--src/client/util/ServerStats.tsx47
-rw-r--r--src/client/util/SettingsManager.tsx419
-rw-r--r--src/client/util/SharingManager.tsx751
-rw-r--r--src/client/util/SnappingManager.ts55
-rw-r--r--src/client/util/TrackMovements.ts24
-rw-r--r--src/client/util/Transform.ts14
-rw-r--r--src/client/util/TypedEvent.ts18
-rw-r--r--src/client/util/UndoManager.ts106
-rw-r--r--src/client/util/bezierFit.ts401
-rw-r--r--src/client/util/reportManager/ReportManager.tsx67
-rw-r--r--src/client/util/reportManager/ReportManagerComponents.tsx131
-rw-r--r--src/client/util/reportManager/reportManagerSchema.ts1
-rw-r--r--src/client/util/reportManager/reportManagerUtils.ts17
-rw-r--r--src/client/util/request-image-size.ts26
-rw-r--r--src/client/views/AntimodeMenu.tsx26
-rw-r--r--src/client/views/ComponentDecorations.tsx7
-rw-r--r--src/client/views/ContextMenu.tsx53
-rw-r--r--src/client/views/ContextMenuItem.tsx44
-rw-r--r--src/client/views/DashboardView.tsx151
-rw-r--r--src/client/views/DictationOverlay.tsx55
-rw-r--r--src/client/views/DocComponent.tsx183
-rw-r--r--src/client/views/DocViewUtils.ts21
-rw-r--r--src/client/views/DocumentButtonBar.tsx161
-rw-r--r--src/client/views/DocumentDecorations.scss2
-rw-r--r--src/client/views/DocumentDecorations.tsx317
-rw-r--r--src/client/views/EditableView.tsx25
-rw-r--r--src/client/views/ExtractColors.ts168
-rw-r--r--src/client/views/FieldsDropdown.tsx39
-rw-r--r--src/client/views/FilterPanel.tsx173
-rw-r--r--src/client/views/GestureOverlay.tsx282
-rw-r--r--src/client/views/GlobalKeyHandler.ts211
-rw-r--r--src/client/views/InkControlPtHandles.tsx124
-rw-r--r--src/client/views/InkStrokeProperties.ts85
-rw-r--r--src/client/views/InkTangentHandles.tsx16
-rw-r--r--src/client/views/InkTranscription.tsx1
-rw-r--r--src/client/views/InkingStroke.tsx160
-rw-r--r--src/client/views/KeyphraseQueryView.tsx26
-rw-r--r--src/client/views/LightboxView.scss1
-rw-r--r--src/client/views/LightboxView.tsx184
-rw-r--r--src/client/views/Main.tsx118
-rw-r--r--src/client/views/MainView.scss6
-rw-r--r--src/client/views/MainView.tsx277
-rw-r--r--src/client/views/MainViewModal.tsx9
-rw-r--r--src/client/views/MarqueeAnnotator.tsx106
-rw-r--r--src/client/views/MetadataEntryMenu.tsx197
-rw-r--r--src/client/views/ObservableReactComponent.tsx19
-rw-r--r--src/client/views/OverlayView.tsx58
-rw-r--r--src/client/views/PinFuncs.ts139
-rw-r--r--src/client/views/PreviewCursor.tsx33
-rw-r--r--src/client/views/PropertiesButtons.tsx214
-rw-r--r--src/client/views/PropertiesDocBacklinksSelector.tsx12
-rw-r--r--src/client/views/PropertiesDocContextSelector.tsx17
-rw-r--r--src/client/views/PropertiesSection.tsx60
-rw-r--r--src/client/views/PropertiesView.scss20
-rw-r--r--src/client/views/PropertiesView.tsx1195
-rw-r--r--src/client/views/ScriptBox.tsx47
-rw-r--r--src/client/views/ScriptingRepl.tsx199
-rw-r--r--src/client/views/SidebarAnnos.tsx41
-rw-r--r--src/client/views/StyleProp.ts24
-rw-r--r--src/client/views/StyleProvider.scss1
-rw-r--r--src/client/views/StyleProvider.tsx309
-rw-r--r--src/client/views/TemplateMenu.scss1
-rw-r--r--src/client/views/TemplateMenu.tsx84
-rw-r--r--src/client/views/Touchable.tsx213
-rw-r--r--src/client/views/UndoStack.tsx19
-rw-r--r--src/client/views/ViewBoxInterface.ts60
-rw-r--r--src/client/views/animationtimeline/Timeline.tsx65
-rw-r--r--src/client/views/animationtimeline/TimelineMenu.tsx3
-rw-r--r--src/client/views/animationtimeline/TimelineOverview.tsx16
-rw-r--r--src/client/views/animationtimeline/Track.tsx2
-rw-r--r--src/client/views/collections/CollectionCalendarView.tsx34
-rw-r--r--src/client/views/collections/CollectionCardDeckView.scss84
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx513
-rw-r--r--src/client/views/collections/CollectionCarousel3DView.tsx113
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx23
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx254
-rw-r--r--src/client/views/collections/CollectionMasonryViewFieldRow.tsx107
-rw-r--r--src/client/views/collections/CollectionMenu.scss2
-rw-r--r--src/client/views/collections/CollectionMenu.tsx186
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.scss47
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx212
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewColumn.tsx132
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewDivider.tsx17
-rw-r--r--src/client/views/collections/CollectionPileView.tsx40
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx200
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx105
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx111
-rw-r--r--src/client/views/collections/CollectionSubView.tsx232
-rw-r--r--src/client/views/collections/CollectionTimeView.tsx46
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx147
-rw-r--r--src/client/views/collections/CollectionTreeViewType.ts5
-rw-r--r--src/client/views/collections/CollectionView.tsx108
-rw-r--r--src/client/views/collections/KeyRestrictionRow.tsx32
-rw-r--r--src/client/views/collections/TabDocView.tsx608
-rw-r--r--src/client/views/collections/TreeView.tsx405
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx11
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts217
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx71
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx232
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx66
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx30
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx76
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss39
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx1276
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx12
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx92
-rw-r--r--src/client/views/collections/collectionGrid/CollectionGridView.tsx58
-rw-r--r--src/client/views/collections/collectionLinear/CollectionLinearView.tsx77
-rw-r--r--src/client/views/collections/collectionLinear/index.ts2
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx57
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx24
-rw-r--r--src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx26
-rw-r--r--src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx2
-rw-r--r--src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx3
-rw-r--r--src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx28
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.scss13
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx562
-rw-r--r--src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx21
-rw-r--r--src/client/views/collections/collectionSchema/SchemaRowBox.tsx98
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTableCell.tsx161
-rw-r--r--src/client/views/global/globalEnums.tsx57
-rw-r--r--src/client/views/global/globalScripts.ts409
-rw-r--r--src/client/views/linking/LinkMenuGroup.tsx31
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx79
-rw-r--r--src/client/views/linking/LinkPopup.tsx23
-rw-r--r--src/client/views/linking/LinkRelationshipSearch.tsx63
-rw-r--r--src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx27
-rw-r--r--src/client/views/newlightbox/ExploreView/ExploreView.tsx30
-rw-r--r--src/client/views/newlightbox/ExploreView/index.ts2
-rw-r--r--src/client/views/newlightbox/ExploreView/utils.ts21
-rw-r--r--src/client/views/newlightbox/Header/LightboxHeader.tsx97
-rw-r--r--src/client/views/newlightbox/Header/index.ts2
-rw-r--r--src/client/views/newlightbox/NewLightboxView.tsx372
-rw-r--r--src/client/views/newlightbox/RecommendationList/RecommendationList.tsx311
-rw-r--r--src/client/views/newlightbox/RecommendationList/index.ts2
-rw-r--r--src/client/views/newlightbox/RecommendationList/utils.ts11
-rw-r--r--src/client/views/newlightbox/components/EditableText/index.ts2
-rw-r--r--src/client/views/newlightbox/components/Recommendation/Recommendation.tsx12
-rw-r--r--src/client/views/newlightbox/components/Recommendation/index.ts4
-rw-r--r--src/client/views/newlightbox/components/Recommendation/utils.ts38
-rw-r--r--src/client/views/newlightbox/components/SkeletonDoc/index.ts2
-rw-r--r--src/client/views/newlightbox/components/Template/index.ts2
-rw-r--r--src/client/views/newlightbox/components/index.ts6
-rw-r--r--src/client/views/newlightbox/utils.ts7
-rw-r--r--src/client/views/nodes/AudioBox.tsx163
-rw-r--r--src/client/views/nodes/ChatBox/ChatBox.scss228
-rw-r--r--src/client/views/nodes/ChatBox/ChatBox.tsx609
-rw-r--r--src/client/views/nodes/ChatBox/MessageComponent.tsx116
-rw-r--r--src/client/views/nodes/ChatBox/types.ts23
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx134
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx163
-rw-r--r--src/client/views/nodes/DataVizBox/DataVizBox.scss9
-rw-r--r--src/client/views/nodes/DataVizBox/DataVizBox.tsx299
-rw-r--r--src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx65
-rw-r--r--src/client/views/nodes/DataVizBox/components/Chart.scss77
-rw-r--r--src/client/views/nodes/DataVizBox/components/Histogram.tsx346
-rw-r--r--src/client/views/nodes/DataVizBox/components/LineChart.tsx378
-rw-r--r--src/client/views/nodes/DataVizBox/components/PieChart.tsx332
-rw-r--r--src/client/views/nodes/DataVizBox/components/TableBox.tsx297
-rw-r--r--src/client/views/nodes/DataVizBox/utils/D3Utils.ts34
-rw-r--r--src/client/views/nodes/DiagramBox.scss88
-rw-r--r--src/client/views/nodes/DiagramBox.tsx305
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx152
-rw-r--r--src/client/views/nodes/DocumentIcon.tsx72
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx62
-rw-r--r--src/client/views/nodes/DocumentView.scss7
-rw-r--r--src/client/views/nodes/DocumentView.tsx872
-rw-r--r--src/client/views/nodes/EquationBox.tsx40
-rw-r--r--src/client/views/nodes/FaceRectangle.tsx10
-rw-r--r--src/client/views/nodes/FieldView.tsx58
-rw-r--r--src/client/views/nodes/FocusViewOptions.ts24
-rw-r--r--src/client/views/nodes/FontIconBox/ButtonInterface.ts2
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBox.tsx156
-rw-r--r--src/client/views/nodes/FontIconBox/TrailsIcon.tsx86
-rw-r--r--src/client/views/nodes/FunctionPlotBox.tsx43
-rw-r--r--src/client/views/nodes/ImageBox.tsx256
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx173
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx25
-rw-r--r--src/client/views/nodes/LabelBox.tsx46
-rw-r--r--src/client/views/nodes/LinkAnchorBox.scss34
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx115
-rw-r--r--src/client/views/nodes/LinkBox.tsx185
-rw-r--r--src/client/views/nodes/LinkDescriptionPopup.tsx42
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx104
-rw-r--r--src/client/views/nodes/LoadingBox.tsx27
-rw-r--r--src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx39
-rw-r--r--src/client/views/nodes/MapBox/AnimationUtility.ts59
-rw-r--r--src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx18
-rw-r--r--src/client/views/nodes/MapBox/GeocoderControl.tsx7
-rw-r--r--src/client/views/nodes/MapBox/MapAnchorMenu.tsx106
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx1096
-rw-r--r--src/client/views/nodes/MapBox/MapBox2.tsx6
-rw-r--r--src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx2
-rw-r--r--src/client/views/nodes/MapBox/MapPushpinBox.tsx11
-rw-r--r--src/client/views/nodes/MapBox/MapboxApiUtility.ts76
-rw-r--r--src/client/views/nodes/MapBox/MarkerIcons.tsx3
-rw-r--r--src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx151
-rw-r--r--src/client/views/nodes/OpenWhere.ts27
-rw-r--r--src/client/views/nodes/PDFBox.scss2
-rw-r--r--src/client/views/nodes/PDFBox.tsx173
-rw-r--r--src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx383
-rw-r--r--src/client/views/nodes/RadialMenu.tsx140
-rw-r--r--src/client/views/nodes/RadialMenuItem.tsx4
-rw-r--r--src/client/views/nodes/RecordingBox/ProgressBar.tsx205
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingBox.tsx101
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingView.scss322
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingView.tsx43
-rw-r--r--src/client/views/nodes/RecordingBox/index.ts4
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx65
-rw-r--r--src/client/views/nodes/ScriptingBox.tsx175
-rw-r--r--src/client/views/nodes/SliderBox-components.tsx122
-rw-r--r--src/client/views/nodes/TaskCompletedBox.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx254
-rw-r--r--src/client/views/nodes/WebBox.tsx302
-rw-r--r--src/client/views/nodes/WebBoxRenderer.js133
-rw-r--r--src/client/views/nodes/audio/AudioWaveform.tsx8
-rw-r--r--src/client/views/nodes/audio/WaveCanvas.tsx12
-rw-r--r--src/client/views/nodes/calendarBox/CalendarBox.tsx17
-rw-r--r--src/client/views/nodes/formattedText/DashDocCommentView.tsx159
-rw-r--r--src/client/views/nodes/formattedText/DashDocView.tsx127
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.scss33
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx343
-rw-r--r--src/client/views/nodes/formattedText/EquationEditor.tsx3
-rw-r--r--src/client/views/nodes/formattedText/EquationView.tsx98
-rw-r--r--src/client/views/nodes/formattedText/FootnoteView.tsx12
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss16
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx914
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx33
-rw-r--r--src/client/views/nodes/formattedText/OrderedListView.tsx9
-rw-r--r--src/client/views/nodes/formattedText/ParagraphNodeSpec.ts100
-rw-r--r--src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts213
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx548
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts254
-rw-r--r--src/client/views/nodes/formattedText/SummaryView.tsx29
-rw-r--r--src/client/views/nodes/formattedText/marks_rts.ts64
-rw-r--r--src/client/views/nodes/formattedText/nodes_rts.ts57
-rw-r--r--src/client/views/nodes/generativeFill/GenerativeFill.tsx149
-rw-r--r--src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx10
-rw-r--r--src/client/views/nodes/generativeFill/generativeFillUtils/BrushHandler.ts6
-rw-r--r--src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts8
-rw-r--r--src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts36
-rw-r--r--src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts18
-rw-r--r--src/client/views/nodes/importBox/ImportElementBox.tsx5
-rw-r--r--src/client/views/nodes/trails/CubicBezierEditor.tsx202
-rw-r--r--src/client/views/nodes/trails/PresBox.scss170
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx1900
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx135
-rw-r--r--src/client/views/nodes/trails/PresEnums.ts2
-rw-r--r--src/client/views/nodes/trails/SlideEffect.scss19
-rw-r--r--src/client/views/nodes/trails/SlideEffect.tsx120
-rw-r--r--src/client/views/nodes/trails/SpringUtils.ts177
-rw-r--r--src/client/views/nodes/trails/index.ts6
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx68
-rw-r--r--src/client/views/pdf/Annotation.tsx168
-rw-r--r--src/client/views/pdf/GPTPopup/GPTPopup.scss43
-rw-r--r--src/client/views/pdf/GPTPopup/GPTPopup.tsx341
-rw-r--r--src/client/views/pdf/PDFViewer.tsx98
-rw-r--r--src/client/views/search/SearchBox.tsx298
-rw-r--r--src/client/views/selectedDoc/SelectedDocView.tsx18
-rw-r--r--src/client/views/selectedDoc/index.ts2
-rw-r--r--src/client/views/topbar/TopBar.tsx44
-rw-r--r--src/client/views/webcam/DashWebRTCVideo.scss82
-rw-r--r--src/client/views/webcam/DashWebRTCVideo.tsx76
-rw-r--r--src/client/views/webcam/WebCamLogic.js292
-rw-r--r--src/debug/Repl.tsx18
-rw-r--r--src/debug/Test.tsx3
-rw-r--r--src/debug/Viewer.tsx50
-rw-r--r--src/extensions/Extensions.ts9
-rw-r--r--src/extensions/ExtensionsTypings.ts (renamed from src/extensions/General/ExtensionsTypings.ts)3
-rw-r--r--src/extensions/Extensions_Array.ts (renamed from src/extensions/ArrayExtensions.ts)10
-rw-r--r--src/extensions/Extensions_String.ts (renamed from src/extensions/StringExtensions.ts)9
-rw-r--r--src/extensions/General/Extensions.ts9
-rw-r--r--src/fields/DateField.ts5
-rw-r--r--src/fields/Doc.ts642
-rw-r--r--src/fields/DocSymbols.ts35
-rw-r--r--src/fields/HtmlField.ts4
-rw-r--r--src/fields/IconField.ts2
-rw-r--r--src/fields/InkField.ts22
-rw-r--r--src/fields/List.ts97
-rw-r--r--src/fields/ObjectField.ts26
-rw-r--r--src/fields/PresField.ts6
-rw-r--r--src/fields/Proxy.ts19
-rw-r--r--src/fields/RefField.ts4
-rw-r--r--src/fields/RichTextField.ts6
-rw-r--r--src/fields/RichTextUtils.ts212
-rw-r--r--src/fields/Schema.ts27
-rw-r--r--src/fields/SchemaHeaderField.ts25
-rw-r--r--src/fields/ScriptField.ts167
-rw-r--r--src/fields/Types.ts95
-rw-r--r--src/fields/URLField.ts40
-rw-r--r--src/fields/documentSchemas.ts4
-rw-r--r--src/fields/util.ts222
-rw-r--r--src/mobile/ImageUpload.tsx102
-rw-r--r--src/mobile/MobileInkOverlay.tsx6
-rw-r--r--src/mobile/MobileInterface.tsx14
-rw-r--r--src/mobile/MobileMain.tsx2
-rw-r--r--src/pen-gestures/GestureTypes.ts16
-rw-r--r--src/pen-gestures/GestureUtils.ts26
-rw-r--r--src/pen-gestures/ndollar.ts252
-rw-r--r--src/server/ActionUtilities.ts136
-rw-r--r--src/server/ApiManagers/ApiManager.ts4
-rw-r--r--src/server/ApiManagers/AssistantManager.ts131
-rw-r--r--src/server/ApiManagers/DataVizManager.ts15
-rw-r--r--src/server/ApiManagers/DeleteManager.ts14
-rw-r--r--src/server/ApiManagers/DownloadManager.ts385
-rw-r--r--src/server/ApiManagers/GeneralGoogleManager.ts39
-rw-r--r--src/server/ApiManagers/MongoStore.js413
-rw-r--r--src/server/ApiManagers/SearchManager.ts78
-rw-r--r--src/server/ApiManagers/SessionManager.ts75
-rw-r--r--src/server/ApiManagers/UploadManager.ts347
-rw-r--r--src/server/ApiManagers/UserManager.ts60
-rw-r--r--src/server/ApiManagers/UtilManager.ts31
-rw-r--r--src/server/Client.ts8
-rw-r--r--src/server/DashSession/DashSessionAgent.ts30
-rw-r--r--src/server/DashSession/Session/agents/applied_session_agent.ts23
-rw-r--r--src/server/DashSession/Session/agents/monitor.ts48
-rw-r--r--src/server/DashSession/Session/agents/process_message_router.ts12
-rw-r--r--src/server/DashSession/Session/agents/promisified_ipc_manager.ts56
-rw-r--r--src/server/DashSession/Session/agents/server_worker.ts46
-rw-r--r--src/server/DashSession/Session/utilities/repl.ts76
-rw-r--r--src/server/DashSession/Session/utilities/session_config.ts104
-rw-r--r--src/server/DashSession/Session/utilities/utilities.ts43
-rw-r--r--src/server/DashStats.ts244
-rw-r--r--src/server/DashUploadUtils.ts746
-rw-r--r--src/server/DataVizUtils.ts11
-rw-r--r--src/server/GarbageCollector.ts70
-rw-r--r--src/server/MemoryDatabase.ts37
-rw-r--r--src/server/Message.ts91
-rw-r--r--src/server/PdfTypes.ts20
-rw-r--r--src/server/ProcessFactory.ts54
-rw-r--r--src/server/RouteManager.ts92
-rw-r--r--src/server/RouteSubscriber.ts5
-rw-r--r--src/server/Search.ts43
-rw-r--r--src/server/SharedMediaTypes.ts36
-rw-r--r--src/server/SocketData.ts35
-rw-r--r--src/server/apis/google/CredentialsLoader.ts27
-rw-r--r--src/server/apis/google/GoogleApiServerUtils.ts16
-rw-r--r--src/server/apis/google/SharedTypes.ts13
-rw-r--r--src/server/apis/youtube/youtubeApiSample.d.ts2
-rw-r--r--src/server/authentication/AuthenticationManager.ts127
-rw-r--r--src/server/authentication/DashUserModel.ts22
-rw-r--r--src/server/authentication/Passport.ts25
-rw-r--r--src/server/database.ts166
-rw-r--r--src/server/index.ts69
-rw-r--r--src/server/public/assets/dash-colon-menu.gifbin0 -> 348794 bytes
-rw-r--r--src/server/public/assets/dash-create-link-board.gifbin0 -> 167854 bytes
-rw-r--r--src/server/public/assets/dash-following-link.gifbin0 -> 181851 bytes
-rw-r--r--src/server/public/assets/documentation.pngbin0 -> 4526 bytes
-rw-r--r--src/server/public/assets/pdf.worker.2.4.456.min.js22
-rw-r--r--src/server/public/assets/pdf.worker.js22
-rw-r--r--src/server/remapUrl.ts69
-rw-r--r--src/server/server_Initialization.ts250
-rw-r--r--src/server/updateProtos.ts6
-rw-r--r--src/server/websocket.ts368
-rw-r--r--src/typings/connect-flash/index.d.ts1
-rw-r--r--src/typings/connect-mongo/index.d.ts1
-rw-r--r--src/typings/express-flash/index.d.ts1
-rw-r--r--src/typings/image-data-uri/index.d.ts3
-rw-r--r--src/typings/index.d.ts5
-rw-r--r--src/typings/jpeg-autorotate/index.d.ts3
-rw-r--r--tsconfig.json7
-rw-r--r--views/resources/statsviewcontroller.js86
-rw-r--r--webpack.config.js7
423 files changed, 32051 insertions, 25845 deletions
diff --git a/.env.swp b/.env.swp
new file mode 100644
index 000000000..8280a666e
--- /dev/null
+++ b/.env.swp
Binary files differ
diff --git a/.eslintrc.json b/.eslintrc.json
index 43bb53566..2e4da56b8 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,18 +1,82 @@
{
- "extends": ["airbnb", "prettier", "plugin:node/recommended"],
- "plugins": ["prettier"],
+ "extends": ["airbnb", "prettier", "plugin:node/recommended", "plugin:import/react"],
+ "plugins": ["prettier", "import", "@typescript-eslint"],
+ "ignorePatterns": ["solr-8.3.1/*", "deploy/*"], // <<< ignore all files in test folder
+ "settings": {
+ "import/parsers": {
+ "@typescript-eslint/parser": [".ts", ".tsx"]
+ },
+ "import/resolver": {
+ "typescript": {
+ "alwaysTryTypes": true // always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
+ },
+ "node": {
+ "extensions": [".js", ".ts", ".tsx"]
+ }
+ },
+ "import/extensions": [".js", ".jsx", ".ts", ".tsx"]
+ },
"rules": {
+ "import/extensions": [
+ "warn",
+ "ignorePackages",
+ {
+ "": "never",
+ "js": "never",
+ "ts": "never",
+ "tsx": "never"
+ }
+ ],
+ "node/no-missing-import": 0,
"prettier/prettier": "error",
- "no-unused-vars": "warn",
"no-console": "off",
"func-names": "off",
"no-process-exit": "off",
"object-shorthand": "off",
"class-methods-use-this": "off",
- "single-quote": "off"
+ "single-quote": "off",
+ "max-classes-per-file": 0,
+ "node/no-unsupported-features/es-syntax": ["error", { "ignores": ["modules"] }],
+ "react/jsx-filename-extension": [2, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }],
+ "import/prefer-default-export": "off",
+ "no-unused-expressions": "off",
+ "prefer-template": "off",
+ "no-inner-declarations": "off",
+ "no-plusplus": "off",
+ "no-multi-assign": "off",
+ "no-underscore-dangle": "off",
+ "no-nested-ternary": "off",
+ "lines-between-class-members": "off",
+ "no-explicit-any": "off",
+ // Note: you must disable the base rule as it can report incorrect errors
+ "no-shadow": "off",
+ "@typescript-eslint/no-shadow": "warn",
+ "no-unused-vars": "off",
+ "@typescript-eslint/no-unused-vars": "error",
+ "@typescript-eslint/no-namespace": 0,
+ "react/destructuring-assignment": 0,
+ "no-restricted-globals": ["error", "event"],
+ "no-param-reassign": ["error", { "props": false }],
+ // "import/no-cycle": 0,
+ "no-alert": 0,
+ "radix": "off"
},
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {
+ "no-undef": "off"
+ }
+ }
+ ],
+ "parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 11,
- "sourceType": "module"
+ "sourceType": "module",
+ "ecmaFeatures": {
+ "jsx": true,
+ "modules": true
+ },
+ "useJSXTextNode": false
}
}
diff --git a/.gitignore b/.gitignore
index f841c1a86..6a1963b4e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,6 @@ node_modules
dist/
.DS_Store
.env
-ClientUtils.ts
solr-8.3.1/server/logs/
solr-8.3.1/server/solr/dash/data/tlog/*
solr-8.3.1/server/solr/dash/data/index/*
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 9ba624af9..e4c31361c 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -95,5 +95,10 @@
"internalConsoleOptions": "openOnSessionStart",
"protocol": "inspector"
}
+ ],
+
+ "resolveSourceMapLocations": [
+ "${workspaceFolder}/**",
+ "!**/node_modules/**"
]
}
diff --git a/deploy/assets/pdf.worker.2.4.456.min.js b/deploy/assets/pdf.worker.2.4.456.min.js
deleted file mode 100644
index 54eb544f6..000000000
--- a/deploy/assets/pdf.worker.2.4.456.min.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * @licstart The following is the entire license notice for the
- * Javascript code in this page
- *
- * Copyright 2020 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * Javascript code in this page
- */
-!function (e, t) { "object" == typeof exports && "object" == typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define("pdfjs-dist/build/pdf.worker", [], t) : "object" == typeof exports ? exports["pdfjs-dist/build/pdf.worker"] = t() : e["pdfjs-dist/build/pdf.worker"] = e.pdfjsWorker = t() }(this, (function () { return function (e) { var t = {}; function a(r) { if (t[r]) return t[r].exports; var i = t[r] = { i: r, l: !1, exports: {} }; e[r].call(i.exports, i, i.exports, a); i.l = !0; return i.exports } a.m = e; a.c = t; a.d = function (e, t, r) { a.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r }) }; a.r = function (e) { "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }); Object.defineProperty(e, "__esModule", { value: !0 }) }; a.t = function (e, t) { 1 & t && (e = a(e)); if (8 & t) return e; if (4 & t && "object" == typeof e && e && e.__esModule) return e; var r = Object.create(null); a.r(r); Object.defineProperty(r, "default", { enumerable: !0, value: e }); if (2 & t && "string" != typeof e) for (var i in e) a.d(r, i, function (t) { return e[t] }.bind(null, i)); return r }; a.n = function (e) { var t = e && e.__esModule ? function () { return e.default } : function () { return e }; a.d(t, "a", t); return t }; a.o = function (e, t) { return Object.prototype.hasOwnProperty.call(e, t) }; a.p = ""; return a(a.s = 0) }([function (e, t, a) { "use strict"; const r = a(1); t.WorkerMessageHandler = r.WorkerMessageHandler }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.WorkerMessageHandler = t.WorkerTask = void 0; var r = a(2), i = a(4), n = a(5), s = a(44), o = a(45), c = a(46), l = a(7), h = function () { function e(e) { this.name = e; this.terminated = !1; this._capability = (0, r.createPromiseCapability)() } e.prototype = { get finished() { return this._capability.promise }, finish() { this._capability.resolve() }, terminate() { this.terminated = !0 }, ensureNotTerminated() { if (this.terminated) throw new Error("Worker task was terminated") } }; return e }(); t.WorkerTask = h; var u, d = { setup(e, t) { var a = !1; e.on("test", (function (t) { if (a) return; a = !0; if (!(t instanceof Uint8Array)) { e.send("test", null); return } const r = 255 === t[0]; e.postMessageTransfers = r; e.send("test", { supportTransfers: r }) })); e.on("configure", (function (e) { (0, r.setVerbosityLevel)(e.verbosity) })); e.on("GetDocRequest", (function (e) { return d.createDocumentHandler(e, t) })) }, createDocumentHandler(e, t) { var a, s = !1, u = null, d = []; const f = (0, r.getVerbosityLevel)(), g = e.apiVersion; if ("2.4.456" !== g) throw new Error(`The API version "${g}" does not match ` + 'the Worker version "2.4.456".'); const m = []; for (const e in []) m.push(e); if (m.length) throw new Error("The `Array.prototype` contains unexpected enumerable properties: " + m.join(", ") + "; thus breaking e.g. `for...in` iteration of `Array`s."); var p = e.docId, b = e.docBaseUrl, y = e.docId + "_worker", v = new o.MessageHandler(y, p, t); v.postMessageTransfers = e.postMessageTransfers; function w() { if (s) throw new Error("Worker was terminated") } function k(e) { d.push(e) } function S(e) { e.finish(); var t = d.indexOf(e); d.splice(t, 1) } async function C(e) { await a.ensureDoc("checkHeader"); await a.ensureDoc("parseStartXRef"); await a.ensureDoc("parse", [e]); e || await a.ensureDoc("checkFirstPage"); const [t, r] = await Promise.all([a.ensureDoc("numPages"), a.ensureDoc("fingerprint")]); return { numPages: t, fingerprint: r } } function x(e, t) { var a, i = (0, r.createPromiseCapability)(), s = e.source; if (s.data) { try { a = new n.LocalPdfManager(p, s.data, s.password, t, b); i.resolve(a) } catch (e) { i.reject(e) } return i.promise } var o, l = []; try { o = new c.PDFWorkerStream(v) } catch (e) { i.reject(e); return i.promise } var h = o.getFullReader(); h.headersReady.then((function () { if (h.isRangeSupported) { var e = s.disableAutoFetch || h.isStreamingSupported; a = new n.NetworkPdfManager(p, o, { msgHandler: v, password: s.password, length: h.contentLength, disableAutoFetch: e, rangeChunkSize: s.rangeChunkSize }, t, b); for (let e = 0; e < l.length; e++)a.sendProgressiveData(l[e]); l = []; i.resolve(a); u = null } })).catch((function (e) { i.reject(e); u = null })); var d = 0; new Promise((function (e, o) { var c = function (e) { try { w(); if (e.done) { a || function () { var e = (0, r.arraysToBytes)(l); s.length && e.length !== s.length && (0, r.warn)("reported HTTP length is different from actual"); try { a = new n.LocalPdfManager(p, e, s.password, t, b); i.resolve(a) } catch (e) { i.reject(e) } l = [] }(); u = null; return } var f = e.value; d += (0, r.arrayByteLength)(f); h.isStreamingSupported || v.send("DocProgress", { loaded: d, total: Math.max(d, h.contentLength || 0) }); a ? a.sendProgressiveData(f) : l.push(f); h.read().then(c, o) } catch (e) { o(e) } }; h.read().then(c, o) })).catch((function (e) { i.reject(e); u = null })); u = function (e) { o.cancelAllRequests(e) }; return i.promise } v.on("GetPage", (function (e) { return a.getPage(e.pageIndex).then((function (e) { return Promise.all([a.ensure(e, "rotate"), a.ensure(e, "ref"), a.ensure(e, "userUnit"), a.ensure(e, "view")]).then((function ([e, t, a, r]) { return { rotate: e, ref: t, userUnit: a, view: r } })) })) })); v.on("GetPageIndex", (function (e) { var t = i.Ref.get(e.ref.num, e.ref.gen); return a.pdfDocument.catalog.getPageIndex(t) })); v.on("GetDestinations", (function (e) { return a.ensureCatalog("destinations") })); v.on("GetDestination", (function (e) { return a.ensureCatalog("getDestination", [e.id]) })); v.on("GetPageLabels", (function (e) { return a.ensureCatalog("pageLabels") })); v.on("GetPageLayout", (function (e) { return a.ensureCatalog("pageLayout") })); v.on("GetPageMode", (function (e) { return a.ensureCatalog("pageMode") })); v.on("GetViewerPreferences", (function (e) { return a.ensureCatalog("viewerPreferences") })); v.on("GetOpenAction", (function (e) { return a.ensureCatalog("openAction") })); v.on("GetAttachments", (function (e) { return a.ensureCatalog("attachments") })); v.on("GetJavaScript", (function (e) { return a.ensureCatalog("javaScript") })); v.on("GetOutline", (function (e) { return a.ensureCatalog("documentOutline") })); v.on("GetPermissions", (function (e) { return a.ensureCatalog("permissions") })); v.on("GetMetadata", (function (e) { return Promise.all([a.ensureDoc("documentInfo"), a.ensureCatalog("metadata")]) })); v.on("GetData", (function (e) { a.requestLoadedStream(); return a.onLoadedStream().then((function (e) { return e.bytes })) })); v.on("GetStats", (function (e) { return a.pdfDocument.xref.stats })); v.on("GetAnnotations", (function ({ pageIndex: e, intent: t }) { return a.getPage(e).then((function (e) { return e.getAnnotationsData(t) })) })); v.on("GetOperatorList", (function (e, t) { var i = e.pageIndex; a.getPage(i).then((function (a) { var n = new h(`GetOperatorList: page ${i}`); k(n); const s = f >= r.VerbosityLevel.INFOS ? Date.now() : 0; a.getOperatorList({ handler: v, sink: t, task: n, intent: e.intent, renderInteractiveForms: e.renderInteractiveForms }).then((function (e) { S(n); s && (0, r.info)(`page=${i + 1} - getOperatorList: time=` + `${Date.now() - s}ms, len=${e.length}`); t.close() }), (function (e) { S(n); if (!n.terminated) { v.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); t.error(e) } })) })) }), this); v.on("GetTextContent", (function (e, t) { var i = e.pageIndex; t.onPull = function (e) { }; t.onCancel = function (e) { }; a.getPage(i).then((function (a) { var n = new h("GetTextContent: page " + i); k(n); const s = f >= r.VerbosityLevel.INFOS ? Date.now() : 0; a.extractTextContent({ handler: v, task: n, sink: t, normalizeWhitespace: e.normalizeWhitespace, combineTextItems: e.combineTextItems }).then((function () { S(n); s && (0, r.info)(`page=${i + 1} - getTextContent: time=` + `${Date.now() - s}ms`); t.close() }), (function (e) { S(n); n.terminated || t.error(e) })) })) })); v.on("FontFallback", (function (e) { return a.fontFallback(e.id, v) })); v.on("Cleanup", (function (e) { return a.cleanup() })); v.on("Terminate", (function (e) { s = !0; const t = []; if (a) { a.terminate(new r.AbortException("Worker was terminated.")); const e = a.cleanup(); t.push(e); a = null } else (0, i.clearPrimitiveCaches)(); u && u(new r.AbortException("Worker was terminated.")); d.forEach((function (e) { t.push(e.finished); e.terminate() })); return Promise.all(t).then((function () { v.destroy(); v = null })) })); v.on("Ready", (function (t) { !function (e) { function t(e) { w(); v.send("GetDoc", { pdfInfo: e }) } function i(e) { w(); if (e instanceof r.PasswordException) { var t = new h(`PasswordException: response ${e.code}`); k(t); v.sendWithPromise("PasswordRequest", e).then((function (e) { S(t); a.updatePassword(e.password); n() })).catch((function () { S(t); v.send("DocException", e) })) } else e instanceof r.InvalidPDFException || e instanceof r.MissingPDFException || e instanceof r.UnexpectedResponseException || e instanceof r.UnknownErrorException ? v.send("DocException", e) : v.send("DocException", new r.UnknownErrorException(e.message, e.toString())) } function n() { w(); C(!1).then(t, (function (e) { w(); if (e instanceof l.XRefParseException) { a.requestLoadedStream(); a.onLoadedStream().then((function () { w(); C(!0).then(t, i) })) } else i(e) }), i) } w(); x(e, { forceDataSchema: e.disableCreateObjectURL, maxImageSize: e.maxImageSize, disableFontFace: e.disableFontFace, nativeImageDecoderSupport: e.nativeImageDecoderSupport, ignoreErrors: e.ignoreErrors, isEvalSupported: e.isEvalSupported }).then((function (e) { if (s) { e.terminate(new r.AbortException("Worker was terminated.")); throw new Error("Worker was terminated") } (a = e).onLoadedStream().then((function (e) { v.send("DataLoaded", { length: e.bytes.byteLength }) })) })).then(n, i) }(e); e = null })); return y }, initializeFromPort(e) { var t = new o.MessageHandler("worker", "main", e); d.setup(t, e); t.send("ready", null) } }; t.WorkerMessageHandler = d; "undefined" == typeof window && !s.isNodeJS && "undefined" != typeof self && ("function" == typeof (u = self).postMessage && "onmessage" in u) && d.initializeFromPort(self) }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.arrayByteLength = d; t.arraysToBytes = function (e) { const t = e.length; if (1 === t && e[0] instanceof Uint8Array) return e[0]; let a = 0; for (let r = 0; r < t; r++)a += d(e[r]); let r = 0; const i = new Uint8Array(a); for (let a = 0; a < t; a++) { let t = e[a]; t instanceof Uint8Array || (t = "string" == typeof t ? u(t) : new Uint8Array(t)); const n = t.byteLength; i.set(t, r); r += n } return i }; t.assert = o; t.bytesToString = function (e) { o(null !== e && "object" == typeof e && void 0 !== e.length, "Invalid argument for bytesToString"); const t = e.length; if (t < 8192) return String.fromCharCode.apply(null, e); const a = []; for (let r = 0; r < t; r += 8192) { const i = Math.min(r + 8192, t), n = e.subarray(r, i); a.push(String.fromCharCode.apply(null, n)) } return a.join("") }; t.createPromiseCapability = function () { const e = Object.create(null); let t = !1; Object.defineProperty(e, "settled", { get: () => t }); e.promise = new Promise((function (a, r) { e.resolve = function (e) { t = !0; a(e) }; e.reject = function (e) { t = !0; r(e) } })); return e }; t.getVerbosityLevel = function () { return i }; t.info = function (e) { i >= r.INFOS && console.log(`Info: ${e}`) }; t.isArrayBuffer = function (e) { return "object" == typeof e && null !== e && void 0 !== e.byteLength }; t.isArrayEqual = function (e, t) { if (e.length !== t.length) return !1; return e.every((function (e, a) { return e === t[a] })) }; t.isBool = function (e) { return "boolean" == typeof e }; t.isEmptyObj = function (e) { for (const t in e) return !1; return !0 }; t.isNum = function (e) { return "number" == typeof e }; t.isString = function (e) { return "string" == typeof e }; t.isSameOrigin = function (e, t) { let a; try { a = new URL(e); if (!a.origin || "null" === a.origin) return !1 } catch (e) { return !1 } const r = new URL(t, a); return a.origin === r.origin }; t.createValidAbsoluteUrl = function (e, t) { if (!e) return null; try { const a = t ? new URL(e, t) : new URL(e); if (function (e) { if (!e) return !1; switch (e.protocol) { case "http:": case "https:": case "ftp:": case "mailto:": case "tel:": return !0; default: return !1 } }(a)) return a } catch (e) { } return null }; t.removeNullCharacters = function (e) { if ("string" != typeof e) { n("The argument for removeNullCharacters must be a string."); return e } return e.replace(h, "") }; t.setVerbosityLevel = function (e) { Number.isInteger(e) && (i = e) }; t.shadow = c; t.string32 = function (e) { return String.fromCharCode(e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e) }; t.stringToBytes = u; t.stringToPDFString = function (e) { const t = e.length, a = []; if ("þ" === e[0] && "ÿ" === e[1]) for (let r = 2; r < t; r += 2)a.push(String.fromCharCode(e.charCodeAt(r) << 8 | e.charCodeAt(r + 1))); else if ("ÿ" === e[0] && "þ" === e[1]) for (let r = 2; r < t; r += 2)a.push(String.fromCharCode(e.charCodeAt(r + 1) << 8 | e.charCodeAt(r))); else for (let r = 0; r < t; ++r) { const t = b[e.charCodeAt(r)]; a.push(t ? String.fromCharCode(t) : e.charAt(r)) } return a.join("") }; t.stringToUTF8String = function (e) { return decodeURIComponent(escape(e)) }; t.utf8StringToString = function (e) { return unescape(encodeURIComponent(e)) }; t.warn = n; t.unreachable = s; t.IsEvalSupportedCached = t.IsLittleEndianCached = t.createObjectURL = t.FormatError = t.Util = t.UnknownErrorException = t.UnexpectedResponseException = t.TextRenderingMode = t.StreamType = t.PermissionFlag = t.PasswordResponses = t.PasswordException = t.NativeImageDecoding = t.MissingPDFException = t.InvalidPDFException = t.AbortException = t.CMapCompressionType = t.ImageKind = t.FontType = t.AnnotationType = t.AnnotationStateModelType = t.AnnotationReviewState = t.AnnotationReplyType = t.AnnotationMarkedState = t.AnnotationFlag = t.AnnotationFieldFlag = t.AnnotationBorderStyleType = t.UNSUPPORTED_FEATURES = t.VerbosityLevel = t.OPS = t.IDENTITY_MATRIX = t.FONT_IDENTITY_MATRIX = t.BaseException = void 0; a(3); t.IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; t.FONT_IDENTITY_MATRIX = [.001, 0, 0, .001, 0, 0]; t.NativeImageDecoding = { NONE: "none", DECODE: "decode", DISPLAY: "display" }; t.PermissionFlag = { PRINT: 4, MODIFY_CONTENTS: 8, COPY: 16, MODIFY_ANNOTATIONS: 32, FILL_INTERACTIVE_FORMS: 256, COPY_FOR_ACCESSIBILITY: 512, ASSEMBLE: 1024, PRINT_HIGH_QUALITY: 2048 }; t.TextRenderingMode = { FILL: 0, STROKE: 1, FILL_STROKE: 2, INVISIBLE: 3, FILL_ADD_TO_PATH: 4, STROKE_ADD_TO_PATH: 5, FILL_STROKE_ADD_TO_PATH: 6, ADD_TO_PATH: 7, FILL_STROKE_MASK: 3, ADD_TO_PATH_FLAG: 4 }; t.ImageKind = { GRAYSCALE_1BPP: 1, RGB_24BPP: 2, RGBA_32BPP: 3 }; t.AnnotationType = { TEXT: 1, LINK: 2, FREETEXT: 3, LINE: 4, SQUARE: 5, CIRCLE: 6, POLYGON: 7, POLYLINE: 8, HIGHLIGHT: 9, UNDERLINE: 10, SQUIGGLY: 11, STRIKEOUT: 12, STAMP: 13, CARET: 14, INK: 15, POPUP: 16, FILEATTACHMENT: 17, SOUND: 18, MOVIE: 19, WIDGET: 20, SCREEN: 21, PRINTERMARK: 22, TRAPNET: 23, WATERMARK: 24, THREED: 25, REDACT: 26 }; t.AnnotationStateModelType = { MARKED: "Marked", REVIEW: "Review" }; t.AnnotationMarkedState = { MARKED: "Marked", UNMARKED: "Unmarked" }; t.AnnotationReviewState = { ACCEPTED: "Accepted", REJECTED: "Rejected", CANCELLED: "Cancelled", COMPLETED: "Completed", NONE: "None" }; t.AnnotationReplyType = { GROUP: "Group", REPLY: "R" }; t.AnnotationFlag = { INVISIBLE: 1, HIDDEN: 2, PRINT: 4, NOZOOM: 8, NOROTATE: 16, NOVIEW: 32, READONLY: 64, LOCKED: 128, TOGGLENOVIEW: 256, LOCKEDCONTENTS: 512 }; t.AnnotationFieldFlag = { READONLY: 1, REQUIRED: 2, NOEXPORT: 4, MULTILINE: 4096, PASSWORD: 8192, NOTOGGLETOOFF: 16384, RADIO: 32768, PUSHBUTTON: 65536, COMBO: 131072, EDIT: 262144, SORT: 524288, FILESELECT: 1048576, MULTISELECT: 2097152, DONOTSPELLCHECK: 4194304, DONOTSCROLL: 8388608, COMB: 16777216, RICHTEXT: 33554432, RADIOSINUNISON: 33554432, COMMITONSELCHANGE: 67108864 }; t.AnnotationBorderStyleType = { SOLID: 1, DASHED: 2, BEVELED: 3, INSET: 4, UNDERLINE: 5 }; t.StreamType = { UNKNOWN: "UNKNOWN", FLATE: "FLATE", LZW: "LZW", DCT: "DCT", JPX: "JPX", JBIG: "JBIG", A85: "A85", AHX: "AHX", CCF: "CCF", RLX: "RLX" }; t.FontType = { UNKNOWN: "UNKNOWN", TYPE1: "TYPE1", TYPE1C: "TYPE1C", CIDFONTTYPE0: "CIDFONTTYPE0", CIDFONTTYPE0C: "CIDFONTTYPE0C", TRUETYPE: "TRUETYPE", CIDFONTTYPE2: "CIDFONTTYPE2", TYPE3: "TYPE3", OPENTYPE: "OPENTYPE", TYPE0: "TYPE0", MMTYPE1: "MMTYPE1" }; const r = { ERRORS: 0, WARNINGS: 1, INFOS: 5 }; t.VerbosityLevel = r; t.CMapCompressionType = { NONE: 0, BINARY: 1, STREAM: 2 }; t.OPS = { dependency: 1, setLineWidth: 2, setLineCap: 3, setLineJoin: 4, setMiterLimit: 5, setDash: 6, setRenderingIntent: 7, setFlatness: 8, setGState: 9, save: 10, restore: 11, transform: 12, moveTo: 13, lineTo: 14, curveTo: 15, curveTo2: 16, curveTo3: 17, closePath: 18, rectangle: 19, stroke: 20, closeStroke: 21, fill: 22, eoFill: 23, fillStroke: 24, eoFillStroke: 25, closeFillStroke: 26, closeEOFillStroke: 27, endPath: 28, clip: 29, eoClip: 30, beginText: 31, endText: 32, setCharSpacing: 33, setWordSpacing: 34, setHScale: 35, setLeading: 36, setFont: 37, setTextRenderingMode: 38, setTextRise: 39, moveText: 40, setLeadingMoveText: 41, setTextMatrix: 42, nextLine: 43, showText: 44, showSpacedText: 45, nextLineShowText: 46, nextLineSetSpacingShowText: 47, setCharWidth: 48, setCharWidthAndBounds: 49, setStrokeColorSpace: 50, setFillColorSpace: 51, setStrokeColor: 52, setStrokeColorN: 53, setFillColor: 54, setFillColorN: 55, setStrokeGray: 56, setFillGray: 57, setStrokeRGBColor: 58, setFillRGBColor: 59, setStrokeCMYKColor: 60, setFillCMYKColor: 61, shadingFill: 62, beginInlineImage: 63, beginImageData: 64, endInlineImage: 65, paintXObject: 66, markPoint: 67, markPointProps: 68, beginMarkedContent: 69, beginMarkedContentProps: 70, endMarkedContent: 71, beginCompat: 72, endCompat: 73, paintFormXObjectBegin: 74, paintFormXObjectEnd: 75, beginGroup: 76, endGroup: 77, beginAnnotations: 78, endAnnotations: 79, beginAnnotation: 80, endAnnotation: 81, paintJpegXObject: 82, paintImageMaskXObject: 83, paintImageMaskXObjectGroup: 84, paintImageXObject: 85, paintInlineImageXObject: 86, paintInlineImageXObjectGroup: 87, paintImageXObjectRepeat: 88, paintImageMaskXObjectRepeat: 89, paintSolidColorImageMask: 90, constructPath: 91 }; t.UNSUPPORTED_FEATURES = { unknown: "unknown", forms: "forms", javaScript: "javaScript", smask: "smask", shadingPattern: "shadingPattern", font: "font" }; t.PasswordResponses = { NEED_PASSWORD: 1, INCORRECT_PASSWORD: 2 }; let i = r.WARNINGS; function n(e) { i >= r.WARNINGS && console.log(`Warning: ${e}`) } function s(e) { throw new Error(e) } function o(e, t) { e || s(t) } function c(e, t, a) { Object.defineProperty(e, t, { value: a, enumerable: !0, configurable: !0, writable: !1 }); return a } const l = function () { function e(t) { this.constructor === e && s("Cannot initialize BaseException."); this.message = t; this.name = this.constructor.name } e.prototype = new Error; e.constructor = e; return e }(); t.BaseException = l; t.PasswordException = class extends l { constructor(e, t) { super(e); this.code = t } }; t.UnknownErrorException = class extends l { constructor(e, t) { super(e); this.details = t } }; t.InvalidPDFException = class extends l { }; t.MissingPDFException = class extends l { }; t.UnexpectedResponseException = class extends l { constructor(e, t) { super(e); this.status = t } }; t.FormatError = class extends l { }; t.AbortException = class extends l { }; const h = /\x00/g; function u(e) { o("string" == typeof e, "Invalid argument for stringToBytes"); const t = e.length, a = new Uint8Array(t); for (let r = 0; r < t; ++r)a[r] = 255 & e.charCodeAt(r); return a } function d(e) { if (void 0 !== e.length) return e.length; o(void 0 !== e.byteLength); return e.byteLength } const f = { get value() { return c(this, "value", function () { const e = new Uint8Array(4); e[0] = 1; return 1 === new Uint32Array(e.buffer, 0, 1)[0] }()) } }; t.IsLittleEndianCached = f; const g = { get value() { return c(this, "value", function () { try { new Function(""); return !0 } catch (e) { return !1 } }()) } }; t.IsEvalSupportedCached = g; const m = ["rgb(", 0, ",", 0, ",", 0, ")"]; class p { static makeCssRgb(e, t, a) { m[1] = e; m[3] = t; m[5] = a; return m.join("") } static transform(e, t) { return [e[0] * t[0] + e[2] * t[1], e[1] * t[0] + e[3] * t[1], e[0] * t[2] + e[2] * t[3], e[1] * t[2] + e[3] * t[3], e[0] * t[4] + e[2] * t[5] + e[4], e[1] * t[4] + e[3] * t[5] + e[5]] } static applyTransform(e, t) { return [e[0] * t[0] + e[1] * t[2] + t[4], e[0] * t[1] + e[1] * t[3] + t[5]] } static applyInverseTransform(e, t) { const a = t[0] * t[3] - t[1] * t[2]; return [(e[0] * t[3] - e[1] * t[2] + t[2] * t[5] - t[4] * t[3]) / a, (-e[0] * t[1] + e[1] * t[0] + t[4] * t[1] - t[5] * t[0]) / a] } static getAxialAlignedBoundingBox(e, t) { const a = p.applyTransform(e, t), r = p.applyTransform(e.slice(2, 4), t), i = p.applyTransform([e[0], e[3]], t), n = p.applyTransform([e[2], e[1]], t); return [Math.min(a[0], r[0], i[0], n[0]), Math.min(a[1], r[1], i[1], n[1]), Math.max(a[0], r[0], i[0], n[0]), Math.max(a[1], r[1], i[1], n[1])] } static inverseTransform(e) { const t = e[0] * e[3] - e[1] * e[2]; return [e[3] / t, -e[1] / t, -e[2] / t, e[0] / t, (e[2] * e[5] - e[4] * e[3]) / t, (e[4] * e[1] - e[5] * e[0]) / t] } static apply3dTransform(e, t) { return [e[0] * t[0] + e[1] * t[1] + e[2] * t[2], e[3] * t[0] + e[4] * t[1] + e[5] * t[2], e[6] * t[0] + e[7] * t[1] + e[8] * t[2]] } static singularValueDecompose2dScale(e) { const t = [e[0], e[2], e[1], e[3]], a = e[0] * t[0] + e[1] * t[2], r = e[0] * t[1] + e[1] * t[3], i = e[2] * t[0] + e[3] * t[2], n = e[2] * t[1] + e[3] * t[3], s = (a + n) / 2, o = Math.sqrt((a + n) * (a + n) - 4 * (a * n - i * r)) / 2, c = s + o || 1, l = s - o || 1; return [Math.sqrt(c), Math.sqrt(l)] } static normalizeRect(e) { const t = e.slice(0); if (e[0] > e[2]) { t[0] = e[2]; t[2] = e[0] } if (e[1] > e[3]) { t[1] = e[3]; t[3] = e[1] } return t } static intersect(e, t) { function a(e, t) { return e - t } const r = [e[0], e[2], t[0], t[2]].sort(a), i = [e[1], e[3], t[1], t[3]].sort(a), n = []; e = p.normalizeRect(e); t = p.normalizeRect(t); if (!(r[0] === e[0] && r[1] === t[0] || r[0] === t[0] && r[1] === e[0])) return null; n[0] = r[1]; n[2] = r[2]; if (!(i[0] === e[1] && i[1] === t[1] || i[0] === t[1] && i[1] === e[1])) return null; n[1] = i[1]; n[3] = i[2]; return n } } t.Util = p; const b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 728, 711, 710, 729, 733, 731, 730, 732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8226, 8224, 8225, 8230, 8212, 8211, 402, 8260, 8249, 8250, 8722, 8240, 8222, 8220, 8221, 8216, 8217, 8218, 8482, 64257, 64258, 321, 338, 352, 376, 381, 305, 322, 339, 353, 382, 0, 8364]; const y = function () { const e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; return function (t, a, r = !1) { if (!r && URL.createObjectURL) { const e = new Blob([t], { type: a }); return URL.createObjectURL(e) } let i = `data:${a};base64,`; for (let a = 0, r = t.length; a < r; a += 3) { const n = 255 & t[a], s = 255 & t[a + 1], o = 255 & t[a + 2]; i += e[n >> 2] + e[(3 & n) << 4 | s >> 4] + e[a + 1 < r ? (15 & s) << 2 | o >> 6 : 64] + e[a + 2 < r ? 63 & o : 64] } return i } }(); t.createObjectURL = y }, function (e, t, a) { }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.clearPrimitiveCaches = function () { n._clearCache(); i._clearCache(); o._clearCache() }; t.isEOF = function (e) { return e === r }; t.isCmd = function (e, t) { return e instanceof n && (void 0 === t || e.cmd === t) }; t.isDict = u; t.isName = h; t.isRef = function (e) { return e instanceof o }; t.isRefsEqual = function (e, t) { return e.num === t.num && e.gen === t.gen }; t.isStream = function (e) { return "object" == typeof e && null !== e && void 0 !== e.getBytes }; t.RefSetCache = t.RefSet = t.Ref = t.Name = t.Dict = t.Cmd = t.EOF = void 0; a(2); var r = {}; t.EOF = r; var i = function () { let e = Object.create(null); function t(e) { this.name = e } t.prototype = {}; t.get = function (a) { var r = e[a]; return r || (e[a] = new t(a)) }; t._clearCache = function () { e = Object.create(null) }; return t }(); t.Name = i; var n = function () { let e = Object.create(null); function t(e) { this.cmd = e } t.prototype = {}; t.get = function (a) { var r = e[a]; return r || (e[a] = new t(a)) }; t._clearCache = function () { e = Object.create(null) }; return t }(); t.Cmd = n; var s = function () { var e = function () { return e }; function t(t) { this._map = Object.create(null); this.xref = t; this.objId = null; this.suppressEncryption = !1; this.__nonSerializable__ = e } t.prototype = { assignXref: function (e) { this.xref = e }, get(e, t, a) { let r = this._map[e]; if (void 0 === r && void 0 !== t) { r = this._map[t]; void 0 === r && void 0 !== a && (r = this._map[a]) } return r instanceof o && this.xref ? this.xref.fetch(r, this.suppressEncryption) : r }, async getAsync(e, t, a) { let r = this._map[e]; if (void 0 === r && void 0 !== t) { r = this._map[t]; void 0 === r && void 0 !== a && (r = this._map[a]) } return r instanceof o && this.xref ? this.xref.fetchAsync(r, this.suppressEncryption) : r }, getArray(e, t, a) { let r = this.get(e, t, a); if (!Array.isArray(r) || !this.xref) return r; r = r.slice(); for (let e = 0, t = r.length; e < t; e++)r[e] instanceof o && (r[e] = this.xref.fetch(r[e], this.suppressEncryption)); return r }, getRaw: function (e) { return this._map[e] }, getKeys: function () { return Object.keys(this._map) }, set: function (e, t) { this._map[e] = t }, has: function (e) { return void 0 !== this._map[e] }, forEach: function (e) { for (var t in this._map) e(t, this.get(t)) } }; t.empty = new t(null); t.merge = function (e, a) { const r = new t(e); for (let e = 0, t = a.length; e < t; e++) { const t = a[e]; if (u(t)) for (const e in t._map) void 0 === r._map[e] && (r._map[e] = t._map[e]) } return r }; return t }(); t.Dict = s; var o = function () { let e = Object.create(null); function t(e, t) { this.num = e; this.gen = t } t.prototype = { toString: function () { return 0 === this.gen ? `${this.num}R` : `${this.num}R${this.gen}` } }; t.get = function (a, r) { const i = 0 === r ? `${a}R` : `${a}R${r}`, n = e[i]; return n || (e[i] = new t(a, r)) }; t._clearCache = function () { e = Object.create(null) }; return t }(); t.Ref = o; var c = function () { function e() { this.dict = Object.create(null) } e.prototype = { has: function (e) { return e.toString() in this.dict }, put: function (e) { this.dict[e.toString()] = !0 }, remove: function (e) { delete this.dict[e.toString()] } }; return e }(); t.RefSet = c; var l = function () { function e() { this.dict = Object.create(null) } e.prototype = { get: function (e) { return this.dict[e.toString()] }, has: function (e) { return e.toString() in this.dict }, put: function (e, t) { this.dict[e.toString()] = t }, putAlias: function (e, t) { this.dict[e.toString()] = this.get(t) }, forEach: function (e) { for (const t in this.dict) e(this.dict[t]) }, clear: function () { this.dict = Object.create(null) } }; return e }(); t.RefSetCache = l; function h(e, t) { return e instanceof i && (void 0 === t || e.name === t) } function u(e, t) { return e instanceof s && (void 0 === t || h(e.get("Type"), t)) } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.NetworkPdfManager = t.LocalPdfManager = void 0; var r = a(2), i = a(6), n = a(7), s = a(8), o = a(11); class c { constructor() { this.constructor === c && (0, r.unreachable)("Cannot initialize BasePdfManager.") } get docId() { return this._docId } get password() { return this._password } get docBaseUrl() { let e = null; if (this._docBaseUrl) { const t = (0, r.createValidAbsoluteUrl)(this._docBaseUrl); t ? e = t.href : (0, r.warn)(`Invalid absolute docBaseUrl: "${this._docBaseUrl}".`) } return (0, r.shadow)(this, "docBaseUrl", e) } onLoadedStream() { (0, r.unreachable)("Abstract method `onLoadedStream` called") } ensureDoc(e, t) { return this.ensure(this.pdfDocument, e, t) } ensureXRef(e, t) { return this.ensure(this.pdfDocument.xref, e, t) } ensureCatalog(e, t) { return this.ensure(this.pdfDocument.catalog, e, t) } getPage(e) { return this.pdfDocument.getPage(e) } fontFallback(e, t) { return this.pdfDocument.fontFallback(e, t) } cleanup() { return this.pdfDocument.cleanup() } async ensure(e, t, a) { (0, r.unreachable)("Abstract method `ensure` called") } requestRange(e, t) { (0, r.unreachable)("Abstract method `requestRange` called") } requestLoadedStream() { (0, r.unreachable)("Abstract method `requestLoadedStream` called") } sendProgressiveData(e) { (0, r.unreachable)("Abstract method `sendProgressiveData` called") } updatePassword(e) { this._password = e } terminate(e) { (0, r.unreachable)("Abstract method `terminate` called") } } t.LocalPdfManager = class extends c { constructor(e, t, a, r, i) { super(); this._docId = e; this._password = a; this._docBaseUrl = i; this.evaluatorOptions = r; const n = new o.Stream(t); this.pdfDocument = new s.PDFDocument(this, n); this._loadedStreamPromise = Promise.resolve(n) } async ensure(e, t, a) { const r = e[t]; return "function" == typeof r ? r.apply(e, a) : r } requestRange(e, t) { return Promise.resolve() } requestLoadedStream() { } onLoadedStream() { return this._loadedStreamPromise } terminate(e) { } }; t.NetworkPdfManager = class extends c { constructor(e, t, a, r, n) { super(); this._docId = e; this._password = a.password; this._docBaseUrl = n; this.msgHandler = a.msgHandler; this.evaluatorOptions = r; this.streamManager = new i.ChunkedStreamManager(t, { msgHandler: a.msgHandler, length: a.length, disableAutoFetch: a.disableAutoFetch, rangeChunkSize: a.rangeChunkSize }); this.pdfDocument = new s.PDFDocument(this, this.streamManager.getStream()) } async ensure(e, t, a) { try { const r = e[t]; return "function" == typeof r ? r.apply(e, a) : r } catch (r) { if (!(r instanceof n.MissingDataException)) throw r; await this.requestRange(r.begin, r.end); return this.ensure(e, t, a) } } requestRange(e, t) { return this.streamManager.requestRange(e, t) } requestLoadedStream() { this.streamManager.requestAllChunks() } sendProgressiveData(e) { this.streamManager.onReceiveData({ chunk: e }) } onLoadedStream() { return this.streamManager.onLoadedStream() } terminate(e) { this.streamManager.abort(e) } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.ChunkedStreamManager = t.ChunkedStream = void 0; var r = a(2), i = a(7); class n { constructor(e, t, a) { this.bytes = new Uint8Array(e); this.start = 0; this.pos = 0; this.end = e; this.chunkSize = t; this.loadedChunks = []; this.numChunksLoaded = 0; this.numChunks = Math.ceil(e / t); this.manager = a; this.progressiveDataLength = 0; this.lastSuccessfulEnsureByteChunk = -1 } getMissingChunks() { const e = []; for (let t = 0, a = this.numChunks; t < a; ++t)this.loadedChunks[t] || e.push(t); return e } getBaseStreams() { return [this] } allChunksLoaded() { return this.numChunksLoaded === this.numChunks } onReceiveData(e, t) { const a = this.chunkSize; if (e % a != 0) throw new Error(`Bad begin offset: ${e}`); const r = e + t.byteLength; if (r % a != 0 && r !== this.bytes.length) throw new Error(`Bad end offset: ${r}`); this.bytes.set(new Uint8Array(t), e); const i = Math.floor(e / a), n = Math.floor((r - 1) / a) + 1; for (let e = i; e < n; ++e)if (!this.loadedChunks[e]) { this.loadedChunks[e] = !0; ++this.numChunksLoaded } } onReceiveProgressiveData(e) { let t = this.progressiveDataLength; const a = Math.floor(t / this.chunkSize); this.bytes.set(new Uint8Array(e), t); t += e.byteLength; this.progressiveDataLength = t; const r = t >= this.end ? this.numChunks : Math.floor(t / this.chunkSize); for (let e = a; e < r; ++e)if (!this.loadedChunks[e]) { this.loadedChunks[e] = !0; ++this.numChunksLoaded } } ensureByte(e) { if (e < this.progressiveDataLength) return; const t = Math.floor(e / this.chunkSize); if (t !== this.lastSuccessfulEnsureByteChunk) { if (!this.loadedChunks[t]) throw new i.MissingDataException(e, e + 1); this.lastSuccessfulEnsureByteChunk = t } } ensureRange(e, t) { if (e >= t) return; if (t <= this.progressiveDataLength) return; const a = this.chunkSize, r = Math.floor(e / a), n = Math.floor((t - 1) / a) + 1; for (let a = r; a < n; ++a)if (!this.loadedChunks[a]) throw new i.MissingDataException(e, t) } nextEmptyChunk(e) { const t = this.numChunks; for (let a = 0; a < t; ++a) { const r = (e + a) % t; if (!this.loadedChunks[r]) return r } return null } hasChunk(e) { return !!this.loadedChunks[e] } get length() { return this.end - this.start } get isEmpty() { return 0 === this.length } getByte() { const e = this.pos; if (e >= this.end) return -1; e >= this.progressiveDataLength && this.ensureByte(e); return this.bytes[this.pos++] } getUint16() { const e = this.getByte(), t = this.getByte(); return -1 === e || -1 === t ? -1 : (e << 8) + t } getInt32() { return (this.getByte() << 24) + (this.getByte() << 16) + (this.getByte() << 8) + this.getByte() } getBytes(e, t = !1) { const a = this.bytes, r = this.pos, i = this.end; if (!e) { i > this.progressiveDataLength && this.ensureRange(r, i); const e = a.subarray(r, i); return t ? new Uint8ClampedArray(e) : e } let n = r + e; n > i && (n = i); n > this.progressiveDataLength && this.ensureRange(r, n); this.pos = n; const s = a.subarray(r, n); return t ? new Uint8ClampedArray(s) : s } peekByte() { const e = this.getByte(); -1 !== e && this.pos--; return e } peekBytes(e, t = !1) { const a = this.getBytes(e, t); this.pos -= a.length; return a } getByteRange(e, t) { e < 0 && (e = 0); t > this.end && (t = this.end); t > this.progressiveDataLength && this.ensureRange(e, t); return this.bytes.subarray(e, t) } skip(e) { e || (e = 1); this.pos += e } reset() { this.pos = this.start } moveStart() { this.start = this.pos } makeSubStream(e, t, a) { t ? e + t > this.progressiveDataLength && this.ensureRange(e, e + t) : e >= this.progressiveDataLength && this.ensureByte(e); function r() { } r.prototype = Object.create(this); r.prototype.getMissingChunks = function () { const e = this.chunkSize, t = Math.floor(this.start / e), a = Math.floor((this.end - 1) / e) + 1, r = []; for (let e = t; e < a; ++e)this.loadedChunks[e] || r.push(e); return r }; r.prototype.allChunksLoaded = function () { return this.numChunksLoaded === this.numChunks || 0 === this.getMissingChunks().length }; const i = new r; i.pos = i.start = e; i.end = e + t || this.end; i.dict = a; return i } } t.ChunkedStream = n; t.ChunkedStreamManager = class { constructor(e, t) { this.length = t.length; this.chunkSize = t.rangeChunkSize; this.stream = new n(this.length, this.chunkSize, this); this.pdfNetworkStream = e; this.disableAutoFetch = t.disableAutoFetch; this.msgHandler = t.msgHandler; this.currRequestId = 0; this.chunksNeededByRequest = Object.create(null); this.requestsByChunk = Object.create(null); this.promisesByRequest = Object.create(null); this.progressiveDataLength = 0; this.aborted = !1; this._loadedStreamCapability = (0, r.createPromiseCapability)() } onLoadedStream() { return this._loadedStreamCapability.promise } sendRequest(e, t) { const a = this.pdfNetworkStream.getRangeReader(e, t); a.isStreamingSupported || (a.onProgress = this.onProgress.bind(this)); let i = [], n = 0; new Promise((e, t) => { const s = o => { try { if (!o.done) { const e = o.value; i.push(e); n += (0, r.arrayByteLength)(e); a.isStreamingSupported && this.onProgress({ loaded: n }); a.read().then(s, t); return } const c = (0, r.arraysToBytes)(i); i = null; e(c) } catch (e) { t(e) } }; a.read().then(s, t) }).then(t => { this.aborted || this.onReceiveData({ chunk: t, begin: e }) }) } requestAllChunks() { const e = this.stream.getMissingChunks(); this._requestChunks(e); return this._loadedStreamCapability.promise } _requestChunks(e) { const t = this.currRequestId++, a = Object.create(null); this.chunksNeededByRequest[t] = a; for (const t of e) this.stream.hasChunk(t) || (a[t] = !0); if ((0, r.isEmptyObj)(a)) return Promise.resolve(); const i = (0, r.createPromiseCapability)(); this.promisesByRequest[t] = i; const n = []; for (let e in a) { e |= 0; if (!(e in this.requestsByChunk)) { this.requestsByChunk[e] = []; n.push(e) } this.requestsByChunk[e].push(t) } if (!n.length) return i.promise; const s = this.groupChunks(n); for (const e of s) { const t = e.beginChunk * this.chunkSize, a = Math.min(e.endChunk * this.chunkSize, this.length); this.sendRequest(t, a) } return i.promise } getStream() { return this.stream } requestRange(e, t) { t = Math.min(t, this.length); const a = this.getBeginChunk(e), r = this.getEndChunk(t), i = []; for (let e = a; e < r; ++e)i.push(e); return this._requestChunks(i) } requestRanges(e = []) { const t = []; for (const a of e) { const e = this.getBeginChunk(a.begin), r = this.getEndChunk(a.end); for (let a = e; a < r; ++a)t.includes(a) || t.push(a) } t.sort((function (e, t) { return e - t })); return this._requestChunks(t) } groupChunks(e) { const t = []; let a = -1, r = -1; for (let i = 0, n = e.length; i < n; ++i) { const n = e[i]; a < 0 && (a = n); if (r >= 0 && r + 1 !== n) { t.push({ beginChunk: a, endChunk: r + 1 }); a = n } i + 1 === e.length && t.push({ beginChunk: a, endChunk: n + 1 }); r = n } return t } onProgress(e) { this.msgHandler.send("DocProgress", { loaded: this.stream.numChunksLoaded * this.chunkSize + e.loaded, total: this.length }) } onReceiveData(e) { const t = e.chunk, a = void 0 === e.begin, i = a ? this.progressiveDataLength : e.begin, n = i + t.byteLength, s = Math.floor(i / this.chunkSize), o = n < this.length ? Math.floor(n / this.chunkSize) : Math.ceil(n / this.chunkSize); if (a) { this.stream.onReceiveProgressiveData(t); this.progressiveDataLength = n } else this.stream.onReceiveData(i, t); this.stream.allChunksLoaded() && this._loadedStreamCapability.resolve(this.stream); const c = []; for (let e = s; e < o; ++e) { const t = this.requestsByChunk[e] || []; delete this.requestsByChunk[e]; for (const a of t) { const t = this.chunksNeededByRequest[a]; e in t && delete t[e]; (0, r.isEmptyObj)(t) && c.push(a) } } if (!this.disableAutoFetch && (0, r.isEmptyObj)(this.requestsByChunk)) { let e; if (1 === this.stream.numChunksLoaded) { const t = this.stream.numChunks - 1; this.stream.hasChunk(t) || (e = t) } else e = this.stream.nextEmptyChunk(o); Number.isInteger(e) && this._requestChunks([e]) } for (const e of c) { const t = this.promisesByRequest[e]; delete this.promisesByRequest[e]; t.resolve() } this.msgHandler.send("DocProgress", { loaded: this.stream.numChunksLoaded * this.chunkSize, total: this.length }) } onError(e) { this._loadedStreamCapability.reject(e) } getBeginChunk(e) { return Math.floor(e / this.chunkSize) } getEndChunk(e) { return Math.floor((e - 1) / this.chunkSize) + 1 } abort(e) { this.aborted = !0; this.pdfNetworkStream && this.pdfNetworkStream.cancelAllRequests(e); for (const t in this.promisesByRequest) this.promisesByRequest[t].reject(e) } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getLookupTableFactory = function (e) { let t; return function () { if (e) { t = Object.create(null); e(t); e = null } return t } }; t.getInheritableProperty = function ({ dict: e, key: t, getArray: a = !1, stopWhenFound: i = !0 }) { let n, s = 0; for (; e;) { const o = a ? e.getArray(t) : e.get(t); if (void 0 !== o) { if (i) return o; n || (n = []); n.push(o) } if (++s > 100) { (0, r.warn)(`getInheritableProperty: maximum loop count exceeded for "${t}"`); break } e = e.get("Parent") } return n }; t.toRomanNumerals = function (e, t = !1) { (0, r.assert)(Number.isInteger(e) && e > 0, "The number should be a positive integer."); const a = []; let i; for (; e >= 1e3;) { e -= 1e3; a.push("M") } i = e / 100 | 0; e %= 100; a.push(o[i]); i = e / 10 | 0; e %= 10; a.push(o[10 + i]); a.push(o[20 + e]); const n = a.join(""); return t ? n.toLowerCase() : n }; t.log2 = function (e) { if (e <= 0) return 0; return Math.ceil(Math.log2(e)) }; t.readInt8 = function (e, t) { return e[t] << 24 >> 24 }; t.readUint16 = function (e, t) { return e[t] << 8 | e[t + 1] }; t.readUint32 = function (e, t) { return (e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3]) >>> 0 }; t.isWhiteSpace = function (e) { return 32 === e || 9 === e || 13 === e || 10 === e }; t.XRefParseException = t.XRefEntryException = t.MissingDataException = void 0; var r = a(2); class i extends r.BaseException { constructor(e, t) { super(`Missing data [${e}, ${t})`); this.begin = e; this.end = t } } t.MissingDataException = i; class n extends r.BaseException { } t.XRefEntryException = n; class s extends r.BaseException { } t.XRefParseException = s; const o = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"] }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PDFDocument = t.Page = void 0; var r = a(2), i = a(9), n = a(4), s = a(7), o = a(11), c = a(23), l = a(21), h = a(10), u = a(24), d = a(25), f = a(39); const g = [0, 0, 612, 792]; function m(e, t) { return "display" === t && e.viewable || "print" === t && e.printable } class p { constructor({ pdfManager: e, xref: t, pageIndex: a, pageDict: r, ref: i, fontCache: n, builtInCMapCache: s, pdfFunctionFactory: o }) { this.pdfManager = e; this.pageIndex = a; this.pageDict = r; this.xref = t; this.ref = i; this.fontCache = n; this.builtInCMapCache = s; this.pdfFunctionFactory = o; this.evaluatorOptions = e.evaluatorOptions; this.resourcesPromise = null; const c = { obj: 0 }; this.idFactory = { createObjId: () => `p${a}_${++c.obj}`, getDocId: () => `g_${e.docId}` } } _getInheritableProperty(e, t = !1) { const a = (0, s.getInheritableProperty)({ dict: this.pageDict, key: e, getArray: t, stopWhenFound: !1 }); return Array.isArray(a) ? 1 !== a.length && (0, n.isDict)(a[0]) ? n.Dict.merge(this.xref, a) : a[0] : a } get content() { return this.pageDict.get("Contents") } get resources() { return (0, r.shadow)(this, "resources", this._getInheritableProperty("Resources") || n.Dict.empty) } _getBoundingBox(e) { const t = this._getInheritableProperty(e, !0); if (Array.isArray(t) && 4 === t.length) { if (t[2] - t[0] != 0 && t[3] - t[1] != 0) return t; (0, r.warn)(`Empty /${e} entry.`) } return null } get mediaBox() { return (0, r.shadow)(this, "mediaBox", this._getBoundingBox("MediaBox") || g) } get cropBox() { return (0, r.shadow)(this, "cropBox", this._getBoundingBox("CropBox") || this.mediaBox) } get userUnit() { let e = this.pageDict.get("UserUnit"); (!(0, r.isNum)(e) || e <= 0) && (e = 1); return (0, r.shadow)(this, "userUnit", e) } get view() { const { cropBox: e, mediaBox: t } = this; let a; if (e === t || (0, r.isArrayEqual)(e, t)) a = t; else { const i = r.Util.intersect(e, t); i && i[2] - i[0] != 0 && i[3] - i[1] != 0 ? a = i : (0, r.warn)("Empty /CropBox and /MediaBox intersection.") } return (0, r.shadow)(this, "view", a || t) } get rotate() { let e = this._getInheritableProperty("Rotate") || 0; e % 90 != 0 ? e = 0 : e >= 360 ? e %= 360 : e < 0 && (e = (e % 360 + 360) % 360); return (0, r.shadow)(this, "rotate", e) } getContentStream() { const e = this.content; let t; if (Array.isArray(e)) { const a = this.xref, r = []; for (const t of e) r.push(a.fetchIfRef(t)); t = new o.StreamsSequenceStream(r) } else t = (0, n.isStream)(e) ? e : new o.NullStream; return t } loadResources(e) { this.resourcesPromise || (this.resourcesPromise = this.pdfManager.ensure(this, "resources")); return this.resourcesPromise.then(() => new i.ObjectLoader(this.resources, e, this.xref).load()) } getOperatorList({ handler: e, sink: t, task: a, intent: i, renderInteractiveForms: n }) { const s = this.pdfManager.ensure(this, "getContentStream"), o = this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"]), c = new d.PartialEvaluator({ xref: this.xref, handler: e, pageIndex: this.pageIndex, idFactory: this.idFactory, fontCache: this.fontCache, builtInCMapCache: this.builtInCMapCache, options: this.evaluatorOptions, pdfFunctionFactory: this.pdfFunctionFactory }), l = Promise.all([s, o]).then(([r]) => { const n = new u.OperatorList(i, t, this.pageIndex); e.send("StartRenderPage", { transparency: c.hasBlendModes(this.resources), pageIndex: this.pageIndex, intent: i }); return c.getOperatorList({ stream: r, task: a, resources: this.resources, operatorList: n }).then((function () { return n })) }); return Promise.all([l, this._parsedAnnotations]).then((function ([e, t]) { if (0 === t.length) { e.flush(!0); return { length: e.totalLength } } const s = []; for (const e of t) m(e, i) && s.push(e.getOperatorList(c, a, n)); return Promise.all(s).then((function (t) { e.addOp(r.OPS.beginAnnotations, []); for (const a of t) e.addOpList(a); e.addOp(r.OPS.endAnnotations, []); e.flush(!0); return { length: e.totalLength } })) })) } extractTextContent({ handler: e, task: t, normalizeWhitespace: a, sink: r, combineTextItems: i }) { const n = this.pdfManager.ensure(this, "getContentStream"), s = this.loadResources(["ExtGState", "XObject", "Font"]); return Promise.all([n, s]).then(([n]) => new d.PartialEvaluator({ xref: this.xref, handler: e, pageIndex: this.pageIndex, idFactory: this.idFactory, fontCache: this.fontCache, builtInCMapCache: this.builtInCMapCache, options: this.evaluatorOptions, pdfFunctionFactory: this.pdfFunctionFactory }).getTextContent({ stream: n, task: t, resources: this.resources, normalizeWhitespace: a, combineTextItems: i, sink: r })) } getAnnotationsData(e) { return this._parsedAnnotations.then((function (t) { const a = []; for (let r = 0, i = t.length; r < i; r++)e && !m(t[r], e) || a.push(t[r].data); return a })) } get annotations() { return (0, r.shadow)(this, "annotations", this._getInheritableProperty("Annots") || []) } get _parsedAnnotations() { const e = this.pdfManager.ensure(this, "annotations").then(() => { const e = this.annotations, t = []; for (let a = 0, r = e.length; a < r; a++)t.push(c.AnnotationFactory.create(this.xref, e[a], this.pdfManager, this.idFactory)); return Promise.all(t).then((function (e) { return e.filter((function (e) { return !!e })) }), (function (e) { (0, r.warn)(`_parsedAnnotations: "${e}".`); return [] })) }); return (0, r.shadow)(this, "_parsedAnnotations", e) } } t.Page = p; const b = new Uint8Array([37, 80, 68, 70, 45]), y = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]), v = new Uint8Array([101, 110, 100, 111, 98, 106]), w = /^[1-9]\.[0-9]$/; function k(e, t, a = 1024, r = !1) { const i = t.length, n = e.peekBytes(a), s = n.length - i; if (s <= 0) return !1; if (r) { const a = i - 1; let r = n.length - 1; for (; r >= a;) { let s = 0; for (; s < i && n[r - s] === t[a - s];)s++; if (s >= i) { e.pos += r - a; return !0 } r-- } } else { let a = 0; for (; a <= s;) { let r = 0; for (; r < i && n[a + r] === t[r];)r++; if (r >= i) { e.pos += a; return !0 } a++ } } return !1 } t.PDFDocument = class { constructor(e, t) { let a; if ((0, n.isStream)(t)) a = t; else { if (!(0, r.isArrayBuffer)(t)) throw new Error("PDFDocument: Unknown argument type"); a = new o.Stream(t) } if (a.length <= 0) throw new r.InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes."); this.pdfManager = e; this.stream = a; this.xref = new i.XRef(a, e); this.pdfFunctionFactory = new f.PDFFunctionFactory({ xref: this.xref, isEvalSupported: e.evaluatorOptions.isEvalSupported }); this._pagePromises = [] } parse(e) { this.setup(e); const t = this.catalog.catDict.get("Version"); (0, n.isName)(t) && (this.pdfFormatVersion = t.name); try { this.acroForm = this.catalog.catDict.get("AcroForm"); if (this.acroForm) { this.xfa = this.acroForm.get("XFA"); const e = this.acroForm.get("Fields"); Array.isArray(e) && 0 !== e.length || this.xfa || (this.acroForm = null) } } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("Cannot fetch AcroForm entry; assuming no AcroForms are present"); this.acroForm = null } try { const e = this.catalog.catDict.get("Collection"); (0, n.isDict)(e) && e.getKeys().length > 0 && (this.collection = e) } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("Cannot fetch Collection dictionary.") } } get linearization() { let e = null; try { e = h.Linearization.create(this.stream) } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)(e) } return (0, r.shadow)(this, "linearization", e) } get startXRef() { const e = this.stream; let t = 0; if (this.linearization) { e.reset(); k(e, v) && (t = e.pos + 6 - e.start) } else { const a = 1024, r = y.length; let i = !1, n = e.end; for (; !i && n > 0;) { n -= a - r; n < 0 && (n = 0); e.pos = n; i = k(e, y, a, !0) } if (i) { e.skip(9); let a; do { a = e.getByte() } while ((0, s.isWhiteSpace)(a)); let r = ""; for (; a >= 32 && a <= 57;) { r += String.fromCharCode(a); a = e.getByte() } t = parseInt(r, 10); isNaN(t) && (t = 0) } } return (0, r.shadow)(this, "startXRef", t) } checkHeader() { const e = this.stream; e.reset(); if (!k(e, b)) return; e.moveStart(); let t, a = ""; for (; (t = e.getByte()) > 32 && !(a.length >= 12);)a += String.fromCharCode(t); this.pdfFormatVersion || (this.pdfFormatVersion = a.substring(5)) } parseStartXRef() { this.xref.setStartXRef(this.startXRef) } setup(e) { this.xref.parse(e); this.catalog = new i.Catalog(this.pdfManager, this.xref) } get numPages() { const e = this.linearization, t = e ? e.numPages : this.catalog.numPages; return (0, r.shadow)(this, "numPages", t) } get documentInfo() { const e = { Title: r.isString, Author: r.isString, Subject: r.isString, Keywords: r.isString, Creator: r.isString, Producer: r.isString, CreationDate: r.isString, ModDate: r.isString, Trapped: n.isName }; let t = this.pdfFormatVersion; if ("string" != typeof t || !w.test(t)) { (0, r.warn)(`Invalid PDF header version number: ${t}`); t = null } const a = { PDFFormatVersion: t, IsLinearized: !!this.linearization, IsAcroFormPresent: !!this.acroForm, IsXFAPresent: !!this.xfa, IsCollectionPresent: !!this.collection }; let i; try { i = this.xref.trailer.get("Info") } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("The document information dictionary is invalid.") } if ((0, n.isDict)(i)) for (const t of i.getKeys()) { const s = i.get(t); if (e[t]) e[t](s) ? a[t] = "string" != typeof s ? s : (0, r.stringToPDFString)(s) : (0, r.info)(`Bad value in document info for "${t}".`); else if ("string" == typeof t) { let e; if ((0, r.isString)(s)) e = (0, r.stringToPDFString)(s); else { if (!((0, n.isName)(s) || (0, r.isNum)(s) || (0, r.isBool)(s))) { (0, r.info)(`Unsupported value in document info for (custom) "${t}".`); continue } e = s } a.Custom || (a.Custom = Object.create(null)); a.Custom[t] = e } } return (0, r.shadow)(this, "documentInfo", a) } get fingerprint() { let e; const t = this.xref.trailer.get("ID"); e = Array.isArray(t) && t[0] && (0, r.isString)(t[0]) && "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" !== t[0] ? (0, r.stringToBytes)(t[0]) : (0, l.calculateMD5)(this.stream.getByteRange(0, 1024), 0, 1024); const a = []; for (let t = 0, r = e.length; t < r; t++) { const r = e[t].toString(16); a.push(r.padStart(2, "0")) } return (0, r.shadow)(this, "fingerprint", a.join("")) } _getLinearizationPage(e) { const { catalog: t, linearization: a } = this; (0, r.assert)(a && a.pageFirst === e); const i = n.Ref.get(a.objectNumberFirst, 0); return this.xref.fetchAsync(i).then(e => { if ((0, n.isDict)(e, "Page") || (0, n.isDict)(e) && !e.has("Type") && e.has("Contents")) { i && !t.pageKidsCountCache.has(i) && t.pageKidsCountCache.put(i, 1); return [e, i] } throw new r.FormatError("The Linearization dictionary doesn't point to a valid Page dictionary.") }).catch(a => { (0, r.info)(a); return t.getPageDict(e) }) } getPage(e) { if (void 0 !== this._pagePromises[e]) return this._pagePromises[e]; const { catalog: t, linearization: a } = this, r = a && a.pageFirst === e ? this._getLinearizationPage(e) : t.getPageDict(e); return this._pagePromises[e] = r.then(([a, r]) => new p({ pdfManager: this.pdfManager, xref: this.xref, pageIndex: e, pageDict: a, ref: r, fontCache: t.fontCache, builtInCMapCache: t.builtInCMapCache, pdfFunctionFactory: this.pdfFunctionFactory })) } checkFirstPage() { return this.getPage(0).catch(async e => { if (e instanceof s.XRefEntryException) { this._pagePromises.length = 0; await this.cleanup(); throw new s.XRefParseException } }) } fontFallback(e, t) { return this.catalog.fontFallback(e, t) } async cleanup() { return this.catalog ? this.catalog.cleanup() : (0, n.clearPrimitiveCaches)() } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.FileSpec = t.XRef = t.ObjectLoader = t.Catalog = void 0; var r = a(2), i = a(4), n = a(10), s = a(7), o = a(21), c = a(22); function l(e) { return (0, i.isDict)(e) ? e.get("D") : e } class h { constructor(e, t) { this.pdfManager = e; this.xref = t; this.catDict = t.getCatalogObj(); if (!(0, i.isDict)(this.catDict)) throw new r.FormatError("Catalog object is not a dictionary."); this.fontCache = new i.RefSetCache; this.builtInCMapCache = new Map; this.pageKidsCountCache = new i.RefSetCache } get metadata() { const e = this.catDict.getRaw("Metadata"); if (!(0, i.isRef)(e)) return (0, r.shadow)(this, "metadata", null); const t = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata), a = this.xref.fetch(e, t); let n; if (a && (0, i.isDict)(a.dict)) { const e = a.dict.get("Type"), t = a.dict.get("Subtype"); if ((0, i.isName)(e, "Metadata") && (0, i.isName)(t, "XML")) try { n = (0, r.stringToUTF8String)((0, r.bytesToString)(a.getBytes())) } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("Skipping invalid metadata.") } } return (0, r.shadow)(this, "metadata", n) } get toplevelPagesDict() { const e = this.catDict.get("Pages"); if (!(0, i.isDict)(e)) throw new r.FormatError("Invalid top-level pages dictionary."); return (0, r.shadow)(this, "toplevelPagesDict", e) } get documentOutline() { let e = null; try { e = this._readDocumentOutline() } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)("Unable to read document outline.") } return (0, r.shadow)(this, "documentOutline", e) } _readDocumentOutline() { let e = this.catDict.get("Outlines"); if (!(0, i.isDict)(e)) return null; e = e.getRaw("First"); if (!(0, i.isRef)(e)) return null; const t = { items: [] }, a = [{ obj: e, parent: t }], n = new i.RefSet; n.put(e); const s = this.xref, o = new Uint8ClampedArray(3); for (; a.length > 0;) { const t = a.shift(), l = s.fetchIfRef(t.obj); if (null === l) continue; if (!l.has("Title")) throw new r.FormatError("Invalid outline item encountered."); const u = { url: null, dest: null }; h.parseDestDictionary({ destDict: l, resultObj: u, docBaseUrl: this.pdfManager.docBaseUrl }); const d = l.get("Title"), f = l.get("F") || 0, g = l.getArray("C"), m = l.get("Count"); let p = o; !Array.isArray(g) || 3 !== g.length || 0 === g[0] && 0 === g[1] && 0 === g[2] || (p = c.ColorSpace.singletons.rgb.getRgb(g, 0)); const b = { dest: u.dest, url: u.url, unsafeUrl: u.unsafeUrl, newWindow: u.newWindow, title: (0, r.stringToPDFString)(d), color: p, count: Number.isInteger(m) ? m : void 0, bold: !!(2 & f), italic: !!(1 & f), items: [] }; t.parent.items.push(b); e = l.getRaw("First"); if ((0, i.isRef)(e) && !n.has(e)) { a.push({ obj: e, parent: b }); n.put(e) } e = l.getRaw("Next"); if ((0, i.isRef)(e) && !n.has(e)) { a.push({ obj: e, parent: t.parent }); n.put(e) } } return t.items.length > 0 ? t.items : null } get permissions() { let e = null; try { e = this._readPermissions() } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)("Unable to read permissions.") } return (0, r.shadow)(this, "permissions", e) } _readPermissions() { const e = this.xref.trailer.get("Encrypt"); if (!(0, i.isDict)(e)) return null; let t = e.get("P"); if (!(0, r.isNum)(t)) return null; t += 2 ** 32; const a = []; for (const e in r.PermissionFlag) { const i = r.PermissionFlag[e]; t & i && a.push(i) } return a } get numPages() { const e = this.toplevelPagesDict.get("Count"); if (!Number.isInteger(e)) throw new r.FormatError("Page count in top-level pages dictionary is not an integer."); return (0, r.shadow)(this, "numPages", e) } get destinations() { const e = this._readDests(), t = Object.create(null); if (e instanceof f) { const a = e.getAll(); for (const e in a) t[e] = l(a[e]) } else e instanceof i.Dict && e.forEach((function (e, a) { a && (t[e] = l(a)) })); return (0, r.shadow)(this, "destinations", t) } getDestination(e) { const t = this._readDests(); return t instanceof f || t instanceof i.Dict ? l(t.get(e) || null) : null } _readDests() { const e = this.catDict.get("Names"); return e && e.has("Dests") ? new f(e.getRaw("Dests"), this.xref) : this.catDict.has("Dests") ? this.catDict.get("Dests") : void 0 } get pageLabels() { let e = null; try { e = this._readPageLabels() } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)("Unable to read page labels.") } return (0, r.shadow)(this, "pageLabels", e) } _readPageLabels() { const e = this.catDict.getRaw("PageLabels"); if (!e) return null; const t = new Array(this.numPages); let a = null, n = ""; const o = new g(e, this.xref).getAll(); let c = "", l = 1; for (let e = 0, h = this.numPages; e < h; e++) { if (e in o) { const t = o[e]; if (!(0, i.isDict)(t)) throw new r.FormatError("PageLabel is not a dictionary."); if (t.has("Type") && !(0, i.isName)(t.get("Type"), "PageLabel")) throw new r.FormatError("Invalid type in PageLabel dictionary."); if (t.has("S")) { const e = t.get("S"); if (!(0, i.isName)(e)) throw new r.FormatError("Invalid style in PageLabel dictionary."); a = e.name } else a = null; if (t.has("P")) { const e = t.get("P"); if (!(0, r.isString)(e)) throw new r.FormatError("Invalid prefix in PageLabel dictionary."); n = (0, r.stringToPDFString)(e) } else n = ""; if (t.has("St")) { const e = t.get("St"); if (!(Number.isInteger(e) && e >= 1)) throw new r.FormatError("Invalid start in PageLabel dictionary."); l = e } else l = 1 } switch (a) { case "D": c = l; break; case "R": case "r": c = (0, s.toRomanNumerals)(l, "r" === a); break; case "A": case "a": const e = 26, t = 65, i = 97, n = "a" === a ? i : t, o = l - 1, h = String.fromCharCode(n + o % e), u = []; for (let t = 0, a = o / e | 0; t <= a; t++)u.push(h); c = u.join(""); break; default: if (a) throw new r.FormatError(`Invalid style "${a}" in PageLabel dictionary.`); c = "" }t[e] = n + c; l++ } return t } get pageLayout() { const e = this.catDict.get("PageLayout"); let t = ""; if ((0, i.isName)(e)) switch (e.name) { case "SinglePage": case "OneColumn": case "TwoColumnLeft": case "TwoColumnRight": case "TwoPageLeft": case "TwoPageRight": t = e.name }return (0, r.shadow)(this, "pageLayout", t) } get pageMode() { const e = this.catDict.get("PageMode"); let t = "UseNone"; if ((0, i.isName)(e)) switch (e.name) { case "UseNone": case "UseOutlines": case "UseThumbs": case "FullScreen": case "UseOC": case "UseAttachments": t = e.name }return (0, r.shadow)(this, "pageMode", t) } get viewerPreferences() { const e = { HideToolbar: r.isBool, HideMenubar: r.isBool, HideWindowUI: r.isBool, FitWindow: r.isBool, CenterWindow: r.isBool, DisplayDocTitle: r.isBool, NonFullScreenPageMode: i.isName, Direction: i.isName, ViewArea: i.isName, ViewClip: i.isName, PrintArea: i.isName, PrintClip: i.isName, PrintScaling: i.isName, Duplex: i.isName, PickTrayByPDFSize: r.isBool, PrintPageRange: Array.isArray, NumCopies: Number.isInteger }, t = this.catDict.get("ViewerPreferences"), a = Object.create(null); if ((0, i.isDict)(t)) for (const i in e) { if (!t.has(i)) continue; const n = t.get(i); if (!e[i](n)) { (0, r.info)(`Bad value in ViewerPreferences for "${i}".`); continue } let s; switch (i) { case "NonFullScreenPageMode": switch (n.name) { case "UseNone": case "UseOutlines": case "UseThumbs": case "UseOC": s = n.name; break; default: s = "UseNone" }break; case "Direction": switch (n.name) { case "L2R": case "R2L": s = n.name; break; default: s = "L2R" }break; case "ViewArea": case "ViewClip": case "PrintArea": case "PrintClip": switch (n.name) { case "MediaBox": case "CropBox": case "BleedBox": case "TrimBox": case "ArtBox": s = n.name; break; default: s = "CropBox" }break; case "PrintScaling": switch (n.name) { case "None": case "AppDefault": s = n.name; break; default: s = "AppDefault" }break; case "Duplex": switch (n.name) { case "Simplex": case "DuplexFlipShortEdge": case "DuplexFlipLongEdge": s = n.name; break; default: s = "None" }break; case "PrintPageRange": if (n.length % 2 != 0) break; n.every((e, t, a) => Number.isInteger(e) && e > 0 && (0 === t || e >= a[t - 1]) && e <= this.numPages) && (s = n); break; case "NumCopies": n > 0 && (s = n); break; default: (0, r.assert)("boolean" == typeof n); s = n }void 0 !== s ? a[i] = s : (0, r.info)(`Bad value in ViewerPreferences for "${i}".`) } return (0, r.shadow)(this, "viewerPreferences", a) } get openAction() { const e = this.catDict.get("OpenAction"); let t = null; if ((0, i.isDict)(e)) { const a = new i.Dict(this.xref); a.set("A", e); const r = { url: null, dest: null, action: null }; h.parseDestDictionary({ destDict: a, resultObj: r }); if (Array.isArray(r.dest)) { t || (t = Object.create(null)); t.dest = r.dest } else if (r.action) { t || (t = Object.create(null)); t.action = r.action } } else if (Array.isArray(e)) { t || (t = Object.create(null)); t.dest = e } return (0, r.shadow)(this, "openAction", t) } get attachments() { const e = this.catDict.get("Names"); let t = null; if (e && e.has("EmbeddedFiles")) { const a = new f(e.getRaw("EmbeddedFiles"), this.xref).getAll(); for (const e in a) { const i = new m(a[e], this.xref); t || (t = Object.create(null)); t[(0, r.stringToPDFString)(e)] = i.serializable } } return (0, r.shadow)(this, "attachments", t) } get javaScript() { const e = this.catDict.get("Names"); let t = null; function a(e) { const a = e.get("S"); if (!(0, i.isName)(a, "JavaScript")) return; let n = e.get("JS"); if ((0, i.isStream)(n)) n = (0, r.bytesToString)(n.getBytes()); else if (!(0, r.isString)(n)) return; t || (t = []); t.push((0, r.stringToPDFString)(n)) } if (e && e.has("JavaScript")) { const t = new f(e.getRaw("JavaScript"), this.xref).getAll(); for (const e in t) { const r = t[e]; (0, i.isDict)(r) && a(r) } } const n = this.catDict.get("OpenAction"); (0, i.isDict)(n) && (0, i.isName)(n.get("S"), "JavaScript") && a(n); return (0, r.shadow)(this, "javaScript", t) } fontFallback(e, t) { const a = []; this.fontCache.forEach((function (e) { a.push(e) })); return Promise.all(a).then(a => { for (const r of a) if (r.loadedName === e) { r.fallback(t); return } }) } cleanup() { (0, i.clearPrimitiveCaches)(); this.pageKidsCountCache.clear(); const e = []; this.fontCache.forEach((function (t) { e.push(t) })); return Promise.all(e).then(e => { for (const { dict: t } of e) delete t.translated; this.fontCache.clear(); this.builtInCMapCache.clear() }) } getPageDict(e) { const t = (0, r.createPromiseCapability)(), a = [this.catDict.getRaw("Pages")], n = new i.RefSet, s = this.xref, o = this.pageKidsCountCache; let c, l = 0; !function h() { for (; a.length;) { const u = a.pop(); if ((0, i.isRef)(u)) { c = o.get(u); if (c > 0 && l + c < e) { l += c; continue } if (n.has(u)) { t.reject(new r.FormatError("Pages tree contains circular reference.")); return } n.put(u); s.fetchAsync(u).then((function (r) { if ((0, i.isDict)(r, "Page") || (0, i.isDict)(r) && !r.has("Kids")) if (e === l) { u && !o.has(u) && o.put(u, 1); t.resolve([r, u]) } else { l++; h() } else { a.push(r); h() } }), t.reject); return } if (!(0, i.isDict)(u)) { t.reject(new r.FormatError("Page dictionary kid reference points to wrong type of object.")); return } c = u.get("Count"); if (Number.isInteger(c) && c >= 0) { const t = u.objId; t && !o.has(t) && o.put(t, c); if (l + c <= e) { l += c; continue } } const d = u.get("Kids"); if (!Array.isArray(d)) { if ((0, i.isName)(u.get("Type"), "Page") || !u.has("Type") && u.has("Contents")) { if (l === e) { t.resolve([u, null]); return } l++; continue } t.reject(new r.FormatError("Page dictionary kids object is not an array.")); return } for (let e = d.length - 1; e >= 0; e--)a.push(d[e]) } t.reject(new Error(`Page index ${e} not found.`)) }(); return t.promise } getPageIndex(e) { const t = this.xref; let a = 0; return function n(s) { return function (a) { let n, s = 0; return t.fetchAsync(a).then((function (t) { if ((0, i.isRefsEqual)(a, e) && !(0, i.isDict)(t, "Page") && (!(0, i.isDict)(t) || t.has("Type") || !t.has("Contents"))) throw new r.FormatError("The reference does not point to a /Page dictionary."); if (!t) return null; if (!(0, i.isDict)(t)) throw new r.FormatError("Node must be a dictionary."); n = t.getRaw("Parent"); return t.getAsync("Parent") })).then((function (e) { if (!e) return null; if (!(0, i.isDict)(e)) throw new r.FormatError("Parent must be a dictionary."); return e.getAsync("Kids") })).then((function (e) { if (!e) return null; const o = []; let c = !1; for (let n = 0, l = e.length; n < l; n++) { const l = e[n]; if (!(0, i.isRef)(l)) throw new r.FormatError("Kid must be a reference."); if ((0, i.isRefsEqual)(l, a)) { c = !0; break } o.push(t.fetchAsync(l).then((function (e) { if (!(0, i.isDict)(e)) throw new r.FormatError("Kid node must be a dictionary."); e.has("Count") ? s += e.get("Count") : s++ }))) } if (!c) throw new r.FormatError("Kid reference not found in parent's kids."); return Promise.all(o).then((function () { return [s, n] })) })) }(s).then((function (e) { if (!e) return a; const [t, r] = e; a += t; return n(r) })) }(e) } static parseDestDictionary(e) { const t = e.destDict; if (!(0, i.isDict)(t)) { (0, r.warn)("parseDestDictionary: `destDict` must be a dictionary."); return } const a = e.resultObj; if ("object" != typeof a) { (0, r.warn)("parseDestDictionary: `resultObj` must be an object."); return } const n = e.docBaseUrl || null; let s, o, c = t.get("A"); !(0, i.isDict)(c) && t.has("Dest") && (c = t.get("Dest")); if ((0, i.isDict)(c)) { const e = c.get("S"); if (!(0, i.isName)(e)) { (0, r.warn)("parseDestDictionary: Invalid type in Action dictionary."); return } const t = e.name; switch (t) { case "URI": s = c.get("URI"); (0, i.isName)(s) ? s = "/" + s.name : (0, r.isString)(s) && (s = function (e) { return e.startsWith("www.") ? `http://${e}` : e }(s)); break; case "GoTo": o = c.get("D"); break; case "Launch": case "GoToR": const e = c.get("F"); (0, i.isDict)(e) ? s = e.get("F") || null : (0, r.isString)(e) && (s = e); let n = c.get("D"); if (n) { (0, i.isName)(n) && (n = n.name); if ((0, r.isString)(s)) { const e = s.split("#")[0]; (0, r.isString)(n) ? s = e + "#" + n : Array.isArray(n) && (s = e + "#" + JSON.stringify(n)) } } const l = c.get("NewWindow"); (0, r.isBool)(l) && (a.newWindow = l); break; case "Named": const h = c.get("N"); (0, i.isName)(h) && (a.action = h.name); break; case "JavaScript": const u = c.get("JS"); let d; (0, i.isStream)(u) ? d = (0, r.bytesToString)(u.getBytes()) : (0, r.isString)(u) && (d = u); if (d) { const e = new RegExp("^\\s*(" + ["app.launchURL", "window.open"].join("|").split(".").join("\\.") + ")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))", "i").exec((0, r.stringToPDFString)(d)); if (e && e[2]) { s = e[2]; "true" === e[3] && "app.launchURL" === e[1] && (a.newWindow = !0); break } } default: (0, r.warn)(`parseDestDictionary: unsupported action type "${t}".`) } } else t.has("Dest") && (o = t.get("Dest")); if ((0, r.isString)(s)) { s = function (e) { try { return (0, r.stringToUTF8String)(e) } catch (t) { return e } }(s); const e = (0, r.createValidAbsoluteUrl)(s, n); e && (a.url = e.href); a.unsafeUrl = s } if (o) { (0, i.isName)(o) && (o = o.name); ((0, r.isString)(o) || Array.isArray(o)) && (a.dest = o) } } } t.Catalog = h; var u = function () { function e(e, t) { this.stream = e; this.pdfManager = t; this.entries = []; this.xrefstms = Object.create(null); this._cacheMap = new Map; this.stats = { streamTypes: Object.create(null), fontTypes: Object.create(null) } } e.prototype = { setStartXRef: function (e) { this.startXRefQueue = [e] }, parse: function (e) { var t; if (e) { (0, r.warn)("Indexing all PDF objects"); t = this.indexObjects() } else t = this.readXRef(); t.assignXref(this); this.trailer = t; let a, n; try { a = t.get("Encrypt") } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)(`XRef.parse - Invalid "Encrypt" reference: "${e}".`) } if ((0, i.isDict)(a)) { var c = t.get("ID"), l = c && c.length ? c[0] : ""; a.suppressEncryption = !0; this.encrypt = new o.CipherTransformFactory(a, l, this.pdfManager.password) } try { n = t.get("Root") } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)(`XRef.parse - Invalid "Root" reference: "${e}".`) } if (!(0, i.isDict)(n) || !n.has("Pages")) { if (!e) throw new s.XRefParseException; throw new r.FormatError("Invalid root reference") } this.root = n }, processXRefTable: function (e) { "tableState" in this || (this.tableState = { entryNum: 0, streamPos: e.lexer.stream.pos, parserBuf1: e.buf1, parserBuf2: e.buf2 }); var t = this.readXRefTable(e); if (!(0, i.isCmd)(t, "trailer")) throw new r.FormatError("Invalid XRef table: could not find trailer dictionary"); var a = e.getObj(); !(0, i.isDict)(a) && a.dict && (a = a.dict); if (!(0, i.isDict)(a)) throw new r.FormatError("Invalid XRef table: could not parse trailer dictionary"); delete this.tableState; return a }, readXRefTable: function (e) { var t, a = e.lexer.stream, n = this.tableState; a.pos = n.streamPos; e.buf1 = n.parserBuf1; e.buf2 = n.parserBuf2; for (; ;) { if (!("firstEntryNum" in n) || !("entryCount" in n)) { if ((0, i.isCmd)(t = e.getObj(), "trailer")) break; n.firstEntryNum = t; n.entryCount = e.getObj() } var s = n.firstEntryNum, o = n.entryCount; if (!Number.isInteger(s) || !Number.isInteger(o)) throw new r.FormatError("Invalid XRef table: wrong types in subsection header"); for (var c = n.entryNum; c < o; c++) { n.streamPos = a.pos; n.entryNum = c; n.parserBuf1 = e.buf1; n.parserBuf2 = e.buf2; var l = {}; l.offset = e.getObj(); l.gen = e.getObj(); var h = e.getObj(); if (h instanceof i.Cmd) switch (h.cmd) { case "f": l.free = !0; break; case "n": l.uncompressed = !0 }if (!Number.isInteger(l.offset) || !Number.isInteger(l.gen) || !l.free && !l.uncompressed) throw new r.FormatError(`Invalid entry in XRef subsection: ${s}, ${o}`); 0 === c && l.free && 1 === s && (s = 0); this.entries[c + s] || (this.entries[c + s] = l) } n.entryNum = 0; n.streamPos = a.pos; n.parserBuf1 = e.buf1; n.parserBuf2 = e.buf2; delete n.firstEntryNum; delete n.entryCount } if (this.entries[0] && !this.entries[0].free) throw new r.FormatError("Invalid XRef table: unexpected first object"); return t }, processXRefStream: function (e) { if (!("streamState" in this)) { var t = e.dict, a = t.get("W"), r = t.get("Index"); r || (r = [0, t.get("Size")]); this.streamState = { entryRanges: r, byteWidths: a, entryNum: 0, streamPos: e.pos } } this.readXRefStream(e); delete this.streamState; return e.dict }, readXRefStream: function (e) { var t, a, i = this.streamState; e.pos = i.streamPos; for (var n = i.byteWidths, s = n[0], o = n[1], c = n[2], l = i.entryRanges; l.length > 0;) { var h = l[0], u = l[1]; if (!Number.isInteger(h) || !Number.isInteger(u)) throw new r.FormatError(`Invalid XRef range fields: ${h}, ${u}`); if (!Number.isInteger(s) || !Number.isInteger(o) || !Number.isInteger(c)) throw new r.FormatError(`Invalid XRef entry fields length: ${h}, ${u}`); for (t = i.entryNum; t < u; ++t) { i.entryNum = t; i.streamPos = e.pos; var d = 0, f = 0, g = 0; for (a = 0; a < s; ++a)d = d << 8 | e.getByte(); 0 === s && (d = 1); for (a = 0; a < o; ++a)f = f << 8 | e.getByte(); for (a = 0; a < c; ++a)g = g << 8 | e.getByte(); var m = {}; m.offset = f; m.gen = g; switch (d) { case 0: m.free = !0; break; case 1: m.uncompressed = !0; break; case 2: break; default: throw new r.FormatError(`Invalid XRef entry type: ${d}`) }this.entries[h + t] || (this.entries[h + t] = m) } i.entryNum = 0; i.streamPos = e.pos; l.splice(0, 2) } }, indexObjects: function () { function e(e, t) { for (var a = "", r = e[t]; 10 !== r && 13 !== r && 60 !== r && !(++t >= e.length);) { a += String.fromCharCode(r); r = e[t] } return a } function t(e, t, a) { for (var r = a.length, i = e.length, n = 0; t < i;) { for (var s = 0; s < r && e[t + s] === a[s];)++s; if (s >= r) break; t++; n++ } return n } var a = /^(\d+)\s+(\d+)\s+obj\b/; const o = /\bendobj[\b\s]$/, c = /\s+(\d+\s+\d+\s+obj[\b\s<])$/; var l = new Uint8Array([116, 114, 97, 105, 108, 101, 114]), h = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]); const u = new Uint8Array([111, 98, 106]); var d = new Uint8Array([47, 88, 82, 101, 102]); this.entries.length = 0; var f = this.stream; f.pos = 0; for (var g, m, p = f.getBytes(), b = f.start, y = p.length, v = [], w = []; b < y;) { var k = p[b]; if (9 !== k && 10 !== k && 13 !== k && 32 !== k) if (37 !== k) { var S, C = e(p, b); if (C.startsWith("xref") && (4 === C.length || /\s/.test(C[4]))) { b += t(p, b, l); v.push(b); b += t(p, b, h) } else if (S = a.exec(C)) { const e = 0 | S[1], a = 0 | S[2]; this.entries[e] && this.entries[e].gen !== a || (this.entries[e] = { offset: b - f.start, gen: a, uncompressed: !0 }); let i, n = b + C.length; for (; n < p.length;) { const e = n + t(p, n, u) + 4; i = e - b; const a = Math.max(e - 25, n), s = (0, r.bytesToString)(p.subarray(a, e)); if (o.test(s)) break; { const e = c.exec(s); if (e && e[1]) { (0, r.warn)('indexObjects: Found new "obj" inside of another "obj", caused by missing "endobj" -- trying to recover.'); i -= e[1].length; break } } n = e } const s = p.subarray(b, b + i); var x = t(s, 0, d); if (x < i && s[x + 5] < 64) { w.push(b - f.start); this.xrefstms[b - f.start] = 1 } b += i } else if (C.startsWith("trailer") && (7 === C.length || /\s/.test(C[7]))) { v.push(b); b += t(p, b, h) } else b += C.length + 1 } else do { if (++b >= y) break; k = p[b] } while (10 !== k && 13 !== k); else ++b } for (g = 0, m = w.length; g < m; ++g) { this.startXRefQueue.push(w[g]); this.readXRef(!0) } let A; for (g = 0, m = v.length; g < m; ++g) { f.pos = v[g]; const e = new n.Parser({ lexer: new n.Lexer(f), xref: this, allowStreams: !0, recoveryMode: !0 }); var I = e.getObj(); if (!(0, i.isCmd)(I, "trailer")) continue; const t = e.getObj(); if (!(0, i.isDict)(t)) continue; let a; try { a = t.get("Root") } catch (e) { if (e instanceof s.MissingDataException) throw e; continue } if ((0, i.isDict)(a) && a.has("Pages")) { if (t.has("ID")) return t; A = t } } if (A) return A; throw new r.InvalidPDFException("Invalid PDF structure.") }, readXRef: function (e) { var t = this.stream; const a = Object.create(null); try { for (; this.startXRefQueue.length;) { var o = this.startXRefQueue[0]; if (a[o]) { (0, r.warn)("readXRef - skipping XRef table since it was already parsed."); this.startXRefQueue.shift(); continue } a[o] = !0; t.pos = o + t.start; const e = new n.Parser({ lexer: new n.Lexer(t), xref: this, allowStreams: !0 }); var c, l = e.getObj(); if ((0, i.isCmd)(l, "xref")) { c = this.processXRefTable(e); this.topDict || (this.topDict = c); l = c.get("XRefStm"); if (Number.isInteger(l)) { var h = l; if (!(h in this.xrefstms)) { this.xrefstms[h] = 1; this.startXRefQueue.push(h) } } } else { if (!Number.isInteger(l)) throw new r.FormatError("Invalid XRef stream header"); if (!Number.isInteger(e.getObj()) || !(0, i.isCmd)(e.getObj(), "obj") || !(0, i.isStream)(l = e.getObj())) throw new r.FormatError("Invalid XRef stream"); c = this.processXRefStream(l); this.topDict || (this.topDict = c); if (!c) throw new r.FormatError("Failed to read XRef stream") } l = c.get("Prev"); Number.isInteger(l) ? this.startXRefQueue.push(l) : (0, i.isRef)(l) && this.startXRefQueue.push(l.num); this.startXRefQueue.shift() } return this.topDict } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("(while reading XRef): " + e) } if (!e) throw new s.XRefParseException }, getEntry: function (e) { var t = this.entries[e]; return t && !t.free && t.offset ? t : null }, fetchIfRef: function (e, t) { return e instanceof i.Ref ? this.fetch(e, t) : e }, fetch: function (e, t) { if (!(e instanceof i.Ref)) throw new Error("ref object is not a reference"); const a = e.num, r = this._cacheMap.get(a); if (void 0 !== r) { r instanceof i.Dict && !r.objId && (r.objId = e.toString()); return r } let n = this.getEntry(a); if (null === n) { this._cacheMap.set(a, n); return n } n = n.uncompressed ? this.fetchUncompressed(e, n, t) : this.fetchCompressed(e, n, t); (0, i.isDict)(n) ? n.objId = e.toString() : (0, i.isStream)(n) && (n.dict.objId = e.toString()); return n }, fetchUncompressed(e, t, a = !1) { var r = e.gen, o = e.num; if (t.gen !== r) throw new s.XRefEntryException(`Inconsistent generation in XRef: ${e}`); var c = this.stream.makeSubStream(t.offset + this.stream.start); const l = new n.Parser({ lexer: new n.Lexer(c), xref: this, allowStreams: !0 }); var h = l.getObj(), u = l.getObj(), d = l.getObj(); if (h !== o || u !== r || !(d instanceof i.Cmd)) throw new s.XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`); if ("obj" !== d.cmd) { if (d.cmd.startsWith("obj")) { o = parseInt(d.cmd.substring(3), 10); if (!Number.isNaN(o)) return o } throw new s.XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`) } t = this.encrypt && !a ? l.getObj(this.encrypt.createCipherTransform(o, r)) : l.getObj(); (0, i.isStream)(t) || this._cacheMap.set(o, t); return t }, fetchCompressed(e, t, a = !1) { const o = t.offset, c = this.fetch(i.Ref.get(o, 0)); if (!(0, i.isStream)(c)) throw new r.FormatError("bad ObjStm stream"); const l = c.dict.get("First"), h = c.dict.get("N"); if (!Number.isInteger(l) || !Number.isInteger(h)) throw new r.FormatError("invalid first and n parameters for ObjStm stream"); const u = new n.Parser({ lexer: new n.Lexer(c), xref: this, allowStreams: !0 }), d = new Array(h); for (let e = 0; e < h; ++e) { const t = u.getObj(); if (!Number.isInteger(t)) throw new r.FormatError(`invalid object number in the ObjStm stream: ${t}`); const a = u.getObj(); if (!Number.isInteger(a)) throw new r.FormatError(`invalid object offset in the ObjStm stream: ${a}`); d[e] = t } const f = new Array(h); for (let e = 0; e < h; ++e) { const t = u.getObj(); f[e] = t; u.buf1 instanceof i.Cmd && "endobj" === u.buf1.cmd && u.shift(); if ((0, i.isStream)(t)) continue; const a = d[e], r = this.entries[a]; r && r.offset === o && r.gen === e && this._cacheMap.set(a, t) } if (void 0 === (t = f[t.gen])) throw new s.XRefEntryException(`Bad (compressed) XRef entry: ${e}`); return t }, async fetchIfRefAsync(e, t) { return e instanceof i.Ref ? this.fetchAsync(e, t) : e }, async fetchAsync(e, t) { try { return this.fetch(e, t) } catch (a) { if (!(a instanceof s.MissingDataException)) throw a; await this.pdfManager.requestRange(a.begin, a.end); return this.fetchAsync(e, t) } }, getCatalogObj: function () { return this.root } }; return e }(); t.XRef = u; class d { constructor(e, t, a) { this.constructor === d && (0, r.unreachable)("Cannot initialize NameOrNumberTree."); this.root = e; this.xref = t; this._type = a } getAll() { const e = Object.create(null); if (!this.root) return e; const t = this.xref, a = new i.RefSet; a.put(this.root); const n = [this.root]; for (; n.length > 0;) { const s = t.fetchIfRef(n.shift()); if (!(0, i.isDict)(s)) continue; if (s.has("Kids")) { const e = s.get("Kids"); for (let t = 0, i = e.length; t < i; t++) { const i = e[t]; if (a.has(i)) throw new r.FormatError(`Duplicate entry in "${this._type}" tree.`); n.push(i); a.put(i) } continue } const o = s.get(this._type); if (Array.isArray(o)) for (let a = 0, r = o.length; a < r; a += 2)e[t.fetchIfRef(o[a])] = t.fetchIfRef(o[a + 1]) } return e } get(e) { if (!this.root) return null; const t = this.xref; let a = t.fetchIfRef(this.root), i = 0; for (; a.has("Kids");) { if (++i > 10) { (0, r.warn)(`Search depth limit reached for "${this._type}" tree.`); return null } const n = a.get("Kids"); if (!Array.isArray(n)) return null; let s = 0, o = n.length - 1; for (; s <= o;) { const r = s + o >> 1, i = t.fetchIfRef(n[r]).get("Limits"); if (e < t.fetchIfRef(i[0])) o = r - 1; else { if (!(e > t.fetchIfRef(i[1]))) { a = t.fetchIfRef(n[r]); break } s = r + 1 } } if (s > o) return null } const n = a.get(this._type); if (Array.isArray(n)) { let a = 0, i = n.length - 2; for (; a <= i;) { const r = a + i >> 1, s = r + (1 & r), o = t.fetchIfRef(n[s]); if (e < o) i = s - 2; else { if (!(e > o)) return t.fetchIfRef(n[s + 1]); a = s + 2 } } (0, r.info)(`Falling back to an exhaustive search, for key "${e}", ` + `in "${this._type}" tree.`); for (let a = 0, i = n.length; a < i; a += 2) { if (t.fetchIfRef(n[a]) === e) { (0, r.warn)(`The "${e}" key was found at an incorrect, ` + `i.e. out-of-order, position in "${this._type}" tree.`); return t.fetchIfRef(n[a + 1]) } } } return null } } class f extends d { constructor(e, t) { super(e, t, "Names") } } class g extends d { constructor(e, t) { super(e, t, "Nums") } } var m = function () { function e(e, t) { if (e && (0, i.isDict)(e)) { this.xref = t; this.root = e; e.has("FS") && (this.fs = e.get("FS")); this.description = e.has("Desc") ? (0, r.stringToPDFString)(e.get("Desc")) : ""; e.has("RF") && (0, r.warn)("Related file specifications are not supported"); this.contentAvailable = !0; if (!e.has("EF")) { this.contentAvailable = !1; (0, r.warn)("Non-embedded file specifications are not supported") } } } function t(e) { return e.has("UF") ? e.get("UF") : e.has("F") ? e.get("F") : e.has("Unix") ? e.get("Unix") : e.has("Mac") ? e.get("Mac") : e.has("DOS") ? e.get("DOS") : null } e.prototype = { get filename() { if (!this._filename && this.root) { var e = t(this.root) || "unnamed"; this._filename = (0, r.stringToPDFString)(e).replace(/\\\\/g, "\\").replace(/\\\//g, "/").replace(/\\/g, "/") } return this._filename }, get content() { if (!this.contentAvailable) return null; !this.contentRef && this.root && (this.contentRef = t(this.root.get("EF"))); var e = null; if (this.contentRef) { var a = this.xref.fetchIfRef(this.contentRef); a && (0, i.isStream)(a) ? e = a.getBytes() : (0, r.warn)("Embedded file specification points to non-existing/invalid content") } else (0, r.warn)("Embedded file specification does not have a content"); return e }, get serializable() { return { filename: this.filename, content: this.content } } }; return e }(); t.FileSpec = m; const p = function () { function e(e) { return e instanceof i.Ref || e instanceof i.Dict || Array.isArray(e) || (0, i.isStream)(e) } function t(t, a) { if (t instanceof i.Dict || (0, i.isStream)(t)) { const r = t instanceof i.Dict ? t : t.dict, n = r.getKeys(); for (let t = 0, i = n.length; t < i; t++) { const i = r.getRaw(n[t]); e(i) && a.push(i) } } else if (Array.isArray(t)) for (let r = 0, i = t.length; r < i; r++) { const i = t[r]; e(i) && a.push(i) } } function a(e, t, a) { this.dict = e; this.keys = t; this.xref = a; this.refSet = null } a.prototype = { async load() { if (!this.xref.stream.allChunksLoaded || this.xref.stream.allChunksLoaded()) return; const { keys: e, dict: t } = this; this.refSet = new i.RefSet; const a = []; for (let r = 0, i = e.length; r < i; r++) { const i = t.getRaw(e[r]); void 0 !== i && a.push(i) } return this._walk(a) }, async _walk(e) { const a = [], r = []; for (; e.length;) { let n = e.pop(); if (n instanceof i.Ref) { if (this.refSet.has(n)) continue; try { this.refSet.put(n); n = this.xref.fetch(n) } catch (e) { if (!(e instanceof s.MissingDataException)) throw e; a.push(n); r.push({ begin: e.begin, end: e.end }) } } if (n && n.getBaseStreams) { const e = n.getBaseStreams(); let t = !1; for (let a = 0, i = e.length; a < i; a++) { const i = e[a]; if (i.allChunksLoaded && !i.allChunksLoaded()) { t = !0; r.push({ begin: i.start, end: i.end }) } } t && a.push(n) } t(n, e) } if (r.length) { await this.xref.stream.manager.requestRanges(r); for (let e = 0, t = a.length; e < t; e++) { const t = a[e]; t instanceof i.Ref && this.refSet.remove(t) } return this._walk(a) } this.refSet = null } }; return a }(); t.ObjectLoader = p }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.Parser = t.Linearization = t.Lexer = void 0; var r = a(11), i = a(2), n = a(4), s = a(7), o = a(12), c = a(14), l = a(17), h = a(19); function u(e) { const t = e.length; let a = 1, r = 0; for (let i = 0; i < t; ++i) { a += 255 & e[i]; r += a } return r % 65521 << 16 | a % 65521 } class d { constructor({ lexer: e, xref: t, allowStreams: a = !1, recoveryMode: r = !1 }) { this.lexer = e; this.xref = t; this.allowStreams = a; this.recoveryMode = r; this.imageCache = Object.create(null); this.refill() } refill() { this.buf1 = this.lexer.getObj(); this.buf2 = this.lexer.getObj() } shift() { if (this.buf2 instanceof n.Cmd && "ID" === this.buf2.cmd) { this.buf1 = this.buf2; this.buf2 = null } else { this.buf1 = this.buf2; this.buf2 = this.lexer.getObj() } } tryShift() { try { this.shift(); return !0 } catch (e) { if (e instanceof s.MissingDataException) throw e; return !1 } } getObj(e = null) { const t = this.buf1; this.shift(); if (t instanceof n.Cmd) switch (t.cmd) { case "BI": return this.makeInlineImage(e); case "[": const a = []; for (; !(0, n.isCmd)(this.buf1, "]") && !(0, n.isEOF)(this.buf1);)a.push(this.getObj(e)); if ((0, n.isEOF)(this.buf1)) { if (!this.recoveryMode) throw new i.FormatError("End of file inside array"); return a } this.shift(); return a; case "<<": const r = new n.Dict(this.xref); for (; !(0, n.isCmd)(this.buf1, ">>") && !(0, n.isEOF)(this.buf1);) { if (!(0, n.isName)(this.buf1)) { (0, i.info)("Malformed dictionary: key must be a name object"); this.shift(); continue } const t = this.buf1.name; this.shift(); if ((0, n.isEOF)(this.buf1)) break; r.set(t, this.getObj(e)) } if ((0, n.isEOF)(this.buf1)) { if (!this.recoveryMode) throw new i.FormatError("End of file inside dictionary"); return r } if ((0, n.isCmd)(this.buf2, "stream")) return this.allowStreams ? this.makeStream(r, e) : r; this.shift(); return r; default: return t }if (Number.isInteger(t)) { if (Number.isInteger(this.buf1) && (0, n.isCmd)(this.buf2, "R")) { const e = n.Ref.get(t, this.buf1); this.shift(); this.shift(); return e } return t } return "string" == typeof t && e ? e.decryptString(t) : t } findDefaultInlineStreamEnd(e) { const t = e.pos; let a, r, n = 0; for (; -1 !== (a = e.getByte());)if (0 === n) n = 69 === a ? 1 : 0; else if (1 === n) n = 73 === a ? 2 : 0; else { (0, i.assert)(2 === n); if (32 === a || 10 === a || 13 === a) { r = e.pos; const t = e.peekBytes(10); for (let e = 0, r = t.length; e < r; e++) { a = t[e]; if ((0 !== a || 0 === t[e + 1]) && (10 !== a && 13 !== a && (a < 32 || a > 127))) { n = 0; break } } if (2 === n) break } else n = 0 } if (-1 === a) { (0, i.warn)("findDefaultInlineStreamEnd: Reached the end of the stream without finding a valid EI marker"); if (r) { (0, i.warn)('... trying to recover by using the last "EI" occurrence.'); e.skip(-(e.pos - r)) } } let o = 4; e.skip(-o); a = e.peekByte(); e.skip(o); (0, s.isWhiteSpace)(a) || o--; return e.pos - o - t } findDCTDecodeInlineStreamEnd(e) { const t = e.pos; let a, r, n = !1; for (; -1 !== (a = e.getByte());)if (255 === a) { switch (e.getByte()) { case 0: break; case 255: e.skip(-1); break; case 217: n = !0; break; case 192: case 193: case 194: case 195: case 197: case 198: case 199: case 201: case 202: case 203: case 205: case 206: case 207: case 196: case 204: case 218: case 219: case 220: case 221: case 222: case 223: case 224: case 225: case 226: case 227: case 228: case 229: case 230: case 231: case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239: case 254: r = e.getUint16(); r > 2 ? e.skip(r - 2) : e.skip(-2) }if (n) break } const s = e.pos - t; if (-1 === a) { (0, i.warn)("Inline DCTDecode image stream: EOI marker not found, searching for /EI/ instead."); e.skip(-s); return this.findDefaultInlineStreamEnd(e) } this.inlineStreamSkipEI(e); return s } findASCII85DecodeInlineStreamEnd(e) { const t = e.pos; let a; for (; -1 !== (a = e.getByte());)if (126 === a) { const t = e.pos; a = e.peekByte(); for (; (0, s.isWhiteSpace)(a);) { e.skip(); a = e.peekByte() } if (62 === a) { e.skip(); break } if (e.pos > t) { const t = e.peekBytes(2); if (69 === t[0] && 73 === t[1]) break } } const r = e.pos - t; if (-1 === a) { (0, i.warn)("Inline ASCII85Decode image stream: EOD marker not found, searching for /EI/ instead."); e.skip(-r); return this.findDefaultInlineStreamEnd(e) } this.inlineStreamSkipEI(e); return r } findASCIIHexDecodeInlineStreamEnd(e) { const t = e.pos; let a; for (; -1 !== (a = e.getByte()) && 62 !== a;); const r = e.pos - t; if (-1 === a) { (0, i.warn)("Inline ASCIIHexDecode image stream: EOD marker not found, searching for /EI/ instead."); e.skip(-r); return this.findDefaultInlineStreamEnd(e) } this.inlineStreamSkipEI(e); return r } inlineStreamSkipEI(e) { let t, a = 0; for (; -1 !== (t = e.getByte());)if (0 === a) a = 69 === t ? 1 : 0; else if (1 === a) a = 73 === t ? 2 : 0; else if (2 === a) break } makeInlineImage(e) { const t = this.lexer, a = t.stream, r = new n.Dict(this.xref); let s; for (; !(0, n.isCmd)(this.buf1, "ID") && !(0, n.isEOF)(this.buf1);) { if (!(0, n.isName)(this.buf1)) throw new i.FormatError("Dictionary key must be a name object"); const t = this.buf1.name; this.shift(); if ((0, n.isEOF)(this.buf1)) break; r.set(t, this.getObj(e)) } -1 !== t.beginInlineImagePos && (s = a.pos - t.beginInlineImagePos); const o = r.get("Filter", "F"); let c; if ((0, n.isName)(o)) c = o.name; else if (Array.isArray(o)) { const e = this.xref.fetchIfRef(o[0]); (0, n.isName)(e) && (c = e.name) } const l = a.pos; let h; h = "DCTDecode" === c || "DCT" === c ? this.findDCTDecodeInlineStreamEnd(a) : "ASCII85Decode" === c || "A85" === c ? this.findASCII85DecodeInlineStreamEnd(a) : "ASCIIHexDecode" === c || "AHx" === c ? this.findASCIIHexDecodeInlineStreamEnd(a) : this.findDefaultInlineStreamEnd(a); let d, f = a.makeSubStream(l, h, r); if (h < 1e3 && s < 5552) { const e = f.getBytes(); f.reset(); const r = a.pos; a.pos = t.beginInlineImagePos; const i = a.getBytes(s); a.pos = r; d = u(e) + "_" + u(i); const o = this.imageCache[d]; if (void 0 !== o) { this.buf2 = n.Cmd.get("EI"); this.shift(); o.reset(); return o } } e && (f = e.createStream(f, h)); f = this.filter(f, r, h); f.dict = r; if (void 0 !== d) { f.cacheKey = `inline_${h}_${d}`; this.imageCache[d] = f } this.buf2 = n.Cmd.get("EI"); this.shift(); return f } _findStreamLength(e, t) { const { stream: a } = this.lexer; a.pos = e; const r = t.length; for (; a.pos < a.end;) { const i = a.peekBytes(2048), n = i.length - r; if (n <= 0) break; let s = 0; for (; s < n;) { let n = 0; for (; n < r && i[s + n] === t[n];)n++; if (n >= r) { a.pos += s; return a.pos - e } s++ } a.pos += n } return -1 } makeStream(e, t) { const a = this.lexer; let r = a.stream; a.skipToNextLine(); const o = r.pos - 1; let c = e.get("Length"); if (!Number.isInteger(c)) { (0, i.info)(`Bad length "${c}" in stream`); c = 0 } r.pos = o + c; a.nextChar(); if (this.tryShift() && (0, n.isCmd)(this.buf2, "endstream")) this.shift(); else { const e = new Uint8Array([101, 110, 100, 115, 116, 114, 101, 97, 109]); let t = this._findStreamLength(o, e); if (t < 0) { const a = 1; for (let n = 1; n <= a; n++) { const a = e.length - n, c = e.slice(0, a), l = this._findStreamLength(o, c); if (l >= 0) { const e = r.peekBytes(a + 1)[a]; if (!(0, s.isWhiteSpace)(e)) break; (0, i.info)(`Found "${(0, i.bytesToString)(c)}" when ` + "searching for endstream command."); t = l; break } } if (t < 0) throw new i.FormatError("Missing endstream command.") } c = t; a.nextChar(); this.shift(); this.shift() } this.shift(); r = r.makeSubStream(o, c, e); t && (r = t.createStream(r, c)); r = this.filter(r, e, c); r.dict = e; return r } filter(e, t, a) { let r = t.get("Filter", "F"), s = t.get("DecodeParms", "DP"); if ((0, n.isName)(r)) { Array.isArray(s) && (0, i.warn)("/DecodeParms should not contain an Array, when /Filter contains a Name."); return this.makeFilter(e, r.name, a, s) } let o = a; if (Array.isArray(r)) { const t = r, a = s; for (let c = 0, l = t.length; c < l; ++c) { r = this.xref.fetchIfRef(t[c]); if (!(0, n.isName)(r)) throw new i.FormatError(`Bad filter name "${r}"`); s = null; Array.isArray(a) && c in a && (s = this.xref.fetchIfRef(a[c])); e = this.makeFilter(e, r.name, o, s); o = null } } return e } makeFilter(e, t, a, n) { if (0 === a) { (0, i.warn)(`Empty "${t}" stream.`); return new r.NullStream } try { const s = this.xref.stats.streamTypes; if ("FlateDecode" === t || "Fl" === t) { s[i.StreamType.FLATE] = !0; return n ? new r.PredictorStream(new r.FlateStream(e, a), a, n) : new r.FlateStream(e, a) } if ("LZWDecode" === t || "LZW" === t) { s[i.StreamType.LZW] = !0; let t = 1; if (n) { n.has("EarlyChange") && (t = n.get("EarlyChange")); return new r.PredictorStream(new r.LZWStream(e, a, t), a, n) } return new r.LZWStream(e, a, t) } if ("DCTDecode" === t || "DCT" === t) { s[i.StreamType.DCT] = !0; return new l.JpegStream(e, a, e.dict, n) } if ("JPXDecode" === t || "JPX" === t) { s[i.StreamType.JPX] = !0; return new h.JpxStream(e, a, e.dict, n) } if ("ASCII85Decode" === t || "A85" === t) { s[i.StreamType.A85] = !0; return new r.Ascii85Stream(e, a) } if ("ASCIIHexDecode" === t || "AHx" === t) { s[i.StreamType.AHX] = !0; return new r.AsciiHexStream(e, a) } if ("CCITTFaxDecode" === t || "CCF" === t) { s[i.StreamType.CCF] = !0; return new o.CCITTFaxStream(e, a, n) } if ("RunLengthDecode" === t || "RL" === t) { s[i.StreamType.RLX] = !0; return new r.RunLengthStream(e, a) } if ("JBIG2Decode" === t) { s[i.StreamType.JBIG] = !0; return new c.Jbig2Stream(e, a, e.dict, n) } (0, i.warn)(`Filter "${t}" is not supported.`); return e } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, i.warn)(`Invalid stream: "${e}"`); return new r.NullStream } } } t.Parser = d; const f = [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; function g(e) { return e >= 48 && e <= 57 ? 15 & e : e >= 65 && e <= 70 || e >= 97 && e <= 102 ? 9 + (15 & e) : -1 } class m { constructor(e, t = null) { this.stream = e; this.nextChar(); this.strBuf = []; this.knownCommands = t; this._hexStringNumWarn = 0; this.beginInlineImagePos = -1 } nextChar() { return this.currentChar = this.stream.getByte() } peekChar() { return this.stream.peekByte() } getNumber() { let e = this.currentChar, t = !1, a = 0, r = 0; if (45 === e) { r = -1; e = this.nextChar(); 45 === e && (e = this.nextChar()) } else if (43 === e) { r = 1; e = this.nextChar() } if (10 === e || 13 === e) do { e = this.nextChar() } while (10 === e || 13 === e); if (46 === e) { a = 10; e = this.nextChar() } if (e < 48 || e > 57) { if (10 === a && 0 === r && ((0, s.isWhiteSpace)(e) || -1 === e)) { (0, i.warn)("Lexer.getNumber - treating a single decimal point as zero."); return 0 } throw new i.FormatError(`Invalid number: ${String.fromCharCode(e)} (charCode ${e})`) } r = r || 1; let n = e - 48, o = 0, c = 1; for (; (e = this.nextChar()) >= 0;)if (e >= 48 && e <= 57) { const r = e - 48; if (t) o = 10 * o + r; else { 0 !== a && (a *= 10); n = 10 * n + r } } else if (46 === e) { if (0 !== a) break; a = 1 } else if (45 === e) (0, i.warn)("Badly formatted number: minus sign in the middle"); else { if (69 !== e && 101 !== e) break; e = this.peekChar(); if (43 === e || 45 === e) { c = 45 === e ? -1 : 1; this.nextChar() } else if (e < 48 || e > 57) break; t = !0 } 0 !== a && (n /= a); t && (n *= 10 ** (c * o)); return r * n } getString() { let e = 1, t = !1; const a = this.strBuf; a.length = 0; let r = this.nextChar(); for (; ;) { let n = !1; switch (0 | r) { case -1: (0, i.warn)("Unterminated string"); t = !0; break; case 40: ++e; a.push("("); break; case 41: if (0 == --e) { this.nextChar(); t = !0 } else a.push(")"); break; case 92: r = this.nextChar(); switch (r) { case -1: (0, i.warn)("Unterminated string"); t = !0; break; case 110: a.push("\n"); break; case 114: a.push("\r"); break; case 116: a.push("\t"); break; case 98: a.push("\b"); break; case 102: a.push("\f"); break; case 92: case 40: case 41: a.push(String.fromCharCode(r)); break; case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: let e = 15 & r; r = this.nextChar(); n = !0; if (r >= 48 && r <= 55) { e = (e << 3) + (15 & r); r = this.nextChar(); if (r >= 48 && r <= 55) { n = !1; e = (e << 3) + (15 & r) } } a.push(String.fromCharCode(e)); break; case 13: 10 === this.peekChar() && this.nextChar(); break; case 10: break; default: a.push(String.fromCharCode(r)) }break; default: a.push(String.fromCharCode(r)) }if (t) break; n || (r = this.nextChar()) } return a.join("") } getName() { let e, t; const a = this.strBuf; a.length = 0; for (; (e = this.nextChar()) >= 0 && !f[e];)if (35 === e) { e = this.nextChar(); if (f[e]) { (0, i.warn)("Lexer_getName: NUMBER SIGN (#) should be followed by a hexadecimal number."); a.push("#"); break } const r = g(e); if (-1 !== r) { t = e; e = this.nextChar(); const n = g(e); if (-1 === n) { (0, i.warn)(`Lexer_getName: Illegal digit (${String.fromCharCode(e)}) ` + "in hexadecimal number."); a.push("#", String.fromCharCode(t)); if (f[e]) break; a.push(String.fromCharCode(e)); continue } a.push(String.fromCharCode(r << 4 | n)) } else a.push("#", String.fromCharCode(e)) } else a.push(String.fromCharCode(e)); a.length > 127 && (0, i.warn)(`Name token is longer than allowed by the spec: ${a.length}`); return n.Name.get(a.join("")) } _hexStringWarn(e) { 5 != this._hexStringNumWarn++ ? this._hexStringNumWarn > 5 || (0, i.warn)(`getHexString - ignoring invalid character: ${e}`) : (0, i.warn)("getHexString - ignoring additional invalid characters.") } getHexString() { const e = this.strBuf; e.length = 0; let t, a, r = this.currentChar, n = !0; this._hexStringNumWarn = 0; for (; ;) { if (r < 0) { (0, i.warn)("Unterminated hex string"); break } if (62 === r) { this.nextChar(); break } if (1 !== f[r]) { if (n) { t = g(r); if (-1 === t) { this._hexStringWarn(r); r = this.nextChar(); continue } } else { a = g(r); if (-1 === a) { this._hexStringWarn(r); r = this.nextChar(); continue } e.push(String.fromCharCode(t << 4 | a)) } n = !n; r = this.nextChar() } else r = this.nextChar() } return e.join("") } getObj() { let e = !1, t = this.currentChar; for (; ;) { if (t < 0) return n.EOF; if (e) 10 !== t && 13 !== t || (e = !1); else if (37 === t) e = !0; else if (1 !== f[t]) break; t = this.nextChar() } switch (0 | t) { case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 43: case 45: case 46: return this.getNumber(); case 40: return this.getString(); case 47: return this.getName(); case 91: this.nextChar(); return n.Cmd.get("["); case 93: this.nextChar(); return n.Cmd.get("]"); case 60: t = this.nextChar(); if (60 === t) { this.nextChar(); return n.Cmd.get("<<") } return this.getHexString(); case 62: t = this.nextChar(); if (62 === t) { this.nextChar(); return n.Cmd.get(">>") } return n.Cmd.get(">"); case 123: this.nextChar(); return n.Cmd.get("{"); case 125: this.nextChar(); return n.Cmd.get("}"); case 41: this.nextChar(); throw new i.FormatError(`Illegal character: ${t}`) }let a = String.fromCharCode(t); const r = this.knownCommands; let s = r && void 0 !== r[a]; for (; (t = this.nextChar()) >= 0 && !f[t];) { const e = a + String.fromCharCode(t); if (s && void 0 === r[e]) break; if (128 === a.length) throw new i.FormatError(`Command token too long: ${a.length}`); a = e; s = r && void 0 !== r[a] } if ("true" === a) return !0; if ("false" === a) return !1; if ("null" === a) return null; "BI" === a && (this.beginInlineImagePos = this.stream.pos); return n.Cmd.get(a) } skipToNextLine() { let e = this.currentChar; for (; e >= 0;) { if (13 === e) { e = this.nextChar(); 10 === e && this.nextChar(); break } if (10 === e) { this.nextChar(); break } e = this.nextChar() } } } t.Lexer = m; t.Linearization = class { static create(e) { function t(e, t, a = !1) { const r = e.get(t); if (Number.isInteger(r) && (a ? r >= 0 : r > 0)) return r; throw new Error(`The "${t}" parameter in the linearization ` + "dictionary is invalid.") } const a = new d({ lexer: new m(e), xref: null }), r = a.getObj(), s = a.getObj(), o = a.getObj(), c = a.getObj(); let l, h; if (!(Number.isInteger(r) && Number.isInteger(s) && (0, n.isCmd)(o, "obj") && (0, n.isDict)(c) && (0, i.isNum)(l = c.get("Linearized")) && l > 0)) return null; if ((h = t(c, "L")) !== e.length) throw new Error('The "L" parameter in the linearization dictionary does not equal the stream length.'); return { length: h, hints: function (e) { const t = e.get("H"); let a; if (Array.isArray(t) && (2 === (a = t.length) || 4 === a)) { for (let e = 0; e < a; e++) { const a = t[e]; if (!(Number.isInteger(a) && a > 0)) throw new Error(`Hint (${e}) in the linearization dictionary is invalid.`) } return t } throw new Error("Hint array in the linearization dictionary is invalid.") }(c), objectNumberFirst: t(c, "O"), endFirst: t(c, "E"), numPages: t(c, "N"), mainXRefEntriesOffset: t(c, "T"), pageFirst: c.has("P") ? t(c, "P", !0) : 0 } } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.LZWStream = t.StringStream = t.StreamsSequenceStream = t.Stream = t.RunLengthStream = t.PredictorStream = t.NullStream = t.FlateStream = t.DecodeStream = t.DecryptStream = t.AsciiHexStream = t.Ascii85Stream = void 0; var r = a(2), i = a(4), n = a(7), s = function () { function e(e, t, a, r) { this.bytes = e instanceof Uint8Array ? e : new Uint8Array(e); this.start = t || 0; this.pos = this.start; this.end = t + a || this.bytes.length; this.dict = r } e.prototype = { get length() { return this.end - this.start }, get isEmpty() { return 0 === this.length }, getByte: function () { return this.pos >= this.end ? -1 : this.bytes[this.pos++] }, getUint16: function () { var e = this.getByte(), t = this.getByte(); return -1 === e || -1 === t ? -1 : (e << 8) + t }, getInt32: function () { return (this.getByte() << 24) + (this.getByte() << 16) + (this.getByte() << 8) + this.getByte() }, getBytes(e, t = !1) { var a = this.bytes, r = this.pos, i = this.end; if (!e) { const e = a.subarray(r, i); return t ? new Uint8ClampedArray(e) : e } var n = r + e; n > i && (n = i); this.pos = n; const s = a.subarray(r, n); return t ? new Uint8ClampedArray(s) : s }, peekByte: function () { var e = this.getByte(); -1 !== e && this.pos--; return e }, peekBytes(e, t = !1) { var a = this.getBytes(e, t); this.pos -= a.length; return a }, getByteRange(e, t) { e < 0 && (e = 0); t > this.end && (t = this.end); return this.bytes.subarray(e, t) }, skip: function (e) { e || (e = 1); this.pos += e }, reset: function () { this.pos = this.start }, moveStart: function () { this.start = this.pos }, makeSubStream: function (t, a, r) { return new e(this.bytes.buffer, t, a, r) } }; return e }(); t.Stream = s; var o = function () { function e(e) { const t = (0, r.stringToBytes)(e); s.call(this, t) } e.prototype = s.prototype; return e }(); t.StringStream = o; var c = function () { var e = new Uint8Array(0); function t(t) { this._rawMinBufferLength = t || 0; this.pos = 0; this.bufferLength = 0; this.eof = !1; this.buffer = e; this.minBufferLength = 512; if (t) for (; this.minBufferLength < t;)this.minBufferLength *= 2 } t.prototype = { get isEmpty() { for (; !this.eof && 0 === this.bufferLength;)this.readBlock(); return 0 === this.bufferLength }, ensureBuffer: function (e) { var t = this.buffer; if (e <= t.byteLength) return t; for (var a = this.minBufferLength; a < e;)a *= 2; var r = new Uint8Array(a); r.set(t); return this.buffer = r }, getByte: function () { for (var e = this.pos; this.bufferLength <= e;) { if (this.eof) return -1; this.readBlock() } return this.buffer[this.pos++] }, getUint16: function () { var e = this.getByte(), t = this.getByte(); return -1 === e || -1 === t ? -1 : (e << 8) + t }, getInt32: function () { return (this.getByte() << 24) + (this.getByte() << 16) + (this.getByte() << 8) + this.getByte() }, getBytes(e, t = !1) { var a, r = this.pos; if (e) { this.ensureBuffer(r + e); a = r + e; for (; !this.eof && this.bufferLength < a;)this.readBlock(); var i = this.bufferLength; a > i && (a = i) } else { for (; !this.eof;)this.readBlock(); a = this.bufferLength } this.pos = a; const n = this.buffer.subarray(r, a); return !t || n instanceof Uint8ClampedArray ? n : new Uint8ClampedArray(n) }, peekByte: function () { var e = this.getByte(); -1 !== e && this.pos--; return e }, peekBytes(e, t = !1) { var a = this.getBytes(e, t); this.pos -= a.length; return a }, makeSubStream: function (e, t, a) { for (var r = e + t; this.bufferLength <= r && !this.eof;)this.readBlock(); return new s(this.buffer, e, t, a) }, getByteRange(e, t) { (0, r.unreachable)("Should not call DecodeStream.getByteRange") }, skip: function (e) { e || (e = 1); this.pos += e }, reset: function () { this.pos = 0 }, getBaseStreams: function () { return this.str && this.str.getBaseStreams ? this.str.getBaseStreams() : [] } }; return t }(); t.DecodeStream = c; var l = function () { function e(e) { this.streams = e; let t = 0; for (let a = 0, r = e.length; a < r; a++) { const r = e[a]; t += r instanceof c ? r._rawMinBufferLength : r.length } c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { var e = this.streams; if (0 !== e.length) { var t = e.shift().getBytes(), a = this.bufferLength, r = a + t.length; this.ensureBuffer(r).set(t, a); this.bufferLength = r } else this.eof = !0 }; e.prototype.getBaseStreams = function () { for (var e = [], t = 0, a = this.streams.length; t < a; t++) { var r = this.streams[t]; r.getBaseStreams && e.push(...r.getBaseStreams()) } return e }; return e }(); t.StreamsSequenceStream = l; var h = function () { var e = new Int32Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]), t = new Int32Array([3, 4, 5, 6, 7, 8, 9, 10, 65547, 65549, 65551, 65553, 131091, 131095, 131099, 131103, 196643, 196651, 196659, 196667, 262211, 262227, 262243, 262259, 327811, 327843, 327875, 327907, 258, 258, 258]), a = new Int32Array([1, 2, 3, 4, 65541, 65543, 131081, 131085, 196625, 196633, 262177, 262193, 327745, 327777, 393345, 393409, 459009, 459137, 524801, 525057, 590849, 591361, 657409, 658433, 724993, 727041, 794625, 798721, 868353, 876545]), i = [new Int32Array([459008, 524368, 524304, 524568, 459024, 524400, 524336, 590016, 459016, 524384, 524320, 589984, 524288, 524416, 524352, 590048, 459012, 524376, 524312, 589968, 459028, 524408, 524344, 590032, 459020, 524392, 524328, 59e4, 524296, 524424, 524360, 590064, 459010, 524372, 524308, 524572, 459026, 524404, 524340, 590024, 459018, 524388, 524324, 589992, 524292, 524420, 524356, 590056, 459014, 524380, 524316, 589976, 459030, 524412, 524348, 590040, 459022, 524396, 524332, 590008, 524300, 524428, 524364, 590072, 459009, 524370, 524306, 524570, 459025, 524402, 524338, 590020, 459017, 524386, 524322, 589988, 524290, 524418, 524354, 590052, 459013, 524378, 524314, 589972, 459029, 524410, 524346, 590036, 459021, 524394, 524330, 590004, 524298, 524426, 524362, 590068, 459011, 524374, 524310, 524574, 459027, 524406, 524342, 590028, 459019, 524390, 524326, 589996, 524294, 524422, 524358, 590060, 459015, 524382, 524318, 589980, 459031, 524414, 524350, 590044, 459023, 524398, 524334, 590012, 524302, 524430, 524366, 590076, 459008, 524369, 524305, 524569, 459024, 524401, 524337, 590018, 459016, 524385, 524321, 589986, 524289, 524417, 524353, 590050, 459012, 524377, 524313, 589970, 459028, 524409, 524345, 590034, 459020, 524393, 524329, 590002, 524297, 524425, 524361, 590066, 459010, 524373, 524309, 524573, 459026, 524405, 524341, 590026, 459018, 524389, 524325, 589994, 524293, 524421, 524357, 590058, 459014, 524381, 524317, 589978, 459030, 524413, 524349, 590042, 459022, 524397, 524333, 590010, 524301, 524429, 524365, 590074, 459009, 524371, 524307, 524571, 459025, 524403, 524339, 590022, 459017, 524387, 524323, 589990, 524291, 524419, 524355, 590054, 459013, 524379, 524315, 589974, 459029, 524411, 524347, 590038, 459021, 524395, 524331, 590006, 524299, 524427, 524363, 590070, 459011, 524375, 524311, 524575, 459027, 524407, 524343, 590030, 459019, 524391, 524327, 589998, 524295, 524423, 524359, 590062, 459015, 524383, 524319, 589982, 459031, 524415, 524351, 590046, 459023, 524399, 524335, 590014, 524303, 524431, 524367, 590078, 459008, 524368, 524304, 524568, 459024, 524400, 524336, 590017, 459016, 524384, 524320, 589985, 524288, 524416, 524352, 590049, 459012, 524376, 524312, 589969, 459028, 524408, 524344, 590033, 459020, 524392, 524328, 590001, 524296, 524424, 524360, 590065, 459010, 524372, 524308, 524572, 459026, 524404, 524340, 590025, 459018, 524388, 524324, 589993, 524292, 524420, 524356, 590057, 459014, 524380, 524316, 589977, 459030, 524412, 524348, 590041, 459022, 524396, 524332, 590009, 524300, 524428, 524364, 590073, 459009, 524370, 524306, 524570, 459025, 524402, 524338, 590021, 459017, 524386, 524322, 589989, 524290, 524418, 524354, 590053, 459013, 524378, 524314, 589973, 459029, 524410, 524346, 590037, 459021, 524394, 524330, 590005, 524298, 524426, 524362, 590069, 459011, 524374, 524310, 524574, 459027, 524406, 524342, 590029, 459019, 524390, 524326, 589997, 524294, 524422, 524358, 590061, 459015, 524382, 524318, 589981, 459031, 524414, 524350, 590045, 459023, 524398, 524334, 590013, 524302, 524430, 524366, 590077, 459008, 524369, 524305, 524569, 459024, 524401, 524337, 590019, 459016, 524385, 524321, 589987, 524289, 524417, 524353, 590051, 459012, 524377, 524313, 589971, 459028, 524409, 524345, 590035, 459020, 524393, 524329, 590003, 524297, 524425, 524361, 590067, 459010, 524373, 524309, 524573, 459026, 524405, 524341, 590027, 459018, 524389, 524325, 589995, 524293, 524421, 524357, 590059, 459014, 524381, 524317, 589979, 459030, 524413, 524349, 590043, 459022, 524397, 524333, 590011, 524301, 524429, 524365, 590075, 459009, 524371, 524307, 524571, 459025, 524403, 524339, 590023, 459017, 524387, 524323, 589991, 524291, 524419, 524355, 590055, 459013, 524379, 524315, 589975, 459029, 524411, 524347, 590039, 459021, 524395, 524331, 590007, 524299, 524427, 524363, 590071, 459011, 524375, 524311, 524575, 459027, 524407, 524343, 590031, 459019, 524391, 524327, 589999, 524295, 524423, 524359, 590063, 459015, 524383, 524319, 589983, 459031, 524415, 524351, 590047, 459023, 524399, 524335, 590015, 524303, 524431, 524367, 590079]), 9], n = [new Int32Array([327680, 327696, 327688, 327704, 327684, 327700, 327692, 327708, 327682, 327698, 327690, 327706, 327686, 327702, 327694, 0, 327681, 327697, 327689, 327705, 327685, 327701, 327693, 327709, 327683, 327699, 327691, 327707, 327687, 327703, 327695, 0]), 5]; function s(e, t) { this.str = e; this.dict = e.dict; var a = e.getByte(), i = e.getByte(); if (-1 === a || -1 === i) throw new r.FormatError(`Invalid header in flate stream: ${a}, ${i}`); if (8 != (15 & a)) throw new r.FormatError(`Unknown compression method in flate stream: ${a}, ${i}`); if (((a << 8) + i) % 31 != 0) throw new r.FormatError(`Bad FCHECK in flate stream: ${a}, ${i}`); if (32 & i) throw new r.FormatError(`FDICT bit set in flate stream: ${a}, ${i}`); this.codeSize = 0; this.codeBuf = 0; c.call(this, t) } s.prototype = Object.create(c.prototype); s.prototype.getBits = function (e) { for (var t, a = this.str, i = this.codeSize, n = this.codeBuf; i < e;) { if (-1 === (t = a.getByte())) throw new r.FormatError("Bad encoding in flate stream"); n |= t << i; i += 8 } t = n & (1 << e) - 1; this.codeBuf = n >> e; this.codeSize = i -= e; return t }; s.prototype.getCode = function (e) { for (var t, a = this.str, i = e[0], n = e[1], s = this.codeSize, o = this.codeBuf; s < n && -1 !== (t = a.getByte());) { o |= t << s; s += 8 } var c = i[o & (1 << n) - 1], l = c >> 16, h = 65535 & c; if (l < 1 || s < l) throw new r.FormatError("Bad encoding in flate stream"); this.codeBuf = o >> l; this.codeSize = s - l; return h }; s.prototype.generateHuffmanTable = function (e) { var t, a = e.length, r = 0; for (t = 0; t < a; ++t)e[t] > r && (r = e[t]); for (var i = 1 << r, n = new Int32Array(i), s = 1, o = 0, c = 2; s <= r; ++s, o <<= 1, c <<= 1)for (var l = 0; l < a; ++l)if (e[l] === s) { var h = 0, u = o; for (t = 0; t < s; ++t) { h = h << 1 | 1 & u; u >>= 1 } for (t = h; t < i; t += c)n[t] = s << 16 | l; ++o } return [n, r] }; s.prototype.readBlock = function () { var s, o, c = this.str, l = this.getBits(3); 1 & l && (this.eof = !0); if (0 !== (l >>= 1)) { var h, u; if (1 === l) { h = i; u = n } else { if (2 !== l) throw new r.FormatError("Unknown block type in flate stream"); var d, f = this.getBits(5) + 257, g = this.getBits(5) + 1, m = this.getBits(4) + 4, p = new Uint8Array(e.length); for (d = 0; d < m; ++d)p[e[d]] = this.getBits(3); var b = this.generateHuffmanTable(p); o = 0; d = 0; for (var y, v, w, k = f + g, S = new Uint8Array(k); d < k;) { var C = this.getCode(b); if (16 === C) { y = 2; v = 3; w = o } else if (17 === C) { y = 3; v = 3; w = o = 0 } else { if (18 !== C) { S[d++] = o = C; continue } y = 7; v = 11; w = o = 0 } for (var x = this.getBits(y) + v; x-- > 0;)S[d++] = w } h = this.generateHuffmanTable(S.subarray(0, f)); u = this.generateHuffmanTable(S.subarray(f, k)) } for (var A = (s = this.buffer) ? s.length : 0, I = this.bufferLength; ;) { var F = this.getCode(h); if (F < 256) { I + 1 >= A && (A = (s = this.ensureBuffer(I + 1)).length); s[I++] = F } else { if (256 === F) { this.bufferLength = I; return } var T = (F = t[F -= 257]) >> 16; T > 0 && (T = this.getBits(T)); o = (65535 & F) + T; F = this.getCode(u); (T = (F = a[F]) >> 16) > 0 && (T = this.getBits(T)); var E = (65535 & F) + T; I + o >= A && (A = (s = this.ensureBuffer(I + o)).length); for (var O = 0; O < o; ++O, ++I)s[I] = s[I - E] } } } else { var P; if (-1 === (P = c.getByte())) throw new r.FormatError("Bad block header in flate stream"); var B = P; if (-1 === (P = c.getByte())) throw new r.FormatError("Bad block header in flate stream"); B |= P << 8; if (-1 === (P = c.getByte())) throw new r.FormatError("Bad block header in flate stream"); var D = P; if (-1 === (P = c.getByte())) throw new r.FormatError("Bad block header in flate stream"); if ((D |= P << 8) !== (65535 & ~B) && (0 !== B || 0 !== D)) throw new r.FormatError("Bad uncompressed block length in flate stream"); this.codeBuf = 0; this.codeSize = 0; const e = this.bufferLength, t = e + B; s = this.ensureBuffer(t); this.bufferLength = t; if (0 === B) -1 === c.peekByte() && (this.eof = !0); else { const t = c.getBytes(B); s.set(t, e); t.length < B && (this.eof = !0) } } }; return s }(); t.FlateStream = h; var u = function () { function e(e, t, a) { if (!(0, i.isDict)(a)) return e; var n = this.predictor = a.get("Predictor") || 1; if (n <= 1) return e; if (2 !== n && (n < 10 || n > 15)) throw new r.FormatError(`Unsupported predictor: ${n}`); this.readBlock = 2 === n ? this.readBlockTiff : this.readBlockPng; this.str = e; this.dict = e.dict; var s = this.colors = a.get("Colors") || 1, o = this.bits = a.get("BitsPerComponent") || 8, l = this.columns = a.get("Columns") || 1; this.pixBytes = s * o + 7 >> 3; this.rowBytes = l * s * o + 7 >> 3; c.call(this, t); return this } e.prototype = Object.create(c.prototype); e.prototype.readBlockTiff = function () { var e = this.rowBytes, t = this.bufferLength, a = this.ensureBuffer(t + e), r = this.bits, i = this.colors, n = this.str.getBytes(e); this.eof = !n.length; if (!this.eof) { var s, o = 0, c = 0, l = 0, h = 0, u = t; if (1 === r && 1 === i) for (s = 0; s < e; ++s) { var d = n[s] ^ o; d ^= d >> 1; d ^= d >> 2; o = (1 & (d ^= d >> 4)) << 7; a[u++] = d } else if (8 === r) { for (s = 0; s < i; ++s)a[u++] = n[s]; for (; s < e; ++s) { a[u] = a[u - i] + n[s]; u++ } } else if (16 === r) { var f = 2 * i; for (s = 0; s < f; ++s)a[u++] = n[s]; for (; s < e; s += 2) { var g = ((255 & n[s]) << 8) + (255 & n[s + 1]) + ((255 & a[u - f]) << 8) + (255 & a[u - f + 1]); a[u++] = g >> 8 & 255; a[u++] = 255 & g } } else { var m = new Uint8Array(i + 1), p = (1 << r) - 1, b = 0, y = t, v = this.columns; for (s = 0; s < v; ++s)for (var w = 0; w < i; ++w) { if (l < r) { o = o << 8 | 255 & n[b++]; l += 8 } m[w] = m[w] + (o >> l - r) & p; l -= r; c = c << r | m[w]; if ((h += r) >= 8) { a[y++] = c >> h - 8 & 255; h -= 8 } } h > 0 && (a[y++] = (c << 8 - h) + (o & (1 << 8 - h) - 1)) } this.bufferLength += e } }; e.prototype.readBlockPng = function () { var e = this.rowBytes, t = this.pixBytes, a = this.str.getByte(), i = this.str.getBytes(e); this.eof = !i.length; if (!this.eof) { var n = this.bufferLength, s = this.ensureBuffer(n + e), o = s.subarray(n - e, n); 0 === o.length && (o = new Uint8Array(e)); var c, l, h, u = n; switch (a) { case 0: for (c = 0; c < e; ++c)s[u++] = i[c]; break; case 1: for (c = 0; c < t; ++c)s[u++] = i[c]; for (; c < e; ++c) { s[u] = s[u - t] + i[c] & 255; u++ } break; case 2: for (c = 0; c < e; ++c)s[u++] = o[c] + i[c] & 255; break; case 3: for (c = 0; c < t; ++c)s[u++] = (o[c] >> 1) + i[c]; for (; c < e; ++c) { s[u] = (o[c] + s[u - t] >> 1) + i[c] & 255; u++ } break; case 4: for (c = 0; c < t; ++c) { l = o[c]; h = i[c]; s[u++] = l + h } for (; c < e; ++c) { l = o[c]; var d = o[c - t], f = s[u - t], g = f + l - d, m = g - f; m < 0 && (m = -m); var p = g - l; p < 0 && (p = -p); var b = g - d; b < 0 && (b = -b); h = i[c]; s[u++] = m <= p && m <= b ? f + h : p <= b ? l + h : d + h } break; default: throw new r.FormatError(`Unsupported predictor: ${a}`) }this.bufferLength += e } }; return e }(); t.PredictorStream = u; var d = function () { function e(e, t, a) { this.str = e; this.dict = e.dict; this.decrypt = a; this.nextChunk = null; this.initialized = !1; c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { var e; if (this.initialized) e = this.nextChunk; else { e = this.str.getBytes(512); this.initialized = !0 } if (e && 0 !== e.length) { this.nextChunk = this.str.getBytes(512); var t = this.nextChunk && this.nextChunk.length > 0; e = (0, this.decrypt)(e, !t); var a, r = this.bufferLength, i = e.length, n = this.ensureBuffer(r + i); for (a = 0; a < i; a++)n[r++] = e[a]; this.bufferLength = r } else this.eof = !0 }; return e }(); t.DecryptStream = d; var f = function () { function e(e, t) { this.str = e; this.dict = e.dict; this.input = new Uint8Array(5); t && (t *= .8); c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { for (var e = this.str, t = e.getByte(); (0, n.isWhiteSpace)(t);)t = e.getByte(); if (-1 !== t && 126 !== t) { var a, r, i = this.bufferLength; if (122 === t) { a = this.ensureBuffer(i + 4); for (r = 0; r < 4; ++r)a[i + r] = 0; this.bufferLength += 4 } else { var s = this.input; s[0] = t; for (r = 1; r < 5; ++r) { t = e.getByte(); for (; (0, n.isWhiteSpace)(t);)t = e.getByte(); s[r] = t; if (-1 === t || 126 === t) break } a = this.ensureBuffer(i + r - 1); this.bufferLength += r - 1; if (r < 5) { for (; r < 5; ++r)s[r] = 117; this.eof = !0 } var o = 0; for (r = 0; r < 5; ++r)o = 85 * o + (s[r] - 33); for (r = 3; r >= 0; --r) { a[i + r] = 255 & o; o >>= 8 } } } else this.eof = !0 }; return e }(); t.Ascii85Stream = f; var g = function () { function e(e, t) { this.str = e; this.dict = e.dict; this.firstDigit = -1; t && (t *= .5); c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { var e = this.str.getBytes(8e3); if (e.length) { for (var t = e.length + 1 >> 1, a = this.ensureBuffer(this.bufferLength + t), r = this.bufferLength, i = this.firstDigit, n = 0, s = e.length; n < s; n++) { var o, c = e[n]; if (c >= 48 && c <= 57) o = 15 & c; else { if (!(c >= 65 && c <= 70 || c >= 97 && c <= 102)) { if (62 === c) { this.eof = !0; break } continue } o = 9 + (15 & c) } if (i < 0) i = o; else { a[r++] = i << 4 | o; i = -1 } } if (i >= 0 && this.eof) { a[r++] = i << 4; i = -1 } this.firstDigit = i; this.bufferLength = r } else this.eof = !0 }; return e }(); t.AsciiHexStream = g; var m = function () { function e(e, t) { this.str = e; this.dict = e.dict; c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { var e = this.str.getBytes(2); if (!e || e.length < 2 || 128 === e[0]) this.eof = !0; else { var t, a = this.bufferLength, r = e[0]; if (r < 128) { (t = this.ensureBuffer(a + r + 1))[a++] = e[1]; if (r > 0) { var i = this.str.getBytes(r); t.set(i, a); a += r } } else { r = 257 - r; var n = e[1]; t = this.ensureBuffer(a + r + 1); for (var s = 0; s < r; s++)t[a++] = n } this.bufferLength = a } }; return e }(); t.RunLengthStream = m; var p = function () { function e(e, t, a) { this.str = e; this.dict = e.dict; this.cachedData = 0; this.bitsCached = 0; for (var r = { earlyChange: a, codeLength: 9, nextCode: 258, dictionaryValues: new Uint8Array(4096), dictionaryLengths: new Uint16Array(4096), dictionaryPrevCodes: new Uint16Array(4096), currentSequence: new Uint8Array(4096), currentSequenceLength: 0 }, i = 0; i < 256; ++i) { r.dictionaryValues[i] = i; r.dictionaryLengths[i] = 1 } this.lzwState = r; c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBits = function (e) { for (var t = this.bitsCached, a = this.cachedData; t < e;) { var r = this.str.getByte(); if (-1 === r) { this.eof = !0; return null } a = a << 8 | r; t += 8 } this.bitsCached = t -= e; this.cachedData = a; this.lastCode = null; return a >>> t & (1 << e) - 1 }; e.prototype.readBlock = function () { var e, t, a, r = 1024, i = this.lzwState; if (i) { var n = i.earlyChange, s = i.nextCode, o = i.dictionaryValues, c = i.dictionaryLengths, l = i.dictionaryPrevCodes, h = i.codeLength, u = i.prevCode, d = i.currentSequence, f = i.currentSequenceLength, g = 0, m = this.bufferLength, p = this.ensureBuffer(this.bufferLength + r); for (e = 0; e < 512; e++) { var b = this.readBits(h), y = f > 0; if (b < 256) { d[0] = b; f = 1 } else { if (!(b >= 258)) { if (256 === b) { h = 9; s = 258; f = 0; continue } this.eof = !0; delete this.lzwState; break } if (b < s) for (t = (f = c[b]) - 1, a = b; t >= 0; t--) { d[t] = o[a]; a = l[a] } else d[f++] = d[0] } if (y) { l[s] = u; c[s] = c[u] + 1; o[s] = d[0]; h = ++s + n & s + n - 1 ? h : 0 | Math.min(Math.log(s + n) / .6931471805599453 + 1, 12) } u = b; if (r < (g += f)) { do { r += 512 } while (r < g); p = this.ensureBuffer(this.bufferLength + r) } for (t = 0; t < f; t++)p[m++] = d[t] } i.nextCode = s; i.codeLength = h; i.prevCode = u; i.currentSequenceLength = f; this.bufferLength = m } }; return e }(); t.LZWStream = p; var b = function () { function e() { s.call(this, new Uint8Array(0)) } e.prototype = s.prototype; return e }(); t.NullStream = b }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.CCITTFaxStream = void 0; var r = a(4), i = a(13), n = a(11), s = function () { function e(e, t, a) { this.str = e; this.dict = e.dict; (0, r.isDict)(a) || (a = r.Dict.empty); const s = { next: () => e.getByte() }; this.ccittFaxDecoder = new i.CCITTFaxDecoder(s, { K: a.get("K"), EndOfLine: a.get("EndOfLine"), EncodedByteAlign: a.get("EncodedByteAlign"), Columns: a.get("Columns"), Rows: a.get("Rows"), EndOfBlock: a.get("EndOfBlock"), BlackIs1: a.get("BlackIs1") }); n.DecodeStream.call(this, t) } e.prototype = Object.create(n.DecodeStream.prototype); e.prototype.readBlock = function () { for (; !this.eof;) { const e = this.ccittFaxDecoder.readNextChar(); if (-1 === e) { this.eof = !0; return } this.ensureBuffer(this.bufferLength + 1); this.buffer[this.bufferLength++] = e } }; return e }(); t.CCITTFaxStream = s }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.CCITTFaxDecoder = void 0; var r = a(2); const i = function () { const e = [[-1, -1], [-1, -1], [7, 8], [7, 7], [6, 6], [6, 6], [6, 5], [6, 5], [4, 0], [4, 0], [4, 0], [4, 0], [4, 0], [4, 0], [4, 0], [4, 0], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2]], t = [[-1, -1], [12, -2], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [12, 1984], [12, 2048], [12, 2112], [12, 2176], [12, 2240], [12, 2304], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [12, 2368], [12, 2432], [12, 2496], [12, 2560]], a = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [8, 29], [8, 29], [8, 30], [8, 30], [8, 45], [8, 45], [8, 46], [8, 46], [7, 22], [7, 22], [7, 22], [7, 22], [7, 23], [7, 23], [7, 23], [7, 23], [8, 47], [8, 47], [8, 48], [8, 48], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [7, 20], [7, 20], [7, 20], [7, 20], [8, 33], [8, 33], [8, 34], [8, 34], [8, 35], [8, 35], [8, 36], [8, 36], [8, 37], [8, 37], [8, 38], [8, 38], [7, 19], [7, 19], [7, 19], [7, 19], [8, 31], [8, 31], [8, 32], [8, 32], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [8, 53], [8, 53], [8, 54], [8, 54], [7, 26], [7, 26], [7, 26], [7, 26], [8, 39], [8, 39], [8, 40], [8, 40], [8, 41], [8, 41], [8, 42], [8, 42], [8, 43], [8, 43], [8, 44], [8, 44], [7, 21], [7, 21], [7, 21], [7, 21], [7, 28], [7, 28], [7, 28], [7, 28], [8, 61], [8, 61], [8, 62], [8, 62], [8, 63], [8, 63], [8, 0], [8, 0], [8, 320], [8, 320], [8, 384], [8, 384], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [7, 27], [7, 27], [7, 27], [7, 27], [8, 59], [8, 59], [8, 60], [8, 60], [9, 1472], [9, 1536], [9, 1600], [9, 1728], [7, 18], [7, 18], [7, 18], [7, 18], [7, 24], [7, 24], [7, 24], [7, 24], [8, 49], [8, 49], [8, 50], [8, 50], [8, 51], [8, 51], [8, 52], [8, 52], [7, 25], [7, 25], [7, 25], [7, 25], [8, 55], [8, 55], [8, 56], [8, 56], [8, 57], [8, 57], [8, 58], [8, 58], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [8, 448], [8, 448], [8, 512], [8, 512], [9, 704], [9, 768], [8, 640], [8, 640], [8, 576], [8, 576], [9, 832], [9, 896], [9, 960], [9, 1024], [9, 1088], [9, 1152], [9, 1216], [9, 1280], [9, 1344], [9, 1408], [7, 256], [7, 256], [7, 256], [7, 256], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7]], i = [[-1, -1], [-1, -1], [12, -2], [12, -2], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [11, 1792], [11, 1792], [12, 1984], [12, 1984], [12, 2048], [12, 2048], [12, 2112], [12, 2112], [12, 2176], [12, 2176], [12, 2240], [12, 2240], [12, 2304], [12, 2304], [11, 1856], [11, 1856], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [11, 1920], [11, 1920], [12, 2368], [12, 2368], [12, 2432], [12, 2432], [12, 2496], [12, 2496], [12, 2560], [12, 2560], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [12, 52], [12, 52], [13, 640], [13, 704], [13, 768], [13, 832], [12, 55], [12, 55], [12, 56], [12, 56], [13, 1280], [13, 1344], [13, 1408], [13, 1472], [12, 59], [12, 59], [12, 60], [12, 60], [13, 1536], [13, 1600], [11, 24], [11, 24], [11, 24], [11, 24], [11, 25], [11, 25], [11, 25], [11, 25], [13, 1664], [13, 1728], [12, 320], [12, 320], [12, 384], [12, 384], [12, 448], [12, 448], [13, 512], [13, 576], [12, 53], [12, 53], [12, 54], [12, 54], [13, 896], [13, 960], [13, 1024], [13, 1088], [13, 1152], [13, 1216], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64]], n = [[8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [11, 23], [11, 23], [12, 50], [12, 51], [12, 44], [12, 45], [12, 46], [12, 47], [12, 57], [12, 58], [12, 61], [12, 256], [10, 16], [10, 16], [10, 16], [10, 16], [10, 17], [10, 17], [10, 17], [10, 17], [12, 48], [12, 49], [12, 62], [12, 63], [12, 30], [12, 31], [12, 32], [12, 33], [12, 40], [12, 41], [11, 22], [11, 22], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [12, 128], [12, 192], [12, 26], [12, 27], [12, 28], [12, 29], [11, 19], [11, 19], [11, 20], [11, 20], [12, 34], [12, 35], [12, 36], [12, 37], [12, 38], [12, 39], [11, 21], [11, 21], [12, 42], [12, 43], [10, 0], [10, 0], [10, 0], [10, 0], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12]], s = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [6, 9], [6, 8], [5, 7], [5, 7], [4, 6], [4, 6], [4, 6], [4, 6], [4, 5], [4, 5], [4, 5], [4, 5], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]]; function o(e, t = {}) { if (!e || "function" != typeof e.next) throw new Error('CCITTFaxDecoder - invalid "source" parameter.'); this.source = e; this.eof = !1; this.encoding = t.K || 0; this.eoline = t.EndOfLine || !1; this.byteAlign = t.EncodedByteAlign || !1; this.columns = t.Columns || 1728; this.rows = t.Rows || 0; let a, r = t.EndOfBlock; null == r && (r = !0); this.eoblock = r; this.black = t.BlackIs1 || !1; this.codingLine = new Uint32Array(this.columns + 1); this.refLine = new Uint32Array(this.columns + 2); this.codingLine[0] = this.columns; this.codingPos = 0; this.row = 0; this.nextLine2D = this.encoding < 0; this.inputBits = 0; this.inputBuf = 0; this.outputBits = 0; this.rowsDone = !1; for (; 0 === (a = this._lookBits(12));)this._eatBits(1); 1 === a && this._eatBits(12); if (this.encoding > 0) { this.nextLine2D = !this._lookBits(1); this._eatBits(1) } } o.prototype = { readNextChar() { if (this.eof) return -1; const e = this.refLine, t = this.codingLine, a = this.columns; let i, n, s, o, c; if (0 === this.outputBits) { this.rowsDone && (this.eof = !0); if (this.eof) return -1; this.err = !1; let s, c, l; if (this.nextLine2D) { for (o = 0; t[o] < a; ++o)e[o] = t[o]; e[o++] = a; e[o] = a; t[0] = 0; this.codingPos = 0; i = 0; n = 0; for (; t[this.codingPos] < a;) { s = this._getTwoDimCode(); switch (s) { case 0: this._addPixels(e[i + 1], n); e[i + 1] < a && (i += 2); break; case 1: s = c = 0; if (n) { do { s += l = this._getBlackCode() } while (l >= 64); do { c += l = this._getWhiteCode() } while (l >= 64) } else { do { s += l = this._getWhiteCode() } while (l >= 64); do { c += l = this._getBlackCode() } while (l >= 64) } this._addPixels(t[this.codingPos] + s, n); t[this.codingPos] < a && this._addPixels(t[this.codingPos] + c, 1 ^ n); for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2; break; case 7: this._addPixels(e[i] + 3, n); n ^= 1; if (t[this.codingPos] < a) { ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 5: this._addPixels(e[i] + 2, n); n ^= 1; if (t[this.codingPos] < a) { ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 3: this._addPixels(e[i] + 1, n); n ^= 1; if (t[this.codingPos] < a) { ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 2: this._addPixels(e[i], n); n ^= 1; if (t[this.codingPos] < a) { ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 8: this._addPixelsNeg(e[i] - 3, n); n ^= 1; if (t[this.codingPos] < a) { i > 0 ? --i : ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 6: this._addPixelsNeg(e[i] - 2, n); n ^= 1; if (t[this.codingPos] < a) { i > 0 ? --i : ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 4: this._addPixelsNeg(e[i] - 1, n); n ^= 1; if (t[this.codingPos] < a) { i > 0 ? --i : ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case -1: this._addPixels(a, 0); this.eof = !0; break; default: (0, r.info)("bad 2d code"); this._addPixels(a, 0); this.err = !0 } } } else { t[0] = 0; this.codingPos = 0; n = 0; for (; t[this.codingPos] < a;) { s = 0; if (n) do { s += l = this._getBlackCode() } while (l >= 64); else do { s += l = this._getWhiteCode() } while (l >= 64); this._addPixels(t[this.codingPos] + s, n); n ^= 1 } } let h = !1; this.byteAlign && (this.inputBits &= -8); if (this.eoblock || this.row !== this.rows - 1) { s = this._lookBits(12); if (this.eoline) for (; -1 !== s && 1 !== s;) { this._eatBits(1); s = this._lookBits(12) } else for (; 0 === s;) { this._eatBits(1); s = this._lookBits(12) } if (1 === s) { this._eatBits(12); h = !0 } else -1 === s && (this.eof = !0) } else this.rowsDone = !0; if (!this.eof && this.encoding > 0 && !this.rowsDone) { this.nextLine2D = !this._lookBits(1); this._eatBits(1) } if (this.eoblock && h && this.byteAlign) { s = this._lookBits(12); if (1 === s) { this._eatBits(12); if (this.encoding > 0) { this._lookBits(1); this._eatBits(1) } if (this.encoding >= 0) for (o = 0; o < 4; ++o) { s = this._lookBits(12); 1 !== s && (0, r.info)("bad rtc code: " + s); this._eatBits(12); if (this.encoding > 0) { this._lookBits(1); this._eatBits(1) } } this.eof = !0 } } else if (this.err && this.eoline) { for (; ;) { s = this._lookBits(13); if (-1 === s) { this.eof = !0; return -1 } if (s >> 1 == 1) break; this._eatBits(1) } this._eatBits(12); if (this.encoding > 0) { this._eatBits(1); this.nextLine2D = !(1 & s) } } t[0] > 0 ? this.outputBits = t[this.codingPos = 0] : this.outputBits = t[this.codingPos = 1]; this.row++ } if (this.outputBits >= 8) { c = 1 & this.codingPos ? 0 : 255; this.outputBits -= 8; if (0 === this.outputBits && t[this.codingPos] < a) { this.codingPos++; this.outputBits = t[this.codingPos] - t[this.codingPos - 1] } } else { s = 8; c = 0; do { if (this.outputBits > s) { c <<= s; 1 & this.codingPos || (c |= 255 >> 8 - s); this.outputBits -= s; s = 0 } else { c <<= this.outputBits; 1 & this.codingPos || (c |= 255 >> 8 - this.outputBits); s -= this.outputBits; this.outputBits = 0; if (t[this.codingPos] < a) { this.codingPos++; this.outputBits = t[this.codingPos] - t[this.codingPos - 1] } else if (s > 0) { c <<= s; s = 0 } } } while (s) } this.black && (c ^= 255); return c }, _addPixels(e, t) { const a = this.codingLine; let i = this.codingPos; if (e > a[i]) { if (e > this.columns) { (0, r.info)("row is wrong length"); this.err = !0; e = this.columns } 1 & i ^ t && ++i; a[i] = e } this.codingPos = i }, _addPixelsNeg(e, t) { const a = this.codingLine; let i = this.codingPos; if (e > a[i]) { if (e > this.columns) { (0, r.info)("row is wrong length"); this.err = !0; e = this.columns } 1 & i ^ t && ++i; a[i] = e } else if (e < a[i]) { if (e < 0) { (0, r.info)("invalid code"); this.err = !0; e = 0 } for (; i > 0 && e < a[i - 1];)--i; a[i] = e } this.codingPos = i }, _findTableCode(e, t, a, r) { const i = r || 0; for (let r = e; r <= t; ++r) { let e = this._lookBits(r); if (-1 === e) return [!0, 1, !1]; r < t && (e <<= t - r); if (!i || e >= i) { const t = a[e - i]; if (t[0] === r) { this._eatBits(r); return [!0, t[1], !0] } } } return [!1, 0, !1] }, _getTwoDimCode() { let t, a = 0; if (this.eoblock) { a = this._lookBits(7); t = e[a]; if (t && t[0] > 0) { this._eatBits(t[0]); return t[1] } } else { const t = this._findTableCode(1, 7, e); if (t[0] && t[2]) return t[1] } (0, r.info)("Bad two dim code"); return -1 }, _getWhiteCode() { let e, i = 0; if (this.eoblock) { i = this._lookBits(12); if (-1 === i) return 1; e = i >> 5 == 0 ? t[i] : a[i >> 3]; if (e[0] > 0) { this._eatBits(e[0]); return e[1] } } else { let e = this._findTableCode(1, 9, a); if (e[0]) return e[1]; e = this._findTableCode(11, 12, t); if (e[0]) return e[1] } (0, r.info)("bad white code"); this._eatBits(1); return 1 }, _getBlackCode() { let e, t; if (this.eoblock) { e = this._lookBits(13); if (-1 === e) return 1; t = e >> 7 == 0 ? i[e] : e >> 9 == 0 && e >> 7 != 0 ? n[(e >> 1) - 64] : s[e >> 7]; if (t[0] > 0) { this._eatBits(t[0]); return t[1] } } else { let e = this._findTableCode(2, 6, s); if (e[0]) return e[1]; e = this._findTableCode(7, 12, n, 64); if (e[0]) return e[1]; e = this._findTableCode(10, 13, i); if (e[0]) return e[1] } (0, r.info)("bad black code"); this._eatBits(1); return 1 }, _lookBits(e) { let t; for (; this.inputBits < e;) { if (-1 === (t = this.source.next())) return 0 === this.inputBits ? -1 : this.inputBuf << e - this.inputBits & 65535 >> 16 - e; this.inputBuf = this.inputBuf << 8 | t; this.inputBits += 8 } return this.inputBuf >> this.inputBits - e & 65535 >> 16 - e }, _eatBits(e) { (this.inputBits -= e) < 0 && (this.inputBits = 0) } }; return o }(); t.CCITTFaxDecoder = i }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.Jbig2Stream = void 0; var r = a(4), i = a(11), n = a(15), s = a(2); const o = function () { function e(e, t, a, r) { this.stream = e; this.maybeLength = t; this.dict = a; this.params = r; i.DecodeStream.call(this, t) } e.prototype = Object.create(i.DecodeStream.prototype); Object.defineProperty(e.prototype, "bytes", { get() { return (0, s.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)) }, configurable: !0 }); e.prototype.ensureBuffer = function (e) { }; e.prototype.readBlock = function () { if (this.eof) return; const e = new n.Jbig2Image, t = []; if ((0, r.isDict)(this.params)) { const e = this.params.get("JBIG2Globals"); if ((0, r.isStream)(e)) { const a = e.getBytes(); t.push({ data: a, start: 0, end: a.length }) } } t.push({ data: this.bytes, start: 0, end: this.bytes.length }); const a = e.parseChunks(t), i = a.length; for (let e = 0; e < i; e++)a[e] ^= 255; this.buffer = a; this.bufferLength = i; this.eof = !0 }; return e }(); t.Jbig2Stream = o }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.Jbig2Image = void 0; var r = a(2), i = a(7), n = a(16), s = a(13); class o extends r.BaseException { constructor(e) { super(`JBIG2 error: ${e}`) } } var c = function () { function e() { } e.prototype = { getContexts(e) { return e in this ? this[e] : this[e] = new Int8Array(65536) } }; function t(e, t, a) { this.data = e; this.start = t; this.end = a } t.prototype = { get decoder() { var e = new n.ArithmeticDecoder(this.data, this.start, this.end); return (0, r.shadow)(this, "decoder", e) }, get contextCache() { var t = new e; return (0, r.shadow)(this, "contextCache", t) } }; function a(e, t, a) { var r = e.getContexts(t), i = 1; function n(e) { for (var t = 0, n = 0; n < e; n++) { var s = a.readBit(r, i); i = i < 256 ? i << 1 | s : 511 & (i << 1 | s) | 256; t = t << 1 | s } return t >>> 0 } var s = n(1), o = n(1) ? n(1) ? n(1) ? n(1) ? n(1) ? n(32) + 4436 : n(12) + 340 : n(8) + 84 : n(6) + 20 : n(4) + 4 : n(2); return 0 === s ? o : o > 0 ? -o : null } function c(e, t, a) { for (var r = e.getContexts("IAID"), i = 1, n = 0; n < a; n++) { i = i << 1 | t.readBit(r, i) } return a < 31 ? i & (1 << a) - 1 : 2147483647 & i } var l = ["SymbolDictionary", null, null, null, "IntermediateTextRegion", null, "ImmediateTextRegion", "ImmediateLosslessTextRegion", null, null, null, null, null, null, null, null, "PatternDictionary", null, null, null, "IntermediateHalftoneRegion", null, "ImmediateHalftoneRegion", "ImmediateLosslessHalftoneRegion", null, null, null, null, null, null, null, null, null, null, null, null, "IntermediateGenericRegion", null, "ImmediateGenericRegion", "ImmediateLosslessGenericRegion", "IntermediateGenericRefinementRegion", null, "ImmediateGenericRefinementRegion", "ImmediateLosslessGenericRefinementRegion", null, null, null, null, "PageInformation", "EndOfPage", "EndOfStripe", "EndOfFile", "Profiles", "Tables", null, null, null, null, null, null, null, null, "Extension"], h = [[{ x: -1, y: -2 }, { x: 0, y: -2 }, { x: 1, y: -2 }, { x: -2, y: -1 }, { x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: 2, y: -1 }, { x: -4, y: 0 }, { x: -3, y: 0 }, { x: -2, y: 0 }, { x: -1, y: 0 }], [{ x: -1, y: -2 }, { x: 0, y: -2 }, { x: 1, y: -2 }, { x: 2, y: -2 }, { x: -2, y: -1 }, { x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: 2, y: -1 }, { x: -3, y: 0 }, { x: -2, y: 0 }, { x: -1, y: 0 }], [{ x: -1, y: -2 }, { x: 0, y: -2 }, { x: 1, y: -2 }, { x: -2, y: -1 }, { x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: -2, y: 0 }, { x: -1, y: 0 }], [{ x: -3, y: -1 }, { x: -2, y: -1 }, { x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: -4, y: 0 }, { x: -3, y: 0 }, { x: -2, y: 0 }, { x: -1, y: 0 }]], u = [{ coding: [{ x: 0, y: -1 }, { x: 1, y: -1 }, { x: -1, y: 0 }], reference: [{ x: 0, y: -1 }, { x: 1, y: -1 }, { x: -1, y: 0 }, { x: 0, y: 0 }, { x: 1, y: 0 }, { x: -1, y: 1 }, { x: 0, y: 1 }, { x: 1, y: 1 }] }, { coding: [{ x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: -1, y: 0 }], reference: [{ x: 0, y: -1 }, { x: -1, y: 0 }, { x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }] }], d = [39717, 1941, 229, 405], f = [32, 8]; function g(e, t, a, r, i, n, s, o) { if (e) { return B(new E(o.data, o.start, o.end), t, a, !1) } if (0 === r && !n && !i && 4 === s.length && 3 === s[0].x && -1 === s[0].y && -3 === s[1].x && -1 === s[1].y && 2 === s[2].x && -2 === s[2].y && -2 === s[3].x && -2 === s[3].y) return function (e, t, a) { var r, i, n, s, o, c, l, h = a.decoder, u = a.contextCache.getContexts("GB"), d = []; for (i = 0; i < t; i++) { o = d[i] = new Uint8Array(e); c = i < 1 ? o : d[i - 1]; r = (l = i < 2 ? o : d[i - 2])[0] << 13 | l[1] << 12 | l[2] << 11 | c[0] << 7 | c[1] << 6 | c[2] << 5 | c[3] << 4; for (n = 0; n < e; n++) { o[n] = s = h.readBit(u, r); r = (31735 & r) << 1 | (n + 3 < e ? l[n + 3] << 11 : 0) | (n + 4 < e ? c[n + 4] << 4 : 0) | s } } return d }(t, a, o); var c = !!n, l = h[r].concat(s); l.sort((function (e, t) { return e.y - t.y || e.x - t.x })); var u, f, g = l.length, m = new Int8Array(g), p = new Int8Array(g), b = [], y = 0, v = 0, w = 0, k = 0; for (f = 0; f < g; f++) { m[f] = l[f].x; p[f] = l[f].y; v = Math.min(v, l[f].x); w = Math.max(w, l[f].x); k = Math.min(k, l[f].y); f < g - 1 && l[f].y === l[f + 1].y && l[f].x === l[f + 1].x - 1 ? y |= 1 << g - 1 - f : b.push(f) } var S = b.length, C = new Int8Array(S), x = new Int8Array(S), A = new Uint16Array(S); for (u = 0; u < S; u++) { f = b[u]; C[u] = l[f].x; x[u] = l[f].y; A[u] = 1 << g - 1 - f } for (var I, F, T, O, P, D = -v, N = -k, M = t - w, L = d[r], R = new Uint8Array(t), U = [], q = o.decoder, j = o.contextCache.getContexts("GB"), _ = 0, z = 0, H = 0; H < a; H++) { if (i) { if (_ ^= q.readBit(j, L)) { U.push(R); continue } } R = new Uint8Array(R); U.push(R); for (I = 0; I < t; I++)if (c && n[H][I]) R[I] = 0; else { if (I >= D && I < M && H >= N) { z = z << 1 & y; for (f = 0; f < S; f++) { F = H + x[f]; T = I + C[f]; (O = U[F][T]) && (z |= O = A[f]) } } else { z = 0; P = g - 1; for (f = 0; f < g; f++, P--)(T = I + m[f]) >= 0 && T < t && (F = H + p[f]) >= 0 && (O = U[F][T]) && (z |= O << P) } var G = q.readBit(j, z); R[I] = G } } return U } function m(e, t, a, r, i, n, s, c, l) { var h = u[a].coding; 0 === a && (h = h.concat([c[0]])); var d, g = h.length, m = new Int32Array(g), p = new Int32Array(g); for (d = 0; d < g; d++) { m[d] = h[d].x; p[d] = h[d].y } var b = u[a].reference; 0 === a && (b = b.concat([c[1]])); var y = b.length, v = new Int32Array(y), w = new Int32Array(y); for (d = 0; d < y; d++) { v[d] = b[d].x; w[d] = b[d].y } for (var k = r[0].length, S = r.length, C = f[a], x = [], A = l.decoder, I = l.contextCache.getContexts("GR"), F = 0, T = 0; T < t; T++) { if (s) { if (F ^= A.readBit(I, C)) throw new o("prediction is not supported") } var E = new Uint8Array(e); x.push(E); for (var O = 0; O < e; O++) { var P, B, D = 0; for (d = 0; d < g; d++) { P = T + p[d]; B = O + m[d]; P < 0 || B < 0 || B >= e ? D <<= 1 : D = D << 1 | x[P][B] } for (d = 0; d < y; d++) { P = T + w[d] - n; B = O + v[d] - i; P < 0 || P >= S || B < 0 || B >= k ? D <<= 1 : D = D << 1 | r[P][B] } var N = A.readBit(I, D); E[O] = N } } return x } function p(e, t, r, i, n, s, l, h, u, d, f, g, p, b, y, v, w, k, S) { if (e && t) throw new o("refinement with Huffman is not supported"); var C, x, A = []; for (C = 0; C < i; C++) { x = new Uint8Array(r); if (n) for (var I = 0; I < r; I++)x[I] = n; A.push(x) } var F = w.decoder, T = w.contextCache, E = e ? -b.tableDeltaT.decode(S) : -a(T, "IADT", F), O = 0; C = 0; for (; C < s;) { E += e ? b.tableDeltaT.decode(S) : a(T, "IADT", F); for (var P = O += e ? b.tableFirstS.decode(S) : a(T, "IAFS", F); ;) { let i = 0; l > 1 && (i = e ? S.readBits(k) : a(T, "IAIT", F)); var B = l * E + i, D = e ? b.symbolIDTable.decode(S) : c(T, F, u), N = t && (e ? S.readBit() : a(T, "IARI", F)), M = h[D], L = M[0].length, R = M.length; if (N) { var U = a(T, "IARDW", F), q = a(T, "IARDH", F); M = m(L += U, R += q, y, M, (U >> 1) + a(T, "IARDX", F), (q >> 1) + a(T, "IARDY", F), !1, v, w) } var j, _, z, H = B - (1 & g ? 0 : R - 1), G = P - (2 & g ? L - 1 : 0); if (d) { for (j = 0; j < R; j++)if (x = A[G + j]) { z = M[j]; var W = Math.min(r - H, L); switch (p) { case 0: for (_ = 0; _ < W; _++)x[H + _] |= z[_]; break; case 2: for (_ = 0; _ < W; _++)x[H + _] ^= z[_]; break; default: throw new o(`operator ${p} is not supported`) } } P += R - 1 } else { for (_ = 0; _ < R; _++)if (x = A[H + _]) { z = M[_]; switch (p) { case 0: for (j = 0; j < L; j++)x[G + j] |= z[j]; break; case 2: for (j = 0; j < L; j++)x[G + j] ^= z[j]; break; default: throw new o(`operator ${p} is not supported`) } } P += L - 1 } C++; var X = e ? b.tableDeltaS.decode(S) : a(T, "IADS", F); if (null === X) break; P += X + f } } return A } function b(e, t) { var a = {}; a.number = (0, i.readUint32)(e, t); var r = e[t + 4], n = 63 & r; if (!l[n]) throw new o("invalid segment type: " + n); a.type = n; a.typeName = l[n]; a.deferredNonRetain = !!(128 & r); var s = !!(64 & r), c = e[t + 5], h = c >> 5 & 7, u = [31 & c], d = t + 6; if (7 === c) { h = 536870911 & (0, i.readUint32)(e, d - 1); d += 3; var f = h + 7 >> 3; u[0] = e[d++]; for (; --f > 0;)u.push(e[d++]) } else if (5 === c || 6 === c) throw new o("invalid referred-to flags"); a.retainBits = u; let g = 4; a.number <= 256 ? g = 1 : a.number <= 65536 && (g = 2); var m, p, b = []; for (m = 0; m < h; m++) { let t; t = 1 === g ? e[d] : 2 === g ? (0, i.readUint16)(e, d) : (0, i.readUint32)(e, d); b.push(t); d += g } a.referredTo = b; if (s) { a.pageAssociation = (0, i.readUint32)(e, d); d += 4 } else a.pageAssociation = e[d++]; a.length = (0, i.readUint32)(e, d); d += 4; if (4294967295 === a.length) { if (38 !== n) throw new o("invalid unknown segment length"); var y = v(e, d), k = !!(1 & e[d + w]), S = new Uint8Array(6); if (!k) { S[0] = 255; S[1] = 172 } S[2] = y.height >>> 24 & 255; S[3] = y.height >> 16 & 255; S[4] = y.height >> 8 & 255; S[5] = 255 & y.height; for (m = d, p = e.length; m < p; m++) { for (var C = 0; C < 6 && S[C] === e[m + C];)C++; if (6 === C) { a.length = m + 6; break } } if (4294967295 === a.length) throw new o("segment end was not found") } a.headerEnd = d; return a } function y(e, t, a, r) { for (var i = [], n = a; n < r;) { var s = b(t, n); n = s.headerEnd; var o = { header: s, data: t }; if (!e.randomAccess) { o.start = n; n += s.length; o.end = n } i.push(o); if (51 === s.type) break } if (e.randomAccess) for (var c = 0, l = i.length; c < l; c++) { i[c].start = n; n += i[c].header.length; i[c].end = n } return i } function v(e, t) { return { width: (0, i.readUint32)(e, t), height: (0, i.readUint32)(e, t + 4), x: (0, i.readUint32)(e, t + 8), y: (0, i.readUint32)(e, t + 12), combinationOperator: 7 & e[t + 16] } } var w = 17; function k(e, t) { var a, r, n, s, c = e.header, l = e.data, h = e.start, u = e.end; switch (c.type) { case 0: var d = {}, f = (0, i.readUint16)(l, h); d.huffman = !!(1 & f); d.refinement = !!(2 & f); d.huffmanDHSelector = f >> 2 & 3; d.huffmanDWSelector = f >> 4 & 3; d.bitmapSizeSelector = f >> 6 & 1; d.aggregationInstancesSelector = f >> 7 & 1; d.bitmapCodingContextUsed = !!(256 & f); d.bitmapCodingContextRetained = !!(512 & f); d.template = f >> 10 & 3; d.refinementTemplate = f >> 12 & 1; h += 2; if (!d.huffman) { s = 0 === d.template ? 4 : 1; r = []; for (n = 0; n < s; n++) { r.push({ x: (0, i.readInt8)(l, h), y: (0, i.readInt8)(l, h + 1) }); h += 2 } d.at = r } if (d.refinement && !d.refinementTemplate) { r = []; for (n = 0; n < 2; n++) { r.push({ x: (0, i.readInt8)(l, h), y: (0, i.readInt8)(l, h + 1) }); h += 2 } d.refinementAt = r } d.numberOfExportedSymbols = (0, i.readUint32)(l, h); h += 4; d.numberOfNewSymbols = (0, i.readUint32)(l, h); h += 4; a = [d, c.number, c.referredTo, l, h, u]; break; case 6: case 7: var g = {}; g.info = v(l, h); h += w; var m = (0, i.readUint16)(l, h); h += 2; g.huffman = !!(1 & m); g.refinement = !!(2 & m); g.logStripSize = m >> 2 & 3; g.stripSize = 1 << g.logStripSize; g.referenceCorner = m >> 4 & 3; g.transposed = !!(64 & m); g.combinationOperator = m >> 7 & 3; g.defaultPixelValue = m >> 9 & 1; g.dsOffset = m << 17 >> 27; g.refinementTemplate = m >> 15 & 1; if (g.huffman) { var p = (0, i.readUint16)(l, h); h += 2; g.huffmanFS = 3 & p; g.huffmanDS = p >> 2 & 3; g.huffmanDT = p >> 4 & 3; g.huffmanRefinementDW = p >> 6 & 3; g.huffmanRefinementDH = p >> 8 & 3; g.huffmanRefinementDX = p >> 10 & 3; g.huffmanRefinementDY = p >> 12 & 3; g.huffmanRefinementSizeSelector = !!(16384 & p) } if (g.refinement && !g.refinementTemplate) { r = []; for (n = 0; n < 2; n++) { r.push({ x: (0, i.readInt8)(l, h), y: (0, i.readInt8)(l, h + 1) }); h += 2 } g.refinementAt = r } g.numberOfSymbolInstances = (0, i.readUint32)(l, h); h += 4; a = [g, c.referredTo, l, h, u]; break; case 16: const e = {}, t = l[h++]; e.mmr = !!(1 & t); e.template = t >> 1 & 3; e.patternWidth = l[h++]; e.patternHeight = l[h++]; e.maxPatternIndex = (0, i.readUint32)(l, h); h += 4; a = [e, c.number, l, h, u]; break; case 22: case 23: const C = {}; C.info = v(l, h); h += w; const x = l[h++]; C.mmr = !!(1 & x); C.template = x >> 1 & 3; C.enableSkip = !!(8 & x); C.combinationOperator = x >> 4 & 7; C.defaultPixelValue = x >> 7 & 1; C.gridWidth = (0, i.readUint32)(l, h); h += 4; C.gridHeight = (0, i.readUint32)(l, h); h += 4; C.gridOffsetX = 4294967295 & (0, i.readUint32)(l, h); h += 4; C.gridOffsetY = 4294967295 & (0, i.readUint32)(l, h); h += 4; C.gridVectorX = (0, i.readUint16)(l, h); h += 2; C.gridVectorY = (0, i.readUint16)(l, h); h += 2; a = [C, c.referredTo, l, h, u]; break; case 38: case 39: var b = {}; b.info = v(l, h); h += w; var y = l[h++]; b.mmr = !!(1 & y); b.template = y >> 1 & 3; b.prediction = !!(8 & y); if (!b.mmr) { s = 0 === b.template ? 4 : 1; r = []; for (n = 0; n < s; n++) { r.push({ x: (0, i.readInt8)(l, h), y: (0, i.readInt8)(l, h + 1) }); h += 2 } b.at = r } a = [b, l, h, u]; break; case 48: var k = { width: (0, i.readUint32)(l, h), height: (0, i.readUint32)(l, h + 4), resolutionX: (0, i.readUint32)(l, h + 8), resolutionY: (0, i.readUint32)(l, h + 12) }; 4294967295 === k.height && delete k.height; var S = l[h + 16]; (0, i.readUint16)(l, h + 17); k.lossless = !!(1 & S); k.refinement = !!(2 & S); k.defaultPixelValue = S >> 2 & 1; k.combinationOperator = S >> 3 & 3; k.requiresBuffer = !!(32 & S); k.combinationOperatorOverride = !!(64 & S); a = [k]; break; case 49: case 50: case 51: break; case 53: a = [c.number, l, h, u]; break; case 62: break; default: throw new o(`segment type ${c.typeName}(${c.type})` + " is not implemented") }var C = "on" + c.typeName; C in t && t[C].apply(t, a) } function S(e, t) { for (var a = 0, r = e.length; a < r; a++)k(e[a], t) } function C() { } C.prototype = { onPageInformation: function (e) { this.currentPageInfo = e; var t = e.width + 7 >> 3, a = new Uint8ClampedArray(t * e.height); if (e.defaultPixelValue) for (var r = 0, i = a.length; r < i; r++)a[r] = 255; this.buffer = a }, drawBitmap: function (e, t) { var a, r, i, n, s = this.currentPageInfo, c = e.width, l = e.height, h = s.width + 7 >> 3, u = s.combinationOperatorOverride ? e.combinationOperator : s.combinationOperator, d = this.buffer, f = 128 >> (7 & e.x), g = e.y * h + (e.x >> 3); switch (u) { case 0: for (a = 0; a < l; a++) { i = f; n = g; for (r = 0; r < c; r++) { t[a][r] && (d[n] |= i); if (!(i >>= 1)) { i = 128; n++ } } g += h } break; case 2: for (a = 0; a < l; a++) { i = f; n = g; for (r = 0; r < c; r++) { t[a][r] && (d[n] ^= i); if (!(i >>= 1)) { i = 128; n++ } } g += h } break; default: throw new o(`operator ${u} is not supported`) } }, onImmediateGenericRegion: function (e, a, r, i) { var n = e.info, s = new t(a, r, i), o = g(e.mmr, n.width, n.height, e.template, e.prediction, null, e.at, s); this.drawBitmap(n, o) }, onImmediateLosslessGenericRegion: function () { this.onImmediateGenericRegion.apply(this, arguments) }, onSymbolDictionary: function (e, r, n, s, l, h) { let u, d; if (e.huffman) { u = function (e, t, a) { let r, i, n, s, c = 0; switch (e.huffmanDHSelector) { case 0: case 1: r = T(e.huffmanDHSelector + 4); break; case 3: r = O(c, t, a); c++; break; default: throw new o("invalid Huffman DH selector") }switch (e.huffmanDWSelector) { case 0: case 1: i = T(e.huffmanDWSelector + 2); break; case 3: i = O(c, t, a); c++; break; default: throw new o("invalid Huffman DW selector") }if (e.bitmapSizeSelector) { n = O(c, t, a); c++ } else n = T(1); s = e.aggregationInstancesSelector ? O(c, t, a) : T(1); return { tableDeltaHeight: r, tableDeltaWidth: i, tableBitmapSize: n, tableAggregateInstances: s } }(e, n, this.customTables); d = new E(s, l, h) } var f = this.symbols; f || (this.symbols = f = {}); for (var b = [], y = 0, v = n.length; y < v; y++) { const e = f[n[y]]; e && (b = b.concat(e)) } var w = new t(s, l, h); f[r] = function (e, t, r, n, s, l, h, u, d, f, b, y) { if (e && t) throw new o("symbol refinement with Huffman is not supported"); var v = [], w = 0, k = (0, i.log2)(r.length + n), S = b.decoder, C = b.contextCache; let x, A; if (e) { x = T(1); A = []; k = Math.max(k, 1) } for (; v.length < n;) { w += e ? l.tableDeltaHeight.decode(y) : a(C, "IADH", S); let i = 0, n = 0; const s = e ? A.length : 0; for (; ;) { var I, F = e ? l.tableDeltaWidth.decode(y) : a(C, "IADW", S); if (null === F) break; i += F; n += i; if (t) { var E = a(C, "IAAI", S); if (E > 1) I = p(e, t, i, w, 0, E, 1, r.concat(v), k, 0, 0, 1, 0, l, d, f, b, 0, y); else { var O = c(C, S, k), D = a(C, "IARDX", S), N = a(C, "IARDY", S); I = m(i, w, d, O < r.length ? r[O] : v[O - r.length], D, N, !1, f, b) } v.push(I) } else if (e) A.push(i); else { I = g(!1, i, w, h, !1, null, u, b); v.push(I) } } if (e && !t) { const e = l.tableBitmapSize.decode(y); y.byteAlign(); let t; if (0 === e) t = P(y, n, w); else { const a = y.end, r = y.position + e; y.end = r; t = B(y, n, w, !1); y.end = a; y.position = r } const a = A.length; if (s === a - 1) v.push(t); else { let e, r, i, n, o, c = 0; for (e = s; e < a; e++) { n = A[e]; i = c + n; o = []; for (r = 0; r < w; r++)o.push(t[r].subarray(c, i)); v.push(o); c = i } } } } for (var M = [], L = [], R = !1, U = r.length + n; L.length < U;) { for (var q = e ? x.decode(y) : a(C, "IAEX", S); q--;)L.push(R); R = !R } for (var j = 0, _ = r.length; j < _; j++)L[j] && M.push(r[j]); for (var z = 0; z < n; j++, z++)L[j] && M.push(v[z]); return M }(e.huffman, e.refinement, b, e.numberOfNewSymbols, e.numberOfExportedSymbols, u, e.template, e.at, e.refinementTemplate, e.refinementAt, w, d) }, onImmediateTextRegion: function (e, a, r, n, s) { var c = e.info; let l, h; for (var u = this.symbols, d = [], f = 0, g = a.length; f < g; f++) { const e = u[a[f]]; e && (d = d.concat(e)) } var m = (0, i.log2)(d.length); if (e.huffman) { h = new E(r, n, s); l = function (e, t, a, r, i) { const n = []; for (let e = 0; e <= 34; e++) { const t = i.readBits(4); n.push(new x([e, t, 0, 0])) } const s = new I(n, !1); n.length = 0; for (let e = 0; e < r;) { const t = s.decode(i); if (t >= 32) { let a, r, s; switch (t) { case 32: if (0 === e) throw new o("no previous value in symbol ID table"); r = i.readBits(2) + 3; a = n[e - 1].prefixLength; break; case 33: r = i.readBits(3) + 3; a = 0; break; case 34: r = i.readBits(7) + 11; a = 0; break; default: throw new o("invalid code length in symbol ID table") }for (s = 0; s < r; s++) { n.push(new x([e, a, 0, 0])); e++ } } else { n.push(new x([e, t, 0, 0])); e++ } } i.byteAlign(); const c = new I(n, !1); let l, h, u, d = 0; switch (e.huffmanFS) { case 0: case 1: l = T(e.huffmanFS + 6); break; case 3: l = O(d, t, a); d++; break; default: throw new o("invalid Huffman FS selector") }switch (e.huffmanDS) { case 0: case 1: case 2: h = T(e.huffmanDS + 8); break; case 3: h = O(d, t, a); d++; break; default: throw new o("invalid Huffman DS selector") }switch (e.huffmanDT) { case 0: case 1: case 2: u = T(e.huffmanDT + 11); break; case 3: u = O(d, t, a); d++; break; default: throw new o("invalid Huffman DT selector") }if (e.refinement) throw new o("refinement with Huffman is not supported"); return { symbolIDTable: c, tableFirstS: l, tableDeltaS: h, tableDeltaT: u } }(e, a, this.customTables, d.length, h) } var b = new t(r, n, s), y = p(e.huffman, e.refinement, c.width, c.height, e.defaultPixelValue, e.numberOfSymbolInstances, e.stripSize, d, m, e.transposed, e.dsOffset, e.referenceCorner, e.combinationOperator, l, e.refinementTemplate, e.refinementAt, b, e.logStripSize, h); this.drawBitmap(c, y) }, onImmediateLosslessTextRegion: function () { this.onImmediateTextRegion.apply(this, arguments) }, onPatternDictionary(e, a, r, i, n) { let s = this.patterns; s || (this.patterns = s = {}); const o = new t(r, i, n); s[a] = function (e, t, a, r, i, n) { const s = []; if (!e) { s.push({ x: -t, y: 0 }); if (0 === i) { s.push({ x: -3, y: -1 }); s.push({ x: 2, y: -2 }); s.push({ x: -2, y: -2 }) } } const o = g(e, (r + 1) * t, a, i, !1, null, s, n), c = []; for (let e = 0; e <= r; e++) { const r = [], i = t * e, n = i + t; for (let e = 0; e < a; e++)r.push(o[e].subarray(i, n)); c.push(r) } return c }(e.mmr, e.patternWidth, e.patternHeight, e.maxPatternIndex, e.template, o) }, onImmediateHalftoneRegion(e, a, r, n, s) { const c = this.patterns[a[0]], l = e.info, h = new t(r, n, s), u = function (e, t, a, r, n, s, c, l, h, u, d, f, m, p, b) { if (c) throw new o("skip is not supported"); if (0 !== l) throw new o("operator " + l + " is not supported in halftone region"); const y = []; let v, w, k; for (v = 0; v < n; v++) { k = new Uint8Array(r); if (s) for (w = 0; w < r; w++)k[w] = s; y.push(k) } const S = t.length, C = t[0], x = C[0].length, A = C.length, I = (0, i.log2)(S), F = []; if (!e) { F.push({ x: a <= 1 ? 3 : 2, y: -1 }); if (0 === a) { F.push({ x: -3, y: -1 }); F.push({ x: 2, y: -2 }); F.push({ x: -2, y: -2 }) } } const T = []; let O, P, D, N, M, L, R, U, q, j, _; e && (O = new E(b.data, b.start, b.end)); for (v = I - 1; v >= 0; v--) { P = e ? B(O, h, u, !0) : g(!1, h, u, a, !1, null, F, b); T[v] = P } for (D = 0; D < u; D++)for (N = 0; N < h; N++) { M = 0; L = 0; for (w = I - 1; w >= 0; w--) { M = T[w][D][N] ^ M; L |= M << w } R = t[L]; U = d + D * p + N * m >> 8; q = f + D * m - N * p >> 8; if (U >= 0 && U + x <= r && q >= 0 && q + A <= n) for (v = 0; v < A; v++) { _ = y[q + v]; j = R[v]; for (w = 0; w < x; w++)_[U + w] |= j[w] } else { let e, t; for (v = 0; v < A; v++) { t = q + v; if (!(t < 0 || t >= n)) { _ = y[t]; j = R[v]; for (w = 0; w < x; w++) { e = U + w; e >= 0 && e < r && (_[e] |= j[w]) } } } } } return y }(e.mmr, c, e.template, l.width, l.height, e.defaultPixelValue, e.enableSkip, e.combinationOperator, e.gridWidth, e.gridHeight, e.gridOffsetX, e.gridOffsetY, e.gridVectorX, e.gridVectorY, h); this.drawBitmap(l, u) }, onImmediateLosslessHalftoneRegion() { this.onImmediateHalftoneRegion.apply(this, arguments) }, onTables(e, t, a, r) { let n = this.customTables; n || (this.customTables = n = {}); n[e] = function (e, t, a) { const r = e[t], n = 4294967295 & (0, i.readUint32)(e, t + 1), s = 4294967295 & (0, i.readUint32)(e, t + 5), o = new E(e, t + 9, a), c = 1 + (r >> 1 & 7), l = 1 + (r >> 4 & 7), h = []; let u, d, f = n; do { u = o.readBits(c); d = o.readBits(l); h.push(new x([f, u, d, 0])); f += 1 << d } while (f < s); u = o.readBits(c); h.push(new x([n - 1, u, 32, 0, "lower"])); u = o.readBits(c); h.push(new x([s, u, 32, 0])); if (1 & r) { u = o.readBits(c); h.push(new x([u, 0])) } return new I(h, !1) }(t, a, r) } }; function x(e) { if (2 === e.length) { this.isOOB = !0; this.rangeLow = 0; this.prefixLength = e[0]; this.rangeLength = 0; this.prefixCode = e[1]; this.isLowerRange = !1 } else { this.isOOB = !1; this.rangeLow = e[0]; this.prefixLength = e[1]; this.rangeLength = e[2]; this.prefixCode = e[3]; this.isLowerRange = "lower" === e[4] } } function A(e) { this.children = []; if (e) { this.isLeaf = !0; this.rangeLength = e.rangeLength; this.rangeLow = e.rangeLow; this.isLowerRange = e.isLowerRange; this.isOOB = e.isOOB } else this.isLeaf = !1 } A.prototype = { buildTree(e, t) { const a = e.prefixCode >> t & 1; if (t <= 0) this.children[a] = new A(e); else { let r = this.children[a]; r || (this.children[a] = r = new A(null)); r.buildTree(e, t - 1) } }, decodeNode(e) { if (this.isLeaf) { if (this.isOOB) return null; const t = e.readBits(this.rangeLength); return this.rangeLow + (this.isLowerRange ? -t : t) } const t = this.children[e.readBit()]; if (!t) throw new o("invalid Huffman data"); return t.decodeNode(e) } }; function I(e, t) { t || this.assignPrefixCodes(e); this.rootNode = new A(null); for (let t = 0, a = e.length; t < a; t++) { const a = e[t]; a.prefixLength > 0 && this.rootNode.buildTree(a, a.prefixLength - 1) } } I.prototype = { decode(e) { return this.rootNode.decodeNode(e) }, assignPrefixCodes(e) { const t = e.length; let a = 0; for (let r = 0; r < t; r++)a = Math.max(a, e[r].prefixLength); const r = new Uint32Array(a + 1); for (let a = 0; a < t; a++)r[e[a].prefixLength]++; let i, n, s, o = 1, c = 0; r[0] = 0; for (; o <= a;) { c = c + r[o - 1] << 1; i = c; n = 0; for (; n < t;) { s = e[n]; if (s.prefixLength === o) { s.prefixCode = i; i++ } n++ } o++ } } }; const F = {}; function T(e) { let t, a = F[e]; if (a) return a; switch (e) { case 1: t = [[0, 1, 4, 0], [16, 2, 8, 2], [272, 3, 16, 6], [65808, 3, 32, 7]]; break; case 2: t = [[0, 1, 0, 0], [1, 2, 0, 2], [2, 3, 0, 6], [3, 4, 3, 14], [11, 5, 6, 30], [75, 6, 32, 62], [6, 63]]; break; case 3: t = [[-256, 8, 8, 254], [0, 1, 0, 0], [1, 2, 0, 2], [2, 3, 0, 6], [3, 4, 3, 14], [11, 5, 6, 30], [-257, 8, 32, 255, "lower"], [75, 7, 32, 126], [6, 62]]; break; case 4: t = [[1, 1, 0, 0], [2, 2, 0, 2], [3, 3, 0, 6], [4, 4, 3, 14], [12, 5, 6, 30], [76, 5, 32, 31]]; break; case 5: t = [[-255, 7, 8, 126], [1, 1, 0, 0], [2, 2, 0, 2], [3, 3, 0, 6], [4, 4, 3, 14], [12, 5, 6, 30], [-256, 7, 32, 127, "lower"], [76, 6, 32, 62]]; break; case 6: t = [[-2048, 5, 10, 28], [-1024, 4, 9, 8], [-512, 4, 8, 9], [-256, 4, 7, 10], [-128, 5, 6, 29], [-64, 5, 5, 30], [-32, 4, 5, 11], [0, 2, 7, 0], [128, 3, 7, 2], [256, 3, 8, 3], [512, 4, 9, 12], [1024, 4, 10, 13], [-2049, 6, 32, 62, "lower"], [2048, 6, 32, 63]]; break; case 7: t = [[-1024, 4, 9, 8], [-512, 3, 8, 0], [-256, 4, 7, 9], [-128, 5, 6, 26], [-64, 5, 5, 27], [-32, 4, 5, 10], [0, 4, 5, 11], [32, 5, 5, 28], [64, 5, 6, 29], [128, 4, 7, 12], [256, 3, 8, 1], [512, 3, 9, 2], [1024, 3, 10, 3], [-1025, 5, 32, 30, "lower"], [2048, 5, 32, 31]]; break; case 8: t = [[-15, 8, 3, 252], [-7, 9, 1, 508], [-5, 8, 1, 253], [-3, 9, 0, 509], [-2, 7, 0, 124], [-1, 4, 0, 10], [0, 2, 1, 0], [2, 5, 0, 26], [3, 6, 0, 58], [4, 3, 4, 4], [20, 6, 1, 59], [22, 4, 4, 11], [38, 4, 5, 12], [70, 5, 6, 27], [134, 5, 7, 28], [262, 6, 7, 60], [390, 7, 8, 125], [646, 6, 10, 61], [-16, 9, 32, 510, "lower"], [1670, 9, 32, 511], [2, 1]]; break; case 9: t = [[-31, 8, 4, 252], [-15, 9, 2, 508], [-11, 8, 2, 253], [-7, 9, 1, 509], [-5, 7, 1, 124], [-3, 4, 1, 10], [-1, 3, 1, 2], [1, 3, 1, 3], [3, 5, 1, 26], [5, 6, 1, 58], [7, 3, 5, 4], [39, 6, 2, 59], [43, 4, 5, 11], [75, 4, 6, 12], [139, 5, 7, 27], [267, 5, 8, 28], [523, 6, 8, 60], [779, 7, 9, 125], [1291, 6, 11, 61], [-32, 9, 32, 510, "lower"], [3339, 9, 32, 511], [2, 0]]; break; case 10: t = [[-21, 7, 4, 122], [-5, 8, 0, 252], [-4, 7, 0, 123], [-3, 5, 0, 24], [-2, 2, 2, 0], [2, 5, 0, 25], [3, 6, 0, 54], [4, 7, 0, 124], [5, 8, 0, 253], [6, 2, 6, 1], [70, 5, 5, 26], [102, 6, 5, 55], [134, 6, 6, 56], [198, 6, 7, 57], [326, 6, 8, 58], [582, 6, 9, 59], [1094, 6, 10, 60], [2118, 7, 11, 125], [-22, 8, 32, 254, "lower"], [4166, 8, 32, 255], [2, 2]]; break; case 11: t = [[1, 1, 0, 0], [2, 2, 1, 2], [4, 4, 0, 12], [5, 4, 1, 13], [7, 5, 1, 28], [9, 5, 2, 29], [13, 6, 2, 60], [17, 7, 2, 122], [21, 7, 3, 123], [29, 7, 4, 124], [45, 7, 5, 125], [77, 7, 6, 126], [141, 7, 32, 127]]; break; case 12: t = [[1, 1, 0, 0], [2, 2, 0, 2], [3, 3, 1, 6], [5, 5, 0, 28], [6, 5, 1, 29], [8, 6, 1, 60], [10, 7, 0, 122], [11, 7, 1, 123], [13, 7, 2, 124], [17, 7, 3, 125], [25, 7, 4, 126], [41, 8, 5, 254], [73, 8, 32, 255]]; break; case 13: t = [[1, 1, 0, 0], [2, 3, 0, 4], [3, 4, 0, 12], [4, 5, 0, 28], [5, 4, 1, 13], [7, 3, 3, 5], [15, 6, 1, 58], [17, 6, 2, 59], [21, 6, 3, 60], [29, 6, 4, 61], [45, 6, 5, 62], [77, 7, 6, 126], [141, 7, 32, 127]]; break; case 14: t = [[-2, 3, 0, 4], [-1, 3, 0, 5], [0, 1, 0, 0], [1, 3, 0, 6], [2, 3, 0, 7]]; break; case 15: t = [[-24, 7, 4, 124], [-8, 6, 2, 60], [-4, 5, 1, 28], [-2, 4, 0, 12], [-1, 3, 0, 4], [0, 1, 0, 0], [1, 3, 0, 5], [2, 4, 0, 13], [3, 5, 1, 29], [5, 6, 2, 61], [9, 7, 4, 125], [-25, 7, 32, 126, "lower"], [25, 7, 32, 127]]; break; default: throw new o(`standard table B.${e} does not exist`) }for (let e = 0, a = t.length; e < a; e++)t[e] = new x(t[e]); a = new I(t, !0); F[e] = a; return a } function E(e, t, a) { this.data = e; this.start = t; this.end = a; this.position = t; this.shift = -1; this.currentByte = 0 } E.prototype = { readBit() { if (this.shift < 0) { if (this.position >= this.end) throw new o("end of data while reading bit"); this.currentByte = this.data[this.position++]; this.shift = 7 } const e = this.currentByte >> this.shift & 1; this.shift--; return e }, readBits(e) { let t, a = 0; for (t = e - 1; t >= 0; t--)a |= this.readBit() << t; return a }, byteAlign() { this.shift = -1 }, next() { return this.position >= this.end ? -1 : this.data[this.position++] } }; function O(e, t, a) { let r = 0; for (let i = 0, n = t.length; i < n; i++) { const n = a[t[i]]; if (n) { if (e === r) return n; r++ } } throw new o("can't find custom Huffman table") } function P(e, t, a) { const r = []; for (let i = 0; i < a; i++) { const a = new Uint8Array(t); r.push(a); for (let r = 0; r < t; r++)a[r] = e.readBit(); e.byteAlign() } return r } function B(e, t, a, r) { const i = { K: -1, Columns: t, Rows: a, BlackIs1: !0, EndOfBlock: r }, n = new s.CCITTFaxDecoder(e, i), o = []; let c, l = !1; for (let e = 0; e < a; e++) { const e = new Uint8Array(t); o.push(e); let a = -1; for (let r = 0; r < t; r++) { if (a < 0) { c = n.readNextChar(); if (-1 === c) { c = 0; l = !0 } a = 7 } e[r] = c >> a & 1; a-- } } if (r && !l) { const e = 5; for (let t = 0; t < e && -1 !== n.readNextChar(); t++); } return o } function D() { } D.prototype = { parseChunks: e => function (e) { for (var t = new C, a = 0, r = e.length; a < r; a++) { var i = e[a]; S(y({}, i.data, i.start, i.end), t) } return t.buffer }(e), parse(e) { const { imgData: t, width: a, height: r } = function (e) { const t = e.length; let a = 0; if (151 !== e[a] || 74 !== e[a + 1] || 66 !== e[a + 2] || 50 !== e[a + 3] || 13 !== e[a + 4] || 10 !== e[a + 5] || 26 !== e[a + 6] || 10 !== e[a + 7]) throw new o("parseJbig2 - invalid header."); const r = Object.create(null); a += 8; const n = e[a++]; r.randomAccess = !(1 & n); if (!(2 & n)) { r.numberOfPages = (0, i.readUint32)(e, a); a += 4 } const s = y(r, e, a, t), c = new C; S(s, c); const { width: l, height: h } = c.currentPageInfo, u = c.buffer, d = new Uint8ClampedArray(l * h); let f = 0, g = 0; for (let e = 0; e < h; e++) { let e, t = 0; for (let a = 0; a < l; a++) { if (!t) { t = 128; e = u[g++] } d[f++] = e & t ? 0 : 255; t >>= 1 } } return { imgData: d, width: l, height: h } }(e); this.width = a; this.height = r; return t } }; return D }(); t.Jbig2Image = c }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.ArithmeticDecoder = void 0; const r = [{ qe: 22017, nmps: 1, nlps: 1, switchFlag: 1 }, { qe: 13313, nmps: 2, nlps: 6, switchFlag: 0 }, { qe: 6145, nmps: 3, nlps: 9, switchFlag: 0 }, { qe: 2753, nmps: 4, nlps: 12, switchFlag: 0 }, { qe: 1313, nmps: 5, nlps: 29, switchFlag: 0 }, { qe: 545, nmps: 38, nlps: 33, switchFlag: 0 }, { qe: 22017, nmps: 7, nlps: 6, switchFlag: 1 }, { qe: 21505, nmps: 8, nlps: 14, switchFlag: 0 }, { qe: 18433, nmps: 9, nlps: 14, switchFlag: 0 }, { qe: 14337, nmps: 10, nlps: 14, switchFlag: 0 }, { qe: 12289, nmps: 11, nlps: 17, switchFlag: 0 }, { qe: 9217, nmps: 12, nlps: 18, switchFlag: 0 }, { qe: 7169, nmps: 13, nlps: 20, switchFlag: 0 }, { qe: 5633, nmps: 29, nlps: 21, switchFlag: 0 }, { qe: 22017, nmps: 15, nlps: 14, switchFlag: 1 }, { qe: 21505, nmps: 16, nlps: 14, switchFlag: 0 }, { qe: 20737, nmps: 17, nlps: 15, switchFlag: 0 }, { qe: 18433, nmps: 18, nlps: 16, switchFlag: 0 }, { qe: 14337, nmps: 19, nlps: 17, switchFlag: 0 }, { qe: 13313, nmps: 20, nlps: 18, switchFlag: 0 }, { qe: 12289, nmps: 21, nlps: 19, switchFlag: 0 }, { qe: 10241, nmps: 22, nlps: 19, switchFlag: 0 }, { qe: 9217, nmps: 23, nlps: 20, switchFlag: 0 }, { qe: 8705, nmps: 24, nlps: 21, switchFlag: 0 }, { qe: 7169, nmps: 25, nlps: 22, switchFlag: 0 }, { qe: 6145, nmps: 26, nlps: 23, switchFlag: 0 }, { qe: 5633, nmps: 27, nlps: 24, switchFlag: 0 }, { qe: 5121, nmps: 28, nlps: 25, switchFlag: 0 }, { qe: 4609, nmps: 29, nlps: 26, switchFlag: 0 }, { qe: 4353, nmps: 30, nlps: 27, switchFlag: 0 }, { qe: 2753, nmps: 31, nlps: 28, switchFlag: 0 }, { qe: 2497, nmps: 32, nlps: 29, switchFlag: 0 }, { qe: 2209, nmps: 33, nlps: 30, switchFlag: 0 }, { qe: 1313, nmps: 34, nlps: 31, switchFlag: 0 }, { qe: 1089, nmps: 35, nlps: 32, switchFlag: 0 }, { qe: 673, nmps: 36, nlps: 33, switchFlag: 0 }, { qe: 545, nmps: 37, nlps: 34, switchFlag: 0 }, { qe: 321, nmps: 38, nlps: 35, switchFlag: 0 }, { qe: 273, nmps: 39, nlps: 36, switchFlag: 0 }, { qe: 133, nmps: 40, nlps: 37, switchFlag: 0 }, { qe: 73, nmps: 41, nlps: 38, switchFlag: 0 }, { qe: 37, nmps: 42, nlps: 39, switchFlag: 0 }, { qe: 21, nmps: 43, nlps: 40, switchFlag: 0 }, { qe: 9, nmps: 44, nlps: 41, switchFlag: 0 }, { qe: 5, nmps: 45, nlps: 42, switchFlag: 0 }, { qe: 1, nmps: 45, nlps: 43, switchFlag: 0 }, { qe: 22017, nmps: 46, nlps: 46, switchFlag: 0 }]; t.ArithmeticDecoder = class { constructor(e, t, a) { this.data = e; this.bp = t; this.dataEnd = a; this.chigh = e[t]; this.clow = 0; this.byteIn(); this.chigh = this.chigh << 7 & 65535 | this.clow >> 9 & 127; this.clow = this.clow << 7 & 65535; this.ct -= 7; this.a = 32768 } byteIn() { const e = this.data; let t = this.bp; if (255 === e[t]) if (e[t + 1] > 143) { this.clow += 65280; this.ct = 8 } else { t++; this.clow += e[t] << 9; this.ct = 7; this.bp = t } else { t++; this.clow += t < this.dataEnd ? e[t] << 8 : 65280; this.ct = 8; this.bp = t } if (this.clow > 65535) { this.chigh += this.clow >> 16; this.clow &= 65535 } } readBit(e, t) { let a = e[t] >> 1, i = 1 & e[t]; const n = r[a], s = n.qe; let o, c = this.a - s; if (this.chigh < s) if (c < s) { c = s; o = i; a = n.nmps } else { c = s; o = 1 ^ i; 1 === n.switchFlag && (i = o); a = n.nlps } else { this.chigh -= s; if (0 != (32768 & c)) { this.a = c; return i } if (c < s) { o = 1 ^ i; 1 === n.switchFlag && (i = o); a = n.nlps } else { o = i; a = n.nmps } } do { 0 === this.ct && this.byteIn(); c <<= 1; this.chigh = this.chigh << 1 & 65535 | this.clow >> 15 & 1; this.clow = this.clow << 1 & 65535; this.ct-- } while (0 == (32768 & c)); this.a = c; e[t] = a << 1 | i; return o } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.JpegStream = void 0; var r = a(2), i = a(11), n = a(4), s = a(18); const o = function () { function e(e, t, a, r) { let n; for (; -1 !== (n = e.getByte());)if (255 === n) { e.skip(-1); break } this.stream = e; this.maybeLength = t; this.dict = a; this.params = r; i.DecodeStream.call(this, t) } e.prototype = Object.create(i.DecodeStream.prototype); Object.defineProperty(e.prototype, "bytes", { get: function () { return (0, r.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)) }, configurable: !0 }); e.prototype.ensureBuffer = function (e) { }; e.prototype.readBlock = function () { if (this.eof) return; const e = { decodeTransform: void 0, colorTransform: void 0 }, t = this.dict.getArray("Decode", "D"); if (this.forceRGB && Array.isArray(t)) { const a = this.dict.get("BitsPerComponent") || 8, r = t.length, i = new Int32Array(r); let n = !1; const s = (1 << a) - 1; for (let e = 0; e < r; e += 2) { i[e] = 256 * (t[e + 1] - t[e]) | 0; i[e + 1] = t[e] * s | 0; 256 === i[e] && 0 === i[e + 1] || (n = !0) } n && (e.decodeTransform = i) } if ((0, n.isDict)(this.params)) { const t = this.params.get("ColorTransform"); Number.isInteger(t) && (e.colorTransform = t) } const a = new s.JpegImage(e); a.parse(this.bytes); const r = a.getData({ width: this.drawWidth, height: this.drawHeight, forceRGB: this.forceRGB, isSourcePDF: !0 }); this.buffer = r; this.bufferLength = r.length; this.eof = !0 }; Object.defineProperty(e.prototype, "maybeValidDimensions", { get: function () { const { dict: e, stream: t } = this, a = e.get("Height", "H"), i = t.pos; let n, s = !0, o = !1; for (; -1 !== (n = t.getByte());)if (255 === n) { switch (t.getByte()) { case 192: case 193: case 194: o = !0; t.pos += 2; t.pos += 1; const e = t.getUint16(); if (e === a) break; if (0 === e) { s = !1; break } if (e > 10 * a) { s = !1; break } break; case 195: case 197: case 198: case 199: case 201: case 202: case 203: case 205: case 206: case 207: o = !0; break; case 196: case 204: case 218: case 219: case 220: case 221: case 222: case 223: case 224: case 225: case 226: case 227: case 228: case 229: case 230: case 231: case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239: case 254: const r = t.getUint16(); r > 2 ? t.skip(r - 2) : t.skip(-2); break; case 255: t.skip(-1); break; case 217: o = !0 }if (o) break } t.pos = i; return (0, r.shadow)(this, "maybeValidDimensions", s) }, configurable: !0 }); e.prototype.getIR = function (e = !1) { return (0, r.createObjectURL)(this.bytes, "image/jpeg", e) }; return e }(); t.JpegStream = o }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.JpegImage = void 0; var r = a(2), i = a(7); class n extends r.BaseException { constructor(e) { super(`JPEG error: ${e}`) } } class s extends r.BaseException { constructor(e, t) { super(e); this.scanLines = t } } class o extends r.BaseException { } var c = function () { var e = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]); function t({ decodeTransform: e = null, colorTransform: t = -1 } = {}) { this._decodeTransform = e; this._colorTransform = t } function a(e, t) { for (var a, r, i = 0, n = [], s = 16; s > 0 && !e[s - 1];)s--; n.push({ children: [], index: 0 }); var o, c = n[0]; for (a = 0; a < s; a++) { for (r = 0; r < e[a]; r++) { (c = n.pop()).children[c.index] = t[i]; for (; c.index > 0;)c = n.pop(); c.index++; n.push(c); for (; n.length <= a;) { n.push(o = { children: [], index: 0 }); c.children[c.index] = o.children; c = o } i++ } if (a + 1 < s) { n.push(o = { children: [], index: 0 }); c.children[c.index] = o.children; c = o } } return n[0].children } function c(e, t, a) { return 64 * ((e.blocksPerLine + 1) * t + a) } function l(t, a, l, h, u, f, g, m, p, b = !1) { var y = l.mcusPerLine, v = l.progressive, w = a, k = 0, S = 0; function C() { if (S > 0) { S--; return k >> S & 1 } if (255 === (k = t[a++])) { var e = t[a++]; if (e) { if (220 === e && b) { a += 2; const e = (0, i.readUint16)(t, a); a += 2; if (e > 0 && e !== l.scanLines) throw new s("Found DNL marker (0xFFDC) while parsing scan data", e) } else if (217 === e) { if (b) { const e = 8 * O; if (e > 0 && e < l.scanLines / 10) throw new s("Found EOI marker (0xFFD9) while parsing scan data, possibly caused by incorrect `scanLines` parameter", e) } throw new o("Found EOI marker (0xFFD9) while parsing scan data") } throw new n(`unexpected marker ${(k << 8 | e).toString(16)}`) } } S = 7; return k >>> 7 } function x(e) { for (var t = e; ;) { switch (typeof (t = t[C()])) { case "number": return t; case "object": continue }throw new n("invalid huffman sequence") } } function A(e) { for (var t = 0; e > 0;) { t = t << 1 | C(); e-- } return t } function I(e) { if (1 === e) return 1 === C() ? 1 : -1; var t = A(e); return t >= 1 << e - 1 ? t : t + (-1 << e) + 1 } var F = 0; var T, E = 0; let O = 0; function P(e, t, a, r, i) { var n = a % y; O = (a / y | 0) * e.v + r; var s = n * e.h + i; t(e, c(e, O, s)) } function B(e, t, a) { O = a / e.blocksPerLine | 0; var r = a % e.blocksPerLine; t(e, c(e, O, r)) } var D, N, M, L, R, U, q = h.length; U = v ? 0 === f ? 0 === m ? function (e, t) { var a = x(e.huffmanTableDC), r = 0 === a ? 0 : I(a) << p; e.blockData[t] = e.pred += r } : function (e, t) { e.blockData[t] |= C() << p } : 0 === m ? function (t, a) { if (F > 0) F--; else for (var r = f, i = g; r <= i;) { var n = x(t.huffmanTableAC), s = 15 & n, o = n >> 4; if (0 !== s) { var c = e[r += o]; t.blockData[a + c] = I(s) * (1 << p); r++ } else { if (o < 15) { F = A(o) + (1 << o) - 1; break } r += 16 } } } : function (t, a) { for (var r, i, s = f, o = g, c = 0; s <= o;) { const o = a + e[s], l = t.blockData[o] < 0 ? -1 : 1; switch (E) { case 0: c = (i = x(t.huffmanTableAC)) >> 4; if (0 === (r = 15 & i)) if (c < 15) { F = A(c) + (1 << c); E = 4 } else { c = 16; E = 1 } else { if (1 !== r) throw new n("invalid ACn encoding"); T = I(r); E = c ? 2 : 3 } continue; case 1: case 2: t.blockData[o] ? t.blockData[o] += l * (C() << p) : 0 === --c && (E = 2 === E ? 3 : 0); break; case 3: if (t.blockData[o]) t.blockData[o] += l * (C() << p); else { t.blockData[o] = T << p; E = 0 } break; case 4: t.blockData[o] && (t.blockData[o] += l * (C() << p)) }s++ } 4 === E && 0 === --F && (E = 0) } : function (t, a) { var r = x(t.huffmanTableDC), i = 0 === r ? 0 : I(r); t.blockData[a] = t.pred += i; for (var n = 1; n < 64;) { var s = x(t.huffmanTableAC), o = 15 & s, c = s >> 4; if (0 !== o) { var l = e[n += c]; t.blockData[a + l] = I(o); n++ } else { if (c < 15) break; n += 16 } } }; var j, _, z, H, G = 0; _ = 1 === q ? h[0].blocksPerLine * h[0].blocksPerColumn : y * l.mcusPerColumn; for (; G < _;) { var W = u ? Math.min(_ - G, u) : _; for (N = 0; N < q; N++)h[N].pred = 0; F = 0; if (1 === q) { D = h[0]; for (R = 0; R < W; R++) { B(D, U, G); G++ } } else for (R = 0; R < W; R++) { for (N = 0; N < q; N++) { z = (D = h[N]).h; H = D.v; for (M = 0; M < H; M++)for (L = 0; L < z; L++)P(D, U, G, M, L) } G++ } S = 0; if (!(j = d(t, a))) break; if (j.invalid) { (0, r.warn)("decodeScan - unexpected MCU data, current marker is: " + j.invalid); a = j.offset } var X = j && j.marker; if (!X || X <= 65280) throw new n("decodeScan - a valid marker was not found."); if (!(X >= 65488 && X <= 65495)) break; a += 2 } if ((j = d(t, a)) && j.invalid) { (0, r.warn)("decodeScan - unexpected Scan data, current marker is: " + j.invalid); a = j.offset } return a - w } function h(e, t, a) { var r, i, s, o, c, l, h, u, d, f, g, m, p, b, y, v, w, k = e.quantizationTable, S = e.blockData; if (!k) throw new n("missing required Quantization Table."); for (var C = 0; C < 64; C += 8) { d = S[t + C]; f = S[t + C + 1]; g = S[t + C + 2]; m = S[t + C + 3]; p = S[t + C + 4]; b = S[t + C + 5]; y = S[t + C + 6]; v = S[t + C + 7]; d *= k[C]; if (0 != (f | g | m | p | b | y | v)) { f *= k[C + 1]; g *= k[C + 2]; m *= k[C + 3]; p *= k[C + 4]; b *= k[C + 5]; i = (r = (r = 5793 * d + 128 >> 8) + (i = 5793 * p + 128 >> 8) + 1 >> 1) - i; w = 3784 * (s = g) + 1567 * (o = y *= k[C + 6]) + 128 >> 8; s = 1567 * s - 3784 * o + 128 >> 8; h = (c = (c = 2896 * (f - (v *= k[C + 7])) + 128 >> 8) + (h = b << 4) + 1 >> 1) - h; l = (u = (u = 2896 * (f + v) + 128 >> 8) + (l = m << 4) + 1 >> 1) - l; o = (r = r + (o = w) + 1 >> 1) - o; s = (i = i + s + 1 >> 1) - s; w = 2276 * c + 3406 * u + 2048 >> 12; c = 3406 * c - 2276 * u + 2048 >> 12; u = w; w = 799 * l + 4017 * h + 2048 >> 12; l = 4017 * l - 799 * h + 2048 >> 12; h = w; a[C] = r + u; a[C + 7] = r - u; a[C + 1] = i + h; a[C + 6] = i - h; a[C + 2] = s + l; a[C + 5] = s - l; a[C + 3] = o + c; a[C + 4] = o - c } else { w = 5793 * d + 512 >> 10; a[C] = w; a[C + 1] = w; a[C + 2] = w; a[C + 3] = w; a[C + 4] = w; a[C + 5] = w; a[C + 6] = w; a[C + 7] = w } } for (var x = 0; x < 8; ++x) { d = a[x]; if (0 != ((f = a[x + 8]) | (g = a[x + 16]) | (m = a[x + 24]) | (p = a[x + 32]) | (b = a[x + 40]) | (y = a[x + 48]) | (v = a[x + 56]))) { i = (r = 4112 + ((r = 5793 * d + 2048 >> 12) + (i = 5793 * p + 2048 >> 12) + 1 >> 1)) - i; w = 3784 * (s = g) + 1567 * (o = y) + 2048 >> 12; s = 1567 * s - 3784 * o + 2048 >> 12; o = w; h = (c = (c = 2896 * (f - v) + 2048 >> 12) + (h = b) + 1 >> 1) - h; l = (u = (u = 2896 * (f + v) + 2048 >> 12) + (l = m) + 1 >> 1) - l; w = 2276 * c + 3406 * u + 2048 >> 12; c = 3406 * c - 2276 * u + 2048 >> 12; u = w; w = 799 * l + 4017 * h + 2048 >> 12; l = 4017 * l - 799 * h + 2048 >> 12; (d = (r = r + o + 1 >> 1) + u) < 16 ? d = 0 : d >= 4080 ? d = 255 : d >>= 4; (f = (i = i + s + 1 >> 1) + (h = w)) < 16 ? f = 0 : f >= 4080 ? f = 255 : f >>= 4; (g = (s = i - s) + l) < 16 ? g = 0 : g >= 4080 ? g = 255 : g >>= 4; (m = (o = r - o) + c) < 16 ? m = 0 : m >= 4080 ? m = 255 : m >>= 4; (p = o - c) < 16 ? p = 0 : p >= 4080 ? p = 255 : p >>= 4; (b = s - l) < 16 ? b = 0 : b >= 4080 ? b = 255 : b >>= 4; (y = i - h) < 16 ? y = 0 : y >= 4080 ? y = 255 : y >>= 4; (v = r - u) < 16 ? v = 0 : v >= 4080 ? v = 255 : v >>= 4; S[t + x] = d; S[t + x + 8] = f; S[t + x + 16] = g; S[t + x + 24] = m; S[t + x + 32] = p; S[t + x + 40] = b; S[t + x + 48] = y; S[t + x + 56] = v } else { w = (w = 5793 * d + 8192 >> 14) < -2040 ? 0 : w >= 2024 ? 255 : w + 2056 >> 4; S[t + x] = w; S[t + x + 8] = w; S[t + x + 16] = w; S[t + x + 24] = w; S[t + x + 32] = w; S[t + x + 40] = w; S[t + x + 48] = w; S[t + x + 56] = w } } } function u(e, t) { for (var a = t.blocksPerLine, r = t.blocksPerColumn, i = new Int16Array(64), n = 0; n < r; n++)for (var s = 0; s < a; s++) { h(t, c(t, n, s), i) } return t.blockData } function d(e, t, a = t) { const r = e.length - 1; var n = a < t ? a : t; if (t >= r) return null; var s = (0, i.readUint16)(e, t); if (s >= 65472 && s <= 65534) return { invalid: null, marker: s, offset: t }; for (var o = (0, i.readUint16)(e, n); !(o >= 65472 && o <= 65534);) { if (++n >= r) return null; o = (0, i.readUint16)(e, n) } return { invalid: s.toString(16), marker: o, offset: n } } t.prototype = { parse(t, { dnlScanLines: c = null } = {}) { function h() { const e = (0, i.readUint16)(t, p); let a = (p += 2) + e - 2; var n = d(t, a, p); if (n && n.invalid) { (0, r.warn)("readDataBlock - incorrect length, current marker is: " + n.invalid); a = n.offset } var s = t.subarray(p, a); p += s.length; return s } function f(e) { for (var t = Math.ceil(e.samplesPerLine / 8 / e.maxH), a = Math.ceil(e.scanLines / 8 / e.maxV), r = 0; r < e.components.length; r++) { z = e.components[r]; var i = Math.ceil(Math.ceil(e.samplesPerLine / 8) * z.h / e.maxH), n = Math.ceil(Math.ceil(e.scanLines / 8) * z.v / e.maxV), s = t * z.h, o = 64 * (a * z.v) * (s + 1); z.blockData = new Int16Array(o); z.blocksPerLine = i; z.blocksPerColumn = n } e.mcusPerLine = t; e.mcusPerColumn = a } var g, m, p = 0, b = null, y = null; let v = 0; var w = [], k = [], S = []; let C = (0, i.readUint16)(t, p); p += 2; if (65496 !== C) throw new n("SOI not found"); C = (0, i.readUint16)(t, p); p += 2; e: for (; 65497 !== C;) { var x, A, I; switch (C) { case 65504: case 65505: case 65506: case 65507: case 65508: case 65509: case 65510: case 65511: case 65512: case 65513: case 65514: case 65515: case 65516: case 65517: case 65518: case 65519: case 65534: var F = h(); 65504 === C && 74 === F[0] && 70 === F[1] && 73 === F[2] && 70 === F[3] && 0 === F[4] && (b = { version: { major: F[5], minor: F[6] }, densityUnits: F[7], xDensity: F[8] << 8 | F[9], yDensity: F[10] << 8 | F[11], thumbWidth: F[12], thumbHeight: F[13], thumbData: F.subarray(14, 14 + 3 * F[12] * F[13]) }); 65518 === C && 65 === F[0] && 100 === F[1] && 111 === F[2] && 98 === F[3] && 101 === F[4] && (y = { version: F[5] << 8 | F[6], flags0: F[7] << 8 | F[8], flags1: F[9] << 8 | F[10], transformCode: F[11] }); break; case 65499: for (var T = (0, i.readUint16)(t, p) + (p += 2) - 2; p < T;) { var E = t[p++], O = new Uint16Array(64); if (E >> 4 == 0) for (A = 0; A < 64; A++)O[e[A]] = t[p++]; else { if (E >> 4 != 1) throw new n("DQT - invalid table spec"); for (A = 0; A < 64; A++) { O[e[A]] = (0, i.readUint16)(t, p); p += 2 } } w[15 & E] = O } break; case 65472: case 65473: case 65474: if (g) throw new n("Only single frame JPEGs supported"); p += 2; (g = {}).extended = 65473 === C; g.progressive = 65474 === C; g.precision = t[p++]; const u = (0, i.readUint16)(t, p); p += 2; g.scanLines = c || u; g.samplesPerLine = (0, i.readUint16)(t, p); p += 2; g.components = []; g.componentIds = {}; var P, B = t[p++], D = 0, N = 0; for (x = 0; x < B; x++) { P = t[p]; var M = t[p + 1] >> 4, L = 15 & t[p + 1]; D < M && (D = M); N < L && (N = L); var R = t[p + 2]; I = g.components.push({ h: M, v: L, quantizationId: R, quantizationTable: null }); g.componentIds[P] = I - 1; p += 3 } g.maxH = D; g.maxV = N; f(g); break; case 65476: const J = (0, i.readUint16)(t, p); p += 2; for (x = 2; x < J;) { var U = t[p++], q = new Uint8Array(16), j = 0; for (A = 0; A < 16; A++, p++)j += q[A] = t[p]; var _ = new Uint8Array(j); for (A = 0; A < j; A++, p++)_[A] = t[p]; x += 17 + j; (U >> 4 == 0 ? S : k)[15 & U] = a(q, _) } break; case 65501: p += 2; m = (0, i.readUint16)(t, p); p += 2; break; case 65498: const Z = 1 == ++v && !c; p += 2; var z, H = t[p++], G = []; for (x = 0; x < H; x++) { var W = g.componentIds[t[p++]]; z = g.components[W]; var X = t[p++]; z.huffmanTableDC = S[X >> 4]; z.huffmanTableAC = k[15 & X]; G.push(z) } var V = t[p++], K = t[p++], Y = t[p++]; try { var $ = l(t, p, g, G, m, V, K, Y >> 4, 15 & Y, Z); p += $ } catch (e) { if (e instanceof s) { (0, r.warn)(`${e.message} -- attempting to re-parse the JPEG image.`); return this.parse(t, { dnlScanLines: e.scanLines }) } if (e instanceof o) { (0, r.warn)(`${e.message} -- ignoring the rest of the image data.`); break e } throw e } break; case 65500: p += 4; break; case 65535: 255 !== t[p] && p--; break; default: const Q = d(t, p - 2, p - 3); if (Q && Q.invalid) { (0, r.warn)("JpegImage.parse - unexpected data, current marker is: " + Q.invalid); p = Q.offset; break } if (p >= t.length - 1) { (0, r.warn)("JpegImage.parse - reached the end of the image data without finding an EOI marker (0xFFD9)."); break e } throw new n("JpegImage.parse - unknown marker: " + C.toString(16)) }C = (0, i.readUint16)(t, p); p += 2 } this.width = g.samplesPerLine; this.height = g.scanLines; this.jfif = b; this.adobe = y; this.components = []; for (x = 0; x < g.components.length; x++) { var J = w[(z = g.components[x]).quantizationId]; J && (z.quantizationTable = J); this.components.push({ output: u(0, z), scaleX: z.h / g.maxH, scaleY: z.v / g.maxV, blocksPerLine: z.blocksPerLine, blocksPerColumn: z.blocksPerColumn }) } this.numComponents = this.components.length }, _getLinearizedBlockData(e, t, a = !1) { var r, i, n, s, o, c, l, h, u, d, f, g = this.width / e, m = this.height / t, p = 0, b = this.components.length, y = e * t * b, v = new Uint8ClampedArray(y), w = new Uint32Array(e); let k; for (l = 0; l < b; l++) { i = (r = this.components[l]).scaleX * g; n = r.scaleY * m; p = l; f = r.output; s = r.blocksPerLine + 1 << 3; if (i !== k) { for (o = 0; o < e; o++) { h = 0 | o * i; w[o] = (4294967288 & h) << 3 | 7 & h } k = i } for (c = 0; c < t; c++) { d = s * (4294967288 & (h = 0 | c * n)) | (7 & h) << 3; for (o = 0; o < e; o++) { v[p] = f[d + w[o]]; p += b } } } let S = this._decodeTransform; a || 4 !== b || S || (S = new Int32Array([-256, 255, -256, 255, -256, 255, -256, 255])); if (S) for (l = 0; l < y;)for (h = 0, u = 0; h < b; h++, l++, u += 2)v[l] = (v[l] * S[u] >> 8) + S[u + 1]; return v }, get _isColorConversionNeeded() { return this.adobe ? !!this.adobe.transformCode : 3 === this.numComponents ? 0 !== this._colorTransform : 1 === this._colorTransform }, _convertYccToRgb: function (e) { for (var t, a, r, i = 0, n = e.length; i < n; i += 3) { t = e[i]; a = e[i + 1]; r = e[i + 2]; e[i] = t - 179.456 + 1.402 * r; e[i + 1] = t + 135.459 - .344 * a - .714 * r; e[i + 2] = t - 226.816 + 1.772 * a } return e }, _convertYcckToRgb: function (e) { for (var t, a, r, i, n = 0, s = 0, o = e.length; s < o; s += 4) { t = e[s]; a = e[s + 1]; r = e[s + 2]; i = e[s + 3]; e[n++] = a * (-660635669420364e-19 * a + .000437130475926232 * r - 54080610064599e-18 * t + .00048449797120281 * i - .154362151871126) - 122.67195406894 + r * (-.000957964378445773 * r + .000817076911346625 * t - .00477271405408747 * i + 1.53380253221734) + t * (.000961250184130688 * t - .00266257332283933 * i + .48357088451265) + i * (-.000336197177618394 * i + .484791561490776); e[n++] = 107.268039397724 + a * (219927104525741e-19 * a - .000640992018297945 * r + .000659397001245577 * t + .000426105652938837 * i - .176491792462875) + r * (-.000778269941513683 * r + .00130872261408275 * t + .000770482631801132 * i - .151051492775562) + t * (.00126935368114843 * t - .00265090189010898 * i + .25802910206845) + i * (-.000318913117588328 * i - .213742400323665); e[n++] = a * (-.000570115196973677 * a - 263409051004589e-19 * r + .0020741088115012 * t - .00288260236853442 * i + .814272968359295) - 20.810012546947 + r * (-153496057440975e-19 * r - .000132689043961446 * t + .000560833691242812 * i - .195152027534049) + t * (.00174418132927582 * t - .00255243321439347 * i + .116935020465145) + i * (-.000343531996510555 * i + .24165260232407) } return e.subarray(0, n) }, _convertYcckToCmyk: function (e) { for (var t, a, r, i = 0, n = e.length; i < n; i += 4) { t = e[i]; a = e[i + 1]; r = e[i + 2]; e[i] = 434.456 - t - 1.402 * r; e[i + 1] = 119.541 - t + .344 * a + .714 * r; e[i + 2] = 481.816 - t - 1.772 * a } return e }, _convertCmykToRgb: function (e) { for (var t, a, r, i, n = 0, s = 0, o = e.length; s < o; s += 4) { t = e[s]; a = e[s + 1]; r = e[s + 2]; i = e[s + 3]; e[n++] = 255 + t * (-6747147073602441e-20 * t + .0008379262121013727 * a + .0002894718188643294 * r + .003264231057537806 * i - 1.1185611867203937) + a * (26374107616089405e-21 * a - 8626949158638572e-20 * r - .0002748769067499491 * i - .02155688794978967) + r * (-3878099212869363e-20 * r - .0003267808279485286 * i + .0686742238595345) - i * (.0003361971776183937 * i + .7430659151342254); e[n++] = 255 + t * (.00013596372813588848 * t + .000924537132573585 * a + .00010567359618683593 * r + .0004791864687436512 * i - .3109689587515875) + a * (-.00023545346108370344 * a + .0002702845253534714 * r + .0020200308977307156 * i - .7488052167015494) + r * (6834815998235662e-20 * r + .00015168452363460973 * i - .09751927774728933) - i * (.0003189131175883281 * i + .7364883807733168); e[n++] = 255 + t * (13598650411385307e-21 * t + .00012423956175490851 * a + .0004751985097583589 * r - 36729317476630422e-22 * i - .05562186980264034) + a * (.00016141380598724676 * a + .0009692239130725186 * r + .0007782692450036253 * i - .44015232367526463) + r * (5.068882914068769e-7 * r + .0017778369011375071 * i - .7591454649749609) - i * (.0003435319965105553 * i + .7063770186160144) } return e.subarray(0, n) }, getData({ width: e, height: t, forceRGB: a = !1, isSourcePDF: r = !1 }) { if (this.numComponents > 4) throw new n("Unsupported color mode"); var i = this._getLinearizedBlockData(e, t, r); if (1 === this.numComponents && a) { for (var s = i.length, o = new Uint8ClampedArray(3 * s), c = 0, l = 0; l < s; l++) { var h = i[l]; o[c++] = h; o[c++] = h; o[c++] = h } return o } if (3 === this.numComponents && this._isColorConversionNeeded) return this._convertYccToRgb(i); if (4 === this.numComponents) { if (this._isColorConversionNeeded) return a ? this._convertYcckToRgb(i) : this._convertYcckToCmyk(i); if (a) return this._convertCmykToRgb(i) } return i } }; return t }(); t.JpegImage = c }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.JpxStream = void 0; var r = a(11), i = a(20), n = a(2); const s = function () { function e(e, t, a, i) { this.stream = e; this.maybeLength = t; this.dict = a; this.params = i; r.DecodeStream.call(this, t) } e.prototype = Object.create(r.DecodeStream.prototype); Object.defineProperty(e.prototype, "bytes", { get: function () { return (0, n.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)) }, configurable: !0 }); e.prototype.ensureBuffer = function (e) { }; e.prototype.readBlock = function () { if (this.eof) return; const e = new i.JpxImage; e.parse(this.bytes); const t = e.width, a = e.height, r = e.componentsCount, n = e.tiles.length; if (1 === n) this.buffer = e.tiles[0].items; else { const i = new Uint8ClampedArray(t * a * r); for (let a = 0; a < n; a++) { const n = e.tiles[a], s = n.width, o = n.height, c = n.left, l = n.top, h = n.items; let u = 0, d = (t * l + c) * r; const f = t * r, g = s * r; for (let e = 0; e < o; e++) { const e = h.subarray(u, u + g); i.set(e, d); u += g; d += f } } this.buffer = i } this.bufferLength = this.buffer.length; this.eof = !0 }; return e }(); t.JpxStream = s }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.JpxImage = void 0; var r = a(2), i = a(7), n = a(16); class s extends r.BaseException { constructor(e) { super(`JPX error: ${e}`) } } var o = function () { var e = { LL: 0, LH: 1, HL: 1, HH: 2 }; function t() { this.failOnCorruptedImage = !1 } t.prototype = { parse: function (e) { if (65359 !== (0, i.readUint16)(e, 0)) for (var t = 0, a = e.length; t < a;) { var n = 8, o = (0, i.readUint32)(e, t), c = (0, i.readUint32)(e, t + 4); t += n; if (1 === o) { o = 4294967296 * (0, i.readUint32)(e, t) + (0, i.readUint32)(e, t + 4); t += 8; n += 8 } 0 === o && (o = a - t + n); if (o < n) throw new s("Invalid box field size"); var l = o - n, h = !0; switch (c) { case 1785737832: h = !1; break; case 1668246642: var u = e[t]; if (1 === u) { var d = (0, i.readUint32)(e, t + 3); switch (d) { case 16: case 17: case 18: break; default: (0, r.warn)("Unknown colorspace " + d) } } else 2 === u && (0, r.info)("ICC profile not supported"); break; case 1785737827: this.parseCodestream(e, t, t + l); break; case 1783636e3: 218793738 !== (0, i.readUint32)(e, t) && (0, r.warn)("Invalid JP2 signature"); break; case 1783634458: case 1718909296: case 1920099697: case 1919251232: case 1768449138: break; default: var f = String.fromCharCode(c >> 24 & 255, c >> 16 & 255, c >> 8 & 255, 255 & c); (0, r.warn)("Unsupported header type " + c + " (" + f + ")") }h && (t += l) } else this.parseCodestream(e, 0, e.length) }, parseImageProperties: function (e) { for (var t = e.getByte(); t >= 0;) { if (65361 === (t << 8 | (t = e.getByte()))) { e.skip(4); var a = e.getInt32() >>> 0, r = e.getInt32() >>> 0, i = e.getInt32() >>> 0, n = e.getInt32() >>> 0; e.skip(16); var o = e.getUint16(); this.width = a - i; this.height = r - n; this.componentsCount = o; this.bitsPerComponent = 8; return } } throw new s("No size marker found in JPX stream") }, parseCodestream: function (e, t, n) { var c = {}, l = !1; try { for (var h = t; h + 1 < n;) { var u = (0, i.readUint16)(e, h); h += 2; var d, f, g, m, p, b, y = 0; switch (u) { case 65359: c.mainHeader = !0; break; case 65497: break; case 65361: y = (0, i.readUint16)(e, h); var k = {}; k.Xsiz = (0, i.readUint32)(e, h + 4); k.Ysiz = (0, i.readUint32)(e, h + 8); k.XOsiz = (0, i.readUint32)(e, h + 12); k.YOsiz = (0, i.readUint32)(e, h + 16); k.XTsiz = (0, i.readUint32)(e, h + 20); k.YTsiz = (0, i.readUint32)(e, h + 24); k.XTOsiz = (0, i.readUint32)(e, h + 28); k.YTOsiz = (0, i.readUint32)(e, h + 32); var x = (0, i.readUint16)(e, h + 36); k.Csiz = x; var A = []; d = h + 38; for (var I = 0; I < x; I++) { var F = { precision: 1 + (127 & e[d]), isSigned: !!(128 & e[d]), XRsiz: e[d + 1], YRsiz: e[d + 2] }; d += 3; a(F, k); A.push(F) } c.SIZ = k; c.components = A; o(c, A); c.QCC = []; c.COC = []; break; case 65372: y = (0, i.readUint16)(e, h); var T = {}; d = h + 2; switch (31 & (f = e[d++])) { case 0: m = 8; p = !0; break; case 1: m = 16; p = !1; break; case 2: m = 16; p = !0; break; default: throw new Error("Invalid SQcd value " + f) }T.noQuantization = 8 === m; T.scalarExpounded = p; T.guardBits = f >> 5; g = []; for (; d < y + h;) { var E = {}; if (8 === m) { E.epsilon = e[d++] >> 3; E.mu = 0 } else { E.epsilon = e[d] >> 3; E.mu = (7 & e[d]) << 8 | e[d + 1]; d += 2 } g.push(E) } T.SPqcds = g; if (c.mainHeader) c.QCD = T; else { c.currentTile.QCD = T; c.currentTile.QCC = [] } break; case 65373: y = (0, i.readUint16)(e, h); var O, P = {}; d = h + 2; if (c.SIZ.Csiz < 257) O = e[d++]; else { O = (0, i.readUint16)(e, d); d += 2 } switch (31 & (f = e[d++])) { case 0: m = 8; p = !0; break; case 1: m = 16; p = !1; break; case 2: m = 16; p = !0; break; default: throw new Error("Invalid SQcd value " + f) }P.noQuantization = 8 === m; P.scalarExpounded = p; P.guardBits = f >> 5; g = []; for (; d < y + h;) { E = {}; if (8 === m) { E.epsilon = e[d++] >> 3; E.mu = 0 } else { E.epsilon = e[d] >> 3; E.mu = (7 & e[d]) << 8 | e[d + 1]; d += 2 } g.push(E) } P.SPqcds = g; c.mainHeader ? c.QCC[O] = P : c.currentTile.QCC[O] = P; break; case 65362: y = (0, i.readUint16)(e, h); var B = {}; d = h + 2; var D = e[d++]; B.entropyCoderWithCustomPrecincts = !!(1 & D); B.sopMarkerUsed = !!(2 & D); B.ephMarkerUsed = !!(4 & D); B.progressionOrder = e[d++]; B.layersCount = (0, i.readUint16)(e, d); d += 2; B.multipleComponentTransform = e[d++]; B.decompositionLevelsCount = e[d++]; B.xcb = 2 + (15 & e[d++]); B.ycb = 2 + (15 & e[d++]); var N = e[d++]; B.selectiveArithmeticCodingBypass = !!(1 & N); B.resetContextProbabilities = !!(2 & N); B.terminationOnEachCodingPass = !!(4 & N); B.verticallyStripe = !!(8 & N); B.predictableTermination = !!(16 & N); B.segmentationSymbolUsed = !!(32 & N); B.reversibleTransformation = e[d++]; if (B.entropyCoderWithCustomPrecincts) { for (var M = []; d < y + h;) { var L = e[d++]; M.push({ PPx: 15 & L, PPy: L >> 4 }) } B.precinctsSizes = M } var R = []; B.selectiveArithmeticCodingBypass && R.push("selectiveArithmeticCodingBypass"); B.resetContextProbabilities && R.push("resetContextProbabilities"); B.terminationOnEachCodingPass && R.push("terminationOnEachCodingPass"); B.verticallyStripe && R.push("verticallyStripe"); B.predictableTermination && R.push("predictableTermination"); if (R.length > 0) { l = !0; throw new Error("Unsupported COD options (" + R.join(", ") + ")") } if (c.mainHeader) c.COD = B; else { c.currentTile.COD = B; c.currentTile.COC = [] } break; case 65424: y = (0, i.readUint16)(e, h); (b = {}).index = (0, i.readUint16)(e, h + 2); b.length = (0, i.readUint32)(e, h + 4); b.dataEnd = b.length + h - 2; b.partIndex = e[h + 8]; b.partsCount = e[h + 9]; c.mainHeader = !1; if (0 === b.partIndex) { b.COD = c.COD; b.COC = c.COC.slice(0); b.QCD = c.QCD; b.QCC = c.QCC.slice(0) } c.currentTile = b; break; case 65427: if (0 === (b = c.currentTile).partIndex) { C(c, b.index); v(c) } w(c, e, h, y = b.dataEnd - h); break; case 65365: case 65367: case 65368: case 65380: y = (0, i.readUint16)(e, h); break; case 65363: throw new Error("Codestream code 0xFF53 (COC) is not implemented"); default: throw new Error("Unknown codestream code: " + u.toString(16)) }h += y } } catch (e) { if (l || this.failOnCorruptedImage) throw new s(e.message); (0, r.warn)("JPX: Trying to recover from: " + e.message) } this.tiles = function (e) { for (var t = e.SIZ, a = e.components, r = t.Csiz, i = [], n = 0, s = e.tiles.length; n < s; n++) { var o, c = e.tiles[n], l = []; for (o = 0; o < r; o++)l[o] = S(e, c, o); var h, u, d, f, g, m, p, b = l[0], y = new Uint8ClampedArray(b.items.length * r), v = { left: b.left, top: b.top, width: b.width, height: b.height, items: y }, w = 0; if (c.codingStyleDefaultParameters.multipleComponentTransform) { var k = 4 === r, C = l[0].items, x = l[1].items, A = l[2].items, I = k ? l[3].items : null; h = a[0].precision - 8; u = .5 + (128 << h); var F = c.components[0], T = r - 3; f = C.length; if (F.codingStyleParameters.reversibleTransformation) for (d = 0; d < f; d++, w += T) { g = C[d] + u; m = x[d]; p = A[d]; const e = g - (p + m >> 2); y[w++] = e + p >> h; y[w++] = e >> h; y[w++] = e + m >> h } else for (d = 0; d < f; d++, w += T) { g = C[d] + u; m = x[d]; p = A[d]; y[w++] = g + 1.402 * p >> h; y[w++] = g - .34413 * m - .71414 * p >> h; y[w++] = g + 1.772 * m >> h } if (k) for (d = 0, w = 3; d < f; d++, w += 4)y[w] = I[d] + u >> h } else for (o = 0; o < r; o++) { var E = l[o].items; h = a[o].precision - 8; u = .5 + (128 << h); for (w = o, d = 0, f = E.length; d < f; d++) { y[w] = E[d] + u >> h; w += r } } i.push(v) } return i }(c); this.width = c.SIZ.Xsiz - c.SIZ.XOsiz; this.height = c.SIZ.Ysiz - c.SIZ.YOsiz; this.componentsCount = c.SIZ.Csiz } }; function a(e, t) { e.x0 = Math.ceil(t.XOsiz / e.XRsiz); e.x1 = Math.ceil(t.Xsiz / e.XRsiz); e.y0 = Math.ceil(t.YOsiz / e.YRsiz); e.y1 = Math.ceil(t.Ysiz / e.YRsiz); e.width = e.x1 - e.x0; e.height = e.y1 - e.y0 } function o(e, t) { for (var a, r = e.SIZ, i = [], n = Math.ceil((r.Xsiz - r.XTOsiz) / r.XTsiz), s = Math.ceil((r.Ysiz - r.YTOsiz) / r.YTsiz), o = 0; o < s; o++)for (var c = 0; c < n; c++) { (a = {}).tx0 = Math.max(r.XTOsiz + c * r.XTsiz, r.XOsiz); a.ty0 = Math.max(r.YTOsiz + o * r.YTsiz, r.YOsiz); a.tx1 = Math.min(r.XTOsiz + (c + 1) * r.XTsiz, r.Xsiz); a.ty1 = Math.min(r.YTOsiz + (o + 1) * r.YTsiz, r.Ysiz); a.width = a.tx1 - a.tx0; a.height = a.ty1 - a.ty0; a.components = []; i.push(a) } e.tiles = i; for (var l = 0, h = r.Csiz; l < h; l++)for (var u = t[l], d = 0, f = i.length; d < f; d++) { var g = {}; a = i[d]; g.tcx0 = Math.ceil(a.tx0 / u.XRsiz); g.tcy0 = Math.ceil(a.ty0 / u.YRsiz); g.tcx1 = Math.ceil(a.tx1 / u.XRsiz); g.tcy1 = Math.ceil(a.ty1 / u.YRsiz); g.width = g.tcx1 - g.tcx0; g.height = g.tcy1 - g.tcy0; a.components[l] = g } } function c(e, t, a) { var r = t.codingStyleParameters, i = {}; if (r.entropyCoderWithCustomPrecincts) { i.PPx = r.precinctsSizes[a].PPx; i.PPy = r.precinctsSizes[a].PPy } else { i.PPx = 15; i.PPy = 15 } i.xcb_ = a > 0 ? Math.min(r.xcb, i.PPx - 1) : Math.min(r.xcb, i.PPx); i.ycb_ = a > 0 ? Math.min(r.ycb, i.PPy - 1) : Math.min(r.ycb, i.PPy); return i } function l(e, t, a) { var r = 1 << a.PPx, i = 1 << a.PPy, n = 0 === t.resLevel, s = 1 << a.PPx + (n ? 0 : -1), o = 1 << a.PPy + (n ? 0 : -1), c = t.trx1 > t.trx0 ? Math.ceil(t.trx1 / r) - Math.floor(t.trx0 / r) : 0, l = t.try1 > t.try0 ? Math.ceil(t.try1 / i) - Math.floor(t.try0 / i) : 0, h = c * l; t.precinctParameters = { precinctWidth: r, precinctHeight: i, numprecinctswide: c, numprecinctshigh: l, numprecincts: h, precinctWidthInSubband: s, precinctHeightInSubband: o } } function h(e, t, a) { var r, i, n, s, o = a.xcb_, c = a.ycb_, l = 1 << o, h = 1 << c, u = t.tbx0 >> o, d = t.tby0 >> c, f = t.tbx1 + l - 1 >> o, g = t.tby1 + h - 1 >> c, m = t.resolution.precinctParameters, p = [], b = []; for (i = d; i < g; i++)for (r = u; r < f; r++) { (n = { cbx: r, cby: i, tbx0: l * r, tby0: h * i, tbx1: l * (r + 1), tby1: h * (i + 1) }).tbx0_ = Math.max(t.tbx0, n.tbx0); n.tby0_ = Math.max(t.tby0, n.tby0); n.tbx1_ = Math.min(t.tbx1, n.tbx1); n.tby1_ = Math.min(t.tby1, n.tby1); s = Math.floor((n.tbx0_ - t.tbx0) / m.precinctWidthInSubband) + Math.floor((n.tby0_ - t.tby0) / m.precinctHeightInSubband) * m.numprecinctswide; n.precinctNumber = s; n.subbandType = t.type; n.Lblock = 3; if (!(n.tbx1_ <= n.tbx0_ || n.tby1_ <= n.tby0_)) { p.push(n); var y = b[s]; if (void 0 !== y) { r < y.cbxMin ? y.cbxMin = r : r > y.cbxMax && (y.cbxMax = r); i < y.cbyMin ? y.cbxMin = i : i > y.cbyMax && (y.cbyMax = i) } else b[s] = y = { cbxMin: r, cbyMin: i, cbxMax: r, cbyMax: i }; n.precinct = y } } t.codeblockParameters = { codeblockWidth: o, codeblockHeight: c, numcodeblockwide: f - u + 1, numcodeblockhigh: g - d + 1 }; t.codeblocks = p; t.precincts = b } function u(e, t, a) { for (var r = [], i = e.subbands, n = 0, s = i.length; n < s; n++)for (var o = i[n].codeblocks, c = 0, l = o.length; c < l; c++) { var h = o[c]; h.precinctNumber === t && r.push(h) } return { layerNumber: a, codeblocks: r } } function d(e) { for (var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = r.codingStyleDefaultParameters.layersCount, n = t.Csiz, o = 0, c = 0; c < n; c++)o = Math.max(o, r.components[c].codingStyleParameters.decompositionLevelsCount); var l = 0, h = 0, d = 0, f = 0; this.nextPacket = function () { for (; l < i; l++) { for (; h <= o; h++) { for (; d < n; d++) { var e = r.components[d]; if (!(h > e.codingStyleParameters.decompositionLevelsCount)) { for (var t = e.resolutions[h], a = t.precinctParameters.numprecincts; f < a;) { var c = u(t, f, l); f++; return c } f = 0 } } d = 0 } h = 0 } throw new s("Out of packets") } } function f(e) { for (var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = r.codingStyleDefaultParameters.layersCount, n = t.Csiz, o = 0, c = 0; c < n; c++)o = Math.max(o, r.components[c].codingStyleParameters.decompositionLevelsCount); var l = 0, h = 0, d = 0, f = 0; this.nextPacket = function () { for (; l <= o; l++) { for (; h < i; h++) { for (; d < n; d++) { var e = r.components[d]; if (!(l > e.codingStyleParameters.decompositionLevelsCount)) { for (var t = e.resolutions[l], a = t.precinctParameters.numprecincts; f < a;) { var c = u(t, f, h); f++; return c } f = 0 } } d = 0 } h = 0 } throw new s("Out of packets") } } function g(e) { var t, a, r, i, n = e.SIZ, o = e.currentTile.index, c = e.tiles[o], l = c.codingStyleDefaultParameters.layersCount, h = n.Csiz, d = 0; for (r = 0; r < h; r++) { var f = c.components[r]; d = Math.max(d, f.codingStyleParameters.decompositionLevelsCount) } var g = new Int32Array(d + 1); for (a = 0; a <= d; ++a) { var m = 0; for (r = 0; r < h; ++r) { var p = c.components[r].resolutions; a < p.length && (m = Math.max(m, p[a].precinctParameters.numprecincts)) } g[a] = m } t = 0; a = 0; r = 0; i = 0; this.nextPacket = function () { for (; a <= d; a++) { for (; i < g[a]; i++) { for (; r < h; r++) { var e = c.components[r]; if (!(a > e.codingStyleParameters.decompositionLevelsCount)) { var n = e.resolutions[a], o = n.precinctParameters.numprecincts; if (!(i >= o)) { for (; t < l;) { var f = u(n, i, t); t++; return f } t = 0 } } } r = 0 } i = 0 } throw new s("Out of packets") } } function m(e) { var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = r.codingStyleDefaultParameters.layersCount, n = t.Csiz, o = y(r), c = o, l = 0, h = 0, d = 0, f = 0, g = 0; this.nextPacket = function () { for (; g < c.maxNumHigh; g++) { for (; f < c.maxNumWide; f++) { for (; d < n; d++) { for (var e = r.components[d], t = e.codingStyleParameters.decompositionLevelsCount; h <= t; h++) { var a = e.resolutions[h], m = o.components[d].resolutions[h], p = b(f, g, m, c, a); if (null !== p) { for (; l < i;) { var y = u(a, p, l); l++; return y } l = 0 } } h = 0 } d = 0 } f = 0 } throw new s("Out of packets") } } function p(e) { var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = r.codingStyleDefaultParameters.layersCount, n = t.Csiz, o = y(r), c = 0, l = 0, h = 0, d = 0, f = 0; this.nextPacket = function () { for (; h < n; ++h) { for (var e = r.components[h], t = o.components[h], a = e.codingStyleParameters.decompositionLevelsCount; f < t.maxNumHigh; f++) { for (; d < t.maxNumWide; d++) { for (; l <= a; l++) { var g = e.resolutions[l], m = t.resolutions[l], p = b(d, f, m, t, g); if (null !== p) { for (; c < i;) { var y = u(g, p, c); c++; return y } c = 0 } } l = 0 } d = 0 } f = 0 } throw new s("Out of packets") } } function b(e, t, a, r, i) { var n = e * r.minWidth, s = t * r.minHeight; if (n % a.width != 0 || s % a.height != 0) return null; var o = s / a.width * i.precinctParameters.numprecinctswide; return n / a.height + o } function y(e) { for (var t = e.components.length, a = Number.MAX_VALUE, r = Number.MAX_VALUE, i = 0, n = 0, s = new Array(t), o = 0; o < t; o++) { for (var c = e.components[o], l = c.codingStyleParameters.decompositionLevelsCount, h = new Array(l + 1), u = Number.MAX_VALUE, d = Number.MAX_VALUE, f = 0, g = 0, m = 1, p = l; p >= 0; --p) { var b = c.resolutions[p], y = m * b.precinctParameters.precinctWidth, v = m * b.precinctParameters.precinctHeight; u = Math.min(u, y); d = Math.min(d, v); f = Math.max(f, b.precinctParameters.numprecinctswide); g = Math.max(g, b.precinctParameters.numprecinctshigh); h[p] = { width: y, height: v }; m <<= 1 } a = Math.min(a, u); r = Math.min(r, d); i = Math.max(i, f); n = Math.max(n, g); s[o] = { resolutions: h, minWidth: u, minHeight: d, maxNumWide: f, maxNumHigh: g } } return { components: s, minWidth: a, minHeight: r, maxNumWide: i, maxNumHigh: n } } function v(e) { for (var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = t.Csiz, n = 0; n < i; n++) { for (var o = r.components[n], u = o.codingStyleParameters.decompositionLevelsCount, b = [], y = [], v = 0; v <= u; v++) { var w, k = c(0, o, v), S = {}, C = 1 << u - v; S.trx0 = Math.ceil(o.tcx0 / C); S.try0 = Math.ceil(o.tcy0 / C); S.trx1 = Math.ceil(o.tcx1 / C); S.try1 = Math.ceil(o.tcy1 / C); S.resLevel = v; l(0, S, k); b.push(S); if (0 === v) { (w = {}).type = "LL"; w.tbx0 = Math.ceil(o.tcx0 / C); w.tby0 = Math.ceil(o.tcy0 / C); w.tbx1 = Math.ceil(o.tcx1 / C); w.tby1 = Math.ceil(o.tcy1 / C); w.resolution = S; h(0, w, k); y.push(w); S.subbands = [w] } else { var x = 1 << u - v + 1, A = []; (w = {}).type = "HL"; w.tbx0 = Math.ceil(o.tcx0 / x - .5); w.tby0 = Math.ceil(o.tcy0 / x); w.tbx1 = Math.ceil(o.tcx1 / x - .5); w.tby1 = Math.ceil(o.tcy1 / x); w.resolution = S; h(0, w, k); y.push(w); A.push(w); (w = {}).type = "LH"; w.tbx0 = Math.ceil(o.tcx0 / x); w.tby0 = Math.ceil(o.tcy0 / x - .5); w.tbx1 = Math.ceil(o.tcx1 / x); w.tby1 = Math.ceil(o.tcy1 / x - .5); w.resolution = S; h(0, w, k); y.push(w); A.push(w); (w = {}).type = "HH"; w.tbx0 = Math.ceil(o.tcx0 / x - .5); w.tby0 = Math.ceil(o.tcy0 / x - .5); w.tbx1 = Math.ceil(o.tcx1 / x - .5); w.tby1 = Math.ceil(o.tcy1 / x - .5); w.resolution = S; h(0, w, k); y.push(w); A.push(w); S.subbands = A } } o.resolutions = b; o.subbands = y } var I = r.codingStyleDefaultParameters.progressionOrder; switch (I) { case 0: r.packetsIterator = new d(e); break; case 1: r.packetsIterator = new f(e); break; case 2: r.packetsIterator = new g(e); break; case 3: r.packetsIterator = new m(e); break; case 4: r.packetsIterator = new p(e); break; default: throw new s(`Unsupported progression order ${I}`) } } function w(e, t, a, r) { var n, s = 0, o = 0, c = !1; function l(e) { for (; o < e;) { var r = t[a + s]; s++; if (c) { n = n << 7 | r; o += 7; c = !1 } else { n = n << 8 | r; o += 8 } 255 === r && (c = !0) } return n >>> (o -= e) & (1 << e) - 1 } function h(e) { if (255 === t[a + s - 1] && t[a + s] === e) { u(1); return !0 } if (255 === t[a + s] && t[a + s + 1] === e) { u(2); return !0 } return !1 } function u(e) { s += e } function d() { o = 0; if (c) { s++; c = !1 } } function f() { if (0 === l(1)) return 1; if (0 === l(1)) return 2; var e = l(2); return e < 3 ? e + 3 : (e = l(5)) < 31 ? e + 6 : (e = l(7)) + 37 } for (var g = e.currentTile.index, m = e.tiles[g], p = e.COD.sopMarkerUsed, b = e.COD.ephMarkerUsed, y = m.packetsIterator; s < r;) { d(); p && h(145) && u(4); var v = y.nextPacket(); if (l(1)) { for (var w, k = v.layerNumber, S = [], C = 0, I = v.codeblocks.length; C < I; C++) { var F = (w = v.codeblocks[C]).precinct, T = w.cbx - F.cbxMin, E = w.cby - F.cbyMin, O = !1, P = !1; if (void 0 !== w.included) O = !!l(1); else { var B, D; if (void 0 !== (F = w.precinct).inclusionTree) B = F.inclusionTree; else { var N = F.cbxMax - F.cbxMin + 1, M = F.cbyMax - F.cbyMin + 1; B = new A(N, M, k); D = new x(N, M); F.inclusionTree = B; F.zeroBitPlanesTree = D } if (B.reset(T, E, k)) for (; ;) { if (!l(1)) { B.incrementValue(k); break } if (!B.nextLevel()) { w.included = !0; O = P = !0; break } } } if (O) { if (P) { (D = F.zeroBitPlanesTree).reset(T, E); for (; ;)if (l(1)) { if (!D.nextLevel()) break } else D.incrementValue(); w.zeroBitPlanes = D.value } for (var L = f(); l(1);)w.Lblock++; var R = (0, i.log2)(L), U = l((L < 1 << R ? R - 1 : R) + w.Lblock); S.push({ codeblock: w, codingpasses: L, dataLength: U }) } } d(); b && h(146); for (; S.length > 0;) { var q = S.shift(); void 0 === (w = q.codeblock).data && (w.data = []); w.data.push({ data: t, start: a + s, end: a + s + q.dataLength, codingpasses: q.codingpasses }); s += q.dataLength } } } return s } function k(e, t, a, r, i, s, o, c) { for (var l = r.tbx0, h = r.tby0, u = r.tbx1 - r.tbx0, d = r.codeblocks, f = "H" === r.type.charAt(0) ? 1 : 0, g = "H" === r.type.charAt(1) ? t : 0, m = 0, p = d.length; m < p; ++m) { var b = d[m], y = b.tbx1_ - b.tbx0_, v = b.tby1_ - b.tby0_; if (0 !== y && 0 !== v && void 0 !== b.data) { var w, k; w = new I(y, v, b.subbandType, b.zeroBitPlanes, s); k = 2; var S, C, x, A = b.data, F = 0, T = 0; for (S = 0, C = A.length; S < C; S++) { F += (x = A[S]).end - x.start; T += x.codingpasses } var E = new Uint8Array(F), O = 0; for (S = 0, C = A.length; S < C; S++) { var P = (x = A[S]).data.subarray(x.start, x.end); E.set(P, O); O += P.length } var B = new n.ArithmeticDecoder(E, 0, F); w.setDecoder(B); for (S = 0; S < T; S++) { switch (k) { case 0: w.runSignificancePropagationPass(); break; case 1: w.runMagnitudeRefinementPass(); break; case 2: w.runCleanupPass(); c && w.checkSegmentationSymbol() }k = (k + 1) % 3 } var D, N, M, L = b.tbx0_ - l + (b.tby0_ - h) * u, R = w.coefficentsSign, U = w.coefficentsMagnitude, q = w.bitsDecoded, j = o ? 0 : .5; O = 0; var _ = "LL" !== r.type; for (S = 0; S < v; S++) { var z = 2 * (L / u | 0) * (t - u) + f + g; for (D = 0; D < y; D++) { if (0 !== (N = U[O])) { N = (N + j) * i; 0 !== R[O] && (N = -N); M = q[O]; var H = _ ? z + (L << 1) : L; e[H] = o && M >= s ? N : N * (1 << s - M) } L++; O++ } L += u - y } } } } function S(t, a, r) { for (var i = a.components[r], n = i.codingStyleParameters, s = i.quantizationParameters, o = n.decompositionLevelsCount, c = s.SPqcds, l = s.scalarExpounded, h = s.guardBits, u = n.segmentationSymbolUsed, d = t.components[r].precision, f = n.reversibleTransformation, g = f ? new E : new T, m = [], p = 0, b = 0; b <= o; b++) { for (var y = i.resolutions[b], v = y.trx1 - y.trx0, w = y.try1 - y.try0, S = new Float32Array(v * w), C = 0, x = y.subbands.length; C < x; C++) { var A, I; if (l) { A = c[p].mu; I = c[p].epsilon; p++ } else { A = c[0].mu; I = c[0].epsilon + (b > 0 ? 1 - b : 0) } var F = y.subbands[C], O = e[F.type]; k(S, v, 0, F, f ? 1 : 2 ** (d + O - I) * (1 + A / 2048), h + I - 1, f, u) } m.push({ width: v, height: w, items: S }) } var P = g.calculate(m, i.tcx0, i.tcy0); return { left: i.tcx0, top: i.tcy0, width: P.width, height: P.height, items: P.items } } function C(e, t) { for (var a = e.SIZ.Csiz, r = e.tiles[t], i = 0; i < a; i++) { var n = r.components[i], s = void 0 !== e.currentTile.QCC[i] ? e.currentTile.QCC[i] : e.currentTile.QCD; n.quantizationParameters = s; var o = void 0 !== e.currentTile.COC[i] ? e.currentTile.COC[i] : e.currentTile.COD; n.codingStyleParameters = o } r.codingStyleDefaultParameters = e.currentTile.COD } var x = function () { function e(e, t) { var a = (0, i.log2)(Math.max(e, t)) + 1; this.levels = []; for (var r = 0; r < a; r++) { var n = { width: e, height: t, items: [] }; this.levels.push(n); e = Math.ceil(e / 2); t = Math.ceil(t / 2) } } e.prototype = { reset: function (e, t) { for (var a, r = 0, i = 0; r < this.levels.length;) { var n = e + t * (a = this.levels[r]).width; if (void 0 !== a.items[n]) { i = a.items[n]; break } a.index = n; e >>= 1; t >>= 1; r++ } r--; (a = this.levels[r]).items[a.index] = i; this.currentLevel = r; delete this.value }, incrementValue: function () { var e = this.levels[this.currentLevel]; e.items[e.index]++ }, nextLevel: function () { var e = this.currentLevel, t = this.levels[e], a = t.items[t.index]; if (--e < 0) { this.value = a; return !1 } this.currentLevel = e; (t = this.levels[e]).items[t.index] = a; return !0 } }; return e }(), A = function () { function e(e, t, a) { var r = (0, i.log2)(Math.max(e, t)) + 1; this.levels = []; for (var n = 0; n < r; n++) { for (var s = new Uint8Array(e * t), o = 0, c = s.length; o < c; o++)s[o] = a; var l = { width: e, height: t, items: s }; this.levels.push(l); e = Math.ceil(e / 2); t = Math.ceil(t / 2) } } e.prototype = { reset: function (e, t, a) { for (var r = 0; r < this.levels.length;) { var i = this.levels[r], n = e + t * i.width; i.index = n; var s = i.items[n]; if (255 === s) break; if (s > a) { this.currentLevel = r; this.propagateValues(); return !1 } e >>= 1; t >>= 1; r++ } this.currentLevel = r - 1; return !0 }, incrementValue: function (e) { var t = this.levels[this.currentLevel]; t.items[t.index] = e + 1; this.propagateValues() }, propagateValues: function () { for (var e = this.currentLevel, t = this.levels[e], a = t.items[t.index]; --e >= 0;)(t = this.levels[e]).items[t.index] = a }, nextLevel: function () { var e = this.currentLevel, t = this.levels[e], a = t.items[t.index]; t.items[t.index] = 255; if (--e < 0) return !1; this.currentLevel = e; (t = this.levels[e]).items[t.index] = a; return !0 } }; return e }(), I = function () { var e = new Uint8Array([0, 5, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 1, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8]), t = new Uint8Array([0, 3, 4, 0, 5, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8]), a = new Uint8Array([0, 1, 2, 0, 1, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 3, 4, 5, 0, 4, 5, 5, 0, 5, 5, 5, 0, 0, 0, 0, 0, 6, 7, 7, 0, 7, 7, 7, 0, 7, 7, 7, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8]); function r(r, i, n, s, o) { this.width = r; this.height = i; let c; c = "HH" === n ? a : "HL" === n ? t : e; this.contextLabelTable = c; var l = r * i; this.neighborsSignificance = new Uint8Array(l); this.coefficentsSign = new Uint8Array(l); let h; h = o > 14 ? new Uint32Array(l) : o > 6 ? new Uint16Array(l) : new Uint8Array(l); this.coefficentsMagnitude = h; this.processingFlags = new Uint8Array(l); var u = new Uint8Array(l); if (0 !== s) for (var d = 0; d < l; d++)u[d] = s; this.bitsDecoded = u; this.reset() } r.prototype = { setDecoder: function (e) { this.decoder = e }, reset: function () { this.contexts = new Int8Array(19); this.contexts[0] = 8; this.contexts[17] = 92; this.contexts[18] = 6 }, setNeighborsSignificance: function (e, t, a) { var r, i = this.neighborsSignificance, n = this.width, s = this.height, o = t > 0, c = t + 1 < n; if (e > 0) { r = a - n; o && (i[r - 1] += 16); c && (i[r + 1] += 16); i[r] += 4 } if (e + 1 < s) { r = a + n; o && (i[r - 1] += 16); c && (i[r + 1] += 16); i[r] += 4 } o && (i[a - 1] += 1); c && (i[a + 1] += 1); i[a] |= 128 }, runSignificancePropagationPass: function () { for (var e = this.decoder, t = this.width, a = this.height, r = this.coefficentsMagnitude, i = this.coefficentsSign, n = this.neighborsSignificance, s = this.processingFlags, o = this.contexts, c = this.contextLabelTable, l = this.bitsDecoded, h = 0; h < a; h += 4)for (var u = 0; u < t; u++)for (var d = h * t + u, f = 0; f < 4; f++, d += t) { var g = h + f; if (g >= a) break; s[d] &= -2; if (!r[d] && n[d]) { var m = c[n[d]]; if (e.readBit(o, m)) { var p = this.decodeSignBit(g, u, d); i[d] = p; r[d] = 1; this.setNeighborsSignificance(g, u, d); s[d] |= 2 } l[d]++; s[d] |= 1 } } }, decodeSignBit: function (e, t, a) { var r, i, n, s, o, c, l = this.width, h = this.height, u = this.coefficentsMagnitude, d = this.coefficentsSign; s = t > 0 && 0 !== u[a - 1]; if (t + 1 < l && 0 !== u[a + 1]) { n = d[a + 1]; r = s ? 1 - n - (i = d[a - 1]) : 1 - n - n } else r = s ? 1 - (i = d[a - 1]) - i : 0; var f = 3 * r; s = e > 0 && 0 !== u[a - l]; if (e + 1 < h && 0 !== u[a + l]) { n = d[a + l]; r = s ? 1 - n - (i = d[a - l]) + f : 1 - n - n + f } else r = s ? 1 - (i = d[a - l]) - i + f : f; if (r >= 0) { o = 9 + r; c = this.decoder.readBit(this.contexts, o) } else { o = 9 - r; c = 1 ^ this.decoder.readBit(this.contexts, o) } return c }, runMagnitudeRefinementPass: function () { for (var e, t = this.decoder, a = this.width, r = this.height, i = this.coefficentsMagnitude, n = this.neighborsSignificance, s = this.contexts, o = this.bitsDecoded, c = this.processingFlags, l = a * r, h = 4 * a, u = 0; u < l; u = e) { e = Math.min(l, u + h); for (var d = 0; d < a; d++)for (var f = u + d; f < e; f += a)if (i[f] && 0 == (1 & c[f])) { var g = 16; if (0 != (2 & c[f])) { c[f] ^= 2; g = 0 === (127 & n[f]) ? 15 : 14 } var m = t.readBit(s, g); i[f] = i[f] << 1 | m; o[f]++; c[f] |= 1 } } }, runCleanupPass: function () { for (var e, t = this.decoder, a = this.width, r = this.height, i = this.neighborsSignificance, n = this.coefficentsMagnitude, s = this.coefficentsSign, o = this.contexts, c = this.contextLabelTable, l = this.bitsDecoded, h = this.processingFlags, u = a, d = 2 * a, f = 3 * a, g = 0; g < r; g = e) { e = Math.min(g + 4, r); for (var m = g * a, p = g + 3 < r, b = 0; b < a; b++) { var y, v = m + b, w = 0, k = v, S = g; if (p && 0 === h[v] && 0 === h[v + u] && 0 === h[v + d] && 0 === h[v + f] && 0 === i[v] && 0 === i[v + u] && 0 === i[v + d] && 0 === i[v + f]) { if (!t.readBit(o, 18)) { l[v]++; l[v + u]++; l[v + d]++; l[v + f]++; continue } if (0 !== (w = t.readBit(o, 17) << 1 | t.readBit(o, 17))) { S = g + w; k += w * a } y = this.decodeSignBit(S, b, k); s[k] = y; n[k] = 1; this.setNeighborsSignificance(S, b, k); h[k] |= 2; k = v; for (var C = g; C <= S; C++, k += a)l[k]++; w++ } for (S = g + w; S < e; S++, k += a)if (!n[k] && 0 == (1 & h[k])) { var x = c[i[k]]; if (1 === t.readBit(o, x)) { y = this.decodeSignBit(S, b, k); s[k] = y; n[k] = 1; this.setNeighborsSignificance(S, b, k); h[k] |= 2 } l[k]++ } } } }, checkSegmentationSymbol: function () { var e = this.decoder, t = this.contexts; if (10 !== (e.readBit(t, 17) << 3 | e.readBit(t, 17) << 2 | e.readBit(t, 17) << 1 | e.readBit(t, 17))) throw new s("Invalid segmentation symbol") } }; return r }(), F = function () { function e() { } e.prototype.calculate = function (e, t, a) { for (var r = e[0], i = 1, n = e.length; i < n; i++)r = this.iterate(r, e[i], t, a); return r }; e.prototype.extend = function (e, t, a) { var r = t - 1, i = t + 1, n = t + a - 2, s = t + a; e[r--] = e[i++]; e[s++] = e[n--]; e[r--] = e[i++]; e[s++] = e[n--]; e[r--] = e[i++]; e[s++] = e[n--]; e[r] = e[i]; e[s] = e[n] }; e.prototype.iterate = function (e, t, a, r) { var i, n, s, o, c, l, h = e.width, u = e.height, d = e.items, f = t.width, g = t.height, m = t.items; for (s = 0, i = 0; i < u; i++) { o = 2 * i * f; for (n = 0; n < h; n++, s++, o += 2)m[o] = d[s] } d = e.items = null; var p = new Float32Array(f + 8); if (1 === f) { if (0 != (1 & a)) for (l = 0, s = 0; l < g; l++, s += f)m[s] *= .5 } else for (l = 0, s = 0; l < g; l++, s += f) { p.set(m.subarray(s, s + f), 4); this.extend(p, 4, f); this.filter(p, 4, f); m.set(p.subarray(4, 4 + f), s) } var b = 16, y = []; for (i = 0; i < b; i++)y.push(new Float32Array(g + 8)); var v, w = 0; e = 4 + g; if (1 === g) { if (0 != (1 & r)) for (c = 0; c < f; c++)m[c] *= .5 } else for (c = 0; c < f; c++) { if (0 === w) { b = Math.min(f - c, b); for (s = c, o = 4; o < e; s += f, o++)for (v = 0; v < b; v++)y[v][o] = m[s + v]; w = b } var k = y[--w]; this.extend(k, 4, g); this.filter(k, 4, g); if (0 === w) { s = c - b + 1; for (o = 4; o < e; s += f, o++)for (v = 0; v < b; v++)m[s + v] = y[v][o] } } return { width: f, height: g, items: m } }; return e }(), T = function () { function e() { F.call(this) } e.prototype = Object.create(F.prototype); e.prototype.filter = function (e, t, a) { var r, i, n, s, o = a >> 1, c = -1.586134342059924, l = -.052980118572961, h = .882911075530934, u = .443506852043971, d = 1.230174104914001; r = (t |= 0) - 3; for (i = o + 4; i--; r += 2)e[r] *= .8128930661159609; n = u * e[(r = t - 2) - 1]; for (i = o + 3; i--; r += 2) { s = u * e[r + 1]; e[r] = d * e[r] - n - s; if (!i--) break; n = u * e[(r += 2) + 1]; e[r] = d * e[r] - n - s } n = h * e[(r = t - 1) - 1]; for (i = o + 2; i--; r += 2) { s = h * e[r + 1]; e[r] -= n + s; if (!i--) break; n = h * e[(r += 2) + 1]; e[r] -= n + s } n = l * e[(r = t) - 1]; for (i = o + 1; i--; r += 2) { s = l * e[r + 1]; e[r] -= n + s; if (!i--) break; n = l * e[(r += 2) + 1]; e[r] -= n + s } if (0 !== o) { n = c * e[(r = t + 1) - 1]; for (i = o; i--; r += 2) { s = c * e[r + 1]; e[r] -= n + s; if (!i--) break; n = c * e[(r += 2) + 1]; e[r] -= n + s } } }; return e }(), E = function () { function e() { F.call(this) } e.prototype = Object.create(F.prototype); e.prototype.filter = function (e, t, a) { var r, i, n = a >> 1; for (r = t |= 0, i = n + 1; i--; r += 2)e[r] -= e[r - 1] + e[r + 1] + 2 >> 2; for (r = t + 1, i = n; i--; r += 2)e[r] += e[r - 1] + e[r + 1] >> 1 }; return e }(); return t }(); t.JpxImage = o }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.calculateSHA512 = t.calculateSHA384 = t.calculateSHA256 = t.calculateMD5 = t.PDF20 = t.PDF17 = t.CipherTransformFactory = t.ARCFourCipher = t.AES256Cipher = t.AES128Cipher = void 0; var r = a(2), i = a(4), n = a(11), s = function () { function e(e) { this.a = 0; this.b = 0; var t, a, r = new Uint8Array(256), i = 0, n = e.length; for (t = 0; t < 256; ++t)r[t] = t; for (t = 0; t < 256; ++t) { i = i + (a = r[t]) + e[t % n] & 255; r[t] = r[i]; r[i] = a } this.s = r } e.prototype = { encryptBlock: function (e) { var t, a, r, i = e.length, n = this.a, s = this.b, o = this.s, c = new Uint8Array(i); for (t = 0; t < i; ++t) { r = o[s = s + (a = o[n = n + 1 & 255]) & 255]; o[n] = r; o[s] = a; c[t] = e[t] ^ o[a + r & 255] } this.a = n; this.b = s; return c } }; e.prototype.decryptBlock = e.prototype.encryptBlock; return e }(); t.ARCFourCipher = s; var o, c, l = (o = new Uint8Array([7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]), c = new Int32Array([-680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, -145523070, -1120210379, 718787259, -343485551]), function (e, t, a) { var r, i, n, s = 1732584193, l = -271733879, h = -1732584194, u = 271733878, d = a + 72 & -64, f = new Uint8Array(d); for (r = 0; r < a; ++r)f[r] = e[t++]; f[r++] = 128; n = d - 8; for (; r < n;)f[r++] = 0; f[r++] = a << 3 & 255; f[r++] = a >> 5 & 255; f[r++] = a >> 13 & 255; f[r++] = a >> 21 & 255; f[r++] = a >>> 29 & 255; f[r++] = 0; f[r++] = 0; f[r++] = 0; var g = new Int32Array(16); for (r = 0; r < d;) { for (i = 0; i < 16; ++i, r += 4)g[i] = f[r] | f[r + 1] << 8 | f[r + 2] << 16 | f[r + 3] << 24; var m, p, b = s, y = l, v = h, w = u; for (i = 0; i < 64; ++i) { if (i < 16) { m = y & v | ~y & w; p = i } else if (i < 32) { m = w & y | ~w & v; p = 5 * i + 1 & 15 } else if (i < 48) { m = y ^ v ^ w; p = 3 * i + 5 & 15 } else { m = v ^ (y | ~w); p = 7 * i & 15 } var k = w, S = b + m + c[i] + g[p] | 0, C = o[i]; w = v; v = y; y = y + (S << C | S >>> 32 - C) | 0; b = k } s = s + b | 0; l = l + y | 0; h = h + v | 0; u = u + w | 0 } return new Uint8Array([255 & s, s >> 8 & 255, s >> 16 & 255, s >>> 24 & 255, 255 & l, l >> 8 & 255, l >> 16 & 255, l >>> 24 & 255, 255 & h, h >> 8 & 255, h >> 16 & 255, h >>> 24 & 255, 255 & u, u >> 8 & 255, u >> 16 & 255, u >>> 24 & 255]) }); t.calculateMD5 = l; var h = function () { function e(e, t) { this.high = 0 | e; this.low = 0 | t } e.prototype = { and: function (e) { this.high &= e.high; this.low &= e.low }, xor: function (e) { this.high ^= e.high; this.low ^= e.low }, or: function (e) { this.high |= e.high; this.low |= e.low }, shiftRight: function (e) { if (e >= 32) { this.low = this.high >>> e - 32 | 0; this.high = 0 } else { this.low = this.low >>> e | this.high << 32 - e; this.high = this.high >>> e | 0 } }, shiftLeft: function (e) { if (e >= 32) { this.high = this.low << e - 32; this.low = 0 } else { this.high = this.high << e | this.low >>> 32 - e; this.low = this.low << e } }, rotateRight: function (e) { var t, a; if (32 & e) { a = this.low; t = this.high } else { t = this.low; a = this.high } e &= 31; this.low = t >>> e | a << 32 - e; this.high = a >>> e | t << 32 - e }, not: function () { this.high = ~this.high; this.low = ~this.low }, add: function (e) { var t = (this.low >>> 0) + (e.low >>> 0), a = (this.high >>> 0) + (e.high >>> 0); t > 4294967295 && (a += 1); this.low = 0 | t; this.high = 0 | a }, copyTo: function (e, t) { e[t] = this.high >>> 24 & 255; e[t + 1] = this.high >> 16 & 255; e[t + 2] = this.high >> 8 & 255; e[t + 3] = 255 & this.high; e[t + 4] = this.low >>> 24 & 255; e[t + 5] = this.low >> 16 & 255; e[t + 6] = this.low >> 8 & 255; e[t + 7] = 255 & this.low }, assign: function (e) { this.high = e.high; this.low = e.low } }; return e }(), u = function () { function e(e, t) { return e >>> t | e << 32 - t } function t(e, t, a) { return e & t ^ ~e & a } function a(e, t, a) { return e & t ^ e & a ^ t & a } function r(t) { return e(t, 2) ^ e(t, 13) ^ e(t, 22) } function i(t) { return e(t, 6) ^ e(t, 11) ^ e(t, 25) } function n(t) { return e(t, 7) ^ e(t, 18) ^ t >>> 3 } var s = [1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298]; return function (o, c, l) { var h, u, d, f = 1779033703, g = 3144134277, m = 1013904242, p = 2773480762, b = 1359893119, y = 2600822924, v = 528734635, w = 1541459225, k = 64 * Math.ceil((l + 9) / 64), S = new Uint8Array(k); for (h = 0; h < l; ++h)S[h] = o[c++]; S[h++] = 128; d = k - 8; for (; h < d;)S[h++] = 0; S[h++] = 0; S[h++] = 0; S[h++] = 0; S[h++] = l >>> 29 & 255; S[h++] = l >> 21 & 255; S[h++] = l >> 13 & 255; S[h++] = l >> 5 & 255; S[h++] = l << 3 & 255; var C, x = new Uint32Array(64); for (h = 0; h < k;) { for (u = 0; u < 16; ++u) { x[u] = S[h] << 24 | S[h + 1] << 16 | S[h + 2] << 8 | S[h + 3]; h += 4 } for (u = 16; u < 64; ++u)x[u] = (e(C = x[u - 2], 17) ^ e(C, 19) ^ C >>> 10) + x[u - 7] + n(x[u - 15]) + x[u - 16] | 0; var A, I, F = f, T = g, E = m, O = p, P = b, B = y, D = v, N = w; for (u = 0; u < 64; ++u) { A = N + i(P) + t(P, B, D) + s[u] + x[u]; I = r(F) + a(F, T, E); N = D; D = B; B = P; P = O + A | 0; O = E; E = T; T = F; F = A + I | 0 } f = f + F | 0; g = g + T | 0; m = m + E | 0; p = p + O | 0; b = b + P | 0; y = y + B | 0; v = v + D | 0; w = w + N | 0 } return new Uint8Array([f >> 24 & 255, f >> 16 & 255, f >> 8 & 255, 255 & f, g >> 24 & 255, g >> 16 & 255, g >> 8 & 255, 255 & g, m >> 24 & 255, m >> 16 & 255, m >> 8 & 255, 255 & m, p >> 24 & 255, p >> 16 & 255, p >> 8 & 255, 255 & p, b >> 24 & 255, b >> 16 & 255, b >> 8 & 255, 255 & b, y >> 24 & 255, y >> 16 & 255, y >> 8 & 255, 255 & y, v >> 24 & 255, v >> 16 & 255, v >> 8 & 255, 255 & v, w >> 24 & 255, w >> 16 & 255, w >> 8 & 255, 255 & w]) } }(); t.calculateSHA256 = u; var d = function () { function e(e, t, a, r, i) { e.assign(t); e.and(a); i.assign(t); i.not(); i.and(r); e.xor(i) } function t(e, t, a, r, i) { e.assign(t); e.and(a); i.assign(t); i.and(r); e.xor(i); i.assign(a); i.and(r); e.xor(i) } function a(e, t, a) { e.assign(t); e.rotateRight(28); a.assign(t); a.rotateRight(34); e.xor(a); a.assign(t); a.rotateRight(39); e.xor(a) } function r(e, t, a) { e.assign(t); e.rotateRight(14); a.assign(t); a.rotateRight(18); e.xor(a); a.assign(t); a.rotateRight(41); e.xor(a) } function i(e, t, a) { e.assign(t); e.rotateRight(1); a.assign(t); a.rotateRight(8); e.xor(a); a.assign(t); a.shiftRight(7); e.xor(a) } function n(e, t, a) { e.assign(t); e.rotateRight(19); a.assign(t); a.rotateRight(61); e.xor(a); a.assign(t); a.shiftRight(6); e.xor(a) } var s = [new h(1116352408, 3609767458), new h(1899447441, 602891725), new h(3049323471, 3964484399), new h(3921009573, 2173295548), new h(961987163, 4081628472), new h(1508970993, 3053834265), new h(2453635748, 2937671579), new h(2870763221, 3664609560), new h(3624381080, 2734883394), new h(310598401, 1164996542), new h(607225278, 1323610764), new h(1426881987, 3590304994), new h(1925078388, 4068182383), new h(2162078206, 991336113), new h(2614888103, 633803317), new h(3248222580, 3479774868), new h(3835390401, 2666613458), new h(4022224774, 944711139), new h(264347078, 2341262773), new h(604807628, 2007800933), new h(770255983, 1495990901), new h(1249150122, 1856431235), new h(1555081692, 3175218132), new h(1996064986, 2198950837), new h(2554220882, 3999719339), new h(2821834349, 766784016), new h(2952996808, 2566594879), new h(3210313671, 3203337956), new h(3336571891, 1034457026), new h(3584528711, 2466948901), new h(113926993, 3758326383), new h(338241895, 168717936), new h(666307205, 1188179964), new h(773529912, 1546045734), new h(1294757372, 1522805485), new h(1396182291, 2643833823), new h(1695183700, 2343527390), new h(1986661051, 1014477480), new h(2177026350, 1206759142), new h(2456956037, 344077627), new h(2730485921, 1290863460), new h(2820302411, 3158454273), new h(3259730800, 3505952657), new h(3345764771, 106217008), new h(3516065817, 3606008344), new h(3600352804, 1432725776), new h(4094571909, 1467031594), new h(275423344, 851169720), new h(430227734, 3100823752), new h(506948616, 1363258195), new h(659060556, 3750685593), new h(883997877, 3785050280), new h(958139571, 3318307427), new h(1322822218, 3812723403), new h(1537002063, 2003034995), new h(1747873779, 3602036899), new h(1955562222, 1575990012), new h(2024104815, 1125592928), new h(2227730452, 2716904306), new h(2361852424, 442776044), new h(2428436474, 593698344), new h(2756734187, 3733110249), new h(3204031479, 2999351573), new h(3329325298, 3815920427), new h(3391569614, 3928383900), new h(3515267271, 566280711), new h(3940187606, 3454069534), new h(4118630271, 4000239992), new h(116418474, 1914138554), new h(174292421, 2731055270), new h(289380356, 3203993006), new h(460393269, 320620315), new h(685471733, 587496836), new h(852142971, 1086792851), new h(1017036298, 365543100), new h(1126000580, 2618297676), new h(1288033470, 3409855158), new h(1501505948, 4234509866), new h(1607167915, 987167468), new h(1816402316, 1246189591)]; return function (o, c, l, u) { var d, f, g, m, p, b, y, v; if (u = !!u) { d = new h(3418070365, 3238371032); f = new h(1654270250, 914150663); g = new h(2438529370, 812702999); m = new h(355462360, 4144912697); p = new h(1731405415, 4290775857); b = new h(2394180231, 1750603025); y = new h(3675008525, 1694076839); v = new h(1203062813, 3204075428) } else { d = new h(1779033703, 4089235720); f = new h(3144134277, 2227873595); g = new h(1013904242, 4271175723); m = new h(2773480762, 1595750129); p = new h(1359893119, 2917565137); b = new h(2600822924, 725511199); y = new h(528734635, 4215389547); v = new h(1541459225, 327033209) } var w, k, S, C = 128 * Math.ceil((l + 17) / 128), x = new Uint8Array(C); for (w = 0; w < l; ++w)x[w] = o[c++]; x[w++] = 128; S = C - 16; for (; w < S;)x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = l >>> 29 & 255; x[w++] = l >> 21 & 255; x[w++] = l >> 13 & 255; x[w++] = l >> 5 & 255; x[w++] = l << 3 & 255; var A = new Array(80); for (w = 0; w < 80; w++)A[w] = new h(0, 0); var I, F, T = new h(0, 0), E = new h(0, 0), O = new h(0, 0), P = new h(0, 0), B = new h(0, 0), D = new h(0, 0), N = new h(0, 0), M = new h(0, 0), L = new h(0, 0), R = new h(0, 0), U = new h(0, 0), q = new h(0, 0); for (w = 0; w < C;) { for (k = 0; k < 16; ++k) { A[k].high = x[w] << 24 | x[w + 1] << 16 | x[w + 2] << 8 | x[w + 3]; A[k].low = x[w + 4] << 24 | x[w + 5] << 16 | x[w + 6] << 8 | x[w + 7]; w += 8 } for (k = 16; k < 80; ++k) { n(I = A[k], A[k - 2], q); I.add(A[k - 7]); i(U, A[k - 15], q); I.add(U); I.add(A[k - 16]) } T.assign(d); E.assign(f); O.assign(g); P.assign(m); B.assign(p); D.assign(b); N.assign(y); M.assign(v); for (k = 0; k < 80; ++k) { L.assign(M); r(U, B, q); L.add(U); e(U, B, D, N, q); L.add(U); L.add(s[k]); L.add(A[k]); a(R, T, q); t(U, T, E, O, q); R.add(U); I = M; M = N; N = D; D = B; P.add(L); B = P; P = O; O = E; E = T; I.assign(L); I.add(R); T = I } d.add(T); f.add(E); g.add(O); m.add(P); p.add(B); b.add(D); y.add(N); v.add(M) } if (u) { F = new Uint8Array(48); d.copyTo(F, 0); f.copyTo(F, 8); g.copyTo(F, 16); m.copyTo(F, 24); p.copyTo(F, 32); b.copyTo(F, 40) } else { F = new Uint8Array(64); d.copyTo(F, 0); f.copyTo(F, 8); g.copyTo(F, 16); m.copyTo(F, 24); p.copyTo(F, 32); b.copyTo(F, 40); y.copyTo(F, 48); v.copyTo(F, 56) } return F } }(); t.calculateSHA512 = d; var f = function (e, t, a) { return d(e, t, a, !0) }; t.calculateSHA384 = f; var g = function () { function e() { } e.prototype = { decryptBlock: function (e) { return e } }; return e }(); class m { constructor() { this.constructor === m && (0, r.unreachable)("Cannot initialize AESBaseCipher."); this._s = new Uint8Array([99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22]); this._inv_s = new Uint8Array([82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125]); this._mix = new Uint32Array([0, 235474187, 470948374, 303765277, 941896748, 908933415, 607530554, 708780849, 1883793496, 2118214995, 1817866830, 1649639237, 1215061108, 1181045119, 1417561698, 1517767529, 3767586992, 4003061179, 4236429990, 4069246893, 3635733660, 3602770327, 3299278474, 3400528769, 2430122216, 2664543715, 2362090238, 2193862645, 2835123396, 2801107407, 3035535058, 3135740889, 3678124923, 3576870512, 3341394285, 3374361702, 3810496343, 3977675356, 4279080257, 4043610186, 2876494627, 2776292904, 3076639029, 3110650942, 2472011535, 2640243204, 2403728665, 2169303058, 1001089995, 899835584, 666464733, 699432150, 59727847, 226906860, 530400753, 294930682, 1273168787, 1172967064, 1475418501, 1509430414, 1942435775, 2110667444, 1876241833, 1641816226, 2910219766, 2743034109, 2976151520, 3211623147, 2505202138, 2606453969, 2302690252, 2269728455, 3711829422, 3543599269, 3240894392, 3475313331, 3843699074, 3943906441, 4178062228, 4144047775, 1306967366, 1139781709, 1374988112, 1610459739, 1975683434, 2076935265, 1775276924, 1742315127, 1034867998, 866637845, 566021896, 800440835, 92987698, 193195065, 429456164, 395441711, 1984812685, 2017778566, 1784663195, 1683407248, 1315562145, 1080094634, 1383856311, 1551037884, 101039829, 135050206, 437757123, 337553864, 1042385657, 807962610, 573804783, 742039012, 2531067453, 2564033334, 2328828971, 2227573024, 2935566865, 2700099354, 3001755655, 3168937228, 3868552805, 3902563182, 4203181171, 4102977912, 3736164937, 3501741890, 3265478751, 3433712980, 1106041591, 1340463100, 1576976609, 1408749034, 2043211483, 2009195472, 1708848333, 1809054150, 832877231, 1068351396, 766945465, 599762354, 159417987, 126454664, 361929877, 463180190, 2709260871, 2943682380, 3178106961, 3009879386, 2572697195, 2538681184, 2236228733, 2336434550, 3509871135, 3745345300, 3441850377, 3274667266, 3910161971, 3877198648, 4110568485, 4211818798, 2597806476, 2497604743, 2261089178, 2295101073, 2733856160, 2902087851, 3202437046, 2968011453, 3936291284, 3835036895, 4136440770, 4169408201, 3535486456, 3702665459, 3467192302, 3231722213, 2051518780, 1951317047, 1716890410, 1750902305, 1113818384, 1282050075, 1584504582, 1350078989, 168810852, 67556463, 371049330, 404016761, 841739592, 1008918595, 775550814, 540080725, 3969562369, 3801332234, 4035489047, 4269907996, 3569255213, 3669462566, 3366754619, 3332740144, 2631065433, 2463879762, 2160117071, 2395588676, 2767645557, 2868897406, 3102011747, 3069049960, 202008497, 33778362, 270040487, 504459436, 875451293, 975658646, 675039627, 641025152, 2084704233, 1917518562, 1615861247, 1851332852, 1147550661, 1248802510, 1484005843, 1451044056, 933301370, 967311729, 733156972, 632953703, 260388950, 25965917, 328671808, 496906059, 1206477858, 1239443753, 1543208500, 1441952575, 2144161806, 1908694277, 1675577880, 1842759443, 3610369226, 3644379585, 3408119516, 3307916247, 4011190502, 3776767469, 4077384432, 4245618683, 2809771154, 2842737049, 3144396420, 3043140495, 2673705150, 2438237621, 2203032232, 2370213795]); this._mixCol = new Uint8Array(256); for (let e = 0; e < 256; e++)this._mixCol[e] = e < 128 ? e << 1 : e << 1 ^ 27; this.buffer = new Uint8Array(16); this.bufferPosition = 0 } _expandKey(e) { (0, r.unreachable)("Cannot call `_expandKey` on the base class") } _decrypt(e, t) { let a, r, i; const n = new Uint8Array(16); n.set(e); for (let e = 0, a = this._keySize; e < 16; ++e, ++a)n[e] ^= t[a]; for (let e = this._cyclesOfRepetition - 1; e >= 1; --e) { a = n[13]; n[13] = n[9]; n[9] = n[5]; n[5] = n[1]; n[1] = a; a = n[14]; r = n[10]; n[14] = n[6]; n[10] = n[2]; n[6] = a; n[2] = r; a = n[15]; r = n[11]; i = n[7]; n[15] = n[3]; n[11] = a; n[7] = r; n[3] = i; for (let e = 0; e < 16; ++e)n[e] = this._inv_s[n[e]]; for (let a = 0, r = 16 * e; a < 16; ++a, ++r)n[a] ^= t[r]; for (let e = 0; e < 16; e += 4) { const t = this._mix[n[e]], r = this._mix[n[e + 1]], i = this._mix[n[e + 2]], s = this._mix[n[e + 3]]; a = t ^ r >>> 8 ^ r << 24 ^ i >>> 16 ^ i << 16 ^ s >>> 24 ^ s << 8; n[e] = a >>> 24 & 255; n[e + 1] = a >> 16 & 255; n[e + 2] = a >> 8 & 255; n[e + 3] = 255 & a } } a = n[13]; n[13] = n[9]; n[9] = n[5]; n[5] = n[1]; n[1] = a; a = n[14]; r = n[10]; n[14] = n[6]; n[10] = n[2]; n[6] = a; n[2] = r; a = n[15]; r = n[11]; i = n[7]; n[15] = n[3]; n[11] = a; n[7] = r; n[3] = i; for (let e = 0; e < 16; ++e) { n[e] = this._inv_s[n[e]]; n[e] ^= t[e] } return n } _encrypt(e, t) { const a = this._s; let r, i, n; const s = new Uint8Array(16); s.set(e); for (let e = 0; e < 16; ++e)s[e] ^= t[e]; for (let e = 1; e < this._cyclesOfRepetition; e++) { for (let e = 0; e < 16; ++e)s[e] = a[s[e]]; n = s[1]; s[1] = s[5]; s[5] = s[9]; s[9] = s[13]; s[13] = n; n = s[2]; i = s[6]; s[2] = s[10]; s[6] = s[14]; s[10] = n; s[14] = i; n = s[3]; i = s[7]; r = s[11]; s[3] = s[15]; s[7] = n; s[11] = i; s[15] = r; for (let e = 0; e < 16; e += 4) { const t = s[e + 0], a = s[e + 1], i = s[e + 2], n = s[e + 3]; r = t ^ a ^ i ^ n; s[e + 0] ^= r ^ this._mixCol[t ^ a]; s[e + 1] ^= r ^ this._mixCol[a ^ i]; s[e + 2] ^= r ^ this._mixCol[i ^ n]; s[e + 3] ^= r ^ this._mixCol[n ^ t] } for (let a = 0, r = 16 * e; a < 16; ++a, ++r)s[a] ^= t[r] } for (let e = 0; e < 16; ++e)s[e] = a[s[e]]; n = s[1]; s[1] = s[5]; s[5] = s[9]; s[9] = s[13]; s[13] = n; n = s[2]; i = s[6]; s[2] = s[10]; s[6] = s[14]; s[10] = n; s[14] = i; n = s[3]; i = s[7]; r = s[11]; s[3] = s[15]; s[7] = n; s[11] = i; s[15] = r; for (let e = 0, a = this._keySize; e < 16; ++e, ++a)s[e] ^= t[a]; return s } _decryptBlock2(e, t) { const a = e.length; let r = this.buffer, i = this.bufferPosition; const n = []; let s = this.iv; for (let t = 0; t < a; ++t) { r[i] = e[t]; ++i; if (i < 16) continue; const a = this._decrypt(r, this._key); for (let e = 0; e < 16; ++e)a[e] ^= s[e]; s = r; n.push(a); r = new Uint8Array(16); i = 0 } this.buffer = r; this.bufferLength = i; this.iv = s; if (0 === n.length) return new Uint8Array(0); let o = 16 * n.length; if (t) { const e = n[n.length - 1]; let t = e[15]; if (t <= 16) { for (let a = 15, r = 16 - t; a >= r; --a)if (e[a] !== t) { t = 0; break } o -= t; n[n.length - 1] = e.subarray(0, 16 - t) } } const c = new Uint8Array(o); for (let e = 0, t = 0, a = n.length; e < a; ++e, t += 16)c.set(n[e], t); return c } decryptBlock(e, t, a = null) { const r = e.length, i = this.buffer; let n = this.bufferPosition; if (a) this.iv = a; else { for (let t = 0; n < 16 && t < r; ++t, ++n)i[n] = e[t]; if (n < 16) { this.bufferLength = n; return new Uint8Array(0) } this.iv = i; e = e.subarray(16) } this.buffer = new Uint8Array(16); this.bufferLength = 0; this.decryptBlock = this._decryptBlock2; return this.decryptBlock(e, t) } encrypt(e, t) { const a = e.length; let r = this.buffer, i = this.bufferPosition; const n = []; t || (t = new Uint8Array(16)); for (let s = 0; s < a; ++s) { r[i] = e[s]; ++i; if (i < 16) continue; for (let e = 0; e < 16; ++e)r[e] ^= t[e]; const a = this._encrypt(r, this._key); t = a; n.push(a); r = new Uint8Array(16); i = 0 } this.buffer = r; this.bufferLength = i; this.iv = t; if (0 === n.length) return new Uint8Array(0); const s = 16 * n.length, o = new Uint8Array(s); for (let e = 0, t = 0, a = n.length; e < a; ++e, t += 16)o.set(n[e], t); return o } } class p extends m { constructor(e) { super(); this._cyclesOfRepetition = 10; this._keySize = 160; this._rcon = new Uint8Array([141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141]); this._key = this._expandKey(e) } _expandKey(e) { const t = this._s, a = this._rcon, r = new Uint8Array(176); r.set(e); for (let e = 16, i = 1; e < 176; ++i) { let n = r[e - 3], s = r[e - 2], o = r[e - 1], c = r[e - 4]; n = t[n]; s = t[s]; o = t[o]; c = t[c]; n ^= a[i]; for (let t = 0; t < 4; ++t) { r[e] = n ^= r[e - 16]; e++; r[e] = s ^= r[e - 16]; e++; r[e] = o ^= r[e - 16]; e++; r[e] = c ^= r[e - 16]; e++ } } return r } } t.AES128Cipher = p; class b extends m { constructor(e) { super(); this._cyclesOfRepetition = 14; this._keySize = 224; this._key = this._expandKey(e) } _expandKey(e) { const t = this._s, a = new Uint8Array(240); a.set(e); let r, i, n, s, o = 1; for (let e = 32, c = 1; e < 240; ++c) { if (e % 32 == 16) { r = t[r]; i = t[i]; n = t[n]; s = t[s] } else if (e % 32 == 0) { r = a[e - 3]; i = a[e - 2]; n = a[e - 1]; s = a[e - 4]; r = t[r]; i = t[i]; n = t[n]; s = t[s]; r ^= o; (o <<= 1) >= 256 && (o = 255 & (27 ^ o)) } for (let t = 0; t < 4; ++t) { a[e] = r ^= a[e - 32]; e++; a[e] = i ^= a[e - 32]; e++; a[e] = n ^= a[e - 32]; e++; a[e] = s ^= a[e - 32]; e++ } } return a } } t.AES256Cipher = b; var y = function () { function e(e, t) { if (e.length !== t.length) return !1; for (var a = 0; a < e.length; a++)if (e[a] !== t[a]) return !1; return !0 } function t() { } t.prototype = { checkOwnerPassword: function (t, a, r, i) { var n = new Uint8Array(t.length + 56); n.set(t, 0); n.set(a, t.length); n.set(r, t.length + a.length); return e(u(n, 0, n.length), i) }, checkUserPassword: function (t, a, r) { var i = new Uint8Array(t.length + 8); i.set(t, 0); i.set(a, t.length); return e(u(i, 0, i.length), r) }, getOwnerKey: function (e, t, a, r) { var i = new Uint8Array(e.length + 56); i.set(e, 0); i.set(t, e.length); i.set(a, e.length + t.length); var n = u(i, 0, i.length); return new b(n).decryptBlock(r, !1, new Uint8Array(16)) }, getUserKey: function (e, t, a) { var r = new Uint8Array(e.length + 8); r.set(e, 0); r.set(t, e.length); var i = u(r, 0, r.length); return new b(i).decryptBlock(a, !1, new Uint8Array(16)) } }; return t }(); t.PDF17 = y; var v = function () { function e(e, t) { var a = new Uint8Array(e.length + t.length); a.set(e, 0); a.set(t, e.length); return a } function t(t, a, r) { for (var i = u(a, 0, a.length).subarray(0, 32), n = [0], s = 0; s < 64 || n[n.length - 1] > s - 32;) { var o = t.length + i.length + r.length, c = new Uint8Array(64 * o), l = e(t, i); l = e(l, r); for (var h = 0, g = 0; h < 64; h++, g += o)c.set(l, g); n = new p(i.subarray(0, 16)).encrypt(c, i.subarray(16, 32)); for (var m = 0, b = 0; b < 16; b++) { m *= 1; m %= 3; m += (n[b] >>> 0) % 3; m %= 3 } 0 === m ? i = u(n, 0, n.length) : 1 === m ? i = f(n, 0, n.length) : 2 === m && (i = d(n, 0, n.length)); s++ } return i.subarray(0, 32) } function a() { } function r(e, t) { if (e.length !== t.length) return !1; for (var a = 0; a < e.length; a++)if (e[a] !== t[a]) return !1; return !0 } a.prototype = { hash: function (e, a, r) { return t(e, a, r) }, checkOwnerPassword: function (e, a, i, n) { var s = new Uint8Array(e.length + 56); s.set(e, 0); s.set(a, e.length); s.set(i, e.length + a.length); return r(t(e, s, i), n) }, checkUserPassword: function (e, a, i) { var n = new Uint8Array(e.length + 8); n.set(e, 0); n.set(a, e.length); return r(t(e, n, []), i) }, getOwnerKey: function (e, a, r, i) { var n = new Uint8Array(e.length + 56); n.set(e, 0); n.set(a, e.length); n.set(r, e.length + a.length); var s = t(e, n, r); return new b(s).decryptBlock(i, !1, new Uint8Array(16)) }, getUserKey: function (e, a, r) { var i = new Uint8Array(e.length + 8); i.set(e, 0); i.set(a, e.length); var n = t(e, i, []); return new b(n).decryptBlock(r, !1, new Uint8Array(16)) } }; return a }(); t.PDF20 = v; var w = function () { function e(e, t) { this.StringCipherConstructor = e; this.StreamCipherConstructor = t } e.prototype = { createStream: function (e, t) { var a = new this.StreamCipherConstructor; return new n.DecryptStream(e, t, (function (e, t) { return a.decryptBlock(e, t) })) }, decryptString: function (e) { var t = new this.StringCipherConstructor, a = (0, r.stringToBytes)(e); a = t.decryptBlock(a, !0); return (0, r.bytesToString)(a) } }; return e }(), k = function () { var e = new Uint8Array([40, 191, 78, 94, 78, 117, 138, 65, 100, 0, 78, 86, 255, 250, 1, 8, 46, 46, 0, 182, 208, 104, 62, 128, 47, 12, 169, 254, 100, 83, 105, 122]); function t(t, a, r, i, n, o, c, h) { var u, d, f = 40 + r.length + t.length, g = new Uint8Array(f), m = 0; if (a) { d = Math.min(32, a.length); for (; m < d; ++m)g[m] = a[m] } u = 0; for (; m < 32;)g[m++] = e[u++]; for (u = 0, d = r.length; u < d; ++u)g[m++] = r[u]; g[m++] = 255 & n; g[m++] = n >> 8 & 255; g[m++] = n >> 16 & 255; g[m++] = n >>> 24 & 255; for (u = 0, d = t.length; u < d; ++u)g[m++] = t[u]; if (o >= 4 && !h) { g[m++] = 255; g[m++] = 255; g[m++] = 255; g[m++] = 255 } var p = l(g, 0, m), b = c >> 3; if (o >= 3) for (u = 0; u < 50; ++u)p = l(p, 0, b); var y, v = p.subarray(0, b); if (o >= 3) { for (m = 0; m < 32; ++m)g[m] = e[m]; for (u = 0, d = t.length; u < d; ++u)g[m++] = t[u]; y = new s(v).encryptBlock(l(g, 0, m)); d = v.length; var w, k = new Uint8Array(d); for (u = 1; u <= 19; ++u) { for (w = 0; w < d; ++w)k[w] = v[w] ^ u; y = new s(k).encryptBlock(y) } for (u = 0, d = y.length; u < d; ++u)if (i[u] !== y[u]) return null } else for (u = 0, d = (y = new s(v).encryptBlock(e)).length; u < d; ++u)if (i[u] !== y[u]) return null; return v } var a = i.Name.get("Identity"); function n(n, o, c) { var h = n.get("Filter"); if (!(0, i.isName)(h, "Standard")) throw new r.FormatError("unknown encryption method"); this.dict = n; var u = n.get("V"); if (!Number.isInteger(u) || 1 !== u && 2 !== u && 4 !== u && 5 !== u) throw new r.FormatError("unsupported encryption algorithm"); this.algorithm = u; var d = n.get("Length"); if (!d) if (u <= 3) d = 40; else { var f = n.get("CF"), g = n.get("StmF"); if ((0, i.isDict)(f) && (0, i.isName)(g)) { f.suppressEncryption = !0; var m = f.get(g.name); (d = m && m.get("Length") || 128) < 40 && (d <<= 3) } } if (!Number.isInteger(d) || d < 40 || d % 8 != 0) throw new r.FormatError("invalid key length"); var p = (0, r.stringToBytes)(n.get("O")).subarray(0, 32), b = (0, r.stringToBytes)(n.get("U")).subarray(0, 32), w = n.get("P"), k = n.get("R"), S = (4 === u || 5 === u) && !1 !== n.get("EncryptMetadata"); this.encryptMetadata = S; var C, x, A = (0, r.stringToBytes)(o); if (c) { if (6 === k) try { c = (0, r.utf8StringToString)(c) } catch (e) { (0, r.warn)("CipherTransformFactory: Unable to convert UTF8 encoded password.") } C = (0, r.stringToBytes)(c) } if (5 !== u) x = t(A, C, p, b, w, k, d, S); else { var I = (0, r.stringToBytes)(n.get("O")).subarray(32, 40), F = (0, r.stringToBytes)(n.get("O")).subarray(40, 48), T = (0, r.stringToBytes)(n.get("U")).subarray(0, 48), E = (0, r.stringToBytes)(n.get("U")).subarray(32, 40), O = (0, r.stringToBytes)(n.get("U")).subarray(40, 48), P = (0, r.stringToBytes)(n.get("OE")), B = (0, r.stringToBytes)(n.get("UE")); (0, r.stringToBytes)(n.get("Perms")); x = function (e, t, a, r, i, n, s, o, c, l, h, u) { if (t) { var d = Math.min(127, t.length); t = t.subarray(0, d) } else t = []; var f; return (f = 6 === e ? new v : new y).checkUserPassword(t, o, s) ? f.getUserKey(t, c, h) : t.length && f.checkOwnerPassword(t, r, n, a) ? f.getOwnerKey(t, i, n, l) : null }(k, C, p, I, F, T, b, E, O, P, B) } if (!x && !c) throw new r.PasswordException("No password given", r.PasswordResponses.NEED_PASSWORD); if (!x && c) { x = t(A, function (t, a, r, i) { var n, o, c = new Uint8Array(32), h = 0; o = Math.min(32, t.length); for (; h < o; ++h)c[h] = t[h]; n = 0; for (; h < 32;)c[h++] = e[n++]; var u, d = l(c, 0, h), f = i >> 3; if (r >= 3) for (n = 0; n < 50; ++n)d = l(d, 0, d.length); if (r >= 3) { u = a; var g, m = new Uint8Array(f); for (n = 19; n >= 0; n--) { for (g = 0; g < f; ++g)m[g] = d[g] ^ n; u = new s(m).encryptBlock(u) } } else u = new s(d.subarray(0, f)).encryptBlock(a); return u }(C, p, k, d), p, b, w, k, d, S) } if (!x) throw new r.PasswordException("Incorrect Password", r.PasswordResponses.INCORRECT_PASSWORD); this.encryptionKey = x; if (u >= 4) { var D = n.get("CF"); (0, i.isDict)(D) && (D.suppressEncryption = !0); this.cf = D; this.stmf = n.get("StmF") || a; this.strf = n.get("StrF") || a; this.eff = n.get("EFF") || this.stmf } } function o(e, t, a, r) { var i, n, s = new Uint8Array(a.length + 9); for (i = 0, n = a.length; i < n; ++i)s[i] = a[i]; s[i++] = 255 & e; s[i++] = e >> 8 & 255; s[i++] = e >> 16 & 255; s[i++] = 255 & t; s[i++] = t >> 8 & 255; if (r) { s[i++] = 115; s[i++] = 65; s[i++] = 108; s[i++] = 84 } return l(s, 0, i).subarray(0, Math.min(a.length + 5, 16)) } function c(e, t, a, n, c) { if (!(0, i.isName)(t)) throw new r.FormatError("Invalid crypt filter name."); var l, h = e.get(t.name); null != h && (l = h.get("CFM")); if (!l || "None" === l.name) return function () { return new g }; if ("V2" === l.name) return function () { return new s(o(a, n, c, !1)) }; if ("AESV2" === l.name) return function () { return new p(o(a, n, c, !0)) }; if ("AESV3" === l.name) return function () { return new b(c) }; throw new r.FormatError("Unknown crypto method") } n.prototype = { createCipherTransform: function (e, t) { if (4 === this.algorithm || 5 === this.algorithm) return new w(c(this.cf, this.stmf, e, t, this.encryptionKey), c(this.cf, this.strf, e, t, this.encryptionKey)); var a = o(e, t, this.encryptionKey, !1), r = function () { return new s(a) }; return new w(r, r) } }; return n }(); t.CipherTransformFactory = k }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.ColorSpace = void 0; var r = a(2), i = a(4); class n { constructor(e, t) { this.constructor === n && (0, r.unreachable)("Cannot initialize ColorSpace."); this.name = e; this.numComps = t } getRgb(e, t) { const a = new Uint8ClampedArray(3); this.getRgbItem(e, t, a, 0); return a } getRgbItem(e, t, a, i) { (0, r.unreachable)("Should not call ColorSpace.getRgbItem") } getRgbBuffer(e, t, a, i, n, s, o) { (0, r.unreachable)("Should not call ColorSpace.getRgbBuffer") } getOutputLength(e, t) { (0, r.unreachable)("Should not call ColorSpace.getOutputLength") } isPassthrough(e) { return !1 } isDefaultDecode(e, t) { return n.isDefaultDecode(e, this.numComps) } fillRgb(e, t, a, r, i, n, s, o, c) { const l = t * a; let h = null; const u = 1 << s, d = a !== i || t !== r; if (this.isPassthrough(s)) h = o; else if (1 === this.numComps && l > u && "DeviceGray" !== this.name && "DeviceRGB" !== this.name) { const t = s <= 8 ? new Uint8Array(u) : new Uint16Array(u); for (let e = 0; e < u; e++)t[e] = e; const a = new Uint8ClampedArray(3 * u); this.getRgbBuffer(t, 0, u, a, 0, s, 0); if (d) { h = new Uint8Array(3 * l); let e = 0; for (let t = 0; t < l; ++t) { const r = 3 * o[t]; h[e++] = a[r]; h[e++] = a[r + 1]; h[e++] = a[r + 2] } } else { let t = 0; for (let r = 0; r < l; ++r) { const i = 3 * o[r]; e[t++] = a[i]; e[t++] = a[i + 1]; e[t++] = a[i + 2]; t += c } } } else if (d) { h = new Uint8ClampedArray(3 * l); this.getRgbBuffer(o, 0, l, h, 0, s, 0) } else this.getRgbBuffer(o, 0, r * n, e, 0, s, c); if (h) if (d) !function (e, t, a, r, i, n, s) { s = 1 !== s ? 0 : s; const o = a / i, c = r / n; let l, h = 0; const u = new Uint16Array(i), d = 3 * a; for (let e = 0; e < i; e++)u[e] = 3 * Math.floor(e * o); for (let a = 0; a < n; a++) { const r = Math.floor(a * c) * d; for (let a = 0; a < i; a++) { l = r + u[a]; t[h++] = e[l++]; t[h++] = e[l++]; t[h++] = e[l++]; h += s } } }(h, e, t, a, r, i, c); else { let t = 0, a = 0; for (let i = 0, s = r * n; i < s; i++) { e[t++] = h[a++]; e[t++] = h[a++]; e[t++] = h[a++]; t += c } } } get usesZeroToOneRange() { return (0, r.shadow)(this, "usesZeroToOneRange", !0) } static parse(e, t, a, r) { const i = this.parseToIR(e, t, a, r); return this.fromIR(i) } static fromIR(e) { const t = Array.isArray(e) ? e[0] : e; let a, i, n; switch (t) { case "DeviceGrayCS": return this.singletons.gray; case "DeviceRgbCS": return this.singletons.rgb; case "DeviceCmykCS": return this.singletons.cmyk; case "CalGrayCS": a = e[1]; i = e[2]; n = e[3]; return new d(a, i, n); case "CalRGBCS": a = e[1]; i = e[2]; n = e[3]; const l = e[4]; return new f(a, i, n, l); case "PatternCS": let h = e[1]; h && (h = this.fromIR(h)); return new o(h); case "IndexedCS": const u = e[1], m = e[2], p = e[3]; return new c(this.fromIR(u), m, p); case "AlternateCS": const b = e[1], y = e[2], v = e[3]; return new s(b, this.fromIR(y), v); case "LabCS": a = e[1]; i = e[2]; const w = e[3]; return new g(a, i, w); default: throw new r.FormatError(`Unknown colorspace name: ${t}`) } } static parseToIR(e, t, a = null, n) { e = t.fetchIfRef(e); if ((0, i.isName)(e)) switch (e.name) { case "DeviceGray": case "G": return "DeviceGrayCS"; case "DeviceRGB": case "RGB": return "DeviceRgbCS"; case "DeviceCMYK": case "CMYK": return "DeviceCmykCS"; case "Pattern": return ["PatternCS", null]; default: if ((0, i.isDict)(a)) { const r = a.get("ColorSpace"); if ((0, i.isDict)(r)) { const s = r.get(e.name); if (s) { if ((0, i.isName)(s)) return this.parseToIR(s, t, a, n); e = s; break } } } throw new r.FormatError(`unrecognized colorspace ${e.name}`) }if (Array.isArray(e)) { const s = t.fetchIfRef(e[0]).name; let o, c, l, h, u, d; switch (s) { case "DeviceGray": case "G": return "DeviceGrayCS"; case "DeviceRGB": case "RGB": return "DeviceRgbCS"; case "DeviceCMYK": case "CMYK": return "DeviceCmykCS"; case "CalGray": c = t.fetchIfRef(e[1]); h = c.getArray("WhitePoint"); u = c.getArray("BlackPoint"); d = c.get("Gamma"); return ["CalGrayCS", h, u, d]; case "CalRGB": c = t.fetchIfRef(e[1]); h = c.getArray("WhitePoint"); u = c.getArray("BlackPoint"); d = c.getArray("Gamma"); return ["CalRGBCS", h, u, d, c.getArray("Matrix")]; case "ICCBased": const f = t.fetchIfRef(e[1]).dict; o = f.get("N"); l = f.get("Alternate"); if (l) { const e = this.parseToIR(l, t, a, n); if (this.fromIR(e, n).numComps === o) return e; (0, r.warn)("ICCBased color space: Ignoring incorrect /Alternate entry.") } if (1 === o) return "DeviceGrayCS"; if (3 === o) return "DeviceRgbCS"; if (4 === o) return "DeviceCmykCS"; break; case "Pattern": let g = e[1] || null; g && (g = this.parseToIR(g, t, a, n)); return ["PatternCS", g]; case "Indexed": case "I": const m = this.parseToIR(e[1], t, a, n), p = t.fetchIfRef(e[2]) + 1; let b = t.fetchIfRef(e[3]); (0, i.isStream)(b) && (b = b.getBytes()); return ["IndexedCS", m, p, b]; case "Separation": case "DeviceN": const y = t.fetchIfRef(e[1]); o = Array.isArray(y) ? y.length : 1; l = this.parseToIR(e[2], t, a, n); return ["AlternateCS", o, l, n.create(t.fetchIfRef(e[3]))]; case "Lab": c = t.fetchIfRef(e[1]); h = c.getArray("WhitePoint"); u = c.getArray("BlackPoint"); return ["LabCS", h, u, c.getArray("Range")]; default: throw new r.FormatError(`unimplemented color space object "${s}"`) } } throw new r.FormatError(`unrecognized color space object: "${e}"`) } static isDefaultDecode(e, t) { if (!Array.isArray(e)) return !0; if (2 * t !== e.length) { (0, r.warn)("The decode map is not the correct length"); return !0 } for (let t = 0, a = e.length; t < a; t += 2)if (0 !== e[t] || 1 !== e[t + 1]) return !1; return !0 } static get singletons() { return (0, r.shadow)(this, "singletons", { get gray() { return (0, r.shadow)(this, "gray", new l) }, get rgb() { return (0, r.shadow)(this, "rgb", new h) }, get cmyk() { return (0, r.shadow)(this, "cmyk", new u) } }) } } t.ColorSpace = n; class s extends n { constructor(e, t, a) { super("Alternate", e); this.base = t; this.tintFn = a; this.tmpBuf = new Float32Array(t.numComps) } getRgbItem(e, t, a, r) { const i = this.tmpBuf; this.tintFn(e, t, i, 0); this.base.getRgbItem(i, 0, a, r) } getRgbBuffer(e, t, a, r, i, n, s) { const o = this.tintFn, c = this.base, l = 1 / ((1 << n) - 1), h = c.numComps, u = c.usesZeroToOneRange, d = (c.isPassthrough(8) || !u) && 0 === s; let f = d ? i : 0; const g = d ? r : new Uint8ClampedArray(h * a), m = this.numComps, p = new Float32Array(m), b = new Float32Array(h); let y, v; for (y = 0; y < a; y++) { for (v = 0; v < m; v++)p[v] = e[t++] * l; o(p, 0, b, 0); if (u) for (v = 0; v < h; v++)g[f++] = 255 * b[v]; else { c.getRgbItem(b, 0, g, f); f += h } } d || c.getRgbBuffer(g, 0, a, r, i, 8, s) } getOutputLength(e, t) { return this.base.getOutputLength(e * this.base.numComps / this.numComps, t) } } class o extends n { constructor(e) { super("Pattern", null); this.base = e } isDefaultDecode(e, t) { (0, r.unreachable)("Should not call PatternCS.isDefaultDecode") } } class c extends n { constructor(e, t, a) { super("Indexed", 1); this.base = e; this.highVal = t; const n = e.numComps * t; if ((0, i.isStream)(a)) { this.lookup = new Uint8Array(n); const e = a.getBytes(n); this.lookup.set(e) } else if ((0, r.isString)(a)) { this.lookup = new Uint8Array(n); for (let e = 0; e < n; ++e)this.lookup[e] = a.charCodeAt(e) } else { if (!(a instanceof Uint8Array)) throw new r.FormatError(`Unrecognized lookup table: ${a}`); this.lookup = a } } getRgbItem(e, t, a, r) { const i = this.base.numComps, n = e[t] * i; this.base.getRgbBuffer(this.lookup, n, 1, a, r, 8, 0) } getRgbBuffer(e, t, a, r, i, n, s) { const o = this.base, c = o.numComps, l = o.getOutputLength(c, s), h = this.lookup; for (let n = 0; n < a; ++n) { const a = e[t++] * c; o.getRgbBuffer(h, a, 1, r, i, 8, s); i += l } } getOutputLength(e, t) { return this.base.getOutputLength(e * this.base.numComps, t) } isDefaultDecode(e, t) { if (!Array.isArray(e)) return !0; if (2 !== e.length) { (0, r.warn)("Decode map length is not correct"); return !0 } if (!Number.isInteger(t) || t < 1) { (0, r.warn)("Bits per component is not correct"); return !0 } return 0 === e[0] && e[1] === (1 << t) - 1 } } class l extends n { constructor() { super("DeviceGray", 1) } getRgbItem(e, t, a, r) { const i = 255 * e[t]; a[r] = a[r + 1] = a[r + 2] = i } getRgbBuffer(e, t, a, r, i, n, s) { const o = 255 / ((1 << n) - 1); let c = t, l = i; for (let t = 0; t < a; ++t) { const t = o * e[c++]; r[l++] = t; r[l++] = t; r[l++] = t; l += s } } getOutputLength(e, t) { return e * (3 + t) } } class h extends n { constructor() { super("DeviceRGB", 3) } getRgbItem(e, t, a, r) { a[r] = 255 * e[t]; a[r + 1] = 255 * e[t + 1]; a[r + 2] = 255 * e[t + 2] } getRgbBuffer(e, t, a, r, i, n, s) { if (8 === n && 0 === s) { r.set(e.subarray(t, t + 3 * a), i); return } const o = 255 / ((1 << n) - 1); let c = t, l = i; for (let t = 0; t < a; ++t) { r[l++] = o * e[c++]; r[l++] = o * e[c++]; r[l++] = o * e[c++]; l += s } } getOutputLength(e, t) { return e * (3 + t) / 3 | 0 } isPassthrough(e) { return 8 === e } } const u = function () { function e(e, t, a, r, i) { const n = e[t] * a, s = e[t + 1] * a, o = e[t + 2] * a, c = e[t + 3] * a; r[i] = 255 + n * (-4.387332384609988 * n + 54.48615194189176 * s + 18.82290502165302 * o + 212.25662451639585 * c - 285.2331026137004) + s * (1.7149763477362134 * s - 5.6096736904047315 * o + -17.873870861415444 * c - 5.497006427196366) + o * (-2.5217340131683033 * o - 21.248923337353073 * c + 17.5119270841813) + c * (-21.86122147463605 * c - 189.48180835922747); r[i + 1] = 255 + n * (8.841041422036149 * n + 60.118027045597366 * s + 6.871425592049007 * o + 31.159100130055922 * c - 79.2970844816548) + s * (-15.310361306967817 * s + 17.575251261109482 * o + 131.35250912493976 * c - 190.9453302588951) + o * (4.444339102852739 * o + 9.8632861493405 * c - 24.86741582555878) + c * (-20.737325471181034 * c - 187.80453709719578); r[i + 2] = 255 + n * (.8842522430003296 * n + 8.078677503112928 * s + 30.89978309703729 * o - .23883238689178934 * c - 14.183576799673286) + s * (10.49593273432072 * s + 63.02378494754052 * o + 50.606957656360734 * c - 112.23884253719248) + o * (.03296041114873217 * o + 115.60384449646641 * c - 193.58209356861505) + c * (-22.33816807309886 * c - 180.12613974708367) } return class extends n { constructor() { super("DeviceCMYK", 4) } getRgbItem(t, a, r, i) { e(t, a, 1, r, i) } getRgbBuffer(t, a, r, i, n, s, o) { const c = 1 / ((1 << s) - 1); for (let s = 0; s < r; s++) { e(t, a, c, i, n); a += 4; n += 3 + o } } getOutputLength(e, t) { return e / 4 * (3 + t) | 0 } } }(), d = function () { function e(e, t, a, r, i, n) { const s = (t[a] * n) ** e.G, o = e.YW * s, c = Math.max(295.8 * o ** .3333333333333333 - 40.8, 0); r[i] = c; r[i + 1] = c; r[i + 2] = c } return class extends n { constructor(e, t, a) { super("CalGray", 1); if (!e) throw new r.FormatError("WhitePoint missing - required for color space CalGray"); t = t || [0, 0, 0]; a = a || 1; this.XW = e[0]; this.YW = e[1]; this.ZW = e[2]; this.XB = t[0]; this.YB = t[1]; this.ZB = t[2]; this.G = a; if (this.XW < 0 || this.ZW < 0 || 1 !== this.YW) throw new r.FormatError(`Invalid WhitePoint components for ${this.name}` + ", no fallback available"); if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { (0, r.info)(`Invalid BlackPoint for ${this.name}, falling back to default.`); this.XB = this.YB = this.ZB = 0 } 0 === this.XB && 0 === this.YB && 0 === this.ZB || (0, r.warn)(`${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, ` + `ZB: ${this.ZB}, only default values are supported.`); if (this.G < 1) { (0, r.info)(`Invalid Gamma: ${this.G} for ${this.name}, ` + "falling back to default."); this.G = 1 } } getRgbItem(t, a, r, i) { e(this, t, a, r, i, 1) } getRgbBuffer(t, a, r, i, n, s, o) { const c = 1 / ((1 << s) - 1); for (let s = 0; s < r; ++s) { e(this, t, a, i, n, c); a += 1; n += 3 + o } } getOutputLength(e, t) { return e * (3 + t) } } }(), f = function () { const e = new Float32Array([.8951, .2664, -.1614, -.7502, 1.7135, .0367, .0389, -.0685, 1.0296]), t = new Float32Array([.9869929, -.1470543, .1599627, .4323053, .5183603, .0492912, -.0085287, .0400428, .9684867]), a = new Float32Array([3.2404542, -1.5371385, -.4985314, -.969266, 1.8760108, .041556, .0556434, -.2040259, 1.0572252]), i = new Float32Array([1, 1, 1]), s = new Float32Array(3), o = new Float32Array(3), c = new Float32Array(3); function l(e, t, a) { a[0] = e[0] * t[0] + e[1] * t[1] + e[2] * t[2]; a[1] = e[3] * t[0] + e[4] * t[1] + e[5] * t[2]; a[2] = e[6] * t[0] + e[7] * t[1] + e[8] * t[2] } function h(e) { return u(0, 1, e <= .0031308 ? 12.92 * e : 1.055 * e ** (1 / 2.4) - .055) } function u(e, t, a) { return Math.max(e, Math.min(t, a)) } function d(e) { return e < 0 ? -d(-e) : e > 8 ? ((e + 16) / 116) ** 3 : e * ((24 / 116) ** 3 / 8) } function f(r, n, f, g, m, p) { const b = u(0, 1, n[f] * p), y = u(0, 1, n[f + 1] * p), v = u(0, 1, n[f + 2] * p), w = b ** r.GR, k = y ** r.GG, S = v ** r.GB, C = r.MXA * w + r.MXB * k + r.MXC * S, x = r.MYA * w + r.MYB * k + r.MYC * S, A = r.MZA * w + r.MZB * k + r.MZC * S, I = o; I[0] = C; I[1] = x; I[2] = A; const F = c; !function (a, r, i) { if (1 === a[0] && 1 === a[2]) { i[0] = r[0]; i[1] = r[1]; i[2] = r[2]; return } const n = i; l(e, r, n); const o = s; !function (e, t, a) { a[0] = 1 * t[0] / e[0]; a[1] = 1 * t[1] / e[1]; a[2] = 1 * t[2] / e[2] }(a, n, o); l(t, o, i) }(r.whitePoint, I, F); const T = o; !function (e, t, a) { if (0 === e[0] && 0 === e[1] && 0 === e[2]) { a[0] = t[0]; a[1] = t[1]; a[2] = t[2]; return } const r = d(0), i = (1 - r) / (1 - d(e[0])), n = 1 - i, s = (1 - r) / (1 - d(e[1])), o = 1 - s, c = (1 - r) / (1 - d(e[2])), l = 1 - c; a[0] = t[0] * i + n; a[1] = t[1] * s + o; a[2] = t[2] * c + l }(r.blackPoint, F, T); const E = c; !function (a, r, i) { const n = i; l(e, r, n); const o = s; !function (e, t, a) { a[0] = .95047 * t[0] / e[0]; a[1] = 1 * t[1] / e[1]; a[2] = 1.08883 * t[2] / e[2] }(a, n, o); l(t, o, i) }(i, T, E); const O = o; l(a, E, O); g[m] = 255 * h(O[0]); g[m + 1] = 255 * h(O[1]); g[m + 2] = 255 * h(O[2]) } return class extends n { constructor(e, t, a, i) { super("CalRGB", 3); if (!e) throw new r.FormatError("WhitePoint missing - required for color space CalRGB"); t = t || new Float32Array(3); a = a || new Float32Array([1, 1, 1]); i = i || new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]); const n = e[0], s = e[1], o = e[2]; this.whitePoint = e; const c = t[0], l = t[1], h = t[2]; this.blackPoint = t; this.GR = a[0]; this.GG = a[1]; this.GB = a[2]; this.MXA = i[0]; this.MYA = i[1]; this.MZA = i[2]; this.MXB = i[3]; this.MYB = i[4]; this.MZB = i[5]; this.MXC = i[6]; this.MYC = i[7]; this.MZC = i[8]; if (n < 0 || o < 0 || 1 !== s) throw new r.FormatError(`Invalid WhitePoint components for ${this.name}` + ", no fallback available"); if (c < 0 || l < 0 || h < 0) { (0, r.info)(`Invalid BlackPoint for ${this.name} [${c}, ${l}, ${h}], ` + "falling back to default."); this.blackPoint = new Float32Array(3) } if (this.GR < 0 || this.GG < 0 || this.GB < 0) { (0, r.info)(`Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for ` + `${this.name}, falling back to default.`); this.GR = this.GG = this.GB = 1 } } getRgbItem(e, t, a, r) { f(this, e, t, a, r, 1) } getRgbBuffer(e, t, a, r, i, n, s) { const o = 1 / ((1 << n) - 1); for (let n = 0; n < a; ++n) { f(this, e, t, r, i, o); t += 3; i += 3 + s } } getOutputLength(e, t) { return e * (3 + t) / 3 | 0 } } }(), g = function () { function e(e) { let t; t = e >= 6 / 29 ? e * e * e : 108 / 841 * (e - 4 / 29); return t } function t(e, t, a, r) { return a + e * (r - a) / t } function a(a, r, i, n, s, o) { let c = r[i], l = r[i + 1], h = r[i + 2]; if (!1 !== n) { c = t(c, n, 0, 100); l = t(l, n, a.amin, a.amax); h = t(h, n, a.bmin, a.bmax) } l > a.amax ? l = a.amax : l < a.amin && (l = a.amin); h > a.bmax ? h = a.bmax : h < a.bmin && (h = a.bmin); const u = (c + 16) / 116, d = u + l / 500, f = u - h / 200, g = a.XW * e(d), m = a.YW * e(u), p = a.ZW * e(f); let b, y, v; if (a.ZW < 1) { b = 3.1339 * g + -1.617 * m + -.4906 * p; y = -.9785 * g + 1.916 * m + .0333 * p; v = .072 * g + -.229 * m + 1.4057 * p } else { b = 3.2406 * g + -1.5372 * m + -.4986 * p; y = -.9689 * g + 1.8758 * m + .0415 * p; v = .0557 * g + -.204 * m + 1.057 * p } s[o] = 255 * Math.sqrt(b); s[o + 1] = 255 * Math.sqrt(y); s[o + 2] = 255 * Math.sqrt(v) } return class extends n { constructor(e, t, a) { super("Lab", 3); if (!e) throw new r.FormatError("WhitePoint missing - required for color space Lab"); t = t || [0, 0, 0]; a = a || [-100, 100, -100, 100]; this.XW = e[0]; this.YW = e[1]; this.ZW = e[2]; this.amin = a[0]; this.amax = a[1]; this.bmin = a[2]; this.bmax = a[3]; this.XB = t[0]; this.YB = t[1]; this.ZB = t[2]; if (this.XW < 0 || this.ZW < 0 || 1 !== this.YW) throw new r.FormatError("Invalid WhitePoint components, no fallback available"); if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { (0, r.info)("Invalid BlackPoint, falling back to default"); this.XB = this.YB = this.ZB = 0 } if (this.amin > this.amax || this.bmin > this.bmax) { (0, r.info)("Invalid Range, falling back to defaults"); this.amin = -100; this.amax = 100; this.bmin = -100; this.bmax = 100 } } getRgbItem(e, t, r, i) { a(this, e, t, !1, r, i) } getRgbBuffer(e, t, r, i, n, s, o) { const c = (1 << s) - 1; for (let s = 0; s < r; s++) { a(this, e, t, c, i, n); t += 3; n += 3 + o } } getOutputLength(e, t) { return e * (3 + t) / 3 | 0 } isDefaultDecode(e, t) { return !0 } get usesZeroToOneRange() { return (0, r.shadow)(this, "usesZeroToOneRange", !1) } } }() }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getQuadPoints = h; t.MarkupAnnotation = t.AnnotationFactory = t.AnnotationBorderStyle = t.Annotation = void 0; var r = a(2), i = a(9), n = a(4), s = a(22), o = a(7), c = a(24), l = a(11); t.AnnotationFactory = class { static create(e, t, a, r) { return a.ensure(this, "_create", [e, t, a, r]) } static _create(e, t, a, i) { const s = e.fetchIfRef(t); if (!(0, n.isDict)(s)) return; const c = (0, n.isRef)(t) ? t.toString() : `annot_${i.createObjId()}`; let l = s.get("Subtype"); l = (0, n.isName)(l) ? l.name : null; const h = { xref: e, dict: s, subtype: l, id: c, pdfManager: a }; switch (l) { case "Link": return new v(h); case "Text": return new y(h); case "Widget": let e = (0, o.getInheritableProperty)({ dict: s, key: "FT" }); e = (0, n.isName)(e) ? e.name : null; switch (e) { case "Tx": return new m(h); case "Btn": return new p(h); case "Ch": return new b(h) }(0, r.warn)('Unimplemented widget field type "' + e + '", falling back to base field type.'); return new g(h); case "Popup": return new w(h); case "FreeText": return new k(h); case "Line": return new S(h); case "Square": return new C(h); case "Circle": return new x(h); case "PolyLine": return new A(h); case "Polygon": return new I(h); case "Caret": return new F(h); case "Ink": return new T(h); case "Highlight": return new E(h); case "Underline": return new O(h); case "Squiggly": return new P(h); case "StrikeOut": return new B(h); case "Stamp": return new D(h); case "FileAttachment": return new N(h); default: l ? (0, r.warn)('Unimplemented annotation type "' + l + '", falling back to base annotation.') : (0, r.warn)("Annotation is missing the required /Subtype."); return new u(h) } } }; function h(e, t) { if (!e.has("QuadPoints")) return null; const a = e.getArray("QuadPoints"); if (!Array.isArray(a) || a.length % 8 > 0) return null; const r = []; for (let e = 0, i = a.length / 8; e < i; e++) { r.push([]); for (let i = 8 * e, n = 8 * e + 8; i < n; i += 2) { const n = a[i], s = a[i + 1]; if (n < t[0] || n > t[2] || s < t[1] || s > t[3]) return null; r[e].push({ x: n, y: s }) } } return r } class u { constructor(e) { const t = e.dict; this.setContents(t.get("Contents")); this.setModificationDate(t.get("M")); this.setFlags(t.get("F")); this.setRectangle(t.getArray("Rect")); this.setColor(t.getArray("C")); this.setBorderStyle(t); this.setAppearance(t); this.data = { annotationFlags: this.flags, borderStyle: this.borderStyle, color: this.color, contents: this.contents, hasAppearance: !!this.appearance, id: e.id, modificationDate: this.modificationDate, rect: this.rectangle, subtype: e.subtype } } _hasFlag(e, t) { return !!(e & t) } _isViewable(e) { return !this._hasFlag(e, r.AnnotationFlag.INVISIBLE) && !this._hasFlag(e, r.AnnotationFlag.HIDDEN) && !this._hasFlag(e, r.AnnotationFlag.NOVIEW) } _isPrintable(e) { return this._hasFlag(e, r.AnnotationFlag.PRINT) && !this._hasFlag(e, r.AnnotationFlag.INVISIBLE) && !this._hasFlag(e, r.AnnotationFlag.HIDDEN) } get viewable() { return 0 === this.flags || this._isViewable(this.flags) } get printable() { return 0 !== this.flags && this._isPrintable(this.flags) } setContents(e) { this.contents = (0, r.stringToPDFString)(e || "") } setModificationDate(e) { this.modificationDate = (0, r.isString)(e) ? e : null } setFlags(e) { this.flags = Number.isInteger(e) && e > 0 ? e : 0 } hasFlag(e) { return this._hasFlag(this.flags, e) } setRectangle(e) { Array.isArray(e) && 4 === e.length ? this.rectangle = r.Util.normalizeRect(e) : this.rectangle = [0, 0, 0, 0] } setColor(e) { const t = new Uint8ClampedArray(3); if (Array.isArray(e)) switch (e.length) { case 0: this.color = null; break; case 1: s.ColorSpace.singletons.gray.getRgbItem(e, 0, t, 0); this.color = t; break; case 3: s.ColorSpace.singletons.rgb.getRgbItem(e, 0, t, 0); this.color = t; break; case 4: s.ColorSpace.singletons.cmyk.getRgbItem(e, 0, t, 0); this.color = t; break; default: this.color = t } else this.color = t } setBorderStyle(e) { this.borderStyle = new d; if ((0, n.isDict)(e)) if (e.has("BS")) { const t = e.get("BS"), a = t.get("Type"); if (!a || (0, n.isName)(a, "Border")) { this.borderStyle.setWidth(t.get("W"), this.rectangle); this.borderStyle.setStyle(t.get("S")); this.borderStyle.setDashArray(t.getArray("D")) } } else if (e.has("Border")) { const t = e.getArray("Border"); if (Array.isArray(t) && t.length >= 3) { this.borderStyle.setHorizontalCornerRadius(t[0]); this.borderStyle.setVerticalCornerRadius(t[1]); this.borderStyle.setWidth(t[2], this.rectangle); 4 === t.length && this.borderStyle.setDashArray(t[3]) } } else this.borderStyle.setWidth(0) } setAppearance(e) { this.appearance = null; const t = e.get("AP"); if (!(0, n.isDict)(t)) return; const a = t.get("N"); if ((0, n.isStream)(a)) { this.appearance = a; return } if (!(0, n.isDict)(a)) return; const r = e.get("AS"); (0, n.isName)(r) && a.has(r.name) && (this.appearance = a.get(r.name)) } loadResources(e) { return this.appearance.dict.getAsync("Resources").then(t => { if (!t) return; return new i.ObjectLoader(t, e, t.xref).load().then((function () { return t })) }) } getOperatorList(e, t, a) { if (!this.appearance) return Promise.resolve(new c.OperatorList); const i = this.data, n = this.appearance.dict, s = this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"]), o = n.getArray("BBox") || [0, 0, 1, 1], l = n.getArray("Matrix") || [1, 0, 0, 1, 0, 0], h = function (e, t, a) { const [i, n, s, o] = r.Util.getAxialAlignedBoundingBox(t, a); if (i === s || n === o) return [1, 0, 0, 1, e[0], e[1]]; const c = (e[2] - e[0]) / (s - i), l = (e[3] - e[1]) / (o - n); return [c, 0, 0, l, e[0] - i * c, e[1] - n * l] }(i.rect, o, l); return s.then(a => { const n = new c.OperatorList; n.addOp(r.OPS.beginAnnotation, [i.rect, h, l]); return e.getOperatorList({ stream: this.appearance, task: t, resources: a, operatorList: n }).then(() => { n.addOp(r.OPS.endAnnotation, []); this.appearance.reset(); return n }) }) } } t.Annotation = u; class d { constructor() { this.width = 1; this.style = r.AnnotationBorderStyleType.SOLID; this.dashArray = [3]; this.horizontalCornerRadius = 0; this.verticalCornerRadius = 0 } setWidth(e, t = [0, 0, 0, 0]) { if ((0, n.isName)(e)) this.width = 0; else if (Number.isInteger(e)) { if (e > 0) { const a = (t[2] - t[0]) / 2, i = (t[3] - t[1]) / 2; if (a > 0 && i > 0 && (e > a || e > i)) { (0, r.warn)(`AnnotationBorderStyle.setWidth - ignoring width: ${e}`); e = 1 } } this.width = e } } setStyle(e) { if ((0, n.isName)(e)) switch (e.name) { case "S": this.style = r.AnnotationBorderStyleType.SOLID; break; case "D": this.style = r.AnnotationBorderStyleType.DASHED; break; case "B": this.style = r.AnnotationBorderStyleType.BEVELED; break; case "I": this.style = r.AnnotationBorderStyleType.INSET; break; case "U": this.style = r.AnnotationBorderStyleType.UNDERLINE } } setDashArray(e) { if (Array.isArray(e) && e.length > 0) { let t = !0, a = !0; for (const r of e) { if (!(+r >= 0)) { t = !1; break } r > 0 && (a = !1) } t && !a ? this.dashArray = e : this.width = 0 } else e && (this.width = 0) } setHorizontalCornerRadius(e) { Number.isInteger(e) && (this.horizontalCornerRadius = e) } setVerticalCornerRadius(e) { Number.isInteger(e) && (this.verticalCornerRadius = e) } } t.AnnotationBorderStyle = d; class f extends u { constructor(e) { super(e); const t = e.dict; if (t.has("IRT")) { const e = t.getRaw("IRT"); this.data.inReplyTo = (0, n.isRef)(e) ? e.toString() : null; const a = t.get("RT"); this.data.replyType = (0, n.isName)(a) ? a.name : r.AnnotationReplyType.REPLY } if (this.data.replyType === r.AnnotationReplyType.GROUP) { const e = t.get("IRT"); this.data.title = (0, r.stringToPDFString)(e.get("T") || ""); this.setContents(e.get("Contents")); this.data.contents = this.contents; if (e.has("CreationDate")) { this.setCreationDate(e.get("CreationDate")); this.data.creationDate = this.creationDate } else this.data.creationDate = null; if (e.has("M")) { this.setModificationDate(e.get("M")); this.data.modificationDate = this.modificationDate } else this.data.modificationDate = null; this.data.hasPopup = e.has("Popup"); if (e.has("C")) { this.setColor(e.getArray("C")); this.data.color = this.color } else this.data.color = null } else { this.data.title = (0, r.stringToPDFString)(t.get("T") || ""); this.setCreationDate(t.get("CreationDate")); this.data.creationDate = this.creationDate; this.data.hasPopup = t.has("Popup"); t.has("C") || (this.data.color = null) } } setCreationDate(e) { this.creationDate = (0, r.isString)(e) ? e : null } } t.MarkupAnnotation = f; class g extends u { constructor(e) { super(e); const t = e.dict, a = this.data; a.annotationType = r.AnnotationType.WIDGET; a.fieldName = this._constructFieldName(t); a.fieldValue = (0, o.getInheritableProperty)({ dict: t, key: "V", getArray: !0 }); a.alternativeText = (0, r.stringToPDFString)(t.get("TU") || ""); a.defaultAppearance = (0, o.getInheritableProperty)({ dict: t, key: "DA" }) || ""; const i = (0, o.getInheritableProperty)({ dict: t, key: "FT" }); a.fieldType = (0, n.isName)(i) ? i.name : null; this.fieldResources = (0, o.getInheritableProperty)({ dict: t, key: "DR" }) || n.Dict.empty; a.fieldFlags = (0, o.getInheritableProperty)({ dict: t, key: "Ff" }); (!Number.isInteger(a.fieldFlags) || a.fieldFlags < 0) && (a.fieldFlags = 0); a.readOnly = this.hasFieldFlag(r.AnnotationFieldFlag.READONLY); if ("Sig" === a.fieldType) { a.fieldValue = null; this.setFlags(r.AnnotationFlag.HIDDEN) } } _constructFieldName(e) { if (!e.has("T") && !e.has("Parent")) { (0, r.warn)("Unknown field name, falling back to empty field name."); return "" } if (!e.has("Parent")) return (0, r.stringToPDFString)(e.get("T")); const t = []; e.has("T") && t.unshift((0, r.stringToPDFString)(e.get("T"))); let a = e; for (; a.has("Parent");) { a = a.get("Parent"); if (!(0, n.isDict)(a)) break; a.has("T") && t.unshift((0, r.stringToPDFString)(a.get("T"))) } return t.join(".") } hasFieldFlag(e) { return !!(this.data.fieldFlags & e) } getOperatorList(e, t, a) { return a ? Promise.resolve(new c.OperatorList) : super.getOperatorList(e, t, a) } } class m extends g { constructor(e) { super(e); const t = e.dict; this.data.fieldValue = (0, r.stringToPDFString)(this.data.fieldValue || ""); let a = (0, o.getInheritableProperty)({ dict: t, key: "Q" }); (!Number.isInteger(a) || a < 0 || a > 2) && (a = null); this.data.textAlignment = a; let i = (0, o.getInheritableProperty)({ dict: t, key: "MaxLen" }); (!Number.isInteger(i) || i < 0) && (i = null); this.data.maxLen = i; this.data.multiLine = this.hasFieldFlag(r.AnnotationFieldFlag.MULTILINE); this.data.comb = this.hasFieldFlag(r.AnnotationFieldFlag.COMB) && !this.hasFieldFlag(r.AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(r.AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(r.AnnotationFieldFlag.FILESELECT) && null !== this.data.maxLen } getOperatorList(e, t, a) { if (a || this.appearance) return super.getOperatorList(e, t, a); const i = new c.OperatorList; if (!this.data.defaultAppearance) return Promise.resolve(i); const n = new l.Stream((0, r.stringToBytes)(this.data.defaultAppearance)); return e.getOperatorList({ stream: n, task: t, resources: this.fieldResources, operatorList: i }).then((function () { return i })) } } class p extends g { constructor(e) { super(e); this.data.checkBox = !this.hasFieldFlag(r.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON); this.data.radioButton = this.hasFieldFlag(r.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON); this.data.pushButton = this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON); this.data.checkBox ? this._processCheckBox(e) : this.data.radioButton ? this._processRadioButton(e) : this.data.pushButton ? this._processPushButton(e) : (0, r.warn)("Invalid field flags for button widget annotation") } _processCheckBox(e) { (0, n.isName)(this.data.fieldValue) && (this.data.fieldValue = this.data.fieldValue.name); const t = e.dict.get("AP"); if (!(0, n.isDict)(t)) return; const a = t.get("D"); if (!(0, n.isDict)(a)) return; const r = a.getKeys(); 2 === r.length && (this.data.exportValue = "Off" === r[0] ? r[1] : r[0]) } _processRadioButton(e) { this.data.fieldValue = this.data.buttonValue = null; const t = e.dict.get("Parent"); if ((0, n.isDict)(t) && t.has("V")) { const e = t.get("V"); (0, n.isName)(e) && (this.data.fieldValue = e.name) } const a = e.dict.get("AP"); if (!(0, n.isDict)(a)) return; const r = a.get("N"); if ((0, n.isDict)(r)) for (const e of r.getKeys()) if ("Off" !== e) { this.data.buttonValue = e; break } } _processPushButton(e) { e.dict.has("A") ? i.Catalog.parseDestDictionary({ destDict: e.dict, resultObj: this.data, docBaseUrl: e.pdfManager.docBaseUrl }) : (0, r.warn)("Push buttons without action dictionaries are not supported") } } class b extends g { constructor(e) { super(e); this.data.options = []; const t = (0, o.getInheritableProperty)({ dict: e.dict, key: "Opt" }); if (Array.isArray(t)) { const a = e.xref; for (let e = 0, i = t.length; e < i; e++) { const i = a.fetchIfRef(t[e]), n = Array.isArray(i); this.data.options[e] = { exportValue: n ? a.fetchIfRef(i[0]) : i, displayValue: (0, r.stringToPDFString)(n ? a.fetchIfRef(i[1]) : i) } } } Array.isArray(this.data.fieldValue) || (this.data.fieldValue = [this.data.fieldValue]); this.data.combo = this.hasFieldFlag(r.AnnotationFieldFlag.COMBO); this.data.multiSelect = this.hasFieldFlag(r.AnnotationFieldFlag.MULTISELECT) } } class y extends f { constructor(e) { super(e); const t = e.dict; this.data.annotationType = r.AnnotationType.TEXT; if (this.data.hasAppearance) this.data.name = "NoIcon"; else { this.data.rect[1] = this.data.rect[3] - 22; this.data.rect[2] = this.data.rect[0] + 22; this.data.name = t.has("Name") ? t.get("Name").name : "Note" } if (t.has("State")) { this.data.state = t.get("State") || null; this.data.stateModel = t.get("StateModel") || null } else { this.data.state = null; this.data.stateModel = null } } } class v extends u { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.LINK; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t); i.Catalog.parseDestDictionary({ destDict: e.dict, resultObj: this.data, docBaseUrl: e.pdfManager.docBaseUrl }) } } class w extends u { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.POPUP; let t = e.dict.get("Parent"); if (!t) { (0, r.warn)("Popup annotation has a missing or invalid parent annotation."); return } const a = t.get("Subtype"); this.data.parentType = (0, n.isName)(a) ? a.name : null; const i = e.dict.getRaw("Parent"); this.data.parentId = (0, n.isRef)(i) ? i.toString() : null; const s = t.get("RT"); (0, n.isName)(s, r.AnnotationReplyType.GROUP) && (t = t.get("IRT")); if (t.has("M")) { this.setModificationDate(t.get("M")); this.data.modificationDate = this.modificationDate } else this.data.modificationDate = null; if (t.has("C")) { this.setColor(t.getArray("C")); this.data.color = this.color } else this.data.color = null; if (!this.viewable) { const e = t.get("F"); this._isViewable(e) && this.setFlags(e) } this.data.title = (0, r.stringToPDFString)(t.get("T") || ""); this.data.contents = (0, r.stringToPDFString)(t.get("Contents") || "") } } class k extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.FREETEXT } } class S extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.LINE; this.data.lineCoordinates = r.Util.normalizeRect(e.dict.getArray("L")) } } class C extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.SQUARE } } class x extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.CIRCLE } } class A extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.POLYLINE; const t = e.dict.getArray("Vertices"); this.data.vertices = []; for (let e = 0, a = t.length; e < a; e += 2)this.data.vertices.push({ x: t[e], y: t[e + 1] }) } } class I extends A { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.POLYGON } } class F extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.CARET } } class T extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.INK; const t = e.xref, a = e.dict.getArray("InkList"); this.data.inkLists = []; for (let e = 0, r = a.length; e < r; ++e) { this.data.inkLists.push([]); for (let r = 0, i = a[e].length; r < i; r += 2)this.data.inkLists[e].push({ x: t.fetchIfRef(a[e][r]), y: t.fetchIfRef(a[e][r + 1]) }) } } } class E extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.HIGHLIGHT; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t) } } class O extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.UNDERLINE; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t) } } class P extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.SQUIGGLY; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t) } } class B extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.STRIKEOUT; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t) } } class D extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.STAMP } } class N extends f { constructor(e) { super(e); const t = new i.FileSpec(e.dict.get("FS"), e.xref); this.data.annotationType = r.AnnotationType.FILEATTACHMENT; this.data.file = t.serializable } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.OperatorList = void 0; var r = a(2), i = function () { function e(e, t, a, r, i) { for (var n = e, s = 0, o = t.length - 1; s < o; s++) { var c = t[s]; n = n[c] || (n[c] = []) } n[t[t.length - 1]] = { checkFn: a, iterateFn: r, processFn: i } } var t = []; e(t, [r.OPS.save, r.OPS.transform, r.OPS.paintInlineImageXObject, r.OPS.restore], null, (function (e, t) { var a = e.fnArray, i = (t - (e.iCurr - 3)) % 4; switch (i) { case 0: return a[t] === r.OPS.save; case 1: return a[t] === r.OPS.transform; case 2: return a[t] === r.OPS.paintInlineImageXObject; case 3: return a[t] === r.OPS.restore }throw new Error(`iterateInlineImageGroup - invalid pos: ${i}`) }), (function (e, t) { var a = e.fnArray, i = e.argsArray, n = e.iCurr, s = n - 3, o = n - 2, c = n - 1, l = Math.min(Math.floor((t - s) / 4), 200); if (l < 10) return t - (t - s) % 4; var h, u = 0, d = [], f = 0, g = 1, m = 1; for (h = 0; h < l; h++) { var p = i[o + (h << 2)], b = i[c + (h << 2)][0]; if (g + b.width > 1e3) { u = Math.max(u, g); m += f + 2; g = 0; f = 0 } d.push({ transform: p, x: g, y: m, w: b.width, h: b.height }); g += b.width + 2; f = Math.max(f, b.height) } var y = Math.max(u, g) + 1, v = m + f + 1, w = new Uint8ClampedArray(y * v * 4), k = y << 2; for (h = 0; h < l; h++) { var S = i[c + (h << 2)][0].data, C = d[h].w << 2, x = 0, A = d[h].x + d[h].y * y << 2; w.set(S.subarray(0, C), A - k); for (var I = 0, F = d[h].h; I < F; I++) { w.set(S.subarray(x, x + C), A); x += C; A += k } w.set(S.subarray(x - C, x), A); for (; A >= 0;) { S[A - 4] = S[A]; S[A - 3] = S[A + 1]; S[A - 2] = S[A + 2]; S[A - 1] = S[A + 3]; S[A + C] = S[A + C - 4]; S[A + C + 1] = S[A + C - 3]; S[A + C + 2] = S[A + C - 2]; S[A + C + 3] = S[A + C - 1]; A -= k } } a.splice(s, 4 * l, r.OPS.paintInlineImageXObjectGroup); i.splice(s, 4 * l, [{ width: y, height: v, kind: r.ImageKind.RGBA_32BPP, data: w }, d]); return s + 1 })); e(t, [r.OPS.save, r.OPS.transform, r.OPS.paintImageMaskXObject, r.OPS.restore], null, (function (e, t) { var a = e.fnArray, i = (t - (e.iCurr - 3)) % 4; switch (i) { case 0: return a[t] === r.OPS.save; case 1: return a[t] === r.OPS.transform; case 2: return a[t] === r.OPS.paintImageMaskXObject; case 3: return a[t] === r.OPS.restore }throw new Error(`iterateImageMaskGroup - invalid pos: ${i}`) }), (function (e, t) { var a, i = e.fnArray, n = e.argsArray, s = e.iCurr, o = s - 3, c = s - 2, l = s - 1, h = Math.floor((t - o) / 4); if ((h = function (e, t, a, i) { for (var n = e + 2, s = 0; s < t; s++) { var o = i[n + 4 * s], c = 1 === o.length && o[0]; if (!c || 1 !== c.width || 1 !== c.height || c.data.length && (1 !== c.data.length || 0 !== c.data[0])) break; a[n + 4 * s] = r.OPS.paintSolidColorImageMask } return t - s }(o, h, i, n)) < 10) return t - (t - o) % 4; var u, d, f = !1, g = n[l][0]; if (0 === n[c][1] && 0 === n[c][2]) { f = !0; var m = n[c][0], p = n[c][3]; u = c + 4; var b = l + 4; for (a = 1; a < h; a++, u += 4, b += 4) { d = n[u]; if (n[b][0] !== g || d[0] !== m || 0 !== d[1] || 0 !== d[2] || d[3] !== p) { a < 10 ? f = !1 : h = a; break } } } if (f) { h = Math.min(h, 1e3); var y = new Float32Array(2 * h); u = c; for (a = 0; a < h; a++, u += 4) { d = n[u]; y[a << 1] = d[4]; y[1 + (a << 1)] = d[5] } i.splice(o, 4 * h, r.OPS.paintImageMaskXObjectRepeat); n.splice(o, 4 * h, [g, m, p, y]) } else { h = Math.min(h, 100); var v = []; for (a = 0; a < h; a++) { d = n[c + (a << 2)]; var w = n[l + (a << 2)][0]; v.push({ data: w.data, width: w.width, height: w.height, transform: d }) } i.splice(o, 4 * h, r.OPS.paintImageMaskXObjectGroup); n.splice(o, 4 * h, [v]) } return o + 1 })); e(t, [r.OPS.save, r.OPS.transform, r.OPS.paintImageXObject, r.OPS.restore], (function (e) { var t = e.argsArray, a = e.iCurr - 2; return 0 === t[a][1] && 0 === t[a][2] }), (function (e, t) { var a = e.fnArray, i = e.argsArray, n = (t - (e.iCurr - 3)) % 4; switch (n) { case 0: return a[t] === r.OPS.save; case 1: if (a[t] !== r.OPS.transform) return !1; var s = e.iCurr - 2, o = i[s][0], c = i[s][3]; return i[t][0] === o && 0 === i[t][1] && 0 === i[t][2] && i[t][3] === c; case 2: if (a[t] !== r.OPS.paintImageXObject) return !1; var l = i[e.iCurr - 1][0]; return i[t][0] === l; case 3: return a[t] === r.OPS.restore }throw new Error(`iterateImageGroup - invalid pos: ${n}`) }), (function (e, t) { var a = e.fnArray, i = e.argsArray, n = e.iCurr, s = n - 3, o = n - 2, c = i[n - 1][0], l = i[o][0], h = i[o][3], u = Math.min(Math.floor((t - s) / 4), 1e3); if (u < 3) return t - (t - s) % 4; for (var d = new Float32Array(2 * u), f = o, g = 0; g < u; g++, f += 4) { var m = i[f]; d[g << 1] = m[4]; d[1 + (g << 1)] = m[5] } var p = [c, l, h, d]; a.splice(s, 4 * u, r.OPS.paintImageXObjectRepeat); i.splice(s, 4 * u, p); return s + 1 })); e(t, [r.OPS.beginText, r.OPS.setFont, r.OPS.setTextMatrix, r.OPS.showText, r.OPS.endText], null, (function (e, t) { var a = e.fnArray, i = e.argsArray, n = (t - (e.iCurr - 4)) % 5; switch (n) { case 0: return a[t] === r.OPS.beginText; case 1: return a[t] === r.OPS.setFont; case 2: return a[t] === r.OPS.setTextMatrix; case 3: if (a[t] !== r.OPS.showText) return !1; var s = e.iCurr - 3, o = i[s][0], c = i[s][1]; return i[t][0] === o && i[t][1] === c; case 4: return a[t] === r.OPS.endText }throw new Error(`iterateShowTextGroup - invalid pos: ${n}`) }), (function (e, t) { var a = e.fnArray, r = e.argsArray, i = e.iCurr, n = i - 4, s = i - 3, o = i - 2, c = i - 1, l = i, h = r[s][0], u = r[s][1], d = Math.min(Math.floor((t - n) / 5), 1e3); if (d < 3) return t - (t - n) % 5; var f = n; if (n >= 4 && a[n - 4] === a[s] && a[n - 3] === a[o] && a[n - 2] === a[c] && a[n - 1] === a[l] && r[n - 4][0] === h && r[n - 4][1] === u) { d++; f -= 5 } for (var g = f + 4, m = 1; m < d; m++) { a.splice(g, 3); r.splice(g, 3); g += 2 } return g + 1 })); function a(e) { this.queue = e; this.state = null; this.context = { iCurr: 0, fnArray: e.fnArray, argsArray: e.argsArray }; this.match = null; this.lastProcessed = 0 } a.prototype = { _optimize() { const e = this.queue.fnArray; let a = this.lastProcessed, r = e.length, i = this.state, n = this.match; if (!i && !n && a + 1 === r && !t[e[a]]) { this.lastProcessed = r; return } const s = this.context; for (; a < r;) { if (n) { if ((0, n.iterateFn)(s, a)) { a++; continue } a = (0, n.processFn)(s, a + 1); r = e.length; n = null; i = null; if (a >= r) break } i = (i || t)[e[a]]; if (i && !Array.isArray(i)) { s.iCurr = a; a++; if (!i.checkFn || (0, i.checkFn)(s)) { n = i; i = null } else i = null } else a++ } this.state = i; this.match = n; this.lastProcessed = a }, push(e, t) { this.queue.fnArray.push(e); this.queue.argsArray.push(t); this._optimize() }, flush() { for (; this.match;) { const e = this.queue.fnArray.length; this.lastProcessed = (0, this.match.processFn)(this.context, e); this.match = null; this.state = null; this._optimize() } }, reset() { this.state = null; this.match = null; this.lastProcessed = 0 } }; return a }(), n = function () { function e(e) { this.queue = e } e.prototype = { push(e, t) { this.queue.fnArray.push(e); this.queue.argsArray.push(t) }, flush() { }, reset() { } }; return e }(), s = function () { function e(e, t, a) { this._streamSink = t; this.fnArray = []; this.argsArray = []; this.optimizer = t && "oplist" !== e ? new i(this) : new n(this); this.dependencies = Object.create(null); this._totalLength = 0; this.pageIndex = a; this.intent = e; this.weight = 0; this._resolved = t ? null : Promise.resolve() } e.prototype = { get length() { return this.argsArray.length }, get ready() { return this._resolved || this._streamSink.ready }, get totalLength() { return this._totalLength + this.length }, addOp(e, t) { this.optimizer.push(e, t); this.weight++; this._streamSink && (this.weight >= 1e3 || this.weight >= 995 && (e === r.OPS.restore || e === r.OPS.endText)) && this.flush() }, addDependency(e) { if (!(e in this.dependencies)) { this.dependencies[e] = !0; this.addOp(r.OPS.dependency, [e]) } }, addDependencies(e) { for (var t in e) this.addDependency(t) }, addOpList(e) { Object.assign(this.dependencies, e.dependencies); for (var t = 0, a = e.length; t < a; t++)this.addOp(e.fnArray[t], e.argsArray[t]) }, getIR() { return { fnArray: this.fnArray, argsArray: this.argsArray, length: this.length } }, get _transfers() { const e = [], { fnArray: t, argsArray: a, length: i } = this; for (let n = 0; n < i; n++)switch (t[n]) { case r.OPS.paintInlineImageXObject: case r.OPS.paintInlineImageXObjectGroup: case r.OPS.paintImageMaskXObject: const t = a[n][0]; t.cached || e.push(t.data.buffer) }return e }, flush(e = !1) { this.optimizer.flush(); const t = this.length; this._totalLength += t; this._streamSink.enqueue({ fnArray: this.fnArray, argsArray: this.argsArray, lastChunk: e, length: t }, 1, this._transfers); this.dependencies = Object.create(null); this.fnArray.length = 0; this.argsArray.length = 0; this.weight = 0; this.optimizer.reset() } }; return e }(); t.OperatorList = s }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PartialEvaluator = void 0; var r = a(2), i = a(26), n = a(4), s = a(27), o = a(30), c = a(7), l = a(33), h = a(32), u = a(36), d = a(10), f = a(37), g = a(22), m = a(11), p = a(31), b = a(38), y = a(39), v = a(17), w = a(41), k = a(42), S = a(24), C = a(43), x = function () { const e = { forceDataSchema: !1, maxImageSize: -1, disableFontFace: !1, nativeImageDecoderSupport: r.NativeImageDecoding.DECODE, ignoreErrors: !1, isEvalSupported: !0 }; function t({ xref: t, handler: a, pageIndex: i, idFactory: n, fontCache: s, builtInCMapCache: o, options: c = null, pdfFunctionFactory: l }) { this.xref = t; this.handler = a; this.pageIndex = i; this.idFactory = n; this.fontCache = s; this.builtInCMapCache = o; this.options = c || e; this.pdfFunctionFactory = l; this.parsingType3Font = !1; this.fetchBuiltInCMap = async e => { if (this.builtInCMapCache.has(e)) return this.builtInCMapCache.get(e); const t = this.handler.sendWithStream("FetchBuiltInCMap", { name: e }).getReader(), a = await new Promise((function (e, a) { !function r() { t.read().then((function ({ value: t, done: a }) { if (!a) { e(t); r() } }), a) }() })); a.compressionType !== r.CMapCompressionType.NONE && this.builtInCMapCache.set(e, a); return a } } function a() { this.reset() } a.prototype = { check: function () { if (++this.checked < 100) return !1; this.checked = 0; return this.endTime <= Date.now() }, reset: function () { this.endTime = Date.now() + 20; this.checked = 0 } }; function d(e, t = !1) { if (Array.isArray(e)) { for (let t = 0, a = e.length; t < a; t++) { const a = d(e[t], !0); if (a) return a } (0, r.warn)(`Unsupported blend mode Array: ${e}`); return "source-over" } if (!(0, n.isName)(e)) return t ? null : "source-over"; switch (e.name) { case "Normal": case "Compatible": return "source-over"; case "Multiply": return "multiply"; case "Screen": return "screen"; case "Overlay": return "overlay"; case "Darken": return "darken"; case "Lighten": return "lighten"; case "ColorDodge": return "color-dodge"; case "ColorBurn": return "color-burn"; case "HardLight": return "hard-light"; case "SoftLight": return "soft-light"; case "Difference": return "difference"; case "Exclusion": return "exclusion"; case "Hue": return "hue"; case "Saturation": return "saturation"; case "Color": return "color"; case "Luminosity": return "luminosity" }if (t) return null; (0, r.warn)(`Unsupported blend mode: ${e.name}`); return "source-over" } var x = Promise.resolve(); t.prototype = { clone(t = e) { var a = Object.create(this); a.options = t; return a }, hasBlendModes: function (e) { if (!(e instanceof n.Dict)) return !1; var t = Object.create(null); e.objId && (t[e.objId] = !0); for (var a = [e], i = this.xref; a.length;) { var s = a.shift(), o = s.get("ExtGState"); if (o instanceof n.Dict) { var l = o.getKeys(); for (let e = 0, a = l.length; e < a; e++) { const a = l[e]; let s = o.getRaw(a); if (s instanceof n.Ref) { if (t[s.toString()]) continue; try { s = i.fetch(s) } catch (e) { if (e instanceof c.MissingDataException) throw e; if (this.options.ignoreErrors) { s instanceof n.Ref && (t[s.toString()] = !0); this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`hasBlendModes - ignoring ExtGState: "${e}".`); continue } throw e } } if (!(s instanceof n.Dict)) continue; s.objId && (t[s.objId] = !0); const h = s.get("BM"); if (h instanceof n.Name) { if ("Normal" !== h.name) return !0 } else if (void 0 !== h && Array.isArray(h)) for (let e = 0, t = h.length; e < t; e++)if (h[e] instanceof n.Name && "Normal" !== h[e].name) return !0 } } var h = s.get("XObject"); if (h instanceof n.Dict) { var u = h.getKeys(); for (let e = 0, s = u.length; e < s; e++) { const s = u[e]; var d = h.getRaw(s); if (d instanceof n.Ref) { if (t[d.toString()]) continue; try { d = i.fetch(d) } catch (e) { if (e instanceof c.MissingDataException) throw e; if (this.options.ignoreErrors) { d instanceof n.Ref && (t[d.toString()] = !0); this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`hasBlendModes - ignoring XObject: "${e}".`); continue } throw e } } if ((0, n.isStream)(d)) { if (d.dict.objId) { if (t[d.dict.objId]) continue; t[d.dict.objId] = !0 } var f = d.dict.get("Resources"); if (f instanceof n.Dict && (!f.objId || !t[f.objId])) { a.push(f); f.objId && (t[f.objId] = !0) } } } } } return !1 }, async buildFormXObject(e, t, a, i, s, o) { var c = t.dict, l = c.getArray("Matrix"), h = c.getArray("BBox"); h = Array.isArray(h) && 4 === h.length ? r.Util.normalizeRect(h) : null; var u = c.get("Group"); if (u) { var d = { matrix: l, bbox: h, smask: a, isolated: !1, knockout: !1 }, f = u.get("S"), m = null; if ((0, n.isName)(f, "Transparency")) { d.isolated = u.get("I") || !1; d.knockout = u.get("K") || !1; u.has("CS") && (m = await this.parseColorSpace({ cs: u.get("CS"), resources: e })) } if (a && a.backdrop) { m = m || g.ColorSpace.singletons.rgb; a.backdrop = m.getRgb(a.backdrop, 0) } i.addOp(r.OPS.beginGroup, [d]) } i.addOp(r.OPS.paintFormXObjectBegin, [l, h]); return this.getOperatorList({ stream: t, task: s, resources: c.get("Resources") || e, operatorList: i, initialState: o }).then((function () { i.addOp(r.OPS.paintFormXObjectEnd, []); u && i.addOp(r.OPS.endGroup, [d]) })) }, async buildPaintImageXObject({ resources: e, image: t, isInline: a = !1, operatorList: i, cacheKey: n, imageCache: s, forceDisableNativeImageDecoder: o = !1 }) { var c = t.dict, l = c.get("Width", "W"), h = c.get("Height", "H"); if (!(l && (0, r.isNum)(l) && h && (0, r.isNum)(h))) { (0, r.warn)("Image dimensions are missing, or not numbers."); return } var u, d, f = this.options.maxImageSize; if (-1 !== f && l * h > f) { (0, r.warn)("Image exceeded maximum allowed size and was removed."); return } if (c.get("ImageMask", "IM") || !1) { var g = c.get("Width", "W"), p = c.get("Height", "H"), b = g + 7 >> 3, y = t.getBytes(b * p, !0), w = c.getArray("Decode", "D"); (u = C.PDFImage.createMask({ imgArray: y, width: g, height: p, imageIsFromDecodeStream: t instanceof m.DecodeStream, inverseDecode: !!w && w[0] > 0 })).cached = !!n; d = [u]; i.addOp(r.OPS.paintImageMaskXObject, d); n && (s[n] = { fn: r.OPS.paintImageMaskXObject, args: d }); return } var S = c.get("SMask", "SM") || !1, x = c.get("Mask") || !1; if (a && !S && !x && !(t instanceof v.JpegStream) && l + h < 200) { u = new C.PDFImage({ xref: this.xref, res: e, image: t, isInline: a, pdfFunctionFactory: this.pdfFunctionFactory }).createImageData(!0); i.addOp(r.OPS.paintInlineImageXObject, [u]); return } const A = o ? r.NativeImageDecoding.NONE : this.options.nativeImageDecoderSupport; let I = `img_${this.idFactory.createObjId()}`; if (this.parsingType3Font) { (0, r.assert)(A === r.NativeImageDecoding.NONE, "Type3 image resources should be completely decoded in the worker."); I = `${this.idFactory.getDocId()}_type3res_${I}` } if (A !== r.NativeImageDecoding.NONE && !S && !x && t instanceof v.JpegStream && k.NativeImageDecoder.isSupported(t, this.xref, e, this.pdfFunctionFactory) && t.maybeValidDimensions) return this.handler.sendWithPromise("obj", [I, this.pageIndex, "JpegStream", t.getIR(this.options.forceDataSchema)]).then((function () { i.addDependency(I); d = [I, l, h]; i.addOp(r.OPS.paintJpegXObject, d); n && (s[n] = { fn: r.OPS.paintJpegXObject, args: d }) }), o => { (0, r.warn)("Native JPEG decoding failed -- trying to recover: " + (o && o.message)); return this.buildPaintImageXObject({ resources: e, image: t, isInline: a, operatorList: i, cacheKey: n, imageCache: s, forceDisableNativeImageDecoder: !0 }) }); var F = null; A === r.NativeImageDecoding.DECODE && (t instanceof v.JpegStream || x instanceof v.JpegStream || S instanceof v.JpegStream) && (F = new k.NativeImageDecoder({ xref: this.xref, resources: e, handler: this.handler, forceDataSchema: this.options.forceDataSchema, pdfFunctionFactory: this.pdfFunctionFactory })); i.addDependency(I); d = [I, l, h]; const T = C.PDFImage.buildImage({ handler: this.handler, xref: this.xref, res: e, image: t, isInline: a, nativeDecoder: F, pdfFunctionFactory: this.pdfFunctionFactory }).then(e => { var t = e.createImageData(!1); if (this.parsingType3Font) return this.handler.sendWithPromise("commonobj", [I, "FontType3Res", t], [t.data.buffer]); this.handler.send("obj", [I, this.pageIndex, "Image", t], [t.data.buffer]) }).catch(e => { (0, r.warn)("Unable to decode image: " + e); if (this.parsingType3Font) return this.handler.sendWithPromise("commonobj", [I, "FontType3Res", null]); this.handler.send("obj", [I, this.pageIndex, "Image", null]) }); this.parsingType3Font && await T; i.addOp(r.OPS.paintImageXObject, d); n && (s[n] = { fn: r.OPS.paintImageXObject, args: d }) }, handleSMask: function (e, t, a, r, i) { var n = e.get("G"), s = { subtype: e.get("S").name, backdrop: e.get("BC") }, o = e.get("TR"); if ((0, y.isPDFFunction)(o)) { const e = this.pdfFunctionFactory.create(o); for (var c = new Uint8Array(256), l = new Float32Array(1), h = 0; h < 256; h++) { l[0] = h / 255; e(l, 0, l, 0); c[h] = 255 * l[0] | 0 } s.transferMap = c } return this.buildFormXObject(t, n, s, a, r, i.state.clone()) }, handleTilingType(e, t, a, i, s, o, c) { const l = new S.OperatorList, h = [s.get("Resources"), a], d = n.Dict.merge(this.xref, h); return this.getOperatorList({ stream: i, task: c, resources: d, operatorList: l }).then((function () { return (0, u.getTilingPatternIR)({ fnArray: l.fnArray, argsArray: l.argsArray }, s, t) })).then((function (t) { o.addDependencies(l.dependencies); o.addOp(e, t) }), e => { if (!(e instanceof r.AbortException)) { if (!this.options.ignoreErrors) throw e; this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`handleTilingType - ignoring pattern: "${e}".`) } }) }, handleSetFont: function (e, t, a, i, n, o) { var c; t && (c = (t = t.slice())[0].name); return this.loadFont(c, a, e).then(t => t.font.isType3Font ? t.loadType3Data(this, e, i, n).then((function () { return t })).catch(e => { this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); return new A("g_font_error", new s.ErrorFont("Type3 font load error: " + e), t.font) }) : t).then(e => { o.font = e.font; e.send(this.handler); return e.loadedName }) }, handleText(e, a) { const i = a.font, n = i.charsToGlyphs(e); if (i.data) { (!!(a.textRenderingMode & r.TextRenderingMode.ADD_TO_PATH_FLAG) || "Pattern" === a.fillColorSpace.name || i.disableFontFace || this.options.disableFontFace) && t.buildFontPaths(i, n, this.handler) } return n }, ensureStateFont(e) { if (e.font) return; const t = new r.FormatError("Missing setFont (Tf) operator before text rendering operator."); if (!this.options.ignoreErrors) throw t; this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); (0, r.warn)(`ensureStateFont: "${t}".`) }, setGState: function (e, t, a, i, s) { for (var o = [], c = t.getKeys(), l = Promise.resolve(), h = 0, u = c.length; h < u; h++) { const u = c[h], f = t.get(u); switch (u) { case "Type": break; case "LW": case "LC": case "LJ": case "ML": case "D": case "RI": case "FL": case "CA": case "ca": o.push([u, f]); break; case "Font": l = l.then(() => this.handleSetFont(e, null, f[0], a, i, s.state).then((function (e) { a.addDependency(e); o.push([u, [e, f[1]]]) }))); break; case "BM": o.push([u, d(f)]); break; case "SMask": if ((0, n.isName)(f, "None")) { o.push([u, !1]); break } if ((0, n.isDict)(f)) { l = l.then(() => this.handleSMask(f, e, a, i, s)); o.push([u, !0]) } else (0, r.warn)("Unsupported SMask type"); break; case "OP": case "op": case "OPM": case "BG": case "BG2": case "UCR": case "UCR2": case "TR": case "TR2": case "HT": case "SM": case "SA": case "AIS": case "TK": (0, r.info)("graphic state operator " + u); break; default: (0, r.info)("Unknown graphic state operator " + u) } } return l.then((function () { o.length > 0 && a.addOp(r.OPS.setGState, [o]) })) }, loadFont: function (e, a, i) { function o() { return Promise.resolve(new A("g_font_error", new s.ErrorFont("Font " + e + " is not available"), a)) } var c, l = this.xref; if (a) { if (!(0, n.isRef)(a)) throw new r.FormatError('The "font" object should be a reference.'); c = a } else { var h = i.get("Font"); h && (c = h.getRaw(e)) } if (!c) { const i = `Font "${e || a && a.toString()}" is not available`; if (!this.options.ignoreErrors && !this.parsingType3Font) { (0, r.warn)(`${i}.`); return o() } this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); (0, r.warn)(`${i} -- attempting to fallback to a default font.`); c = t.getFallbackFontDict() } if (this.fontCache.has(c)) return this.fontCache.get(c); a = l.fetchIfRef(c); if (!(0, n.isDict)(a)) return o(); if (a.translated) return a.translated; var u = (0, r.createPromiseCapability)(), d = this.preEvaluateFont(a); const { descriptor: f, hash: g } = d; var m, p, b = (0, n.isRef)(c); b && (m = c.toString()); if (g && (0, n.isDict)(f)) { f.fontAliases || (f.fontAliases = Object.create(null)); var y = f.fontAliases; if (y[g]) { var v = y[g].aliasRef; if (b && v && this.fontCache.has(v)) { this.fontCache.putAlias(c, v); return this.fontCache.get(c) } } else y[g] = { fontID: s.Font.getFontID() }; b && (y[g].aliasRef = c); m = y[g].fontID } if (b) this.fontCache.put(c, u.promise); else { m || (m = this.idFactory.createObjId()); this.fontCache.put(`id_${m}`, u.promise) } (0, r.assert)(m, 'The "fontID" must be defined.'); a.loadedName = `${this.idFactory.getDocId()}_f${m}`; a.translated = u.promise; try { p = this.translateFont(d) } catch (e) { p = Promise.reject(e) } p.then((function (e) { if (void 0 !== e.fontType) { l.stats.fontTypes[e.fontType] = !0 } u.resolve(new A(a.loadedName, e, a)) })).catch(e => { this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); try { var t = f && f.get("FontFile3"), i = t && t.get("Subtype"), n = (0, s.getFontType)(d.type, i && i.name); l.stats.fontTypes[n] = !0 } catch (e) { } u.resolve(new A(a.loadedName, new s.ErrorFont(e instanceof Error ? e.message : e), a)) }); return u.promise }, buildPath(e, t, a, i = !1) { var n = e.length - 1; a || (a = []); if (n < 0 || e.fnArray[n] !== r.OPS.constructPath) { if (i) { (0, r.warn)(`Encountered path operator "${t}" inside of a text object.`); e.addOp(r.OPS.save, null) } e.addOp(r.OPS.constructPath, [[t], a]); i && e.addOp(r.OPS.restore, null) } else { var s = e.argsArray[n]; s[0].push(t); Array.prototype.push.apply(s[1], a) } }, parseColorSpace({ cs: e, resources: t }) { return new Promise(a => { a(g.ColorSpace.parse(e, this.xref, t, this.pdfFunctionFactory)) }).catch(e => { if (e instanceof r.AbortException) return null; if (this.options.ignoreErrors) { this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`parseColorSpace - ignoring ColorSpace: "${e}".`); return null } throw e }) }, async handleColorN(e, t, a, i, s, o, c) { var l, h = a[a.length - 1]; if ((0, n.isName)(h) && (l = s.get(h.name))) { var d = (0, n.isStream)(l) ? l.dict : l, f = d.get("PatternType"); if (1 === f) { var g = i.base ? i.base.getRgb(a, 0) : null; return this.handleTilingType(t, g, o, l, d, e, c) } if (2 === f) { var m = d.get("Shading"), p = d.getArray("Matrix"); l = u.Pattern.parseShading(m, p, this.xref, o, this.handler, this.pdfFunctionFactory); e.addOp(t, l.getIR()); return } throw new r.FormatError(`Unknown PatternType: ${f}`) } throw new r.FormatError(`Unknown PatternName: ${h}`) }, getOperatorList({ stream: e, task: t, resources: i, operatorList: s, initialState: o = null }) { i = i || n.Dict.empty; o = o || new T; if (!s) throw new Error('getOperatorList: missing "operatorList" parameter'); var c = this, l = this.xref; let h = !1; var d = Object.create(null), f = i.get("XObject") || n.Dict.empty, m = i.get("Pattern") || n.Dict.empty, p = new I(o), b = new E(e, l, p), y = new a; function v(e) { for (var t = 0, a = b.savedStatesDepth; t < a; t++)s.addOp(r.OPS.restore, []) } return new Promise((function e(a, o) { const w = function (t) { Promise.all([t, s.ready]).then((function () { try { e(a, o) } catch (e) { o(e) } }), o) }; t.ensureNotTerminated(); y.reset(); for (var k, S, C, A, I = {}; !(k = y.check());) { I.args = null; if (!b.read(I)) break; var F = I.args, T = I.fn; switch (0 | T) { case r.OPS.paintXObject: var E = F[0].name; if (E && void 0 !== d[E]) { s.addOp(d[E].fn, d[E].args); F = null; continue } w(new Promise((function (e, a) { if (!E) throw new r.FormatError("XObject must be referred to by name."); const o = f.get(E); if (!o) { s.addOp(T, F); e(); return } if (!(0, n.isStream)(o)) throw new r.FormatError("XObject should be a stream"); const l = o.dict.get("Subtype"); if (!(0, n.isName)(l)) throw new r.FormatError("XObject should have a Name subtype"); if ("Form" !== l.name) if ("Image" !== l.name) { if ("PS" !== l.name) throw new r.FormatError(`Unhandled XObject subtype ${l.name}`); (0, r.info)("Ignored XObject subtype PS"); e() } else c.buildPaintImageXObject({ resources: i, image: o, operatorList: s, cacheKey: E, imageCache: d }).then(e, a); else { p.save(); c.buildFormXObject(i, o, null, s, t, p.state.clone()).then((function () { p.restore(); e() }), a) } })).catch((function (e) { if (!(e instanceof r.AbortException)) { if (!c.options.ignoreErrors) throw e; c.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`getOperatorList - ignoring XObject: "${e}".`) } }))); return; case r.OPS.setFont: var O = F[1]; w(c.handleSetFont(i, F, null, s, t, p.state).then((function (e) { s.addDependency(e); s.addOp(r.OPS.setFont, [e, O]) }))); return; case r.OPS.beginText: h = !0; break; case r.OPS.endText: h = !1; break; case r.OPS.endInlineImage: var P = F[0].cacheKey; if (P) { var B = d[P]; if (void 0 !== B) { s.addOp(B.fn, B.args); F = null; continue } } w(c.buildPaintImageXObject({ resources: i, image: F[0], isInline: !0, operatorList: s, cacheKey: P, imageCache: d })); return; case r.OPS.showText: if (!p.state.font) { c.ensureStateFont(p.state); continue } F[0] = c.handleText(F[0], p.state); break; case r.OPS.showSpacedText: if (!p.state.font) { c.ensureStateFont(p.state); continue } var D = F[0], N = [], M = D.length, L = p.state; for (S = 0; S < M; ++S) { var R = D[S]; (0, r.isString)(R) ? Array.prototype.push.apply(N, c.handleText(R, L)) : (0, r.isNum)(R) && N.push(R) } F[0] = N; T = r.OPS.showText; break; case r.OPS.nextLineShowText: if (!p.state.font) { c.ensureStateFont(p.state); continue } s.addOp(r.OPS.nextLine); F[0] = c.handleText(F[0], p.state); T = r.OPS.showText; break; case r.OPS.nextLineSetSpacingShowText: if (!p.state.font) { c.ensureStateFont(p.state); continue } s.addOp(r.OPS.nextLine); s.addOp(r.OPS.setWordSpacing, [F.shift()]); s.addOp(r.OPS.setCharSpacing, [F.shift()]); F[0] = c.handleText(F[0], p.state); T = r.OPS.showText; break; case r.OPS.setTextRenderingMode: p.state.textRenderingMode = F[0]; break; case r.OPS.setFillColorSpace: w(c.parseColorSpace({ cs: F[0], resources: i }).then((function (e) { e && (p.state.fillColorSpace = e) }))); return; case r.OPS.setStrokeColorSpace: w(c.parseColorSpace({ cs: F[0], resources: i }).then((function (e) { e && (p.state.strokeColorSpace = e) }))); return; case r.OPS.setFillColor: A = p.state.fillColorSpace; F = A.getRgb(F, 0); T = r.OPS.setFillRGBColor; break; case r.OPS.setStrokeColor: A = p.state.strokeColorSpace; F = A.getRgb(F, 0); T = r.OPS.setStrokeRGBColor; break; case r.OPS.setFillGray: p.state.fillColorSpace = g.ColorSpace.singletons.gray; F = g.ColorSpace.singletons.gray.getRgb(F, 0); T = r.OPS.setFillRGBColor; break; case r.OPS.setStrokeGray: p.state.strokeColorSpace = g.ColorSpace.singletons.gray; F = g.ColorSpace.singletons.gray.getRgb(F, 0); T = r.OPS.setStrokeRGBColor; break; case r.OPS.setFillCMYKColor: p.state.fillColorSpace = g.ColorSpace.singletons.cmyk; F = g.ColorSpace.singletons.cmyk.getRgb(F, 0); T = r.OPS.setFillRGBColor; break; case r.OPS.setStrokeCMYKColor: p.state.strokeColorSpace = g.ColorSpace.singletons.cmyk; F = g.ColorSpace.singletons.cmyk.getRgb(F, 0); T = r.OPS.setStrokeRGBColor; break; case r.OPS.setFillRGBColor: p.state.fillColorSpace = g.ColorSpace.singletons.rgb; F = g.ColorSpace.singletons.rgb.getRgb(F, 0); break; case r.OPS.setStrokeRGBColor: p.state.strokeColorSpace = g.ColorSpace.singletons.rgb; F = g.ColorSpace.singletons.rgb.getRgb(F, 0); break; case r.OPS.setFillColorN: if ("Pattern" === (A = p.state.fillColorSpace).name) { w(c.handleColorN(s, r.OPS.setFillColorN, F, A, m, i, t)); return } F = A.getRgb(F, 0); T = r.OPS.setFillRGBColor; break; case r.OPS.setStrokeColorN: if ("Pattern" === (A = p.state.strokeColorSpace).name) { w(c.handleColorN(s, r.OPS.setStrokeColorN, F, A, m, i, t)); return } F = A.getRgb(F, 0); T = r.OPS.setStrokeRGBColor; break; case r.OPS.shadingFill: var U = i.get("Shading"); if (!U) throw new r.FormatError("No shading resource found"); var q = U.get(F[0].name); if (!q) throw new r.FormatError("No shading object found"); var j = u.Pattern.parseShading(q, null, l, i, c.handler, c.pdfFunctionFactory).getIR(); F = [j]; T = r.OPS.shadingFill; break; case r.OPS.setGState: var _ = F[0], z = i.get("ExtGState"); if (!(0, n.isDict)(z) || !z.has(_.name)) break; var H = z.get(_.name); w(c.setGState(i, H, s, t, p)); return; case r.OPS.moveTo: case r.OPS.lineTo: case r.OPS.curveTo: case r.OPS.curveTo2: case r.OPS.curveTo3: case r.OPS.closePath: case r.OPS.rectangle: c.buildPath(s, T, F, h); continue; case r.OPS.markPoint: case r.OPS.markPointProps: case r.OPS.beginMarkedContent: case r.OPS.beginMarkedContentProps: case r.OPS.endMarkedContent: case r.OPS.beginCompat: case r.OPS.endCompat: continue; default: if (null !== F) { for (S = 0, C = F.length; S < C && !(F[S] instanceof n.Dict); S++); if (S < C) { (0, r.warn)("getOperatorList - ignoring operator: " + T); continue } } }s.addOp(T, F) } if (k) w(x); else { v(); a() } })).catch(e => { if (!(e instanceof r.AbortException)) { if (!this.options.ignoreErrors) throw e; this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`getOperatorList - ignoring errors during "${t.name}" ` + `task: "${e}".`); v() } }) }, getTextContent({ stream: e, task: t, resources: i, stateManager: s = null, normalizeWhitespace: o = !1, combineTextItems: c = !1, sink: h, seenStyles: u = Object.create(null) }) { i = i || n.Dict.empty; s = s || new I(new F); var d, g = /\s/g, m = { items: [], styles: Object.create(null) }, p = { initialized: !1, str: [], width: 0, height: 0, vertical: !1, lastAdvanceWidth: 0, lastAdvanceHeight: 0, textAdvanceScale: 0, spaceWidth: 0, fakeSpaceMin: 1 / 0, fakeMultiSpaceMin: 1 / 0, fakeMultiSpaceMax: -0, textRunBreakAllowed: !1, transform: null, fontName: null }, b = this, y = this.xref, v = null, w = Object.create(null), k = new E(e, y, s); function S() { if (p.initialized) return p; var e = d.font; if (!(e.loadedName in u)) { u[e.loadedName] = !0; m.styles[e.loadedName] = { fontFamily: e.fallbackName, ascent: e.ascent, descent: e.descent, vertical: !!e.vertical } } p.fontName = e.loadedName; var t = [d.fontSize * d.textHScale, 0, 0, d.fontSize, 0, d.textRise]; if (e.isType3Font && d.fontSize <= 1 && !(0, r.isArrayEqual)(d.fontMatrix, r.FONT_IDENTITY_MATRIX)) { const a = e.bbox[3] - e.bbox[1]; a > 0 && (t[3] *= a * d.fontMatrix[3]) } var a = r.Util.transform(d.ctm, r.Util.transform(d.textMatrix, t)); p.transform = a; if (e.vertical) { p.width = Math.sqrt(a[0] * a[0] + a[1] * a[1]); p.height = 0; p.vertical = !0 } else { p.width = 0; p.height = Math.sqrt(a[2] * a[2] + a[3] * a[3]); p.vertical = !1 } var i = d.textLineMatrix[0], n = d.textLineMatrix[1], s = Math.sqrt(i * i + n * n); i = d.ctm[0]; n = d.ctm[1]; var o = Math.sqrt(i * i + n * n); p.textAdvanceScale = o * s; p.lastAdvanceWidth = 0; p.lastAdvanceHeight = 0; var c = e.spaceWidth / 1e3 * d.fontSize; if (c) { p.spaceWidth = c; p.fakeSpaceMin = .3 * c; p.fakeMultiSpaceMin = 1.5 * c; p.fakeMultiSpaceMax = 4 * c; p.textRunBreakAllowed = !e.isMonospace } else { p.spaceWidth = 0; p.fakeSpaceMin = 1 / 0; p.fakeMultiSpaceMin = 1 / 0; p.fakeMultiSpaceMax = 0; p.textRunBreakAllowed = !1 } p.initialized = !0; return p } function C(e) { for (var t, a = 0, r = e.length; a < r && (t = e.charCodeAt(a)) >= 32 && t <= 127;)a++; return a < r ? e.replace(g, " ") : e } function A(e, t) { return b.loadFont(e, t, i).then((function (e) { d.font = e.font; d.fontMatrix = e.font.fontMatrix || r.FONT_IDENTITY_MATRIX })) } function T(e) { for (var t = d.font, a = S(), r = 0, i = 0, n = t.charsToGlyphs(e), s = 0; s < n.length; s++) { var o = n[s], c = null; c = t.vertical && o.vmetric ? o.vmetric[0] : o.width; var h = o.unicode, u = (0, l.getNormalizedUnicodes)(); void 0 !== u[h] && (h = u[h]); h = (0, l.reverseIfRtl)(h); var f = d.charSpacing; if (o.isSpace) { var g = d.wordSpacing; f += g; g > 0 && O(g, a.str) } var m = 0, p = 0; if (t.vertical) { i += p = c * d.fontMatrix[0] * d.fontSize + f } else { r += m = (c * d.fontMatrix[0] * d.fontSize + f) * d.textHScale } d.translateTextMatrix(m, p); a.str.push(h) } if (t.vertical) { a.lastAdvanceHeight = i; a.height += Math.abs(i) } else { a.lastAdvanceWidth = r; a.width += r } return a } function O(e, t) { if (!(e < p.fakeSpaceMin)) if (e < p.fakeMultiSpaceMin) t.push(" "); else for (var a = Math.round(e / p.spaceWidth); a-- > 0;)t.push(" ") } function P() { if (p.initialized) { p.vertical ? p.height *= p.textAdvanceScale : p.width *= p.textAdvanceScale; m.items.push((t = (e = p).str.join(""), a = (0, f.bidi)(t, -1, e.vertical), { str: o ? C(a.str) : a.str, dir: a.dir, width: e.width, height: e.height, transform: e.transform, fontName: e.fontName })); var e, t, a; p.initialized = !1; p.str.length = 0 } } function B() { const e = m.items.length; if (e > 0) { h.enqueue(m, e); m.items = []; m.styles = Object.create(null) } } var D = new a; return new Promise((function e(a, l) { const f = function (t) { B(); Promise.all([t, h.ready]).then((function () { try { e(a, l) } catch (e) { l(e) } }), l) }; t.ensureNotTerminated(); D.reset(); for (var g, y = {}, C = []; !(g = D.check());) { C.length = 0; y.args = C; if (!k.read(y)) break; d = s.state; var F, E = y.fn; C = y.args; switch (0 | E) { case r.OPS.setFont: var N = C[0].name, M = C[1]; if (d.font && N === d.fontName && M === d.fontSize) break; P(); d.fontName = N; d.fontSize = M; f(A(N, null)); return; case r.OPS.setTextRise: P(); d.textRise = C[0]; break; case r.OPS.setHScale: P(); d.textHScale = C[0] / 100; break; case r.OPS.setLeading: P(); d.leading = C[0]; break; case r.OPS.moveText: var L = !!d.font && 0 === (d.font.vertical ? C[0] : C[1]); F = C[0] - C[1]; if (c && L && p.initialized && F > 0 && F <= p.fakeMultiSpaceMax) { d.translateTextLineMatrix(C[0], C[1]); p.width += C[0] - p.lastAdvanceWidth; p.height += C[1] - p.lastAdvanceHeight; O(C[0] - p.lastAdvanceWidth - (C[1] - p.lastAdvanceHeight), p.str); break } P(); d.translateTextLineMatrix(C[0], C[1]); d.textMatrix = d.textLineMatrix.slice(); break; case r.OPS.setLeadingMoveText: P(); d.leading = -C[1]; d.translateTextLineMatrix(C[0], C[1]); d.textMatrix = d.textLineMatrix.slice(); break; case r.OPS.nextLine: P(); d.carriageReturn(); break; case r.OPS.setTextMatrix: F = d.calcTextLineMatrixAdvance(C[0], C[1], C[2], C[3], C[4], C[5]); if (c && null !== F && p.initialized && F.value > 0 && F.value <= p.fakeMultiSpaceMax) { d.translateTextLineMatrix(F.width, F.height); p.width += F.width - p.lastAdvanceWidth; p.height += F.height - p.lastAdvanceHeight; O(F.width - p.lastAdvanceWidth - (F.height - p.lastAdvanceHeight), p.str); break } P(); d.setTextMatrix(C[0], C[1], C[2], C[3], C[4], C[5]); d.setTextLineMatrix(C[0], C[1], C[2], C[3], C[4], C[5]); break; case r.OPS.setCharSpacing: d.charSpacing = C[0]; break; case r.OPS.setWordSpacing: d.wordSpacing = C[0]; break; case r.OPS.beginText: P(); d.textMatrix = r.IDENTITY_MATRIX.slice(); d.textLineMatrix = r.IDENTITY_MATRIX.slice(); break; case r.OPS.showSpacedText: if (!s.state.font) { b.ensureStateFont(s.state); continue } for (var R, U = C[0], q = 0, j = U.length; q < j; q++)if ("string" == typeof U[q]) T(U[q]); else if ((0, r.isNum)(U[q])) { S(); F = U[q] * d.fontSize / 1e3; var _ = !1; if (d.font.vertical) { R = F; d.translateTextMatrix(0, R); (_ = p.textRunBreakAllowed && F > p.fakeMultiSpaceMax) || (p.height += R) } else { R = (F = -F) * d.textHScale; d.translateTextMatrix(R, 0); (_ = p.textRunBreakAllowed && F > p.fakeMultiSpaceMax) || (p.width += R) } _ ? P() : F > 0 && O(F, p.str) } break; case r.OPS.showText: if (!s.state.font) { b.ensureStateFont(s.state); continue } T(C[0]); break; case r.OPS.nextLineShowText: if (!s.state.font) { b.ensureStateFont(s.state); continue } P(); d.carriageReturn(); T(C[0]); break; case r.OPS.nextLineSetSpacingShowText: if (!s.state.font) { b.ensureStateFont(s.state); continue } P(); d.wordSpacing = C[0]; d.charSpacing = C[1]; d.carriageReturn(); T(C[2]); break; case r.OPS.paintXObject: P(); v || (v = i.get("XObject") || n.Dict.empty); var z = C[0].name; if (z && void 0 !== w[z]) break; f(new Promise((function (e, a) { if (!z) throw new r.FormatError("XObject must be referred to by name."); const l = v.get(z); if (!l) { e(); return } if (!(0, n.isStream)(l)) throw new r.FormatError("XObject should be a stream"); const d = l.dict.get("Subtype"); if (!(0, n.isName)(d)) throw new r.FormatError("XObject should have a Name subtype"); if ("Form" !== d.name) { w[z] = !0; e(); return } const f = s.state.clone(), g = new I(f), m = l.dict.getArray("Matrix"); Array.isArray(m) && 6 === m.length && g.transform(m); B(); const p = { enqueueInvoked: !1, enqueue(e, t) { this.enqueueInvoked = !0; h.enqueue(e, t) }, get desiredSize() { return h.desiredSize }, get ready() { return h.ready } }; b.getTextContent({ stream: l, task: t, resources: l.dict.get("Resources") || i, stateManager: g, normalizeWhitespace: o, combineTextItems: c, sink: p, seenStyles: u }).then((function () { p.enqueueInvoked || (w[z] = !0); e() }), a) })).catch((function (e) { if (!(e instanceof r.AbortException)) { if (!b.options.ignoreErrors) throw e; (0, r.warn)(`getTextContent - ignoring XObject: "${e}".`) } }))); return; case r.OPS.setGState: P(); var H = C[0], G = i.get("ExtGState"); if (!(0, n.isDict)(G) || !(0, n.isName)(H)) break; var W = G.get(H.name); if (!(0, n.isDict)(W)) break; var X = W.get("Font"); if (X) { d.fontName = null; d.fontSize = X[1]; f(A(null, X[0])); return } }if (m.items.length >= h.desiredSize) { g = !0; break } } if (g) f(x); else { P(); B(); a() } })).catch(e => { if (!(e instanceof r.AbortException)) { if (!this.options.ignoreErrors) throw e; (0, r.warn)(`getTextContent - ignoring errors during "${t.name}" ` + `task: "${e}".`); P(); B() } }) }, extractDataStructures: function (e, t, a) { const i = this.xref; let c; var l = e.get("ToUnicode") || t.get("ToUnicode"), h = l ? this.readToUnicode(l) : Promise.resolve(void 0); if (a.composite) { var u = e.get("CIDSystemInfo"); (0, n.isDict)(u) && (a.cidSystemInfo = { registry: (0, r.stringToPDFString)(u.get("Registry")), ordering: (0, r.stringToPDFString)(u.get("Ordering")), supplement: u.get("Supplement") }); var d = e.get("CIDToGIDMap"); (0, n.isStream)(d) && (c = d.getBytes()) } var f, g = [], m = null; if (e.has("Encoding")) { f = e.get("Encoding"); if ((0, n.isDict)(f)) { m = f.get("BaseEncoding"); m = (0, n.isName)(m) ? m.name : null; if (f.has("Differences")) for (var p = f.get("Differences"), b = 0, y = 0, v = p.length; y < v; y++) { var w = i.fetchIfRef(p[y]); if ((0, r.isNum)(w)) b = w; else { if (!(0, n.isName)(w)) throw new r.FormatError(`Invalid entry in 'Differences' array: ${w}`); g[b++] = w.name } } } else { if (!(0, n.isName)(f)) throw new r.FormatError("Encoding is not a Name nor a Dict"); m = f.name } "MacRomanEncoding" !== m && "MacExpertEncoding" !== m && "WinAnsiEncoding" !== m && (m = null) } if (m) a.defaultEncoding = (0, o.getEncoding)(m).slice(); else { var k = !!(a.flags & s.FontFlags.Symbolic), S = !!(a.flags & s.FontFlags.Nonsymbolic); f = o.StandardEncoding; "TrueType" !== a.type || S || (f = o.WinAnsiEncoding); if (k) { f = o.MacRomanEncoding; a.file || (/Symbol/i.test(a.name) ? f = o.SymbolSetEncoding : /Dingbats|Wingdings/i.test(a.name) && (f = o.ZapfDingbatsEncoding)) } a.defaultEncoding = f } a.differences = g; a.baseEncodingName = m; a.hasEncoding = !!m || g.length > 0; a.dict = e; return h.then(e => { a.toUnicode = e; return this.buildToUnicode(a) }).then(e => { a.toUnicode = e; c && (a.cidToGidMap = this.readCidToGidMap(c, e)); return a }) }, _buildSimpleFontToUnicode(e, t = !1) { (0, r.assert)(!e.composite, "Must be a simple font."); const a = [], i = e.defaultEncoding.slice(), n = e.baseEncodingName, c = e.differences; for (const e in c) { const t = c[e]; ".notdef" !== t && (i[e] = t) } const h = (0, p.getGlyphsUnicode)(); for (const r in i) { let s = i[r]; if ("" !== s) if (void 0 !== h[s]) a[r] = String.fromCharCode(h[s]); else { let i = 0; switch (s[0]) { case "G": 3 === s.length && (i = parseInt(s.substring(1), 16)); break; case "g": 5 === s.length && (i = parseInt(s.substring(1), 16)); break; case "C": case "c": if (s.length >= 3 && s.length <= 4) { const a = s.substring(1); if (t) { i = parseInt(a, 16); break } i = +a; if (Number.isNaN(i) && Number.isInteger(parseInt(a, 16))) return this._buildSimpleFontToUnicode(e, !0) } break; default: const a = (0, l.getUnicodeForGlyph)(s, h); -1 !== a && (i = a) }if (i > 0 && Number.isInteger(i)) { if (n && i === +r) { const e = (0, o.getEncoding)(n); if (e && (s = e[r])) { a[r] = String.fromCharCode(h[s]); continue } } a[r] = String.fromCodePoint(i) } } } return new s.ToUnicodeMap(a) }, buildToUnicode(e) { e.hasIncludedToUnicodeMap = !!e.toUnicode && e.toUnicode.length > 0; if (e.hasIncludedToUnicodeMap) { !e.composite && e.hasEncoding && (e.fallbackToUnicode = this._buildSimpleFontToUnicode(e)); return Promise.resolve(e.toUnicode) } if (!e.composite) return Promise.resolve(this._buildSimpleFontToUnicode(e)); if (e.composite && (e.cMap.builtInCMap && !(e.cMap instanceof i.IdentityCMap) || "Adobe" === e.cidSystemInfo.registry && ("GB1" === e.cidSystemInfo.ordering || "CNS1" === e.cidSystemInfo.ordering || "Japan1" === e.cidSystemInfo.ordering || "Korea1" === e.cidSystemInfo.ordering))) { const t = e.cidSystemInfo.registry, a = e.cidSystemInfo.ordering, o = n.Name.get(t + "-" + a + "-UCS2"); return i.CMapFactory.create({ encoding: o, fetchBuiltInCMap: this.fetchBuiltInCMap, useCMap: null }).then((function (t) { const a = e.cMap, i = []; a.forEach((function (e, a) { if (a > 65535) throw new r.FormatError("Max size of CID is 65,535"); const n = t.lookup(a); n && (i[e] = String.fromCharCode((n.charCodeAt(0) << 8) + n.charCodeAt(1))) })); return new s.ToUnicodeMap(i) })) } return Promise.resolve(new s.IdentityToUnicodeMap(e.firstChar, e.lastChar)) }, readToUnicode: function (e) { var t = e; return (0, n.isName)(t) ? i.CMapFactory.create({ encoding: t, fetchBuiltInCMap: this.fetchBuiltInCMap, useCMap: null }).then((function (e) { return e instanceof i.IdentityCMap ? new s.IdentityToUnicodeMap(0, 65535) : new s.ToUnicodeMap(e.getMap()) })) : (0, n.isStream)(t) ? i.CMapFactory.create({ encoding: t, fetchBuiltInCMap: this.fetchBuiltInCMap, useCMap: null }).then((function (e) { if (e instanceof i.IdentityCMap) return new s.IdentityToUnicodeMap(0, 65535); var t = new Array(e.length); e.forEach((function (e, a) { for (var r = [], i = 0; i < a.length; i += 2) { var n = a.charCodeAt(i) << 8 | a.charCodeAt(i + 1); if (55296 == (63488 & n)) { i += 2; var s = a.charCodeAt(i) << 8 | a.charCodeAt(i + 1); r.push(((1023 & n) << 10) + (1023 & s) + 65536) } else r.push(n) } t[e] = String.fromCodePoint.apply(String, r) })); return new s.ToUnicodeMap(t) }), e => { if (e instanceof r.AbortException) return null; if (this.options.ignoreErrors) { this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); (0, r.warn)(`readToUnicode - ignoring ToUnicode data: "${e}".`); return null } throw e }) : Promise.resolve(null) }, readCidToGidMap(e, t) { for (var a = [], r = 0, i = e.length; r < i; r++) { var n = e[r++] << 8 | e[r]; const i = r >> 1; (0 !== n || t.has(i)) && (a[i] = n) } return a }, extractWidths: function (e, t, a) { var r, i, o, c, l, h, u, d, f = this.xref, g = [], m = 0, p = []; if (a.composite) { m = e.has("DW") ? e.get("DW") : 1e3; if (d = e.get("W")) for (i = 0, o = d.length; i < o; i++) { h = f.fetchIfRef(d[i++]); u = f.fetchIfRef(d[i]); if (Array.isArray(u)) for (c = 0, l = u.length; c < l; c++)g[h++] = f.fetchIfRef(u[c]); else { var b = f.fetchIfRef(d[++i]); for (c = h; c <= u; c++)g[c] = b } } if (a.vertical) { var y = e.getArray("DW2") || [880, -1e3]; r = [y[1], .5 * m, y[0]]; if (y = e.get("W2")) for (i = 0, o = y.length; i < o; i++) { h = f.fetchIfRef(y[i++]); u = f.fetchIfRef(y[i]); if (Array.isArray(u)) for (c = 0, l = u.length; c < l; c++)p[h++] = [f.fetchIfRef(u[c++]), f.fetchIfRef(u[c++]), f.fetchIfRef(u[c])]; else { var v = [f.fetchIfRef(y[++i]), f.fetchIfRef(y[++i]), f.fetchIfRef(y[++i])]; for (c = h; c <= u; c++)p[c] = v } } } } else { var w = a.firstChar; if (d = e.get("Widths")) { c = w; for (i = 0, o = d.length; i < o; i++)g[c++] = f.fetchIfRef(d[i]); m = parseFloat(t.get("MissingWidth")) || 0 } else { var k = e.get("BaseFont"); if ((0, n.isName)(k)) { var S = this.getBaseFontMetrics(k.name); g = this.buildCharCodeToWidth(S.widths, a); m = S.defaultWidth } } } var C = !0, x = m; for (var A in g) { var I = g[A]; if (I) if (x) { if (x !== I) { C = !1; break } } else x = I } C && (a.flags |= s.FontFlags.FixedPitch); a.defaultWidth = m; a.widths = g; a.defaultVMetrics = r; a.vmetrics = p }, isSerifFont: function (e) { var t = e.split("-")[0]; return t in (0, h.getSerifFonts)() || -1 !== t.search(/serif/gi) }, getBaseFontMetrics: function (e) { var t = 0, a = [], i = !1, n = (0, h.getStdFontMap)()[e] || e, s = (0, b.getMetrics)(); n in s || (n = this.isSerifFont(e) ? "Times-Roman" : "Helvetica"); var o = s[n]; if ((0, r.isNum)(o)) { t = o; i = !0 } else a = o(); return { defaultWidth: t, monospace: i, widths: a } }, buildCharCodeToWidth: function (e, t) { for (var a = Object.create(null), r = t.differences, i = t.defaultEncoding, n = 0; n < 256; n++)n in r && e[r[n]] ? a[n] = e[r[n]] : n in i && e[i[n]] && (a[n] = e[i[n]]); return a }, preEvaluateFont: function (e) { var t = e, a = e.get("Subtype"); if (!(0, n.isName)(a)) throw new r.FormatError("invalid font Subtype"); var i, s = !1; if ("Type0" === a.name) { var o = e.get("DescendantFonts"); if (!o) throw new r.FormatError("Descendant fonts are not specified"); a = (e = Array.isArray(o) ? this.xref.fetchIfRef(o[0]) : o).get("Subtype"); if (!(0, n.isName)(a)) throw new r.FormatError("invalid font Subtype"); s = !0 } var c = e.get("FontDescriptor"); if (c) { var l = new w.MurmurHash3_64, h = t.getRaw("Encoding"); if ((0, n.isName)(h)) l.update(h.name); else if ((0, n.isRef)(h)) l.update(h.toString()); else if ((0, n.isDict)(h)) for (var u = h.getKeys(), d = 0, f = u.length; d < f; d++) { var g = h.getRaw(u[d]); if ((0, n.isName)(g)) l.update(g.name); else if ((0, n.isRef)(g)) l.update(g.toString()); else if (Array.isArray(g)) { for (var m = g.length, p = new Array(m), b = 0; b < m; b++) { var y = g[b]; (0, n.isName)(y) ? p[b] = y.name : ((0, r.isNum)(y) || (0, n.isRef)(y)) && (p[b] = y.toString()) } l.update(p.join()) } } const a = e.get("FirstChar") || 0, o = e.get("LastChar") || (s ? 65535 : 255); l.update(`${a}-${o}`); var v = e.get("ToUnicode") || t.get("ToUnicode"); if ((0, n.isStream)(v)) { var k = v.str || v; i = k.buffer ? new Uint8Array(k.buffer.buffer, 0, k.bufferLength) : new Uint8Array(k.bytes.buffer, k.start, k.end - k.start); l.update(i) } else (0, n.isName)(v) && l.update(v.name); var S = e.get("Widths") || t.get("Widths"); if (S) { i = new Uint8Array(new Uint32Array(S).buffer); l.update(i) } } return { descriptor: c, dict: e, baseDict: t, composite: s, type: a.name, hash: l ? l.hexdigest() : "" } }, translateFont: function (e) { var t, a = e.baseDict, o = e.dict, c = e.composite, l = e.descriptor, u = e.type, d = c ? 65535 : 255; const f = o.get("FirstChar") || 0, g = o.get("LastChar") || d; if (!l) { if ("Type3" !== u) { var m = o.get("BaseFont"); if (!(0, n.isName)(m)) throw new r.FormatError("Base font is not specified"); m = m.name.replace(/[,_]/g, "-"); var p = this.getBaseFontMetrics(m), b = m.split("-")[0], y = (this.isSerifFont(b) ? s.FontFlags.Serif : 0) | (p.monospace ? s.FontFlags.FixedPitch : 0) | ((0, h.getSymbolsFonts)()[b] ? s.FontFlags.Symbolic : s.FontFlags.Nonsymbolic); t = { type: u, name: m, widths: p.widths, defaultWidth: p.defaultWidth, flags: y, firstChar: f, lastChar: g }; const e = o.get("Widths"); return this.extractDataStructures(o, o, t).then(t => { if (e) { const a = []; let r = f; for (let t = 0, i = e.length; t < i; t++)a[r++] = this.xref.fetchIfRef(e[t]); t.widths = a } else t.widths = this.buildCharCodeToWidth(p.widths, t); return new s.Font(m, null, t) }) } (l = new n.Dict(null)).set("FontName", n.Name.get(u)); l.set("FontBBox", o.getArray("FontBBox") || [0, 0, 0, 0]) } var v = l.get("FontName"), w = o.get("BaseFont"); (0, r.isString)(v) && (v = n.Name.get(v)); (0, r.isString)(w) && (w = n.Name.get(w)); if ("Type3" !== u) { var k = v && v.name, S = w && w.name; if (k !== S) { (0, r.info)(`The FontDescriptor's FontName is "${k}" but ` + `should be the same as the Font's BaseFont "${S}".`); k && S && S.startsWith(k) && (v = w) } } v = v || w; if (!(0, n.isName)(v)) throw new r.FormatError("invalid font name"); var C, x = l.get("FontFile", "FontFile2", "FontFile3"); if (x && x.dict) { var A = x.dict.get("Subtype"); A && (A = A.name); var I = x.dict.get("Length1"), F = x.dict.get("Length2"), T = x.dict.get("Length3") } t = { type: u, name: v.name, subtype: A, file: x, length1: I, length2: F, length3: T, loadedName: a.loadedName, composite: c, wideChars: c, fixedPitch: !1, fontMatrix: o.getArray("FontMatrix") || r.FONT_IDENTITY_MATRIX, firstChar: f || 0, lastChar: g || d, bbox: l.getArray("FontBBox"), ascent: l.get("Ascent"), descent: l.get("Descent"), xHeight: l.get("XHeight"), capHeight: l.get("CapHeight"), flags: l.get("Flags"), italicAngle: l.get("ItalicAngle"), isType3Font: !1 }; if (c) { var E = a.get("Encoding"); (0, n.isName)(E) && (t.cidEncoding = E.name); C = i.CMapFactory.create({ encoding: E, fetchBuiltInCMap: this.fetchBuiltInCMap, useCMap: null }).then((function (e) { t.cMap = e; t.vertical = t.cMap.vertical })) } else C = Promise.resolve(void 0); return C.then(() => this.extractDataStructures(o, a, t)).then(e => { this.extractWidths(o, l, e); "Type3" === u && (e.isType3Font = !0); return new s.Font(v.name, x, e) }) } }; t.buildFontPaths = function (e, t, a) { function r(t) { e.renderer.hasBuiltPath(t) || a.send("commonobj", [`${e.loadedName}_path_${t}`, "FontPath", e.renderer.getPathJs(t)]) } for (const e of t) { r(e.fontChar); const t = e.accent; t && t.fontChar && r(t.fontChar) } }; t.getFallbackFontDict = function () { if (this._fallbackFontDict) return this._fallbackFontDict; const e = new n.Dict; e.set("BaseFont", n.Name.get("PDFJS-FallbackFont")); e.set("Type", n.Name.get("FallbackType")); e.set("Subtype", n.Name.get("FallbackType")); e.set("Encoding", n.Name.get("WinAnsiEncoding")); return this._fallbackFontDict = e }; return t }(); t.PartialEvaluator = x; var A = function () { function e(e, t, a) { this.loadedName = e; this.font = t; this.dict = a; this.type3Loaded = null; this.sent = !1 } e.prototype = { send(e) { if (!this.sent) { this.sent = !0; e.send("commonobj", [this.loadedName, "Font", this.font.exportData()]) } }, fallback(e) { if (!this.font.data) return; this.font.disableFontFace = !0; const t = this.font.glyphCacheValues; x.buildFontPaths(this.font, t, e) }, loadType3Data(e, t, a, i) { if (!this.font.isType3Font) throw new Error("Must be a Type3 font."); if (this.type3Loaded) return this.type3Loaded; var n = Object.create(e.options); n.ignoreErrors = !1; n.nativeImageDecoderSupport = r.NativeImageDecoding.NONE; var s = e.clone(n); s.parsingType3Font = !0; for (var o = this.font, c = Promise.resolve(), l = this.dict.get("CharProcs"), h = this.dict.get("Resources") || t, u = l.getKeys(), d = Object.create(null), f = 0, g = u.length; f < g; ++f) { const e = u[f]; c = c.then((function () { var t = l.get(e), n = new S.OperatorList; return s.getOperatorList({ stream: t, task: i, resources: h, operatorList: n }).then((function () { d[e] = n.getIR(); a.addDependencies(n.dependencies) })).catch((function (t) { (0, r.warn)(`Type3 font resource "${e}" is not available.`); var a = new S.OperatorList; d[e] = a.getIR() })) })) } this.type3Loaded = c.then((function () { o.charProcOperatorList = d })); return this.type3Loaded } }; return e }(), I = function () { function e(e) { this.state = e; this.stateStack = [] } e.prototype = { save() { var e = this.state; this.stateStack.push(this.state); this.state = e.clone() }, restore() { var e = this.stateStack.pop(); e && (this.state = e) }, transform(e) { this.state.ctm = r.Util.transform(this.state.ctm, e) } }; return e }(), F = function () { function e() { this.ctm = new Float32Array(r.IDENTITY_MATRIX); this.fontName = null; this.fontSize = 0; this.font = null; this.fontMatrix = r.FONT_IDENTITY_MATRIX; this.textMatrix = r.IDENTITY_MATRIX.slice(); this.textLineMatrix = r.IDENTITY_MATRIX.slice(); this.charSpacing = 0; this.wordSpacing = 0; this.leading = 0; this.textHScale = 1; this.textRise = 0 } e.prototype = { setTextMatrix: function (e, t, a, r, i, n) { var s = this.textMatrix; s[0] = e; s[1] = t; s[2] = a; s[3] = r; s[4] = i; s[5] = n }, setTextLineMatrix: function (e, t, a, r, i, n) { var s = this.textLineMatrix; s[0] = e; s[1] = t; s[2] = a; s[3] = r; s[4] = i; s[5] = n }, translateTextMatrix: function (e, t) { var a = this.textMatrix; a[4] = a[0] * e + a[2] * t + a[4]; a[5] = a[1] * e + a[3] * t + a[5] }, translateTextLineMatrix: function (e, t) { var a = this.textLineMatrix; a[4] = a[0] * e + a[2] * t + a[4]; a[5] = a[1] * e + a[3] * t + a[5] }, calcTextLineMatrixAdvance: function (e, t, a, r, i, n) { var s = this.font; if (!s) return null; var o = this.textLineMatrix; if (e !== o[0] || t !== o[1] || a !== o[2] || r !== o[3]) return null; var c = i - o[4], l = n - o[5]; if (s.vertical && 0 !== c || !s.vertical && 0 !== l) return null; var h, u, d = e * r - t * a; if (s.vertical) { h = -l * a / d; u = l * e / d } else { h = c * r / d; u = -c * t / d } return { width: h, height: u, value: s.vertical ? u : h } }, calcRenderMatrix: function (e) { var t = [this.fontSize * this.textHScale, 0, 0, this.fontSize, 0, this.textRise]; return r.Util.transform(e, r.Util.transform(this.textMatrix, t)) }, carriageReturn: function () { this.translateTextLineMatrix(0, -this.leading); this.textMatrix = this.textLineMatrix.slice() }, clone: function () { var e = Object.create(this); e.textMatrix = this.textMatrix.slice(); e.textLineMatrix = this.textLineMatrix.slice(); e.fontMatrix = this.fontMatrix.slice(); return e } }; return e }(), T = function () { function e() { this.ctm = new Float32Array(r.IDENTITY_MATRIX); this.font = null; this.textRenderingMode = r.TextRenderingMode.FILL; this.fillColorSpace = g.ColorSpace.singletons.gray; this.strokeColorSpace = g.ColorSpace.singletons.gray } e.prototype = { clone: function () { return Object.create(this) } }; return e }(), E = function () { var e = (0, c.getLookupTableFactory)((function (e) { e.w = { id: r.OPS.setLineWidth, numArgs: 1, variableArgs: !1 }; e.J = { id: r.OPS.setLineCap, numArgs: 1, variableArgs: !1 }; e.j = { id: r.OPS.setLineJoin, numArgs: 1, variableArgs: !1 }; e.M = { id: r.OPS.setMiterLimit, numArgs: 1, variableArgs: !1 }; e.d = { id: r.OPS.setDash, numArgs: 2, variableArgs: !1 }; e.ri = { id: r.OPS.setRenderingIntent, numArgs: 1, variableArgs: !1 }; e.i = { id: r.OPS.setFlatness, numArgs: 1, variableArgs: !1 }; e.gs = { id: r.OPS.setGState, numArgs: 1, variableArgs: !1 }; e.q = { id: r.OPS.save, numArgs: 0, variableArgs: !1 }; e.Q = { id: r.OPS.restore, numArgs: 0, variableArgs: !1 }; e.cm = { id: r.OPS.transform, numArgs: 6, variableArgs: !1 }; e.m = { id: r.OPS.moveTo, numArgs: 2, variableArgs: !1 }; e.l = { id: r.OPS.lineTo, numArgs: 2, variableArgs: !1 }; e.c = { id: r.OPS.curveTo, numArgs: 6, variableArgs: !1 }; e.v = { id: r.OPS.curveTo2, numArgs: 4, variableArgs: !1 }; e.y = { id: r.OPS.curveTo3, numArgs: 4, variableArgs: !1 }; e.h = { id: r.OPS.closePath, numArgs: 0, variableArgs: !1 }; e.re = { id: r.OPS.rectangle, numArgs: 4, variableArgs: !1 }; e.S = { id: r.OPS.stroke, numArgs: 0, variableArgs: !1 }; e.s = { id: r.OPS.closeStroke, numArgs: 0, variableArgs: !1 }; e.f = { id: r.OPS.fill, numArgs: 0, variableArgs: !1 }; e.F = { id: r.OPS.fill, numArgs: 0, variableArgs: !1 }; e["f*"] = { id: r.OPS.eoFill, numArgs: 0, variableArgs: !1 }; e.B = { id: r.OPS.fillStroke, numArgs: 0, variableArgs: !1 }; e["B*"] = { id: r.OPS.eoFillStroke, numArgs: 0, variableArgs: !1 }; e.b = { id: r.OPS.closeFillStroke, numArgs: 0, variableArgs: !1 }; e["b*"] = { id: r.OPS.closeEOFillStroke, numArgs: 0, variableArgs: !1 }; e.n = { id: r.OPS.endPath, numArgs: 0, variableArgs: !1 }; e.W = { id: r.OPS.clip, numArgs: 0, variableArgs: !1 }; e["W*"] = { id: r.OPS.eoClip, numArgs: 0, variableArgs: !1 }; e.BT = { id: r.OPS.beginText, numArgs: 0, variableArgs: !1 }; e.ET = { id: r.OPS.endText, numArgs: 0, variableArgs: !1 }; e.Tc = { id: r.OPS.setCharSpacing, numArgs: 1, variableArgs: !1 }; e.Tw = { id: r.OPS.setWordSpacing, numArgs: 1, variableArgs: !1 }; e.Tz = { id: r.OPS.setHScale, numArgs: 1, variableArgs: !1 }; e.TL = { id: r.OPS.setLeading, numArgs: 1, variableArgs: !1 }; e.Tf = { id: r.OPS.setFont, numArgs: 2, variableArgs: !1 }; e.Tr = { id: r.OPS.setTextRenderingMode, numArgs: 1, variableArgs: !1 }; e.Ts = { id: r.OPS.setTextRise, numArgs: 1, variableArgs: !1 }; e.Td = { id: r.OPS.moveText, numArgs: 2, variableArgs: !1 }; e.TD = { id: r.OPS.setLeadingMoveText, numArgs: 2, variableArgs: !1 }; e.Tm = { id: r.OPS.setTextMatrix, numArgs: 6, variableArgs: !1 }; e["T*"] = { id: r.OPS.nextLine, numArgs: 0, variableArgs: !1 }; e.Tj = { id: r.OPS.showText, numArgs: 1, variableArgs: !1 }; e.TJ = { id: r.OPS.showSpacedText, numArgs: 1, variableArgs: !1 }; e["'"] = { id: r.OPS.nextLineShowText, numArgs: 1, variableArgs: !1 }; e['"'] = { id: r.OPS.nextLineSetSpacingShowText, numArgs: 3, variableArgs: !1 }; e.d0 = { id: r.OPS.setCharWidth, numArgs: 2, variableArgs: !1 }; e.d1 = { id: r.OPS.setCharWidthAndBounds, numArgs: 6, variableArgs: !1 }; e.CS = { id: r.OPS.setStrokeColorSpace, numArgs: 1, variableArgs: !1 }; e.cs = { id: r.OPS.setFillColorSpace, numArgs: 1, variableArgs: !1 }; e.SC = { id: r.OPS.setStrokeColor, numArgs: 4, variableArgs: !0 }; e.SCN = { id: r.OPS.setStrokeColorN, numArgs: 33, variableArgs: !0 }; e.sc = { id: r.OPS.setFillColor, numArgs: 4, variableArgs: !0 }; e.scn = { id: r.OPS.setFillColorN, numArgs: 33, variableArgs: !0 }; e.G = { id: r.OPS.setStrokeGray, numArgs: 1, variableArgs: !1 }; e.g = { id: r.OPS.setFillGray, numArgs: 1, variableArgs: !1 }; e.RG = { id: r.OPS.setStrokeRGBColor, numArgs: 3, variableArgs: !1 }; e.rg = { id: r.OPS.setFillRGBColor, numArgs: 3, variableArgs: !1 }; e.K = { id: r.OPS.setStrokeCMYKColor, numArgs: 4, variableArgs: !1 }; e.k = { id: r.OPS.setFillCMYKColor, numArgs: 4, variableArgs: !1 }; e.sh = { id: r.OPS.shadingFill, numArgs: 1, variableArgs: !1 }; e.BI = { id: r.OPS.beginInlineImage, numArgs: 0, variableArgs: !1 }; e.ID = { id: r.OPS.beginImageData, numArgs: 0, variableArgs: !1 }; e.EI = { id: r.OPS.endInlineImage, numArgs: 1, variableArgs: !1 }; e.Do = { id: r.OPS.paintXObject, numArgs: 1, variableArgs: !1 }; e.MP = { id: r.OPS.markPoint, numArgs: 1, variableArgs: !1 }; e.DP = { id: r.OPS.markPointProps, numArgs: 2, variableArgs: !1 }; e.BMC = { id: r.OPS.beginMarkedContent, numArgs: 1, variableArgs: !1 }; e.BDC = { id: r.OPS.beginMarkedContentProps, numArgs: 2, variableArgs: !1 }; e.EMC = { id: r.OPS.endMarkedContent, numArgs: 0, variableArgs: !1 }; e.BX = { id: r.OPS.beginCompat, numArgs: 0, variableArgs: !1 }; e.EX = { id: r.OPS.endCompat, numArgs: 0, variableArgs: !1 }; e.BM = null; e.BD = null; e.true = null; e.fa = null; e.fal = null; e.fals = null; e.false = null; e.nu = null; e.nul = null; e.null = null })); function t(t, a, r) { this.opMap = e(); this.parser = new d.Parser({ lexer: new d.Lexer(t, this.opMap), xref: a }); this.stateManager = r; this.nonProcessedArgs = []; this._numInvalidPathOPS = 0 } t.prototype = { get savedStatesDepth() { return this.stateManager.stateStack.length }, read: function (e) { for (var t = e.args; ;) { var a = this.parser.getObj(); if (a instanceof n.Cmd) { var i = a.cmd, s = this.opMap[i]; if (!s) { (0, r.warn)(`Unknown command "${i}".`); continue } var o = s.id, c = s.numArgs, l = null !== t ? t.length : 0; if (s.variableArgs) l > c && (0, r.info)(`Command ${i}: expected [0, ${c}] args, ` + `but received ${l} args.`); else { if (l !== c) { for (var h = this.nonProcessedArgs; l > c;) { h.push(t.shift()); l-- } for (; l < c && 0 !== h.length;) { null === t && (t = []); t.unshift(h.pop()); l++ } } if (l < c) { const e = `command ${i}: expected ${c} args, ` + `but received ${l} args.`; if (o >= r.OPS.moveTo && o <= r.OPS.endPath && ++this._numInvalidPathOPS > 20) throw new r.FormatError(`Invalid ${e}`); (0, r.warn)(`Skipping ${e}`); null !== t && (t.length = 0); continue } } this.preprocessCommand(o, t); e.fn = o; e.args = t; return !0 } if (a === n.EOF) return !1; if (null !== a) { null === t && (t = []); t.push(a); if (t.length > 33) throw new r.FormatError("Too many arguments") } } }, preprocessCommand: function (e, t) { switch (0 | e) { case r.OPS.save: this.stateManager.save(); break; case r.OPS.restore: this.stateManager.restore(); break; case r.OPS.transform: this.stateManager.transform(t) } } }; return t }() }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.CMapFactory = t.IdentityCMap = t.CMap = void 0; var r = a(2), i = a(4), n = a(10), s = a(7), o = a(11), c = ["Adobe-GB1-UCS2", "Adobe-CNS1-UCS2", "Adobe-Japan1-UCS2", "Adobe-Korea1-UCS2", "78-EUC-H", "78-EUC-V", "78-H", "78-RKSJ-H", "78-RKSJ-V", "78-V", "78ms-RKSJ-H", "78ms-RKSJ-V", "83pv-RKSJ-H", "90ms-RKSJ-H", "90ms-RKSJ-V", "90msp-RKSJ-H", "90msp-RKSJ-V", "90pv-RKSJ-H", "90pv-RKSJ-V", "Add-H", "Add-RKSJ-H", "Add-RKSJ-V", "Add-V", "Adobe-CNS1-0", "Adobe-CNS1-1", "Adobe-CNS1-2", "Adobe-CNS1-3", "Adobe-CNS1-4", "Adobe-CNS1-5", "Adobe-CNS1-6", "Adobe-GB1-0", "Adobe-GB1-1", "Adobe-GB1-2", "Adobe-GB1-3", "Adobe-GB1-4", "Adobe-GB1-5", "Adobe-Japan1-0", "Adobe-Japan1-1", "Adobe-Japan1-2", "Adobe-Japan1-3", "Adobe-Japan1-4", "Adobe-Japan1-5", "Adobe-Japan1-6", "Adobe-Korea1-0", "Adobe-Korea1-1", "Adobe-Korea1-2", "B5-H", "B5-V", "B5pc-H", "B5pc-V", "CNS-EUC-H", "CNS-EUC-V", "CNS1-H", "CNS1-V", "CNS2-H", "CNS2-V", "ETHK-B5-H", "ETHK-B5-V", "ETen-B5-H", "ETen-B5-V", "ETenms-B5-H", "ETenms-B5-V", "EUC-H", "EUC-V", "Ext-H", "Ext-RKSJ-H", "Ext-RKSJ-V", "Ext-V", "GB-EUC-H", "GB-EUC-V", "GB-H", "GB-V", "GBK-EUC-H", "GBK-EUC-V", "GBK2K-H", "GBK2K-V", "GBKp-EUC-H", "GBKp-EUC-V", "GBT-EUC-H", "GBT-EUC-V", "GBT-H", "GBT-V", "GBTpc-EUC-H", "GBTpc-EUC-V", "GBpc-EUC-H", "GBpc-EUC-V", "H", "HKdla-B5-H", "HKdla-B5-V", "HKdlb-B5-H", "HKdlb-B5-V", "HKgccs-B5-H", "HKgccs-B5-V", "HKm314-B5-H", "HKm314-B5-V", "HKm471-B5-H", "HKm471-B5-V", "HKscs-B5-H", "HKscs-B5-V", "Hankaku", "Hiragana", "KSC-EUC-H", "KSC-EUC-V", "KSC-H", "KSC-Johab-H", "KSC-Johab-V", "KSC-V", "KSCms-UHC-H", "KSCms-UHC-HW-H", "KSCms-UHC-HW-V", "KSCms-UHC-V", "KSCpc-EUC-H", "KSCpc-EUC-V", "Katakana", "NWP-H", "NWP-V", "RKSJ-H", "RKSJ-V", "Roman", "UniCNS-UCS2-H", "UniCNS-UCS2-V", "UniCNS-UTF16-H", "UniCNS-UTF16-V", "UniCNS-UTF32-H", "UniCNS-UTF32-V", "UniCNS-UTF8-H", "UniCNS-UTF8-V", "UniGB-UCS2-H", "UniGB-UCS2-V", "UniGB-UTF16-H", "UniGB-UTF16-V", "UniGB-UTF32-H", "UniGB-UTF32-V", "UniGB-UTF8-H", "UniGB-UTF8-V", "UniJIS-UCS2-H", "UniJIS-UCS2-HW-H", "UniJIS-UCS2-HW-V", "UniJIS-UCS2-V", "UniJIS-UTF16-H", "UniJIS-UTF16-V", "UniJIS-UTF32-H", "UniJIS-UTF32-V", "UniJIS-UTF8-H", "UniJIS-UTF8-V", "UniJIS2004-UTF16-H", "UniJIS2004-UTF16-V", "UniJIS2004-UTF32-H", "UniJIS2004-UTF32-V", "UniJIS2004-UTF8-H", "UniJIS2004-UTF8-V", "UniJISPro-UCS2-HW-V", "UniJISPro-UCS2-V", "UniJISPro-UTF8-V", "UniJISX0213-UTF32-H", "UniJISX0213-UTF32-V", "UniJISX02132004-UTF32-H", "UniJISX02132004-UTF32-V", "UniKS-UCS2-H", "UniKS-UCS2-V", "UniKS-UTF16-H", "UniKS-UTF16-V", "UniKS-UTF32-H", "UniKS-UTF32-V", "UniKS-UTF8-H", "UniKS-UTF8-V", "V", "WP-Symbol"]; class l { constructor(e = !1) { this.codespaceRanges = [[], [], [], []]; this.numCodespaceRanges = 0; this._map = []; this.name = ""; this.vertical = !1; this.useCMap = null; this.builtInCMap = e } addCodespaceRange(e, t, a) { this.codespaceRanges[e - 1].push(t, a); this.numCodespaceRanges++ } mapCidRange(e, t, a) { for (; e <= t;)this._map[e++] = a++ } mapBfRange(e, t, a) { for (var r = a.length - 1; e <= t;) { this._map[e++] = a; a = a.substring(0, r) + String.fromCharCode(a.charCodeAt(r) + 1) } } mapBfRangeToArray(e, t, a) { const r = a.length; let i = 0; for (; e <= t && i < r;) { this._map[e] = a[i++]; ++e } } mapOne(e, t) { this._map[e] = t } lookup(e) { return this._map[e] } contains(e) { return void 0 !== this._map[e] } forEach(e) { const t = this._map, a = t.length; if (a <= 65536) for (let r = 0; r < a; r++)void 0 !== t[r] && e(r, t[r]); else for (const a in t) e(a, t[a]) } charCodeOf(e) { const t = this._map; if (t.length <= 65536) return t.indexOf(e); for (const a in t) if (t[a] === e) return 0 | a; return -1 } getMap() { return this._map } readCharCode(e, t, a) { let r = 0; const i = this.codespaceRanges; for (let n = 0, s = i.length; n < s; n++) { r = (r << 8 | e.charCodeAt(t + n)) >>> 0; const s = i[n]; for (let e = 0, t = s.length; e < t;) { const t = s[e++], i = s[e++]; if (r >= t && r <= i) { a.charcode = r; a.length = n + 1; return } } } a.charcode = 0; a.length = 1 } get length() { return this._map.length } get isIdentityCMap() { if ("Identity-H" !== this.name && "Identity-V" !== this.name) return !1; if (65536 !== this._map.length) return !1; for (let e = 0; e < 65536; e++)if (this._map[e] !== e) return !1; return !0 } } t.CMap = l; class h extends l { constructor(e, t) { super(); this.vertical = e; this.addCodespaceRange(t, 0, 65535) } mapCidRange(e, t, a) { (0, r.unreachable)("should not call mapCidRange") } mapBfRange(e, t, a) { (0, r.unreachable)("should not call mapBfRange") } mapBfRangeToArray(e, t, a) { (0, r.unreachable)("should not call mapBfRangeToArray") } mapOne(e, t) { (0, r.unreachable)("should not call mapCidOne") } lookup(e) { return Number.isInteger(e) && e <= 65535 ? e : void 0 } contains(e) { return Number.isInteger(e) && e <= 65535 } forEach(e) { for (let t = 0; t <= 65535; t++)e(t, t) } charCodeOf(e) { return Number.isInteger(e) && e <= 65535 ? e : -1 } getMap() { const e = new Array(65536); for (let t = 0; t <= 65535; t++)e[t] = t; return e } get length() { return 65536 } get isIdentityCMap() { (0, r.unreachable)("should not access .isIdentityCMap") } } t.IdentityCMap = h; var u = function () { function e(e, t) { for (var a = 0, r = 0; r <= t; r++)a = a << 8 | e[r]; return a >>> 0 } function t(e, t) { return 1 === t ? String.fromCharCode(e[0], e[1]) : 3 === t ? String.fromCharCode(e[0], e[1], e[2], e[3]) : String.fromCharCode.apply(null, e.subarray(0, t + 1)) } function a(e, t, a) { for (var r = 0, i = a; i >= 0; i--) { r += e[i] + t[i]; e[i] = 255 & r; r >>= 8 } } function i(e, t) { for (var a = 1, r = t; r >= 0 && a > 0; r--) { a += e[r]; e[r] = 255 & a; a >>= 8 } } function n(e) { this.buffer = e; this.pos = 0; this.end = e.length; this.tmpBuf = new Uint8Array(19) } n.prototype = { readByte() { return this.pos >= this.end ? -1 : this.buffer[this.pos++] }, readNumber() { var e, t = 0; do { var a = this.readByte(); if (a < 0) throw new r.FormatError("unexpected EOF in bcmap"); e = !(128 & a); t = t << 7 | 127 & a } while (!e); return t }, readSigned() { var e = this.readNumber(); return 1 & e ? ~(e >>> 1) : e >>> 1 }, readHex(e, t) { e.set(this.buffer.subarray(this.pos, this.pos + t + 1)); this.pos += t + 1 }, readHexNumber(e, t) { var a, i = this.tmpBuf, n = 0; do { var s = this.readByte(); if (s < 0) throw new r.FormatError("unexpected EOF in bcmap"); a = !(128 & s); i[n++] = 127 & s } while (!a); for (var o = t, c = 0, l = 0; o >= 0;) { for (; l < 8 && i.length > 0;) { c = i[--n] << l | c; l += 7 } e[o] = 255 & c; o--; c >>= 8; l -= 8 } }, readHexSigned(e, t) { this.readHexNumber(e, t); for (var a = 1 & e[t] ? 255 : 0, r = 0, i = 0; i <= t; i++) { r = (1 & r) << 8 | e[i]; e[i] = r >> 1 ^ a } }, readString() { for (var e = this.readNumber(), t = "", a = 0; a < e; a++)t += String.fromCharCode(this.readNumber()); return t } }; function s() { } s.prototype = { process: function (r, s, o) { return new Promise((function (c, l) { var h = new n(r), u = h.readByte(); s.vertical = !!(1 & u); for (var d, f, g = null, m = new Uint8Array(16), p = new Uint8Array(16), b = new Uint8Array(16), y = new Uint8Array(16), v = new Uint8Array(16); (f = h.readByte()) >= 0;) { var w = f >> 5; if (7 !== w) { var k = !!(16 & f), S = 15 & f; if (S + 1 > 16) throw new Error("processBinaryCMap: Invalid dataSize."); var C, x = h.readNumber(); switch (w) { case 0: h.readHex(m, S); h.readHexNumber(p, S); a(p, m, S); s.addCodespaceRange(S + 1, e(m, S), e(p, S)); for (C = 1; C < x; C++) { i(p, S); h.readHexNumber(m, S); a(m, p, S); h.readHexNumber(p, S); a(p, m, S); s.addCodespaceRange(S + 1, e(m, S), e(p, S)) } break; case 1: h.readHex(m, S); h.readHexNumber(p, S); a(p, m, S); h.readNumber(); for (C = 1; C < x; C++) { i(p, S); h.readHexNumber(m, S); a(m, p, S); h.readHexNumber(p, S); a(p, m, S); h.readNumber() } break; case 2: h.readHex(b, S); d = h.readNumber(); s.mapOne(e(b, S), d); for (C = 1; C < x; C++) { i(b, S); if (!k) { h.readHexNumber(v, S); a(b, v, S) } d = h.readSigned() + (d + 1); s.mapOne(e(b, S), d) } break; case 3: h.readHex(m, S); h.readHexNumber(p, S); a(p, m, S); d = h.readNumber(); s.mapCidRange(e(m, S), e(p, S), d); for (C = 1; C < x; C++) { i(p, S); if (k) m.set(p); else { h.readHexNumber(m, S); a(m, p, S) } h.readHexNumber(p, S); a(p, m, S); d = h.readNumber(); s.mapCidRange(e(m, S), e(p, S), d) } break; case 4: h.readHex(b, 1); h.readHex(y, S); s.mapOne(e(b, 1), t(y, S)); for (C = 1; C < x; C++) { i(b, 1); if (!k) { h.readHexNumber(v, 1); a(b, v, 1) } i(y, S); h.readHexSigned(v, S); a(y, v, S); s.mapOne(e(b, 1), t(y, S)) } break; case 5: h.readHex(m, 1); h.readHexNumber(p, 1); a(p, m, 1); h.readHex(y, S); s.mapBfRange(e(m, 1), e(p, 1), t(y, S)); for (C = 1; C < x; C++) { i(p, 1); if (k) m.set(p); else { h.readHexNumber(m, 1); a(m, p, 1) } h.readHexNumber(p, 1); a(p, m, 1); h.readHex(y, S); s.mapBfRange(e(m, 1), e(p, 1), t(y, S)) } break; default: l(new Error("processBinaryCMap: Unknown type: " + w)); return } } else switch (31 & f) { case 0: h.readString(); break; case 1: g = h.readString() } } c(g ? o(g) : s) })) } }; return s }(), d = function () { function e(e) { for (var t = 0, a = 0; a < e.length; a++)t = t << 8 | e.charCodeAt(a); return t >>> 0 } function t(e) { if (!(0, r.isString)(e)) throw new r.FormatError("Malformed CMap: expected string.") } function a(e) { if (!Number.isInteger(e)) throw new r.FormatError("Malformed CMap: expected int.") } function d(a, r) { for (; ;) { var n = r.getObj(); if ((0, i.isEOF)(n)) break; if ((0, i.isCmd)(n, "endbfchar")) return; t(n); var s = e(n); t(n = r.getObj()); var o = n; a.mapOne(s, o) } } function f(a, n) { for (; ;) { var s = n.getObj(); if ((0, i.isEOF)(s)) break; if ((0, i.isCmd)(s, "endbfrange")) return; t(s); var o = e(s); t(s = n.getObj()); var c = e(s); s = n.getObj(); if (Number.isInteger(s) || (0, r.isString)(s)) { var l = Number.isInteger(s) ? String.fromCharCode(s) : s; a.mapBfRange(o, c, l) } else { if (!(0, i.isCmd)(s, "[")) break; s = n.getObj(); for (var h = []; !(0, i.isCmd)(s, "]") && !(0, i.isEOF)(s);) { h.push(s); s = n.getObj() } a.mapBfRangeToArray(o, c, h) } } throw new r.FormatError("Invalid bf range.") } function g(r, n) { for (; ;) { var s = n.getObj(); if ((0, i.isEOF)(s)) break; if ((0, i.isCmd)(s, "endcidchar")) return; t(s); var o = e(s); a(s = n.getObj()); var c = s; r.mapOne(o, c) } } function m(r, n) { for (; ;) { var s = n.getObj(); if ((0, i.isEOF)(s)) break; if ((0, i.isCmd)(s, "endcidrange")) return; t(s); var o = e(s); t(s = n.getObj()); var c = e(s); a(s = n.getObj()); var l = s; r.mapCidRange(o, c, l) } } function p(t, a) { for (; ;) { var n = a.getObj(); if ((0, i.isEOF)(n)) break; if ((0, i.isCmd)(n, "endcodespacerange")) return; if (!(0, r.isString)(n)) break; var s = e(n); n = a.getObj(); if (!(0, r.isString)(n)) break; var o = e(n); t.addCodespaceRange(n.length, s, o) } throw new r.FormatError("Invalid codespace range.") } function b(e, t) { var a = t.getObj(); Number.isInteger(a) && (e.vertical = !!a) } function y(e, t) { var a = t.getObj(); (0, i.isName)(a) && (0, r.isString)(a.name) && (e.name = a.name) } function v(e, t, a, n) { var o, c; e: for (; ;)try { var l = t.getObj(); if ((0, i.isEOF)(l)) break; if ((0, i.isName)(l)) { "WMode" === l.name ? b(e, t) : "CMapName" === l.name && y(e, t); o = l } else if ((0, i.isCmd)(l)) switch (l.cmd) { case "endcmap": break e; case "usecmap": (0, i.isName)(o) && (c = o.name); break; case "begincodespacerange": p(e, t); break; case "beginbfchar": d(e, t); break; case "begincidchar": g(e, t); break; case "beginbfrange": f(e, t); break; case "begincidrange": m(e, t) } } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)("Invalid cMap data: " + e); continue } !n && c && (n = c); return n ? w(e, a, n) : Promise.resolve(e) } function w(e, t, a) { return k(a, t).then((function (t) { e.useCMap = t; if (0 === e.numCodespaceRanges) { for (var a = e.useCMap.codespaceRanges, r = 0; r < a.length; r++)e.codespaceRanges[r] = a[r].slice(); e.numCodespaceRanges = e.useCMap.numCodespaceRanges } e.useCMap.forEach((function (t, a) { e.contains(t) || e.mapOne(t, e.useCMap.lookup(t)) })); return e })) } function k(e, t) { return "Identity-H" === e ? Promise.resolve(new h(!1, 2)) : "Identity-V" === e ? Promise.resolve(new h(!0, 2)) : c.includes(e) ? t ? t(e).then((function (e) { var a = e.cMapData, i = e.compressionType, s = new l(!0); if (i === r.CMapCompressionType.BINARY) return (new u).process(a, s, (function (e) { return w(s, t, e) })); if (i === r.CMapCompressionType.NONE) { var c = new n.Lexer(new o.Stream(a)); return v(s, c, t, null) } return Promise.reject(new Error("TODO: Only BINARY/NONE CMap compression is currently supported.")) })) : Promise.reject(new Error("Built-in CMap parameters are not provided.")) : Promise.reject(new Error("Unknown CMap name: " + e)) } return { async create(e) { var t = e.encoding, a = e.fetchBuiltInCMap, r = e.useCMap; if ((0, i.isName)(t)) return k(t.name, a); if ((0, i.isStream)(t)) { return v(new l, new n.Lexer(t), a, r).then((function (e) { return e.isIdentityCMap ? k(e.name, a) : e })) } throw new Error("Encoding required.") } } }(); t.CMapFactory = d }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getFontType = y; t.IdentityToUnicodeMap = t.ToUnicodeMap = t.FontFlags = t.Font = t.ErrorFont = t.SEAC_ANALYSIS_ENABLED = void 0; var r = a(2), i = a(28), n = a(31), s = a(30), o = a(32), c = a(33), l = a(7), h = a(34), u = a(26), d = a(11), f = a(35); const g = [[57344, 63743], [1048576, 1114109]]; t.SEAC_ANALYSIS_ENABLED = !0; var m = { FixedPitch: 1, Serif: 2, Symbolic: 4, Script: 8, Nonsymbolic: 32, Italic: 64, AllCap: 65536, SmallCap: 131072, ForceBold: 262144 }; t.FontFlags = m; var p = [".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron", "dcroat"]; function b(e) { if (e.fontMatrix && e.fontMatrix[0] !== r.FONT_IDENTITY_MATRIX[0]) { var t = .001 / e.fontMatrix[0], a = e.widths; for (var i in a) a[i] *= t; e.defaultWidth *= t } } function y(e, t) { switch (e) { case "Type1": return "Type1C" === t ? r.FontType.TYPE1C : r.FontType.TYPE1; case "CIDFontType0": return "CIDFontType0C" === t ? r.FontType.CIDFONTTYPE0C : r.FontType.CIDFONTTYPE0; case "OpenType": return r.FontType.OPENTYPE; case "TrueType": return r.FontType.TRUETYPE; case "CIDFontType2": return r.FontType.CIDFONTTYPE2; case "MMType1": return r.FontType.MMTYPE1; case "Type0": return r.FontType.TYPE0; default: return r.FontType.UNKNOWN } } function v(e, t) { if (void 0 !== t[e]) return e; var a = (0, c.getUnicodeForGlyph)(e, t); if (-1 !== a) for (var i in t) if (t[i] === a) return i; (0, r.info)("Unable to recover a standard glyph name for: " + e); return e } var w = function () { function e(e, t, a, r, i, n, s, o) { this.fontChar = e; this.unicode = t; this.accent = a; this.width = r; this.vmetric = i; this.operatorListId = n; this.isSpace = s; this.isInFont = o } e.prototype.matchesForCache = function (e, t, a, r, i, n, s, o) { return this.fontChar === e && this.unicode === t && this.accent === a && this.width === r && this.vmetric === i && this.operatorListId === n && this.isSpace === s && this.isInFont === o }; return e }(), k = function () { function e(e = []) { this._map = e } e.prototype = { get length() { return this._map.length }, forEach(e) { for (var t in this._map) e(t, this._map[t].charCodeAt(0)) }, has(e) { return void 0 !== this._map[e] }, get(e) { return this._map[e] }, charCodeOf(e) { const t = this._map; if (t.length <= 65536) return t.indexOf(e); for (const a in t) if (t[a] === e) return 0 | a; return -1 }, amend(e) { for (var t in e) this._map[t] = e[t] } }; return e }(); t.ToUnicodeMap = k; var S = function () { function e(e, t) { this.firstChar = e; this.lastChar = t } e.prototype = { get length() { return this.lastChar + 1 - this.firstChar }, forEach(e) { for (var t = this.firstChar, a = this.lastChar; t <= a; t++)e(t, t) }, has(e) { return this.firstChar <= e && e <= this.lastChar }, get(e) { if (this.firstChar <= e && e <= this.lastChar) return String.fromCharCode(e) }, charCodeOf(e) { return Number.isInteger(e) && e >= this.firstChar && e <= this.lastChar ? e : -1 }, amend(e) { (0, r.unreachable)("Should not call amend()") } }; return e }(); t.IdentityToUnicodeMap = S; var C = function () { function e(e, t, a) { e[t] = a >> 8 & 255; e[t + 1] = 255 & a } function t(e, t, a) { e[t] = a >> 24 & 255; e[t + 1] = a >> 16 & 255; e[t + 2] = a >> 8 & 255; e[t + 3] = 255 & a } function a(e, t, a) { var r, i; if (a instanceof Uint8Array) e.set(a, t); else if ("string" == typeof a) for (r = 0, i = a.length; r < i; r++)e[t++] = 255 & a.charCodeAt(r); else for (r = 0, i = a.length; r < i; r++)e[t++] = 255 & a[r] } function i(e) { this.sfnt = e; this.tables = Object.create(null) } i.getSearchParams = function (e, t) { for (var a = 1, r = 0; (a ^ e) > a;) { a <<= 1; r++ } var i = a * t; return { range: i, entry: r, rangeShift: t * e - i } }; i.prototype = { toArray: function () { var n = this.sfnt, s = this.tables, o = Object.keys(s); o.sort(); var c, h, u, d, f, g = o.length, m = 12 + 16 * g, p = [m]; for (c = 0; c < g; c++) { m += ((d = s[o[c]]).length + 3 & -4) >>> 0; p.push(m) } var b = new Uint8Array(m); for (c = 0; c < g; c++) { d = s[o[c]]; a(b, p[c], d) } "true" === n && (n = (0, r.string32)(65536)); b[0] = 255 & n.charCodeAt(0); b[1] = 255 & n.charCodeAt(1); b[2] = 255 & n.charCodeAt(2); b[3] = 255 & n.charCodeAt(3); e(b, 4, g); var y = i.getSearchParams(g, 16); e(b, 6, y.range); e(b, 8, y.entry); e(b, 10, y.rangeShift); m = 12; for (c = 0; c < g; c++) { f = o[c]; b[m] = 255 & f.charCodeAt(0); b[m + 1] = 255 & f.charCodeAt(1); b[m + 2] = 255 & f.charCodeAt(2); b[m + 3] = 255 & f.charCodeAt(3); var v = 0; for (h = p[c], u = p[c + 1]; h < u; h += 4) { v = v + (0, l.readUint32)(b, h) >>> 0 } t(b, m + 4, v); t(b, m + 8, p[c]); t(b, m + 12, s[f].length); m += 16 } return b }, addTable: function (e, t) { if (e in this.tables) throw new Error("Table " + e + " already exists"); this.tables[e] = t } }; return i }(), x = function () { function e(e, t, a) { var i; this.name = e; this.loadedName = a.loadedName; this.isType3Font = a.isType3Font; this.sizes = []; this.missingFile = !1; this.glyphCache = Object.create(null); this.isSerifFont = !!(a.flags & m.Serif); this.isSymbolicFont = !!(a.flags & m.Symbolic); this.isMonospace = !!(a.flags & m.FixedPitch); var n = a.type, s = a.subtype; this.type = n; this.subtype = s; let o = "sans-serif"; this.isMonospace ? o = "monospace" : this.isSerifFont && (o = "serif"); this.fallbackName = o; this.differences = a.differences; this.widths = a.widths; this.defaultWidth = a.defaultWidth; this.composite = a.composite; this.wideChars = a.wideChars; this.cMap = a.cMap; this.ascent = a.ascent / 1e3; this.descent = a.descent / 1e3; this.fontMatrix = a.fontMatrix; this.bbox = a.bbox; this.defaultEncoding = a.defaultEncoding; this.toUnicode = a.toUnicode; this.fallbackToUnicode = a.fallbackToUnicode || new k; this.toFontChar = []; if ("Type3" !== a.type) { this.cidEncoding = a.cidEncoding; this.vertical = a.vertical; if (this.vertical) { this.vmetrics = a.vmetrics; this.defaultVMetrics = a.defaultVMetrics } if (t && !t.isEmpty) { [n, s] = function (e, { type: t, subtype: a, composite: i }) { let n, s; if (function (e) { var t = e.peekBytes(4); return 65536 === (0, l.readUint32)(t, 0) || "true" === (0, r.bytesToString)(t) }(e) || I(e)) n = i ? "CIDFontType2" : "TrueType"; else if (function (e) { var t = e.peekBytes(4); return "OTTO" === (0, r.bytesToString)(t) }(e)) n = i ? "CIDFontType2" : "OpenType"; else if (function (e) { var t = e.peekBytes(2); if (37 === t[0] && 33 === t[1]) return !0; if (128 === t[0] && 1 === t[1]) return !0; return !1 }(e)) n = i ? "CIDFontType0" : "MMType1" === t ? "MMType1" : "Type1"; else if (function (e) { const t = e.peekBytes(4); if (t[0] >= 1 && t[3] >= 1 && t[3] <= 4) return !0; return !1 }(e)) if (i) { n = "CIDFontType0"; s = "CIDFontType0C" } else { n = "MMType1" === t ? "MMType1" : "Type1"; s = "Type1C" } else { (0, r.warn)("getFontFileType: Unable to detect correct font file Type/Subtype."); n = t; s = a } return [n, s] }(t, a); n === this.type && s === this.subtype || (0, r.info)("Inconsistent font file Type/SubType, expected: " + `${this.type}/${this.subtype} but found: ${n}/${s}.`); try { var c; switch (n) { case "MMType1": (0, r.info)("MMType1 font (" + e + "), falling back to Type1."); case "Type1": case "CIDFontType0": this.mimetype = "font/opentype"; var h = "Type1C" === s || "CIDFontType0C" === s ? new T(t, a) : new F(e, t, a); b(a); c = this.convert(e, h, a); break; case "OpenType": case "TrueType": case "CIDFontType2": this.mimetype = "font/opentype"; c = this.checkAndRepair(e, t, a); if (this.isOpenType) { b(a); n = "OpenType" } break; default: throw new r.FormatError(`Font ${n} is not supported`) } } catch (e) { (0, r.warn)(e); this.fallbackToSystemFont(); return } this.data = c; this.fontType = y(n, s); this.fontMatrix = a.fontMatrix; this.widths = a.widths; this.defaultWidth = a.defaultWidth; this.toUnicode = a.toUnicode; this.encoding = a.baseEncoding; this.seacMap = a.seacMap } else { t && (0, r.warn)('Font file is empty in "' + e + '" (' + this.loadedName + ")"); this.fallbackToSystemFont() } } else { for (i = 0; i < 256; i++)this.toFontChar[i] = this.differences[i] || a.defaultEncoding[i]; this.fontType = r.FontType.TYPE3 } } e.getFontID = (t = 1, function () { return String(t++) }); var t; function a(e, t) { return (e << 8) + t } function f(e, t) { var a = (e << 8) + t; return 32768 & a ? a - 65536 : a } function x(e) { return String.fromCharCode(e >> 8 & 255, 255 & e) } function A(e) { e > 32767 ? e = 32767 : e < -32768 && (e = -32768); return String.fromCharCode(e >> 8 & 255, 255 & e) } function I(e) { const t = e.peekBytes(4); return "ttcf" === (0, r.bytesToString)(t) } function E(e, t, a) { for (var r, i = [], n = 0, s = e.length; n < s; n++)-1 !== (r = (0, c.getUnicodeForGlyph)(e[n], t)) && (i[n] = r); for (var o in a) -1 !== (r = (0, c.getUnicodeForGlyph)(a[o], t)) && (i[+o] = r); return i } function O(e, t, a) { var i = Object.create(null), n = [], s = 0, o = g[s][0], c = g[s][1]; for (var l in e) { var h = e[l |= 0]; if (t(h)) { if (o > c) { if (++s >= g.length) { (0, r.warn)("Ran out of space in font private use area."); break } o = g[s][0]; c = g[s][1] } var u = o++; 0 === h && (h = a); i[u] = h; n[l] = u } } return { toFontChar: n, charCodeToGlyphId: i, nextAvailableFontCharCode: o } } function P(e, t) { var a, i, n, s, o = function (e, t) { var a = []; for (var r in e) e[r] >= t || a.push({ fontCharCode: 0 | r, glyphId: e[r] }); 0 === a.length && a.push({ fontCharCode: 0, glyphId: 0 }); a.sort((function (e, t) { return e.fontCharCode - t.fontCharCode })); for (var i = [], n = a.length, s = 0; s < n;) { var o = a[s].fontCharCode, c = [a[s].glyphId]; ++s; for (var l = o; s < n && l + 1 === a[s].fontCharCode;) { c.push(a[s].glyphId); ++s; if (65535 === ++l) break } i.push([o, l, c]) } return i }(e, t), c = o[o.length - 1][1] > 65535 ? 2 : 1, l = "\0\0" + x(c) + "\0\0" + (0, r.string32)(4 + 8 * c); for (a = o.length - 1; a >= 0 && !(o[a][0] <= 65535); --a); var h = a + 1; o[a][0] < 65535 && 65535 === o[a][1] && (o[a][1] = 65534); var u, d, f, g, m = o[a][1] < 65535 ? 1 : 0, p = h + m, b = C.getSearchParams(p, 2), y = "", v = "", w = "", k = "", S = "", A = 0; for (a = 0, i = h; a < i; a++) { d = (u = o[a])[0]; f = u[1]; y += x(d); v += x(f); var I = !0; for (n = 1, s = (g = u[2]).length; n < s; ++n)if (g[n] !== g[n - 1] + 1) { I = !1; break } if (I) { w += x(g[0] - d & 65535); k += x(0) } else { var F = 2 * (p - a) + 2 * A; A += f - d + 1; w += x(0); k += x(F); for (n = 0, s = g.length; n < s; ++n)S += x(g[n]) } } if (m > 0) { v += "ÿÿ"; y += "ÿÿ"; w += "\0"; k += "\0\0" } var T = "\0\0" + x(2 * p) + x(b.range) + x(b.entry) + x(b.rangeShift) + v + "\0\0" + y + w + k + S, E = "", O = ""; if (c > 1) { l += "\0\0\n" + (0, r.string32)(4 + 8 * c + 4 + T.length); E = ""; for (a = 0, i = o.length; a < i; a++) { d = (u = o[a])[0]; var P = (g = u[2])[0]; for (n = 1, s = g.length; n < s; ++n)if (g[n] !== g[n - 1] + 1) { f = u[0] + n - 1; E += (0, r.string32)(d) + (0, r.string32)(f) + (0, r.string32)(P); d = f + 1; P = g[n] } E += (0, r.string32)(d) + (0, r.string32)(u[1]) + (0, r.string32)(P) } O = "\0\f\0\0" + (0, r.string32)(E.length + 16) + "\0\0\0\0" + (0, r.string32)(E.length / 12) } return l + "\0" + x(T.length + 4) + T + O + E } function B(e, t, a) { a = a || { unitsPerEm: 0, yMax: 0, yMin: 0, ascent: 0, descent: 0 }; var i = 0, n = 0, s = 0, o = 0, l = null, h = 0; if (t) { for (var u in t) { (l > (u |= 0) || !l) && (l = u); h < u && (h = u); var d = (0, c.getUnicodeRangeFor)(u); if (d < 32) i |= 1 << d; else if (d < 64) n |= 1 << d - 32; else if (d < 96) s |= 1 << d - 64; else { if (!(d < 123)) throw new r.FormatError("Unicode ranges Bits > 123 are reserved for internal usage"); o |= 1 << d - 96 } } h > 65535 && (h = 65535) } else { l = 0; h = 255 } var f = e.bbox || [0, 0, 0, 0], g = a.unitsPerEm || 1 / (e.fontMatrix || r.FONT_IDENTITY_MATRIX)[0], m = e.ascentScaled ? 1 : g / 1e3, p = a.ascent || Math.round(m * (e.ascent || f[3])), b = a.descent || Math.round(m * (e.descent || f[1])); b > 0 && e.descent > 0 && f[1] < 0 && (b = -b); var y = a.yMax || p, v = -a.yMin || -b; return "\0$ô\0\0\0Š»\0\0\0ŒŠ»\0\0ß\x001\0\0\0\0" + String.fromCharCode(e.fixedPitch ? 9 : 0) + "\0\0\0\0\0\0" + (0, r.string32)(i) + (0, r.string32)(n) + (0, r.string32)(s) + (0, r.string32)(o) + "*21*" + x(e.italicAngle ? 1 : 0) + x(l || e.firstChar) + x(h || e.lastChar) + x(p) + x(b) + "\0d" + x(y) + x(v) + "\0\0\0\0\0\0\0\0" + x(e.xHeight) + x(e.capHeight) + x(0) + x(l || e.firstChar) + "\0" } function D(e) { var t = Math.floor(65536 * e.italicAngle); return "\0\0\0" + (0, r.string32)(t) + "\0\0\0\0" + (0, r.string32)(e.fixedPitch) + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" } function N(e, t) { t || (t = [[], []]); var a, r, i, n, s, o = [t[0][0] || "Original licence", t[0][1] || e, t[0][2] || "Unknown", t[0][3] || "uniqueID", t[0][4] || e, t[0][5] || "Version 0.11", t[0][6] || "", t[0][7] || "Unknown", t[0][8] || "Unknown", t[0][9] || "Unknown"], c = []; for (a = 0, r = o.length; a < r; a++) { var l = []; for (i = 0, n = (s = t[1][a] || o[a]).length; i < n; i++)l.push(x(s.charCodeAt(i))); c.push(l.join("")) } var h = [o, c], u = ["\0", "\0"], d = ["\0\0", "\0"], f = ["\0\0", "\t"], g = o.length * u.length, m = "\0\0" + x(g) + x(12 * g + 6), p = 0; for (a = 0, r = u.length; a < r; a++) { var b = h[a]; for (i = 0, n = b.length; i < n; i++) { s = b[i]; m += u[a] + d[a] + f[a] + x(i) + x(s.length) + x(p); p += s.length } } return m += o.join("") + c.join("") } e.prototype = { name: null, font: null, mimetype: null, encoding: null, disableFontFace: !1, get renderer() { var e = h.FontRendererFactory.create(this, !0); return (0, r.shadow)(this, "renderer", e) }, exportData: function () { var e = {}; for (var t in this) this.hasOwnProperty(t) && (e[t] = this[t]); return e }, fallbackToSystemFont: function () { this.missingFile = !0; var e, t, a = this.name, i = this.type, l = this.subtype; let h = a.replace(/[,_]/g, "-").replace(/\s/g, ""); var u = (0, o.getStdFontMap)(), d = (0, o.getNonStdFontMap)(), f = !!u[h] || !(!d[h] || !u[d[h]]); h = u[h] || d[h] || h; this.bold = -1 !== h.search(/bold/gi); this.italic = -1 !== h.search(/oblique/gi) || -1 !== h.search(/italic/gi); this.black = -1 !== a.search(/Black/g); this.remeasure = Object.keys(this.widths).length > 0; if (f && "CIDFontType2" === i && this.cidEncoding.startsWith("Identity-")) { const t = (0, o.getGlyphMapForStandardFonts)(), r = []; for (e in t) r[+e] = t[e]; if (/Arial-?Black/i.test(a)) { var g = (0, o.getSupplementalGlyphMapForArialBlack)(); for (e in g) r[+e] = g[e] } else if (/Calibri/i.test(a)) { const t = (0, o.getSupplementalGlyphMapForCalibri)(); for (e in t) r[+e] = t[e] } this.toUnicode instanceof S || this.toUnicode.forEach((function (e, t) { r[+e] = t })); this.toFontChar = r; this.toUnicode = new k(r) } else if (/Symbol/i.test(h)) this.toFontChar = E(s.SymbolSetEncoding, (0, n.getGlyphsUnicode)(), this.differences); else if (/Dingbats/i.test(h)) { /Wingdings/i.test(a) && (0, r.warn)("Non-embedded Wingdings font, falling back to ZapfDingbats."); this.toFontChar = E(s.ZapfDingbatsEncoding, (0, n.getDingbatsGlyphsUnicode)(), this.differences) } else if (f) this.toFontChar = E(this.defaultEncoding, (0, n.getGlyphsUnicode)(), this.differences); else { const r = (0, n.getGlyphsUnicode)(), i = []; this.toUnicode.forEach((e, a) => { if (!this.composite) { var n = this.differences[e] || this.defaultEncoding[e]; -1 !== (t = (0, c.getUnicodeForGlyph)(n, r)) && (a = t) } i[+e] = a }); if (this.composite && this.toUnicode instanceof S && /Verdana/i.test(a)) { const t = (0, o.getGlyphMapForStandardFonts)(); for (e in t) i[+e] = t[e] } this.toFontChar = i } this.loadedName = h.split("-")[0]; this.fontType = y(i, l) }, checkAndRepair: function (e, t, o) { const c = ["OS/2", "cmap", "head", "hhea", "hmtx", "maxp", "name", "post", "loca", "glyf", "fpgm", "prep", "cvt ", "CFF "]; function l(e, a) { const r = Object.create(null); r["OS/2"] = null; r.cmap = null; r.head = null; r.hhea = null; r.hmtx = null; r.maxp = null; r.name = null; r.post = null; for (let e = 0; e < a; e++) { const e = h(t); c.includes(e.tag) && (0 !== e.length && (r[e.tag] = e)) } return r } function h(e) { var t = (0, r.bytesToString)(e.getBytes(4)), a = e.getInt32() >>> 0, i = e.getInt32() >>> 0, n = e.getInt32() >>> 0, s = e.pos; e.pos = e.start ? e.start : 0; e.skip(i); var o = e.getBytes(n); e.pos = s; if ("head" === t) { o[8] = o[9] = o[10] = o[11] = 0; o[17] |= 32 } return { tag: t, checksum: a, length: n, offset: i, data: o } } function g(e) { return { version: (0, r.bytesToString)(e.getBytes(4)), numTables: e.getUint16(), searchRange: e.getUint16(), entrySelector: e.getUint16(), rangeShift: e.getUint16() } } function m(e, t, a, r, i, n) { var s = { length: 0, sizeOfInstructions: 0 }; if (a - t <= 12) return s; var o = e.subarray(t, a), c = f(o[0], o[1]); if (c < 0) { !function (e, t, a) { e[t + 1] = a; e[t] = a >>> 8 }(o, 0, c = -1); r.set(o, i); s.length = o.length; return s } var l, h = 10, u = 0; for (l = 0; l < c; l++) { u = (o[h] << 8 | o[h + 1]) + 1; h += 2 } var d = h, g = o[h] << 8 | o[h + 1]; s.sizeOfInstructions = g; var m = h += 2 + g, p = 0; for (l = 0; l < u; l++) { var b = o[h++]; 192 & b && (o[h - 1] = 63 & b); let e = 2; 2 & b ? e = 1 : 16 & b && (e = 0); let t = 2; 4 & b ? t = 1 : 32 & b && (t = 0); const a = e + t; p += a; if (8 & b) { var y = o[h++]; l += y; p += y * a } } if (0 === p) return s; var v = h + p; if (v > o.length) return s; if (!n && g > 0) { r.set(o.subarray(0, d), i); r.set([0, 0], i + d); r.set(o.subarray(m, v), i + d + 2); v -= g; o.length - v > 3 && (v = v + 3 & -4); s.length = v; return s } if (o.length - v > 3) { v = v + 3 & -4; r.set(o.subarray(0, v), i); s.length = v; return s } r.set(o, i); s.length = o.length; return s } function y(e) { var a = (t.start ? t.start : 0) + e.offset; t.pos = a; var i = [[], []], n = e.length, s = a + n; if (0 !== t.getUint16() || n < 6) return i; var o, c, l = t.getUint16(), h = t.getUint16(), u = []; for (o = 0; o < l && t.pos + 12 <= s; o++) { var d = { platform: t.getUint16(), encoding: t.getUint16(), language: t.getUint16(), name: t.getUint16(), length: t.getUint16(), offset: t.getUint16() }; (1 === d.platform && 0 === d.encoding && 0 === d.language || 3 === d.platform && 1 === d.encoding && 1033 === d.language) && u.push(d) } for (o = 0, c = u.length; o < c; o++) { var f = u[o]; if (!(f.length <= 0)) { var g = a + h + f.offset; if (!(g + f.length > s)) { t.pos = g; var m = f.name; if (f.encoding) { for (var p = "", b = 0, y = f.length; b < y; b += 2)p += String.fromCharCode(t.getUint16()); i[1][m] = p } else i[0][m] = (0, r.bytesToString)(t.getBytes(f.length)) } } } return i } var w = [0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, 0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, 0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2]; function k(e, t) { for (var a, i, n, s, o, c = e.data, l = 0, h = 0, u = 0, d = [], f = [], g = [], m = t.tooComplexToFollowFunctions, p = !1, b = 0, y = 0, v = c.length; l < v;) { var k = c[l++]; if (64 === k) { i = c[l++]; if (p || y) l += i; else for (a = 0; a < i; a++)d.push(c[l++]) } else if (65 === k) { i = c[l++]; if (p || y) l += 2 * i; else for (a = 0; a < i; a++) { n = c[l++]; d.push(n << 8 | c[l++]) } } else if (176 == (248 & k)) { i = k - 176 + 1; if (p || y) l += i; else for (a = 0; a < i; a++)d.push(c[l++]) } else if (184 == (248 & k)) { i = k - 184 + 1; if (p || y) l += 2 * i; else for (a = 0; a < i; a++) { n = c[l++]; d.push(n << 8 | c[l++]) } } else if (43 !== k || m) if (44 !== k || m) { if (45 === k) if (p) { p = !1; h = l } else { if (!(o = f.pop())) { (0, r.warn)("TT: ENDF bad stack"); t.hintsValid = !1; return } s = g.pop(); c = o.data; l = o.i; t.functionsStackDeltas[s] = d.length - o.stackTop } else if (137 === k) { if (p || y) { (0, r.warn)("TT: nested IDEFs not allowed"); m = !0 } p = !0; u = l } else if (88 === k) ++b; else if (27 === k) y = b; else if (89 === k) { y === b && (y = 0); --b } else if (28 === k && !p && !y) { var S = d[d.length - 1]; S > 0 && (l += S - 1) } } else { if (p || y) { (0, r.warn)("TT: nested FDEFs not allowed"); m = !0 } p = !0; u = l; s = d.pop(); t.functionsDefined[s] = { data: c, i: l } } else if (!p && !y) { s = d[d.length - 1]; if (isNaN(s)) (0, r.info)("TT: CALL empty stack (or invalid entry)."); else { t.functionsUsed[s] = !0; if (s in t.functionsStackDeltas) { const e = d.length + t.functionsStackDeltas[s]; if (e < 0) { (0, r.warn)("TT: CALL invalid functions stack delta."); t.hintsValid = !1; return } d.length = e } else if (s in t.functionsDefined && !g.includes(s)) { f.push({ data: c, i: l, stackTop: d.length - 1 }); g.push(s); if (!(o = t.functionsDefined[s])) { (0, r.warn)("TT: CALL non-existent function"); t.hintsValid = !1; return } c = o.data; l = o.i } } } if (!p && !y) { let e = 0; k <= 142 ? e = w[k] : k >= 192 && k <= 223 ? e = -1 : k >= 224 && (e = -2); if (k >= 113 && k <= 117) { i = d.pop(); isNaN(i) || (e = 2 * -i) } for (; e < 0 && d.length > 0;) { d.pop(); e++ } for (; e > 0;) { d.push(NaN); e-- } } } t.tooComplexToFollowFunctions = m; var C = [c]; l > c.length && C.push(new Uint8Array(l - c.length)); if (u > h) { (0, r.warn)("TT: complementing a missing function tail"); C.push(new Uint8Array([34, 45])) } !function (e, t) { if (t.length > 1) { var a, r, i = 0; for (a = 0, r = t.length; a < r; a++)i += t[a].length; i = i + 3 & -4; var n = new Uint8Array(i), s = 0; for (a = 0, r = t.length; a < r; a++) { n.set(t[a], s); s += t[a].length } e.data = n; e.length = i } }(e, C) } let S, x, A, F; if (I(t = new d.Stream(new Uint8Array(t.getBytes())))) { const e = function (e, t) { const { numFonts: a, offsetTable: i } = function (e) { const t = (0, r.bytesToString)(e.getBytes(4)); (0, r.assert)("ttcf" === t, "Must be a TrueType Collection font."); const a = e.getUint16(), i = e.getUint16(), n = e.getInt32() >>> 0, s = []; for (let t = 0; t < n; t++)s.push(e.getInt32() >>> 0); const o = { ttcTag: t, majorVersion: a, minorVersion: i, numFonts: n, offsetTable: s }; switch (a) { case 1: return o; case 2: o.dsigTag = e.getInt32() >>> 0; o.dsigLength = e.getInt32() >>> 0; o.dsigOffset = e.getInt32() >>> 0; return o }throw new r.FormatError(`Invalid TrueType Collection majorVersion: ${a}.`) }(e); for (let n = 0; n < a; n++) { e.pos = (e.start || 0) + i[n]; const a = g(e), s = l(0, a.numTables); if (!s.name) throw new r.FormatError('TrueType Collection font must contain a "name" table.'); const o = y(s.name); for (let e = 0, r = o.length; e < r; e++)for (let r = 0, i = o[e].length; r < i; r++) { const i = o[e][r]; if (i && i.replace(/\s/g, "") === t) return { header: a, tables: s } } } throw new r.FormatError(`TrueType Collection does not contain "${t}" font.`) }(t, this.name); S = e.header; x = e.tables } else { S = g(t); x = l(0, S.numTables) } var E = !x["CFF "]; if (E) { if (!x.loca) throw new r.FormatError('Required "loca" table is not found'); if (!x.glyf) { (0, r.warn)('Required "glyf" table is not found -- trying to recover.'); x.glyf = { tag: "glyf", data: new Uint8Array(0) } } this.isOpenType = !1 } else { const t = o.composite && ((o.cidToGidMap || []).length > 0 || !(o.cMap instanceof u.IdentityCMap)); if ("OTTO" === S.version && !t || !x.head || !x.hhea || !x.maxp || !x.post) { F = new d.Stream(x["CFF "].data); A = new T(F, o); b(o); return this.convert(e, A, o) } delete x.glyf; delete x.loca; delete x.fpgm; delete x.prep; delete x["cvt "]; this.isOpenType = !0 } if (!x.maxp) throw new r.FormatError('Required "maxp" table is not found'); t.pos = (t.start || 0) + x.maxp.offset; var M = t.getInt32(); const L = t.getUint16(); let R = L + 1, U = !0; if (R > 65535) { U = !1; R = L; (0, r.warn)("Not enough space in glyfs to duplicate first glyph.") } var q = 0, j = 0; if (M >= 65536 && x.maxp.length >= 22) { t.pos += 8; if (t.getUint16() > 2) { x.maxp.data[14] = 0; x.maxp.data[15] = 2 } t.pos += 4; q = t.getUint16(); t.pos += 4; j = t.getUint16() } x.maxp.data[4] = R >> 8; x.maxp.data[5] = 255 & R; var _ = function (e, t, a, i) { var n = { functionsDefined: [], functionsUsed: [], functionsStackDeltas: [], tooComplexToFollowFunctions: !1, hintsValid: !0 }; e && k(e, n); t && k(t, n); e && function (e, t) { if (!e.tooComplexToFollowFunctions) if (e.functionsDefined.length > t) { (0, r.warn)("TT: more functions defined than expected"); e.hintsValid = !1 } else for (var a = 0, i = e.functionsUsed.length; a < i; a++) { if (a > t) { (0, r.warn)("TT: invalid function id: " + a); e.hintsValid = !1; return } if (e.functionsUsed[a] && !e.functionsDefined[a]) { (0, r.warn)("TT: undefined function: " + a); e.hintsValid = !1; return } } }(n, i); if (a && 1 & a.length) { var s = new Uint8Array(a.length + 1); s.set(a.data); a.data = s } return n.hintsValid }(x.fpgm, x.prep, x["cvt "], q); if (!_) { delete x.fpgm; delete x.prep; delete x["cvt "] } !function (e, t, a, i, n) { if (t) { e.pos = (e.start ? e.start : 0) + t.offset; e.pos += 4; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 8; e.pos += 2; var s = e.getUint16(); if (s > i) { (0, r.info)("The numOfMetrics (" + s + ") should not be greater than the numGlyphs (" + i + ")"); s = i; t.data[34] = (65280 & s) >> 8; t.data[35] = 255 & s } var o = i - s - (a.length - 4 * s >> 1); if (o > 0) { var c = new Uint8Array(a.length + 2 * o); c.set(a.data); if (n) { c[a.length] = a.data[2]; c[a.length + 1] = a.data[3] } a.data = c } } else a && (a.data = null) }(t, x.hhea, x.hmtx, R, U); if (!x.head) throw new r.FormatError('Required "head" table is not found'); !function (e, t, i) { var n, s, o, c, l = e.data, h = (n = l[0], s = l[1], o = l[2], c = l[3], (n << 24) + (s << 16) + (o << 8) + c); if (h >> 16 != 1) { (0, r.info)("Attempting to fix invalid version in head table: " + h); l[0] = 0; l[1] = 1; l[2] = 0; l[3] = 0 } var u = a(l[50], l[51]); if (u < 0 || u > 1) { (0, r.info)("Attempting to fix invalid indexToLocFormat in head table: " + u); var d = t + 1; if (i === d << 1) { l[50] = 0; l[51] = 0 } else { if (i !== d << 2) throw new r.FormatError("Could not fix indexToLocFormat: " + u); l[50] = 0; l[51] = 1 } } }(x.head, L, E ? x.loca.length : 0); var z = Object.create(null); if (E) { var H = a(x.head.data[50], x.head.data[51]), G = function (e, t, a, r, i, n, s) { var o, c, l; if (r) { o = 4; c = function (e, t) { return e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3] }; l = function (e, t, a) { e[t] = a >>> 24 & 255; e[t + 1] = a >> 16 & 255; e[t + 2] = a >> 8 & 255; e[t + 3] = 255 & a } } else { o = 2; c = function (e, t) { return e[t] << 9 | e[t + 1] << 1 }; l = function (e, t, a) { e[t] = a >> 9 & 255; e[t + 1] = a >> 1 & 255 } } var h = n ? a + 1 : a, u = o * (1 + h), d = new Uint8Array(u); d.set(e.data.subarray(0, u)); e.data = d; var f, g, p = t.data, b = p.length, y = new Uint8Array(b), v = c(d, 0), w = 0, k = Object.create(null); l(d, 0, w); for (f = 0, g = o; f < a; f++, g += o) { var S = c(d, g); 0 === S && (S = v); S > b && (b + 3 & -4) === S && (S = b); S > b && (v = S); var C = m(p, v, S, y, w, i), x = C.length; 0 === x && (k[f] = !0); C.sizeOfInstructions > s && (s = C.sizeOfInstructions); l(d, g, w += x); v = S } if (0 === w) { var A = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]); for (f = 0, g = o; f < h; f++, g += o)l(d, g, A.length); t.data = A } else if (n) { var I = c(d, o); if (y.length > I + w) t.data = y.subarray(0, I + w); else { t.data = new Uint8Array(I + w); t.data.set(y.subarray(0, w)) } t.data.set(y.subarray(0, I), w); l(e.data, d.length - o, w + I) } else t.data = y.subarray(0, w); return { missingGlyphs: k, maxSizeOfInstructions: s } }(x.loca, x.glyf, L, H, _, U, j); z = G.missingGlyphs; if (M >= 65536 && x.maxp.length >= 22) { x.maxp.data[26] = G.maxSizeOfInstructions >> 8; x.maxp.data[27] = 255 & G.maxSizeOfInstructions } } if (!x.hhea) throw new r.FormatError('Required "hhea" table is not found'); if (0 === x.hhea.data[10] && 0 === x.hhea.data[11]) { x.hhea.data[10] = 255; x.hhea.data[11] = 255 } var W = { unitsPerEm: a(x.head.data[18], x.head.data[19]), yMax: a(x.head.data[42], x.head.data[43]), yMin: f(x.head.data[38], x.head.data[39]), ascent: a(x.hhea.data[4], x.hhea.data[5]), descent: f(x.hhea.data[6], x.hhea.data[7]) }; this.ascent = W.ascent / W.unitsPerEm; this.descent = W.descent / W.unitsPerEm; x.post && function (e, a, i) { var n = (t.start ? t.start : 0) + e.offset; t.pos = n; var s, o = n + e.length, c = t.getInt32(); t.getBytes(28); var l, h = !0; switch (c) { case 65536: s = p; break; case 131072: var u = t.getUint16(); if (u !== i) { h = !1; break } var d = []; for (l = 0; l < u; ++l) { var f = t.getUint16(); if (f >= 32768) { h = !1; break } d.push(f) } if (!h) break; for (var g = [], m = []; t.pos < o;) { var b = t.getByte(); m.length = b; for (l = 0; l < b; ++l)m[l] = String.fromCharCode(t.getByte()); g.push(m.join("")) } s = []; for (l = 0; l < u; ++l) { var y = d[l]; y < 258 ? s.push(p[y]) : s.push(g[y - 258]) } break; case 196608: break; default: (0, r.warn)("Unknown/unsupported post table version " + c); h = !1; a.defaultEncoding && (s = a.defaultEncoding) }a.glyphNames = s }(x.post, o, L); x.post = { tag: "post", data: D(o) }; var X, V = []; function K(e) { return !z[e] } if (o.composite) { var Y = o.cidToGidMap || [], $ = 0 === Y.length; o.cMap.forEach((function (e, t) { if (t > 65535) throw new r.FormatError("Max size of CID is 65,535"); var a = -1; $ ? a = t : void 0 !== Y[t] && (a = Y[t]); a >= 0 && a < L && K(a) && (V[e] = a) })) } else { var J = function (e, t, a, i) { if (!e) { (0, r.warn)("No cmap table available."); return { platformId: -1, encodingId: -1, mappings: [], hasShortCmap: !1 } } var n, s = (t.start ? t.start : 0) + e.offset; t.pos = s; t.getUint16(); for (var o, c = t.getUint16(), l = !1, h = 0; h < c; h++) { var u = t.getUint16(), d = t.getUint16(), f = t.getInt32() >>> 0, g = !1; if (!o || o.platformId !== u || o.encodingId !== d) { if (0 === u && 0 === d) g = !0; else if (1 === u && 0 === d) g = !0; else if (3 !== u || 1 !== d || !i && o) { if (a && 3 === u && 0 === d) { g = !0; l = !0 } } else { g = !0; a || (l = !0) } g && (o = { platformId: u, encodingId: d, offset: f }); if (l) break } } o && (t.pos = s + o.offset); if (!o || -1 === t.peekByte()) { (0, r.warn)("Could not find a preferred cmap table."); return { platformId: -1, encodingId: -1, mappings: [], hasShortCmap: !1 } } var m = t.getUint16(); t.getUint16(); t.getUint16(); var p, b, y = !1, v = []; if (0 === m) { for (p = 0; p < 256; p++) { var w = t.getByte(); w && v.push({ charCode: p, glyphId: w }) } y = !0 } else if (4 === m) { var k = t.getUint16() >> 1; t.getBytes(6); var S, C = []; for (S = 0; S < k; S++)C.push({ end: t.getUint16() }); t.getUint16(); for (S = 0; S < k; S++)C[S].start = t.getUint16(); for (S = 0; S < k; S++)C[S].delta = t.getUint16(); var x = 0; for (S = 0; S < k; S++) { n = C[S]; var A = t.getUint16(); if (A) { var I = (A >> 1) - (k - S); n.offsetIndex = I; x = Math.max(x, I + n.end - n.start + 1) } else n.offsetIndex = -1 } var F = []; for (p = 0; p < x; p++)F.push(t.getUint16()); for (S = 0; S < k; S++) { s = (n = C[S]).start; var T = n.end, E = n.delta; I = n.offsetIndex; for (p = s; p <= T; p++)if (65535 !== p) { b = (b = I < 0 ? p : F[I + p - s]) + E & 65535; v.push({ charCode: p, glyphId: b }) } } } else { if (6 !== m) { (0, r.warn)("cmap table has unsupported format: " + m); return { platformId: -1, encodingId: -1, mappings: [], hasShortCmap: !1 } } var O = t.getUint16(), P = t.getUint16(); for (p = 0; p < P; p++) { b = t.getUint16(); var B = O + p; v.push({ charCode: B, glyphId: b }) } } v.sort((function (e, t) { return e.charCode - t.charCode })); for (h = 1; h < v.length; h++)if (v[h - 1].charCode === v[h].charCode) { v.splice(h, 1); h-- } return { platformId: o.platformId, encodingId: o.encodingId, mappings: v, hasShortCmap: y } }(x.cmap, t, this.isSymbolicFont, o.hasEncoding), Z = J.platformId, Q = J.encodingId, ee = J.mappings, te = ee.length; if (o.hasEncoding && (3 === Z && 1 === Q || 1 === Z && 0 === Q) || -1 === Z && -1 === Q && (0, s.getEncoding)(o.baseEncodingName)) { var ae = []; "MacRomanEncoding" !== o.baseEncodingName && "WinAnsiEncoding" !== o.baseEncodingName || (ae = (0, s.getEncoding)(o.baseEncodingName)); var re = (0, n.getGlyphsUnicode)(); for (X = 0; X < 256; X++) { var ie, ne; if (ie = this.differences && X in this.differences ? this.differences[X] : X in ae && "" !== ae[X] ? ae[X] : s.StandardEncoding[X]) { ne = v(ie, re); var se; 3 === Z && 1 === Q ? se = re[ne] : 1 === Z && 0 === Q && (se = s.MacRomanEncoding.indexOf(ne)); var oe = !1; for (let e = 0; e < te; ++e)if (ee[e].charCode === se) { V[X] = ee[e].glyphId; oe = !0; break } if (!oe && o.glyphNames) { var ce = o.glyphNames.indexOf(ie); -1 === ce && ne !== ie && (ce = o.glyphNames.indexOf(ne)); ce > 0 && K(ce) && (V[X] = ce) } } } } else if (0 === Z && 0 === Q) for (let e = 0; e < te; ++e)V[ee[e].charCode] = ee[e].glyphId; else for (let e = 0; e < te; ++e) { X = ee[e].charCode; 3 === Z && X >= 61440 && X <= 61695 && (X &= 255); V[X] = ee[e].glyphId } } 0 === V.length && (V[0] = 0); let le = R - 1; U || (le = 0); var he = O(V, K, le); this.toFontChar = he.toFontChar; x.cmap = { tag: "cmap", data: P(he.charCodeToGlyphId, R) }; x["OS/2"] && function (e) { var t = new d.Stream(e.data), a = t.getUint16(); t.getBytes(60); var r = t.getUint16(); if (a < 4 && 768 & r) return !1; if (t.getUint16() > t.getUint16()) return !1; t.getBytes(6); if (0 === t.getUint16()) return !1; e.data[8] = e.data[9] = 0; return !0 }(x["OS/2"]) || (x["OS/2"] = { tag: "OS/2", data: B(o, he.charCodeToGlyphId, W) }); if (!E) try { F = new d.Stream(x["CFF "].data); A = new i.CFFParser(F, o, !0).parse(); A.duplicateFirstGlyph(); var ue = new i.CFFCompiler(A); x["CFF "].data = ue.compile() } catch (e) { (0, r.warn)("Failed to compile font " + o.loadedName) } if (x.name) { var de = y(x.name); x.name.data = N(e, de) } else x.name = { tag: "name", data: N(this.name) }; var fe = new C(S.version); for (var ge in x) fe.addTable(ge, x[ge].data); return fe.toArray() }, convert: function (e, t, a) { a.fixedPitch = !1; a.builtInEncoding && function (e, t) { if (!e.hasIncludedToUnicodeMap && !(e.hasEncoding || t === e.defaultEncoding || e.toUnicode instanceof S)) { var a = [], r = (0, n.getGlyphsUnicode)(); for (var i in t) { var s = t[i], o = (0, c.getUnicodeForGlyph)(s, r); -1 !== o && (a[i] = String.fromCharCode(o)) } e.toUnicode.amend(a) } }(a, a.builtInEncoding); let i = 1; t instanceof T && (i = t.numGlyphs - 1); var o = t.getGlyphMapping(a), l = O(o, t.hasGlyphId.bind(t), i); this.toFontChar = l.toFontChar; var h = t.numGlyphs; function u(e, t) { var a = null; for (var r in e) if (t === e[r]) { a || (a = []); a.push(0 | r) } return a } function d(e, t) { for (var a in e) if (t === e[a]) return 0 | a; l.charCodeToGlyphId[l.nextAvailableFontCharCode] = t; return l.nextAvailableFontCharCode++ } var f = t.seacs; if (f && f.length) { var g = a.fontMatrix || r.FONT_IDENTITY_MATRIX, m = t.getCharset(), p = Object.create(null); for (var b in f) { var y = f[b |= 0], v = s.StandardEncoding[y[2]], w = s.StandardEncoding[y[3]], k = m.indexOf(v), I = m.indexOf(w); if (!(k < 0 || I < 0)) { var F = { x: y[0] * g[0] + y[1] * g[2] + g[4], y: y[0] * g[1] + y[1] * g[3] + g[5] }, E = u(o, b); if (E) for (var M = 0, L = E.length; M < L; M++) { var R = E[M], U = l.charCodeToGlyphId, q = d(U, k), j = d(U, I); p[R] = { baseFontCharCode: q, accentFontCharCode: j, accentOffset: F } } } } a.seacMap = p } var _ = 1 / (a.fontMatrix || r.FONT_IDENTITY_MATRIX)[0], z = new C("OTTO"); z.addTable("CFF ", t.data); z.addTable("OS/2", B(a, l.charCodeToGlyphId)); z.addTable("cmap", P(l.charCodeToGlyphId, h)); z.addTable("head", "\0\0\0\0\0\0\0\0\0\0_<õ\0\0" + A(_) + "\0\0\0\0ž\v~'\0\0\0\0ž\v~'\0\0" + A(a.descent) + "ÿ" + A(a.ascent) + x(a.italicAngle ? 2 : 0) + "\0\0\0\0\0\0\0"); z.addTable("hhea", "\0\0\0" + A(a.ascent) + A(a.descent) + "\0\0ÿÿ\0\0\0\0\0\0" + A(a.capHeight) + A(Math.tan(a.italicAngle) * a.xHeight) + "\0\0\0\0\0\0\0\0\0\0\0\0" + x(h)); z.addTable("hmtx", function () { for (var e = t.charstrings, a = t.cff ? t.cff.widths : null, r = "\0\0\0\0", i = 1, n = h; i < n; i++) { var s = 0; if (e) { var o = e[i - 1]; s = "width" in o ? o.width : 0 } else a && (s = Math.ceil(a[i] || 0)); r += x(s) + x(0) } return r }()); z.addTable("maxp", "\0\0P\0" + x(h)); z.addTable("name", N(e)); z.addTable("post", D(a)); return z.toArray() }, get spaceWidth() { if ("_shadowWidth" in this) return this._shadowWidth; for (var e, t = ["space", "minus", "one", "i", "I"], a = 0, r = t.length; a < r; a++) { var i = t[a]; if (i in this.widths) { e = this.widths[i]; break } var s = (0, n.getGlyphsUnicode)()[i], o = 0; this.composite && this.cMap.contains(s) && (o = this.cMap.lookup(s)); !o && this.toUnicode && (o = this.toUnicode.charCodeOf(s)); o <= 0 && (o = s); if (e = this.widths[o]) break } e = e || this.defaultWidth; this._shadowWidth = e; return e }, charToGlyph: function (e, t) { var a, i, n, s = e; this.cMap && this.cMap.contains(e) && (s = this.cMap.lookup(e)); i = this.widths[s]; i = (0, r.isNum)(i) ? i : this.defaultWidth; var o = this.vmetrics && this.vmetrics[s]; let l = this.toUnicode.get(e) || this.fallbackToUnicode.get(e) || e; "number" == typeof l && (l = String.fromCharCode(l)); var h = e in this.toFontChar; a = this.toFontChar[e] || e; if (this.missingFile) { const t = this.differences[e] || this.defaultEncoding[e]; ".notdef" !== t && "" !== t || "Type1" !== this.type || (a = 32); a = (0, c.mapSpecialUnicodeValues)(a) } this.isType3Font && (n = a); var u = null; if (this.seacMap && this.seacMap[e]) { h = !0; var d = this.seacMap[e]; a = d.baseFontCharCode; u = { fontChar: String.fromCodePoint(d.accentFontCharCode), offset: d.accentOffset } } var f = "number" == typeof a ? String.fromCodePoint(a) : "", g = this.glyphCache[e]; if (!g || !g.matchesForCache(f, l, u, i, o, n, t, h)) { g = new w(f, l, u, i, o, n, t, h); this.glyphCache[e] = g } return g }, charsToGlyphs: function (e) { var t, a, r, i = this.charsCache; if (i && (t = i[e])) return t; i || (i = this.charsCache = Object.create(null)); t = []; var n, s = e, o = 0; if (this.cMap) for (var c = Object.create(null); o < e.length;) { this.cMap.readCharCode(e, o, c); r = c.charcode; var l = c.length; o += l; var h = 1 === l && 32 === e.charCodeAt(o - 1); a = this.charToGlyph(r, h); t.push(a) } else for (o = 0, n = e.length; o < n; ++o) { r = e.charCodeAt(o); a = this.charToGlyph(r, 32 === r); t.push(a) } return i[s] = t }, get glyphCacheValues() { return Object.values(this.glyphCache) } }; return e }(); t.Font = x; var A = function () { function e(e) { this.error = e; this.loadedName = "g_font_error"; this.missingFile = !0 } e.prototype = { charsToGlyphs: function () { return [] }, exportData: function () { return { error: this.error } } }; return e }(); t.ErrorFont = A; function I(e, t, a) { var r, i, o, c = Object.create(null), l = !!(e.flags & m.Symbolic); if (e.baseEncodingName) { o = (0, s.getEncoding)(e.baseEncodingName); for (i = 0; i < o.length; i++) { r = a.indexOf(o[i]); c[i] = r >= 0 ? r : 0 } } else if (l) for (i in t) c[i] = t[i]; else { o = s.StandardEncoding; for (i = 0; i < o.length; i++) { r = a.indexOf(o[i]); c[i] = r >= 0 ? r : 0 } } var h, u = e.differences; if (u) for (i in u) { var d = u[i]; if (-1 === (r = a.indexOf(d))) { h || (h = (0, n.getGlyphsUnicode)()); var f = v(d, h); f !== d && (r = a.indexOf(f)) } c[i] = r >= 0 ? r : 0 } return c } var F = function () { function e(e, t, a) { for (var r, i = e.length, n = t.length, s = i - n, o = a, c = !1; o < s;) { r = 0; for (; r < n && e[o + r] === t[r];)r++; if (r >= n) { o += r; for (; o < i && (0, l.isWhiteSpace)(e[o]);)o++; c = !0; break } o++ } return { found: c, length: o } } function t(t, a, i) { var n = i.length1, s = (i.length2, a.peekBytes(6)), o = 128 === s[0] && 1 === s[1]; if (o) { a.skip(6); n = s[5] << 24 | s[4] << 16 | s[3] << 8 | s[2] } var c = function (t, a) { var i, n, s, o, c = [101, 101, 120, 101, 99], h = t.pos; try { n = (i = t.getBytes(a)).length } catch (e) { if (e instanceof l.MissingDataException) throw e } if (n === a && (s = e(i, c, a - 2 * c.length)).found && s.length === a) return { stream: new d.Stream(i), length: a }; (0, r.warn)('Invalid "Length1" property in Type1 font -- trying to recover.'); t.pos = h; for (; ;) { if (0 === (s = e(t.peekBytes(2048), c, 0)).length) break; t.pos += s.length; if (s.found) { o = t.pos - h; break } } t.pos = h; if (o) return { stream: new d.Stream(t.getBytes(o)), length: o }; (0, r.warn)('Unable to recover "Length1" property in Type1 font -- using as is.'); return { stream: new d.Stream(t.getBytes(a)), length: a } }(a, n); new f.Type1Parser(c.stream, !1, !0).extractFontHeader(i); o && (s = a.getBytes(6))[5] << 24 | s[4] << 16 | s[3] << 8 | s[2]; var h, u = (h = a.getBytes(), { stream: new d.Stream(h), length: h.length }), g = new f.Type1Parser(u.stream, !0, !0).extractFontProgram(i); for (var m in g.properties) i[m] = g.properties[m]; var p = g.charstrings, b = this.getType2Charstrings(p), y = this.getType2Subrs(g.subrs); this.charstrings = p; this.data = this.wrap(t, b, this.charstrings, y, i); this.seacs = this.getSeacs(g.charstrings) } t.prototype = { get numGlyphs() { return this.charstrings.length + 1 }, getCharset: function () { for (var e = [".notdef"], t = this.charstrings, a = 0; a < t.length; a++)e.push(t[a].glyphName); return e }, getGlyphMapping: function (e) { var t, a = this.charstrings, r = [".notdef"]; for (t = 0; t < a.length; t++)r.push(a[t].glyphName); var i = e.builtInEncoding; if (i) { var n = Object.create(null); for (var s in i) (t = r.indexOf(i[s])) >= 0 && (n[s] = t) } return I(e, n, r) }, hasGlyphId: function (e) { return !(e < 0 || e >= this.numGlyphs) && (0 === e || this.charstrings[e - 1].charstring.length > 0) }, getSeacs: function (e) { var t, a, r = []; for (t = 0, a = e.length; t < a; t++) { var i = e[t]; i.seac && (r[t + 1] = i.seac) } return r }, getType2Charstrings: function (e) { for (var t = [], a = 0, r = e.length; a < r; a++)t.push(e[a].charstring); return t }, getType2Subrs: function (e) { var t = 0, a = e.length; t = a < 1133 ? 107 : a < 33769 ? 1131 : 32768; var r, i = []; for (r = 0; r < t; r++)i.push([11]); for (r = 0; r < a; r++)i.push(e[r]); return i }, wrap: function (e, t, a, r, n) { var s = new i.CFF; s.header = new i.CFFHeader(1, 0, 4, 4); s.names = [e]; var o = new i.CFFTopDict; o.setByName("version", 391); o.setByName("Notice", 392); o.setByName("FullName", 393); o.setByName("FamilyName", 394); o.setByName("Weight", 395); o.setByName("Encoding", null); o.setByName("FontMatrix", n.fontMatrix); o.setByName("FontBBox", n.bbox); o.setByName("charset", null); o.setByName("CharStrings", null); o.setByName("Private", null); s.topDict = o; var c = new i.CFFStrings; c.add("Version 0.11"); c.add("See original notice"); c.add(e); c.add(e); c.add("Medium"); s.strings = c; s.globalSubrIndex = new i.CFFIndex; var l, h, u = t.length, d = [".notdef"]; for (l = 0; l < u; l++) { const e = a[l].glyphName; -1 === i.CFFStandardStrings.indexOf(e) && c.add(e); d.push(e) } s.charset = new i.CFFCharset(!1, 0, d); var f = new i.CFFIndex; f.add([139, 14]); for (l = 0; l < u; l++)f.add(t[l]); s.charStrings = f; var g = new i.CFFPrivateDict; g.setByName("Subrs", null); var m = ["BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StemSnapH", "StemSnapV", "BlueShift", "BlueFuzz", "BlueScale", "LanguageGroup", "ExpansionFactor", "ForceBold", "StdHW", "StdVW"]; for (l = 0, h = m.length; l < h; l++) { var p = m[l]; if (p in n.privateData) { var b = n.privateData[p]; if (Array.isArray(b)) for (var y = b.length - 1; y > 0; y--)b[y] -= b[y - 1]; g.setByName(p, b) } } s.topDict.privateDict = g; var v = new i.CFFIndex; for (l = 0, h = r.length; l < h; l++)v.add(r[l]); g.subrsIndex = v; return new i.CFFCompiler(s).compile() } }; return t }(), T = function () { function e(e, t) { this.properties = t; var a = new i.CFFParser(e, t, !0); this.cff = a.parse(); this.cff.duplicateFirstGlyph(); var n = new i.CFFCompiler(this.cff); this.seacs = this.cff.seacs; try { this.data = n.compile() } catch (a) { (0, r.warn)("Failed to compile font " + t.loadedName); this.data = e } } e.prototype = { get numGlyphs() { return this.cff.charStrings.count }, getCharset: function () { return this.cff.charset.charset }, getGlyphMapping: function () { var e, t, a = this.cff, r = this.properties, i = a.charset.charset; if (r.composite) { e = Object.create(null); let s; if (a.isCIDFont) for (t = 0; t < i.length; t++) { var n = i[t]; s = r.cMap.charCodeOf(n); e[s] = t } else for (t = 0; t < a.charStrings.count; t++) { s = r.cMap.charCodeOf(t); e[s] = t } return e } return e = I(r, a.encoding ? a.encoding.encoding : null, i) }, hasGlyphId: function (e) { return this.cff.hasGlyphId(e) } }; return e }() }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.CFFFDSelect = t.CFFCompiler = t.CFFPrivateDict = t.CFFTopDict = t.CFFCharset = t.CFFIndex = t.CFFStrings = t.CFFHeader = t.CFF = t.CFFParser = t.CFFStandardStrings = void 0; var r = a(2), i = a(29), n = a(30), s = [".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold"]; t.CFFStandardStrings = s; var o = function () { var e = [null, { id: "hstem", min: 2, stackClearing: !0, stem: !0 }, null, { id: "vstem", min: 2, stackClearing: !0, stem: !0 }, { id: "vmoveto", min: 1, stackClearing: !0 }, { id: "rlineto", min: 2, resetStack: !0 }, { id: "hlineto", min: 1, resetStack: !0 }, { id: "vlineto", min: 1, resetStack: !0 }, { id: "rrcurveto", min: 6, resetStack: !0 }, null, { id: "callsubr", min: 1, undefStack: !0 }, { id: "return", min: 0, undefStack: !0 }, null, null, { id: "endchar", min: 0, stackClearing: !0 }, null, null, null, { id: "hstemhm", min: 2, stackClearing: !0, stem: !0 }, { id: "hintmask", min: 0, stackClearing: !0 }, { id: "cntrmask", min: 0, stackClearing: !0 }, { id: "rmoveto", min: 2, stackClearing: !0 }, { id: "hmoveto", min: 1, stackClearing: !0 }, { id: "vstemhm", min: 2, stackClearing: !0, stem: !0 }, { id: "rcurveline", min: 8, resetStack: !0 }, { id: "rlinecurve", min: 8, resetStack: !0 }, { id: "vvcurveto", min: 4, resetStack: !0 }, { id: "hhcurveto", min: 4, resetStack: !0 }, null, { id: "callgsubr", min: 1, undefStack: !0 }, { id: "vhcurveto", min: 4, resetStack: !0 }, { id: "hvcurveto", min: 4, resetStack: !0 }], t = [null, null, null, { id: "and", min: 2, stackDelta: -1 }, { id: "or", min: 2, stackDelta: -1 }, { id: "not", min: 1, stackDelta: 0 }, null, null, null, { id: "abs", min: 1, stackDelta: 0 }, { id: "add", min: 2, stackDelta: -1, stackFn: function (e, t) { e[t - 2] = e[t - 2] + e[t - 1] } }, { id: "sub", min: 2, stackDelta: -1, stackFn: function (e, t) { e[t - 2] = e[t - 2] - e[t - 1] } }, { id: "div", min: 2, stackDelta: -1, stackFn: function (e, t) { e[t - 2] = e[t - 2] / e[t - 1] } }, null, { id: "neg", min: 1, stackDelta: 0, stackFn: function (e, t) { e[t - 1] = -e[t - 1] } }, { id: "eq", min: 2, stackDelta: -1 }, null, null, { id: "drop", min: 1, stackDelta: -1 }, null, { id: "put", min: 2, stackDelta: -2 }, { id: "get", min: 1, stackDelta: 0 }, { id: "ifelse", min: 4, stackDelta: -3 }, { id: "random", min: 0, stackDelta: 1 }, { id: "mul", min: 2, stackDelta: -1, stackFn: function (e, t) { e[t - 2] = e[t - 2] * e[t - 1] } }, null, { id: "sqrt", min: 1, stackDelta: 0 }, { id: "dup", min: 1, stackDelta: 1 }, { id: "exch", min: 2, stackDelta: 0 }, { id: "index", min: 2, stackDelta: 0 }, { id: "roll", min: 3, stackDelta: -2 }, null, null, null, { id: "hflex", min: 7, resetStack: !0 }, { id: "flex", min: 13, resetStack: !0 }, { id: "hflex1", min: 9, resetStack: !0 }, { id: "flex1", min: 11, resetStack: !0 }]; function a(e, t, a) { this.bytes = e.getBytes(); this.properties = t; this.seacAnalysisEnabled = !!a } a.prototype = { parse: function () { var e = this.properties, t = new c; this.cff = t; var a = this.parseHeader(), r = this.parseIndex(a.endPos), i = this.parseIndex(r.endPos), n = this.parseIndex(i.endPos), s = this.parseIndex(n.endPos), o = this.parseDict(i.obj.get(0)), l = this.createDict(f, o, t.strings); t.header = a.obj; t.names = this.parseNameIndex(r.obj); t.strings = this.parseStringIndex(n.obj); t.topDict = l; t.globalSubrIndex = s.obj; this.parsePrivateDict(t.topDict); t.isCIDFont = l.hasName("ROS"); var h = l.getByName("CharStrings"), u = this.parseIndex(h).obj, d = l.getByName("FontMatrix"); d && (e.fontMatrix = d); var g, m, p = l.getByName("FontBBox"); if (p) { e.ascent = Math.max(p[3], p[1]); e.descent = Math.min(p[1], p[3]); e.ascentScaled = !0 } if (t.isCIDFont) { for (var b = this.parseIndex(l.getByName("FDArray")).obj, y = 0, v = b.count; y < v; ++y) { var w = b.get(y), k = this.createDict(f, this.parseDict(w), t.strings); this.parsePrivateDict(k); t.fdArray.push(k) } m = null; g = this.parseCharsets(l.getByName("charset"), u.count, t.strings, !0); t.fdSelect = this.parseFDSelect(l.getByName("FDSelect"), u.count) } else { g = this.parseCharsets(l.getByName("charset"), u.count, t.strings, !1); m = this.parseEncoding(l.getByName("Encoding"), e, t.strings, g.charset) } t.charset = g; t.encoding = m; var S = this.parseCharStrings({ charStrings: u, localSubrIndex: l.privateDict.subrsIndex, globalSubrIndex: s.obj, fdSelect: t.fdSelect, fdArray: t.fdArray, privateDict: l.privateDict }); t.charStrings = S.charStrings; t.seacs = S.seacs; t.widths = S.widths; return t }, parseHeader: function () { for (var e = this.bytes, t = e.length, a = 0; a < t && 1 !== e[a];)++a; if (a >= t) throw new r.FormatError("Invalid CFF header"); if (0 !== a) { (0, r.info)("cff data is shifted"); e = e.subarray(a); this.bytes = e } var i = e[0], n = e[1], s = e[2], o = e[3]; return { obj: new l(i, n, s, o), endPos: s } }, parseDict: function (e) { var t = 0; function a() { var a = e[t++]; if (30 === a) return function () { var a = ""; const r = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "E", "E-", null, "-"]; var i = e.length; for (; t < i;) { var n = e[t++], s = n >> 4, o = 15 & n; if (15 === s) break; a += r[s]; if (15 === o) break; a += r[o] } return parseFloat(a) }(); if (28 === a) return a = ((a = e[t++]) << 24 | e[t++] << 16) >> 16; if (29 === a) return a = (a = (a = (a = e[t++]) << 8 | e[t++]) << 8 | e[t++]) << 8 | e[t++]; if (a >= 32 && a <= 246) return a - 139; if (a >= 247 && a <= 250) return 256 * (a - 247) + e[t++] + 108; if (a >= 251 && a <= 254) return -256 * (a - 251) - e[t++] - 108; (0, r.warn)('CFFParser_parseDict: "' + a + '" is a reserved command.'); return NaN } var i = [], n = []; t = 0; for (var s = e.length; t < s;) { var o = e[t]; if (o <= 21) { 12 === o && (o = o << 8 | e[++t]); n.push([o, i]); i = []; ++t } else i.push(a()) } return n }, parseIndex: function (e) { var t, a, r = new u, i = this.bytes, n = i[e++] << 8 | i[e++], s = [], o = e; if (0 !== n) { var c = i[e++], l = e + (n + 1) * c - 1; for (t = 0, a = n + 1; t < a; ++t) { for (var h = 0, d = 0; d < c; ++d) { h <<= 8; h += i[e++] } s.push(l + h) } o = s[n] } for (t = 0, a = s.length - 1; t < a; ++t) { var f = s[t], g = s[t + 1]; r.add(i.subarray(f, g)) } return { obj: r, endPos: o } }, parseNameIndex: function (e) { for (var t = [], a = 0, i = e.count; a < i; ++a) { var n = e.get(a); t.push((0, r.bytesToString)(n)) } return t }, parseStringIndex: function (e) { for (var t = new h, a = 0, i = e.count; a < i; ++a) { var n = e.get(a); t.add((0, r.bytesToString)(n)) } return t }, createDict: function (e, t, a) { for (var r = new e(a), i = 0, n = t.length; i < n; ++i) { var s = t[i], o = s[0], c = s[1]; r.setByKey(o, c) } return r }, parseCharString: function (a, i, n, s) { if (!i || a.callDepth > 10) return !1; for (var o = a.stackSize, c = a.stack, l = i.length, h = 0; h < l;) { var u = i[h++], d = null; if (12 === u) { var f = i[h++]; if (0 === f) { i[h - 2] = 139; i[h - 1] = 22; o = 0 } else d = t[f] } else if (28 === u) { c[o] = (i[h] << 24 | i[h + 1] << 16) >> 16; h += 2; o++ } else if (14 === u) { if (o >= 4) { o -= 4; if (this.seacAnalysisEnabled) { a.seac = c.slice(o, o + 4); return !1 } } d = e[u] } else if (u >= 32 && u <= 246) { c[o] = u - 139; o++ } else if (u >= 247 && u <= 254) { c[o] = u < 251 ? (u - 247 << 8) + i[h] + 108 : -(u - 251 << 8) - i[h] - 108; h++; o++ } else if (255 === u) { c[o] = (i[h] << 24 | i[h + 1] << 16 | i[h + 2] << 8 | i[h + 3]) / 65536; h += 4; o++ } else if (19 === u || 20 === u) { a.hints += o >> 1; h += a.hints + 7 >> 3; o %= 2; d = e[u] } else { if (10 === u || 29 === u) { var g; if (!(g = 10 === u ? n : s)) { d = e[u]; (0, r.warn)("Missing subrsIndex for " + d.id); return !1 } var m = 32768; g.count < 1240 ? m = 107 : g.count < 33900 && (m = 1131); var p = c[--o] + m; if (p < 0 || p >= g.count || isNaN(p)) { d = e[u]; (0, r.warn)("Out of bounds subrIndex for " + d.id); return !1 } a.stackSize = o; a.callDepth++; if (!this.parseCharString(a, g.get(p), n, s)) return !1; a.callDepth--; o = a.stackSize; continue } if (11 === u) { a.stackSize = o; return !0 } d = e[u] } if (d) { if (d.stem) { a.hints += o >> 1; if (3 === u || 23 === u) a.hasVStems = !0; else if (a.hasVStems && (1 === u || 18 === u)) { (0, r.warn)("CFF stem hints are in wrong order"); i[h - 1] = 1 === u ? 3 : 23 } } if ("min" in d && !a.undefStack && o < d.min) { (0, r.warn)("Not enough parameters for " + d.id + "; actual: " + o + ", expected: " + d.min); return !1 } if (a.firstStackClearing && d.stackClearing) { a.firstStackClearing = !1; (o -= d.min) >= 2 && d.stem ? o %= 2 : o > 1 && (0, r.warn)("Found too many parameters for stack-clearing command"); o > 0 && c[o - 1] >= 0 && (a.width = c[o - 1]) } if ("stackDelta" in d) { "stackFn" in d && d.stackFn(c, o); o += d.stackDelta } else if (d.stackClearing) o = 0; else if (d.resetStack) { o = 0; a.undefStack = !1 } else if (d.undefStack) { o = 0; a.undefStack = !0; a.firstStackClearing = !1 } } } a.stackSize = o; return !0 }, parseCharStrings({ charStrings: e, localSubrIndex: t, globalSubrIndex: a, fdSelect: i, fdArray: n, privateDict: s }) { for (var o = [], c = [], l = e.count, h = 0; h < l; h++) { var u = e.get(h), d = { callDepth: 0, stackSize: 0, stack: [], undefStack: !0, hints: 0, firstStackClearing: !0, seac: null, width: null, hasVStems: !1 }, f = !0, g = null, m = s; if (i && n.length) { var p = i.getFDIndex(h); if (-1 === p) { (0, r.warn)("Glyph index is not in fd select."); f = !1 } if (p >= n.length) { (0, r.warn)("Invalid fd index for glyph index."); f = !1 } f && (g = (m = n[p].privateDict).subrsIndex) } else t && (g = t); f && (f = this.parseCharString(d, u, g, a)); if (null !== d.width) { const e = m.getByName("nominalWidthX"); c[h] = e + d.width } else { const e = m.getByName("defaultWidthX"); c[h] = e } null !== d.seac && (o[h] = d.seac); f || e.set(h, new Uint8Array([14])) } return { charStrings: e, seacs: o, widths: c } }, emptyPrivateDictionary: function (e) { var t = this.createDict(g, [], e.strings); e.setByKey(18, [0, 0]); e.privateDict = t }, parsePrivateDict: function (e) { if (e.hasName("Private")) { var t = e.getByName("Private"); if (Array.isArray(t) && 2 === t.length) { var a = t[0], r = t[1]; if (0 === a || r >= this.bytes.length) this.emptyPrivateDictionary(e); else { var i = r + a, n = this.bytes.subarray(r, i), s = this.parseDict(n), o = this.createDict(g, s, e.strings); e.privateDict = o; if (o.getByName("Subrs")) { var c = o.getByName("Subrs"), l = r + c; if (0 === c || l >= this.bytes.length) this.emptyPrivateDictionary(e); else { var h = this.parseIndex(l); o.subrsIndex = h.obj } } } } else e.removeByName("Private") } else this.emptyPrivateDictionary(e) }, parseCharsets: function (e, t, a, n) { if (0 === e) return new p(!0, m.ISO_ADOBE, i.ISOAdobeCharset); if (1 === e) return new p(!0, m.EXPERT, i.ExpertCharset); if (2 === e) return new p(!0, m.EXPERT_SUBSET, i.ExpertSubsetCharset); var s, o, c, l = this.bytes, h = e, u = l[e++], d = [".notdef"]; t -= 1; switch (u) { case 0: for (c = 0; c < t; c++) { s = l[e++] << 8 | l[e++]; d.push(n ? s : a.get(s)) } break; case 1: for (; d.length <= t;) { s = l[e++] << 8 | l[e++]; o = l[e++]; for (c = 0; c <= o; c++)d.push(n ? s++ : a.get(s++)) } break; case 2: for (; d.length <= t;) { s = l[e++] << 8 | l[e++]; o = l[e++] << 8 | l[e++]; for (c = 0; c <= o; c++)d.push(n ? s++ : a.get(s++)) } break; default: throw new r.FormatError("Unknown charset format") }var f = e, g = l.subarray(h, f); return new p(!1, u, d, g) }, parseEncoding: function (e, t, a, i) { var s, o, c, l = Object.create(null), h = this.bytes, u = !1, d = null; if (0 === e || 1 === e) { u = !0; s = e; var f = e ? n.ExpertEncoding : n.StandardEncoding; for (o = 0, c = i.length; o < c; o++) { var g = f.indexOf(i[o]); -1 !== g && (l[g] = o) } } else { var m = e; switch (127 & (s = h[e++])) { case 0: var p = h[e++]; for (o = 1; o <= p; o++)l[h[e++]] = o; break; case 1: var y = h[e++], v = 1; for (o = 0; o < y; o++)for (var w = h[e++], k = h[e++], S = w; S <= w + k; S++)l[S] = v++; break; default: throw new r.FormatError(`Unknown encoding format: ${s} in CFF`) }var C = e; if (128 & s) { h[m] &= 127; !function () { var t = h[e++]; for (o = 0; o < t; o++) { var r = h[e++], n = (h[e++] << 8) + (255 & h[e++]); l[r] = i.indexOf(a.get(n)) } }() } d = h.subarray(m, C) } return new b(u, s &= 127, l, d) }, parseFDSelect: function (e, t) { var a, i = this.bytes, n = i[e++], s = []; switch (n) { case 0: for (a = 0; a < t; ++a) { var o = i[e++]; s.push(o) } break; case 3: var c = i[e++] << 8 | i[e++]; for (a = 0; a < c; ++a) { var l = i[e++] << 8 | i[e++]; if (0 === a && 0 !== l) { (0, r.warn)("parseFDSelect: The first range must have a first GID of 0 -- trying to recover."); l = 0 } for (var h = i[e++], u = i[e] << 8 | i[e + 1], d = l; d < u; ++d)s.push(h) } e += 2; break; default: throw new r.FormatError(`parseFDSelect: Unknown format "${n}".`) }if (s.length !== t) throw new r.FormatError("parseFDSelect: Invalid font data."); return new y(n, s) } }; return a }(); t.CFFParser = o; var c = function () { function e() { this.header = null; this.names = []; this.topDict = null; this.strings = new h; this.globalSubrIndex = null; this.encoding = null; this.charset = null; this.charStrings = null; this.fdArray = []; this.fdSelect = null; this.isCIDFont = !1 } e.prototype = { duplicateFirstGlyph: function () { if (this.charStrings.count >= 65535) (0, r.warn)("Not enough space in charstrings to duplicate first glyph."); else { var e = this.charStrings.get(0); this.charStrings.add(e); this.isCIDFont && this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0]) } }, hasGlyphId: function (e) { return !(e < 0 || e >= this.charStrings.count) && this.charStrings.get(e).length > 0 } }; return e }(); t.CFF = c; var l = function (e, t, a, r) { this.major = e; this.minor = t; this.hdrSize = a; this.offSize = r }; t.CFFHeader = l; var h = function () { function e() { this.strings = [] } e.prototype = { get: function (e) { return e >= 0 && e <= 390 ? s[e] : e - 391 <= this.strings.length ? this.strings[e - 391] : s[0] }, getSID: function (e) { let t = s.indexOf(e); if (-1 !== t) return t; t = this.strings.indexOf(e); return -1 !== t ? t + 391 : -1 }, add: function (e) { this.strings.push(e) }, get count() { return this.strings.length } }; return e }(); t.CFFStrings = h; var u = function () { function e() { this.objects = []; this.length = 0 } e.prototype = { add: function (e) { this.length += e.length; this.objects.push(e) }, set: function (e, t) { this.length += t.length - this.objects[e].length; this.objects[e] = t }, get: function (e) { return this.objects[e] }, get count() { return this.objects.length } }; return e }(); t.CFFIndex = u; var d = function () { function e(e, t) { this.keyToNameMap = e.keyToNameMap; this.nameToKeyMap = e.nameToKeyMap; this.defaults = e.defaults; this.types = e.types; this.opcodes = e.opcodes; this.order = e.order; this.strings = t; this.values = Object.create(null) } e.prototype = { setByKey: function (e, t) { if (!(e in this.keyToNameMap)) return !1; var a = t.length; if (0 === a) return !0; for (var i = 0; i < a; i++)if (isNaN(t[i])) { (0, r.warn)('Invalid CFFDict value: "' + t + '" for key "' + e + '".'); return !0 } var n = this.types[e]; "num" !== n && "sid" !== n && "offset" !== n || (t = t[0]); this.values[e] = t; return !0 }, setByName: function (e, t) { if (!(e in this.nameToKeyMap)) throw new r.FormatError(`Invalid dictionary name "${e}"`); this.values[this.nameToKeyMap[e]] = t }, hasName: function (e) { return this.nameToKeyMap[e] in this.values }, getByName: function (e) { if (!(e in this.nameToKeyMap)) throw new r.FormatError(`Invalid dictionary name ${e}"`); var t = this.nameToKeyMap[e]; return t in this.values ? this.values[t] : this.defaults[t] }, removeByName: function (e) { delete this.values[this.nameToKeyMap[e]] } }; e.createTables = function (e) { for (var t = { keyToNameMap: {}, nameToKeyMap: {}, defaults: {}, types: {}, opcodes: {}, order: [] }, a = 0, r = e.length; a < r; ++a) { var i = e[a], n = Array.isArray(i[0]) ? (i[0][0] << 8) + i[0][1] : i[0]; t.keyToNameMap[n] = i[1]; t.nameToKeyMap[i[1]] = n; t.types[n] = i[2]; t.defaults[n] = i[3]; t.opcodes[n] = Array.isArray(i[0]) ? i[0] : [i[0]]; t.order.push(n) } return t }; return e }(), f = function () { var e = [[[12, 30], "ROS", ["sid", "sid", "num"], null], [[12, 20], "SyntheticBase", "num", null], [0, "version", "sid", null], [1, "Notice", "sid", null], [[12, 0], "Copyright", "sid", null], [2, "FullName", "sid", null], [3, "FamilyName", "sid", null], [4, "Weight", "sid", null], [[12, 1], "isFixedPitch", "num", 0], [[12, 2], "ItalicAngle", "num", 0], [[12, 3], "UnderlinePosition", "num", -100], [[12, 4], "UnderlineThickness", "num", 50], [[12, 5], "PaintType", "num", 0], [[12, 6], "CharstringType", "num", 2], [[12, 7], "FontMatrix", ["num", "num", "num", "num", "num", "num"], [.001, 0, 0, .001, 0, 0]], [13, "UniqueID", "num", null], [5, "FontBBox", ["num", "num", "num", "num"], [0, 0, 0, 0]], [[12, 8], "StrokeWidth", "num", 0], [14, "XUID", "array", null], [15, "charset", "offset", 0], [16, "Encoding", "offset", 0], [17, "CharStrings", "offset", 0], [18, "Private", ["offset", "offset"], null], [[12, 21], "PostScript", "sid", null], [[12, 22], "BaseFontName", "sid", null], [[12, 23], "BaseFontBlend", "delta", null], [[12, 31], "CIDFontVersion", "num", 0], [[12, 32], "CIDFontRevision", "num", 0], [[12, 33], "CIDFontType", "num", 0], [[12, 34], "CIDCount", "num", 8720], [[12, 35], "UIDBase", "num", null], [[12, 37], "FDSelect", "offset", null], [[12, 36], "FDArray", "offset", null], [[12, 38], "FontName", "sid", null]], t = null; function a(a) { null === t && (t = d.createTables(e)); d.call(this, t, a); this.privateDict = null } a.prototype = Object.create(d.prototype); return a }(); t.CFFTopDict = f; var g = function () { var e = [[6, "BlueValues", "delta", null], [7, "OtherBlues", "delta", null], [8, "FamilyBlues", "delta", null], [9, "FamilyOtherBlues", "delta", null], [[12, 9], "BlueScale", "num", .039625], [[12, 10], "BlueShift", "num", 7], [[12, 11], "BlueFuzz", "num", 1], [10, "StdHW", "num", null], [11, "StdVW", "num", null], [[12, 12], "StemSnapH", "delta", null], [[12, 13], "StemSnapV", "delta", null], [[12, 14], "ForceBold", "num", 0], [[12, 17], "LanguageGroup", "num", 0], [[12, 18], "ExpansionFactor", "num", .06], [[12, 19], "initialRandomSeed", "num", 0], [20, "defaultWidthX", "num", 0], [21, "nominalWidthX", "num", 0], [19, "Subrs", "offset", null]], t = null; function a(a) { null === t && (t = d.createTables(e)); d.call(this, t, a); this.subrsIndex = null } a.prototype = Object.create(d.prototype); return a }(); t.CFFPrivateDict = g; var m = { ISO_ADOBE: 0, EXPERT: 1, EXPERT_SUBSET: 2 }, p = function (e, t, a, r) { this.predefined = e; this.format = t; this.charset = a; this.raw = r }; t.CFFCharset = p; var b = function (e, t, a, r) { this.predefined = e; this.format = t; this.encoding = a; this.raw = r }, y = function () { function e(e, t) { this.format = e; this.fdSelect = t } e.prototype = { getFDIndex: function (e) { return e < 0 || e >= this.fdSelect.length ? -1 : this.fdSelect[e] } }; return e }(); t.CFFFDSelect = y; var v = function () { function e() { this.offsets = Object.create(null) } e.prototype = { isTracking: function (e) { return e in this.offsets }, track: function (e, t) { if (e in this.offsets) throw new r.FormatError(`Already tracking location of ${e}`); this.offsets[e] = t }, offset: function (e) { for (var t in this.offsets) this.offsets[t] += e }, setEntryLocation: function (e, t, a) { if (!(e in this.offsets)) throw new r.FormatError(`Not tracking location of ${e}`); for (var i = a.data, n = this.offsets[e], s = 0, o = t.length; s < o; ++s) { var c = 5 * s + n, l = c + 1, h = c + 2, u = c + 3, d = c + 4; if (29 !== i[c] || 0 !== i[l] || 0 !== i[h] || 0 !== i[u] || 0 !== i[d]) throw new r.FormatError("writing to an offset that is not empty"); var f = t[s]; i[c] = 29; i[l] = f >> 24 & 255; i[h] = f >> 16 & 255; i[u] = f >> 8 & 255; i[d] = 255 & f } } }; return e }(), w = function () { function e(e) { this.cff = e } e.prototype = { compile: function () { var e = this.cff, t = { data: [], length: 0, add: function (e) { this.data = this.data.concat(e); this.length = this.data.length } }, a = this.compileHeader(e.header); t.add(a); var i = this.compileNameIndex(e.names); t.add(i); if (e.isCIDFont && e.topDict.hasName("FontMatrix")) { var n = e.topDict.getByName("FontMatrix"); e.topDict.removeByName("FontMatrix"); for (var s = 0, o = e.fdArray.length; s < o; s++) { var c = e.fdArray[s], l = n.slice(0); c.hasName("FontMatrix") && (l = r.Util.transform(l, c.getByName("FontMatrix"))); c.setByName("FontMatrix", l) } } e.topDict.setByName("charset", 0); var h = this.compileTopDicts([e.topDict], t.length, e.isCIDFont); t.add(h.output); var u = h.trackers[0], d = this.compileStringIndex(e.strings.strings); t.add(d); var f = this.compileIndex(e.globalSubrIndex); t.add(f); if (e.encoding && e.topDict.hasName("Encoding")) if (e.encoding.predefined) u.setEntryLocation("Encoding", [e.encoding.format], t); else { var g = this.compileEncoding(e.encoding); u.setEntryLocation("Encoding", [t.length], t); t.add(g) } var m = this.compileCharset(e.charset, e.charStrings.count, e.strings, e.isCIDFont); u.setEntryLocation("charset", [t.length], t); t.add(m); var p = this.compileCharStrings(e.charStrings); u.setEntryLocation("CharStrings", [t.length], t); t.add(p); if (e.isCIDFont) { u.setEntryLocation("FDSelect", [t.length], t); var b = this.compileFDSelect(e.fdSelect); t.add(b); h = this.compileTopDicts(e.fdArray, t.length, !0); u.setEntryLocation("FDArray", [t.length], t); t.add(h.output); var y = h.trackers; this.compilePrivateDicts(e.fdArray, y, t) } this.compilePrivateDicts([e.topDict], [u], t); t.add([0]); return t.data }, encodeNumber: function (e) { return parseFloat(e) !== parseInt(e, 10) || isNaN(e) ? this.encodeFloat(e) : this.encodeInteger(e) }, encodeFloat: function (e) { var t = e.toString(), a = /\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(t); if (a) { var r = parseFloat("1e" + ((a[2] ? +a[2] : 0) + a[1].length)); t = (Math.round(e * r) / r).toString() } var i, n, s = ""; for (i = 0, n = t.length; i < n; ++i) { var o = t[i]; s += "e" === o ? "-" === t[++i] ? "c" : "b" : "." === o ? "a" : "-" === o ? "e" : o } var c = [30]; for (i = 0, n = (s += 1 & s.length ? "f" : "ff").length; i < n; i += 2)c.push(parseInt(s.substring(i, i + 2), 16)); return c }, encodeInteger: function (e) { return e >= -107 && e <= 107 ? [e + 139] : e >= 108 && e <= 1131 ? [247 + ((e -= 108) >> 8), 255 & e] : e >= -1131 && e <= -108 ? [251 + ((e = -e - 108) >> 8), 255 & e] : e >= -32768 && e <= 32767 ? [28, e >> 8 & 255, 255 & e] : [29, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e] }, compileHeader: function (e) { return [e.major, e.minor, e.hdrSize, e.offSize] }, compileNameIndex: function (e) { for (var t = new u, a = 0, i = e.length; a < i; ++a) { for (var n = e[a], s = Math.min(n.length, 127), o = new Array(s), c = 0; c < s; c++) { var l = n[c]; (l < "!" || l > "~" || "[" === l || "]" === l || "(" === l || ")" === l || "{" === l || "}" === l || "<" === l || ">" === l || "/" === l || "%" === l) && (l = "_"); o[c] = l } "" === (o = o.join("")) && (o = "Bad_Font_Name"); t.add((0, r.stringToBytes)(o)) } return this.compileIndex(t) }, compileTopDicts: function (e, t, a) { for (var r = [], i = new u, n = 0, s = e.length; n < s; ++n) { var o = e[n]; if (a) { o.removeByName("CIDFontVersion"); o.removeByName("CIDFontRevision"); o.removeByName("CIDFontType"); o.removeByName("CIDCount"); o.removeByName("UIDBase") } var c = new v, l = this.compileDict(o, c); r.push(c); i.add(l); c.offset(t) } return { trackers: r, output: i = this.compileIndex(i, r) } }, compilePrivateDicts: function (e, t, a) { for (var i = 0, n = e.length; i < n; ++i) { var s = e[i], o = s.privateDict; if (!o || !s.hasName("Private")) throw new r.FormatError("There must be a private dictionary."); var c = new v, l = this.compileDict(o, c), h = a.length; c.offset(h); l.length || (h = 0); t[i].setEntryLocation("Private", [l.length, h], a); a.add(l); if (o.subrsIndex && o.hasName("Subrs")) { var u = this.compileIndex(o.subrsIndex); c.setEntryLocation("Subrs", [l.length], a); a.add(u) } } }, compileDict: function (e, t) { for (var a = [], i = e.order, n = 0; n < i.length; ++n) { var s = i[n]; if (s in e.values) { var o = e.values[s], c = e.types[s]; Array.isArray(c) || (c = [c]); Array.isArray(o) || (o = [o]); if (0 !== o.length) { for (var l = 0, h = c.length; l < h; ++l) { var u = c[l], d = o[l]; switch (u) { case "num": case "sid": a = a.concat(this.encodeNumber(d)); break; case "offset": var f = e.keyToNameMap[s]; t.isTracking(f) || t.track(f, a.length); a = a.concat([29, 0, 0, 0, 0]); break; case "array": case "delta": a = a.concat(this.encodeNumber(d)); for (var g = 1, m = o.length; g < m; ++g)a = a.concat(this.encodeNumber(o[g])); break; default: throw new r.FormatError(`Unknown data type of ${u}`) } } a = a.concat(e.opcodes[s]) } } } return a }, compileStringIndex: function (e) { for (var t = new u, a = 0, i = e.length; a < i; ++a)t.add((0, r.stringToBytes)(e[a])); return this.compileIndex(t) }, compileGlobalSubrIndex: function () { var e = this.cff.globalSubrIndex; this.out.writeByteArray(this.compileIndex(e)) }, compileCharStrings: function (e) { for (var t = new u, a = 0; a < e.count; a++) { var r = e.get(a); 0 !== r.length ? t.add(r) : t.add(new Uint8Array([139, 14])) } return this.compileIndex(t) }, compileCharset: function (e, t, a, i) { let n; const s = t - 1; if (i) n = new Uint8Array([2, 0, 0, s >> 8 & 255, 255 & s]); else { n = new Uint8Array(1 + 2 * s); n[0] = 0; let t = 0; const i = e.charset.length; let o = !1; for (let s = 1; s < n.length; s += 2) { let c = 0; if (t < i) { const i = e.charset[t++]; c = a.getSID(i); if (-1 === c) { c = 0; if (!o) { o = !0; (0, r.warn)(`Couldn't find ${i} in CFF strings`) } } } n[s] = c >> 8 & 255; n[s + 1] = 255 & c } } return this.compileTypedArray(n) }, compileEncoding: function (e) { return this.compileTypedArray(e.raw) }, compileFDSelect: function (e) { const t = e.format; let a, r; switch (t) { case 0: a = new Uint8Array(1 + e.fdSelect.length); a[0] = t; for (r = 0; r < e.fdSelect.length; r++)a[r + 1] = e.fdSelect[r]; break; case 3: const i = 0; let n = e.fdSelect[0]; const s = [t, 0, 0, i >> 8 & 255, 255 & i, n]; for (r = 1; r < e.fdSelect.length; r++) { const t = e.fdSelect[r]; if (t !== n) { s.push(r >> 8 & 255, 255 & r, t); n = t } } const o = (s.length - 3) / 3; s[1] = o >> 8 & 255; s[2] = 255 & o; s.push(r >> 8 & 255, 255 & r); a = new Uint8Array(s) }return this.compileTypedArray(a) }, compileTypedArray: function (e) { for (var t = [], a = 0, r = e.length; a < r; ++a)t[a] = e[a]; return t }, compileIndex: function (e, t) { t = t || []; var a = e.objects, r = a.length; if (0 === r) return [0, 0, 0]; var i, n, s = [r >> 8 & 255, 255 & r], o = 1; for (i = 0; i < r; ++i)o += a[i].length; n = o < 256 ? 1 : o < 65536 ? 2 : o < 16777216 ? 3 : 4; s.push(n); var c = 1; for (i = 0; i < r + 1; i++) { 1 === n ? s.push(255 & c) : 2 === n ? s.push(c >> 8 & 255, 255 & c) : 3 === n ? s.push(c >> 16 & 255, c >> 8 & 255, 255 & c) : s.push(c >>> 24 & 255, c >> 16 & 255, c >> 8 & 255, 255 & c); a[i] && (c += a[i].length) } for (i = 0; i < r; i++) { t[i] && t[i].offset(s.length); for (var l = 0, h = a[i].length; l < h; l++)s.push(a[i][l]) } return s } }; return e }(); t.CFFCompiler = w }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.ExpertSubsetCharset = t.ExpertCharset = t.ISOAdobeCharset = void 0; t.ISOAdobeCharset = [".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron"]; t.ExpertCharset = [".notdef", "space", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall"]; t.ExpertSubsetCharset = [".notdef", "space", "dollaroldstyle", "dollarsuperior", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "hyphensuperior", "colonmonetary", "onefitted", "rupiah", "centoldstyle", "figuredash", "hypheninferior", "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior"] }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getEncoding = function (e) { switch (e) { case "WinAnsiEncoding": return o; case "StandardEncoding": return s; case "MacRomanEncoding": return n; case "SymbolSetEncoding": return c; case "ZapfDingbatsEncoding": return l; case "ExpertEncoding": return r; case "MacExpertEncoding": return i; default: return null } }; t.ExpertEncoding = t.ZapfDingbatsEncoding = t.SymbolSetEncoding = t.MacRomanEncoding = t.StandardEncoding = t.WinAnsiEncoding = void 0; const r = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclamsmall", "Hungarumlautsmall", "", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "", "", "", "isuperior", "", "", "lsuperior", "msuperior", "nsuperior", "osuperior", "", "", "rsuperior", "ssuperior", "tsuperior", "", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdownsmall", "centoldstyle", "Lslashsmall", "", "", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "", "Dotaccentsmall", "", "", "Macronsmall", "", "", "figuredash", "hypheninferior", "", "", "Ogoneksmall", "Ringsmall", "Cedillasmall", "", "", "", "onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "", "", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall"]; t.ExpertEncoding = r; const i = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclamsmall", "Hungarumlautsmall", "centoldstyle", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "", "threequartersemdash", "", "questionsmall", "", "", "", "", "Ethsmall", "", "", "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "", "", "", "", "", "", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior", "Circumflexsmall", "hypheninferior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "", "", "asuperior", "centsuperior", "", "", "", "", "Aacutesmall", "Agravesmall", "Acircumflexsmall", "Adieresissmall", "Atildesmall", "Aringsmall", "Ccedillasmall", "Eacutesmall", "Egravesmall", "Ecircumflexsmall", "Edieresissmall", "Iacutesmall", "Igravesmall", "Icircumflexsmall", "Idieresissmall", "Ntildesmall", "Oacutesmall", "Ogravesmall", "Ocircumflexsmall", "Odieresissmall", "Otildesmall", "Uacutesmall", "Ugravesmall", "Ucircumflexsmall", "Udieresissmall", "", "eightsuperior", "fourinferior", "threeinferior", "sixinferior", "eightinferior", "seveninferior", "Scaronsmall", "", "centinferior", "twoinferior", "", "Dieresissmall", "", "Caronsmall", "osuperior", "fiveinferior", "", "commainferior", "periodinferior", "Yacutesmall", "", "dollarinferior", "", "", "Thornsmall", "", "nineinferior", "zeroinferior", "Zcaronsmall", "AEsmall", "Oslashsmall", "questiondownsmall", "oneinferior", "Lslashsmall", "", "", "", "", "", "", "Cedillasmall", "", "", "", "", "", "OEsmall", "figuredash", "hyphensuperior", "", "", "", "", "exclamdownsmall", "", "Ydieresissmall", "", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "ninesuperior", "zerosuperior", "", "esuperior", "rsuperior", "tsuperior", "", "", "isuperior", "ssuperior", "dsuperior", "", "", "", "", "", "lsuperior", "Ogoneksmall", "Brevesmall", "Macronsmall", "bsuperior", "nsuperior", "msuperior", "commasuperior", "periodsuperior", "Dotaccentsmall", "Ringsmall", "", "", "", ""], n = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "space", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron"]; t.MacRomanEncoding = n; const s = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "", "endash", "dagger", "daggerdbl", "periodcentered", "", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "", "questiondown", "", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "", "ring", "cedilla", "", "hungarumlaut", "ogonek", "caron", "emdash", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AE", "", "ordfeminine", "", "", "", "", "Lslash", "Oslash", "OE", "ordmasculine", "", "", "", "", "", "ae", "", "", "", "dotlessi", "", "", "lslash", "oslash", "oe", "germandbls", "", "", "", ""]; t.StandardEncoding = s; const o = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "bullet", "Euro", "bullet", "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", "bullet", "Zcaron", "bullet", "bullet", "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", "endash", "emdash", "tilde", "trademark", "scaron", "guilsinglright", "oe", "bullet", "zcaron", "Ydieresis", "space", "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section", "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron", "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered", "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis"]; t.WinAnsiEncoding = o; const c = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "universal", "numbersign", "existential", "percent", "ampersand", "suchthat", "parenleft", "parenright", "asteriskmath", "plus", "comma", "minus", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "congruent", "Alpha", "Beta", "Chi", "Delta", "Epsilon", "Phi", "Gamma", "Eta", "Iota", "theta1", "Kappa", "Lambda", "Mu", "Nu", "Omicron", "Pi", "Theta", "Rho", "Sigma", "Tau", "Upsilon", "sigma1", "Omega", "Xi", "Psi", "Zeta", "bracketleft", "therefore", "bracketright", "perpendicular", "underscore", "radicalex", "alpha", "beta", "chi", "delta", "epsilon", "phi", "gamma", "eta", "iota", "phi1", "kappa", "lambda", "mu", "nu", "omicron", "pi", "theta", "rho", "sigma", "tau", "upsilon", "omega1", "omega", "xi", "psi", "zeta", "braceleft", "bar", "braceright", "similar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Euro", "Upsilon1", "minute", "lessequal", "fraction", "infinity", "florin", "club", "diamond", "heart", "spade", "arrowboth", "arrowleft", "arrowup", "arrowright", "arrowdown", "degree", "plusminus", "second", "greaterequal", "multiply", "proportional", "partialdiff", "bullet", "divide", "notequal", "equivalence", "approxequal", "ellipsis", "arrowvertex", "arrowhorizex", "carriagereturn", "aleph", "Ifraktur", "Rfraktur", "weierstrass", "circlemultiply", "circleplus", "emptyset", "intersection", "union", "propersuperset", "reflexsuperset", "notsubset", "propersubset", "reflexsubset", "element", "notelement", "angle", "gradient", "registerserif", "copyrightserif", "trademarkserif", "product", "radical", "dotmath", "logicalnot", "logicaland", "logicalor", "arrowdblboth", "arrowdblleft", "arrowdblup", "arrowdblright", "arrowdbldown", "lozenge", "angleleft", "registersans", "copyrightsans", "trademarksans", "summation", "parenlefttp", "parenleftex", "parenleftbt", "bracketlefttp", "bracketleftex", "bracketleftbt", "bracelefttp", "braceleftmid", "braceleftbt", "braceex", "", "angleright", "integral", "integraltp", "integralex", "integralbt", "parenrighttp", "parenrightex", "parenrightbt", "bracketrighttp", "bracketrightex", "bracketrightbt", "bracerighttp", "bracerightmid", "bracerightbt", ""]; t.SymbolSetEncoding = c; const l = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", "a118", "a117", "a11", "a12", "a13", "a14", "a15", "a16", "a105", "a17", "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26", "a27", "a28", "a6", "a7", "a8", "a9", "a10", "a29", "a30", "a31", "a32", "a33", "a34", "a35", "a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44", "a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53", "a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62", "a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71", "a72", "a73", "a74", "a203", "a75", "a204", "a76", "a77", "a78", "a79", "a81", "a82", "a83", "a84", "a97", "a98", "a99", "a100", "", "a89", "a90", "a93", "a94", "a91", "a92", "a205", "a85", "a206", "a86", "a87", "a88", "a95", "a96", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "a101", "a102", "a103", "a104", "a106", "a107", "a108", "a112", "a111", "a110", "a109", "a120", "a121", "a122", "a123", "a124", "a125", "a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134", "a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143", "a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152", "a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161", "a163", "a164", "a196", "a165", "a192", "a166", "a167", "a168", "a169", "a170", "a171", "a172", "a173", "a162", "a174", "a175", "a176", "a177", "a178", "a179", "a193", "a180", "a199", "a181", "a200", "a182", "", "a201", "a183", "a184", "a197", "a185", "a194", "a198", "a186", "a195", "a187", "a188", "a189", "a190", "a191", ""]; t.ZapfDingbatsEncoding = l }, function (e, t, a) { var r = a(7).getLookupTableFactory, i = r((function (e) { e.A = 65; e.AE = 198; e.AEacute = 508; e.AEmacron = 482; e.AEsmall = 63462; e.Aacute = 193; e.Aacutesmall = 63457; e.Abreve = 258; e.Abreveacute = 7854; e.Abrevecyrillic = 1232; e.Abrevedotbelow = 7862; e.Abrevegrave = 7856; e.Abrevehookabove = 7858; e.Abrevetilde = 7860; e.Acaron = 461; e.Acircle = 9398; e.Acircumflex = 194; e.Acircumflexacute = 7844; e.Acircumflexdotbelow = 7852; e.Acircumflexgrave = 7846; e.Acircumflexhookabove = 7848; e.Acircumflexsmall = 63458; e.Acircumflextilde = 7850; e.Acute = 63177; e.Acutesmall = 63412; e.Acyrillic = 1040; e.Adblgrave = 512; e.Adieresis = 196; e.Adieresiscyrillic = 1234; e.Adieresismacron = 478; e.Adieresissmall = 63460; e.Adotbelow = 7840; e.Adotmacron = 480; e.Agrave = 192; e.Agravesmall = 63456; e.Ahookabove = 7842; e.Aiecyrillic = 1236; e.Ainvertedbreve = 514; e.Alpha = 913; e.Alphatonos = 902; e.Amacron = 256; e.Amonospace = 65313; e.Aogonek = 260; e.Aring = 197; e.Aringacute = 506; e.Aringbelow = 7680; e.Aringsmall = 63461; e.Asmall = 63329; e.Atilde = 195; e.Atildesmall = 63459; e.Aybarmenian = 1329; e.B = 66; e.Bcircle = 9399; e.Bdotaccent = 7682; e.Bdotbelow = 7684; e.Becyrillic = 1041; e.Benarmenian = 1330; e.Beta = 914; e.Bhook = 385; e.Blinebelow = 7686; e.Bmonospace = 65314; e.Brevesmall = 63220; e.Bsmall = 63330; e.Btopbar = 386; e.C = 67; e.Caarmenian = 1342; e.Cacute = 262; e.Caron = 63178; e.Caronsmall = 63221; e.Ccaron = 268; e.Ccedilla = 199; e.Ccedillaacute = 7688; e.Ccedillasmall = 63463; e.Ccircle = 9400; e.Ccircumflex = 264; e.Cdot = 266; e.Cdotaccent = 266; e.Cedillasmall = 63416; e.Chaarmenian = 1353; e.Cheabkhasiancyrillic = 1212; e.Checyrillic = 1063; e.Chedescenderabkhasiancyrillic = 1214; e.Chedescendercyrillic = 1206; e.Chedieresiscyrillic = 1268; e.Cheharmenian = 1347; e.Chekhakassiancyrillic = 1227; e.Cheverticalstrokecyrillic = 1208; e.Chi = 935; e.Chook = 391; e.Circumflexsmall = 63222; e.Cmonospace = 65315; e.Coarmenian = 1361; e.Csmall = 63331; e.D = 68; e.DZ = 497; e.DZcaron = 452; e.Daarmenian = 1332; e.Dafrican = 393; e.Dcaron = 270; e.Dcedilla = 7696; e.Dcircle = 9401; e.Dcircumflexbelow = 7698; e.Dcroat = 272; e.Ddotaccent = 7690; e.Ddotbelow = 7692; e.Decyrillic = 1044; e.Deicoptic = 1006; e.Delta = 8710; e.Deltagreek = 916; e.Dhook = 394; e.Dieresis = 63179; e.DieresisAcute = 63180; e.DieresisGrave = 63181; e.Dieresissmall = 63400; e.Digammagreek = 988; e.Djecyrillic = 1026; e.Dlinebelow = 7694; e.Dmonospace = 65316; e.Dotaccentsmall = 63223; e.Dslash = 272; e.Dsmall = 63332; e.Dtopbar = 395; e.Dz = 498; e.Dzcaron = 453; e.Dzeabkhasiancyrillic = 1248; e.Dzecyrillic = 1029; e.Dzhecyrillic = 1039; e.E = 69; e.Eacute = 201; e.Eacutesmall = 63465; e.Ebreve = 276; e.Ecaron = 282; e.Ecedillabreve = 7708; e.Echarmenian = 1333; e.Ecircle = 9402; e.Ecircumflex = 202; e.Ecircumflexacute = 7870; e.Ecircumflexbelow = 7704; e.Ecircumflexdotbelow = 7878; e.Ecircumflexgrave = 7872; e.Ecircumflexhookabove = 7874; e.Ecircumflexsmall = 63466; e.Ecircumflextilde = 7876; e.Ecyrillic = 1028; e.Edblgrave = 516; e.Edieresis = 203; e.Edieresissmall = 63467; e.Edot = 278; e.Edotaccent = 278; e.Edotbelow = 7864; e.Efcyrillic = 1060; e.Egrave = 200; e.Egravesmall = 63464; e.Eharmenian = 1335; e.Ehookabove = 7866; e.Eightroman = 8551; e.Einvertedbreve = 518; e.Eiotifiedcyrillic = 1124; e.Elcyrillic = 1051; e.Elevenroman = 8554; e.Emacron = 274; e.Emacronacute = 7702; e.Emacrongrave = 7700; e.Emcyrillic = 1052; e.Emonospace = 65317; e.Encyrillic = 1053; e.Endescendercyrillic = 1186; e.Eng = 330; e.Enghecyrillic = 1188; e.Enhookcyrillic = 1223; e.Eogonek = 280; e.Eopen = 400; e.Epsilon = 917; e.Epsilontonos = 904; e.Ercyrillic = 1056; e.Ereversed = 398; e.Ereversedcyrillic = 1069; e.Escyrillic = 1057; e.Esdescendercyrillic = 1194; e.Esh = 425; e.Esmall = 63333; e.Eta = 919; e.Etarmenian = 1336; e.Etatonos = 905; e.Eth = 208; e.Ethsmall = 63472; e.Etilde = 7868; e.Etildebelow = 7706; e.Euro = 8364; e.Ezh = 439; e.Ezhcaron = 494; e.Ezhreversed = 440; e.F = 70; e.Fcircle = 9403; e.Fdotaccent = 7710; e.Feharmenian = 1366; e.Feicoptic = 996; e.Fhook = 401; e.Fitacyrillic = 1138; e.Fiveroman = 8548; e.Fmonospace = 65318; e.Fourroman = 8547; e.Fsmall = 63334; e.G = 71; e.GBsquare = 13191; e.Gacute = 500; e.Gamma = 915; e.Gammaafrican = 404; e.Gangiacoptic = 1002; e.Gbreve = 286; e.Gcaron = 486; e.Gcedilla = 290; e.Gcircle = 9404; e.Gcircumflex = 284; e.Gcommaaccent = 290; e.Gdot = 288; e.Gdotaccent = 288; e.Gecyrillic = 1043; e.Ghadarmenian = 1346; e.Ghemiddlehookcyrillic = 1172; e.Ghestrokecyrillic = 1170; e.Gheupturncyrillic = 1168; e.Ghook = 403; e.Gimarmenian = 1331; e.Gjecyrillic = 1027; e.Gmacron = 7712; e.Gmonospace = 65319; e.Grave = 63182; e.Gravesmall = 63328; e.Gsmall = 63335; e.Gsmallhook = 667; e.Gstroke = 484; e.H = 72; e.H18533 = 9679; e.H18543 = 9642; e.H18551 = 9643; e.H22073 = 9633; e.HPsquare = 13259; e.Haabkhasiancyrillic = 1192; e.Hadescendercyrillic = 1202; e.Hardsigncyrillic = 1066; e.Hbar = 294; e.Hbrevebelow = 7722; e.Hcedilla = 7720; e.Hcircle = 9405; e.Hcircumflex = 292; e.Hdieresis = 7718; e.Hdotaccent = 7714; e.Hdotbelow = 7716; e.Hmonospace = 65320; e.Hoarmenian = 1344; e.Horicoptic = 1e3; e.Hsmall = 63336; e.Hungarumlaut = 63183; e.Hungarumlautsmall = 63224; e.Hzsquare = 13200; e.I = 73; e.IAcyrillic = 1071; e.IJ = 306; e.IUcyrillic = 1070; e.Iacute = 205; e.Iacutesmall = 63469; e.Ibreve = 300; e.Icaron = 463; e.Icircle = 9406; e.Icircumflex = 206; e.Icircumflexsmall = 63470; e.Icyrillic = 1030; e.Idblgrave = 520; e.Idieresis = 207; e.Idieresisacute = 7726; e.Idieresiscyrillic = 1252; e.Idieresissmall = 63471; e.Idot = 304; e.Idotaccent = 304; e.Idotbelow = 7882; e.Iebrevecyrillic = 1238; e.Iecyrillic = 1045; e.Ifraktur = 8465; e.Igrave = 204; e.Igravesmall = 63468; e.Ihookabove = 7880; e.Iicyrillic = 1048; e.Iinvertedbreve = 522; e.Iishortcyrillic = 1049; e.Imacron = 298; e.Imacroncyrillic = 1250; e.Imonospace = 65321; e.Iniarmenian = 1339; e.Iocyrillic = 1025; e.Iogonek = 302; e.Iota = 921; e.Iotaafrican = 406; e.Iotadieresis = 938; e.Iotatonos = 906; e.Ismall = 63337; e.Istroke = 407; e.Itilde = 296; e.Itildebelow = 7724; e.Izhitsacyrillic = 1140; e.Izhitsadblgravecyrillic = 1142; e.J = 74; e.Jaarmenian = 1345; e.Jcircle = 9407; e.Jcircumflex = 308; e.Jecyrillic = 1032; e.Jheharmenian = 1355; e.Jmonospace = 65322; e.Jsmall = 63338; e.K = 75; e.KBsquare = 13189; e.KKsquare = 13261; e.Kabashkircyrillic = 1184; e.Kacute = 7728; e.Kacyrillic = 1050; e.Kadescendercyrillic = 1178; e.Kahookcyrillic = 1219; e.Kappa = 922; e.Kastrokecyrillic = 1182; e.Kaverticalstrokecyrillic = 1180; e.Kcaron = 488; e.Kcedilla = 310; e.Kcircle = 9408; e.Kcommaaccent = 310; e.Kdotbelow = 7730; e.Keharmenian = 1364; e.Kenarmenian = 1343; e.Khacyrillic = 1061; e.Kheicoptic = 998; e.Khook = 408; e.Kjecyrillic = 1036; e.Klinebelow = 7732; e.Kmonospace = 65323; e.Koppacyrillic = 1152; e.Koppagreek = 990; e.Ksicyrillic = 1134; e.Ksmall = 63339; e.L = 76; e.LJ = 455; e.LL = 63167; e.Lacute = 313; e.Lambda = 923; e.Lcaron = 317; e.Lcedilla = 315; e.Lcircle = 9409; e.Lcircumflexbelow = 7740; e.Lcommaaccent = 315; e.Ldot = 319; e.Ldotaccent = 319; e.Ldotbelow = 7734; e.Ldotbelowmacron = 7736; e.Liwnarmenian = 1340; e.Lj = 456; e.Ljecyrillic = 1033; e.Llinebelow = 7738; e.Lmonospace = 65324; e.Lslash = 321; e.Lslashsmall = 63225; e.Lsmall = 63340; e.M = 77; e.MBsquare = 13190; e.Macron = 63184; e.Macronsmall = 63407; e.Macute = 7742; e.Mcircle = 9410; e.Mdotaccent = 7744; e.Mdotbelow = 7746; e.Menarmenian = 1348; e.Mmonospace = 65325; e.Msmall = 63341; e.Mturned = 412; e.Mu = 924; e.N = 78; e.NJ = 458; e.Nacute = 323; e.Ncaron = 327; e.Ncedilla = 325; e.Ncircle = 9411; e.Ncircumflexbelow = 7754; e.Ncommaaccent = 325; e.Ndotaccent = 7748; e.Ndotbelow = 7750; e.Nhookleft = 413; e.Nineroman = 8552; e.Nj = 459; e.Njecyrillic = 1034; e.Nlinebelow = 7752; e.Nmonospace = 65326; e.Nowarmenian = 1350; e.Nsmall = 63342; e.Ntilde = 209; e.Ntildesmall = 63473; e.Nu = 925; e.O = 79; e.OE = 338; e.OEsmall = 63226; e.Oacute = 211; e.Oacutesmall = 63475; e.Obarredcyrillic = 1256; e.Obarreddieresiscyrillic = 1258; e.Obreve = 334; e.Ocaron = 465; e.Ocenteredtilde = 415; e.Ocircle = 9412; e.Ocircumflex = 212; e.Ocircumflexacute = 7888; e.Ocircumflexdotbelow = 7896; e.Ocircumflexgrave = 7890; e.Ocircumflexhookabove = 7892; e.Ocircumflexsmall = 63476; e.Ocircumflextilde = 7894; e.Ocyrillic = 1054; e.Odblacute = 336; e.Odblgrave = 524; e.Odieresis = 214; e.Odieresiscyrillic = 1254; e.Odieresissmall = 63478; e.Odotbelow = 7884; e.Ogoneksmall = 63227; e.Ograve = 210; e.Ogravesmall = 63474; e.Oharmenian = 1365; e.Ohm = 8486; e.Ohookabove = 7886; e.Ohorn = 416; e.Ohornacute = 7898; e.Ohorndotbelow = 7906; e.Ohorngrave = 7900; e.Ohornhookabove = 7902; e.Ohorntilde = 7904; e.Ohungarumlaut = 336; e.Oi = 418; e.Oinvertedbreve = 526; e.Omacron = 332; e.Omacronacute = 7762; e.Omacrongrave = 7760; e.Omega = 8486; e.Omegacyrillic = 1120; e.Omegagreek = 937; e.Omegaroundcyrillic = 1146; e.Omegatitlocyrillic = 1148; e.Omegatonos = 911; e.Omicron = 927; e.Omicrontonos = 908; e.Omonospace = 65327; e.Oneroman = 8544; e.Oogonek = 490; e.Oogonekmacron = 492; e.Oopen = 390; e.Oslash = 216; e.Oslashacute = 510; e.Oslashsmall = 63480; e.Osmall = 63343; e.Ostrokeacute = 510; e.Otcyrillic = 1150; e.Otilde = 213; e.Otildeacute = 7756; e.Otildedieresis = 7758; e.Otildesmall = 63477; e.P = 80; e.Pacute = 7764; e.Pcircle = 9413; e.Pdotaccent = 7766; e.Pecyrillic = 1055; e.Peharmenian = 1354; e.Pemiddlehookcyrillic = 1190; e.Phi = 934; e.Phook = 420; e.Pi = 928; e.Piwrarmenian = 1363; e.Pmonospace = 65328; e.Psi = 936; e.Psicyrillic = 1136; e.Psmall = 63344; e.Q = 81; e.Qcircle = 9414; e.Qmonospace = 65329; e.Qsmall = 63345; e.R = 82; e.Raarmenian = 1356; e.Racute = 340; e.Rcaron = 344; e.Rcedilla = 342; e.Rcircle = 9415; e.Rcommaaccent = 342; e.Rdblgrave = 528; e.Rdotaccent = 7768; e.Rdotbelow = 7770; e.Rdotbelowmacron = 7772; e.Reharmenian = 1360; e.Rfraktur = 8476; e.Rho = 929; e.Ringsmall = 63228; e.Rinvertedbreve = 530; e.Rlinebelow = 7774; e.Rmonospace = 65330; e.Rsmall = 63346; e.Rsmallinverted = 641; e.Rsmallinvertedsuperior = 694; e.S = 83; e.SF010000 = 9484; e.SF020000 = 9492; e.SF030000 = 9488; e.SF040000 = 9496; e.SF050000 = 9532; e.SF060000 = 9516; e.SF070000 = 9524; e.SF080000 = 9500; e.SF090000 = 9508; e.SF100000 = 9472; e.SF110000 = 9474; e.SF190000 = 9569; e.SF200000 = 9570; e.SF210000 = 9558; e.SF220000 = 9557; e.SF230000 = 9571; e.SF240000 = 9553; e.SF250000 = 9559; e.SF260000 = 9565; e.SF270000 = 9564; e.SF280000 = 9563; e.SF360000 = 9566; e.SF370000 = 9567; e.SF380000 = 9562; e.SF390000 = 9556; e.SF400000 = 9577; e.SF410000 = 9574; e.SF420000 = 9568; e.SF430000 = 9552; e.SF440000 = 9580; e.SF450000 = 9575; e.SF460000 = 9576; e.SF470000 = 9572; e.SF480000 = 9573; e.SF490000 = 9561; e.SF500000 = 9560; e.SF510000 = 9554; e.SF520000 = 9555; e.SF530000 = 9579; e.SF540000 = 9578; e.Sacute = 346; e.Sacutedotaccent = 7780; e.Sampigreek = 992; e.Scaron = 352; e.Scarondotaccent = 7782; e.Scaronsmall = 63229; e.Scedilla = 350; e.Schwa = 399; e.Schwacyrillic = 1240; e.Schwadieresiscyrillic = 1242; e.Scircle = 9416; e.Scircumflex = 348; e.Scommaaccent = 536; e.Sdotaccent = 7776; e.Sdotbelow = 7778; e.Sdotbelowdotaccent = 7784; e.Seharmenian = 1357; e.Sevenroman = 8550; e.Shaarmenian = 1351; e.Shacyrillic = 1064; e.Shchacyrillic = 1065; e.Sheicoptic = 994; e.Shhacyrillic = 1210; e.Shimacoptic = 1004; e.Sigma = 931; e.Sixroman = 8549; e.Smonospace = 65331; e.Softsigncyrillic = 1068; e.Ssmall = 63347; e.Stigmagreek = 986; e.T = 84; e.Tau = 932; e.Tbar = 358; e.Tcaron = 356; e.Tcedilla = 354; e.Tcircle = 9417; e.Tcircumflexbelow = 7792; e.Tcommaaccent = 354; e.Tdotaccent = 7786; e.Tdotbelow = 7788; e.Tecyrillic = 1058; e.Tedescendercyrillic = 1196; e.Tenroman = 8553; e.Tetsecyrillic = 1204; e.Theta = 920; e.Thook = 428; e.Thorn = 222; e.Thornsmall = 63486; e.Threeroman = 8546; e.Tildesmall = 63230; e.Tiwnarmenian = 1359; e.Tlinebelow = 7790; e.Tmonospace = 65332; e.Toarmenian = 1337; e.Tonefive = 444; e.Tonesix = 388; e.Tonetwo = 423; e.Tretroflexhook = 430; e.Tsecyrillic = 1062; e.Tshecyrillic = 1035; e.Tsmall = 63348; e.Twelveroman = 8555; e.Tworoman = 8545; e.U = 85; e.Uacute = 218; e.Uacutesmall = 63482; e.Ubreve = 364; e.Ucaron = 467; e.Ucircle = 9418; e.Ucircumflex = 219; e.Ucircumflexbelow = 7798; e.Ucircumflexsmall = 63483; e.Ucyrillic = 1059; e.Udblacute = 368; e.Udblgrave = 532; e.Udieresis = 220; e.Udieresisacute = 471; e.Udieresisbelow = 7794; e.Udieresiscaron = 473; e.Udieresiscyrillic = 1264; e.Udieresisgrave = 475; e.Udieresismacron = 469; e.Udieresissmall = 63484; e.Udotbelow = 7908; e.Ugrave = 217; e.Ugravesmall = 63481; e.Uhookabove = 7910; e.Uhorn = 431; e.Uhornacute = 7912; e.Uhorndotbelow = 7920; e.Uhorngrave = 7914; e.Uhornhookabove = 7916; e.Uhorntilde = 7918; e.Uhungarumlaut = 368; e.Uhungarumlautcyrillic = 1266; e.Uinvertedbreve = 534; e.Ukcyrillic = 1144; e.Umacron = 362; e.Umacroncyrillic = 1262; e.Umacrondieresis = 7802; e.Umonospace = 65333; e.Uogonek = 370; e.Upsilon = 933; e.Upsilon1 = 978; e.Upsilonacutehooksymbolgreek = 979; e.Upsilonafrican = 433; e.Upsilondieresis = 939; e.Upsilondieresishooksymbolgreek = 980; e.Upsilonhooksymbol = 978; e.Upsilontonos = 910; e.Uring = 366; e.Ushortcyrillic = 1038; e.Usmall = 63349; e.Ustraightcyrillic = 1198; e.Ustraightstrokecyrillic = 1200; e.Utilde = 360; e.Utildeacute = 7800; e.Utildebelow = 7796; e.V = 86; e.Vcircle = 9419; e.Vdotbelow = 7806; e.Vecyrillic = 1042; e.Vewarmenian = 1358; e.Vhook = 434; e.Vmonospace = 65334; e.Voarmenian = 1352; e.Vsmall = 63350; e.Vtilde = 7804; e.W = 87; e.Wacute = 7810; e.Wcircle = 9420; e.Wcircumflex = 372; e.Wdieresis = 7812; e.Wdotaccent = 7814; e.Wdotbelow = 7816; e.Wgrave = 7808; e.Wmonospace = 65335; e.Wsmall = 63351; e.X = 88; e.Xcircle = 9421; e.Xdieresis = 7820; e.Xdotaccent = 7818; e.Xeharmenian = 1341; e.Xi = 926; e.Xmonospace = 65336; e.Xsmall = 63352; e.Y = 89; e.Yacute = 221; e.Yacutesmall = 63485; e.Yatcyrillic = 1122; e.Ycircle = 9422; e.Ycircumflex = 374; e.Ydieresis = 376; e.Ydieresissmall = 63487; e.Ydotaccent = 7822; e.Ydotbelow = 7924; e.Yericyrillic = 1067; e.Yerudieresiscyrillic = 1272; e.Ygrave = 7922; e.Yhook = 435; e.Yhookabove = 7926; e.Yiarmenian = 1349; e.Yicyrillic = 1031; e.Yiwnarmenian = 1362; e.Ymonospace = 65337; e.Ysmall = 63353; e.Ytilde = 7928; e.Yusbigcyrillic = 1130; e.Yusbigiotifiedcyrillic = 1132; e.Yuslittlecyrillic = 1126; e.Yuslittleiotifiedcyrillic = 1128; e.Z = 90; e.Zaarmenian = 1334; e.Zacute = 377; e.Zcaron = 381; e.Zcaronsmall = 63231; e.Zcircle = 9423; e.Zcircumflex = 7824; e.Zdot = 379; e.Zdotaccent = 379; e.Zdotbelow = 7826; e.Zecyrillic = 1047; e.Zedescendercyrillic = 1176; e.Zedieresiscyrillic = 1246; e.Zeta = 918; e.Zhearmenian = 1338; e.Zhebrevecyrillic = 1217; e.Zhecyrillic = 1046; e.Zhedescendercyrillic = 1174; e.Zhedieresiscyrillic = 1244; e.Zlinebelow = 7828; e.Zmonospace = 65338; e.Zsmall = 63354; e.Zstroke = 437; e.a = 97; e.aabengali = 2438; e.aacute = 225; e.aadeva = 2310; e.aagujarati = 2694; e.aagurmukhi = 2566; e.aamatragurmukhi = 2622; e.aarusquare = 13059; e.aavowelsignbengali = 2494; e.aavowelsigndeva = 2366; e.aavowelsigngujarati = 2750; e.abbreviationmarkarmenian = 1375; e.abbreviationsigndeva = 2416; e.abengali = 2437; e.abopomofo = 12570; e.abreve = 259; e.abreveacute = 7855; e.abrevecyrillic = 1233; e.abrevedotbelow = 7863; e.abrevegrave = 7857; e.abrevehookabove = 7859; e.abrevetilde = 7861; e.acaron = 462; e.acircle = 9424; e.acircumflex = 226; e.acircumflexacute = 7845; e.acircumflexdotbelow = 7853; e.acircumflexgrave = 7847; e.acircumflexhookabove = 7849; e.acircumflextilde = 7851; e.acute = 180; e.acutebelowcmb = 791; e.acutecmb = 769; e.acutecomb = 769; e.acutedeva = 2388; e.acutelowmod = 719; e.acutetonecmb = 833; e.acyrillic = 1072; e.adblgrave = 513; e.addakgurmukhi = 2673; e.adeva = 2309; e.adieresis = 228; e.adieresiscyrillic = 1235; e.adieresismacron = 479; e.adotbelow = 7841; e.adotmacron = 481; e.ae = 230; e.aeacute = 509; e.aekorean = 12624; e.aemacron = 483; e.afii00208 = 8213; e.afii08941 = 8356; e.afii10017 = 1040; e.afii10018 = 1041; e.afii10019 = 1042; e.afii10020 = 1043; e.afii10021 = 1044; e.afii10022 = 1045; e.afii10023 = 1025; e.afii10024 = 1046; e.afii10025 = 1047; e.afii10026 = 1048; e.afii10027 = 1049; e.afii10028 = 1050; e.afii10029 = 1051; e.afii10030 = 1052; e.afii10031 = 1053; e.afii10032 = 1054; e.afii10033 = 1055; e.afii10034 = 1056; e.afii10035 = 1057; e.afii10036 = 1058; e.afii10037 = 1059; e.afii10038 = 1060; e.afii10039 = 1061; e.afii10040 = 1062; e.afii10041 = 1063; e.afii10042 = 1064; e.afii10043 = 1065; e.afii10044 = 1066; e.afii10045 = 1067; e.afii10046 = 1068; e.afii10047 = 1069; e.afii10048 = 1070; e.afii10049 = 1071; e.afii10050 = 1168; e.afii10051 = 1026; e.afii10052 = 1027; e.afii10053 = 1028; e.afii10054 = 1029; e.afii10055 = 1030; e.afii10056 = 1031; e.afii10057 = 1032; e.afii10058 = 1033; e.afii10059 = 1034; e.afii10060 = 1035; e.afii10061 = 1036; e.afii10062 = 1038; e.afii10063 = 63172; e.afii10064 = 63173; e.afii10065 = 1072; e.afii10066 = 1073; e.afii10067 = 1074; e.afii10068 = 1075; e.afii10069 = 1076; e.afii10070 = 1077; e.afii10071 = 1105; e.afii10072 = 1078; e.afii10073 = 1079; e.afii10074 = 1080; e.afii10075 = 1081; e.afii10076 = 1082; e.afii10077 = 1083; e.afii10078 = 1084; e.afii10079 = 1085; e.afii10080 = 1086; e.afii10081 = 1087; e.afii10082 = 1088; e.afii10083 = 1089; e.afii10084 = 1090; e.afii10085 = 1091; e.afii10086 = 1092; e.afii10087 = 1093; e.afii10088 = 1094; e.afii10089 = 1095; e.afii10090 = 1096; e.afii10091 = 1097; e.afii10092 = 1098; e.afii10093 = 1099; e.afii10094 = 1100; e.afii10095 = 1101; e.afii10096 = 1102; e.afii10097 = 1103; e.afii10098 = 1169; e.afii10099 = 1106; e.afii10100 = 1107; e.afii10101 = 1108; e.afii10102 = 1109; e.afii10103 = 1110; e.afii10104 = 1111; e.afii10105 = 1112; e.afii10106 = 1113; e.afii10107 = 1114; e.afii10108 = 1115; e.afii10109 = 1116; e.afii10110 = 1118; e.afii10145 = 1039; e.afii10146 = 1122; e.afii10147 = 1138; e.afii10148 = 1140; e.afii10192 = 63174; e.afii10193 = 1119; e.afii10194 = 1123; e.afii10195 = 1139; e.afii10196 = 1141; e.afii10831 = 63175; e.afii10832 = 63176; e.afii10846 = 1241; e.afii299 = 8206; e.afii300 = 8207; e.afii301 = 8205; e.afii57381 = 1642; e.afii57388 = 1548; e.afii57392 = 1632; e.afii57393 = 1633; e.afii57394 = 1634; e.afii57395 = 1635; e.afii57396 = 1636; e.afii57397 = 1637; e.afii57398 = 1638; e.afii57399 = 1639; e.afii57400 = 1640; e.afii57401 = 1641; e.afii57403 = 1563; e.afii57407 = 1567; e.afii57409 = 1569; e.afii57410 = 1570; e.afii57411 = 1571; e.afii57412 = 1572; e.afii57413 = 1573; e.afii57414 = 1574; e.afii57415 = 1575; e.afii57416 = 1576; e.afii57417 = 1577; e.afii57418 = 1578; e.afii57419 = 1579; e.afii57420 = 1580; e.afii57421 = 1581; e.afii57422 = 1582; e.afii57423 = 1583; e.afii57424 = 1584; e.afii57425 = 1585; e.afii57426 = 1586; e.afii57427 = 1587; e.afii57428 = 1588; e.afii57429 = 1589; e.afii57430 = 1590; e.afii57431 = 1591; e.afii57432 = 1592; e.afii57433 = 1593; e.afii57434 = 1594; e.afii57440 = 1600; e.afii57441 = 1601; e.afii57442 = 1602; e.afii57443 = 1603; e.afii57444 = 1604; e.afii57445 = 1605; e.afii57446 = 1606; e.afii57448 = 1608; e.afii57449 = 1609; e.afii57450 = 1610; e.afii57451 = 1611; e.afii57452 = 1612; e.afii57453 = 1613; e.afii57454 = 1614; e.afii57455 = 1615; e.afii57456 = 1616; e.afii57457 = 1617; e.afii57458 = 1618; e.afii57470 = 1607; e.afii57505 = 1700; e.afii57506 = 1662; e.afii57507 = 1670; e.afii57508 = 1688; e.afii57509 = 1711; e.afii57511 = 1657; e.afii57512 = 1672; e.afii57513 = 1681; e.afii57514 = 1722; e.afii57519 = 1746; e.afii57534 = 1749; e.afii57636 = 8362; e.afii57645 = 1470; e.afii57658 = 1475; e.afii57664 = 1488; e.afii57665 = 1489; e.afii57666 = 1490; e.afii57667 = 1491; e.afii57668 = 1492; e.afii57669 = 1493; e.afii57670 = 1494; e.afii57671 = 1495; e.afii57672 = 1496; e.afii57673 = 1497; e.afii57674 = 1498; e.afii57675 = 1499; e.afii57676 = 1500; e.afii57677 = 1501; e.afii57678 = 1502; e.afii57679 = 1503; e.afii57680 = 1504; e.afii57681 = 1505; e.afii57682 = 1506; e.afii57683 = 1507; e.afii57684 = 1508; e.afii57685 = 1509; e.afii57686 = 1510; e.afii57687 = 1511; e.afii57688 = 1512; e.afii57689 = 1513; e.afii57690 = 1514; e.afii57694 = 64298; e.afii57695 = 64299; e.afii57700 = 64331; e.afii57705 = 64287; e.afii57716 = 1520; e.afii57717 = 1521; e.afii57718 = 1522; e.afii57723 = 64309; e.afii57793 = 1460; e.afii57794 = 1461; e.afii57795 = 1462; e.afii57796 = 1467; e.afii57797 = 1464; e.afii57798 = 1463; e.afii57799 = 1456; e.afii57800 = 1458; e.afii57801 = 1457; e.afii57802 = 1459; e.afii57803 = 1474; e.afii57804 = 1473; e.afii57806 = 1465; e.afii57807 = 1468; e.afii57839 = 1469; e.afii57841 = 1471; e.afii57842 = 1472; e.afii57929 = 700; e.afii61248 = 8453; e.afii61289 = 8467; e.afii61352 = 8470; e.afii61573 = 8236; e.afii61574 = 8237; e.afii61575 = 8238; e.afii61664 = 8204; e.afii63167 = 1645; e.afii64937 = 701; e.agrave = 224; e.agujarati = 2693; e.agurmukhi = 2565; e.ahiragana = 12354; e.ahookabove = 7843; e.aibengali = 2448; e.aibopomofo = 12574; e.aideva = 2320; e.aiecyrillic = 1237; e.aigujarati = 2704; e.aigurmukhi = 2576; e.aimatragurmukhi = 2632; e.ainarabic = 1593; e.ainfinalarabic = 65226; e.aininitialarabic = 65227; e.ainmedialarabic = 65228; e.ainvertedbreve = 515; e.aivowelsignbengali = 2504; e.aivowelsigndeva = 2376; e.aivowelsigngujarati = 2760; e.akatakana = 12450; e.akatakanahalfwidth = 65393; e.akorean = 12623; e.alef = 1488; e.alefarabic = 1575; e.alefdageshhebrew = 64304; e.aleffinalarabic = 65166; e.alefhamzaabovearabic = 1571; e.alefhamzaabovefinalarabic = 65156; e.alefhamzabelowarabic = 1573; e.alefhamzabelowfinalarabic = 65160; e.alefhebrew = 1488; e.aleflamedhebrew = 64335; e.alefmaddaabovearabic = 1570; e.alefmaddaabovefinalarabic = 65154; e.alefmaksuraarabic = 1609; e.alefmaksurafinalarabic = 65264; e.alefmaksurainitialarabic = 65267; e.alefmaksuramedialarabic = 65268; e.alefpatahhebrew = 64302; e.alefqamatshebrew = 64303; e.aleph = 8501; e.allequal = 8780; e.alpha = 945; e.alphatonos = 940; e.amacron = 257; e.amonospace = 65345; e.ampersand = 38; e.ampersandmonospace = 65286; e.ampersandsmall = 63270; e.amsquare = 13250; e.anbopomofo = 12578; e.angbopomofo = 12580; e.angbracketleft = 12296; e.angbracketright = 12297; e.angkhankhuthai = 3674; e.angle = 8736; e.anglebracketleft = 12296; e.anglebracketleftvertical = 65087; e.anglebracketright = 12297; e.anglebracketrightvertical = 65088; e.angleleft = 9001; e.angleright = 9002; e.angstrom = 8491; e.anoteleia = 903; e.anudattadeva = 2386; e.anusvarabengali = 2434; e.anusvaradeva = 2306; e.anusvaragujarati = 2690; e.aogonek = 261; e.apaatosquare = 13056; e.aparen = 9372; e.apostrophearmenian = 1370; e.apostrophemod = 700; e.apple = 63743; e.approaches = 8784; e.approxequal = 8776; e.approxequalorimage = 8786; e.approximatelyequal = 8773; e.araeaekorean = 12686; e.araeakorean = 12685; e.arc = 8978; e.arighthalfring = 7834; e.aring = 229; e.aringacute = 507; e.aringbelow = 7681; e.arrowboth = 8596; e.arrowdashdown = 8675; e.arrowdashleft = 8672; e.arrowdashright = 8674; e.arrowdashup = 8673; e.arrowdblboth = 8660; e.arrowdbldown = 8659; e.arrowdblleft = 8656; e.arrowdblright = 8658; e.arrowdblup = 8657; e.arrowdown = 8595; e.arrowdownleft = 8601; e.arrowdownright = 8600; e.arrowdownwhite = 8681; e.arrowheaddownmod = 709; e.arrowheadleftmod = 706; e.arrowheadrightmod = 707; e.arrowheadupmod = 708; e.arrowhorizex = 63719; e.arrowleft = 8592; e.arrowleftdbl = 8656; e.arrowleftdblstroke = 8653; e.arrowleftoverright = 8646; e.arrowleftwhite = 8678; e.arrowright = 8594; e.arrowrightdblstroke = 8655; e.arrowrightheavy = 10142; e.arrowrightoverleft = 8644; e.arrowrightwhite = 8680; e.arrowtableft = 8676; e.arrowtabright = 8677; e.arrowup = 8593; e.arrowupdn = 8597; e.arrowupdnbse = 8616; e.arrowupdownbase = 8616; e.arrowupleft = 8598; e.arrowupleftofdown = 8645; e.arrowupright = 8599; e.arrowupwhite = 8679; e.arrowvertex = 63718; e.asciicircum = 94; e.asciicircummonospace = 65342; e.asciitilde = 126; e.asciitildemonospace = 65374; e.ascript = 593; e.ascriptturned = 594; e.asmallhiragana = 12353; e.asmallkatakana = 12449; e.asmallkatakanahalfwidth = 65383; e.asterisk = 42; e.asteriskaltonearabic = 1645; e.asteriskarabic = 1645; e.asteriskmath = 8727; e.asteriskmonospace = 65290; e.asterisksmall = 65121; e.asterism = 8258; e.asuperior = 63209; e.asymptoticallyequal = 8771; e.at = 64; e.atilde = 227; e.atmonospace = 65312; e.atsmall = 65131; e.aturned = 592; e.aubengali = 2452; e.aubopomofo = 12576; e.audeva = 2324; e.augujarati = 2708; e.augurmukhi = 2580; e.aulengthmarkbengali = 2519; e.aumatragurmukhi = 2636; e.auvowelsignbengali = 2508; e.auvowelsigndeva = 2380; e.auvowelsigngujarati = 2764; e.avagrahadeva = 2365; e.aybarmenian = 1377; e.ayin = 1506; e.ayinaltonehebrew = 64288; e.ayinhebrew = 1506; e.b = 98; e.babengali = 2476; e.backslash = 92; e.backslashmonospace = 65340; e.badeva = 2348; e.bagujarati = 2732; e.bagurmukhi = 2604; e.bahiragana = 12400; e.bahtthai = 3647; e.bakatakana = 12496; e.bar = 124; e.barmonospace = 65372; e.bbopomofo = 12549; e.bcircle = 9425; e.bdotaccent = 7683; e.bdotbelow = 7685; e.beamedsixteenthnotes = 9836; e.because = 8757; e.becyrillic = 1073; e.beharabic = 1576; e.behfinalarabic = 65168; e.behinitialarabic = 65169; e.behiragana = 12409; e.behmedialarabic = 65170; e.behmeeminitialarabic = 64671; e.behmeemisolatedarabic = 64520; e.behnoonfinalarabic = 64621; e.bekatakana = 12505; e.benarmenian = 1378; e.bet = 1489; e.beta = 946; e.betasymbolgreek = 976; e.betdagesh = 64305; e.betdageshhebrew = 64305; e.bethebrew = 1489; e.betrafehebrew = 64332; e.bhabengali = 2477; e.bhadeva = 2349; e.bhagujarati = 2733; e.bhagurmukhi = 2605; e.bhook = 595; e.bihiragana = 12403; e.bikatakana = 12499; e.bilabialclick = 664; e.bindigurmukhi = 2562; e.birusquare = 13105; e.blackcircle = 9679; e.blackdiamond = 9670; e.blackdownpointingtriangle = 9660; e.blackleftpointingpointer = 9668; e.blackleftpointingtriangle = 9664; e.blacklenticularbracketleft = 12304; e.blacklenticularbracketleftvertical = 65083; e.blacklenticularbracketright = 12305; e.blacklenticularbracketrightvertical = 65084; e.blacklowerlefttriangle = 9699; e.blacklowerrighttriangle = 9698; e.blackrectangle = 9644; e.blackrightpointingpointer = 9658; e.blackrightpointingtriangle = 9654; e.blacksmallsquare = 9642; e.blacksmilingface = 9787; e.blacksquare = 9632; e.blackstar = 9733; e.blackupperlefttriangle = 9700; e.blackupperrighttriangle = 9701; e.blackuppointingsmalltriangle = 9652; e.blackuppointingtriangle = 9650; e.blank = 9251; e.blinebelow = 7687; e.block = 9608; e.bmonospace = 65346; e.bobaimaithai = 3610; e.bohiragana = 12412; e.bokatakana = 12508; e.bparen = 9373; e.bqsquare = 13251; e.braceex = 63732; e.braceleft = 123; e.braceleftbt = 63731; e.braceleftmid = 63730; e.braceleftmonospace = 65371; e.braceleftsmall = 65115; e.bracelefttp = 63729; e.braceleftvertical = 65079; e.braceright = 125; e.bracerightbt = 63742; e.bracerightmid = 63741; e.bracerightmonospace = 65373; e.bracerightsmall = 65116; e.bracerighttp = 63740; e.bracerightvertical = 65080; e.bracketleft = 91; e.bracketleftbt = 63728; e.bracketleftex = 63727; e.bracketleftmonospace = 65339; e.bracketlefttp = 63726; e.bracketright = 93; e.bracketrightbt = 63739; e.bracketrightex = 63738; e.bracketrightmonospace = 65341; e.bracketrighttp = 63737; e.breve = 728; e.brevebelowcmb = 814; e.brevecmb = 774; e.breveinvertedbelowcmb = 815; e.breveinvertedcmb = 785; e.breveinverteddoublecmb = 865; e.bridgebelowcmb = 810; e.bridgeinvertedbelowcmb = 826; e.brokenbar = 166; e.bstroke = 384; e.bsuperior = 63210; e.btopbar = 387; e.buhiragana = 12406; e.bukatakana = 12502; e.bullet = 8226; e.bulletinverse = 9688; e.bulletoperator = 8729; e.bullseye = 9678; e.c = 99; e.caarmenian = 1390; e.cabengali = 2458; e.cacute = 263; e.cadeva = 2330; e.cagujarati = 2714; e.cagurmukhi = 2586; e.calsquare = 13192; e.candrabindubengali = 2433; e.candrabinducmb = 784; e.candrabindudeva = 2305; e.candrabindugujarati = 2689; e.capslock = 8682; e.careof = 8453; e.caron = 711; e.caronbelowcmb = 812; e.caroncmb = 780; e.carriagereturn = 8629; e.cbopomofo = 12568; e.ccaron = 269; e.ccedilla = 231; e.ccedillaacute = 7689; e.ccircle = 9426; e.ccircumflex = 265; e.ccurl = 597; e.cdot = 267; e.cdotaccent = 267; e.cdsquare = 13253; e.cedilla = 184; e.cedillacmb = 807; e.cent = 162; e.centigrade = 8451; e.centinferior = 63199; e.centmonospace = 65504; e.centoldstyle = 63394; e.centsuperior = 63200; e.chaarmenian = 1401; e.chabengali = 2459; e.chadeva = 2331; e.chagujarati = 2715; e.chagurmukhi = 2587; e.chbopomofo = 12564; e.cheabkhasiancyrillic = 1213; e.checkmark = 10003; e.checyrillic = 1095; e.chedescenderabkhasiancyrillic = 1215; e.chedescendercyrillic = 1207; e.chedieresiscyrillic = 1269; e.cheharmenian = 1395; e.chekhakassiancyrillic = 1228; e.cheverticalstrokecyrillic = 1209; e.chi = 967; e.chieuchacirclekorean = 12919; e.chieuchaparenkorean = 12823; e.chieuchcirclekorean = 12905; e.chieuchkorean = 12618; e.chieuchparenkorean = 12809; e.chochangthai = 3594; e.chochanthai = 3592; e.chochingthai = 3593; e.chochoethai = 3596; e.chook = 392; e.cieucacirclekorean = 12918; e.cieucaparenkorean = 12822; e.cieuccirclekorean = 12904; e.cieuckorean = 12616; e.cieucparenkorean = 12808; e.cieucuparenkorean = 12828; e.circle = 9675; e.circlecopyrt = 169; e.circlemultiply = 8855; e.circleot = 8857; e.circleplus = 8853; e.circlepostalmark = 12342; e.circlewithlefthalfblack = 9680; e.circlewithrighthalfblack = 9681; e.circumflex = 710; e.circumflexbelowcmb = 813; e.circumflexcmb = 770; e.clear = 8999; e.clickalveolar = 450; e.clickdental = 448; e.clicklateral = 449; e.clickretroflex = 451; e.club = 9827; e.clubsuitblack = 9827; e.clubsuitwhite = 9831; e.cmcubedsquare = 13220; e.cmonospace = 65347; e.cmsquaredsquare = 13216; e.coarmenian = 1409; e.colon = 58; e.colonmonetary = 8353; e.colonmonospace = 65306; e.colonsign = 8353; e.colonsmall = 65109; e.colontriangularhalfmod = 721; e.colontriangularmod = 720; e.comma = 44; e.commaabovecmb = 787; e.commaaboverightcmb = 789; e.commaaccent = 63171; e.commaarabic = 1548; e.commaarmenian = 1373; e.commainferior = 63201; e.commamonospace = 65292; e.commareversedabovecmb = 788; e.commareversedmod = 701; e.commasmall = 65104; e.commasuperior = 63202; e.commaturnedabovecmb = 786; e.commaturnedmod = 699; e.compass = 9788; e.congruent = 8773; e.contourintegral = 8750; e.control = 8963; e.controlACK = 6; e.controlBEL = 7; e.controlBS = 8; e.controlCAN = 24; e.controlCR = 13; e.controlDC1 = 17; e.controlDC2 = 18; e.controlDC3 = 19; e.controlDC4 = 20; e.controlDEL = 127; e.controlDLE = 16; e.controlEM = 25; e.controlENQ = 5; e.controlEOT = 4; e.controlESC = 27; e.controlETB = 23; e.controlETX = 3; e.controlFF = 12; e.controlFS = 28; e.controlGS = 29; e.controlHT = 9; e.controlLF = 10; e.controlNAK = 21; e.controlNULL = 0; e.controlRS = 30; e.controlSI = 15; e.controlSO = 14; e.controlSOT = 2; e.controlSTX = 1; e.controlSUB = 26; e.controlSYN = 22; e.controlUS = 31; e.controlVT = 11; e.copyright = 169; e.copyrightsans = 63721; e.copyrightserif = 63193; e.cornerbracketleft = 12300; e.cornerbracketlefthalfwidth = 65378; e.cornerbracketleftvertical = 65089; e.cornerbracketright = 12301; e.cornerbracketrighthalfwidth = 65379; e.cornerbracketrightvertical = 65090; e.corporationsquare = 13183; e.cosquare = 13255; e.coverkgsquare = 13254; e.cparen = 9374; e.cruzeiro = 8354; e.cstretched = 663; e.curlyand = 8911; e.curlyor = 8910; e.currency = 164; e.cyrBreve = 63185; e.cyrFlex = 63186; e.cyrbreve = 63188; e.cyrflex = 63189; e.d = 100; e.daarmenian = 1380; e.dabengali = 2470; e.dadarabic = 1590; e.dadeva = 2342; e.dadfinalarabic = 65214; e.dadinitialarabic = 65215; e.dadmedialarabic = 65216; e.dagesh = 1468; e.dageshhebrew = 1468; e.dagger = 8224; e.daggerdbl = 8225; e.dagujarati = 2726; e.dagurmukhi = 2598; e.dahiragana = 12384; e.dakatakana = 12480; e.dalarabic = 1583; e.dalet = 1491; e.daletdagesh = 64307; e.daletdageshhebrew = 64307; e.dalethebrew = 1491; e.dalfinalarabic = 65194; e.dammaarabic = 1615; e.dammalowarabic = 1615; e.dammatanaltonearabic = 1612; e.dammatanarabic = 1612; e.danda = 2404; e.dargahebrew = 1447; e.dargalefthebrew = 1447; e.dasiapneumatacyrilliccmb = 1157; e.dblGrave = 63187; e.dblanglebracketleft = 12298; e.dblanglebracketleftvertical = 65085; e.dblanglebracketright = 12299; e.dblanglebracketrightvertical = 65086; e.dblarchinvertedbelowcmb = 811; e.dblarrowleft = 8660; e.dblarrowright = 8658; e.dbldanda = 2405; e.dblgrave = 63190; e.dblgravecmb = 783; e.dblintegral = 8748; e.dbllowline = 8215; e.dbllowlinecmb = 819; e.dbloverlinecmb = 831; e.dblprimemod = 698; e.dblverticalbar = 8214; e.dblverticallineabovecmb = 782; e.dbopomofo = 12553; e.dbsquare = 13256; e.dcaron = 271; e.dcedilla = 7697; e.dcircle = 9427; e.dcircumflexbelow = 7699; e.dcroat = 273; e.ddabengali = 2465; e.ddadeva = 2337; e.ddagujarati = 2721; e.ddagurmukhi = 2593; e.ddalarabic = 1672; e.ddalfinalarabic = 64393; e.dddhadeva = 2396; e.ddhabengali = 2466; e.ddhadeva = 2338; e.ddhagujarati = 2722; e.ddhagurmukhi = 2594; e.ddotaccent = 7691; e.ddotbelow = 7693; e.decimalseparatorarabic = 1643; e.decimalseparatorpersian = 1643; e.decyrillic = 1076; e.degree = 176; e.dehihebrew = 1453; e.dehiragana = 12391; e.deicoptic = 1007; e.dekatakana = 12487; e.deleteleft = 9003; e.deleteright = 8998; e.delta = 948; e.deltaturned = 397; e.denominatorminusonenumeratorbengali = 2552; e.dezh = 676; e.dhabengali = 2471; e.dhadeva = 2343; e.dhagujarati = 2727; e.dhagurmukhi = 2599; e.dhook = 599; e.dialytikatonos = 901; e.dialytikatonoscmb = 836; e.diamond = 9830; e.diamondsuitwhite = 9826; e.dieresis = 168; e.dieresisacute = 63191; e.dieresisbelowcmb = 804; e.dieresiscmb = 776; e.dieresisgrave = 63192; e.dieresistonos = 901; e.dihiragana = 12386; e.dikatakana = 12482; e.dittomark = 12291; e.divide = 247; e.divides = 8739; e.divisionslash = 8725; e.djecyrillic = 1106; e.dkshade = 9619; e.dlinebelow = 7695; e.dlsquare = 13207; e.dmacron = 273; e.dmonospace = 65348; e.dnblock = 9604; e.dochadathai = 3598; e.dodekthai = 3604; e.dohiragana = 12393; e.dokatakana = 12489; e.dollar = 36; e.dollarinferior = 63203; e.dollarmonospace = 65284; e.dollaroldstyle = 63268; e.dollarsmall = 65129; e.dollarsuperior = 63204; e.dong = 8363; e.dorusquare = 13094; e.dotaccent = 729; e.dotaccentcmb = 775; e.dotbelowcmb = 803; e.dotbelowcomb = 803; e.dotkatakana = 12539; e.dotlessi = 305; e.dotlessj = 63166; e.dotlessjstrokehook = 644; e.dotmath = 8901; e.dottedcircle = 9676; e.doubleyodpatah = 64287; e.doubleyodpatahhebrew = 64287; e.downtackbelowcmb = 798; e.downtackmod = 725; e.dparen = 9375; e.dsuperior = 63211; e.dtail = 598; e.dtopbar = 396; e.duhiragana = 12389; e.dukatakana = 12485; e.dz = 499; e.dzaltone = 675; e.dzcaron = 454; e.dzcurl = 677; e.dzeabkhasiancyrillic = 1249; e.dzecyrillic = 1109; e.dzhecyrillic = 1119; e.e = 101; e.eacute = 233; e.earth = 9793; e.ebengali = 2447; e.ebopomofo = 12572; e.ebreve = 277; e.ecandradeva = 2317; e.ecandragujarati = 2701; e.ecandravowelsigndeva = 2373; e.ecandravowelsigngujarati = 2757; e.ecaron = 283; e.ecedillabreve = 7709; e.echarmenian = 1381; e.echyiwnarmenian = 1415; e.ecircle = 9428; e.ecircumflex = 234; e.ecircumflexacute = 7871; e.ecircumflexbelow = 7705; e.ecircumflexdotbelow = 7879; e.ecircumflexgrave = 7873; e.ecircumflexhookabove = 7875; e.ecircumflextilde = 7877; e.ecyrillic = 1108; e.edblgrave = 517; e.edeva = 2319; e.edieresis = 235; e.edot = 279; e.edotaccent = 279; e.edotbelow = 7865; e.eegurmukhi = 2575; e.eematragurmukhi = 2631; e.efcyrillic = 1092; e.egrave = 232; e.egujarati = 2703; e.eharmenian = 1383; e.ehbopomofo = 12573; e.ehiragana = 12360; e.ehookabove = 7867; e.eibopomofo = 12575; e.eight = 56; e.eightarabic = 1640; e.eightbengali = 2542; e.eightcircle = 9319; e.eightcircleinversesansserif = 10129; e.eightdeva = 2414; e.eighteencircle = 9329; e.eighteenparen = 9349; e.eighteenperiod = 9369; e.eightgujarati = 2798; e.eightgurmukhi = 2670; e.eighthackarabic = 1640; e.eighthangzhou = 12328; e.eighthnotebeamed = 9835; e.eightideographicparen = 12839; e.eightinferior = 8328; e.eightmonospace = 65304; e.eightoldstyle = 63288; e.eightparen = 9339; e.eightperiod = 9359; e.eightpersian = 1784; e.eightroman = 8567; e.eightsuperior = 8312; e.eightthai = 3672; e.einvertedbreve = 519; e.eiotifiedcyrillic = 1125; e.ekatakana = 12456; e.ekatakanahalfwidth = 65396; e.ekonkargurmukhi = 2676; e.ekorean = 12628; e.elcyrillic = 1083; e.element = 8712; e.elevencircle = 9322; e.elevenparen = 9342; e.elevenperiod = 9362; e.elevenroman = 8570; e.ellipsis = 8230; e.ellipsisvertical = 8942; e.emacron = 275; e.emacronacute = 7703; e.emacrongrave = 7701; e.emcyrillic = 1084; e.emdash = 8212; e.emdashvertical = 65073; e.emonospace = 65349; e.emphasismarkarmenian = 1371; e.emptyset = 8709; e.enbopomofo = 12579; e.encyrillic = 1085; e.endash = 8211; e.endashvertical = 65074; e.endescendercyrillic = 1187; e.eng = 331; e.engbopomofo = 12581; e.enghecyrillic = 1189; e.enhookcyrillic = 1224; e.enspace = 8194; e.eogonek = 281; e.eokorean = 12627; e.eopen = 603; e.eopenclosed = 666; e.eopenreversed = 604; e.eopenreversedclosed = 606; e.eopenreversedhook = 605; e.eparen = 9376; e.epsilon = 949; e.epsilontonos = 941; e.equal = 61; e.equalmonospace = 65309; e.equalsmall = 65126; e.equalsuperior = 8316; e.equivalence = 8801; e.erbopomofo = 12582; e.ercyrillic = 1088; e.ereversed = 600; e.ereversedcyrillic = 1101; e.escyrillic = 1089; e.esdescendercyrillic = 1195; e.esh = 643; e.eshcurl = 646; e.eshortdeva = 2318; e.eshortvowelsigndeva = 2374; e.eshreversedloop = 426; e.eshsquatreversed = 645; e.esmallhiragana = 12359; e.esmallkatakana = 12455; e.esmallkatakanahalfwidth = 65386; e.estimated = 8494; e.esuperior = 63212; e.eta = 951; e.etarmenian = 1384; e.etatonos = 942; e.eth = 240; e.etilde = 7869; e.etildebelow = 7707; e.etnahtafoukhhebrew = 1425; e.etnahtafoukhlefthebrew = 1425; e.etnahtahebrew = 1425; e.etnahtalefthebrew = 1425; e.eturned = 477; e.eukorean = 12641; e.euro = 8364; e.evowelsignbengali = 2503; e.evowelsigndeva = 2375; e.evowelsigngujarati = 2759; e.exclam = 33; e.exclamarmenian = 1372; e.exclamdbl = 8252; e.exclamdown = 161; e.exclamdownsmall = 63393; e.exclammonospace = 65281; e.exclamsmall = 63265; e.existential = 8707; e.ezh = 658; e.ezhcaron = 495; e.ezhcurl = 659; e.ezhreversed = 441; e.ezhtail = 442; e.f = 102; e.fadeva = 2398; e.fagurmukhi = 2654; e.fahrenheit = 8457; e.fathaarabic = 1614; e.fathalowarabic = 1614; e.fathatanarabic = 1611; e.fbopomofo = 12552; e.fcircle = 9429; e.fdotaccent = 7711; e.feharabic = 1601; e.feharmenian = 1414; e.fehfinalarabic = 65234; e.fehinitialarabic = 65235; e.fehmedialarabic = 65236; e.feicoptic = 997; e.female = 9792; e.ff = 64256; e.f_f = 64256; e.ffi = 64259; e.ffl = 64260; e.fi = 64257; e.fifteencircle = 9326; e.fifteenparen = 9346; e.fifteenperiod = 9366; e.figuredash = 8210; e.filledbox = 9632; e.filledrect = 9644; e.finalkaf = 1498; e.finalkafdagesh = 64314; e.finalkafdageshhebrew = 64314; e.finalkafhebrew = 1498; e.finalmem = 1501; e.finalmemhebrew = 1501; e.finalnun = 1503; e.finalnunhebrew = 1503; e.finalpe = 1507; e.finalpehebrew = 1507; e.finaltsadi = 1509; e.finaltsadihebrew = 1509; e.firsttonechinese = 713; e.fisheye = 9673; e.fitacyrillic = 1139; e.five = 53; e.fivearabic = 1637; e.fivebengali = 2539; e.fivecircle = 9316; e.fivecircleinversesansserif = 10126; e.fivedeva = 2411; e.fiveeighths = 8541; e.fivegujarati = 2795; e.fivegurmukhi = 2667; e.fivehackarabic = 1637; e.fivehangzhou = 12325; e.fiveideographicparen = 12836; e.fiveinferior = 8325; e.fivemonospace = 65301; e.fiveoldstyle = 63285; e.fiveparen = 9336; e.fiveperiod = 9356; e.fivepersian = 1781; e.fiveroman = 8564; e.fivesuperior = 8309; e.fivethai = 3669; e.fl = 64258; e.florin = 402; e.fmonospace = 65350; e.fmsquare = 13209; e.fofanthai = 3615; e.fofathai = 3613; e.fongmanthai = 3663; e.forall = 8704; e.four = 52; e.fourarabic = 1636; e.fourbengali = 2538; e.fourcircle = 9315; e.fourcircleinversesansserif = 10125; e.fourdeva = 2410; e.fourgujarati = 2794; e.fourgurmukhi = 2666; e.fourhackarabic = 1636; e.fourhangzhou = 12324; e.fourideographicparen = 12835; e.fourinferior = 8324; e.fourmonospace = 65300; e.fournumeratorbengali = 2551; e.fouroldstyle = 63284; e.fourparen = 9335; e.fourperiod = 9355; e.fourpersian = 1780; e.fourroman = 8563; e.foursuperior = 8308; e.fourteencircle = 9325; e.fourteenparen = 9345; e.fourteenperiod = 9365; e.fourthai = 3668; e.fourthtonechinese = 715; e.fparen = 9377; e.fraction = 8260; e.franc = 8355; e.g = 103; e.gabengali = 2455; e.gacute = 501; e.gadeva = 2327; e.gafarabic = 1711; e.gaffinalarabic = 64403; e.gafinitialarabic = 64404; e.gafmedialarabic = 64405; e.gagujarati = 2711; e.gagurmukhi = 2583; e.gahiragana = 12364; e.gakatakana = 12460; e.gamma = 947; e.gammalatinsmall = 611; e.gammasuperior = 736; e.gangiacoptic = 1003; e.gbopomofo = 12557; e.gbreve = 287; e.gcaron = 487; e.gcedilla = 291; e.gcircle = 9430; e.gcircumflex = 285; e.gcommaaccent = 291; e.gdot = 289; e.gdotaccent = 289; e.gecyrillic = 1075; e.gehiragana = 12370; e.gekatakana = 12466; e.geometricallyequal = 8785; e.gereshaccenthebrew = 1436; e.gereshhebrew = 1523; e.gereshmuqdamhebrew = 1437; e.germandbls = 223; e.gershayimaccenthebrew = 1438; e.gershayimhebrew = 1524; e.getamark = 12307; e.ghabengali = 2456; e.ghadarmenian = 1394; e.ghadeva = 2328; e.ghagujarati = 2712; e.ghagurmukhi = 2584; e.ghainarabic = 1594; e.ghainfinalarabic = 65230; e.ghaininitialarabic = 65231; e.ghainmedialarabic = 65232; e.ghemiddlehookcyrillic = 1173; e.ghestrokecyrillic = 1171; e.gheupturncyrillic = 1169; e.ghhadeva = 2394; e.ghhagurmukhi = 2650; e.ghook = 608; e.ghzsquare = 13203; e.gihiragana = 12366; e.gikatakana = 12462; e.gimarmenian = 1379; e.gimel = 1490; e.gimeldagesh = 64306; e.gimeldageshhebrew = 64306; e.gimelhebrew = 1490; e.gjecyrillic = 1107; e.glottalinvertedstroke = 446; e.glottalstop = 660; e.glottalstopinverted = 662; e.glottalstopmod = 704; e.glottalstopreversed = 661; e.glottalstopreversedmod = 705; e.glottalstopreversedsuperior = 740; e.glottalstopstroke = 673; e.glottalstopstrokereversed = 674; e.gmacron = 7713; e.gmonospace = 65351; e.gohiragana = 12372; e.gokatakana = 12468; e.gparen = 9378; e.gpasquare = 13228; e.gradient = 8711; e.grave = 96; e.gravebelowcmb = 790; e.gravecmb = 768; e.gravecomb = 768; e.gravedeva = 2387; e.gravelowmod = 718; e.gravemonospace = 65344; e.gravetonecmb = 832; e.greater = 62; e.greaterequal = 8805; e.greaterequalorless = 8923; e.greatermonospace = 65310; e.greaterorequivalent = 8819; e.greaterorless = 8823; e.greateroverequal = 8807; e.greatersmall = 65125; e.gscript = 609; e.gstroke = 485; e.guhiragana = 12368; e.guillemotleft = 171; e.guillemotright = 187; e.guilsinglleft = 8249; e.guilsinglright = 8250; e.gukatakana = 12464; e.guramusquare = 13080; e.gysquare = 13257; e.h = 104; e.haabkhasiancyrillic = 1193; e.haaltonearabic = 1729; e.habengali = 2489; e.hadescendercyrillic = 1203; e.hadeva = 2361; e.hagujarati = 2745; e.hagurmukhi = 2617; e.haharabic = 1581; e.hahfinalarabic = 65186; e.hahinitialarabic = 65187; e.hahiragana = 12399; e.hahmedialarabic = 65188; e.haitusquare = 13098; e.hakatakana = 12495; e.hakatakanahalfwidth = 65418; e.halantgurmukhi = 2637; e.hamzaarabic = 1569; e.hamzalowarabic = 1569; e.hangulfiller = 12644; e.hardsigncyrillic = 1098; e.harpoonleftbarbup = 8636; e.harpoonrightbarbup = 8640; e.hasquare = 13258; e.hatafpatah = 1458; e.hatafpatah16 = 1458; e.hatafpatah23 = 1458; e.hatafpatah2f = 1458; e.hatafpatahhebrew = 1458; e.hatafpatahnarrowhebrew = 1458; e.hatafpatahquarterhebrew = 1458; e.hatafpatahwidehebrew = 1458; e.hatafqamats = 1459; e.hatafqamats1b = 1459; e.hatafqamats28 = 1459; e.hatafqamats34 = 1459; e.hatafqamatshebrew = 1459; e.hatafqamatsnarrowhebrew = 1459; e.hatafqamatsquarterhebrew = 1459; e.hatafqamatswidehebrew = 1459; e.hatafsegol = 1457; e.hatafsegol17 = 1457; e.hatafsegol24 = 1457; e.hatafsegol30 = 1457; e.hatafsegolhebrew = 1457; e.hatafsegolnarrowhebrew = 1457; e.hatafsegolquarterhebrew = 1457; e.hatafsegolwidehebrew = 1457; e.hbar = 295; e.hbopomofo = 12559; e.hbrevebelow = 7723; e.hcedilla = 7721; e.hcircle = 9431; e.hcircumflex = 293; e.hdieresis = 7719; e.hdotaccent = 7715; e.hdotbelow = 7717; e.he = 1492; e.heart = 9829; e.heartsuitblack = 9829; e.heartsuitwhite = 9825; e.hedagesh = 64308; e.hedageshhebrew = 64308; e.hehaltonearabic = 1729; e.heharabic = 1607; e.hehebrew = 1492; e.hehfinalaltonearabic = 64423; e.hehfinalalttwoarabic = 65258; e.hehfinalarabic = 65258; e.hehhamzaabovefinalarabic = 64421; e.hehhamzaaboveisolatedarabic = 64420; e.hehinitialaltonearabic = 64424; e.hehinitialarabic = 65259; e.hehiragana = 12408; e.hehmedialaltonearabic = 64425; e.hehmedialarabic = 65260; e.heiseierasquare = 13179; e.hekatakana = 12504; e.hekatakanahalfwidth = 65421; e.hekutaarusquare = 13110; e.henghook = 615; e.herutusquare = 13113; e.het = 1495; e.hethebrew = 1495; e.hhook = 614; e.hhooksuperior = 689; e.hieuhacirclekorean = 12923; e.hieuhaparenkorean = 12827; e.hieuhcirclekorean = 12909; e.hieuhkorean = 12622; e.hieuhparenkorean = 12813; e.hihiragana = 12402; e.hikatakana = 12498; e.hikatakanahalfwidth = 65419; e.hiriq = 1460; e.hiriq14 = 1460; e.hiriq21 = 1460; e.hiriq2d = 1460; e.hiriqhebrew = 1460; e.hiriqnarrowhebrew = 1460; e.hiriqquarterhebrew = 1460; e.hiriqwidehebrew = 1460; e.hlinebelow = 7830; e.hmonospace = 65352; e.hoarmenian = 1392; e.hohipthai = 3627; e.hohiragana = 12411; e.hokatakana = 12507; e.hokatakanahalfwidth = 65422; e.holam = 1465; e.holam19 = 1465; e.holam26 = 1465; e.holam32 = 1465; e.holamhebrew = 1465; e.holamnarrowhebrew = 1465; e.holamquarterhebrew = 1465; e.holamwidehebrew = 1465; e.honokhukthai = 3630; e.hookabovecomb = 777; e.hookcmb = 777; e.hookpalatalizedbelowcmb = 801; e.hookretroflexbelowcmb = 802; e.hoonsquare = 13122; e.horicoptic = 1001; e.horizontalbar = 8213; e.horncmb = 795; e.hotsprings = 9832; e.house = 8962; e.hparen = 9379; e.hsuperior = 688; e.hturned = 613; e.huhiragana = 12405; e.huiitosquare = 13107; e.hukatakana = 12501; e.hukatakanahalfwidth = 65420; e.hungarumlaut = 733; e.hungarumlautcmb = 779; e.hv = 405; e.hyphen = 45; e.hypheninferior = 63205; e.hyphenmonospace = 65293; e.hyphensmall = 65123; e.hyphensuperior = 63206; e.hyphentwo = 8208; e.i = 105; e.iacute = 237; e.iacyrillic = 1103; e.ibengali = 2439; e.ibopomofo = 12583; e.ibreve = 301; e.icaron = 464; e.icircle = 9432; e.icircumflex = 238; e.icyrillic = 1110; e.idblgrave = 521; e.ideographearthcircle = 12943; e.ideographfirecircle = 12939; e.ideographicallianceparen = 12863; e.ideographiccallparen = 12858; e.ideographiccentrecircle = 12965; e.ideographicclose = 12294; e.ideographiccomma = 12289; e.ideographiccommaleft = 65380; e.ideographiccongratulationparen = 12855; e.ideographiccorrectcircle = 12963; e.ideographicearthparen = 12847; e.ideographicenterpriseparen = 12861; e.ideographicexcellentcircle = 12957; e.ideographicfestivalparen = 12864; e.ideographicfinancialcircle = 12950; e.ideographicfinancialparen = 12854; e.ideographicfireparen = 12843; e.ideographichaveparen = 12850; e.ideographichighcircle = 12964; e.ideographiciterationmark = 12293; e.ideographiclaborcircle = 12952; e.ideographiclaborparen = 12856; e.ideographicleftcircle = 12967; e.ideographiclowcircle = 12966; e.ideographicmedicinecircle = 12969; e.ideographicmetalparen = 12846; e.ideographicmoonparen = 12842; e.ideographicnameparen = 12852; e.ideographicperiod = 12290; e.ideographicprintcircle = 12958; e.ideographicreachparen = 12867; e.ideographicrepresentparen = 12857; e.ideographicresourceparen = 12862; e.ideographicrightcircle = 12968; e.ideographicsecretcircle = 12953; e.ideographicselfparen = 12866; e.ideographicsocietyparen = 12851; e.ideographicspace = 12288; e.ideographicspecialparen = 12853; e.ideographicstockparen = 12849; e.ideographicstudyparen = 12859; e.ideographicsunparen = 12848; e.ideographicsuperviseparen = 12860; e.ideographicwaterparen = 12844; e.ideographicwoodparen = 12845; e.ideographiczero = 12295; e.ideographmetalcircle = 12942; e.ideographmooncircle = 12938; e.ideographnamecircle = 12948; e.ideographsuncircle = 12944; e.ideographwatercircle = 12940; e.ideographwoodcircle = 12941; e.ideva = 2311; e.idieresis = 239; e.idieresisacute = 7727; e.idieresiscyrillic = 1253; e.idotbelow = 7883; e.iebrevecyrillic = 1239; e.iecyrillic = 1077; e.ieungacirclekorean = 12917; e.ieungaparenkorean = 12821; e.ieungcirclekorean = 12903; e.ieungkorean = 12615; e.ieungparenkorean = 12807; e.igrave = 236; e.igujarati = 2695; e.igurmukhi = 2567; e.ihiragana = 12356; e.ihookabove = 7881; e.iibengali = 2440; e.iicyrillic = 1080; e.iideva = 2312; e.iigujarati = 2696; e.iigurmukhi = 2568; e.iimatragurmukhi = 2624; e.iinvertedbreve = 523; e.iishortcyrillic = 1081; e.iivowelsignbengali = 2496; e.iivowelsigndeva = 2368; e.iivowelsigngujarati = 2752; e.ij = 307; e.ikatakana = 12452; e.ikatakanahalfwidth = 65394; e.ikorean = 12643; e.ilde = 732; e.iluyhebrew = 1452; e.imacron = 299; e.imacroncyrillic = 1251; e.imageorapproximatelyequal = 8787; e.imatragurmukhi = 2623; e.imonospace = 65353; e.increment = 8710; e.infinity = 8734; e.iniarmenian = 1387; e.integral = 8747; e.integralbottom = 8993; e.integralbt = 8993; e.integralex = 63733; e.integraltop = 8992; e.integraltp = 8992; e.intersection = 8745; e.intisquare = 13061; e.invbullet = 9688; e.invcircle = 9689; e.invsmileface = 9787; e.iocyrillic = 1105; e.iogonek = 303; e.iota = 953; e.iotadieresis = 970; e.iotadieresistonos = 912; e.iotalatin = 617; e.iotatonos = 943; e.iparen = 9380; e.irigurmukhi = 2674; e.ismallhiragana = 12355; e.ismallkatakana = 12451; e.ismallkatakanahalfwidth = 65384; e.issharbengali = 2554; e.istroke = 616; e.isuperior = 63213; e.iterationhiragana = 12445; e.iterationkatakana = 12541; e.itilde = 297; e.itildebelow = 7725; e.iubopomofo = 12585; e.iucyrillic = 1102; e.ivowelsignbengali = 2495; e.ivowelsigndeva = 2367; e.ivowelsigngujarati = 2751; e.izhitsacyrillic = 1141; e.izhitsadblgravecyrillic = 1143; e.j = 106; e.jaarmenian = 1393; e.jabengali = 2460; e.jadeva = 2332; e.jagujarati = 2716; e.jagurmukhi = 2588; e.jbopomofo = 12560; e.jcaron = 496; e.jcircle = 9433; e.jcircumflex = 309; e.jcrossedtail = 669; e.jdotlessstroke = 607; e.jecyrillic = 1112; e.jeemarabic = 1580; e.jeemfinalarabic = 65182; e.jeeminitialarabic = 65183; e.jeemmedialarabic = 65184; e.jeharabic = 1688; e.jehfinalarabic = 64395; e.jhabengali = 2461; e.jhadeva = 2333; e.jhagujarati = 2717; e.jhagurmukhi = 2589; e.jheharmenian = 1403; e.jis = 12292; e.jmonospace = 65354; e.jparen = 9381; e.jsuperior = 690; e.k = 107; e.kabashkircyrillic = 1185; e.kabengali = 2453; e.kacute = 7729; e.kacyrillic = 1082; e.kadescendercyrillic = 1179; e.kadeva = 2325; e.kaf = 1499; e.kafarabic = 1603; e.kafdagesh = 64315; e.kafdageshhebrew = 64315; e.kaffinalarabic = 65242; e.kafhebrew = 1499; e.kafinitialarabic = 65243; e.kafmedialarabic = 65244; e.kafrafehebrew = 64333; e.kagujarati = 2709; e.kagurmukhi = 2581; e.kahiragana = 12363; e.kahookcyrillic = 1220; e.kakatakana = 12459; e.kakatakanahalfwidth = 65398; e.kappa = 954; e.kappasymbolgreek = 1008; e.kapyeounmieumkorean = 12657; e.kapyeounphieuphkorean = 12676; e.kapyeounpieupkorean = 12664; e.kapyeounssangpieupkorean = 12665; e.karoriisquare = 13069; e.kashidaautoarabic = 1600; e.kashidaautonosidebearingarabic = 1600; e.kasmallkatakana = 12533; e.kasquare = 13188; e.kasraarabic = 1616; e.kasratanarabic = 1613; e.kastrokecyrillic = 1183; e.katahiraprolongmarkhalfwidth = 65392; e.kaverticalstrokecyrillic = 1181; e.kbopomofo = 12558; e.kcalsquare = 13193; e.kcaron = 489; e.kcedilla = 311; e.kcircle = 9434; e.kcommaaccent = 311; e.kdotbelow = 7731; e.keharmenian = 1412; e.kehiragana = 12369; e.kekatakana = 12465; e.kekatakanahalfwidth = 65401; e.kenarmenian = 1391; e.kesmallkatakana = 12534; e.kgreenlandic = 312; e.khabengali = 2454; e.khacyrillic = 1093; e.khadeva = 2326; e.khagujarati = 2710; e.khagurmukhi = 2582; e.khaharabic = 1582; e.khahfinalarabic = 65190; e.khahinitialarabic = 65191; e.khahmedialarabic = 65192; e.kheicoptic = 999; e.khhadeva = 2393; e.khhagurmukhi = 2649; e.khieukhacirclekorean = 12920; e.khieukhaparenkorean = 12824; e.khieukhcirclekorean = 12906; e.khieukhkorean = 12619; e.khieukhparenkorean = 12810; e.khokhaithai = 3586; e.khokhonthai = 3589; e.khokhuatthai = 3587; e.khokhwaithai = 3588; e.khomutthai = 3675; e.khook = 409; e.khorakhangthai = 3590; e.khzsquare = 13201; e.kihiragana = 12365; e.kikatakana = 12461; e.kikatakanahalfwidth = 65399; e.kiroguramusquare = 13077; e.kiromeetorusquare = 13078; e.kirosquare = 13076; e.kiyeokacirclekorean = 12910; e.kiyeokaparenkorean = 12814; e.kiyeokcirclekorean = 12896; e.kiyeokkorean = 12593; e.kiyeokparenkorean = 12800; e.kiyeoksioskorean = 12595; e.kjecyrillic = 1116; e.klinebelow = 7733; e.klsquare = 13208; e.kmcubedsquare = 13222; e.kmonospace = 65355; e.kmsquaredsquare = 13218; e.kohiragana = 12371; e.kohmsquare = 13248; e.kokaithai = 3585; e.kokatakana = 12467; e.kokatakanahalfwidth = 65402; e.kooposquare = 13086; e.koppacyrillic = 1153; e.koreanstandardsymbol = 12927; e.koroniscmb = 835; e.kparen = 9382; e.kpasquare = 13226; e.ksicyrillic = 1135; e.ktsquare = 13263; e.kturned = 670; e.kuhiragana = 12367; e.kukatakana = 12463; e.kukatakanahalfwidth = 65400; e.kvsquare = 13240; e.kwsquare = 13246; e.l = 108; e.labengali = 2482; e.lacute = 314; e.ladeva = 2354; e.lagujarati = 2738; e.lagurmukhi = 2610; e.lakkhangyaothai = 3653; e.lamaleffinalarabic = 65276; e.lamalefhamzaabovefinalarabic = 65272; e.lamalefhamzaaboveisolatedarabic = 65271; e.lamalefhamzabelowfinalarabic = 65274; e.lamalefhamzabelowisolatedarabic = 65273; e.lamalefisolatedarabic = 65275; e.lamalefmaddaabovefinalarabic = 65270; e.lamalefmaddaaboveisolatedarabic = 65269; e.lamarabic = 1604; e.lambda = 955; e.lambdastroke = 411; e.lamed = 1500; e.lameddagesh = 64316; e.lameddageshhebrew = 64316; e.lamedhebrew = 1500; e.lamfinalarabic = 65246; e.lamhahinitialarabic = 64714; e.laminitialarabic = 65247; e.lamjeeminitialarabic = 64713; e.lamkhahinitialarabic = 64715; e.lamlamhehisolatedarabic = 65010; e.lammedialarabic = 65248; e.lammeemhahinitialarabic = 64904; e.lammeeminitialarabic = 64716; e.largecircle = 9711; e.lbar = 410; e.lbelt = 620; e.lbopomofo = 12556; e.lcaron = 318; e.lcedilla = 316; e.lcircle = 9435; e.lcircumflexbelow = 7741; e.lcommaaccent = 316; e.ldot = 320; e.ldotaccent = 320; e.ldotbelow = 7735; e.ldotbelowmacron = 7737; e.leftangleabovecmb = 794; e.lefttackbelowcmb = 792; e.less = 60; e.lessequal = 8804; e.lessequalorgreater = 8922; e.lessmonospace = 65308; e.lessorequivalent = 8818; e.lessorgreater = 8822; e.lessoverequal = 8806; e.lesssmall = 65124; e.lezh = 622; e.lfblock = 9612; e.lhookretroflex = 621; e.lira = 8356; e.liwnarmenian = 1388; e.lj = 457; e.ljecyrillic = 1113; e.ll = 63168; e.lladeva = 2355; e.llagujarati = 2739; e.llinebelow = 7739; e.llladeva = 2356; e.llvocalicbengali = 2529; e.llvocalicdeva = 2401; e.llvocalicvowelsignbengali = 2531; e.llvocalicvowelsigndeva = 2403; e.lmiddletilde = 619; e.lmonospace = 65356; e.lmsquare = 13264; e.lochulathai = 3628; e.logicaland = 8743; e.logicalnot = 172; e.logicalnotreversed = 8976; e.logicalor = 8744; e.lolingthai = 3621; e.longs = 383; e.lowlinecenterline = 65102; e.lowlinecmb = 818; e.lowlinedashed = 65101; e.lozenge = 9674; e.lparen = 9383; e.lslash = 322; e.lsquare = 8467; e.lsuperior = 63214; e.ltshade = 9617; e.luthai = 3622; e.lvocalicbengali = 2444; e.lvocalicdeva = 2316; e.lvocalicvowelsignbengali = 2530; e.lvocalicvowelsigndeva = 2402; e.lxsquare = 13267; e.m = 109; e.mabengali = 2478; e.macron = 175; e.macronbelowcmb = 817; e.macroncmb = 772; e.macronlowmod = 717; e.macronmonospace = 65507; e.macute = 7743; e.madeva = 2350; e.magujarati = 2734; e.magurmukhi = 2606; e.mahapakhhebrew = 1444; e.mahapakhlefthebrew = 1444; e.mahiragana = 12414; e.maichattawalowleftthai = 63637; e.maichattawalowrightthai = 63636; e.maichattawathai = 3659; e.maichattawaupperleftthai = 63635; e.maieklowleftthai = 63628; e.maieklowrightthai = 63627; e.maiekthai = 3656; e.maiekupperleftthai = 63626; e.maihanakatleftthai = 63620; e.maihanakatthai = 3633; e.maitaikhuleftthai = 63625; e.maitaikhuthai = 3655; e.maitholowleftthai = 63631; e.maitholowrightthai = 63630; e.maithothai = 3657; e.maithoupperleftthai = 63629; e.maitrilowleftthai = 63634; e.maitrilowrightthai = 63633; e.maitrithai = 3658; e.maitriupperleftthai = 63632; e.maiyamokthai = 3654; e.makatakana = 12510; e.makatakanahalfwidth = 65423; e.male = 9794; e.mansyonsquare = 13127; e.maqafhebrew = 1470; e.mars = 9794; e.masoracirclehebrew = 1455; e.masquare = 13187; e.mbopomofo = 12551; e.mbsquare = 13268; e.mcircle = 9436; e.mcubedsquare = 13221; e.mdotaccent = 7745; e.mdotbelow = 7747; e.meemarabic = 1605; e.meemfinalarabic = 65250; e.meeminitialarabic = 65251; e.meemmedialarabic = 65252; e.meemmeeminitialarabic = 64721; e.meemmeemisolatedarabic = 64584; e.meetorusquare = 13133; e.mehiragana = 12417; e.meizierasquare = 13182; e.mekatakana = 12513; e.mekatakanahalfwidth = 65426; e.mem = 1502; e.memdagesh = 64318; e.memdageshhebrew = 64318; e.memhebrew = 1502; e.menarmenian = 1396; e.merkhahebrew = 1445; e.merkhakefulahebrew = 1446; e.merkhakefulalefthebrew = 1446; e.merkhalefthebrew = 1445; e.mhook = 625; e.mhzsquare = 13202; e.middledotkatakanahalfwidth = 65381; e.middot = 183; e.mieumacirclekorean = 12914; e.mieumaparenkorean = 12818; e.mieumcirclekorean = 12900; e.mieumkorean = 12609; e.mieumpansioskorean = 12656; e.mieumparenkorean = 12804; e.mieumpieupkorean = 12654; e.mieumsioskorean = 12655; e.mihiragana = 12415; e.mikatakana = 12511; e.mikatakanahalfwidth = 65424; e.minus = 8722; e.minusbelowcmb = 800; e.minuscircle = 8854; e.minusmod = 727; e.minusplus = 8723; e.minute = 8242; e.miribaarusquare = 13130; e.mirisquare = 13129; e.mlonglegturned = 624; e.mlsquare = 13206; e.mmcubedsquare = 13219; e.mmonospace = 65357; e.mmsquaredsquare = 13215; e.mohiragana = 12418; e.mohmsquare = 13249; e.mokatakana = 12514; e.mokatakanahalfwidth = 65427; e.molsquare = 13270; e.momathai = 3617; e.moverssquare = 13223; e.moverssquaredsquare = 13224; e.mparen = 9384; e.mpasquare = 13227; e.mssquare = 13235; e.msuperior = 63215; e.mturned = 623; e.mu = 181; e.mu1 = 181; e.muasquare = 13186; e.muchgreater = 8811; e.muchless = 8810; e.mufsquare = 13196; e.mugreek = 956; e.mugsquare = 13197; e.muhiragana = 12416; e.mukatakana = 12512; e.mukatakanahalfwidth = 65425; e.mulsquare = 13205; e.multiply = 215; e.mumsquare = 13211; e.munahhebrew = 1443; e.munahlefthebrew = 1443; e.musicalnote = 9834; e.musicalnotedbl = 9835; e.musicflatsign = 9837; e.musicsharpsign = 9839; e.mussquare = 13234; e.muvsquare = 13238; e.muwsquare = 13244; e.mvmegasquare = 13241; e.mvsquare = 13239; e.mwmegasquare = 13247; e.mwsquare = 13245; e.n = 110; e.nabengali = 2472; e.nabla = 8711; e.nacute = 324; e.nadeva = 2344; e.nagujarati = 2728; e.nagurmukhi = 2600; e.nahiragana = 12394; e.nakatakana = 12490; e.nakatakanahalfwidth = 65413; e.napostrophe = 329; e.nasquare = 13185; e.nbopomofo = 12555; e.nbspace = 160; e.ncaron = 328; e.ncedilla = 326; e.ncircle = 9437; e.ncircumflexbelow = 7755; e.ncommaaccent = 326; e.ndotaccent = 7749; e.ndotbelow = 7751; e.nehiragana = 12397; e.nekatakana = 12493; e.nekatakanahalfwidth = 65416; e.newsheqelsign = 8362; e.nfsquare = 13195; e.ngabengali = 2457; e.ngadeva = 2329; e.ngagujarati = 2713; e.ngagurmukhi = 2585; e.ngonguthai = 3591; e.nhiragana = 12435; e.nhookleft = 626; e.nhookretroflex = 627; e.nieunacirclekorean = 12911; e.nieunaparenkorean = 12815; e.nieuncieuckorean = 12597; e.nieuncirclekorean = 12897; e.nieunhieuhkorean = 12598; e.nieunkorean = 12596; e.nieunpansioskorean = 12648; e.nieunparenkorean = 12801; e.nieunsioskorean = 12647; e.nieuntikeutkorean = 12646; e.nihiragana = 12395; e.nikatakana = 12491; e.nikatakanahalfwidth = 65414; e.nikhahitleftthai = 63641; e.nikhahitthai = 3661; e.nine = 57; e.ninearabic = 1641; e.ninebengali = 2543; e.ninecircle = 9320; e.ninecircleinversesansserif = 10130; e.ninedeva = 2415; e.ninegujarati = 2799; e.ninegurmukhi = 2671; e.ninehackarabic = 1641; e.ninehangzhou = 12329; e.nineideographicparen = 12840; e.nineinferior = 8329; e.ninemonospace = 65305; e.nineoldstyle = 63289; e.nineparen = 9340; e.nineperiod = 9360; e.ninepersian = 1785; e.nineroman = 8568; e.ninesuperior = 8313; e.nineteencircle = 9330; e.nineteenparen = 9350; e.nineteenperiod = 9370; e.ninethai = 3673; e.nj = 460; e.njecyrillic = 1114; e.nkatakana = 12531; e.nkatakanahalfwidth = 65437; e.nlegrightlong = 414; e.nlinebelow = 7753; e.nmonospace = 65358; e.nmsquare = 13210; e.nnabengali = 2467; e.nnadeva = 2339; e.nnagujarati = 2723; e.nnagurmukhi = 2595; e.nnnadeva = 2345; e.nohiragana = 12398; e.nokatakana = 12494; e.nokatakanahalfwidth = 65417; e.nonbreakingspace = 160; e.nonenthai = 3603; e.nonuthai = 3609; e.noonarabic = 1606; e.noonfinalarabic = 65254; e.noonghunnaarabic = 1722; e.noonghunnafinalarabic = 64415; e.nooninitialarabic = 65255; e.noonjeeminitialarabic = 64722; e.noonjeemisolatedarabic = 64587; e.noonmedialarabic = 65256; e.noonmeeminitialarabic = 64725; e.noonmeemisolatedarabic = 64590; e.noonnoonfinalarabic = 64653; e.notcontains = 8716; e.notelement = 8713; e.notelementof = 8713; e.notequal = 8800; e.notgreater = 8815; e.notgreaternorequal = 8817; e.notgreaternorless = 8825; e.notidentical = 8802; e.notless = 8814; e.notlessnorequal = 8816; e.notparallel = 8742; e.notprecedes = 8832; e.notsubset = 8836; e.notsucceeds = 8833; e.notsuperset = 8837; e.nowarmenian = 1398; e.nparen = 9385; e.nssquare = 13233; e.nsuperior = 8319; e.ntilde = 241; e.nu = 957; e.nuhiragana = 12396; e.nukatakana = 12492; e.nukatakanahalfwidth = 65415; e.nuktabengali = 2492; e.nuktadeva = 2364; e.nuktagujarati = 2748; e.nuktagurmukhi = 2620; e.numbersign = 35; e.numbersignmonospace = 65283; e.numbersignsmall = 65119; e.numeralsigngreek = 884; e.numeralsignlowergreek = 885; e.numero = 8470; e.nun = 1504; e.nundagesh = 64320; e.nundageshhebrew = 64320; e.nunhebrew = 1504; e.nvsquare = 13237; e.nwsquare = 13243; e.nyabengali = 2462; e.nyadeva = 2334; e.nyagujarati = 2718; e.nyagurmukhi = 2590; e.o = 111; e.oacute = 243; e.oangthai = 3629; e.obarred = 629; e.obarredcyrillic = 1257; e.obarreddieresiscyrillic = 1259; e.obengali = 2451; e.obopomofo = 12571; e.obreve = 335; e.ocandradeva = 2321; e.ocandragujarati = 2705; e.ocandravowelsigndeva = 2377; e.ocandravowelsigngujarati = 2761; e.ocaron = 466; e.ocircle = 9438; e.ocircumflex = 244; e.ocircumflexacute = 7889; e.ocircumflexdotbelow = 7897; e.ocircumflexgrave = 7891; e.ocircumflexhookabove = 7893; e.ocircumflextilde = 7895; e.ocyrillic = 1086; e.odblacute = 337; e.odblgrave = 525; e.odeva = 2323; e.odieresis = 246; e.odieresiscyrillic = 1255; e.odotbelow = 7885; e.oe = 339; e.oekorean = 12634; e.ogonek = 731; e.ogonekcmb = 808; e.ograve = 242; e.ogujarati = 2707; e.oharmenian = 1413; e.ohiragana = 12362; e.ohookabove = 7887; e.ohorn = 417; e.ohornacute = 7899; e.ohorndotbelow = 7907; e.ohorngrave = 7901; e.ohornhookabove = 7903; e.ohorntilde = 7905; e.ohungarumlaut = 337; e.oi = 419; e.oinvertedbreve = 527; e.okatakana = 12458; e.okatakanahalfwidth = 65397; e.okorean = 12631; e.olehebrew = 1451; e.omacron = 333; e.omacronacute = 7763; e.omacrongrave = 7761; e.omdeva = 2384; e.omega = 969; e.omega1 = 982; e.omegacyrillic = 1121; e.omegalatinclosed = 631; e.omegaroundcyrillic = 1147; e.omegatitlocyrillic = 1149; e.omegatonos = 974; e.omgujarati = 2768; e.omicron = 959; e.omicrontonos = 972; e.omonospace = 65359; e.one = 49; e.onearabic = 1633; e.onebengali = 2535; e.onecircle = 9312; e.onecircleinversesansserif = 10122; e.onedeva = 2407; e.onedotenleader = 8228; e.oneeighth = 8539; e.onefitted = 63196; e.onegujarati = 2791; e.onegurmukhi = 2663; e.onehackarabic = 1633; e.onehalf = 189; e.onehangzhou = 12321; e.oneideographicparen = 12832; e.oneinferior = 8321; e.onemonospace = 65297; e.onenumeratorbengali = 2548; e.oneoldstyle = 63281; e.oneparen = 9332; e.oneperiod = 9352; e.onepersian = 1777; e.onequarter = 188; e.oneroman = 8560; e.onesuperior = 185; e.onethai = 3665; e.onethird = 8531; e.oogonek = 491; e.oogonekmacron = 493; e.oogurmukhi = 2579; e.oomatragurmukhi = 2635; e.oopen = 596; e.oparen = 9386; e.openbullet = 9702; e.option = 8997; e.ordfeminine = 170; e.ordmasculine = 186; e.orthogonal = 8735; e.oshortdeva = 2322; e.oshortvowelsigndeva = 2378; e.oslash = 248; e.oslashacute = 511; e.osmallhiragana = 12361; e.osmallkatakana = 12457; e.osmallkatakanahalfwidth = 65387; e.ostrokeacute = 511; e.osuperior = 63216; e.otcyrillic = 1151; e.otilde = 245; e.otildeacute = 7757; e.otildedieresis = 7759; e.oubopomofo = 12577; e.overline = 8254; e.overlinecenterline = 65098; e.overlinecmb = 773; e.overlinedashed = 65097; e.overlinedblwavy = 65100; e.overlinewavy = 65099; e.overscore = 175; e.ovowelsignbengali = 2507; e.ovowelsigndeva = 2379; e.ovowelsigngujarati = 2763; e.p = 112; e.paampssquare = 13184; e.paasentosquare = 13099; e.pabengali = 2474; e.pacute = 7765; e.padeva = 2346; e.pagedown = 8671; e.pageup = 8670; e.pagujarati = 2730; e.pagurmukhi = 2602; e.pahiragana = 12401; e.paiyannoithai = 3631; e.pakatakana = 12497; e.palatalizationcyrilliccmb = 1156; e.palochkacyrillic = 1216; e.pansioskorean = 12671; e.paragraph = 182; e.parallel = 8741; e.parenleft = 40; e.parenleftaltonearabic = 64830; e.parenleftbt = 63725; e.parenleftex = 63724; e.parenleftinferior = 8333; e.parenleftmonospace = 65288; e.parenleftsmall = 65113; e.parenleftsuperior = 8317; e.parenlefttp = 63723; e.parenleftvertical = 65077; e.parenright = 41; e.parenrightaltonearabic = 64831; e.parenrightbt = 63736; e.parenrightex = 63735; e.parenrightinferior = 8334; e.parenrightmonospace = 65289; e.parenrightsmall = 65114; e.parenrightsuperior = 8318; e.parenrighttp = 63734; e.parenrightvertical = 65078; e.partialdiff = 8706; e.paseqhebrew = 1472; e.pashtahebrew = 1433; e.pasquare = 13225; e.patah = 1463; e.patah11 = 1463; e.patah1d = 1463; e.patah2a = 1463; e.patahhebrew = 1463; e.patahnarrowhebrew = 1463; e.patahquarterhebrew = 1463; e.patahwidehebrew = 1463; e.pazerhebrew = 1441; e.pbopomofo = 12550; e.pcircle = 9439; e.pdotaccent = 7767; e.pe = 1508; e.pecyrillic = 1087; e.pedagesh = 64324; e.pedageshhebrew = 64324; e.peezisquare = 13115; e.pefinaldageshhebrew = 64323; e.peharabic = 1662; e.peharmenian = 1402; e.pehebrew = 1508; e.pehfinalarabic = 64343; e.pehinitialarabic = 64344; e.pehiragana = 12410; e.pehmedialarabic = 64345; e.pekatakana = 12506; e.pemiddlehookcyrillic = 1191; e.perafehebrew = 64334; e.percent = 37; e.percentarabic = 1642; e.percentmonospace = 65285; e.percentsmall = 65130; e.period = 46; e.periodarmenian = 1417; e.periodcentered = 183; e.periodhalfwidth = 65377; e.periodinferior = 63207; e.periodmonospace = 65294; e.periodsmall = 65106; e.periodsuperior = 63208; e.perispomenigreekcmb = 834; e.perpendicular = 8869; e.perthousand = 8240; e.peseta = 8359; e.pfsquare = 13194; e.phabengali = 2475; e.phadeva = 2347; e.phagujarati = 2731; e.phagurmukhi = 2603; e.phi = 966; e.phi1 = 981; e.phieuphacirclekorean = 12922; e.phieuphaparenkorean = 12826; e.phieuphcirclekorean = 12908; e.phieuphkorean = 12621; e.phieuphparenkorean = 12812; e.philatin = 632; e.phinthuthai = 3642; e.phisymbolgreek = 981; e.phook = 421; e.phophanthai = 3614; e.phophungthai = 3612; e.phosamphaothai = 3616; e.pi = 960; e.pieupacirclekorean = 12915; e.pieupaparenkorean = 12819; e.pieupcieuckorean = 12662; e.pieupcirclekorean = 12901; e.pieupkiyeokkorean = 12658; e.pieupkorean = 12610; e.pieupparenkorean = 12805; e.pieupsioskiyeokkorean = 12660; e.pieupsioskorean = 12612; e.pieupsiostikeutkorean = 12661; e.pieupthieuthkorean = 12663; e.pieuptikeutkorean = 12659; e.pihiragana = 12404; e.pikatakana = 12500; e.pisymbolgreek = 982; e.piwrarmenian = 1411; e.plus = 43; e.plusbelowcmb = 799; e.pluscircle = 8853; e.plusminus = 177; e.plusmod = 726; e.plusmonospace = 65291; e.plussmall = 65122; e.plussuperior = 8314; e.pmonospace = 65360; e.pmsquare = 13272; e.pohiragana = 12413; e.pointingindexdownwhite = 9759; e.pointingindexleftwhite = 9756; e.pointingindexrightwhite = 9758; e.pointingindexupwhite = 9757; e.pokatakana = 12509; e.poplathai = 3611; e.postalmark = 12306; e.postalmarkface = 12320; e.pparen = 9387; e.precedes = 8826; e.prescription = 8478; e.primemod = 697; e.primereversed = 8245; e.product = 8719; e.projective = 8965; e.prolongedkana = 12540; e.propellor = 8984; e.propersubset = 8834; e.propersuperset = 8835; e.proportion = 8759; e.proportional = 8733; e.psi = 968; e.psicyrillic = 1137; e.psilipneumatacyrilliccmb = 1158; e.pssquare = 13232; e.puhiragana = 12407; e.pukatakana = 12503; e.pvsquare = 13236; e.pwsquare = 13242; e.q = 113; e.qadeva = 2392; e.qadmahebrew = 1448; e.qafarabic = 1602; e.qaffinalarabic = 65238; e.qafinitialarabic = 65239; e.qafmedialarabic = 65240; e.qamats = 1464; e.qamats10 = 1464; e.qamats1a = 1464; e.qamats1c = 1464; e.qamats27 = 1464; e.qamats29 = 1464; e.qamats33 = 1464; e.qamatsde = 1464; e.qamatshebrew = 1464; e.qamatsnarrowhebrew = 1464; e.qamatsqatanhebrew = 1464; e.qamatsqatannarrowhebrew = 1464; e.qamatsqatanquarterhebrew = 1464; e.qamatsqatanwidehebrew = 1464; e.qamatsquarterhebrew = 1464; e.qamatswidehebrew = 1464; e.qarneyparahebrew = 1439; e.qbopomofo = 12561; e.qcircle = 9440; e.qhook = 672; e.qmonospace = 65361; e.qof = 1511; e.qofdagesh = 64327; e.qofdageshhebrew = 64327; e.qofhebrew = 1511; e.qparen = 9388; e.quarternote = 9833; e.qubuts = 1467; e.qubuts18 = 1467; e.qubuts25 = 1467; e.qubuts31 = 1467; e.qubutshebrew = 1467; e.qubutsnarrowhebrew = 1467; e.qubutsquarterhebrew = 1467; e.qubutswidehebrew = 1467; e.question = 63; e.questionarabic = 1567; e.questionarmenian = 1374; e.questiondown = 191; e.questiondownsmall = 63423; e.questiongreek = 894; e.questionmonospace = 65311; e.questionsmall = 63295; e.quotedbl = 34; e.quotedblbase = 8222; e.quotedblleft = 8220; e.quotedblmonospace = 65282; e.quotedblprime = 12318; e.quotedblprimereversed = 12317; e.quotedblright = 8221; e.quoteleft = 8216; e.quoteleftreversed = 8219; e.quotereversed = 8219; e.quoteright = 8217; e.quoterightn = 329; e.quotesinglbase = 8218; e.quotesingle = 39; e.quotesinglemonospace = 65287; e.r = 114; e.raarmenian = 1404; e.rabengali = 2480; e.racute = 341; e.radeva = 2352; e.radical = 8730; e.radicalex = 63717; e.radoverssquare = 13230; e.radoverssquaredsquare = 13231; e.radsquare = 13229; e.rafe = 1471; e.rafehebrew = 1471; e.ragujarati = 2736; e.ragurmukhi = 2608; e.rahiragana = 12425; e.rakatakana = 12521; e.rakatakanahalfwidth = 65431; e.ralowerdiagonalbengali = 2545; e.ramiddlediagonalbengali = 2544; e.ramshorn = 612; e.ratio = 8758; e.rbopomofo = 12566; e.rcaron = 345; e.rcedilla = 343; e.rcircle = 9441; e.rcommaaccent = 343; e.rdblgrave = 529; e.rdotaccent = 7769; e.rdotbelow = 7771; e.rdotbelowmacron = 7773; e.referencemark = 8251; e.reflexsubset = 8838; e.reflexsuperset = 8839; e.registered = 174; e.registersans = 63720; e.registerserif = 63194; e.reharabic = 1585; e.reharmenian = 1408; e.rehfinalarabic = 65198; e.rehiragana = 12428; e.rekatakana = 12524; e.rekatakanahalfwidth = 65434; e.resh = 1512; e.reshdageshhebrew = 64328; e.reshhebrew = 1512; e.reversedtilde = 8765; e.reviahebrew = 1431; e.reviamugrashhebrew = 1431; e.revlogicalnot = 8976; e.rfishhook = 638; e.rfishhookreversed = 639; e.rhabengali = 2525; e.rhadeva = 2397; e.rho = 961; e.rhook = 637; e.rhookturned = 635; e.rhookturnedsuperior = 693; e.rhosymbolgreek = 1009; e.rhotichookmod = 734; e.rieulacirclekorean = 12913; e.rieulaparenkorean = 12817; e.rieulcirclekorean = 12899; e.rieulhieuhkorean = 12608; e.rieulkiyeokkorean = 12602; e.rieulkiyeoksioskorean = 12649; e.rieulkorean = 12601; e.rieulmieumkorean = 12603; e.rieulpansioskorean = 12652; e.rieulparenkorean = 12803; e.rieulphieuphkorean = 12607; e.rieulpieupkorean = 12604; e.rieulpieupsioskorean = 12651; e.rieulsioskorean = 12605; e.rieulthieuthkorean = 12606; e.rieultikeutkorean = 12650; e.rieulyeorinhieuhkorean = 12653; e.rightangle = 8735; e.righttackbelowcmb = 793; e.righttriangle = 8895; e.rihiragana = 12426; e.rikatakana = 12522; e.rikatakanahalfwidth = 65432; e.ring = 730; e.ringbelowcmb = 805; e.ringcmb = 778; e.ringhalfleft = 703; e.ringhalfleftarmenian = 1369; e.ringhalfleftbelowcmb = 796; e.ringhalfleftcentered = 723; e.ringhalfright = 702; e.ringhalfrightbelowcmb = 825; e.ringhalfrightcentered = 722; e.rinvertedbreve = 531; e.rittorusquare = 13137; e.rlinebelow = 7775; e.rlongleg = 636; e.rlonglegturned = 634; e.rmonospace = 65362; e.rohiragana = 12429; e.rokatakana = 12525; e.rokatakanahalfwidth = 65435; e.roruathai = 3619; e.rparen = 9389; e.rrabengali = 2524; e.rradeva = 2353; e.rragurmukhi = 2652; e.rreharabic = 1681; e.rrehfinalarabic = 64397; e.rrvocalicbengali = 2528; e.rrvocalicdeva = 2400; e.rrvocalicgujarati = 2784; e.rrvocalicvowelsignbengali = 2500; e.rrvocalicvowelsigndeva = 2372; e.rrvocalicvowelsigngujarati = 2756; e.rsuperior = 63217; e.rtblock = 9616; e.rturned = 633; e.rturnedsuperior = 692; e.ruhiragana = 12427; e.rukatakana = 12523; e.rukatakanahalfwidth = 65433; e.rupeemarkbengali = 2546; e.rupeesignbengali = 2547; e.rupiah = 63197; e.ruthai = 3620; e.rvocalicbengali = 2443; e.rvocalicdeva = 2315; e.rvocalicgujarati = 2699; e.rvocalicvowelsignbengali = 2499; e.rvocalicvowelsigndeva = 2371; e.rvocalicvowelsigngujarati = 2755; e.s = 115; e.sabengali = 2488; e.sacute = 347; e.sacutedotaccent = 7781; e.sadarabic = 1589; e.sadeva = 2360; e.sadfinalarabic = 65210; e.sadinitialarabic = 65211; e.sadmedialarabic = 65212; e.sagujarati = 2744; e.sagurmukhi = 2616; e.sahiragana = 12373; e.sakatakana = 12469; e.sakatakanahalfwidth = 65403; e.sallallahoualayhewasallamarabic = 65018; e.samekh = 1505; e.samekhdagesh = 64321; e.samekhdageshhebrew = 64321; e.samekhhebrew = 1505; e.saraaathai = 3634; e.saraaethai = 3649; e.saraaimaimalaithai = 3652; e.saraaimaimuanthai = 3651; e.saraamthai = 3635; e.saraathai = 3632; e.saraethai = 3648; e.saraiileftthai = 63622; e.saraiithai = 3637; e.saraileftthai = 63621; e.saraithai = 3636; e.saraothai = 3650; e.saraueeleftthai = 63624; e.saraueethai = 3639; e.saraueleftthai = 63623; e.sarauethai = 3638; e.sarauthai = 3640; e.sarauuthai = 3641; e.sbopomofo = 12569; e.scaron = 353; e.scarondotaccent = 7783; e.scedilla = 351; e.schwa = 601; e.schwacyrillic = 1241; e.schwadieresiscyrillic = 1243; e.schwahook = 602; e.scircle = 9442; e.scircumflex = 349; e.scommaaccent = 537; e.sdotaccent = 7777; e.sdotbelow = 7779; e.sdotbelowdotaccent = 7785; e.seagullbelowcmb = 828; e.second = 8243; e.secondtonechinese = 714; e.section = 167; e.seenarabic = 1587; e.seenfinalarabic = 65202; e.seeninitialarabic = 65203; e.seenmedialarabic = 65204; e.segol = 1462; e.segol13 = 1462; e.segol1f = 1462; e.segol2c = 1462; e.segolhebrew = 1462; e.segolnarrowhebrew = 1462; e.segolquarterhebrew = 1462; e.segoltahebrew = 1426; e.segolwidehebrew = 1462; e.seharmenian = 1405; e.sehiragana = 12379; e.sekatakana = 12475; e.sekatakanahalfwidth = 65406; e.semicolon = 59; e.semicolonarabic = 1563; e.semicolonmonospace = 65307; e.semicolonsmall = 65108; e.semivoicedmarkkana = 12444; e.semivoicedmarkkanahalfwidth = 65439; e.sentisquare = 13090; e.sentosquare = 13091; e.seven = 55; e.sevenarabic = 1639; e.sevenbengali = 2541; e.sevencircle = 9318; e.sevencircleinversesansserif = 10128; e.sevendeva = 2413; e.seveneighths = 8542; e.sevengujarati = 2797; e.sevengurmukhi = 2669; e.sevenhackarabic = 1639; e.sevenhangzhou = 12327; e.sevenideographicparen = 12838; e.seveninferior = 8327; e.sevenmonospace = 65303; e.sevenoldstyle = 63287; e.sevenparen = 9338; e.sevenperiod = 9358; e.sevenpersian = 1783; e.sevenroman = 8566; e.sevensuperior = 8311; e.seventeencircle = 9328; e.seventeenparen = 9348; e.seventeenperiod = 9368; e.seventhai = 3671; e.sfthyphen = 173; e.shaarmenian = 1399; e.shabengali = 2486; e.shacyrillic = 1096; e.shaddaarabic = 1617; e.shaddadammaarabic = 64609; e.shaddadammatanarabic = 64606; e.shaddafathaarabic = 64608; e.shaddakasraarabic = 64610; e.shaddakasratanarabic = 64607; e.shade = 9618; e.shadedark = 9619; e.shadelight = 9617; e.shademedium = 9618; e.shadeva = 2358; e.shagujarati = 2742; e.shagurmukhi = 2614; e.shalshelethebrew = 1427; e.shbopomofo = 12565; e.shchacyrillic = 1097; e.sheenarabic = 1588; e.sheenfinalarabic = 65206; e.sheeninitialarabic = 65207; e.sheenmedialarabic = 65208; e.sheicoptic = 995; e.sheqel = 8362; e.sheqelhebrew = 8362; e.sheva = 1456; e.sheva115 = 1456; e.sheva15 = 1456; e.sheva22 = 1456; e.sheva2e = 1456; e.shevahebrew = 1456; e.shevanarrowhebrew = 1456; e.shevaquarterhebrew = 1456; e.shevawidehebrew = 1456; e.shhacyrillic = 1211; e.shimacoptic = 1005; e.shin = 1513; e.shindagesh = 64329; e.shindageshhebrew = 64329; e.shindageshshindot = 64300; e.shindageshshindothebrew = 64300; e.shindageshsindot = 64301; e.shindageshsindothebrew = 64301; e.shindothebrew = 1473; e.shinhebrew = 1513; e.shinshindot = 64298; e.shinshindothebrew = 64298; e.shinsindot = 64299; e.shinsindothebrew = 64299; e.shook = 642; e.sigma = 963; e.sigma1 = 962; e.sigmafinal = 962; e.sigmalunatesymbolgreek = 1010; e.sihiragana = 12375; e.sikatakana = 12471; e.sikatakanahalfwidth = 65404; e.siluqhebrew = 1469; e.siluqlefthebrew = 1469; e.similar = 8764; e.sindothebrew = 1474; e.siosacirclekorean = 12916; e.siosaparenkorean = 12820; e.sioscieuckorean = 12670; e.sioscirclekorean = 12902; e.sioskiyeokkorean = 12666; e.sioskorean = 12613; e.siosnieunkorean = 12667; e.siosparenkorean = 12806; e.siospieupkorean = 12669; e.siostikeutkorean = 12668; e.six = 54; e.sixarabic = 1638; e.sixbengali = 2540; e.sixcircle = 9317; e.sixcircleinversesansserif = 10127; e.sixdeva = 2412; e.sixgujarati = 2796; e.sixgurmukhi = 2668; e.sixhackarabic = 1638; e.sixhangzhou = 12326; e.sixideographicparen = 12837; e.sixinferior = 8326; e.sixmonospace = 65302; e.sixoldstyle = 63286; e.sixparen = 9337; e.sixperiod = 9357; e.sixpersian = 1782; e.sixroman = 8565; e.sixsuperior = 8310; e.sixteencircle = 9327; e.sixteencurrencydenominatorbengali = 2553; e.sixteenparen = 9347; e.sixteenperiod = 9367; e.sixthai = 3670; e.slash = 47; e.slashmonospace = 65295; e.slong = 383; e.slongdotaccent = 7835; e.smileface = 9786; e.smonospace = 65363; e.sofpasuqhebrew = 1475; e.softhyphen = 173; e.softsigncyrillic = 1100; e.sohiragana = 12381; e.sokatakana = 12477; e.sokatakanahalfwidth = 65407; e.soliduslongoverlaycmb = 824; e.solidusshortoverlaycmb = 823; e.sorusithai = 3625; e.sosalathai = 3624; e.sosothai = 3595; e.sosuathai = 3626; e.space = 32; e.spacehackarabic = 32; e.spade = 9824; e.spadesuitblack = 9824; e.spadesuitwhite = 9828; e.sparen = 9390; e.squarebelowcmb = 827; e.squarecc = 13252; e.squarecm = 13213; e.squarediagonalcrosshatchfill = 9641; e.squarehorizontalfill = 9636; e.squarekg = 13199; e.squarekm = 13214; e.squarekmcapital = 13262; e.squareln = 13265; e.squarelog = 13266; e.squaremg = 13198; e.squaremil = 13269; e.squaremm = 13212; e.squaremsquared = 13217; e.squareorthogonalcrosshatchfill = 9638; e.squareupperlefttolowerrightfill = 9639; e.squareupperrighttolowerleftfill = 9640; e.squareverticalfill = 9637; e.squarewhitewithsmallblack = 9635; e.srsquare = 13275; e.ssabengali = 2487; e.ssadeva = 2359; e.ssagujarati = 2743; e.ssangcieuckorean = 12617; e.ssanghieuhkorean = 12677; e.ssangieungkorean = 12672; e.ssangkiyeokkorean = 12594; e.ssangnieunkorean = 12645; e.ssangpieupkorean = 12611; e.ssangsioskorean = 12614; e.ssangtikeutkorean = 12600; e.ssuperior = 63218; e.sterling = 163; e.sterlingmonospace = 65505; e.strokelongoverlaycmb = 822; e.strokeshortoverlaycmb = 821; e.subset = 8834; e.subsetnotequal = 8842; e.subsetorequal = 8838; e.succeeds = 8827; e.suchthat = 8715; e.suhiragana = 12377; e.sukatakana = 12473; e.sukatakanahalfwidth = 65405; e.sukunarabic = 1618; e.summation = 8721; e.sun = 9788; e.superset = 8835; e.supersetnotequal = 8843; e.supersetorequal = 8839; e.svsquare = 13276; e.syouwaerasquare = 13180; e.t = 116; e.tabengali = 2468; e.tackdown = 8868; e.tackleft = 8867; e.tadeva = 2340; e.tagujarati = 2724; e.tagurmukhi = 2596; e.taharabic = 1591; e.tahfinalarabic = 65218; e.tahinitialarabic = 65219; e.tahiragana = 12383; e.tahmedialarabic = 65220; e.taisyouerasquare = 13181; e.takatakana = 12479; e.takatakanahalfwidth = 65408; e.tatweelarabic = 1600; e.tau = 964; e.tav = 1514; e.tavdages = 64330; e.tavdagesh = 64330; e.tavdageshhebrew = 64330; e.tavhebrew = 1514; e.tbar = 359; e.tbopomofo = 12554; e.tcaron = 357; e.tccurl = 680; e.tcedilla = 355; e.tcheharabic = 1670; e.tchehfinalarabic = 64379; e.tchehinitialarabic = 64380; e.tchehmedialarabic = 64381; e.tcircle = 9443; e.tcircumflexbelow = 7793; e.tcommaaccent = 355; e.tdieresis = 7831; e.tdotaccent = 7787; e.tdotbelow = 7789; e.tecyrillic = 1090; e.tedescendercyrillic = 1197; e.teharabic = 1578; e.tehfinalarabic = 65174; e.tehhahinitialarabic = 64674; e.tehhahisolatedarabic = 64524; e.tehinitialarabic = 65175; e.tehiragana = 12390; e.tehjeeminitialarabic = 64673; e.tehjeemisolatedarabic = 64523; e.tehmarbutaarabic = 1577; e.tehmarbutafinalarabic = 65172; e.tehmedialarabic = 65176; e.tehmeeminitialarabic = 64676; e.tehmeemisolatedarabic = 64526; e.tehnoonfinalarabic = 64627; e.tekatakana = 12486; e.tekatakanahalfwidth = 65411; e.telephone = 8481; e.telephoneblack = 9742; e.telishagedolahebrew = 1440; e.telishaqetanahebrew = 1449; e.tencircle = 9321; e.tenideographicparen = 12841; e.tenparen = 9341; e.tenperiod = 9361; e.tenroman = 8569; e.tesh = 679; e.tet = 1496; e.tetdagesh = 64312; e.tetdageshhebrew = 64312; e.tethebrew = 1496; e.tetsecyrillic = 1205; e.tevirhebrew = 1435; e.tevirlefthebrew = 1435; e.thabengali = 2469; e.thadeva = 2341; e.thagujarati = 2725; e.thagurmukhi = 2597; e.thalarabic = 1584; e.thalfinalarabic = 65196; e.thanthakhatlowleftthai = 63640; e.thanthakhatlowrightthai = 63639; e.thanthakhatthai = 3660; e.thanthakhatupperleftthai = 63638; e.theharabic = 1579; e.thehfinalarabic = 65178; e.thehinitialarabic = 65179; e.thehmedialarabic = 65180; e.thereexists = 8707; e.therefore = 8756; e.theta = 952; e.theta1 = 977; e.thetasymbolgreek = 977; e.thieuthacirclekorean = 12921; e.thieuthaparenkorean = 12825; e.thieuthcirclekorean = 12907; e.thieuthkorean = 12620; e.thieuthparenkorean = 12811; e.thirteencircle = 9324; e.thirteenparen = 9344; e.thirteenperiod = 9364; e.thonangmonthothai = 3601; e.thook = 429; e.thophuthaothai = 3602; e.thorn = 254; e.thothahanthai = 3607; e.thothanthai = 3600; e.thothongthai = 3608; e.thothungthai = 3606; e.thousandcyrillic = 1154; e.thousandsseparatorarabic = 1644; e.thousandsseparatorpersian = 1644; e.three = 51; e.threearabic = 1635; e.threebengali = 2537; e.threecircle = 9314; e.threecircleinversesansserif = 10124; e.threedeva = 2409; e.threeeighths = 8540; e.threegujarati = 2793; e.threegurmukhi = 2665; e.threehackarabic = 1635; e.threehangzhou = 12323; e.threeideographicparen = 12834; e.threeinferior = 8323; e.threemonospace = 65299; e.threenumeratorbengali = 2550; e.threeoldstyle = 63283; e.threeparen = 9334; e.threeperiod = 9354; e.threepersian = 1779; e.threequarters = 190; e.threequartersemdash = 63198; e.threeroman = 8562; e.threesuperior = 179; e.threethai = 3667; e.thzsquare = 13204; e.tihiragana = 12385; e.tikatakana = 12481; e.tikatakanahalfwidth = 65409; e.tikeutacirclekorean = 12912; e.tikeutaparenkorean = 12816; e.tikeutcirclekorean = 12898; e.tikeutkorean = 12599; e.tikeutparenkorean = 12802; e.tilde = 732; e.tildebelowcmb = 816; e.tildecmb = 771; e.tildecomb = 771; e.tildedoublecmb = 864; e.tildeoperator = 8764; e.tildeoverlaycmb = 820; e.tildeverticalcmb = 830; e.timescircle = 8855; e.tipehahebrew = 1430; e.tipehalefthebrew = 1430; e.tippigurmukhi = 2672; e.titlocyrilliccmb = 1155; e.tiwnarmenian = 1407; e.tlinebelow = 7791; e.tmonospace = 65364; e.toarmenian = 1385; e.tohiragana = 12392; e.tokatakana = 12488; e.tokatakanahalfwidth = 65412; e.tonebarextrahighmod = 741; e.tonebarextralowmod = 745; e.tonebarhighmod = 742; e.tonebarlowmod = 744; e.tonebarmidmod = 743; e.tonefive = 445; e.tonesix = 389; e.tonetwo = 424; e.tonos = 900; e.tonsquare = 13095; e.topatakthai = 3599; e.tortoiseshellbracketleft = 12308; e.tortoiseshellbracketleftsmall = 65117; e.tortoiseshellbracketleftvertical = 65081; e.tortoiseshellbracketright = 12309; e.tortoiseshellbracketrightsmall = 65118; e.tortoiseshellbracketrightvertical = 65082; e.totaothai = 3605; e.tpalatalhook = 427; e.tparen = 9391; e.trademark = 8482; e.trademarksans = 63722; e.trademarkserif = 63195; e.tretroflexhook = 648; e.triagdn = 9660; e.triaglf = 9668; e.triagrt = 9658; e.triagup = 9650; e.ts = 678; e.tsadi = 1510; e.tsadidagesh = 64326; e.tsadidageshhebrew = 64326; e.tsadihebrew = 1510; e.tsecyrillic = 1094; e.tsere = 1461; e.tsere12 = 1461; e.tsere1e = 1461; e.tsere2b = 1461; e.tserehebrew = 1461; e.tserenarrowhebrew = 1461; e.tserequarterhebrew = 1461; e.tserewidehebrew = 1461; e.tshecyrillic = 1115; e.tsuperior = 63219; e.ttabengali = 2463; e.ttadeva = 2335; e.ttagujarati = 2719; e.ttagurmukhi = 2591; e.tteharabic = 1657; e.ttehfinalarabic = 64359; e.ttehinitialarabic = 64360; e.ttehmedialarabic = 64361; e.tthabengali = 2464; e.tthadeva = 2336; e.tthagujarati = 2720; e.tthagurmukhi = 2592; e.tturned = 647; e.tuhiragana = 12388; e.tukatakana = 12484; e.tukatakanahalfwidth = 65410; e.tusmallhiragana = 12387; e.tusmallkatakana = 12483; e.tusmallkatakanahalfwidth = 65391; e.twelvecircle = 9323; e.twelveparen = 9343; e.twelveperiod = 9363; e.twelveroman = 8571; e.twentycircle = 9331; e.twentyhangzhou = 21316; e.twentyparen = 9351; e.twentyperiod = 9371; e.two = 50; e.twoarabic = 1634; e.twobengali = 2536; e.twocircle = 9313; e.twocircleinversesansserif = 10123; e.twodeva = 2408; e.twodotenleader = 8229; e.twodotleader = 8229; e.twodotleadervertical = 65072; e.twogujarati = 2792; e.twogurmukhi = 2664; e.twohackarabic = 1634; e.twohangzhou = 12322; e.twoideographicparen = 12833; e.twoinferior = 8322; e.twomonospace = 65298; e.twonumeratorbengali = 2549; e.twooldstyle = 63282; e.twoparen = 9333; e.twoperiod = 9353; e.twopersian = 1778; e.tworoman = 8561; e.twostroke = 443; e.twosuperior = 178; e.twothai = 3666; e.twothirds = 8532; e.u = 117; e.uacute = 250; e.ubar = 649; e.ubengali = 2441; e.ubopomofo = 12584; e.ubreve = 365; e.ucaron = 468; e.ucircle = 9444; e.ucircumflex = 251; e.ucircumflexbelow = 7799; e.ucyrillic = 1091; e.udattadeva = 2385; e.udblacute = 369; e.udblgrave = 533; e.udeva = 2313; e.udieresis = 252; e.udieresisacute = 472; e.udieresisbelow = 7795; e.udieresiscaron = 474; e.udieresiscyrillic = 1265; e.udieresisgrave = 476; e.udieresismacron = 470; e.udotbelow = 7909; e.ugrave = 249; e.ugujarati = 2697; e.ugurmukhi = 2569; e.uhiragana = 12358; e.uhookabove = 7911; e.uhorn = 432; e.uhornacute = 7913; e.uhorndotbelow = 7921; e.uhorngrave = 7915; e.uhornhookabove = 7917; e.uhorntilde = 7919; e.uhungarumlaut = 369; e.uhungarumlautcyrillic = 1267; e.uinvertedbreve = 535; e.ukatakana = 12454; e.ukatakanahalfwidth = 65395; e.ukcyrillic = 1145; e.ukorean = 12636; e.umacron = 363; e.umacroncyrillic = 1263; e.umacrondieresis = 7803; e.umatragurmukhi = 2625; e.umonospace = 65365; e.underscore = 95; e.underscoredbl = 8215; e.underscoremonospace = 65343; e.underscorevertical = 65075; e.underscorewavy = 65103; e.union = 8746; e.universal = 8704; e.uogonek = 371; e.uparen = 9392; e.upblock = 9600; e.upperdothebrew = 1476; e.upsilon = 965; e.upsilondieresis = 971; e.upsilondieresistonos = 944; e.upsilonlatin = 650; e.upsilontonos = 973; e.uptackbelowcmb = 797; e.uptackmod = 724; e.uragurmukhi = 2675; e.uring = 367; e.ushortcyrillic = 1118; e.usmallhiragana = 12357; e.usmallkatakana = 12453; e.usmallkatakanahalfwidth = 65385; e.ustraightcyrillic = 1199; e.ustraightstrokecyrillic = 1201; e.utilde = 361; e.utildeacute = 7801; e.utildebelow = 7797; e.uubengali = 2442; e.uudeva = 2314; e.uugujarati = 2698; e.uugurmukhi = 2570; e.uumatragurmukhi = 2626; e.uuvowelsignbengali = 2498; e.uuvowelsigndeva = 2370; e.uuvowelsigngujarati = 2754; e.uvowelsignbengali = 2497; e.uvowelsigndeva = 2369; e.uvowelsigngujarati = 2753; e.v = 118; e.vadeva = 2357; e.vagujarati = 2741; e.vagurmukhi = 2613; e.vakatakana = 12535; e.vav = 1493; e.vavdagesh = 64309; e.vavdagesh65 = 64309; e.vavdageshhebrew = 64309; e.vavhebrew = 1493; e.vavholam = 64331; e.vavholamhebrew = 64331; e.vavvavhebrew = 1520; e.vavyodhebrew = 1521; e.vcircle = 9445; e.vdotbelow = 7807; e.vecyrillic = 1074; e.veharabic = 1700; e.vehfinalarabic = 64363; e.vehinitialarabic = 64364; e.vehmedialarabic = 64365; e.vekatakana = 12537; e.venus = 9792; e.verticalbar = 124; e.verticallineabovecmb = 781; e.verticallinebelowcmb = 809; e.verticallinelowmod = 716; e.verticallinemod = 712; e.vewarmenian = 1406; e.vhook = 651; e.vikatakana = 12536; e.viramabengali = 2509; e.viramadeva = 2381; e.viramagujarati = 2765; e.visargabengali = 2435; e.visargadeva = 2307; e.visargagujarati = 2691; e.vmonospace = 65366; e.voarmenian = 1400; e.voicediterationhiragana = 12446; e.voicediterationkatakana = 12542; e.voicedmarkkana = 12443; e.voicedmarkkanahalfwidth = 65438; e.vokatakana = 12538; e.vparen = 9393; e.vtilde = 7805; e.vturned = 652; e.vuhiragana = 12436; e.vukatakana = 12532; e.w = 119; e.wacute = 7811; e.waekorean = 12633; e.wahiragana = 12431; e.wakatakana = 12527; e.wakatakanahalfwidth = 65436; e.wakorean = 12632; e.wasmallhiragana = 12430; e.wasmallkatakana = 12526; e.wattosquare = 13143; e.wavedash = 12316; e.wavyunderscorevertical = 65076; e.wawarabic = 1608; e.wawfinalarabic = 65262; e.wawhamzaabovearabic = 1572; e.wawhamzaabovefinalarabic = 65158; e.wbsquare = 13277; e.wcircle = 9446; e.wcircumflex = 373; e.wdieresis = 7813; e.wdotaccent = 7815; e.wdotbelow = 7817; e.wehiragana = 12433; e.weierstrass = 8472; e.wekatakana = 12529; e.wekorean = 12638; e.weokorean = 12637; e.wgrave = 7809; e.whitebullet = 9702; e.whitecircle = 9675; e.whitecircleinverse = 9689; e.whitecornerbracketleft = 12302; e.whitecornerbracketleftvertical = 65091; e.whitecornerbracketright = 12303; e.whitecornerbracketrightvertical = 65092; e.whitediamond = 9671; e.whitediamondcontainingblacksmalldiamond = 9672; e.whitedownpointingsmalltriangle = 9663; e.whitedownpointingtriangle = 9661; e.whiteleftpointingsmalltriangle = 9667; e.whiteleftpointingtriangle = 9665; e.whitelenticularbracketleft = 12310; e.whitelenticularbracketright = 12311; e.whiterightpointingsmalltriangle = 9657; e.whiterightpointingtriangle = 9655; e.whitesmallsquare = 9643; e.whitesmilingface = 9786; e.whitesquare = 9633; e.whitestar = 9734; e.whitetelephone = 9743; e.whitetortoiseshellbracketleft = 12312; e.whitetortoiseshellbracketright = 12313; e.whiteuppointingsmalltriangle = 9653; e.whiteuppointingtriangle = 9651; e.wihiragana = 12432; e.wikatakana = 12528; e.wikorean = 12639; e.wmonospace = 65367; e.wohiragana = 12434; e.wokatakana = 12530; e.wokatakanahalfwidth = 65382; e.won = 8361; e.wonmonospace = 65510; e.wowaenthai = 3623; e.wparen = 9394; e.wring = 7832; e.wsuperior = 695; e.wturned = 653; e.wynn = 447; e.x = 120; e.xabovecmb = 829; e.xbopomofo = 12562; e.xcircle = 9447; e.xdieresis = 7821; e.xdotaccent = 7819; e.xeharmenian = 1389; e.xi = 958; e.xmonospace = 65368; e.xparen = 9395; e.xsuperior = 739; e.y = 121; e.yaadosquare = 13134; e.yabengali = 2479; e.yacute = 253; e.yadeva = 2351; e.yaekorean = 12626; e.yagujarati = 2735; e.yagurmukhi = 2607; e.yahiragana = 12420; e.yakatakana = 12516; e.yakatakanahalfwidth = 65428; e.yakorean = 12625; e.yamakkanthai = 3662; e.yasmallhiragana = 12419; e.yasmallkatakana = 12515; e.yasmallkatakanahalfwidth = 65388; e.yatcyrillic = 1123; e.ycircle = 9448; e.ycircumflex = 375; e.ydieresis = 255; e.ydotaccent = 7823; e.ydotbelow = 7925; e.yeharabic = 1610; e.yehbarreearabic = 1746; e.yehbarreefinalarabic = 64431; e.yehfinalarabic = 65266; e.yehhamzaabovearabic = 1574; e.yehhamzaabovefinalarabic = 65162; e.yehhamzaaboveinitialarabic = 65163; e.yehhamzaabovemedialarabic = 65164; e.yehinitialarabic = 65267; e.yehmedialarabic = 65268; e.yehmeeminitialarabic = 64733; e.yehmeemisolatedarabic = 64600; e.yehnoonfinalarabic = 64660; e.yehthreedotsbelowarabic = 1745; e.yekorean = 12630; e.yen = 165; e.yenmonospace = 65509; e.yeokorean = 12629; e.yeorinhieuhkorean = 12678; e.yerahbenyomohebrew = 1450; e.yerahbenyomolefthebrew = 1450; e.yericyrillic = 1099; e.yerudieresiscyrillic = 1273; e.yesieungkorean = 12673; e.yesieungpansioskorean = 12675; e.yesieungsioskorean = 12674; e.yetivhebrew = 1434; e.ygrave = 7923; e.yhook = 436; e.yhookabove = 7927; e.yiarmenian = 1397; e.yicyrillic = 1111; e.yikorean = 12642; e.yinyang = 9775; e.yiwnarmenian = 1410; e.ymonospace = 65369; e.yod = 1497; e.yoddagesh = 64313; e.yoddageshhebrew = 64313; e.yodhebrew = 1497; e.yodyodhebrew = 1522; e.yodyodpatahhebrew = 64287; e.yohiragana = 12424; e.yoikorean = 12681; e.yokatakana = 12520; e.yokatakanahalfwidth = 65430; e.yokorean = 12635; e.yosmallhiragana = 12423; e.yosmallkatakana = 12519; e.yosmallkatakanahalfwidth = 65390; e.yotgreek = 1011; e.yoyaekorean = 12680; e.yoyakorean = 12679; e.yoyakthai = 3618; e.yoyingthai = 3597; e.yparen = 9396; e.ypogegrammeni = 890; e.ypogegrammenigreekcmb = 837; e.yr = 422; e.yring = 7833; e.ysuperior = 696; e.ytilde = 7929; e.yturned = 654; e.yuhiragana = 12422; e.yuikorean = 12684; e.yukatakana = 12518; e.yukatakanahalfwidth = 65429; e.yukorean = 12640; e.yusbigcyrillic = 1131; e.yusbigiotifiedcyrillic = 1133; e.yuslittlecyrillic = 1127; e.yuslittleiotifiedcyrillic = 1129; e.yusmallhiragana = 12421; e.yusmallkatakana = 12517; e.yusmallkatakanahalfwidth = 65389; e.yuyekorean = 12683; e.yuyeokorean = 12682; e.yyabengali = 2527; e.yyadeva = 2399; e.z = 122; e.zaarmenian = 1382; e.zacute = 378; e.zadeva = 2395; e.zagurmukhi = 2651; e.zaharabic = 1592; e.zahfinalarabic = 65222; e.zahinitialarabic = 65223; e.zahiragana = 12374; e.zahmedialarabic = 65224; e.zainarabic = 1586; e.zainfinalarabic = 65200; e.zakatakana = 12470; e.zaqefgadolhebrew = 1429; e.zaqefqatanhebrew = 1428; e.zarqahebrew = 1432; e.zayin = 1494; e.zayindagesh = 64310; e.zayindageshhebrew = 64310; e.zayinhebrew = 1494; e.zbopomofo = 12567; e.zcaron = 382; e.zcircle = 9449; e.zcircumflex = 7825; e.zcurl = 657; e.zdot = 380; e.zdotaccent = 380; e.zdotbelow = 7827; e.zecyrillic = 1079; e.zedescendercyrillic = 1177; e.zedieresiscyrillic = 1247; e.zehiragana = 12380; e.zekatakana = 12476; e.zero = 48; e.zeroarabic = 1632; e.zerobengali = 2534; e.zerodeva = 2406; e.zerogujarati = 2790; e.zerogurmukhi = 2662; e.zerohackarabic = 1632; e.zeroinferior = 8320; e.zeromonospace = 65296; e.zerooldstyle = 63280; e.zeropersian = 1776; e.zerosuperior = 8304; e.zerothai = 3664; e.zerowidthjoiner = 65279; e.zerowidthnonjoiner = 8204; e.zerowidthspace = 8203; e.zeta = 950; e.zhbopomofo = 12563; e.zhearmenian = 1386; e.zhebrevecyrillic = 1218; e.zhecyrillic = 1078; e.zhedescendercyrillic = 1175; e.zhedieresiscyrillic = 1245; e.zihiragana = 12376; e.zikatakana = 12472; e.zinorhebrew = 1454; e.zlinebelow = 7829; e.zmonospace = 65370; e.zohiragana = 12382; e.zokatakana = 12478; e.zparen = 9397; e.zretroflexhook = 656; e.zstroke = 438; e.zuhiragana = 12378; e.zukatakana = 12474; e[".notdef"] = 0; e.angbracketleftbig = 9001; e.angbracketleftBig = 9001; e.angbracketleftbigg = 9001; e.angbracketleftBigg = 9001; e.angbracketrightBig = 9002; e.angbracketrightbig = 9002; e.angbracketrightBigg = 9002; e.angbracketrightbigg = 9002; e.arrowhookleft = 8618; e.arrowhookright = 8617; e.arrowlefttophalf = 8636; e.arrowleftbothalf = 8637; e.arrownortheast = 8599; e.arrownorthwest = 8598; e.arrowrighttophalf = 8640; e.arrowrightbothalf = 8641; e.arrowsoutheast = 8600; e.arrowsouthwest = 8601; e.backslashbig = 8726; e.backslashBig = 8726; e.backslashBigg = 8726; e.backslashbigg = 8726; e.bardbl = 8214; e.bracehtipdownleft = 65079; e.bracehtipdownright = 65079; e.bracehtipupleft = 65080; e.bracehtipupright = 65080; e.braceleftBig = 123; e.braceleftbig = 123; e.braceleftbigg = 123; e.braceleftBigg = 123; e.bracerightBig = 125; e.bracerightbig = 125; e.bracerightbigg = 125; e.bracerightBigg = 125; e.bracketleftbig = 91; e.bracketleftBig = 91; e.bracketleftbigg = 91; e.bracketleftBigg = 91; e.bracketrightBig = 93; e.bracketrightbig = 93; e.bracketrightbigg = 93; e.bracketrightBigg = 93; e.ceilingleftbig = 8968; e.ceilingleftBig = 8968; e.ceilingleftBigg = 8968; e.ceilingleftbigg = 8968; e.ceilingrightbig = 8969; e.ceilingrightBig = 8969; e.ceilingrightbigg = 8969; e.ceilingrightBigg = 8969; e.circledotdisplay = 8857; e.circledottext = 8857; e.circlemultiplydisplay = 8855; e.circlemultiplytext = 8855; e.circleplusdisplay = 8853; e.circleplustext = 8853; e.contintegraldisplay = 8750; e.contintegraltext = 8750; e.coproductdisplay = 8720; e.coproducttext = 8720; e.floorleftBig = 8970; e.floorleftbig = 8970; e.floorleftbigg = 8970; e.floorleftBigg = 8970; e.floorrightbig = 8971; e.floorrightBig = 8971; e.floorrightBigg = 8971; e.floorrightbigg = 8971; e.hatwide = 770; e.hatwider = 770; e.hatwidest = 770; e.intercal = 7488; e.integraldisplay = 8747; e.integraltext = 8747; e.intersectiondisplay = 8898; e.intersectiontext = 8898; e.logicalanddisplay = 8743; e.logicalandtext = 8743; e.logicalordisplay = 8744; e.logicalortext = 8744; e.parenleftBig = 40; e.parenleftbig = 40; e.parenleftBigg = 40; e.parenleftbigg = 40; e.parenrightBig = 41; e.parenrightbig = 41; e.parenrightBigg = 41; e.parenrightbigg = 41; e.prime = 8242; e.productdisplay = 8719; e.producttext = 8719; e.radicalbig = 8730; e.radicalBig = 8730; e.radicalBigg = 8730; e.radicalbigg = 8730; e.radicalbt = 8730; e.radicaltp = 8730; e.radicalvertex = 8730; e.slashbig = 47; e.slashBig = 47; e.slashBigg = 47; e.slashbigg = 47; e.summationdisplay = 8721; e.summationtext = 8721; e.tildewide = 732; e.tildewider = 732; e.tildewidest = 732; e.uniondisplay = 8899; e.unionmultidisplay = 8846; e.unionmultitext = 8846; e.unionsqdisplay = 8852; e.unionsqtext = 8852; e.uniontext = 8899; e.vextenddouble = 8741; e.vextendsingle = 8739 })), n = r((function (e) { e.space = 32; e.a1 = 9985; e.a2 = 9986; e.a202 = 9987; e.a3 = 9988; e.a4 = 9742; e.a5 = 9990; e.a119 = 9991; e.a118 = 9992; e.a117 = 9993; e.a11 = 9755; e.a12 = 9758; e.a13 = 9996; e.a14 = 9997; e.a15 = 9998; e.a16 = 9999; e.a105 = 1e4; e.a17 = 10001; e.a18 = 10002; e.a19 = 10003; e.a20 = 10004; e.a21 = 10005; e.a22 = 10006; e.a23 = 10007; e.a24 = 10008; e.a25 = 10009; e.a26 = 10010; e.a27 = 10011; e.a28 = 10012; e.a6 = 10013; e.a7 = 10014; e.a8 = 10015; e.a9 = 10016; e.a10 = 10017; e.a29 = 10018; e.a30 = 10019; e.a31 = 10020; e.a32 = 10021; e.a33 = 10022; e.a34 = 10023; e.a35 = 9733; e.a36 = 10025; e.a37 = 10026; e.a38 = 10027; e.a39 = 10028; e.a40 = 10029; e.a41 = 10030; e.a42 = 10031; e.a43 = 10032; e.a44 = 10033; e.a45 = 10034; e.a46 = 10035; e.a47 = 10036; e.a48 = 10037; e.a49 = 10038; e.a50 = 10039; e.a51 = 10040; e.a52 = 10041; e.a53 = 10042; e.a54 = 10043; e.a55 = 10044; e.a56 = 10045; e.a57 = 10046; e.a58 = 10047; e.a59 = 10048; e.a60 = 10049; e.a61 = 10050; e.a62 = 10051; e.a63 = 10052; e.a64 = 10053; e.a65 = 10054; e.a66 = 10055; e.a67 = 10056; e.a68 = 10057; e.a69 = 10058; e.a70 = 10059; e.a71 = 9679; e.a72 = 10061; e.a73 = 9632; e.a74 = 10063; e.a203 = 10064; e.a75 = 10065; e.a204 = 10066; e.a76 = 9650; e.a77 = 9660; e.a78 = 9670; e.a79 = 10070; e.a81 = 9687; e.a82 = 10072; e.a83 = 10073; e.a84 = 10074; e.a97 = 10075; e.a98 = 10076; e.a99 = 10077; e.a100 = 10078; e.a101 = 10081; e.a102 = 10082; e.a103 = 10083; e.a104 = 10084; e.a106 = 10085; e.a107 = 10086; e.a108 = 10087; e.a112 = 9827; e.a111 = 9830; e.a110 = 9829; e.a109 = 9824; e.a120 = 9312; e.a121 = 9313; e.a122 = 9314; e.a123 = 9315; e.a124 = 9316; e.a125 = 9317; e.a126 = 9318; e.a127 = 9319; e.a128 = 9320; e.a129 = 9321; e.a130 = 10102; e.a131 = 10103; e.a132 = 10104; e.a133 = 10105; e.a134 = 10106; e.a135 = 10107; e.a136 = 10108; e.a137 = 10109; e.a138 = 10110; e.a139 = 10111; e.a140 = 10112; e.a141 = 10113; e.a142 = 10114; e.a143 = 10115; e.a144 = 10116; e.a145 = 10117; e.a146 = 10118; e.a147 = 10119; e.a148 = 10120; e.a149 = 10121; e.a150 = 10122; e.a151 = 10123; e.a152 = 10124; e.a153 = 10125; e.a154 = 10126; e.a155 = 10127; e.a156 = 10128; e.a157 = 10129; e.a158 = 10130; e.a159 = 10131; e.a160 = 10132; e.a161 = 8594; e.a163 = 8596; e.a164 = 8597; e.a196 = 10136; e.a165 = 10137; e.a192 = 10138; e.a166 = 10139; e.a167 = 10140; e.a168 = 10141; e.a169 = 10142; e.a170 = 10143; e.a171 = 10144; e.a172 = 10145; e.a173 = 10146; e.a162 = 10147; e.a174 = 10148; e.a175 = 10149; e.a176 = 10150; e.a177 = 10151; e.a178 = 10152; e.a179 = 10153; e.a193 = 10154; e.a180 = 10155; e.a199 = 10156; e.a181 = 10157; e.a200 = 10158; e.a182 = 10159; e.a201 = 10161; e.a183 = 10162; e.a184 = 10163; e.a197 = 10164; e.a185 = 10165; e.a194 = 10166; e.a198 = 10167; e.a186 = 10168; e.a195 = 10169; e.a187 = 10170; e.a188 = 10171; e.a189 = 10172; e.a190 = 10173; e.a191 = 10174; e.a89 = 10088; e.a90 = 10089; e.a93 = 10090; e.a94 = 10091; e.a91 = 10092; e.a92 = 10093; e.a205 = 10094; e.a85 = 10095; e.a206 = 10096; e.a86 = 10097; e.a87 = 10098; e.a88 = 10099; e.a95 = 10100; e.a96 = 10101; e[".notdef"] = 0 })); t.getGlyphsUnicode = i; t.getDingbatsGlyphsUnicode = n }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getSupplementalGlyphMapForCalibri = t.getSupplementalGlyphMapForArialBlack = t.getGlyphMapForStandardFonts = t.getSymbolsFonts = t.getSerifFonts = t.getNonStdFontMap = t.getStdFontMap = void 0; var r = a(7); const i = (0, r.getLookupTableFactory)((function (e) { e.ArialNarrow = "Helvetica"; e["ArialNarrow-Bold"] = "Helvetica-Bold"; e["ArialNarrow-BoldItalic"] = "Helvetica-BoldOblique"; e["ArialNarrow-Italic"] = "Helvetica-Oblique"; e.ArialBlack = "Helvetica"; e["ArialBlack-Bold"] = "Helvetica-Bold"; e["ArialBlack-BoldItalic"] = "Helvetica-BoldOblique"; e["ArialBlack-Italic"] = "Helvetica-Oblique"; e["Arial-Black"] = "Helvetica"; e["Arial-Black-Bold"] = "Helvetica-Bold"; e["Arial-Black-BoldItalic"] = "Helvetica-BoldOblique"; e["Arial-Black-Italic"] = "Helvetica-Oblique"; e.Arial = "Helvetica"; e["Arial-Bold"] = "Helvetica-Bold"; e["Arial-BoldItalic"] = "Helvetica-BoldOblique"; e["Arial-Italic"] = "Helvetica-Oblique"; e["Arial-BoldItalicMT"] = "Helvetica-BoldOblique"; e["Arial-BoldMT"] = "Helvetica-Bold"; e["Arial-ItalicMT"] = "Helvetica-Oblique"; e.ArialMT = "Helvetica"; e["Courier-Bold"] = "Courier-Bold"; e["Courier-BoldItalic"] = "Courier-BoldOblique"; e["Courier-Italic"] = "Courier-Oblique"; e.CourierNew = "Courier"; e["CourierNew-Bold"] = "Courier-Bold"; e["CourierNew-BoldItalic"] = "Courier-BoldOblique"; e["CourierNew-Italic"] = "Courier-Oblique"; e["CourierNewPS-BoldItalicMT"] = "Courier-BoldOblique"; e["CourierNewPS-BoldMT"] = "Courier-Bold"; e["CourierNewPS-ItalicMT"] = "Courier-Oblique"; e.CourierNewPSMT = "Courier"; e.Helvetica = "Helvetica"; e["Helvetica-Bold"] = "Helvetica-Bold"; e["Helvetica-BoldItalic"] = "Helvetica-BoldOblique"; e["Helvetica-BoldOblique"] = "Helvetica-BoldOblique"; e["Helvetica-Italic"] = "Helvetica-Oblique"; e["Helvetica-Oblique"] = "Helvetica-Oblique"; e["Symbol-Bold"] = "Symbol"; e["Symbol-BoldItalic"] = "Symbol"; e["Symbol-Italic"] = "Symbol"; e.TimesNewRoman = "Times-Roman"; e["TimesNewRoman-Bold"] = "Times-Bold"; e["TimesNewRoman-BoldItalic"] = "Times-BoldItalic"; e["TimesNewRoman-Italic"] = "Times-Italic"; e.TimesNewRomanPS = "Times-Roman"; e["TimesNewRomanPS-Bold"] = "Times-Bold"; e["TimesNewRomanPS-BoldItalic"] = "Times-BoldItalic"; e["TimesNewRomanPS-BoldItalicMT"] = "Times-BoldItalic"; e["TimesNewRomanPS-BoldMT"] = "Times-Bold"; e["TimesNewRomanPS-Italic"] = "Times-Italic"; e["TimesNewRomanPS-ItalicMT"] = "Times-Italic"; e.TimesNewRomanPSMT = "Times-Roman"; e["TimesNewRomanPSMT-Bold"] = "Times-Bold"; e["TimesNewRomanPSMT-BoldItalic"] = "Times-BoldItalic"; e["TimesNewRomanPSMT-Italic"] = "Times-Italic" })); t.getStdFontMap = i; const n = (0, r.getLookupTableFactory)((function (e) { e.Calibri = "Helvetica"; e["Calibri-Bold"] = "Helvetica-Bold"; e["Calibri-BoldItalic"] = "Helvetica-BoldOblique"; e["Calibri-Italic"] = "Helvetica-Oblique"; e.CenturyGothic = "Helvetica"; e["CenturyGothic-Bold"] = "Helvetica-Bold"; e["CenturyGothic-BoldItalic"] = "Helvetica-BoldOblique"; e["CenturyGothic-Italic"] = "Helvetica-Oblique"; e.ComicSansMS = "Comic Sans MS"; e["ComicSansMS-Bold"] = "Comic Sans MS-Bold"; e["ComicSansMS-BoldItalic"] = "Comic Sans MS-BoldItalic"; e["ComicSansMS-Italic"] = "Comic Sans MS-Italic"; e.LucidaConsole = "Courier"; e["LucidaConsole-Bold"] = "Courier-Bold"; e["LucidaConsole-BoldItalic"] = "Courier-BoldOblique"; e["LucidaConsole-Italic"] = "Courier-Oblique"; e["LucidaSans-Demi"] = "Helvetica-Bold"; e["MS-Gothic"] = "MS Gothic"; e["MS-Gothic-Bold"] = "MS Gothic-Bold"; e["MS-Gothic-BoldItalic"] = "MS Gothic-BoldItalic"; e["MS-Gothic-Italic"] = "MS Gothic-Italic"; e["MS-Mincho"] = "MS Mincho"; e["MS-Mincho-Bold"] = "MS Mincho-Bold"; e["MS-Mincho-BoldItalic"] = "MS Mincho-BoldItalic"; e["MS-Mincho-Italic"] = "MS Mincho-Italic"; e["MS-PGothic"] = "MS PGothic"; e["MS-PGothic-Bold"] = "MS PGothic-Bold"; e["MS-PGothic-BoldItalic"] = "MS PGothic-BoldItalic"; e["MS-PGothic-Italic"] = "MS PGothic-Italic"; e["MS-PMincho"] = "MS PMincho"; e["MS-PMincho-Bold"] = "MS PMincho-Bold"; e["MS-PMincho-BoldItalic"] = "MS PMincho-BoldItalic"; e["MS-PMincho-Italic"] = "MS PMincho-Italic"; e.NuptialScript = "Times-Italic"; e.SegoeUISymbol = "Helvetica"; e.Wingdings = "ZapfDingbats"; e["Wingdings-Regular"] = "ZapfDingbats" })); t.getNonStdFontMap = n; const s = (0, r.getLookupTableFactory)((function (e) { e["Adobe Jenson"] = !0; e["Adobe Text"] = !0; e.Albertus = !0; e.Aldus = !0; e.Alexandria = !0; e.Algerian = !0; e["American Typewriter"] = !0; e.Antiqua = !0; e.Apex = !0; e.Arno = !0; e.Aster = !0; e.Aurora = !0; e.Baskerville = !0; e.Bell = !0; e.Bembo = !0; e["Bembo Schoolbook"] = !0; e.Benguiat = !0; e["Berkeley Old Style"] = !0; e["Bernhard Modern"] = !0; e["Berthold City"] = !0; e.Bodoni = !0; e["Bauer Bodoni"] = !0; e["Book Antiqua"] = !0; e.Bookman = !0; e["Bordeaux Roman"] = !0; e["Californian FB"] = !0; e.Calisto = !0; e.Calvert = !0; e.Capitals = !0; e.Cambria = !0; e.Cartier = !0; e.Caslon = !0; e.Catull = !0; e.Centaur = !0; e["Century Old Style"] = !0; e["Century Schoolbook"] = !0; e.Chaparral = !0; e["Charis SIL"] = !0; e.Cheltenham = !0; e["Cholla Slab"] = !0; e.Clarendon = !0; e.Clearface = !0; e.Cochin = !0; e.Colonna = !0; e["Computer Modern"] = !0; e["Concrete Roman"] = !0; e.Constantia = !0; e["Cooper Black"] = !0; e.Corona = !0; e.Ecotype = !0; e.Egyptienne = !0; e.Elephant = !0; e.Excelsior = !0; e.Fairfield = !0; e["FF Scala"] = !0; e.Folkard = !0; e.Footlight = !0; e.FreeSerif = !0; e["Friz Quadrata"] = !0; e.Garamond = !0; e.Gentium = !0; e.Georgia = !0; e.Gloucester = !0; e["Goudy Old Style"] = !0; e["Goudy Schoolbook"] = !0; e["Goudy Pro Font"] = !0; e.Granjon = !0; e["Guardian Egyptian"] = !0; e.Heather = !0; e.Hercules = !0; e["High Tower Text"] = !0; e.Hiroshige = !0; e["Hoefler Text"] = !0; e["Humana Serif"] = !0; e.Imprint = !0; e["Ionic No. 5"] = !0; e.Janson = !0; e.Joanna = !0; e.Korinna = !0; e.Lexicon = !0; e["Liberation Serif"] = !0; e["Linux Libertine"] = !0; e.Literaturnaya = !0; e.Lucida = !0; e["Lucida Bright"] = !0; e.Melior = !0; e.Memphis = !0; e.Miller = !0; e.Minion = !0; e.Modern = !0; e["Mona Lisa"] = !0; e["Mrs Eaves"] = !0; e["MS Serif"] = !0; e["Museo Slab"] = !0; e["New York"] = !0; e["Nimbus Roman"] = !0; e["NPS Rawlinson Roadway"] = !0; e.NuptialScript = !0; e.Palatino = !0; e.Perpetua = !0; e.Plantin = !0; e["Plantin Schoolbook"] = !0; e.Playbill = !0; e["Poor Richard"] = !0; e["Rawlinson Roadway"] = !0; e.Renault = !0; e.Requiem = !0; e.Rockwell = !0; e.Roman = !0; e["Rotis Serif"] = !0; e.Sabon = !0; e.Scala = !0; e.Seagull = !0; e.Sistina = !0; e.Souvenir = !0; e.STIX = !0; e["Stone Informal"] = !0; e["Stone Serif"] = !0; e.Sylfaen = !0; e.Times = !0; e.Trajan = !0; e["Trinité"] = !0; e["Trump Mediaeval"] = !0; e.Utopia = !0; e["Vale Type"] = !0; e["Bitstream Vera"] = !0; e["Vera Serif"] = !0; e.Versailles = !0; e.Wanted = !0; e.Weiss = !0; e["Wide Latin"] = !0; e.Windsor = !0; e.XITS = !0 })); t.getSerifFonts = s; const o = (0, r.getLookupTableFactory)((function (e) { e.Dingbats = !0; e.Symbol = !0; e.ZapfDingbats = !0 })); t.getSymbolsFonts = o; const c = (0, r.getLookupTableFactory)((function (e) { e[2] = 10; e[3] = 32; e[4] = 33; e[5] = 34; e[6] = 35; e[7] = 36; e[8] = 37; e[9] = 38; e[10] = 39; e[11] = 40; e[12] = 41; e[13] = 42; e[14] = 43; e[15] = 44; e[16] = 45; e[17] = 46; e[18] = 47; e[19] = 48; e[20] = 49; e[21] = 50; e[22] = 51; e[23] = 52; e[24] = 53; e[25] = 54; e[26] = 55; e[27] = 56; e[28] = 57; e[29] = 58; e[30] = 894; e[31] = 60; e[32] = 61; e[33] = 62; e[34] = 63; e[35] = 64; e[36] = 65; e[37] = 66; e[38] = 67; e[39] = 68; e[40] = 69; e[41] = 70; e[42] = 71; e[43] = 72; e[44] = 73; e[45] = 74; e[46] = 75; e[47] = 76; e[48] = 77; e[49] = 78; e[50] = 79; e[51] = 80; e[52] = 81; e[53] = 82; e[54] = 83; e[55] = 84; e[56] = 85; e[57] = 86; e[58] = 87; e[59] = 88; e[60] = 89; e[61] = 90; e[62] = 91; e[63] = 92; e[64] = 93; e[65] = 94; e[66] = 95; e[67] = 96; e[68] = 97; e[69] = 98; e[70] = 99; e[71] = 100; e[72] = 101; e[73] = 102; e[74] = 103; e[75] = 104; e[76] = 105; e[77] = 106; e[78] = 107; e[79] = 108; e[80] = 109; e[81] = 110; e[82] = 111; e[83] = 112; e[84] = 113; e[85] = 114; e[86] = 115; e[87] = 116; e[88] = 117; e[89] = 118; e[90] = 119; e[91] = 120; e[92] = 121; e[93] = 122; e[94] = 123; e[95] = 124; e[96] = 125; e[97] = 126; e[98] = 196; e[99] = 197; e[100] = 199; e[101] = 201; e[102] = 209; e[103] = 214; e[104] = 220; e[105] = 225; e[106] = 224; e[107] = 226; e[108] = 228; e[109] = 227; e[110] = 229; e[111] = 231; e[112] = 233; e[113] = 232; e[114] = 234; e[115] = 235; e[116] = 237; e[117] = 236; e[118] = 238; e[119] = 239; e[120] = 241; e[121] = 243; e[122] = 242; e[123] = 244; e[124] = 246; e[125] = 245; e[126] = 250; e[127] = 249; e[128] = 251; e[129] = 252; e[130] = 8224; e[131] = 176; e[132] = 162; e[133] = 163; e[134] = 167; e[135] = 8226; e[136] = 182; e[137] = 223; e[138] = 174; e[139] = 169; e[140] = 8482; e[141] = 180; e[142] = 168; e[143] = 8800; e[144] = 198; e[145] = 216; e[146] = 8734; e[147] = 177; e[148] = 8804; e[149] = 8805; e[150] = 165; e[151] = 181; e[152] = 8706; e[153] = 8721; e[154] = 8719; e[156] = 8747; e[157] = 170; e[158] = 186; e[159] = 8486; e[160] = 230; e[161] = 248; e[162] = 191; e[163] = 161; e[164] = 172; e[165] = 8730; e[166] = 402; e[167] = 8776; e[168] = 8710; e[169] = 171; e[170] = 187; e[171] = 8230; e[210] = 218; e[223] = 711; e[224] = 321; e[225] = 322; e[227] = 353; e[229] = 382; e[234] = 253; e[252] = 263; e[253] = 268; e[254] = 269; e[258] = 258; e[260] = 260; e[261] = 261; e[265] = 280; e[266] = 281; e[268] = 283; e[269] = 313; e[275] = 323; e[276] = 324; e[278] = 328; e[284] = 345; e[285] = 346; e[286] = 347; e[292] = 367; e[295] = 377; e[296] = 378; e[298] = 380; e[305] = 963; e[306] = 964; e[307] = 966; e[308] = 8215; e[309] = 8252; e[310] = 8319; e[311] = 8359; e[312] = 8592; e[313] = 8593; e[337] = 9552; e[493] = 1039; e[494] = 1040; e[705] = 1524; e[706] = 8362; e[710] = 64288; e[711] = 64298; e[759] = 1617; e[761] = 1776; e[763] = 1778; e[775] = 1652; e[777] = 1764; e[778] = 1780; e[779] = 1781; e[780] = 1782; e[782] = 771; e[783] = 64726; e[786] = 8363; e[788] = 8532; e[790] = 768; e[791] = 769; e[792] = 768; e[795] = 803; e[797] = 64336; e[798] = 64337; e[799] = 64342; e[800] = 64343; e[801] = 64344; e[802] = 64345; e[803] = 64362; e[804] = 64363; e[805] = 64364; e[2424] = 7821; e[2425] = 7822; e[2426] = 7823; e[2427] = 7824; e[2428] = 7825; e[2429] = 7826; e[2430] = 7827; e[2433] = 7682; e[2678] = 8045; e[2679] = 8046; e[2830] = 1552; e[2838] = 686; e[2840] = 751; e[2842] = 753; e[2843] = 754; e[2844] = 755; e[2846] = 757; e[2856] = 767; e[2857] = 848; e[2858] = 849; e[2862] = 853; e[2863] = 854; e[2864] = 855; e[2865] = 861; e[2866] = 862; e[2906] = 7460; e[2908] = 7462; e[2909] = 7463; e[2910] = 7464; e[2912] = 7466; e[2913] = 7467; e[2914] = 7468; e[2916] = 7470; e[2917] = 7471; e[2918] = 7472; e[2920] = 7474; e[2921] = 7475; e[2922] = 7476; e[2924] = 7478; e[2925] = 7479; e[2926] = 7480; e[2928] = 7482; e[2929] = 7483; e[2930] = 7484; e[2932] = 7486; e[2933] = 7487; e[2934] = 7488; e[2936] = 7490; e[2937] = 7491; e[2938] = 7492; e[2940] = 7494; e[2941] = 7495; e[2942] = 7496; e[2944] = 7498; e[2946] = 7500; e[2948] = 7502; e[2950] = 7504; e[2951] = 7505; e[2952] = 7506; e[2954] = 7508; e[2955] = 7509; e[2956] = 7510; e[2958] = 7512; e[2959] = 7513; e[2960] = 7514; e[2962] = 7516; e[2963] = 7517; e[2964] = 7518; e[2966] = 7520; e[2967] = 7521; e[2968] = 7522; e[2970] = 7524; e[2971] = 7525; e[2972] = 7526; e[2974] = 7528; e[2975] = 7529; e[2976] = 7530; e[2978] = 1537; e[2979] = 1538; e[2980] = 1539; e[2982] = 1549; e[2983] = 1551; e[2984] = 1552; e[2986] = 1554; e[2987] = 1555; e[2988] = 1556; e[2990] = 1623; e[2991] = 1624; e[2995] = 1775; e[2999] = 1791; e[3002] = 64290; e[3003] = 64291; e[3004] = 64292; e[3006] = 64294; e[3007] = 64295; e[3008] = 64296; e[3011] = 1900; e[3014] = 8223; e[3015] = 8244; e[3017] = 7532; e[3018] = 7533; e[3019] = 7534; e[3075] = 7590; e[3076] = 7591; e[3079] = 7594; e[3080] = 7595; e[3083] = 7598; e[3084] = 7599; e[3087] = 7602; e[3088] = 7603; e[3091] = 7606; e[3092] = 7607; e[3095] = 7610; e[3096] = 7611; e[3099] = 7614; e[3100] = 7615; e[3103] = 7618; e[3104] = 7619; e[3107] = 8337; e[3108] = 8338; e[3116] = 1884; e[3119] = 1885; e[3120] = 1885; e[3123] = 1886; e[3124] = 1886; e[3127] = 1887; e[3128] = 1887; e[3131] = 1888; e[3132] = 1888; e[3135] = 1889; e[3136] = 1889; e[3139] = 1890; e[3140] = 1890; e[3143] = 1891; e[3144] = 1891; e[3147] = 1892; e[3148] = 1892; e[3153] = 580; e[3154] = 581; e[3157] = 584; e[3158] = 585; e[3161] = 588; e[3162] = 589; e[3165] = 891; e[3166] = 892; e[3169] = 1274; e[3170] = 1275; e[3173] = 1278; e[3174] = 1279; e[3181] = 7622; e[3182] = 7623; e[3282] = 11799; e[3316] = 578; e[3379] = 42785; e[3393] = 1159; e[3416] = 8377 })); t.getGlyphMapForStandardFonts = c; const l = (0, r.getLookupTableFactory)((function (e) { e[227] = 322; e[264] = 261; e[291] = 346 })); t.getSupplementalGlyphMapForArialBlack = l; const h = (0, r.getLookupTableFactory)((function (e) { e[1] = 32; e[4] = 65; e[17] = 66; e[18] = 67; e[24] = 68; e[28] = 69; e[38] = 70; e[39] = 71; e[44] = 72; e[47] = 73; e[58] = 74; e[60] = 75; e[62] = 76; e[68] = 77; e[69] = 78; e[75] = 79; e[87] = 80; e[89] = 81; e[90] = 82; e[94] = 83; e[100] = 84; e[104] = 85; e[115] = 86; e[116] = 87; e[121] = 88; e[122] = 89; e[127] = 90; e[258] = 97; e[268] = 261; e[271] = 98; e[272] = 99; e[273] = 263; e[282] = 100; e[286] = 101; e[295] = 281; e[296] = 102; e[336] = 103; e[346] = 104; e[349] = 105; e[361] = 106; e[364] = 107; e[367] = 108; e[371] = 322; e[373] = 109; e[374] = 110; e[381] = 111; e[383] = 243; e[393] = 112; e[395] = 113; e[396] = 114; e[400] = 115; e[401] = 347; e[410] = 116; e[437] = 117; e[448] = 118; e[449] = 119; e[454] = 120; e[455] = 121; e[460] = 122; e[463] = 380; e[853] = 44; e[855] = 58; e[856] = 46; e[876] = 47; e[878] = 45; e[882] = 45; e[894] = 40; e[895] = 41; e[896] = 91; e[897] = 93; e[923] = 64; e[1004] = 48; e[1005] = 49; e[1006] = 50; e[1007] = 51; e[1008] = 52; e[1009] = 53; e[1010] = 54; e[1011] = 55; e[1012] = 56; e[1013] = 57; e[1081] = 37; e[1085] = 43; e[1086] = 45 })); t.getSupplementalGlyphMapForCalibri = h }, function (e, t, a) { var r = a(7).getLookupTableFactory, i = r((function (e) { e[63721] = 169; e[63193] = 169; e[63720] = 174; e[63194] = 174; e[63722] = 8482; e[63195] = 8482; e[63729] = 9127; e[63730] = 9128; e[63731] = 9129; e[63740] = 9131; e[63741] = 9132; e[63742] = 9133; e[63726] = 9121; e[63727] = 9122; e[63728] = 9123; e[63737] = 9124; e[63738] = 9125; e[63739] = 9126; e[63723] = 9115; e[63724] = 9116; e[63725] = 9117; e[63734] = 9118; e[63735] = 9119; e[63736] = 9120 })); var n = [{ begin: 0, end: 127 }, { begin: 128, end: 255 }, { begin: 256, end: 383 }, { begin: 384, end: 591 }, { begin: 592, end: 687 }, { begin: 688, end: 767 }, { begin: 768, end: 879 }, { begin: 880, end: 1023 }, { begin: 11392, end: 11519 }, { begin: 1024, end: 1279 }, { begin: 1328, end: 1423 }, { begin: 1424, end: 1535 }, { begin: 42240, end: 42559 }, { begin: 1536, end: 1791 }, { begin: 1984, end: 2047 }, { begin: 2304, end: 2431 }, { begin: 2432, end: 2559 }, { begin: 2560, end: 2687 }, { begin: 2688, end: 2815 }, { begin: 2816, end: 2943 }, { begin: 2944, end: 3071 }, { begin: 3072, end: 3199 }, { begin: 3200, end: 3327 }, { begin: 3328, end: 3455 }, { begin: 3584, end: 3711 }, { begin: 3712, end: 3839 }, { begin: 4256, end: 4351 }, { begin: 6912, end: 7039 }, { begin: 4352, end: 4607 }, { begin: 7680, end: 7935 }, { begin: 7936, end: 8191 }, { begin: 8192, end: 8303 }, { begin: 8304, end: 8351 }, { begin: 8352, end: 8399 }, { begin: 8400, end: 8447 }, { begin: 8448, end: 8527 }, { begin: 8528, end: 8591 }, { begin: 8592, end: 8703 }, { begin: 8704, end: 8959 }, { begin: 8960, end: 9215 }, { begin: 9216, end: 9279 }, { begin: 9280, end: 9311 }, { begin: 9312, end: 9471 }, { begin: 9472, end: 9599 }, { begin: 9600, end: 9631 }, { begin: 9632, end: 9727 }, { begin: 9728, end: 9983 }, { begin: 9984, end: 10175 }, { begin: 12288, end: 12351 }, { begin: 12352, end: 12447 }, { begin: 12448, end: 12543 }, { begin: 12544, end: 12591 }, { begin: 12592, end: 12687 }, { begin: 43072, end: 43135 }, { begin: 12800, end: 13055 }, { begin: 13056, end: 13311 }, { begin: 44032, end: 55215 }, { begin: 55296, end: 57343 }, { begin: 67840, end: 67871 }, { begin: 19968, end: 40959 }, { begin: 57344, end: 63743 }, { begin: 12736, end: 12783 }, { begin: 64256, end: 64335 }, { begin: 64336, end: 65023 }, { begin: 65056, end: 65071 }, { begin: 65040, end: 65055 }, { begin: 65104, end: 65135 }, { begin: 65136, end: 65279 }, { begin: 65280, end: 65519 }, { begin: 65520, end: 65535 }, { begin: 3840, end: 4095 }, { begin: 1792, end: 1871 }, { begin: 1920, end: 1983 }, { begin: 3456, end: 3583 }, { begin: 4096, end: 4255 }, { begin: 4608, end: 4991 }, { begin: 5024, end: 5119 }, { begin: 5120, end: 5759 }, { begin: 5760, end: 5791 }, { begin: 5792, end: 5887 }, { begin: 6016, end: 6143 }, { begin: 6144, end: 6319 }, { begin: 10240, end: 10495 }, { begin: 40960, end: 42127 }, { begin: 5888, end: 5919 }, { begin: 66304, end: 66351 }, { begin: 66352, end: 66383 }, { begin: 66560, end: 66639 }, { begin: 118784, end: 119039 }, { begin: 119808, end: 120831 }, { begin: 1044480, end: 1048573 }, { begin: 65024, end: 65039 }, { begin: 917504, end: 917631 }, { begin: 6400, end: 6479 }, { begin: 6480, end: 6527 }, { begin: 6528, end: 6623 }, { begin: 6656, end: 6687 }, { begin: 11264, end: 11359 }, { begin: 11568, end: 11647 }, { begin: 19904, end: 19967 }, { begin: 43008, end: 43055 }, { begin: 65536, end: 65663 }, { begin: 65856, end: 65935 }, { begin: 66432, end: 66463 }, { begin: 66464, end: 66527 }, { begin: 66640, end: 66687 }, { begin: 66688, end: 66735 }, { begin: 67584, end: 67647 }, { begin: 68096, end: 68191 }, { begin: 119552, end: 119647 }, { begin: 73728, end: 74751 }, { begin: 119648, end: 119679 }, { begin: 7040, end: 7103 }, { begin: 7168, end: 7247 }, { begin: 7248, end: 7295 }, { begin: 43136, end: 43231 }, { begin: 43264, end: 43311 }, { begin: 43312, end: 43359 }, { begin: 43520, end: 43615 }, { begin: 65936, end: 65999 }, { begin: 66e3, end: 66047 }, { begin: 66208, end: 66271 }, { begin: 127024, end: 127135 }]; var s = r((function (e) { e["¨"] = " ̈"; e["¯"] = " ̄"; e["´"] = " ́"; e["µ"] = "μ"; e["¸"] = " ̧"; e["IJ"] = "IJ"; e["ij"] = "ij"; e["Ŀ"] = "L·"; e["ŀ"] = "l·"; e["ʼn"] = "ʼn"; e["ſ"] = "s"; e["DŽ"] = "DŽ"; e["Dž"] = "Dž"; e["dž"] = "dž"; e["LJ"] = "LJ"; e["Lj"] = "Lj"; e["lj"] = "lj"; e["NJ"] = "NJ"; e["Nj"] = "Nj"; e["nj"] = "nj"; e["DZ"] = "DZ"; e["Dz"] = "Dz"; e["dz"] = "dz"; e["˘"] = " ̆"; e["˙"] = " ̇"; e["˚"] = " ̊"; e["˛"] = " ̨"; e["˜"] = " ̃"; e["˝"] = " ̋"; e["ͺ"] = " ͅ"; e["΄"] = " ́"; e["ϐ"] = "β"; e["ϑ"] = "θ"; e["ϒ"] = "Υ"; e["ϕ"] = "φ"; e["ϖ"] = "π"; e["ϰ"] = "κ"; e["ϱ"] = "ρ"; e["ϲ"] = "ς"; e["ϴ"] = "Θ"; e["ϵ"] = "ε"; e["Ϲ"] = "Σ"; e["և"] = "եւ"; e["ٵ"] = "اٴ"; e["ٶ"] = "وٴ"; e["ٷ"] = "ۇٴ"; e["ٸ"] = "يٴ"; e["ำ"] = "ํา"; e["ຳ"] = "ໍາ"; e["ໜ"] = "ຫນ"; e["ໝ"] = "ຫມ"; e["ཷ"] = "ྲཱྀ"; e["ཹ"] = "ླཱྀ"; e["ẚ"] = "aʾ"; e["᾽"] = " ̓"; e["᾿"] = " ̓"; e["῀"] = " ͂"; e["῾"] = " ̔"; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e["‗"] = " ̳"; e["․"] = "."; e["‥"] = ".."; e["…"] = "..."; e["″"] = "′′"; e["‴"] = "′′′"; e["‶"] = "‵‵"; e["‷"] = "‵‵‵"; e["‼"] = "!!"; e["‾"] = " ̅"; e["⁇"] = "??"; e["⁈"] = "?!"; e["⁉"] = "!?"; e["⁗"] = "′′′′"; e[" "] = " "; e["₨"] = "Rs"; e["℀"] = "a/c"; e["℁"] = "a/s"; e["℃"] = "°C"; e["℅"] = "c/o"; e["℆"] = "c/u"; e["ℇ"] = "Ɛ"; e["℉"] = "°F"; e["№"] = "No"; e["℡"] = "TEL"; e["ℵ"] = "א"; e["ℶ"] = "ב"; e["ℷ"] = "ג"; e["ℸ"] = "ד"; e["℻"] = "FAX"; e["Ⅰ"] = "I"; e["Ⅱ"] = "II"; e["Ⅲ"] = "III"; e["Ⅳ"] = "IV"; e["Ⅴ"] = "V"; e["Ⅵ"] = "VI"; e["Ⅶ"] = "VII"; e["Ⅷ"] = "VIII"; e["Ⅸ"] = "IX"; e["Ⅹ"] = "X"; e["Ⅺ"] = "XI"; e["Ⅻ"] = "XII"; e["Ⅼ"] = "L"; e["Ⅽ"] = "C"; e["Ⅾ"] = "D"; e["Ⅿ"] = "M"; e["ⅰ"] = "i"; e["ⅱ"] = "ii"; e["ⅲ"] = "iii"; e["ⅳ"] = "iv"; e["ⅴ"] = "v"; e["ⅵ"] = "vi"; e["ⅶ"] = "vii"; e["ⅷ"] = "viii"; e["ⅸ"] = "ix"; e["ⅹ"] = "x"; e["ⅺ"] = "xi"; e["ⅻ"] = "xii"; e["ⅼ"] = "l"; e["ⅽ"] = "c"; e["ⅾ"] = "d"; e["ⅿ"] = "m"; e["∬"] = "∫∫"; e["∭"] = "∫∫∫"; e["∯"] = "∮∮"; e["∰"] = "∮∮∮"; e["⑴"] = "(1)"; e["⑵"] = "(2)"; e["⑶"] = "(3)"; e["⑷"] = "(4)"; e["⑸"] = "(5)"; e["⑹"] = "(6)"; e["⑺"] = "(7)"; e["⑻"] = "(8)"; e["⑼"] = "(9)"; e["⑽"] = "(10)"; e["⑾"] = "(11)"; e["⑿"] = "(12)"; e["⒀"] = "(13)"; e["⒁"] = "(14)"; e["⒂"] = "(15)"; e["⒃"] = "(16)"; e["⒄"] = "(17)"; e["⒅"] = "(18)"; e["⒆"] = "(19)"; e["⒇"] = "(20)"; e["⒈"] = "1."; e["⒉"] = "2."; e["⒊"] = "3."; e["⒋"] = "4."; e["⒌"] = "5."; e["⒍"] = "6."; e["⒎"] = "7."; e["⒏"] = "8."; e["⒐"] = "9."; e["⒑"] = "10."; e["⒒"] = "11."; e["⒓"] = "12."; e["⒔"] = "13."; e["⒕"] = "14."; e["⒖"] = "15."; e["⒗"] = "16."; e["⒘"] = "17."; e["⒙"] = "18."; e["⒚"] = "19."; e["⒛"] = "20."; e["⒜"] = "(a)"; e["⒝"] = "(b)"; e["⒞"] = "(c)"; e["⒟"] = "(d)"; e["⒠"] = "(e)"; e["⒡"] = "(f)"; e["⒢"] = "(g)"; e["⒣"] = "(h)"; e["⒤"] = "(i)"; e["⒥"] = "(j)"; e["⒦"] = "(k)"; e["⒧"] = "(l)"; e["⒨"] = "(m)"; e["⒩"] = "(n)"; e["⒪"] = "(o)"; e["⒫"] = "(p)"; e["⒬"] = "(q)"; e["⒭"] = "(r)"; e["⒮"] = "(s)"; e["⒯"] = "(t)"; e["⒰"] = "(u)"; e["⒱"] = "(v)"; e["⒲"] = "(w)"; e["⒳"] = "(x)"; e["⒴"] = "(y)"; e["⒵"] = "(z)"; e["⨌"] = "∫∫∫∫"; e["⩴"] = "::="; e["⩵"] = "=="; e["⩶"] = "==="; e["⺟"] = "母"; e["⻳"] = "龟"; e["⼀"] = "一"; e["⼁"] = "丨"; e["⼂"] = "丶"; e["⼃"] = "丿"; e["⼄"] = "乙"; e["⼅"] = "亅"; e["⼆"] = "二"; e["⼇"] = "亠"; e["⼈"] = "人"; e["⼉"] = "儿"; e["⼊"] = "入"; e["⼋"] = "八"; e["⼌"] = "冂"; e["⼍"] = "冖"; e["⼎"] = "冫"; e["⼏"] = "几"; e["⼐"] = "凵"; e["⼑"] = "刀"; e["⼒"] = "力"; e["⼓"] = "勹"; e["⼔"] = "匕"; e["⼕"] = "匚"; e["⼖"] = "匸"; e["⼗"] = "十"; e["⼘"] = "卜"; e["⼙"] = "卩"; e["⼚"] = "厂"; e["⼛"] = "厶"; e["⼜"] = "又"; e["⼝"] = "口"; e["⼞"] = "囗"; e["⼟"] = "土"; e["⼠"] = "士"; e["⼡"] = "夂"; e["⼢"] = "夊"; e["⼣"] = "夕"; e["⼤"] = "大"; e["⼥"] = "女"; e["⼦"] = "子"; e["⼧"] = "宀"; e["⼨"] = "寸"; e["⼩"] = "小"; e["⼪"] = "尢"; e["⼫"] = "尸"; e["⼬"] = "屮"; e["⼭"] = "山"; e["⼮"] = "巛"; e["⼯"] = "工"; e["⼰"] = "己"; e["⼱"] = "巾"; e["⼲"] = "干"; e["⼳"] = "幺"; e["⼴"] = "广"; e["⼵"] = "廴"; e["⼶"] = "廾"; e["⼷"] = "弋"; e["⼸"] = "弓"; e["⼹"] = "彐"; e["⼺"] = "彡"; e["⼻"] = "彳"; e["⼼"] = "心"; e["⼽"] = "戈"; e["⼾"] = "戶"; e["⼿"] = "手"; e["⽀"] = "支"; e["⽁"] = "攴"; e["⽂"] = "文"; e["⽃"] = "斗"; e["⽄"] = "斤"; e["⽅"] = "方"; e["⽆"] = "无"; e["⽇"] = "日"; e["⽈"] = "曰"; e["⽉"] = "月"; e["⽊"] = "木"; e["⽋"] = "欠"; e["⽌"] = "止"; e["⽍"] = "歹"; e["⽎"] = "殳"; e["⽏"] = "毋"; e["⽐"] = "比"; e["⽑"] = "毛"; e["⽒"] = "氏"; e["⽓"] = "气"; e["⽔"] = "水"; e["⽕"] = "火"; e["⽖"] = "爪"; e["⽗"] = "父"; e["⽘"] = "爻"; e["⽙"] = "爿"; e["⽚"] = "片"; e["⽛"] = "牙"; e["⽜"] = "牛"; e["⽝"] = "犬"; e["⽞"] = "玄"; e["⽟"] = "玉"; e["⽠"] = "瓜"; e["⽡"] = "瓦"; e["⽢"] = "甘"; e["⽣"] = "生"; e["⽤"] = "用"; e["⽥"] = "田"; e["⽦"] = "疋"; e["⽧"] = "疒"; e["⽨"] = "癶"; e["⽩"] = "白"; e["⽪"] = "皮"; e["⽫"] = "皿"; e["⽬"] = "目"; e["⽭"] = "矛"; e["⽮"] = "矢"; e["⽯"] = "石"; e["⽰"] = "示"; e["⽱"] = "禸"; e["⽲"] = "禾"; e["⽳"] = "穴"; e["⽴"] = "立"; e["⽵"] = "竹"; e["⽶"] = "米"; e["⽷"] = "糸"; e["⽸"] = "缶"; e["⽹"] = "网"; e["⽺"] = "羊"; e["⽻"] = "羽"; e["⽼"] = "老"; e["⽽"] = "而"; e["⽾"] = "耒"; e["⽿"] = "耳"; e["⾀"] = "聿"; e["⾁"] = "肉"; e["⾂"] = "臣"; e["⾃"] = "自"; e["⾄"] = "至"; e["⾅"] = "臼"; e["⾆"] = "舌"; e["⾇"] = "舛"; e["⾈"] = "舟"; e["⾉"] = "艮"; e["⾊"] = "色"; e["⾋"] = "艸"; e["⾌"] = "虍"; e["⾍"] = "虫"; e["⾎"] = "血"; e["⾏"] = "行"; e["⾐"] = "衣"; e["⾑"] = "襾"; e["⾒"] = "見"; e["⾓"] = "角"; e["⾔"] = "言"; e["⾕"] = "谷"; e["⾖"] = "豆"; e["⾗"] = "豕"; e["⾘"] = "豸"; e["⾙"] = "貝"; e["⾚"] = "赤"; e["⾛"] = "走"; e["⾜"] = "足"; e["⾝"] = "身"; e["⾞"] = "車"; e["⾟"] = "辛"; e["⾠"] = "辰"; e["⾡"] = "辵"; e["⾢"] = "邑"; e["⾣"] = "酉"; e["⾤"] = "釆"; e["⾥"] = "里"; e["⾦"] = "金"; e["⾧"] = "長"; e["⾨"] = "門"; e["⾩"] = "阜"; e["⾪"] = "隶"; e["⾫"] = "隹"; e["⾬"] = "雨"; e["⾭"] = "靑"; e["⾮"] = "非"; e["⾯"] = "面"; e["⾰"] = "革"; e["⾱"] = "韋"; e["⾲"] = "韭"; e["⾳"] = "音"; e["⾴"] = "頁"; e["⾵"] = "風"; e["⾶"] = "飛"; e["⾷"] = "食"; e["⾸"] = "首"; e["⾹"] = "香"; e["⾺"] = "馬"; e["⾻"] = "骨"; e["⾼"] = "高"; e["⾽"] = "髟"; e["⾾"] = "鬥"; e["⾿"] = "鬯"; e["⿀"] = "鬲"; e["⿁"] = "鬼"; e["⿂"] = "魚"; e["⿃"] = "鳥"; e["⿄"] = "鹵"; e["⿅"] = "鹿"; e["⿆"] = "麥"; e["⿇"] = "麻"; e["⿈"] = "黃"; e["⿉"] = "黍"; e["⿊"] = "黑"; e["⿋"] = "黹"; e["⿌"] = "黽"; e["⿍"] = "鼎"; e["⿎"] = "鼓"; e["⿏"] = "鼠"; e["⿐"] = "鼻"; e["⿑"] = "齊"; e["⿒"] = "齒"; e["⿓"] = "龍"; e["⿔"] = "龜"; e["⿕"] = "龠"; e["〶"] = "〒"; e["〸"] = "十"; e["〹"] = "卄"; e["〺"] = "卅"; e["゛"] = " ゙"; e["゜"] = " ゚"; e["ㄱ"] = "ᄀ"; e["ㄲ"] = "ᄁ"; e["ㄳ"] = "ᆪ"; e["ㄴ"] = "ᄂ"; e["ㄵ"] = "ᆬ"; e["ㄶ"] = "ᆭ"; e["ㄷ"] = "ᄃ"; e["ㄸ"] = "ᄄ"; e["ㄹ"] = "ᄅ"; e["ㄺ"] = "ᆰ"; e["ㄻ"] = "ᆱ"; e["ㄼ"] = "ᆲ"; e["ㄽ"] = "ᆳ"; e["ㄾ"] = "ᆴ"; e["ㄿ"] = "ᆵ"; e["ㅀ"] = "ᄚ"; e["ㅁ"] = "ᄆ"; e["ㅂ"] = "ᄇ"; e["ㅃ"] = "ᄈ"; e["ㅄ"] = "ᄡ"; e["ㅅ"] = "ᄉ"; e["ㅆ"] = "ᄊ"; e["ㅇ"] = "ᄋ"; e["ㅈ"] = "ᄌ"; e["ㅉ"] = "ᄍ"; e["ㅊ"] = "ᄎ"; e["ㅋ"] = "ᄏ"; e["ㅌ"] = "ᄐ"; e["ㅍ"] = "ᄑ"; e["ㅎ"] = "ᄒ"; e["ㅏ"] = "ᅡ"; e["ㅐ"] = "ᅢ"; e["ㅑ"] = "ᅣ"; e["ㅒ"] = "ᅤ"; e["ㅓ"] = "ᅥ"; e["ㅔ"] = "ᅦ"; e["ㅕ"] = "ᅧ"; e["ㅖ"] = "ᅨ"; e["ㅗ"] = "ᅩ"; e["ㅘ"] = "ᅪ"; e["ㅙ"] = "ᅫ"; e["ㅚ"] = "ᅬ"; e["ㅛ"] = "ᅭ"; e["ㅜ"] = "ᅮ"; e["ㅝ"] = "ᅯ"; e["ㅞ"] = "ᅰ"; e["ㅟ"] = "ᅱ"; e["ㅠ"] = "ᅲ"; e["ㅡ"] = "ᅳ"; e["ㅢ"] = "ᅴ"; e["ㅣ"] = "ᅵ"; e["ㅤ"] = "ᅠ"; e["ㅥ"] = "ᄔ"; e["ㅦ"] = "ᄕ"; e["ㅧ"] = "ᇇ"; e["ㅨ"] = "ᇈ"; e["ㅩ"] = "ᇌ"; e["ㅪ"] = "ᇎ"; e["ㅫ"] = "ᇓ"; e["ㅬ"] = "ᇗ"; e["ㅭ"] = "ᇙ"; e["ㅮ"] = "ᄜ"; e["ㅯ"] = "ᇝ"; e["ㅰ"] = "ᇟ"; e["ㅱ"] = "ᄝ"; e["ㅲ"] = "ᄞ"; e["ㅳ"] = "ᄠ"; e["ㅴ"] = "ᄢ"; e["ㅵ"] = "ᄣ"; e["ㅶ"] = "ᄧ"; e["ㅷ"] = "ᄩ"; e["ㅸ"] = "ᄫ"; e["ㅹ"] = "ᄬ"; e["ㅺ"] = "ᄭ"; e["ㅻ"] = "ᄮ"; e["ㅼ"] = "ᄯ"; e["ㅽ"] = "ᄲ"; e["ㅾ"] = "ᄶ"; e["ㅿ"] = "ᅀ"; e["ㆀ"] = "ᅇ"; e["ㆁ"] = "ᅌ"; e["ㆂ"] = "ᇱ"; e["ㆃ"] = "ᇲ"; e["ㆄ"] = "ᅗ"; e["ㆅ"] = "ᅘ"; e["ㆆ"] = "ᅙ"; e["ㆇ"] = "ᆄ"; e["ㆈ"] = "ᆅ"; e["ㆉ"] = "ᆈ"; e["ㆊ"] = "ᆑ"; e["ㆋ"] = "ᆒ"; e["ㆌ"] = "ᆔ"; e["ㆍ"] = "ᆞ"; e["ㆎ"] = "ᆡ"; e["㈀"] = "(ᄀ)"; e["㈁"] = "(ᄂ)"; e["㈂"] = "(ᄃ)"; e["㈃"] = "(ᄅ)"; e["㈄"] = "(ᄆ)"; e["㈅"] = "(ᄇ)"; e["㈆"] = "(ᄉ)"; e["㈇"] = "(ᄋ)"; e["㈈"] = "(ᄌ)"; e["㈉"] = "(ᄎ)"; e["㈊"] = "(ᄏ)"; e["㈋"] = "(ᄐ)"; e["㈌"] = "(ᄑ)"; e["㈍"] = "(ᄒ)"; e["㈎"] = "(가)"; e["㈏"] = "(나)"; e["㈐"] = "(다)"; e["㈑"] = "(라)"; e["㈒"] = "(마)"; e["㈓"] = "(바)"; e["㈔"] = "(사)"; e["㈕"] = "(아)"; e["㈖"] = "(자)"; e["㈗"] = "(차)"; e["㈘"] = "(카)"; e["㈙"] = "(타)"; e["㈚"] = "(파)"; e["㈛"] = "(하)"; e["㈜"] = "(주)"; e["㈝"] = "(오전)"; e["㈞"] = "(오후)"; e["㈠"] = "(一)"; e["㈡"] = "(二)"; e["㈢"] = "(三)"; e["㈣"] = "(四)"; e["㈤"] = "(五)"; e["㈥"] = "(六)"; e["㈦"] = "(七)"; e["㈧"] = "(八)"; e["㈨"] = "(九)"; e["㈩"] = "(十)"; e["㈪"] = "(月)"; e["㈫"] = "(火)"; e["㈬"] = "(水)"; e["㈭"] = "(木)"; e["㈮"] = "(金)"; e["㈯"] = "(土)"; e["㈰"] = "(日)"; e["㈱"] = "(株)"; e["㈲"] = "(有)"; e["㈳"] = "(社)"; e["㈴"] = "(名)"; e["㈵"] = "(特)"; e["㈶"] = "(財)"; e["㈷"] = "(祝)"; e["㈸"] = "(労)"; e["㈹"] = "(代)"; e["㈺"] = "(呼)"; e["㈻"] = "(学)"; e["㈼"] = "(監)"; e["㈽"] = "(企)"; e["㈾"] = "(資)"; e["㈿"] = "(協)"; e["㉀"] = "(祭)"; e["㉁"] = "(休)"; e["㉂"] = "(自)"; e["㉃"] = "(至)"; e["㋀"] = "1月"; e["㋁"] = "2月"; e["㋂"] = "3月"; e["㋃"] = "4月"; e["㋄"] = "5月"; e["㋅"] = "6月"; e["㋆"] = "7月"; e["㋇"] = "8月"; e["㋈"] = "9月"; e["㋉"] = "10月"; e["㋊"] = "11月"; e["㋋"] = "12月"; e["㍘"] = "0点"; e["㍙"] = "1点"; e["㍚"] = "2点"; e["㍛"] = "3点"; e["㍜"] = "4点"; e["㍝"] = "5点"; e["㍞"] = "6点"; e["㍟"] = "7点"; e["㍠"] = "8点"; e["㍡"] = "9点"; e["㍢"] = "10点"; e["㍣"] = "11点"; e["㍤"] = "12点"; e["㍥"] = "13点"; e["㍦"] = "14点"; e["㍧"] = "15点"; e["㍨"] = "16点"; e["㍩"] = "17点"; e["㍪"] = "18点"; e["㍫"] = "19点"; e["㍬"] = "20点"; e["㍭"] = "21点"; e["㍮"] = "22点"; e["㍯"] = "23点"; e["㍰"] = "24点"; e["㏠"] = "1日"; e["㏡"] = "2日"; e["㏢"] = "3日"; e["㏣"] = "4日"; e["㏤"] = "5日"; e["㏥"] = "6日"; e["㏦"] = "7日"; e["㏧"] = "8日"; e["㏨"] = "9日"; e["㏩"] = "10日"; e["㏪"] = "11日"; e["㏫"] = "12日"; e["㏬"] = "13日"; e["㏭"] = "14日"; e["㏮"] = "15日"; e["㏯"] = "16日"; e["㏰"] = "17日"; e["㏱"] = "18日"; e["㏲"] = "19日"; e["㏳"] = "20日"; e["㏴"] = "21日"; e["㏵"] = "22日"; e["㏶"] = "23日"; e["㏷"] = "24日"; e["㏸"] = "25日"; e["㏹"] = "26日"; e["㏺"] = "27日"; e["㏻"] = "28日"; e["㏼"] = "29日"; e["㏽"] = "30日"; e["㏾"] = "31日"; e["ff"] = "ff"; e["fi"] = "fi"; e["fl"] = "fl"; e["ffi"] = "ffi"; e["ffl"] = "ffl"; e["ſt"] = "ſt"; e["st"] = "st"; e["ﬓ"] = "մն"; e["ﬔ"] = "մե"; e["ﬕ"] = "մի"; e["ﬖ"] = "վն"; e["ﬗ"] = "մխ"; e["ﭏ"] = "אל"; e["ﭐ"] = "ٱ"; e["ﭑ"] = "ٱ"; e["ﭒ"] = "ٻ"; e["ﭓ"] = "ٻ"; e["ﭔ"] = "ٻ"; e["ﭕ"] = "ٻ"; e["ﭖ"] = "پ"; e["ﭗ"] = "پ"; e["ﭘ"] = "پ"; e["ﭙ"] = "پ"; e["ﭚ"] = "ڀ"; e["ﭛ"] = "ڀ"; e["ﭜ"] = "ڀ"; e["ﭝ"] = "ڀ"; e["ﭞ"] = "ٺ"; e["ﭟ"] = "ٺ"; e["ﭠ"] = "ٺ"; e["ﭡ"] = "ٺ"; e["ﭢ"] = "ٿ"; e["ﭣ"] = "ٿ"; e["ﭤ"] = "ٿ"; e["ﭥ"] = "ٿ"; e["ﭦ"] = "ٹ"; e["ﭧ"] = "ٹ"; e["ﭨ"] = "ٹ"; e["ﭩ"] = "ٹ"; e["ﭪ"] = "ڤ"; e["ﭫ"] = "ڤ"; e["ﭬ"] = "ڤ"; e["ﭭ"] = "ڤ"; e["ﭮ"] = "ڦ"; e["ﭯ"] = "ڦ"; e["ﭰ"] = "ڦ"; e["ﭱ"] = "ڦ"; e["ﭲ"] = "ڄ"; e["ﭳ"] = "ڄ"; e["ﭴ"] = "ڄ"; e["ﭵ"] = "ڄ"; e["ﭶ"] = "ڃ"; e["ﭷ"] = "ڃ"; e["ﭸ"] = "ڃ"; e["ﭹ"] = "ڃ"; e["ﭺ"] = "چ"; e["ﭻ"] = "چ"; e["ﭼ"] = "چ"; e["ﭽ"] = "چ"; e["ﭾ"] = "ڇ"; e["ﭿ"] = "ڇ"; e["ﮀ"] = "ڇ"; e["ﮁ"] = "ڇ"; e["ﮂ"] = "ڍ"; e["ﮃ"] = "ڍ"; e["ﮄ"] = "ڌ"; e["ﮅ"] = "ڌ"; e["ﮆ"] = "ڎ"; e["ﮇ"] = "ڎ"; e["ﮈ"] = "ڈ"; e["ﮉ"] = "ڈ"; e["ﮊ"] = "ژ"; e["ﮋ"] = "ژ"; e["ﮌ"] = "ڑ"; e["ﮍ"] = "ڑ"; e["ﮎ"] = "ک"; e["ﮏ"] = "ک"; e["ﮐ"] = "ک"; e["ﮑ"] = "ک"; e["ﮒ"] = "گ"; e["ﮓ"] = "گ"; e["ﮔ"] = "گ"; e["ﮕ"] = "گ"; e["ﮖ"] = "ڳ"; e["ﮗ"] = "ڳ"; e["ﮘ"] = "ڳ"; e["ﮙ"] = "ڳ"; e["ﮚ"] = "ڱ"; e["ﮛ"] = "ڱ"; e["ﮜ"] = "ڱ"; e["ﮝ"] = "ڱ"; e["ﮞ"] = "ں"; e["ﮟ"] = "ں"; e["ﮠ"] = "ڻ"; e["ﮡ"] = "ڻ"; e["ﮢ"] = "ڻ"; e["ﮣ"] = "ڻ"; e["ﮤ"] = "ۀ"; e["ﮥ"] = "ۀ"; e["ﮦ"] = "ہ"; e["ﮧ"] = "ہ"; e["ﮨ"] = "ہ"; e["ﮩ"] = "ہ"; e["ﮪ"] = "ھ"; e["ﮫ"] = "ھ"; e["ﮬ"] = "ھ"; e["ﮭ"] = "ھ"; e["ﮮ"] = "ے"; e["ﮯ"] = "ے"; e["ﮰ"] = "ۓ"; e["ﮱ"] = "ۓ"; e["ﯓ"] = "ڭ"; e["ﯔ"] = "ڭ"; e["ﯕ"] = "ڭ"; e["ﯖ"] = "ڭ"; e["ﯗ"] = "ۇ"; e["ﯘ"] = "ۇ"; e["ﯙ"] = "ۆ"; e["ﯚ"] = "ۆ"; e["ﯛ"] = "ۈ"; e["ﯜ"] = "ۈ"; e["ﯝ"] = "ٷ"; e["ﯞ"] = "ۋ"; e["ﯟ"] = "ۋ"; e["ﯠ"] = "ۅ"; e["ﯡ"] = "ۅ"; e["ﯢ"] = "ۉ"; e["ﯣ"] = "ۉ"; e["ﯤ"] = "ې"; e["ﯥ"] = "ې"; e["ﯦ"] = "ې"; e["ﯧ"] = "ې"; e["ﯨ"] = "ى"; e["ﯩ"] = "ى"; e["ﯪ"] = "ئا"; e["ﯫ"] = "ئا"; e["ﯬ"] = "ئە"; e["ﯭ"] = "ئە"; e["ﯮ"] = "ئو"; e["ﯯ"] = "ئو"; e["ﯰ"] = "ئۇ"; e["ﯱ"] = "ئۇ"; e["ﯲ"] = "ئۆ"; e["ﯳ"] = "ئۆ"; e["ﯴ"] = "ئۈ"; e["ﯵ"] = "ئۈ"; e["ﯶ"] = "ئې"; e["ﯷ"] = "ئې"; e["ﯸ"] = "ئې"; e["ﯹ"] = "ئى"; e["ﯺ"] = "ئى"; e["ﯻ"] = "ئى"; e["ﯼ"] = "ی"; e["ﯽ"] = "ی"; e["ﯾ"] = "ی"; e["ﯿ"] = "ی"; e["ﰀ"] = "ئج"; e["ﰁ"] = "ئح"; e["ﰂ"] = "ئم"; e["ﰃ"] = "ئى"; e["ﰄ"] = "ئي"; e["ﰅ"] = "بج"; e["ﰆ"] = "بح"; e["ﰇ"] = "بخ"; e["ﰈ"] = "بم"; e["ﰉ"] = "بى"; e["ﰊ"] = "بي"; e["ﰋ"] = "تج"; e["ﰌ"] = "تح"; e["ﰍ"] = "تخ"; e["ﰎ"] = "تم"; e["ﰏ"] = "تى"; e["ﰐ"] = "تي"; e["ﰑ"] = "ثج"; e["ﰒ"] = "ثم"; e["ﰓ"] = "ثى"; e["ﰔ"] = "ثي"; e["ﰕ"] = "جح"; e["ﰖ"] = "جم"; e["ﰗ"] = "حج"; e["ﰘ"] = "حم"; e["ﰙ"] = "خج"; e["ﰚ"] = "خح"; e["ﰛ"] = "خم"; e["ﰜ"] = "سج"; e["ﰝ"] = "سح"; e["ﰞ"] = "سخ"; e["ﰟ"] = "سم"; e["ﰠ"] = "صح"; e["ﰡ"] = "صم"; e["ﰢ"] = "ضج"; e["ﰣ"] = "ضح"; e["ﰤ"] = "ضخ"; e["ﰥ"] = "ضم"; e["ﰦ"] = "طح"; e["ﰧ"] = "طم"; e["ﰨ"] = "ظم"; e["ﰩ"] = "عج"; e["ﰪ"] = "عم"; e["ﰫ"] = "غج"; e["ﰬ"] = "غم"; e["ﰭ"] = "فج"; e["ﰮ"] = "فح"; e["ﰯ"] = "فخ"; e["ﰰ"] = "فم"; e["ﰱ"] = "فى"; e["ﰲ"] = "في"; e["ﰳ"] = "قح"; e["ﰴ"] = "قم"; e["ﰵ"] = "قى"; e["ﰶ"] = "قي"; e["ﰷ"] = "كا"; e["ﰸ"] = "كج"; e["ﰹ"] = "كح"; e["ﰺ"] = "كخ"; e["ﰻ"] = "كل"; e["ﰼ"] = "كم"; e["ﰽ"] = "كى"; e["ﰾ"] = "كي"; e["ﰿ"] = "لج"; e["ﱀ"] = "لح"; e["ﱁ"] = "لخ"; e["ﱂ"] = "لم"; e["ﱃ"] = "لى"; e["ﱄ"] = "لي"; e["ﱅ"] = "مج"; e["ﱆ"] = "مح"; e["ﱇ"] = "مخ"; e["ﱈ"] = "مم"; e["ﱉ"] = "مى"; e["ﱊ"] = "مي"; e["ﱋ"] = "نج"; e["ﱌ"] = "نح"; e["ﱍ"] = "نخ"; e["ﱎ"] = "نم"; e["ﱏ"] = "نى"; e["ﱐ"] = "ني"; e["ﱑ"] = "هج"; e["ﱒ"] = "هم"; e["ﱓ"] = "هى"; e["ﱔ"] = "هي"; e["ﱕ"] = "يج"; e["ﱖ"] = "يح"; e["ﱗ"] = "يخ"; e["ﱘ"] = "يم"; e["ﱙ"] = "يى"; e["ﱚ"] = "يي"; e["ﱛ"] = "ذٰ"; e["ﱜ"] = "رٰ"; e["ﱝ"] = "ىٰ"; e["ﱞ"] = " ٌّ"; e["ﱟ"] = " ٍّ"; e["ﱠ"] = " َّ"; e["ﱡ"] = " ُّ"; e["ﱢ"] = " ِّ"; e["ﱣ"] = " ّٰ"; e["ﱤ"] = "ئر"; e["ﱥ"] = "ئز"; e["ﱦ"] = "ئم"; e["ﱧ"] = "ئن"; e["ﱨ"] = "ئى"; e["ﱩ"] = "ئي"; e["ﱪ"] = "بر"; e["ﱫ"] = "بز"; e["ﱬ"] = "بم"; e["ﱭ"] = "بن"; e["ﱮ"] = "بى"; e["ﱯ"] = "بي"; e["ﱰ"] = "تر"; e["ﱱ"] = "تز"; e["ﱲ"] = "تم"; e["ﱳ"] = "تن"; e["ﱴ"] = "تى"; e["ﱵ"] = "تي"; e["ﱶ"] = "ثر"; e["ﱷ"] = "ثز"; e["ﱸ"] = "ثم"; e["ﱹ"] = "ثن"; e["ﱺ"] = "ثى"; e["ﱻ"] = "ثي"; e["ﱼ"] = "فى"; e["ﱽ"] = "في"; e["ﱾ"] = "قى"; e["ﱿ"] = "قي"; e["ﲀ"] = "كا"; e["ﲁ"] = "كل"; e["ﲂ"] = "كم"; e["ﲃ"] = "كى"; e["ﲄ"] = "كي"; e["ﲅ"] = "لم"; e["ﲆ"] = "لى"; e["ﲇ"] = "لي"; e["ﲈ"] = "ما"; e["ﲉ"] = "مم"; e["ﲊ"] = "نر"; e["ﲋ"] = "نز"; e["ﲌ"] = "نم"; e["ﲍ"] = "نن"; e["ﲎ"] = "نى"; e["ﲏ"] = "ني"; e["ﲐ"] = "ىٰ"; e["ﲑ"] = "ير"; e["ﲒ"] = "يز"; e["ﲓ"] = "يم"; e["ﲔ"] = "ين"; e["ﲕ"] = "يى"; e["ﲖ"] = "يي"; e["ﲗ"] = "ئج"; e["ﲘ"] = "ئح"; e["ﲙ"] = "ئخ"; e["ﲚ"] = "ئم"; e["ﲛ"] = "ئه"; e["ﲜ"] = "بج"; e["ﲝ"] = "بح"; e["ﲞ"] = "بخ"; e["ﲟ"] = "بم"; e["ﲠ"] = "به"; e["ﲡ"] = "تج"; e["ﲢ"] = "تح"; e["ﲣ"] = "تخ"; e["ﲤ"] = "تم"; e["ﲥ"] = "ته"; e["ﲦ"] = "ثم"; e["ﲧ"] = "جح"; e["ﲨ"] = "جم"; e["ﲩ"] = "حج"; e["ﲪ"] = "حم"; e["ﲫ"] = "خج"; e["ﲬ"] = "خم"; e["ﲭ"] = "سج"; e["ﲮ"] = "سح"; e["ﲯ"] = "سخ"; e["ﲰ"] = "سم"; e["ﲱ"] = "صح"; e["ﲲ"] = "صخ"; e["ﲳ"] = "صم"; e["ﲴ"] = "ضج"; e["ﲵ"] = "ضح"; e["ﲶ"] = "ضخ"; e["ﲷ"] = "ضم"; e["ﲸ"] = "طح"; e["ﲹ"] = "ظم"; e["ﲺ"] = "عج"; e["ﲻ"] = "عم"; e["ﲼ"] = "غج"; e["ﲽ"] = "غم"; e["ﲾ"] = "فج"; e["ﲿ"] = "فح"; e["ﳀ"] = "فخ"; e["ﳁ"] = "فم"; e["ﳂ"] = "قح"; e["ﳃ"] = "قم"; e["ﳄ"] = "كج"; e["ﳅ"] = "كح"; e["ﳆ"] = "كخ"; e["ﳇ"] = "كل"; e["ﳈ"] = "كم"; e["ﳉ"] = "لج"; e["ﳊ"] = "لح"; e["ﳋ"] = "لخ"; e["ﳌ"] = "لم"; e["ﳍ"] = "له"; e["ﳎ"] = "مج"; e["ﳏ"] = "مح"; e["ﳐ"] = "مخ"; e["ﳑ"] = "مم"; e["ﳒ"] = "نج"; e["ﳓ"] = "نح"; e["ﳔ"] = "نخ"; e["ﳕ"] = "نم"; e["ﳖ"] = "نه"; e["ﳗ"] = "هج"; e["ﳘ"] = "هم"; e["ﳙ"] = "هٰ"; e["ﳚ"] = "يج"; e["ﳛ"] = "يح"; e["ﳜ"] = "يخ"; e["ﳝ"] = "يم"; e["ﳞ"] = "يه"; e["ﳟ"] = "ئم"; e["ﳠ"] = "ئه"; e["ﳡ"] = "بم"; e["ﳢ"] = "به"; e["ﳣ"] = "تم"; e["ﳤ"] = "ته"; e["ﳥ"] = "ثم"; e["ﳦ"] = "ثه"; e["ﳧ"] = "سم"; e["ﳨ"] = "سه"; e["ﳩ"] = "شم"; e["ﳪ"] = "شه"; e["ﳫ"] = "كل"; e["ﳬ"] = "كم"; e["ﳭ"] = "لم"; e["ﳮ"] = "نم"; e["ﳯ"] = "نه"; e["ﳰ"] = "يم"; e["ﳱ"] = "يه"; e["ﳲ"] = "ـَّ"; e["ﳳ"] = "ـُّ"; e["ﳴ"] = "ـِّ"; e["ﳵ"] = "طى"; e["ﳶ"] = "طي"; e["ﳷ"] = "عى"; e["ﳸ"] = "عي"; e["ﳹ"] = "غى"; e["ﳺ"] = "غي"; e["ﳻ"] = "سى"; e["ﳼ"] = "سي"; e["ﳽ"] = "شى"; e["ﳾ"] = "شي"; e["ﳿ"] = "حى"; e["ﴀ"] = "حي"; e["ﴁ"] = "جى"; e["ﴂ"] = "جي"; e["ﴃ"] = "خى"; e["ﴄ"] = "خي"; e["ﴅ"] = "صى"; e["ﴆ"] = "صي"; e["ﴇ"] = "ضى"; e["ﴈ"] = "ضي"; e["ﴉ"] = "شج"; e["ﴊ"] = "شح"; e["ﴋ"] = "شخ"; e["ﴌ"] = "شم"; e["ﴍ"] = "شر"; e["ﴎ"] = "سر"; e["ﴏ"] = "صر"; e["ﴐ"] = "ضر"; e["ﴑ"] = "طى"; e["ﴒ"] = "طي"; e["ﴓ"] = "عى"; e["ﴔ"] = "عي"; e["ﴕ"] = "غى"; e["ﴖ"] = "غي"; e["ﴗ"] = "سى"; e["ﴘ"] = "سي"; e["ﴙ"] = "شى"; e["ﴚ"] = "شي"; e["ﴛ"] = "حى"; e["ﴜ"] = "حي"; e["ﴝ"] = "جى"; e["ﴞ"] = "جي"; e["ﴟ"] = "خى"; e["ﴠ"] = "خي"; e["ﴡ"] = "صى"; e["ﴢ"] = "صي"; e["ﴣ"] = "ضى"; e["ﴤ"] = "ضي"; e["ﴥ"] = "شج"; e["ﴦ"] = "شح"; e["ﴧ"] = "شخ"; e["ﴨ"] = "شم"; e["ﴩ"] = "شر"; e["ﴪ"] = "سر"; e["ﴫ"] = "صر"; e["ﴬ"] = "ضر"; e["ﴭ"] = "شج"; e["ﴮ"] = "شح"; e["ﴯ"] = "شخ"; e["ﴰ"] = "شم"; e["ﴱ"] = "سه"; e["ﴲ"] = "شه"; e["ﴳ"] = "طم"; e["ﴴ"] = "سج"; e["ﴵ"] = "سح"; e["ﴶ"] = "سخ"; e["ﴷ"] = "شج"; e["ﴸ"] = "شح"; e["ﴹ"] = "شخ"; e["ﴺ"] = "طم"; e["ﴻ"] = "ظم"; e["ﴼ"] = "اً"; e["ﴽ"] = "اً"; e["ﵐ"] = "تجم"; e["ﵑ"] = "تحج"; e["ﵒ"] = "تحج"; e["ﵓ"] = "تحم"; e["ﵔ"] = "تخم"; e["ﵕ"] = "تمج"; e["ﵖ"] = "تمح"; e["ﵗ"] = "تمخ"; e["ﵘ"] = "جمح"; e["ﵙ"] = "جمح"; e["ﵚ"] = "حمي"; e["ﵛ"] = "حمى"; e["ﵜ"] = "سحج"; e["ﵝ"] = "سجح"; e["ﵞ"] = "سجى"; e["ﵟ"] = "سمح"; e["ﵠ"] = "سمح"; e["ﵡ"] = "سمج"; e["ﵢ"] = "سمم"; e["ﵣ"] = "سمم"; e["ﵤ"] = "صحح"; e["ﵥ"] = "صحح"; e["ﵦ"] = "صمم"; e["ﵧ"] = "شحم"; e["ﵨ"] = "شحم"; e["ﵩ"] = "شجي"; e["ﵪ"] = "شمخ"; e["ﵫ"] = "شمخ"; e["ﵬ"] = "شمم"; e["ﵭ"] = "شمم"; e["ﵮ"] = "ضحى"; e["ﵯ"] = "ضخم"; e["ﵰ"] = "ضخم"; e["ﵱ"] = "طمح"; e["ﵲ"] = "طمح"; e["ﵳ"] = "طمم"; e["ﵴ"] = "طمي"; e["ﵵ"] = "عجم"; e["ﵶ"] = "عمم"; e["ﵷ"] = "عمم"; e["ﵸ"] = "عمى"; e["ﵹ"] = "غمم"; e["ﵺ"] = "غمي"; e["ﵻ"] = "غمى"; e["ﵼ"] = "فخم"; e["ﵽ"] = "فخم"; e["ﵾ"] = "قمح"; e["ﵿ"] = "قمم"; e["ﶀ"] = "لحم"; e["ﶁ"] = "لحي"; e["ﶂ"] = "لحى"; e["ﶃ"] = "لجج"; e["ﶄ"] = "لجج"; e["ﶅ"] = "لخم"; e["ﶆ"] = "لخم"; e["ﶇ"] = "لمح"; e["ﶈ"] = "لمح"; e["ﶉ"] = "محج"; e["ﶊ"] = "محم"; e["ﶋ"] = "محي"; e["ﶌ"] = "مجح"; e["ﶍ"] = "مجم"; e["ﶎ"] = "مخج"; e["ﶏ"] = "مخم"; e["ﶒ"] = "مجخ"; e["ﶓ"] = "همج"; e["ﶔ"] = "همم"; e["ﶕ"] = "نحم"; e["ﶖ"] = "نحى"; e["ﶗ"] = "نجم"; e["ﶘ"] = "نجم"; e["ﶙ"] = "نجى"; e["ﶚ"] = "نمي"; e["ﶛ"] = "نمى"; e["ﶜ"] = "يمم"; e["ﶝ"] = "يمم"; e["ﶞ"] = "بخي"; e["ﶟ"] = "تجي"; e["ﶠ"] = "تجى"; e["ﶡ"] = "تخي"; e["ﶢ"] = "تخى"; e["ﶣ"] = "تمي"; e["ﶤ"] = "تمى"; e["ﶥ"] = "جمي"; e["ﶦ"] = "جحى"; e["ﶧ"] = "جمى"; e["ﶨ"] = "سخى"; e["ﶩ"] = "صحي"; e["ﶪ"] = "شحي"; e["ﶫ"] = "ضحي"; e["ﶬ"] = "لجي"; e["ﶭ"] = "لمي"; e["ﶮ"] = "يحي"; e["ﶯ"] = "يجي"; e["ﶰ"] = "يمي"; e["ﶱ"] = "ممي"; e["ﶲ"] = "قمي"; e["ﶳ"] = "نحي"; e["ﶴ"] = "قمح"; e["ﶵ"] = "لحم"; e["ﶶ"] = "عمي"; e["ﶷ"] = "كمي"; e["ﶸ"] = "نجح"; e["ﶹ"] = "مخي"; e["ﶺ"] = "لجم"; e["ﶻ"] = "كمم"; e["ﶼ"] = "لجم"; e["ﶽ"] = "نجح"; e["ﶾ"] = "جحي"; e["ﶿ"] = "حجي"; e["ﷀ"] = "مجي"; e["ﷁ"] = "فمي"; e["ﷂ"] = "بحي"; e["ﷃ"] = "كمم"; e["ﷄ"] = "عجم"; e["ﷅ"] = "صمم"; e["ﷆ"] = "سخي"; e["ﷇ"] = "نجي"; e["﹉"] = "‾"; e["﹊"] = "‾"; e["﹋"] = "‾"; e["﹌"] = "‾"; e["﹍"] = "_"; e["﹎"] = "_"; e["﹏"] = "_"; e["ﺀ"] = "ء"; e["ﺁ"] = "آ"; e["ﺂ"] = "آ"; e["ﺃ"] = "أ"; e["ﺄ"] = "أ"; e["ﺅ"] = "ؤ"; e["ﺆ"] = "ؤ"; e["ﺇ"] = "إ"; e["ﺈ"] = "إ"; e["ﺉ"] = "ئ"; e["ﺊ"] = "ئ"; e["ﺋ"] = "ئ"; e["ﺌ"] = "ئ"; e["ﺍ"] = "ا"; e["ﺎ"] = "ا"; e["ﺏ"] = "ب"; e["ﺐ"] = "ب"; e["ﺑ"] = "ب"; e["ﺒ"] = "ب"; e["ﺓ"] = "ة"; e["ﺔ"] = "ة"; e["ﺕ"] = "ت"; e["ﺖ"] = "ت"; e["ﺗ"] = "ت"; e["ﺘ"] = "ت"; e["ﺙ"] = "ث"; e["ﺚ"] = "ث"; e["ﺛ"] = "ث"; e["ﺜ"] = "ث"; e["ﺝ"] = "ج"; e["ﺞ"] = "ج"; e["ﺟ"] = "ج"; e["ﺠ"] = "ج"; e["ﺡ"] = "ح"; e["ﺢ"] = "ح"; e["ﺣ"] = "ح"; e["ﺤ"] = "ح"; e["ﺥ"] = "خ"; e["ﺦ"] = "خ"; e["ﺧ"] = "خ"; e["ﺨ"] = "خ"; e["ﺩ"] = "د"; e["ﺪ"] = "د"; e["ﺫ"] = "ذ"; e["ﺬ"] = "ذ"; e["ﺭ"] = "ر"; e["ﺮ"] = "ر"; e["ﺯ"] = "ز"; e["ﺰ"] = "ز"; e["ﺱ"] = "س"; e["ﺲ"] = "س"; e["ﺳ"] = "س"; e["ﺴ"] = "س"; e["ﺵ"] = "ش"; e["ﺶ"] = "ش"; e["ﺷ"] = "ش"; e["ﺸ"] = "ش"; e["ﺹ"] = "ص"; e["ﺺ"] = "ص"; e["ﺻ"] = "ص"; e["ﺼ"] = "ص"; e["ﺽ"] = "ض"; e["ﺾ"] = "ض"; e["ﺿ"] = "ض"; e["ﻀ"] = "ض"; e["ﻁ"] = "ط"; e["ﻂ"] = "ط"; e["ﻃ"] = "ط"; e["ﻄ"] = "ط"; e["ﻅ"] = "ظ"; e["ﻆ"] = "ظ"; e["ﻇ"] = "ظ"; e["ﻈ"] = "ظ"; e["ﻉ"] = "ع"; e["ﻊ"] = "ع"; e["ﻋ"] = "ع"; e["ﻌ"] = "ع"; e["ﻍ"] = "غ"; e["ﻎ"] = "غ"; e["ﻏ"] = "غ"; e["ﻐ"] = "غ"; e["ﻑ"] = "ف"; e["ﻒ"] = "ف"; e["ﻓ"] = "ف"; e["ﻔ"] = "ف"; e["ﻕ"] = "ق"; e["ﻖ"] = "ق"; e["ﻗ"] = "ق"; e["ﻘ"] = "ق"; e["ﻙ"] = "ك"; e["ﻚ"] = "ك"; e["ﻛ"] = "ك"; e["ﻜ"] = "ك"; e["ﻝ"] = "ل"; e["ﻞ"] = "ل"; e["ﻟ"] = "ل"; e["ﻠ"] = "ل"; e["ﻡ"] = "م"; e["ﻢ"] = "م"; e["ﻣ"] = "م"; e["ﻤ"] = "م"; e["ﻥ"] = "ن"; e["ﻦ"] = "ن"; e["ﻧ"] = "ن"; e["ﻨ"] = "ن"; e["ﻩ"] = "ه"; e["ﻪ"] = "ه"; e["ﻫ"] = "ه"; e["ﻬ"] = "ه"; e["ﻭ"] = "و"; e["ﻮ"] = "و"; e["ﻯ"] = "ى"; e["ﻰ"] = "ى"; e["ﻱ"] = "ي"; e["ﻲ"] = "ي"; e["ﻳ"] = "ي"; e["ﻴ"] = "ي"; e["ﻵ"] = "لآ"; e["ﻶ"] = "لآ"; e["ﻷ"] = "لأ"; e["ﻸ"] = "لأ"; e["ﻹ"] = "لإ"; e["ﻺ"] = "لإ"; e["ﻻ"] = "لا"; e["ﻼ"] = "لا" })); t.mapSpecialUnicodeValues = function (e) { return e >= 65520 && e <= 65535 ? 0 : e >= 62976 && e <= 63743 ? i()[e] || e : 173 === e ? 45 : e }; t.reverseIfRtl = function (e) { var t, a, r = e.length; if (r <= 1 || !(t = e.charCodeAt(0), a = n[13], t >= a.begin && t < a.end || t >= (a = n[11]).begin && t < a.end)) return e; for (var i = "", s = r - 1; s >= 0; s--)i += e[s]; return i }; t.getUnicodeRangeFor = function (e) { for (var t = 0, a = n.length; t < a; t++) { var r = n[t]; if (e >= r.begin && e < r.end) return t } return -1 }; t.getNormalizedUnicodes = s; t.getUnicodeForGlyph = function (e, t) { var a = t[e]; if (void 0 !== a) return a; if (!e) return -1; if ("u" === e[0]) { var r, i = e.length; if (7 === i && "n" === e[1] && "i" === e[2]) r = e.substring(3); else { if (!(i >= 5 && i <= 7)) return -1; r = e.substring(1) } if (r === r.toUpperCase() && (a = parseInt(r, 16)) >= 0) return a } return -1 } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.FontRendererFactory = void 0; var r = a(2), i = a(28), n = a(31), s = a(30), o = a(11), c = function () { function e(e, t) { return e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3] } function t(e, t) { return e[t] << 8 | e[t + 1] } function a(e) { const t = e.length; let a = 32768; t < 1240 ? a = 107 : t < 33900 && (a = 1131); return a } function c(a, i, n) { var s, o, c, l = 1 === t(a, i + 2) ? e(a, i + 8) : e(a, i + 16), h = t(a, i + l); if (4 === h) { t(a, i + l + 2); var u = t(a, i + l + 6) >> 1; o = i + l + 14; s = []; for (c = 0; c < u; c++, o += 2)s[c] = { end: t(a, o) }; o += 2; for (c = 0; c < u; c++, o += 2)s[c].start = t(a, o); for (c = 0; c < u; c++, o += 2)s[c].idDelta = t(a, o); for (c = 0; c < u; c++, o += 2) { var d = t(a, o); if (0 !== d) { s[c].ids = []; for (var f = 0, g = s[c].end - s[c].start + 1; f < g; f++) { s[c].ids[f] = t(a, o + d); d += 2 } } } return s } if (12 === h) { e(a, i + l + 4); var m = e(a, i + l + 12); o = i + l + 16; s = []; for (c = 0; c < m; c++) { s.push({ start: e(a, o), end: e(a, o + 4), idDelta: e(a, o + 8) - e(a, o) }); o += 12 } return s } throw new r.FormatError(`unsupported cmap: ${h}`) } function l(e, t, a, r) { var n = new i.CFFParser(new o.Stream(e, t, a - t), {}, r).parse(); return { glyphs: n.charStrings.objects, subrs: n.topDict.privateDict && n.topDict.privateDict.subrsIndex && n.topDict.privateDict.subrsIndex.objects, gsubrs: n.globalSubrIndex && n.globalSubrIndex.objects, isCFFCIDFont: n.isCIDFont, fdSelect: n.fdSelect, fdArray: n.fdArray } } function h(e, t) { for (var a = t.codePointAt(0), r = 0, i = 0, n = e.length - 1; i < n;) { var s = i + n + 1 >> 1; a < e[s].start ? n = s - 1 : i = s } e[i].start <= a && a <= e[i].end && (r = e[i].idDelta + (e[i].ids ? e[i].ids[a - e[i].start] : a) & 65535); return { charCode: a, glyphId: r } } const u = []; class d { constructor(e) { this.constructor === d && (0, r.unreachable)("Cannot initialize CompiledFont."); this.fontMatrix = e; this.compiledGlyphs = Object.create(null); this.compiledCharCodeToGlyphId = Object.create(null) } getPathJs(e) { const t = h(this.cmap, e); let a = this.compiledGlyphs[t.glyphId]; if (!a) { a = this.compileGlyph(this.glyphs[t.glyphId], t.glyphId); this.compiledGlyphs[t.glyphId] = a } void 0 === this.compiledCharCodeToGlyphId[t.charCode] && (this.compiledCharCodeToGlyphId[t.charCode] = t.glyphId); return a } compileGlyph(e, t) { if (!e || 0 === e.length || 14 === e[0]) return u; let a = this.fontMatrix; if (this.isCFFCIDFont) { const e = this.fdSelect.getFDIndex(t); if (e >= 0 && e < this.fdArray.length) { a = this.fdArray[e].getByName("FontMatrix") || r.FONT_IDENTITY_MATRIX } else (0, r.warn)("Invalid fd index for glyph index.") } const i = []; i.push({ cmd: "save" }); i.push({ cmd: "transform", args: a.slice() }); i.push({ cmd: "scale", args: ["size", "-size"] }); this.compileGlyphImpl(e, i, t); i.push({ cmd: "restore" }); return i } compileGlyphImpl() { (0, r.unreachable)("Children classes should implement this.") } hasBuiltPath(e) { const t = h(this.cmap, e); return void 0 !== this.compiledGlyphs[t.glyphId] && void 0 !== this.compiledCharCodeToGlyphId[t.charCode] } } class f extends d { constructor(e, t, a) { super(a || [488e-6, 0, 0, 488e-6, 0, 0]); this.glyphs = e; this.cmap = t } compileGlyphImpl(e, t) { !function e(t, a, r) { function i(e, t) { a.push({ cmd: "moveTo", args: [e, t] }) } function n(e, t) { a.push({ cmd: "lineTo", args: [e, t] }) } function s(e, t, r, i) { a.push({ cmd: "quadraticCurveTo", args: [e, t, r, i] }) } var o, c = 0, l = (t[c] << 24 | t[c + 1] << 16) >> 16, h = 0, u = 0; c += 10; if (l < 0) do { o = t[c] << 8 | t[c + 1]; var d, f, g = t[c + 2] << 8 | t[c + 3]; c += 4; if (1 & o) { d = (t[c] << 24 | t[c + 1] << 16) >> 16; f = (t[c + 2] << 24 | t[c + 3] << 16) >> 16; c += 4 } else { d = t[c++]; f = t[c++] } if (2 & o) { h = d; u = f } else { h = 0; u = 0 } var m = 1, p = 1, b = 0, y = 0; if (8 & o) { m = p = (t[c] << 24 | t[c + 1] << 16) / 1073741824; c += 2 } else if (64 & o) { m = (t[c] << 24 | t[c + 1] << 16) / 1073741824; p = (t[c + 2] << 24 | t[c + 3] << 16) / 1073741824; c += 4 } else if (128 & o) { m = (t[c] << 24 | t[c + 1] << 16) / 1073741824; b = (t[c + 2] << 24 | t[c + 3] << 16) / 1073741824; y = (t[c + 4] << 24 | t[c + 5] << 16) / 1073741824; p = (t[c + 6] << 24 | t[c + 7] << 16) / 1073741824; c += 8 } var v = r.glyphs[g]; if (v) { a.push({ cmd: "save" }); a.push({ cmd: "transform", args: [m, b, y, p, h, u] }); e(v, a, r); a.push({ cmd: "restore" }) } } while (32 & o); else { var w, k, S = []; for (w = 0; w < l; w++) { S.push(t[c] << 8 | t[c + 1]); c += 2 } c += 2 + (t[c] << 8 | t[c + 1]); for (var C = S[S.length - 1] + 1, x = []; x.length < C;) { var A = 1; 8 & (o = t[c++]) && (A += t[c++]); for (; A-- > 0;)x.push({ flags: o }) } for (w = 0; w < C; w++) { switch (18 & x[w].flags) { case 0: h += (t[c] << 24 | t[c + 1] << 16) >> 16; c += 2; break; case 2: h -= t[c++]; break; case 18: h += t[c++] }x[w].x = h } for (w = 0; w < C; w++) { switch (36 & x[w].flags) { case 0: u += (t[c] << 24 | t[c + 1] << 16) >> 16; c += 2; break; case 4: u -= t[c++]; break; case 36: u += t[c++] }x[w].y = u } var I = 0; for (c = 0; c < l; c++) { var F = S[c], T = x.slice(I, F + 1); if (1 & T[0].flags) T.push(T[0]); else if (1 & T[T.length - 1].flags) T.unshift(T[T.length - 1]); else { var E = { flags: 1, x: (T[0].x + T[T.length - 1].x) / 2, y: (T[0].y + T[T.length - 1].y) / 2 }; T.unshift(E); T.push(E) } i(T[0].x, T[0].y); for (w = 1, k = T.length; w < k; w++)if (1 & T[w].flags) n(T[w].x, T[w].y); else if (1 & T[w + 1].flags) { s(T[w].x, T[w].y, T[w + 1].x, T[w + 1].y); w++ } else s(T[w].x, T[w].y, (T[w].x + T[w + 1].x) / 2, (T[w].y + T[w + 1].y) / 2); I = F + 1 } } }(e, t, this) } } class g extends d { constructor(e, t, r, i) { super(r || [.001, 0, 0, .001, 0, 0]); this.glyphs = e.glyphs; this.gsubrs = e.gsubrs || []; this.subrs = e.subrs || []; this.cmap = t; this.glyphNameMap = i || (0, n.getGlyphsUnicode)(); this.gsubrsBias = a(this.gsubrs); this.subrsBias = a(this.subrs); this.isCFFCIDFont = e.isCFFCIDFont; this.fdSelect = e.fdSelect; this.fdArray = e.fdArray } compileGlyphImpl(e, t, i) { !function e(t, i, n, o) { var c = [], l = 0, u = 0, d = 0; function f(e, t) { i.push({ cmd: "moveTo", args: [e, t] }) } function g(e, t) { i.push({ cmd: "lineTo", args: [e, t] }) } function m(e, t, a, r, n, s) { i.push({ cmd: "bezierCurveTo", args: [e, t, a, r, n, s] }) } !function t(p) { for (var b = 0; b < p.length;) { var y, v, w, k, S, C, x, A, I = !1, F = p[b++]; switch (F) { case 1: case 3: d += c.length >> 1; I = !0; break; case 4: u += c.pop(); f(l, u); I = !0; break; case 5: for (; c.length > 0;) { l += c.shift(); u += c.shift(); g(l, u) } break; case 6: for (; c.length > 0;) { g(l += c.shift(), u); if (0 === c.length) break; u += c.shift(); g(l, u) } break; case 7: for (; c.length > 0;) { u += c.shift(); g(l, u); if (0 === c.length) break; g(l += c.shift(), u) } break; case 8: for (; c.length > 0;) { y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u) } break; case 10: x = c.pop(); A = null; if (n.isCFFCIDFont) { const e = n.fdSelect.getFDIndex(o); if (e >= 0 && e < n.fdArray.length) { const t = n.fdArray[e]; let r; t.privateDict && t.privateDict.subrsIndex && (r = t.privateDict.subrsIndex.objects); r && (A = r[x += a(r)]) } else (0, r.warn)("Invalid fd index for glyph index.") } else A = n.subrs[x + n.subrsBias]; A && t(A); break; case 11: return; case 12: switch (F = p[b++]) { case 34: v = (y = l + c.shift()) + c.shift(); S = u + c.shift(); l = v + c.shift(); m(y, u, v, S, l, S); v = (y = l + c.shift()) + c.shift(); l = v + c.shift(); m(y, S, v, u, l, u); break; case 35: y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u); y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u); c.pop(); break; case 36: m(y = l + c.shift(), S = u + c.shift(), v = y + c.shift(), C = S + c.shift(), l = v + c.shift(), C); m(y = l + c.shift(), C, v = y + c.shift(), C + c.shift(), l = v + c.shift(), u); break; case 37: var T = l, E = u; y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u); y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v; u = k; Math.abs(l - T) > Math.abs(u - E) ? l += c.shift() : u += c.shift(); m(y, w, v, k, l, u); break; default: throw new r.FormatError(`unknown operator: 12 ${F}`) }break; case 14: if (c.length >= 4) { var O = c.pop(), P = c.pop(); u = c.pop(); l = c.pop(); i.push({ cmd: "save" }); i.push({ cmd: "translate", args: [l, u] }); var B = h(n.cmap, String.fromCharCode(n.glyphNameMap[s.StandardEncoding[O]])); e(n.glyphs[B.glyphId], i, n, B.glyphId); i.push({ cmd: "restore" }); B = h(n.cmap, String.fromCharCode(n.glyphNameMap[s.StandardEncoding[P]])); e(n.glyphs[B.glyphId], i, n, B.glyphId) } return; case 18: d += c.length >> 1; I = !0; break; case 19: case 20: b += (d += c.length >> 1) + 7 >> 3; I = !0; break; case 21: u += c.pop(); f(l += c.pop(), u); I = !0; break; case 22: f(l += c.pop(), u); I = !0; break; case 23: d += c.length >> 1; I = !0; break; case 24: for (; c.length > 2;) { y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u) } l += c.shift(); u += c.shift(); g(l, u); break; case 25: for (; c.length > 6;) { l += c.shift(); u += c.shift(); g(l, u) } y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u); break; case 26: c.length % 2 && (l += c.shift()); for (; c.length > 0;) { y = l; w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v; u = k + c.shift(); m(y, w, v, k, l, u) } break; case 27: c.length % 2 && (u += c.shift()); for (; c.length > 0;)m(y = l + c.shift(), w = u, v = y + c.shift(), k = w + c.shift(), l = v + c.shift(), u = k); break; case 28: c.push((p[b] << 24 | p[b + 1] << 16) >> 16); b += 2; break; case 29: x = c.pop() + n.gsubrsBias; (A = n.gsubrs[x]) && t(A); break; case 30: for (; c.length > 0;) { y = l; w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + (1 === c.length ? c.shift() : 0); m(y, w, v, k, l, u); if (0 === c.length) break; y = l + c.shift(); w = u; v = y + c.shift(); k = w + c.shift(); u = k + c.shift(); m(y, w, v, k, l = v + (1 === c.length ? c.shift() : 0), u) } break; case 31: for (; c.length > 0;) { y = l + c.shift(); w = u; v = y + c.shift(); k = w + c.shift(); u = k + c.shift(); m(y, w, v, k, l = v + (1 === c.length ? c.shift() : 0), u); if (0 === c.length) break; y = l; w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + (1 === c.length ? c.shift() : 0); m(y, w, v, k, l, u) } break; default: if (F < 32) throw new r.FormatError(`unknown operator: ${F}`); if (F < 247) c.push(F - 139); else if (F < 251) c.push(256 * (F - 247) + p[b++] + 108); else if (F < 255) c.push(256 * -(F - 251) - p[b++] - 108); else { c.push((p[b] << 24 | p[b + 1] << 16 | p[b + 2] << 8 | p[b + 3]) / 65536); b += 4 } }I && (c.length = 0) } }(t) }(e, t, this, i) } } return { create: function (a, i) { for (var n, s, o, h, u, d, m = new Uint8Array(a.data), p = t(m, 4), b = 0, y = 12; b < p; b++, y += 16) { var v = (0, r.bytesToString)(m.subarray(y, y + 4)), w = e(m, y + 8), k = e(m, y + 12); switch (v) { case "cmap": n = c(m, w); break; case "glyf": s = m.subarray(w, w + k); break; case "loca": o = m.subarray(w, w + k); break; case "head": d = t(m, w + 18); u = t(m, w + 50); break; case "CFF ": h = l(m, w, w + k, i) } } if (s) { var S = d ? [1 / d, 0, 0, 1 / d, 0, 0] : a.fontMatrix; return new f(function (e, t, a) { var r, i; if (a) { r = 4; i = function (e, t) { return e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3] } } else { r = 2; i = function (e, t) { return e[t] << 9 | e[t + 1] << 1 } } for (var n = [], s = i(t, 0), o = r; o < t.length; o += r) { var c = i(t, o); n.push(e.subarray(s, c)); s = c } return n }(s, o, u), n, S) } return new g(h, n, a.fontMatrix, a.glyphNameMap) } } }(); t.FontRendererFactory = c }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.Type1Parser = void 0; var r = a(30), i = a(7), n = a(11), s = a(2), o = function () { var e = [4], t = [5], a = [6], r = [7], i = [8], n = [12, 35], o = [14], c = [21], l = [22], h = [30], u = [31]; function d() { this.width = 0; this.lsb = 0; this.flexing = !1; this.output = []; this.stack = [] } d.prototype = { convert: function (d, f, g) { for (var m, p, b, y = d.length, v = !1, w = 0; w < y; w++) { var k = d[w]; if (k < 32) { 12 === k && (k = (k << 8) + d[++w]); switch (k) { case 1: case 3: this.stack = []; break; case 4: if (this.flexing) { if (this.stack.length < 1) { v = !0; break } var S = this.stack.pop(); this.stack.push(0, S); break } v = this.executeCommand(1, e); break; case 5: v = this.executeCommand(2, t); break; case 6: v = this.executeCommand(1, a); break; case 7: v = this.executeCommand(1, r); break; case 8: v = this.executeCommand(6, i); break; case 9: this.stack = []; break; case 10: if (this.stack.length < 1) { v = !0; break } if (!f[b = this.stack.pop()]) { v = !0; break } v = this.convert(f[b], f, g); break; case 11: return v; case 13: if (this.stack.length < 2) { v = !0; break } m = this.stack.pop(); p = this.stack.pop(); this.lsb = p; this.width = m; this.stack.push(m, p); v = this.executeCommand(2, l); break; case 14: this.output.push(o[0]); break; case 21: if (this.flexing) break; v = this.executeCommand(2, c); break; case 22: if (this.flexing) { this.stack.push(0); break } v = this.executeCommand(1, l); break; case 30: v = this.executeCommand(4, h); break; case 31: v = this.executeCommand(4, u); break; case 3072: case 3073: case 3074: this.stack = []; break; case 3078: if (g) { this.seac = this.stack.splice(-4, 4); v = this.executeCommand(0, o) } else v = this.executeCommand(4, o); break; case 3079: if (this.stack.length < 4) { v = !0; break } this.stack.pop(); m = this.stack.pop(); var C = this.stack.pop(); p = this.stack.pop(); this.lsb = p; this.width = m; this.stack.push(m, p, C); v = this.executeCommand(3, c); break; case 3084: if (this.stack.length < 2) { v = !0; break } var x = this.stack.pop(), A = this.stack.pop(); this.stack.push(A / x); break; case 3088: if (this.stack.length < 2) { v = !0; break } b = this.stack.pop(); var I = this.stack.pop(); if (0 === b && 3 === I) { var F = this.stack.splice(this.stack.length - 17, 17); this.stack.push(F[2] + F[0], F[3] + F[1], F[4], F[5], F[6], F[7], F[8], F[9], F[10], F[11], F[12], F[13], F[14]); v = this.executeCommand(13, n, !0); this.flexing = !1; this.stack.push(F[15], F[16]) } else 1 === b && 0 === I && (this.flexing = !0); break; case 3089: break; case 3105: this.stack = []; break; default: (0, s.warn)('Unknown type 1 charstring command of "' + k + '"') }if (v) break } else { k <= 246 ? k -= 139 : k = k <= 250 ? 256 * (k - 247) + d[++w] + 108 : k <= 254 ? -256 * (k - 251) - d[++w] - 108 : (255 & d[++w]) << 24 | (255 & d[++w]) << 16 | (255 & d[++w]) << 8 | (255 & d[++w]) << 0; this.stack.push(k) } } return v }, executeCommand(e, t, a) { var r = this.stack.length; if (e > r) return !0; for (var i = r - e, n = i; n < r; n++) { var s = this.stack[n]; if (Number.isInteger(s)) this.output.push(28, s >> 8 & 255, 255 & s); else { s = 65536 * s | 0; this.output.push(255, s >> 24 & 255, s >> 16 & 255, s >> 8 & 255, 255 & s) } } this.output.push.apply(this.output, t); a ? this.stack.splice(i, e) : this.stack.length = 0; return !1 } }; return d }(), c = function () { function e(e) { return e >= 48 && e <= 57 || e >= 65 && e <= 70 || e >= 97 && e <= 102 } function t(e, t, a) { if (a >= e.length) return new Uint8Array(0); var r, i, n = 0 | t; for (r = 0; r < a; r++)n = 52845 * (e[r] + n) + 22719 & 65535; var s = e.length - a, o = new Uint8Array(s); for (r = a, i = 0; i < s; r++, i++) { var c = e[r]; o[i] = c ^ n >> 8; n = 52845 * (c + n) + 22719 & 65535 } return o } function a(e) { return 47 === e || 91 === e || 93 === e || 123 === e || 125 === e || 40 === e || 41 === e } function s(a, r, i) { if (r) { var s = a.getBytes(), o = !(e(s[0]) && e(s[1]) && e(s[2]) && e(s[3])); a = new n.Stream(o ? t(s, 55665, 4) : function (t, a, r) { var i, n, s = 0 | a, o = t.length, c = new Uint8Array(o >>> 1); for (i = 0, n = 0; i < o; i++) { var l = t[i]; if (e(l)) { i++; for (var h; i < o && !e(h = t[i]);)i++; if (i < o) { var u = parseInt(String.fromCharCode(l, h), 16); c[n++] = u ^ s >> 8; s = 52845 * (u + s) + 22719 & 65535 } } } return Array.prototype.slice.call(c, r, n) }(s, 55665, 4)) } this.seacAnalysisEnabled = !!i; this.stream = a; this.nextChar() } s.prototype = { readNumberArray: function () { this.getToken(); for (var e = []; ;) { var t = this.getToken(); if (null === t || "]" === t || "}" === t) break; e.push(parseFloat(t || 0)) } return e }, readNumber: function () { var e = this.getToken(); return parseFloat(e || 0) }, readInt: function () { var e = this.getToken(); return 0 | parseInt(e || 0, 10) }, readBoolean: function () { return "true" === this.getToken() ? 1 : 0 }, nextChar: function () { return this.currentChar = this.stream.getByte() }, getToken: function () { for (var e = !1, t = this.currentChar; ;) { if (-1 === t) return null; if (e) 10 !== t && 13 !== t || (e = !1); else if (37 === t) e = !0; else if (!(0, i.isWhiteSpace)(t)) break; t = this.nextChar() } if (a(t)) { this.nextChar(); return String.fromCharCode(t) } var r = ""; do { r += String.fromCharCode(t); t = this.nextChar() } while (t >= 0 && !(0, i.isWhiteSpace)(t) && !a(t)); return r }, readCharStrings: function (e, a) { return -1 === a ? e : t(e, 4330, a) }, extractFontProgram: function (e) { var t = this.stream, a = [], r = [], i = Object.create(null); i.lenIV = 4; for (var n, s, c, l, h, u = { subrs: [], charstrings: [], properties: { privateData: i } }; null !== (n = this.getToken());)if ("/" === n) switch (n = this.getToken()) { case "CharStrings": this.getToken(); this.getToken(); this.getToken(); this.getToken(); for (; null !== (n = this.getToken()) && "end" !== n;)if ("/" === n) { var d = this.getToken(); s = this.readInt(); this.getToken(); c = s > 0 ? t.getBytes(s) : new Uint8Array(0); l = u.properties.privateData.lenIV; h = this.readCharStrings(c, l); this.nextChar(); "noaccess" === (n = this.getToken()) && this.getToken(); r.push({ glyph: d, encoded: h }) } break; case "Subrs": this.readInt(); this.getToken(); for (; "dup" === this.getToken();) { var f = this.readInt(); s = this.readInt(); this.getToken(); c = s > 0 ? t.getBytes(s) : new Uint8Array(0); l = u.properties.privateData.lenIV; h = this.readCharStrings(c, l); this.nextChar(); "noaccess" === (n = this.getToken()) && this.getToken(); a[f] = h } break; case "BlueValues": case "OtherBlues": case "FamilyBlues": case "FamilyOtherBlues": var g = this.readNumberArray(); g.length > 0 && g.length, 0; break; case "StemSnapH": case "StemSnapV": u.properties.privateData[n] = this.readNumberArray(); break; case "StdHW": case "StdVW": u.properties.privateData[n] = this.readNumberArray()[0]; break; case "BlueShift": case "lenIV": case "BlueFuzz": case "BlueScale": case "LanguageGroup": case "ExpansionFactor": u.properties.privateData[n] = this.readNumber(); break; case "ForceBold": u.properties.privateData[n] = this.readBoolean() }for (var m = 0; m < r.length; m++) { d = r[m].glyph; h = r[m].encoded; var p = new o, b = p.convert(h, a, this.seacAnalysisEnabled), y = p.output; b && (y = [14]); const t = { glyphName: d, charstring: y, width: p.width, lsb: p.lsb, seac: p.seac }; ".notdef" === d ? u.charstrings.unshift(t) : u.charstrings.push(t); if (e.builtInEncoding) { const t = e.builtInEncoding.indexOf(d); t > -1 && void 0 === e.widths[t] && t >= e.firstChar && t <= e.lastChar && (e.widths[t] = p.width) } } return u }, extractFontHeader: function (e) { for (var t; null !== (t = this.getToken());)if ("/" === t) switch (t = this.getToken()) { case "FontMatrix": var a = this.readNumberArray(); e.fontMatrix = a; break; case "Encoding": var i, n = this.getToken(); if (/^\d+$/.test(n)) { i = []; var s = 0 | parseInt(n, 10); this.getToken(); for (var o = 0; o < s; o++) { t = this.getToken(); for (; "dup" !== t && "def" !== t;)if (null === (t = this.getToken())) return; if ("def" === t) break; var c = this.readInt(); this.getToken(); var l = this.getToken(); i[c] = l; this.getToken() } } else i = (0, r.getEncoding)(n); e.builtInEncoding = i; break; case "FontBBox": var h = this.readNumberArray(); e.ascent = Math.max(h[3], h[1]); e.descent = Math.min(h[1], h[3]); e.ascentScaled = !0 } } }; return s }(); t.Type1Parser = c }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getTilingPatternIR = function (e, t, a) { const i = t.getArray("Matrix"), n = r.Util.normalizeRect(t.getArray("BBox")), s = t.get("XStep"), o = t.get("YStep"), c = t.get("PaintType"), l = t.get("TilingType"); if (n[2] - n[0] == 0 || n[3] - n[1] == 0) throw new r.FormatError(`Invalid getTilingPatternIR /BBox array: [${n}].`); return ["TilingPattern", a, e, i, n, s, o, c, l] }; t.Pattern = void 0; var r = a(2), i = a(22), n = a(4), s = a(7), o = 2, c = 3, l = 4, h = 5, u = 6, d = 7, f = function () { function e() { (0, r.unreachable)("should not call Pattern constructor") } e.prototype = { getPattern: function (e) { (0, r.unreachable)(`Should not call Pattern.getStyle: ${e}`) } }; e.parseShading = function (e, t, a, i, f, m) { var p = (0, n.isStream)(e) ? e.dict : e, b = p.get("ShadingType"); try { switch (b) { case o: case c: return new g.RadialAxial(p, t, a, i, m); case l: case h: case u: case d: return new g.Mesh(e, t, a, i, m); default: throw new r.FormatError("Unsupported ShadingType: " + b) } } catch (e) { if (e instanceof s.MissingDataException) throw e; f.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.shadingPattern }); (0, r.warn)(e); return new g.Dummy } }; return e }(); t.Pattern = f; var g = { SMALL_NUMBER: 1e-6 }; g.RadialAxial = function () { function e(e, t, a, n, s) { this.matrix = t; this.coordsArr = e.getArray("Coords"); this.shadingType = e.get("ShadingType"); this.type = "Pattern"; var o = e.get("ColorSpace", "CS"); o = i.ColorSpace.parse(o, a, n, s); this.cs = o; const l = e.getArray("BBox"); Array.isArray(l) && 4 === l.length ? this.bbox = r.Util.normalizeRect(l) : this.bbox = null; var h = 0, u = 1; if (e.has("Domain")) { var d = e.getArray("Domain"); h = d[0]; u = d[1] } var f = !1, m = !1; if (e.has("Extend")) { var p = e.getArray("Extend"); f = p[0]; m = p[1] } if (!(this.shadingType !== c || f && m)) { var b = this.coordsArr[0], y = this.coordsArr[1], v = this.coordsArr[2], w = this.coordsArr[3], k = this.coordsArr[4], S = this.coordsArr[5], C = Math.sqrt((b - w) * (b - w) + (y - k) * (y - k)); v <= S + C && S <= v + C && (0, r.warn)("Unsupported radial gradient.") } this.extendStart = f; this.extendEnd = m; var x = e.get("Function"), A = s.createFromArray(x); const I = (u - h) / 10; var F = this.colorStops = []; if (h >= u || I <= 0) (0, r.info)("Bad shading domain."); else { var T, E = new Float32Array(o.numComps), O = new Float32Array(1); for (let e = 0; e <= 10; e++) { O[0] = h + e * I; A(O, 0, E, 0); T = o.getRgb(E, 0); var P = r.Util.makeCssRgb(T[0], T[1], T[2]); F.push([e / 10, P]) } var B = "transparent"; if (e.has("Background")) { T = o.getRgb(e.get("Background"), 0); B = r.Util.makeCssRgb(T[0], T[1], T[2]) } if (!f) { F.unshift([0, B]); F[1][0] += g.SMALL_NUMBER } if (!m) { F[F.length - 1][0] -= g.SMALL_NUMBER; F.push([1, B]) } this.colorStops = F } } e.prototype = { getIR: function () { var e, t, a, i, n, s = this.coordsArr, l = this.shadingType; if (l === o) { t = [s[0], s[1]]; a = [s[2], s[3]]; i = null; n = null; e = "axial" } else if (l === c) { t = [s[0], s[1]]; a = [s[3], s[4]]; i = s[2]; n = s[5]; e = "radial" } else (0, r.unreachable)(`getPattern type unknown: ${l}`); var h = this.matrix; if (h) { t = r.Util.applyTransform(t, h); a = r.Util.applyTransform(a, h); if (l === c) { var u = r.Util.singularValueDecompose2dScale(h); i *= u[0]; n *= u[1] } } return ["RadialAxial", e, this.bbox, this.colorStops, t, a, i, n] } }; return e }(); g.Mesh = function () { function e(e, t) { this.stream = e; this.context = t; this.buffer = 0; this.bufferLength = 0; var a = t.numComps; this.tmpCompsBuf = new Float32Array(a); var r = t.colorSpace.numComps; this.tmpCsCompsBuf = t.colorFn ? new Float32Array(r) : this.tmpCompsBuf } e.prototype = { get hasData() { if (this.stream.end) return this.stream.pos < this.stream.end; if (this.bufferLength > 0) return !0; var e = this.stream.getByte(); if (e < 0) return !1; this.buffer = e; this.bufferLength = 8; return !0 }, readBits: function (e) { var t = this.buffer, a = this.bufferLength; if (32 === e) { if (0 === a) return (this.stream.getByte() << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte()) >>> 0; t = t << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte(); var r = this.stream.getByte(); this.buffer = r & (1 << a) - 1; return (t << 8 - a | (255 & r) >> a) >>> 0 } if (8 === e && 0 === a) return this.stream.getByte(); for (; a < e;) { t = t << 8 | this.stream.getByte(); a += 8 } a -= e; this.bufferLength = a; this.buffer = t & (1 << a) - 1; return t >> a }, align: function () { this.buffer = 0; this.bufferLength = 0 }, readFlag: function () { return this.readBits(this.context.bitsPerFlag) }, readCoordinate: function () { var e = this.context.bitsPerCoordinate, t = this.readBits(e), a = this.readBits(e), r = this.context.decode, i = e < 32 ? 1 / ((1 << e) - 1) : 2.3283064365386963e-10; return [t * i * (r[1] - r[0]) + r[0], a * i * (r[3] - r[2]) + r[2]] }, readComponents: function () { for (var e = this.context.numComps, t = this.context.bitsPerComponent, a = t < 32 ? 1 / ((1 << t) - 1) : 2.3283064365386963e-10, r = this.context.decode, i = this.tmpCompsBuf, n = 0, s = 4; n < e; n++, s += 2) { var o = this.readBits(t); i[n] = o * a * (r[s + 1] - r[s]) + r[s] } var c = this.tmpCsCompsBuf; this.context.colorFn && this.context.colorFn(i, 0, c, 0); return this.context.colorSpace.getRgb(c, 0) } }; var t, a = (t = [], function (e) { t[e] || (t[e] = function (e) { for (var t = [], a = 0; a <= e; a++) { var r = a / e, i = 1 - r; t.push(new Float32Array([i * i * i, 3 * r * i * i, 3 * r * r * i, r * r * r])) } return t }(e)); return t[e] }); function s(e, t) { var i = e.figures[t]; (0, r.assert)("patch" === i.type, "Unexpected patch mesh figure"); var n = e.coords, s = e.colors, o = i.coords, c = i.colors, l = Math.min(n[o[0]][0], n[o[3]][0], n[o[12]][0], n[o[15]][0]), h = Math.min(n[o[0]][1], n[o[3]][1], n[o[12]][1], n[o[15]][1]), u = Math.max(n[o[0]][0], n[o[3]][0], n[o[12]][0], n[o[15]][0]), d = Math.max(n[o[0]][1], n[o[3]][1], n[o[12]][1], n[o[15]][1]), f = Math.ceil(20 * (u - l) / (e.bounds[2] - e.bounds[0])); f = Math.max(3, Math.min(20, f)); var g = Math.ceil(20 * (d - h) / (e.bounds[3] - e.bounds[1])); g = Math.max(3, Math.min(20, g)); for (var m = f + 1, p = new Int32Array((g + 1) * m), b = new Int32Array((g + 1) * m), y = 0, v = new Uint8Array(3), w = new Uint8Array(3), k = s[c[0]], S = s[c[1]], C = s[c[2]], x = s[c[3]], A = a(g), I = a(f), F = 0; F <= g; F++) { v[0] = (k[0] * (g - F) + C[0] * F) / g | 0; v[1] = (k[1] * (g - F) + C[1] * F) / g | 0; v[2] = (k[2] * (g - F) + C[2] * F) / g | 0; w[0] = (S[0] * (g - F) + x[0] * F) / g | 0; w[1] = (S[1] * (g - F) + x[1] * F) / g | 0; w[2] = (S[2] * (g - F) + x[2] * F) / g | 0; for (var T = 0; T <= f; T++, y++)if (0 !== F && F !== g || 0 !== T && T !== f) { for (var E = 0, O = 0, P = 0, B = 0; B <= 3; B++)for (var D = 0; D <= 3; D++, P++) { var N = A[F][B] * I[T][D]; E += n[o[P]][0] * N; O += n[o[P]][1] * N } p[y] = n.length; n.push([E, O]); b[y] = s.length; var M = new Uint8Array(3); M[0] = (v[0] * (f - T) + w[0] * T) / f | 0; M[1] = (v[1] * (f - T) + w[1] * T) / f | 0; M[2] = (v[2] * (f - T) + w[2] * T) / f | 0; s.push(M) } } p[0] = o[0]; b[0] = c[0]; p[f] = o[3]; b[f] = c[1]; p[m * g] = o[12]; b[m * g] = c[2]; p[m * g + f] = o[15]; b[m * g + f] = c[3]; e.figures[t] = { type: "lattice", coords: p, colors: b, verticesPerRow: m } } function o(e) { for (var t = e.coords[0][0], a = e.coords[0][1], r = t, i = a, n = 1, s = e.coords.length; n < s; n++) { var o = e.coords[n][0], c = e.coords[n][1]; t = t > o ? o : t; a = a > c ? c : a; r = r < o ? o : r; i = i < c ? c : i } e.bounds = [t, a, r, i] } function c(t, a, c, f, g) { if (!(0, n.isStream)(t)) throw new r.FormatError("Mesh data is not a stream"); var m = t.dict; this.matrix = a; this.shadingType = m.get("ShadingType"); this.type = "Pattern"; const p = m.getArray("BBox"); Array.isArray(p) && 4 === p.length ? this.bbox = r.Util.normalizeRect(p) : this.bbox = null; var b = m.get("ColorSpace", "CS"); b = i.ColorSpace.parse(b, c, f, g); this.cs = b; this.background = m.has("Background") ? b.getRgb(m.get("Background"), 0) : null; var y = m.get("Function"), v = y ? g.createFromArray(y) : null; this.coords = []; this.colors = []; this.figures = []; var w = new e(t, { bitsPerCoordinate: m.get("BitsPerCoordinate"), bitsPerComponent: m.get("BitsPerComponent"), bitsPerFlag: m.get("BitsPerFlag"), decode: m.getArray("Decode"), colorFn: v, colorSpace: b, numComps: v ? 1 : b.numComps }), k = !1; switch (this.shadingType) { case l: !function (e, t) { for (var a = e.coords, i = e.colors, n = [], s = [], o = 0; t.hasData;) { var c = t.readFlag(), l = t.readCoordinate(), h = t.readComponents(); if (0 === o) { if (!(0 <= c && c <= 2)) throw new r.FormatError("Unknown type4 flag"); switch (c) { case 0: o = 3; break; case 1: s.push(s[s.length - 2], s[s.length - 1]); o = 1; break; case 2: s.push(s[s.length - 3], s[s.length - 1]); o = 1 }n.push(c) } s.push(a.length); a.push(l); i.push(h); o--; t.align() } e.figures.push({ type: "triangles", coords: new Int32Array(s), colors: new Int32Array(s) }) }(this, w); break; case h: var S = 0 | m.get("VerticesPerRow"); if (S < 2) throw new r.FormatError("Invalid VerticesPerRow"); !function (e, t, a) { for (var r = e.coords, i = e.colors, n = []; t.hasData;) { var s = t.readCoordinate(), o = t.readComponents(); n.push(r.length); r.push(s); i.push(o) } e.figures.push({ type: "lattice", coords: new Int32Array(n), colors: new Int32Array(n), verticesPerRow: a }) }(this, w, S); break; case u: !function (e, t) { for (var a = e.coords, i = e.colors, n = new Int32Array(16), s = new Int32Array(4); t.hasData;) { var o, c, l = t.readFlag(); if (!(0 <= l && l <= 3)) throw new r.FormatError("Unknown type6 flag"); var h = a.length; for (o = 0, c = 0 !== l ? 8 : 12; o < c; o++)a.push(t.readCoordinate()); var u, d, f, g, m = i.length; for (o = 0, c = 0 !== l ? 2 : 4; o < c; o++)i.push(t.readComponents()); switch (l) { case 0: n[12] = h + 3; n[13] = h + 4; n[14] = h + 5; n[15] = h + 6; n[8] = h + 2; n[11] = h + 7; n[4] = h + 1; n[7] = h + 8; n[0] = h; n[1] = h + 11; n[2] = h + 10; n[3] = h + 9; s[2] = m + 1; s[3] = m + 2; s[0] = m; s[1] = m + 3; break; case 1: u = n[12]; d = n[13]; f = n[14]; g = n[15]; n[12] = g; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = f; n[11] = h + 3; n[4] = d; n[7] = h + 4; n[0] = u; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; u = s[2]; d = s[3]; s[2] = d; s[3] = m; s[0] = u; s[1] = m + 1; break; case 2: u = n[15]; d = n[11]; n[12] = n[3]; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = n[7]; n[11] = h + 3; n[4] = d; n[7] = h + 4; n[0] = u; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; u = s[3]; s[2] = s[1]; s[3] = m; s[0] = u; s[1] = m + 1; break; case 3: n[12] = n[0]; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = n[1]; n[11] = h + 3; n[4] = n[2]; n[7] = h + 4; n[0] = n[3]; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; s[2] = s[0]; s[3] = m; s[0] = s[1]; s[1] = m + 1 }n[5] = a.length; a.push([(-4 * a[n[0]][0] - a[n[15]][0] + 6 * (a[n[4]][0] + a[n[1]][0]) - 2 * (a[n[12]][0] + a[n[3]][0]) + 3 * (a[n[13]][0] + a[n[7]][0])) / 9, (-4 * a[n[0]][1] - a[n[15]][1] + 6 * (a[n[4]][1] + a[n[1]][1]) - 2 * (a[n[12]][1] + a[n[3]][1]) + 3 * (a[n[13]][1] + a[n[7]][1])) / 9]); n[6] = a.length; a.push([(-4 * a[n[3]][0] - a[n[12]][0] + 6 * (a[n[2]][0] + a[n[7]][0]) - 2 * (a[n[0]][0] + a[n[15]][0]) + 3 * (a[n[4]][0] + a[n[14]][0])) / 9, (-4 * a[n[3]][1] - a[n[12]][1] + 6 * (a[n[2]][1] + a[n[7]][1]) - 2 * (a[n[0]][1] + a[n[15]][1]) + 3 * (a[n[4]][1] + a[n[14]][1])) / 9]); n[9] = a.length; a.push([(-4 * a[n[12]][0] - a[n[3]][0] + 6 * (a[n[8]][0] + a[n[13]][0]) - 2 * (a[n[0]][0] + a[n[15]][0]) + 3 * (a[n[11]][0] + a[n[1]][0])) / 9, (-4 * a[n[12]][1] - a[n[3]][1] + 6 * (a[n[8]][1] + a[n[13]][1]) - 2 * (a[n[0]][1] + a[n[15]][1]) + 3 * (a[n[11]][1] + a[n[1]][1])) / 9]); n[10] = a.length; a.push([(-4 * a[n[15]][0] - a[n[0]][0] + 6 * (a[n[11]][0] + a[n[14]][0]) - 2 * (a[n[12]][0] + a[n[3]][0]) + 3 * (a[n[2]][0] + a[n[8]][0])) / 9, (-4 * a[n[15]][1] - a[n[0]][1] + 6 * (a[n[11]][1] + a[n[14]][1]) - 2 * (a[n[12]][1] + a[n[3]][1]) + 3 * (a[n[2]][1] + a[n[8]][1])) / 9]); e.figures.push({ type: "patch", coords: new Int32Array(n), colors: new Int32Array(s) }) } }(this, w); k = !0; break; case d: !function (e, t) { for (var a = e.coords, i = e.colors, n = new Int32Array(16), s = new Int32Array(4); t.hasData;) { var o, c, l = t.readFlag(); if (!(0 <= l && l <= 3)) throw new r.FormatError("Unknown type7 flag"); var h = a.length; for (o = 0, c = 0 !== l ? 12 : 16; o < c; o++)a.push(t.readCoordinate()); var u, d, f, g, m = i.length; for (o = 0, c = 0 !== l ? 2 : 4; o < c; o++)i.push(t.readComponents()); switch (l) { case 0: n[12] = h + 3; n[13] = h + 4; n[14] = h + 5; n[15] = h + 6; n[8] = h + 2; n[9] = h + 13; n[10] = h + 14; n[11] = h + 7; n[4] = h + 1; n[5] = h + 12; n[6] = h + 15; n[7] = h + 8; n[0] = h; n[1] = h + 11; n[2] = h + 10; n[3] = h + 9; s[2] = m + 1; s[3] = m + 2; s[0] = m; s[1] = m + 3; break; case 1: u = n[12]; d = n[13]; f = n[14]; g = n[15]; n[12] = g; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = f; n[9] = h + 9; n[10] = h + 10; n[11] = h + 3; n[4] = d; n[5] = h + 8; n[6] = h + 11; n[7] = h + 4; n[0] = u; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; u = s[2]; d = s[3]; s[2] = d; s[3] = m; s[0] = u; s[1] = m + 1; break; case 2: u = n[15]; d = n[11]; n[12] = n[3]; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = n[7]; n[9] = h + 9; n[10] = h + 10; n[11] = h + 3; n[4] = d; n[5] = h + 8; n[6] = h + 11; n[7] = h + 4; n[0] = u; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; u = s[3]; s[2] = s[1]; s[3] = m; s[0] = u; s[1] = m + 1; break; case 3: n[12] = n[0]; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = n[1]; n[9] = h + 9; n[10] = h + 10; n[11] = h + 3; n[4] = n[2]; n[5] = h + 8; n[6] = h + 11; n[7] = h + 4; n[0] = n[3]; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; s[2] = s[0]; s[3] = m; s[0] = s[1]; s[1] = m + 1 }e.figures.push({ type: "patch", coords: new Int32Array(n), colors: new Int32Array(s) }) } }(this, w); k = !0; break; default: (0, r.unreachable)("Unsupported mesh type.") }if (k) { o(this); for (var C = 0, x = this.figures.length; C < x; C++)s(this, C) } o(this); !function (e) { var t, a, r, i, n = e.coords, s = new Float32Array(2 * n.length); for (t = 0, r = 0, a = n.length; t < a; t++) { var o = n[t]; s[r++] = o[0]; s[r++] = o[1] } e.coords = s; var c = e.colors, l = new Uint8Array(3 * c.length); for (t = 0, r = 0, a = c.length; t < a; t++) { var h = c[t]; l[r++] = h[0]; l[r++] = h[1]; l[r++] = h[2] } e.colors = l; var u = e.figures; for (t = 0, a = u.length; t < a; t++) { var d = u[t], f = d.coords, g = d.colors; for (r = 0, i = f.length; r < i; r++) { f[r] *= 2; g[r] *= 3 } } }(this) } c.prototype = { getIR: function () { return ["Mesh", this.shadingType, this.coords, this.colors, this.figures, this.bounds, this.matrix, this.bbox, this.background] } }; return c }(); g.Dummy = function () { function e() { this.type = "Pattern" } e.prototype = { getIR: function () { return ["Dummy"] } }; return e }() }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.bidi = function (e, t, a) { var g = !0, m = e.length; if (0 === m || a) return u(e, g, a); d.length = m; f.length = m; var p, b, y = 0; for (p = 0; p < m; ++p) { d[p] = e.charAt(p); var v = e.charCodeAt(p), w = "L"; v <= 255 ? w = i[v] : 1424 <= v && v <= 1524 ? w = "R" : 1536 <= v && v <= 1791 ? (w = n[255 & v]) || (0, r.warn)("Bidi: invalid Unicode character " + v.toString(16)) : 1792 <= v && v <= 2220 && (w = "AL"); "R" !== w && "AL" !== w && "AN" !== w || y++; f[p] = w } if (0 === y) return u(e, g = !0); if (-1 === t) if (y / m < .3) { g = !0; t = 0 } else { g = !1; t = 1 } var k = []; for (p = 0; p < m; ++p)k[p] = t; var S, C = s(t) ? "R" : "L", x = C, A = x, I = x; for (p = 0; p < m; ++p)"NSM" === f[p] ? f[p] = I : I = f[p]; I = x; for (p = 0; p < m; ++p)"EN" === (S = f[p]) ? f[p] = "AL" === I ? "AN" : "EN" : "R" !== S && "L" !== S && "AL" !== S || (I = S); for (p = 0; p < m; ++p)"AL" === (S = f[p]) && (f[p] = "R"); for (p = 1; p < m - 1; ++p) { "ES" === f[p] && "EN" === f[p - 1] && "EN" === f[p + 1] && (f[p] = "EN"); "CS" !== f[p] || "EN" !== f[p - 1] && "AN" !== f[p - 1] || f[p + 1] !== f[p - 1] || (f[p] = f[p - 1]) } for (p = 0; p < m; ++p)if ("EN" === f[p]) { var F; for (F = p - 1; F >= 0 && "ET" === f[F]; --F)f[F] = "EN"; for (F = p + 1; F < m && "ET" === f[F]; ++F)f[F] = "EN" } for (p = 0; p < m; ++p)"WS" !== (S = f[p]) && "ES" !== S && "ET" !== S && "CS" !== S || (f[p] = "ON"); I = x; for (p = 0; p < m; ++p)"EN" === (S = f[p]) ? f[p] = "L" === I ? "L" : "EN" : "R" !== S && "L" !== S || (I = S); for (p = 0; p < m; ++p)if ("ON" === f[p]) { var T = c(f, p + 1, "ON"), E = x; p > 0 && (E = f[p - 1]); var O = A; T + 1 < m && (O = f[T + 1]); "L" !== E && (E = "R"); "L" !== O && (O = "R"); E === O && l(f, p, T, E); p = T - 1 } for (p = 0; p < m; ++p)"ON" === f[p] && (f[p] = C); for (p = 0; p < m; ++p) { S = f[p]; o(k[p]) ? "R" === S ? k[p] += 1 : "AN" !== S && "EN" !== S || (k[p] += 2) : "L" !== S && "AN" !== S && "EN" !== S || (k[p] += 1) } var P, B = -1, D = 99; for (p = 0, b = k.length; p < b; ++p) { P = k[p]; B < P && (B = P); D > P && s(P) && (D = P) } for (P = B; P >= D; --P) { var N = -1; for (p = 0, b = k.length; p < b; ++p)if (k[p] < P) { if (N >= 0) { h(d, N, p); N = -1 } } else N < 0 && (N = p); N >= 0 && h(d, N, k.length) } for (p = 0, b = d.length; p < b; ++p) { var M = d[p]; "<" !== M && ">" !== M || (d[p] = "") } return u(d.join(""), g) }; var r = a(2), i = ["BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "S", "B", "S", "WS", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "B", "B", "B", "S", "WS", "ON", "ON", "ET", "ET", "ET", "ON", "ON", "ON", "ON", "ON", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON", "BN", "BN", "BN", "BN", "BN", "BN", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "CS", "ON", "ET", "ET", "ET", "ET", "ON", "ON", "ON", "ON", "L", "ON", "ON", "BN", "ON", "ON", "ET", "ET", "EN", "EN", "ON", "L", "ON", "ON", "ON", "EN", "L", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L"], n = ["AN", "AN", "AN", "AN", "AN", "AN", "ON", "ON", "AL", "ET", "ET", "AL", "CS", "AL", "ON", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "ET", "AN", "AN", "AL", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "NSM", "NSM", "ON", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "AL", "AL", "AL", "AL", "AL", "AL"]; function s(e) { return 0 != (1 & e) } function o(e) { return 0 == (1 & e) } function c(e, t, a) { for (var r = t, i = e.length; r < i; ++r)if (e[r] !== a) return r; return r } function l(e, t, a, r) { for (var i = t; i < a; ++i)e[i] = r } function h(e, t, a) { for (var r = t, i = a - 1; r < i; ++r, --i) { var n = e[r]; e[r] = e[i]; e[i] = n } } function u(e, t, a = !1) { let r = "ltr"; a ? r = "ttb" : t || (r = "rtl"); return { str: e, dir: r } } var d = [], f = [] }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getMetrics = void 0; var r = a(7), i = (0, r.getLookupTableFactory)((function (e) { e.Courier = 600; e["Courier-Bold"] = 600; e["Courier-BoldOblique"] = 600; e["Courier-Oblique"] = 600; e.Helvetica = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.exclam = 278; e.quotedbl = 355; e.numbersign = 556; e.dollar = 556; e.percent = 889; e.ampersand = 667; e.quoteright = 222; e.parenleft = 333; e.parenright = 333; e.asterisk = 389; e.plus = 584; e.comma = 278; e.hyphen = 333; e.period = 278; e.slash = 278; e.zero = 556; e.one = 556; e.two = 556; e.three = 556; e.four = 556; e.five = 556; e.six = 556; e.seven = 556; e.eight = 556; e.nine = 556; e.colon = 278; e.semicolon = 278; e.less = 584; e.equal = 584; e.greater = 584; e.question = 556; e.at = 1015; e.A = 667; e.B = 667; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 722; e.I = 278; e.J = 500; e.K = 667; e.L = 556; e.M = 833; e.N = 722; e.O = 778; e.P = 667; e.Q = 778; e.R = 722; e.S = 667; e.T = 611; e.U = 722; e.V = 667; e.W = 944; e.X = 667; e.Y = 667; e.Z = 611; e.bracketleft = 278; e.backslash = 278; e.bracketright = 278; e.asciicircum = 469; e.underscore = 556; e.quoteleft = 222; e.a = 556; e.b = 556; e.c = 500; e.d = 556; e.e = 556; e.f = 278; e.g = 556; e.h = 556; e.i = 222; e.j = 222; e.k = 500; e.l = 222; e.m = 833; e.n = 556; e.o = 556; e.p = 556; e.q = 556; e.r = 333; e.s = 500; e.t = 278; e.u = 556; e.v = 500; e.w = 722; e.x = 500; e.y = 500; e.z = 500; e.braceleft = 334; e.bar = 260; e.braceright = 334; e.asciitilde = 584; e.exclamdown = 333; e.cent = 556; e.sterling = 556; e.fraction = 167; e.yen = 556; e.florin = 556; e.section = 556; e.currency = 556; e.quotesingle = 191; e.quotedblleft = 333; e.guillemotleft = 556; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 500; e.fl = 500; e.endash = 556; e.dagger = 556; e.daggerdbl = 556; e.periodcentered = 278; e.paragraph = 537; e.bullet = 350; e.quotesinglbase = 222; e.quotedblbase = 333; e.quotedblright = 333; e.guillemotright = 556; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 611; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 370; e.Lslash = 556; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 365; e.ae = 889; e.dotlessi = 278; e.lslash = 222; e.oslash = 611; e.oe = 944; e.germandbls = 611; e.Idieresis = 278; e.eacute = 556; e.abreve = 556; e.uhungarumlaut = 556; e.ecaron = 556; e.Ydieresis = 667; e.divide = 584; e.Yacute = 667; e.Acircumflex = 667; e.aacute = 556; e.Ucircumflex = 722; e.yacute = 500; e.scommaaccent = 500; e.ecircumflex = 556; e.Uring = 722; e.Udieresis = 722; e.aogonek = 556; e.Uacute = 722; e.uogonek = 556; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 737; e.Emacron = 667; e.ccaron = 500; e.aring = 556; e.Ncommaaccent = 722; e.lacute = 222; e.agrave = 556; e.Tcommaaccent = 611; e.Cacute = 722; e.atilde = 556; e.Edotaccent = 667; e.scaron = 500; e.scedilla = 500; e.iacute = 278; e.lozenge = 471; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 556; e.acircumflex = 556; e.Amacron = 667; e.rcaron = 333; e.ccedilla = 500; e.Zdotaccent = 611; e.Thorn = 667; e.Omacron = 778; e.Racute = 722; e.Sacute = 667; e.dcaron = 643; e.Umacron = 722; e.uring = 556; e.threesuperior = 333; e.Ograve = 778; e.Agrave = 667; e.Abreve = 667; e.multiply = 584; e.uacute = 556; e.Tcaron = 611; e.partialdiff = 476; e.ydieresis = 500; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 556; e.edieresis = 556; e.cacute = 500; e.nacute = 556; e.umacron = 556; e.Ncaron = 722; e.Iacute = 278; e.plusminus = 584; e.brokenbar = 260; e.registered = 737; e.Gbreve = 778; e.Idotaccent = 278; e.summation = 600; e.Egrave = 667; e.racute = 333; e.omacron = 556; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 222; e.tcaron = 317; e.eogonek = 556; e.Uogonek = 722; e.Aacute = 667; e.Adieresis = 667; e.egrave = 556; e.zacute = 500; e.iogonek = 222; e.Oacute = 778; e.oacute = 556; e.amacron = 556; e.sacute = 500; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 556; e.twosuperior = 333; e.Odieresis = 778; e.mu = 556; e.igrave = 278; e.ohungarumlaut = 556; e.Eogonek = 667; e.dcroat = 556; e.threequarters = 834; e.Scedilla = 667; e.lcaron = 299; e.Kcommaaccent = 667; e.Lacute = 556; e.trademark = 1e3; e.edotaccent = 556; e.Igrave = 278; e.Imacron = 278; e.Lcaron = 556; e.onehalf = 834; e.lessequal = 549; e.ocircumflex = 556; e.ntilde = 556; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 556; e.gbreve = 556; e.onequarter = 834; e.Scaron = 667; e.Scommaaccent = 667; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 556; e.Ccaron = 722; e.ugrave = 556; e.radical = 453; e.Dcaron = 722; e.rcommaaccent = 333; e.Ntilde = 722; e.otilde = 556; e.Rcommaaccent = 722; e.Lcommaaccent = 556; e.Atilde = 667; e.Aogonek = 667; e.Aring = 667; e.Otilde = 778; e.zdotaccent = 500; e.Ecaron = 667; e.Iogonek = 278; e.kcommaaccent = 500; e.minus = 584; e.Icircumflex = 278; e.ncaron = 556; e.tcommaaccent = 278; e.logicalnot = 584; e.odieresis = 556; e.udieresis = 556; e.notequal = 549; e.gcommaaccent = 556; e.eth = 556; e.zcaron = 500; e.ncommaaccent = 556; e.onesuperior = 333; e.imacron = 278; e.Euro = 556 })); e["Helvetica-Bold"] = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.exclam = 333; e.quotedbl = 474; e.numbersign = 556; e.dollar = 556; e.percent = 889; e.ampersand = 722; e.quoteright = 278; e.parenleft = 333; e.parenright = 333; e.asterisk = 389; e.plus = 584; e.comma = 278; e.hyphen = 333; e.period = 278; e.slash = 278; e.zero = 556; e.one = 556; e.two = 556; e.three = 556; e.four = 556; e.five = 556; e.six = 556; e.seven = 556; e.eight = 556; e.nine = 556; e.colon = 333; e.semicolon = 333; e.less = 584; e.equal = 584; e.greater = 584; e.question = 611; e.at = 975; e.A = 722; e.B = 722; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 722; e.I = 278; e.J = 556; e.K = 722; e.L = 611; e.M = 833; e.N = 722; e.O = 778; e.P = 667; e.Q = 778; e.R = 722; e.S = 667; e.T = 611; e.U = 722; e.V = 667; e.W = 944; e.X = 667; e.Y = 667; e.Z = 611; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 584; e.underscore = 556; e.quoteleft = 278; e.a = 556; e.b = 611; e.c = 556; e.d = 611; e.e = 556; e.f = 333; e.g = 611; e.h = 611; e.i = 278; e.j = 278; e.k = 556; e.l = 278; e.m = 889; e.n = 611; e.o = 611; e.p = 611; e.q = 611; e.r = 389; e.s = 556; e.t = 333; e.u = 611; e.v = 556; e.w = 778; e.x = 556; e.y = 556; e.z = 500; e.braceleft = 389; e.bar = 280; e.braceright = 389; e.asciitilde = 584; e.exclamdown = 333; e.cent = 556; e.sterling = 556; e.fraction = 167; e.yen = 556; e.florin = 556; e.section = 556; e.currency = 556; e.quotesingle = 238; e.quotedblleft = 500; e.guillemotleft = 556; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 611; e.fl = 611; e.endash = 556; e.dagger = 556; e.daggerdbl = 556; e.periodcentered = 278; e.paragraph = 556; e.bullet = 350; e.quotesinglbase = 278; e.quotedblbase = 500; e.quotedblright = 500; e.guillemotright = 556; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 611; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 370; e.Lslash = 611; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 365; e.ae = 889; e.dotlessi = 278; e.lslash = 278; e.oslash = 611; e.oe = 944; e.germandbls = 611; e.Idieresis = 278; e.eacute = 556; e.abreve = 556; e.uhungarumlaut = 611; e.ecaron = 556; e.Ydieresis = 667; e.divide = 584; e.Yacute = 667; e.Acircumflex = 722; e.aacute = 556; e.Ucircumflex = 722; e.yacute = 556; e.scommaaccent = 556; e.ecircumflex = 556; e.Uring = 722; e.Udieresis = 722; e.aogonek = 556; e.Uacute = 722; e.uogonek = 611; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 737; e.Emacron = 667; e.ccaron = 556; e.aring = 556; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 556; e.Tcommaaccent = 611; e.Cacute = 722; e.atilde = 556; e.Edotaccent = 667; e.scaron = 556; e.scedilla = 556; e.iacute = 278; e.lozenge = 494; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 611; e.acircumflex = 556; e.Amacron = 722; e.rcaron = 389; e.ccedilla = 556; e.Zdotaccent = 611; e.Thorn = 667; e.Omacron = 778; e.Racute = 722; e.Sacute = 667; e.dcaron = 743; e.Umacron = 722; e.uring = 611; e.threesuperior = 333; e.Ograve = 778; e.Agrave = 722; e.Abreve = 722; e.multiply = 584; e.uacute = 611; e.Tcaron = 611; e.partialdiff = 494; e.ydieresis = 556; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 556; e.edieresis = 556; e.cacute = 556; e.nacute = 611; e.umacron = 611; e.Ncaron = 722; e.Iacute = 278; e.plusminus = 584; e.brokenbar = 280; e.registered = 737; e.Gbreve = 778; e.Idotaccent = 278; e.summation = 600; e.Egrave = 667; e.racute = 389; e.omacron = 611; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 278; e.tcaron = 389; e.eogonek = 556; e.Uogonek = 722; e.Aacute = 722; e.Adieresis = 722; e.egrave = 556; e.zacute = 500; e.iogonek = 278; e.Oacute = 778; e.oacute = 611; e.amacron = 556; e.sacute = 556; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 611; e.twosuperior = 333; e.Odieresis = 778; e.mu = 611; e.igrave = 278; e.ohungarumlaut = 611; e.Eogonek = 667; e.dcroat = 611; e.threequarters = 834; e.Scedilla = 667; e.lcaron = 400; e.Kcommaaccent = 722; e.Lacute = 611; e.trademark = 1e3; e.edotaccent = 556; e.Igrave = 278; e.Imacron = 278; e.Lcaron = 611; e.onehalf = 834; e.lessequal = 549; e.ocircumflex = 611; e.ntilde = 611; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 556; e.gbreve = 611; e.onequarter = 834; e.Scaron = 667; e.Scommaaccent = 667; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 611; e.Ccaron = 722; e.ugrave = 611; e.radical = 549; e.Dcaron = 722; e.rcommaaccent = 389; e.Ntilde = 722; e.otilde = 611; e.Rcommaaccent = 722; e.Lcommaaccent = 611; e.Atilde = 722; e.Aogonek = 722; e.Aring = 722; e.Otilde = 778; e.zdotaccent = 500; e.Ecaron = 667; e.Iogonek = 278; e.kcommaaccent = 556; e.minus = 584; e.Icircumflex = 278; e.ncaron = 611; e.tcommaaccent = 333; e.logicalnot = 584; e.odieresis = 611; e.udieresis = 611; e.notequal = 549; e.gcommaaccent = 611; e.eth = 611; e.zcaron = 500; e.ncommaaccent = 611; e.onesuperior = 333; e.imacron = 278; e.Euro = 556 })); e["Helvetica-BoldOblique"] = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.exclam = 333; e.quotedbl = 474; e.numbersign = 556; e.dollar = 556; e.percent = 889; e.ampersand = 722; e.quoteright = 278; e.parenleft = 333; e.parenright = 333; e.asterisk = 389; e.plus = 584; e.comma = 278; e.hyphen = 333; e.period = 278; e.slash = 278; e.zero = 556; e.one = 556; e.two = 556; e.three = 556; e.four = 556; e.five = 556; e.six = 556; e.seven = 556; e.eight = 556; e.nine = 556; e.colon = 333; e.semicolon = 333; e.less = 584; e.equal = 584; e.greater = 584; e.question = 611; e.at = 975; e.A = 722; e.B = 722; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 722; e.I = 278; e.J = 556; e.K = 722; e.L = 611; e.M = 833; e.N = 722; e.O = 778; e.P = 667; e.Q = 778; e.R = 722; e.S = 667; e.T = 611; e.U = 722; e.V = 667; e.W = 944; e.X = 667; e.Y = 667; e.Z = 611; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 584; e.underscore = 556; e.quoteleft = 278; e.a = 556; e.b = 611; e.c = 556; e.d = 611; e.e = 556; e.f = 333; e.g = 611; e.h = 611; e.i = 278; e.j = 278; e.k = 556; e.l = 278; e.m = 889; e.n = 611; e.o = 611; e.p = 611; e.q = 611; e.r = 389; e.s = 556; e.t = 333; e.u = 611; e.v = 556; e.w = 778; e.x = 556; e.y = 556; e.z = 500; e.braceleft = 389; e.bar = 280; e.braceright = 389; e.asciitilde = 584; e.exclamdown = 333; e.cent = 556; e.sterling = 556; e.fraction = 167; e.yen = 556; e.florin = 556; e.section = 556; e.currency = 556; e.quotesingle = 238; e.quotedblleft = 500; e.guillemotleft = 556; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 611; e.fl = 611; e.endash = 556; e.dagger = 556; e.daggerdbl = 556; e.periodcentered = 278; e.paragraph = 556; e.bullet = 350; e.quotesinglbase = 278; e.quotedblbase = 500; e.quotedblright = 500; e.guillemotright = 556; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 611; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 370; e.Lslash = 611; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 365; e.ae = 889; e.dotlessi = 278; e.lslash = 278; e.oslash = 611; e.oe = 944; e.germandbls = 611; e.Idieresis = 278; e.eacute = 556; e.abreve = 556; e.uhungarumlaut = 611; e.ecaron = 556; e.Ydieresis = 667; e.divide = 584; e.Yacute = 667; e.Acircumflex = 722; e.aacute = 556; e.Ucircumflex = 722; e.yacute = 556; e.scommaaccent = 556; e.ecircumflex = 556; e.Uring = 722; e.Udieresis = 722; e.aogonek = 556; e.Uacute = 722; e.uogonek = 611; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 737; e.Emacron = 667; e.ccaron = 556; e.aring = 556; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 556; e.Tcommaaccent = 611; e.Cacute = 722; e.atilde = 556; e.Edotaccent = 667; e.scaron = 556; e.scedilla = 556; e.iacute = 278; e.lozenge = 494; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 611; e.acircumflex = 556; e.Amacron = 722; e.rcaron = 389; e.ccedilla = 556; e.Zdotaccent = 611; e.Thorn = 667; e.Omacron = 778; e.Racute = 722; e.Sacute = 667; e.dcaron = 743; e.Umacron = 722; e.uring = 611; e.threesuperior = 333; e.Ograve = 778; e.Agrave = 722; e.Abreve = 722; e.multiply = 584; e.uacute = 611; e.Tcaron = 611; e.partialdiff = 494; e.ydieresis = 556; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 556; e.edieresis = 556; e.cacute = 556; e.nacute = 611; e.umacron = 611; e.Ncaron = 722; e.Iacute = 278; e.plusminus = 584; e.brokenbar = 280; e.registered = 737; e.Gbreve = 778; e.Idotaccent = 278; e.summation = 600; e.Egrave = 667; e.racute = 389; e.omacron = 611; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 278; e.tcaron = 389; e.eogonek = 556; e.Uogonek = 722; e.Aacute = 722; e.Adieresis = 722; e.egrave = 556; e.zacute = 500; e.iogonek = 278; e.Oacute = 778; e.oacute = 611; e.amacron = 556; e.sacute = 556; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 611; e.twosuperior = 333; e.Odieresis = 778; e.mu = 611; e.igrave = 278; e.ohungarumlaut = 611; e.Eogonek = 667; e.dcroat = 611; e.threequarters = 834; e.Scedilla = 667; e.lcaron = 400; e.Kcommaaccent = 722; e.Lacute = 611; e.trademark = 1e3; e.edotaccent = 556; e.Igrave = 278; e.Imacron = 278; e.Lcaron = 611; e.onehalf = 834; e.lessequal = 549; e.ocircumflex = 611; e.ntilde = 611; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 556; e.gbreve = 611; e.onequarter = 834; e.Scaron = 667; e.Scommaaccent = 667; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 611; e.Ccaron = 722; e.ugrave = 611; e.radical = 549; e.Dcaron = 722; e.rcommaaccent = 389; e.Ntilde = 722; e.otilde = 611; e.Rcommaaccent = 722; e.Lcommaaccent = 611; e.Atilde = 722; e.Aogonek = 722; e.Aring = 722; e.Otilde = 778; e.zdotaccent = 500; e.Ecaron = 667; e.Iogonek = 278; e.kcommaaccent = 556; e.minus = 584; e.Icircumflex = 278; e.ncaron = 611; e.tcommaaccent = 333; e.logicalnot = 584; e.odieresis = 611; e.udieresis = 611; e.notequal = 549; e.gcommaaccent = 611; e.eth = 611; e.zcaron = 500; e.ncommaaccent = 611; e.onesuperior = 333; e.imacron = 278; e.Euro = 556 })); e["Helvetica-Oblique"] = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.exclam = 278; e.quotedbl = 355; e.numbersign = 556; e.dollar = 556; e.percent = 889; e.ampersand = 667; e.quoteright = 222; e.parenleft = 333; e.parenright = 333; e.asterisk = 389; e.plus = 584; e.comma = 278; e.hyphen = 333; e.period = 278; e.slash = 278; e.zero = 556; e.one = 556; e.two = 556; e.three = 556; e.four = 556; e.five = 556; e.six = 556; e.seven = 556; e.eight = 556; e.nine = 556; e.colon = 278; e.semicolon = 278; e.less = 584; e.equal = 584; e.greater = 584; e.question = 556; e.at = 1015; e.A = 667; e.B = 667; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 722; e.I = 278; e.J = 500; e.K = 667; e.L = 556; e.M = 833; e.N = 722; e.O = 778; e.P = 667; e.Q = 778; e.R = 722; e.S = 667; e.T = 611; e.U = 722; e.V = 667; e.W = 944; e.X = 667; e.Y = 667; e.Z = 611; e.bracketleft = 278; e.backslash = 278; e.bracketright = 278; e.asciicircum = 469; e.underscore = 556; e.quoteleft = 222; e.a = 556; e.b = 556; e.c = 500; e.d = 556; e.e = 556; e.f = 278; e.g = 556; e.h = 556; e.i = 222; e.j = 222; e.k = 500; e.l = 222; e.m = 833; e.n = 556; e.o = 556; e.p = 556; e.q = 556; e.r = 333; e.s = 500; e.t = 278; e.u = 556; e.v = 500; e.w = 722; e.x = 500; e.y = 500; e.z = 500; e.braceleft = 334; e.bar = 260; e.braceright = 334; e.asciitilde = 584; e.exclamdown = 333; e.cent = 556; e.sterling = 556; e.fraction = 167; e.yen = 556; e.florin = 556; e.section = 556; e.currency = 556; e.quotesingle = 191; e.quotedblleft = 333; e.guillemotleft = 556; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 500; e.fl = 500; e.endash = 556; e.dagger = 556; e.daggerdbl = 556; e.periodcentered = 278; e.paragraph = 537; e.bullet = 350; e.quotesinglbase = 222; e.quotedblbase = 333; e.quotedblright = 333; e.guillemotright = 556; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 611; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 370; e.Lslash = 556; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 365; e.ae = 889; e.dotlessi = 278; e.lslash = 222; e.oslash = 611; e.oe = 944; e.germandbls = 611; e.Idieresis = 278; e.eacute = 556; e.abreve = 556; e.uhungarumlaut = 556; e.ecaron = 556; e.Ydieresis = 667; e.divide = 584; e.Yacute = 667; e.Acircumflex = 667; e.aacute = 556; e.Ucircumflex = 722; e.yacute = 500; e.scommaaccent = 500; e.ecircumflex = 556; e.Uring = 722; e.Udieresis = 722; e.aogonek = 556; e.Uacute = 722; e.uogonek = 556; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 737; e.Emacron = 667; e.ccaron = 500; e.aring = 556; e.Ncommaaccent = 722; e.lacute = 222; e.agrave = 556; e.Tcommaaccent = 611; e.Cacute = 722; e.atilde = 556; e.Edotaccent = 667; e.scaron = 500; e.scedilla = 500; e.iacute = 278; e.lozenge = 471; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 556; e.acircumflex = 556; e.Amacron = 667; e.rcaron = 333; e.ccedilla = 500; e.Zdotaccent = 611; e.Thorn = 667; e.Omacron = 778; e.Racute = 722; e.Sacute = 667; e.dcaron = 643; e.Umacron = 722; e.uring = 556; e.threesuperior = 333; e.Ograve = 778; e.Agrave = 667; e.Abreve = 667; e.multiply = 584; e.uacute = 556; e.Tcaron = 611; e.partialdiff = 476; e.ydieresis = 500; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 556; e.edieresis = 556; e.cacute = 500; e.nacute = 556; e.umacron = 556; e.Ncaron = 722; e.Iacute = 278; e.plusminus = 584; e.brokenbar = 260; e.registered = 737; e.Gbreve = 778; e.Idotaccent = 278; e.summation = 600; e.Egrave = 667; e.racute = 333; e.omacron = 556; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 222; e.tcaron = 317; e.eogonek = 556; e.Uogonek = 722; e.Aacute = 667; e.Adieresis = 667; e.egrave = 556; e.zacute = 500; e.iogonek = 222; e.Oacute = 778; e.oacute = 556; e.amacron = 556; e.sacute = 500; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 556; e.twosuperior = 333; e.Odieresis = 778; e.mu = 556; e.igrave = 278; e.ohungarumlaut = 556; e.Eogonek = 667; e.dcroat = 556; e.threequarters = 834; e.Scedilla = 667; e.lcaron = 299; e.Kcommaaccent = 667; e.Lacute = 556; e.trademark = 1e3; e.edotaccent = 556; e.Igrave = 278; e.Imacron = 278; e.Lcaron = 556; e.onehalf = 834; e.lessequal = 549; e.ocircumflex = 556; e.ntilde = 556; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 556; e.gbreve = 556; e.onequarter = 834; e.Scaron = 667; e.Scommaaccent = 667; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 556; e.Ccaron = 722; e.ugrave = 556; e.radical = 453; e.Dcaron = 722; e.rcommaaccent = 333; e.Ntilde = 722; e.otilde = 556; e.Rcommaaccent = 722; e.Lcommaaccent = 556; e.Atilde = 667; e.Aogonek = 667; e.Aring = 667; e.Otilde = 778; e.zdotaccent = 500; e.Ecaron = 667; e.Iogonek = 278; e.kcommaaccent = 500; e.minus = 584; e.Icircumflex = 278; e.ncaron = 556; e.tcommaaccent = 278; e.logicalnot = 584; e.odieresis = 556; e.udieresis = 556; e.notequal = 549; e.gcommaaccent = 556; e.eth = 556; e.zcaron = 500; e.ncommaaccent = 556; e.onesuperior = 333; e.imacron = 278; e.Euro = 556 })); e.Symbol = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 333; e.universal = 713; e.numbersign = 500; e.existential = 549; e.percent = 833; e.ampersand = 778; e.suchthat = 439; e.parenleft = 333; e.parenright = 333; e.asteriskmath = 500; e.plus = 549; e.comma = 250; e.minus = 549; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 278; e.semicolon = 278; e.less = 549; e.equal = 549; e.greater = 549; e.question = 444; e.congruent = 549; e.Alpha = 722; e.Beta = 667; e.Chi = 722; e.Delta = 612; e.Epsilon = 611; e.Phi = 763; e.Gamma = 603; e.Eta = 722; e.Iota = 333; e.theta1 = 631; e.Kappa = 722; e.Lambda = 686; e.Mu = 889; e.Nu = 722; e.Omicron = 722; e.Pi = 768; e.Theta = 741; e.Rho = 556; e.Sigma = 592; e.Tau = 611; e.Upsilon = 690; e.sigma1 = 439; e.Omega = 768; e.Xi = 645; e.Psi = 795; e.Zeta = 611; e.bracketleft = 333; e.therefore = 863; e.bracketright = 333; e.perpendicular = 658; e.underscore = 500; e.radicalex = 500; e.alpha = 631; e.beta = 549; e.chi = 549; e.delta = 494; e.epsilon = 439; e.phi = 521; e.gamma = 411; e.eta = 603; e.iota = 329; e.phi1 = 603; e.kappa = 549; e.lambda = 549; e.mu = 576; e.nu = 521; e.omicron = 549; e.pi = 549; e.theta = 521; e.rho = 549; e.sigma = 603; e.tau = 439; e.upsilon = 576; e.omega1 = 713; e.omega = 686; e.xi = 493; e.psi = 686; e.zeta = 494; e.braceleft = 480; e.bar = 200; e.braceright = 480; e.similar = 549; e.Euro = 750; e.Upsilon1 = 620; e.minute = 247; e.lessequal = 549; e.fraction = 167; e.infinity = 713; e.florin = 500; e.club = 753; e.diamond = 753; e.heart = 753; e.spade = 753; e.arrowboth = 1042; e.arrowleft = 987; e.arrowup = 603; e.arrowright = 987; e.arrowdown = 603; e.degree = 400; e.plusminus = 549; e.second = 411; e.greaterequal = 549; e.multiply = 549; e.proportional = 713; e.partialdiff = 494; e.bullet = 460; e.divide = 549; e.notequal = 549; e.equivalence = 549; e.approxequal = 549; e.ellipsis = 1e3; e.arrowvertex = 603; e.arrowhorizex = 1e3; e.carriagereturn = 658; e.aleph = 823; e.Ifraktur = 686; e.Rfraktur = 795; e.weierstrass = 987; e.circlemultiply = 768; e.circleplus = 768; e.emptyset = 823; e.intersection = 768; e.union = 768; e.propersuperset = 713; e.reflexsuperset = 713; e.notsubset = 713; e.propersubset = 713; e.reflexsubset = 713; e.element = 713; e.notelement = 713; e.angle = 768; e.gradient = 713; e.registerserif = 790; e.copyrightserif = 790; e.trademarkserif = 890; e.product = 823; e.radical = 549; e.dotmath = 250; e.logicalnot = 713; e.logicaland = 603; e.logicalor = 603; e.arrowdblboth = 1042; e.arrowdblleft = 987; e.arrowdblup = 603; e.arrowdblright = 987; e.arrowdbldown = 603; e.lozenge = 494; e.angleleft = 329; e.registersans = 790; e.copyrightsans = 790; e.trademarksans = 786; e.summation = 713; e.parenlefttp = 384; e.parenleftex = 384; e.parenleftbt = 384; e.bracketlefttp = 384; e.bracketleftex = 384; e.bracketleftbt = 384; e.bracelefttp = 494; e.braceleftmid = 494; e.braceleftbt = 494; e.braceex = 494; e.angleright = 329; e.integral = 274; e.integraltp = 686; e.integralex = 686; e.integralbt = 686; e.parenrighttp = 384; e.parenrightex = 384; e.parenrightbt = 384; e.bracketrighttp = 384; e.bracketrightex = 384; e.bracketrightbt = 384; e.bracerighttp = 494; e.bracerightmid = 494; e.bracerightbt = 494; e.apple = 790 })); e["Times-Roman"] = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 333; e.quotedbl = 408; e.numbersign = 500; e.dollar = 500; e.percent = 833; e.ampersand = 778; e.quoteright = 333; e.parenleft = 333; e.parenright = 333; e.asterisk = 500; e.plus = 564; e.comma = 250; e.hyphen = 333; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 278; e.semicolon = 278; e.less = 564; e.equal = 564; e.greater = 564; e.question = 444; e.at = 921; e.A = 722; e.B = 667; e.C = 667; e.D = 722; e.E = 611; e.F = 556; e.G = 722; e.H = 722; e.I = 333; e.J = 389; e.K = 722; e.L = 611; e.M = 889; e.N = 722; e.O = 722; e.P = 556; e.Q = 722; e.R = 667; e.S = 556; e.T = 611; e.U = 722; e.V = 722; e.W = 944; e.X = 722; e.Y = 722; e.Z = 611; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 469; e.underscore = 500; e.quoteleft = 333; e.a = 444; e.b = 500; e.c = 444; e.d = 500; e.e = 444; e.f = 333; e.g = 500; e.h = 500; e.i = 278; e.j = 278; e.k = 500; e.l = 278; e.m = 778; e.n = 500; e.o = 500; e.p = 500; e.q = 500; e.r = 333; e.s = 389; e.t = 278; e.u = 500; e.v = 500; e.w = 722; e.x = 500; e.y = 500; e.z = 444; e.braceleft = 480; e.bar = 200; e.braceright = 480; e.asciitilde = 541; e.exclamdown = 333; e.cent = 500; e.sterling = 500; e.fraction = 167; e.yen = 500; e.florin = 500; e.section = 500; e.currency = 500; e.quotesingle = 180; e.quotedblleft = 444; e.guillemotleft = 500; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 556; e.fl = 556; e.endash = 500; e.dagger = 500; e.daggerdbl = 500; e.periodcentered = 250; e.paragraph = 453; e.bullet = 350; e.quotesinglbase = 333; e.quotedblbase = 444; e.quotedblright = 444; e.guillemotright = 500; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 444; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 889; e.ordfeminine = 276; e.Lslash = 611; e.Oslash = 722; e.OE = 889; e.ordmasculine = 310; e.ae = 667; e.dotlessi = 278; e.lslash = 278; e.oslash = 500; e.oe = 722; e.germandbls = 500; e.Idieresis = 333; e.eacute = 444; e.abreve = 444; e.uhungarumlaut = 500; e.ecaron = 444; e.Ydieresis = 722; e.divide = 564; e.Yacute = 722; e.Acircumflex = 722; e.aacute = 444; e.Ucircumflex = 722; e.yacute = 500; e.scommaaccent = 389; e.ecircumflex = 444; e.Uring = 722; e.Udieresis = 722; e.aogonek = 444; e.Uacute = 722; e.uogonek = 500; e.Edieresis = 611; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 760; e.Emacron = 611; e.ccaron = 444; e.aring = 444; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 444; e.Tcommaaccent = 611; e.Cacute = 667; e.atilde = 444; e.Edotaccent = 611; e.scaron = 389; e.scedilla = 389; e.iacute = 278; e.lozenge = 471; e.Rcaron = 667; e.Gcommaaccent = 722; e.ucircumflex = 500; e.acircumflex = 444; e.Amacron = 722; e.rcaron = 333; e.ccedilla = 444; e.Zdotaccent = 611; e.Thorn = 556; e.Omacron = 722; e.Racute = 667; e.Sacute = 556; e.dcaron = 588; e.Umacron = 722; e.uring = 500; e.threesuperior = 300; e.Ograve = 722; e.Agrave = 722; e.Abreve = 722; e.multiply = 564; e.uacute = 500; e.Tcaron = 611; e.partialdiff = 476; e.ydieresis = 500; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 611; e.adieresis = 444; e.edieresis = 444; e.cacute = 444; e.nacute = 500; e.umacron = 500; e.Ncaron = 722; e.Iacute = 333; e.plusminus = 564; e.brokenbar = 200; e.registered = 760; e.Gbreve = 722; e.Idotaccent = 333; e.summation = 600; e.Egrave = 611; e.racute = 333; e.omacron = 500; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 667; e.lcommaaccent = 278; e.tcaron = 326; e.eogonek = 444; e.Uogonek = 722; e.Aacute = 722; e.Adieresis = 722; e.egrave = 444; e.zacute = 444; e.iogonek = 278; e.Oacute = 722; e.oacute = 500; e.amacron = 444; e.sacute = 389; e.idieresis = 278; e.Ocircumflex = 722; e.Ugrave = 722; e.Delta = 612; e.thorn = 500; e.twosuperior = 300; e.Odieresis = 722; e.mu = 500; e.igrave = 278; e.ohungarumlaut = 500; e.Eogonek = 611; e.dcroat = 500; e.threequarters = 750; e.Scedilla = 556; e.lcaron = 344; e.Kcommaaccent = 722; e.Lacute = 611; e.trademark = 980; e.edotaccent = 444; e.Igrave = 333; e.Imacron = 333; e.Lcaron = 611; e.onehalf = 750; e.lessequal = 549; e.ocircumflex = 500; e.ntilde = 500; e.Uhungarumlaut = 722; e.Eacute = 611; e.emacron = 444; e.gbreve = 500; e.onequarter = 750; e.Scaron = 556; e.Scommaaccent = 556; e.Ohungarumlaut = 722; e.degree = 400; e.ograve = 500; e.Ccaron = 667; e.ugrave = 500; e.radical = 453; e.Dcaron = 722; e.rcommaaccent = 333; e.Ntilde = 722; e.otilde = 500; e.Rcommaaccent = 667; e.Lcommaaccent = 611; e.Atilde = 722; e.Aogonek = 722; e.Aring = 722; e.Otilde = 722; e.zdotaccent = 444; e.Ecaron = 611; e.Iogonek = 333; e.kcommaaccent = 500; e.minus = 564; e.Icircumflex = 333; e.ncaron = 500; e.tcommaaccent = 278; e.logicalnot = 564; e.odieresis = 500; e.udieresis = 500; e.notequal = 549; e.gcommaaccent = 500; e.eth = 500; e.zcaron = 444; e.ncommaaccent = 500; e.onesuperior = 300; e.imacron = 278; e.Euro = 500 })); e["Times-Bold"] = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 333; e.quotedbl = 555; e.numbersign = 500; e.dollar = 500; e.percent = 1e3; e.ampersand = 833; e.quoteright = 333; e.parenleft = 333; e.parenright = 333; e.asterisk = 500; e.plus = 570; e.comma = 250; e.hyphen = 333; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 333; e.semicolon = 333; e.less = 570; e.equal = 570; e.greater = 570; e.question = 500; e.at = 930; e.A = 722; e.B = 667; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 778; e.I = 389; e.J = 500; e.K = 778; e.L = 667; e.M = 944; e.N = 722; e.O = 778; e.P = 611; e.Q = 778; e.R = 722; e.S = 556; e.T = 667; e.U = 722; e.V = 722; e.W = 1e3; e.X = 722; e.Y = 722; e.Z = 667; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 581; e.underscore = 500; e.quoteleft = 333; e.a = 500; e.b = 556; e.c = 444; e.d = 556; e.e = 444; e.f = 333; e.g = 500; e.h = 556; e.i = 278; e.j = 333; e.k = 556; e.l = 278; e.m = 833; e.n = 556; e.o = 500; e.p = 556; e.q = 556; e.r = 444; e.s = 389; e.t = 333; e.u = 556; e.v = 500; e.w = 722; e.x = 500; e.y = 500; e.z = 444; e.braceleft = 394; e.bar = 220; e.braceright = 394; e.asciitilde = 520; e.exclamdown = 333; e.cent = 500; e.sterling = 500; e.fraction = 167; e.yen = 500; e.florin = 500; e.section = 500; e.currency = 500; e.quotesingle = 278; e.quotedblleft = 500; e.guillemotleft = 500; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 556; e.fl = 556; e.endash = 500; e.dagger = 500; e.daggerdbl = 500; e.periodcentered = 250; e.paragraph = 540; e.bullet = 350; e.quotesinglbase = 333; e.quotedblbase = 500; e.quotedblright = 500; e.guillemotright = 500; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 500; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 300; e.Lslash = 667; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 330; e.ae = 722; e.dotlessi = 278; e.lslash = 278; e.oslash = 500; e.oe = 722; e.germandbls = 556; e.Idieresis = 389; e.eacute = 444; e.abreve = 500; e.uhungarumlaut = 556; e.ecaron = 444; e.Ydieresis = 722; e.divide = 570; e.Yacute = 722; e.Acircumflex = 722; e.aacute = 500; e.Ucircumflex = 722; e.yacute = 500; e.scommaaccent = 389; e.ecircumflex = 444; e.Uring = 722; e.Udieresis = 722; e.aogonek = 500; e.Uacute = 722; e.uogonek = 556; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 747; e.Emacron = 667; e.ccaron = 444; e.aring = 500; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 500; e.Tcommaaccent = 667; e.Cacute = 722; e.atilde = 500; e.Edotaccent = 667; e.scaron = 389; e.scedilla = 389; e.iacute = 278; e.lozenge = 494; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 556; e.acircumflex = 500; e.Amacron = 722; e.rcaron = 444; e.ccedilla = 444; e.Zdotaccent = 667; e.Thorn = 611; e.Omacron = 778; e.Racute = 722; e.Sacute = 556; e.dcaron = 672; e.Umacron = 722; e.uring = 556; e.threesuperior = 300; e.Ograve = 778; e.Agrave = 722; e.Abreve = 722; e.multiply = 570; e.uacute = 556; e.Tcaron = 667; e.partialdiff = 494; e.ydieresis = 500; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 500; e.edieresis = 444; e.cacute = 444; e.nacute = 556; e.umacron = 556; e.Ncaron = 722; e.Iacute = 389; e.plusminus = 570; e.brokenbar = 220; e.registered = 747; e.Gbreve = 778; e.Idotaccent = 389; e.summation = 600; e.Egrave = 667; e.racute = 444; e.omacron = 500; e.Zacute = 667; e.Zcaron = 667; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 278; e.tcaron = 416; e.eogonek = 444; e.Uogonek = 722; e.Aacute = 722; e.Adieresis = 722; e.egrave = 444; e.zacute = 444; e.iogonek = 278; e.Oacute = 778; e.oacute = 500; e.amacron = 500; e.sacute = 389; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 556; e.twosuperior = 300; e.Odieresis = 778; e.mu = 556; e.igrave = 278; e.ohungarumlaut = 500; e.Eogonek = 667; e.dcroat = 556; e.threequarters = 750; e.Scedilla = 556; e.lcaron = 394; e.Kcommaaccent = 778; e.Lacute = 667; e.trademark = 1e3; e.edotaccent = 444; e.Igrave = 389; e.Imacron = 389; e.Lcaron = 667; e.onehalf = 750; e.lessequal = 549; e.ocircumflex = 500; e.ntilde = 556; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 444; e.gbreve = 500; e.onequarter = 750; e.Scaron = 556; e.Scommaaccent = 556; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 500; e.Ccaron = 722; e.ugrave = 556; e.radical = 549; e.Dcaron = 722; e.rcommaaccent = 444; e.Ntilde = 722; e.otilde = 500; e.Rcommaaccent = 722; e.Lcommaaccent = 667; e.Atilde = 722; e.Aogonek = 722; e.Aring = 722; e.Otilde = 778; e.zdotaccent = 444; e.Ecaron = 667; e.Iogonek = 389; e.kcommaaccent = 556; e.minus = 570; e.Icircumflex = 389; e.ncaron = 556; e.tcommaaccent = 333; e.logicalnot = 570; e.odieresis = 500; e.udieresis = 556; e.notequal = 549; e.gcommaaccent = 500; e.eth = 500; e.zcaron = 444; e.ncommaaccent = 556; e.onesuperior = 300; e.imacron = 278; e.Euro = 500 })); e["Times-BoldItalic"] = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 389; e.quotedbl = 555; e.numbersign = 500; e.dollar = 500; e.percent = 833; e.ampersand = 778; e.quoteright = 333; e.parenleft = 333; e.parenright = 333; e.asterisk = 500; e.plus = 570; e.comma = 250; e.hyphen = 333; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 333; e.semicolon = 333; e.less = 570; e.equal = 570; e.greater = 570; e.question = 500; e.at = 832; e.A = 667; e.B = 667; e.C = 667; e.D = 722; e.E = 667; e.F = 667; e.G = 722; e.H = 778; e.I = 389; e.J = 500; e.K = 667; e.L = 611; e.M = 889; e.N = 722; e.O = 722; e.P = 611; e.Q = 722; e.R = 667; e.S = 556; e.T = 611; e.U = 722; e.V = 667; e.W = 889; e.X = 667; e.Y = 611; e.Z = 611; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 570; e.underscore = 500; e.quoteleft = 333; e.a = 500; e.b = 500; e.c = 444; e.d = 500; e.e = 444; e.f = 333; e.g = 500; e.h = 556; e.i = 278; e.j = 278; e.k = 500; e.l = 278; e.m = 778; e.n = 556; e.o = 500; e.p = 500; e.q = 500; e.r = 389; e.s = 389; e.t = 278; e.u = 556; e.v = 444; e.w = 667; e.x = 500; e.y = 444; e.z = 389; e.braceleft = 348; e.bar = 220; e.braceright = 348; e.asciitilde = 570; e.exclamdown = 389; e.cent = 500; e.sterling = 500; e.fraction = 167; e.yen = 500; e.florin = 500; e.section = 500; e.currency = 500; e.quotesingle = 278; e.quotedblleft = 500; e.guillemotleft = 500; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 556; e.fl = 556; e.endash = 500; e.dagger = 500; e.daggerdbl = 500; e.periodcentered = 250; e.paragraph = 500; e.bullet = 350; e.quotesinglbase = 333; e.quotedblbase = 500; e.quotedblright = 500; e.guillemotright = 500; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 500; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 944; e.ordfeminine = 266; e.Lslash = 611; e.Oslash = 722; e.OE = 944; e.ordmasculine = 300; e.ae = 722; e.dotlessi = 278; e.lslash = 278; e.oslash = 500; e.oe = 722; e.germandbls = 500; e.Idieresis = 389; e.eacute = 444; e.abreve = 500; e.uhungarumlaut = 556; e.ecaron = 444; e.Ydieresis = 611; e.divide = 570; e.Yacute = 611; e.Acircumflex = 667; e.aacute = 500; e.Ucircumflex = 722; e.yacute = 444; e.scommaaccent = 389; e.ecircumflex = 444; e.Uring = 722; e.Udieresis = 722; e.aogonek = 500; e.Uacute = 722; e.uogonek = 556; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 747; e.Emacron = 667; e.ccaron = 444; e.aring = 500; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 500; e.Tcommaaccent = 611; e.Cacute = 667; e.atilde = 500; e.Edotaccent = 667; e.scaron = 389; e.scedilla = 389; e.iacute = 278; e.lozenge = 494; e.Rcaron = 667; e.Gcommaaccent = 722; e.ucircumflex = 556; e.acircumflex = 500; e.Amacron = 667; e.rcaron = 389; e.ccedilla = 444; e.Zdotaccent = 611; e.Thorn = 611; e.Omacron = 722; e.Racute = 667; e.Sacute = 556; e.dcaron = 608; e.Umacron = 722; e.uring = 556; e.threesuperior = 300; e.Ograve = 722; e.Agrave = 667; e.Abreve = 667; e.multiply = 570; e.uacute = 556; e.Tcaron = 611; e.partialdiff = 494; e.ydieresis = 444; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 500; e.edieresis = 444; e.cacute = 444; e.nacute = 556; e.umacron = 556; e.Ncaron = 722; e.Iacute = 389; e.plusminus = 570; e.brokenbar = 220; e.registered = 747; e.Gbreve = 722; e.Idotaccent = 389; e.summation = 600; e.Egrave = 667; e.racute = 389; e.omacron = 500; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 667; e.lcommaaccent = 278; e.tcaron = 366; e.eogonek = 444; e.Uogonek = 722; e.Aacute = 667; e.Adieresis = 667; e.egrave = 444; e.zacute = 389; e.iogonek = 278; e.Oacute = 722; e.oacute = 500; e.amacron = 500; e.sacute = 389; e.idieresis = 278; e.Ocircumflex = 722; e.Ugrave = 722; e.Delta = 612; e.thorn = 500; e.twosuperior = 300; e.Odieresis = 722; e.mu = 576; e.igrave = 278; e.ohungarumlaut = 500; e.Eogonek = 667; e.dcroat = 500; e.threequarters = 750; e.Scedilla = 556; e.lcaron = 382; e.Kcommaaccent = 667; e.Lacute = 611; e.trademark = 1e3; e.edotaccent = 444; e.Igrave = 389; e.Imacron = 389; e.Lcaron = 611; e.onehalf = 750; e.lessequal = 549; e.ocircumflex = 500; e.ntilde = 556; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 444; e.gbreve = 500; e.onequarter = 750; e.Scaron = 556; e.Scommaaccent = 556; e.Ohungarumlaut = 722; e.degree = 400; e.ograve = 500; e.Ccaron = 667; e.ugrave = 556; e.radical = 549; e.Dcaron = 722; e.rcommaaccent = 389; e.Ntilde = 722; e.otilde = 500; e.Rcommaaccent = 667; e.Lcommaaccent = 611; e.Atilde = 667; e.Aogonek = 667; e.Aring = 667; e.Otilde = 722; e.zdotaccent = 389; e.Ecaron = 667; e.Iogonek = 389; e.kcommaaccent = 500; e.minus = 606; e.Icircumflex = 389; e.ncaron = 556; e.tcommaaccent = 278; e.logicalnot = 606; e.odieresis = 500; e.udieresis = 556; e.notequal = 549; e.gcommaaccent = 500; e.eth = 500; e.zcaron = 389; e.ncommaaccent = 556; e.onesuperior = 300; e.imacron = 278; e.Euro = 500 })); e["Times-Italic"] = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 333; e.quotedbl = 420; e.numbersign = 500; e.dollar = 500; e.percent = 833; e.ampersand = 778; e.quoteright = 333; e.parenleft = 333; e.parenright = 333; e.asterisk = 500; e.plus = 675; e.comma = 250; e.hyphen = 333; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 333; e.semicolon = 333; e.less = 675; e.equal = 675; e.greater = 675; e.question = 500; e.at = 920; e.A = 611; e.B = 611; e.C = 667; e.D = 722; e.E = 611; e.F = 611; e.G = 722; e.H = 722; e.I = 333; e.J = 444; e.K = 667; e.L = 556; e.M = 833; e.N = 667; e.O = 722; e.P = 611; e.Q = 722; e.R = 611; e.S = 500; e.T = 556; e.U = 722; e.V = 611; e.W = 833; e.X = 611; e.Y = 556; e.Z = 556; e.bracketleft = 389; e.backslash = 278; e.bracketright = 389; e.asciicircum = 422; e.underscore = 500; e.quoteleft = 333; e.a = 500; e.b = 500; e.c = 444; e.d = 500; e.e = 444; e.f = 278; e.g = 500; e.h = 500; e.i = 278; e.j = 278; e.k = 444; e.l = 278; e.m = 722; e.n = 500; e.o = 500; e.p = 500; e.q = 500; e.r = 389; e.s = 389; e.t = 278; e.u = 500; e.v = 444; e.w = 667; e.x = 444; e.y = 444; e.z = 389; e.braceleft = 400; e.bar = 275; e.braceright = 400; e.asciitilde = 541; e.exclamdown = 389; e.cent = 500; e.sterling = 500; e.fraction = 167; e.yen = 500; e.florin = 500; e.section = 500; e.currency = 500; e.quotesingle = 214; e.quotedblleft = 556; e.guillemotleft = 500; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 500; e.fl = 500; e.endash = 500; e.dagger = 500; e.daggerdbl = 500; e.periodcentered = 250; e.paragraph = 523; e.bullet = 350; e.quotesinglbase = 333; e.quotedblbase = 556; e.quotedblright = 556; e.guillemotright = 500; e.ellipsis = 889; e.perthousand = 1e3; e.questiondown = 500; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 889; e.AE = 889; e.ordfeminine = 276; e.Lslash = 556; e.Oslash = 722; e.OE = 944; e.ordmasculine = 310; e.ae = 667; e.dotlessi = 278; e.lslash = 278; e.oslash = 500; e.oe = 667; e.germandbls = 500; e.Idieresis = 333; e.eacute = 444; e.abreve = 500; e.uhungarumlaut = 500; e.ecaron = 444; e.Ydieresis = 556; e.divide = 675; e.Yacute = 556; e.Acircumflex = 611; e.aacute = 500; e.Ucircumflex = 722; e.yacute = 444; e.scommaaccent = 389; e.ecircumflex = 444; e.Uring = 722; e.Udieresis = 722; e.aogonek = 500; e.Uacute = 722; e.uogonek = 500; e.Edieresis = 611; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 760; e.Emacron = 611; e.ccaron = 444; e.aring = 500; e.Ncommaaccent = 667; e.lacute = 278; e.agrave = 500; e.Tcommaaccent = 556; e.Cacute = 667; e.atilde = 500; e.Edotaccent = 611; e.scaron = 389; e.scedilla = 389; e.iacute = 278; e.lozenge = 471; e.Rcaron = 611; e.Gcommaaccent = 722; e.ucircumflex = 500; e.acircumflex = 500; e.Amacron = 611; e.rcaron = 389; e.ccedilla = 444; e.Zdotaccent = 556; e.Thorn = 611; e.Omacron = 722; e.Racute = 611; e.Sacute = 500; e.dcaron = 544; e.Umacron = 722; e.uring = 500; e.threesuperior = 300; e.Ograve = 722; e.Agrave = 611; e.Abreve = 611; e.multiply = 675; e.uacute = 500; e.Tcaron = 556; e.partialdiff = 476; e.ydieresis = 444; e.Nacute = 667; e.icircumflex = 278; e.Ecircumflex = 611; e.adieresis = 500; e.edieresis = 444; e.cacute = 444; e.nacute = 500; e.umacron = 500; e.Ncaron = 667; e.Iacute = 333; e.plusminus = 675; e.brokenbar = 275; e.registered = 760; e.Gbreve = 722; e.Idotaccent = 333; e.summation = 600; e.Egrave = 611; e.racute = 389; e.omacron = 500; e.Zacute = 556; e.Zcaron = 556; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 667; e.lcommaaccent = 278; e.tcaron = 300; e.eogonek = 444; e.Uogonek = 722; e.Aacute = 611; e.Adieresis = 611; e.egrave = 444; e.zacute = 389; e.iogonek = 278; e.Oacute = 722; e.oacute = 500; e.amacron = 500; e.sacute = 389; e.idieresis = 278; e.Ocircumflex = 722; e.Ugrave = 722; e.Delta = 612; e.thorn = 500; e.twosuperior = 300; e.Odieresis = 722; e.mu = 500; e.igrave = 278; e.ohungarumlaut = 500; e.Eogonek = 611; e.dcroat = 500; e.threequarters = 750; e.Scedilla = 500; e.lcaron = 300; e.Kcommaaccent = 667; e.Lacute = 556; e.trademark = 980; e.edotaccent = 444; e.Igrave = 333; e.Imacron = 333; e.Lcaron = 611; e.onehalf = 750; e.lessequal = 549; e.ocircumflex = 500; e.ntilde = 500; e.Uhungarumlaut = 722; e.Eacute = 611; e.emacron = 444; e.gbreve = 500; e.onequarter = 750; e.Scaron = 500; e.Scommaaccent = 500; e.Ohungarumlaut = 722; e.degree = 400; e.ograve = 500; e.Ccaron = 667; e.ugrave = 500; e.radical = 453; e.Dcaron = 722; e.rcommaaccent = 389; e.Ntilde = 667; e.otilde = 500; e.Rcommaaccent = 611; e.Lcommaaccent = 556; e.Atilde = 611; e.Aogonek = 611; e.Aring = 611; e.Otilde = 722; e.zdotaccent = 389; e.Ecaron = 611; e.Iogonek = 333; e.kcommaaccent = 444; e.minus = 675; e.Icircumflex = 333; e.ncaron = 500; e.tcommaaccent = 278; e.logicalnot = 675; e.odieresis = 500; e.udieresis = 500; e.notequal = 549; e.gcommaaccent = 500; e.eth = 500; e.zcaron = 389; e.ncommaaccent = 500; e.onesuperior = 300; e.imacron = 278; e.Euro = 500 })); e.ZapfDingbats = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.a1 = 974; e.a2 = 961; e.a202 = 974; e.a3 = 980; e.a4 = 719; e.a5 = 789; e.a119 = 790; e.a118 = 791; e.a117 = 690; e.a11 = 960; e.a12 = 939; e.a13 = 549; e.a14 = 855; e.a15 = 911; e.a16 = 933; e.a105 = 911; e.a17 = 945; e.a18 = 974; e.a19 = 755; e.a20 = 846; e.a21 = 762; e.a22 = 761; e.a23 = 571; e.a24 = 677; e.a25 = 763; e.a26 = 760; e.a27 = 759; e.a28 = 754; e.a6 = 494; e.a7 = 552; e.a8 = 537; e.a9 = 577; e.a10 = 692; e.a29 = 786; e.a30 = 788; e.a31 = 788; e.a32 = 790; e.a33 = 793; e.a34 = 794; e.a35 = 816; e.a36 = 823; e.a37 = 789; e.a38 = 841; e.a39 = 823; e.a40 = 833; e.a41 = 816; e.a42 = 831; e.a43 = 923; e.a44 = 744; e.a45 = 723; e.a46 = 749; e.a47 = 790; e.a48 = 792; e.a49 = 695; e.a50 = 776; e.a51 = 768; e.a52 = 792; e.a53 = 759; e.a54 = 707; e.a55 = 708; e.a56 = 682; e.a57 = 701; e.a58 = 826; e.a59 = 815; e.a60 = 789; e.a61 = 789; e.a62 = 707; e.a63 = 687; e.a64 = 696; e.a65 = 689; e.a66 = 786; e.a67 = 787; e.a68 = 713; e.a69 = 791; e.a70 = 785; e.a71 = 791; e.a72 = 873; e.a73 = 761; e.a74 = 762; e.a203 = 762; e.a75 = 759; e.a204 = 759; e.a76 = 892; e.a77 = 892; e.a78 = 788; e.a79 = 784; e.a81 = 438; e.a82 = 138; e.a83 = 277; e.a84 = 415; e.a97 = 392; e.a98 = 392; e.a99 = 668; e.a100 = 668; e.a89 = 390; e.a90 = 390; e.a93 = 317; e.a94 = 317; e.a91 = 276; e.a92 = 276; e.a205 = 509; e.a85 = 509; e.a206 = 410; e.a86 = 410; e.a87 = 234; e.a88 = 234; e.a95 = 334; e.a96 = 334; e.a101 = 732; e.a102 = 544; e.a103 = 544; e.a104 = 910; e.a106 = 667; e.a107 = 760; e.a108 = 760; e.a112 = 776; e.a111 = 595; e.a110 = 694; e.a109 = 626; e.a120 = 788; e.a121 = 788; e.a122 = 788; e.a123 = 788; e.a124 = 788; e.a125 = 788; e.a126 = 788; e.a127 = 788; e.a128 = 788; e.a129 = 788; e.a130 = 788; e.a131 = 788; e.a132 = 788; e.a133 = 788; e.a134 = 788; e.a135 = 788; e.a136 = 788; e.a137 = 788; e.a138 = 788; e.a139 = 788; e.a140 = 788; e.a141 = 788; e.a142 = 788; e.a143 = 788; e.a144 = 788; e.a145 = 788; e.a146 = 788; e.a147 = 788; e.a148 = 788; e.a149 = 788; e.a150 = 788; e.a151 = 788; e.a152 = 788; e.a153 = 788; e.a154 = 788; e.a155 = 788; e.a156 = 788; e.a157 = 788; e.a158 = 788; e.a159 = 788; e.a160 = 894; e.a161 = 838; e.a163 = 1016; e.a164 = 458; e.a196 = 748; e.a165 = 924; e.a192 = 748; e.a166 = 918; e.a167 = 927; e.a168 = 928; e.a169 = 928; e.a170 = 834; e.a171 = 873; e.a172 = 828; e.a173 = 924; e.a162 = 924; e.a174 = 917; e.a175 = 930; e.a176 = 931; e.a177 = 463; e.a178 = 883; e.a179 = 836; e.a193 = 836; e.a180 = 867; e.a199 = 867; e.a181 = 696; e.a200 = 696; e.a182 = 874; e.a201 = 874; e.a183 = 760; e.a184 = 946; e.a197 = 771; e.a185 = 865; e.a194 = 771; e.a198 = 888; e.a186 = 967; e.a195 = 888; e.a187 = 831; e.a188 = 873; e.a189 = 927; e.a190 = 970; e.a191 = 918 })) })); t.getMetrics = i }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.isPDFFunction = function (e) { var t; if ("object" != typeof e) return !1; if ((0, i.isDict)(e)) t = e; else { if (!(0, i.isStream)(e)) return !1; t = e.dict } return t.has("FunctionType") }; t.PostScriptCompiler = t.PostScriptEvaluator = t.PDFFunctionFactory = void 0; var r = a(2), i = a(4), n = a(40); t.PDFFunctionFactory = class { constructor({ xref: e, isEvalSupported: t = !0 }) { this.xref = e; this.isEvalSupported = !1 !== t } create(e) { return o.parse({ xref: this.xref, isEvalSupported: this.isEvalSupported, fn: e }) } createFromArray(e) { return o.parseArray({ xref: this.xref, isEvalSupported: this.isEvalSupported, fnObj: e }) } }; function s(e) { if (!Array.isArray(e)) return null; const t = e.length; for (let a = 0; a < t; a++)if ("number" != typeof e[a]) { const a = new Array(t); for (let r = 0; r < t; r++)a[r] = +e[r]; return a } return e } var o = { getSampleArray(e, t, a, r) { var i, n, s = 1; for (i = 0, n = e.length; i < n; i++)s *= e[i]; s *= t; var o = new Array(s), c = 0, l = 0, h = 1 / (2 ** a - 1), u = r.getBytes((s * a + 7) / 8), d = 0; for (i = 0; i < s; i++) { for (; c < a;) { l <<= 8; l |= u[d++]; c += 8 } c -= a; o[i] = (l >> c) * h; l &= (1 << c) - 1 } return o }, getIR({ xref: e, isEvalSupported: t, fn: a }) { var i = a.dict; i || (i = a); var n = [this.constructSampled, null, this.constructInterpolated, this.constructStiched, this.constructPostScript][i.get("FunctionType")]; if (!n) throw new r.FormatError("Unknown type of function"); return n.call(this, { xref: e, isEvalSupported: t, fn: a, dict: i }) }, fromIR({ xref: e, isEvalSupported: t, IR: a }) { switch (a[0]) { case 0: return this.constructSampledFromIR({ xref: e, isEvalSupported: t, IR: a }); case 2: return this.constructInterpolatedFromIR({ xref: e, isEvalSupported: t, IR: a }); case 3: return this.constructStichedFromIR({ xref: e, isEvalSupported: t, IR: a }); default: return this.constructPostScriptFromIR({ xref: e, isEvalSupported: t, IR: a }) } }, parse({ xref: e, isEvalSupported: t, fn: a }) { const r = this.getIR({ xref: e, isEvalSupported: t, fn: a }); return this.fromIR({ xref: e, isEvalSupported: t, IR: r }) }, parseArray({ xref: e, isEvalSupported: t, fnObj: a }) { if (!Array.isArray(a)) return this.parse({ xref: e, isEvalSupported: t, fn: a }); for (var r = [], i = 0, n = a.length; i < n; i++)r.push(this.parse({ xref: e, isEvalSupported: t, fn: e.fetchIfRef(a[i]) })); return function (e, t, a, i) { for (var n = 0, s = r.length; n < s; n++)r[n](e, t, a, i + n) } }, constructSampled({ xref: e, isEvalSupported: t, fn: a, dict: i }) { function n(e) { for (var t = e.length, a = [], r = 0, i = 0; i < t; i += 2) { a[r] = [e[i], e[i + 1]]; ++r } return a } var o = s(i.getArray("Domain")), c = s(i.getArray("Range")); if (!o || !c) throw new r.FormatError("No domain or range"); var l = o.length / 2, h = c.length / 2; o = n(o); c = n(c); var u = s(i.getArray("Size")), d = i.get("BitsPerSample"), f = i.get("Order") || 1; 1 !== f && (0, r.info)("No support for cubic spline interpolation: " + f); var g = s(i.getArray("Encode")); if (g) g = n(g); else { g = []; for (var m = 0; m < l; ++m)g.push([0, u[m] - 1]) } var p = s(i.getArray("Decode")); return [0, l, o, g, p = p ? n(p) : c, this.getSampleArray(u, h, d, a), u, h, 2 ** d - 1, c] }, constructSampledFromIR({ xref: e, isEvalSupported: t, IR: a }) { function r(e, t, a, r, i) { return r + (i - r) / (a - t) * (e - t) } return function (e, t, i, n) { var s, o, c = a[1], l = a[2], h = a[3], u = a[4], d = a[5], f = a[6], g = a[7], m = a[9], p = 1 << c, b = new Float64Array(p), y = new Uint32Array(p); for (o = 0; o < p; o++)b[o] = 1; var v = g, w = 1; for (s = 0; s < c; ++s) { var k = l[s][0], S = l[s][1], C = r(Math.min(Math.max(e[t + s], k), S), k, S, h[s][0], h[s][1]), x = f[s], A = (C = Math.min(Math.max(C, 0), x - 1)) < x - 1 ? Math.floor(C) : C - 1, I = A + 1 - C, F = C - A, T = A * v, E = T + v; for (o = 0; o < p; o++)if (o & w) { b[o] *= F; y[o] += E } else { b[o] *= I; y[o] += T } v *= x; w <<= 1 } for (o = 0; o < g; ++o) { var O = 0; for (s = 0; s < p; s++)O += d[y[s] + o] * b[s]; O = r(O, 0, 1, u[o][0], u[o][1]); i[n + o] = Math.min(Math.max(O, m[o][0]), m[o][1]) } } }, constructInterpolated({ xref: e, isEvalSupported: t, fn: a, dict: r }) { for (var i = s(r.getArray("C0")) || [0], n = s(r.getArray("C1")) || [1], o = r.get("N"), c = i.length, l = [], h = 0; h < c; ++h)l.push(n[h] - i[h]); return [2, i, l, o] }, constructInterpolatedFromIR({ xref: e, isEvalSupported: t, IR: a }) { var r = a[1], i = a[2], n = a[3], s = i.length; return function (e, t, a, o) { for (var c = 1 === n ? e[t] : e[t] ** n, l = 0; l < s; ++l)a[o + l] = r[l] + c * i[l] } }, constructStiched({ xref: e, isEvalSupported: t, fn: a, dict: i }) { var n = s(i.getArray("Domain")); if (!n) throw new r.FormatError("No domain"); if (1 != n.length / 2) throw new r.FormatError("Bad domain for stiched function"); for (var o = i.get("Functions"), c = [], l = 0, h = o.length; l < h; ++l)c.push(this.parse({ xref: e, isEvalSupported: t, fn: e.fetchIfRef(o[l]) })); return [3, n, s(i.getArray("Bounds")), s(i.getArray("Encode")), c] }, constructStichedFromIR({ xref: e, isEvalSupported: t, IR: a }) { var r = a[1], i = a[2], n = a[3], s = a[4], o = new Float32Array(1); return function (e, t, a, c) { for (var l = function (e, t, a) { e > a ? e = a : e < t && (e = t); return e }(e[t], r[0], r[1]), h = 0, u = i.length; h < u && !(l < i[h]); ++h); var d = r[0]; h > 0 && (d = i[h - 1]); var f = r[1]; h < i.length && (f = i[h]); var g = n[2 * h], m = n[2 * h + 1]; o[0] = d === f ? g : g + (l - d) * (m - g) / (f - d); s[h](o, 0, a, c) } }, constructPostScript({ xref: e, isEvalSupported: t, fn: a, dict: i }) { var o = s(i.getArray("Domain")), c = s(i.getArray("Range")); if (!o) throw new r.FormatError("No domain."); if (!c) throw new r.FormatError("No range."); var l = new n.PostScriptLexer(a); return [4, o, c, new n.PostScriptParser(l).parse()] }, constructPostScriptFromIR({ xref: e, isEvalSupported: t, IR: a }) { var i = a[1], n = a[2], s = a[3]; if (t && r.IsEvalSupportedCached.value) { const e = (new h).compile(s, i, n); if (e) return new Function("src", "srcOffset", "dest", "destOffset", e) } (0, r.info)("Unable to compile PS function"); var o = n.length >> 1, c = i.length >> 1, u = new l(s), d = Object.create(null), f = 8192, g = new Float32Array(c); return function (e, t, a, r) { var i, s, l = "", h = g; for (i = 0; i < c; i++) { s = e[t + i]; h[i] = s; l += s + "_" } var m = d[l]; if (void 0 === m) { var p = new Float32Array(o), b = u.execute(h), y = b.length - o; for (i = 0; i < o; i++) { s = b[y + i]; var v = n[2 * i]; (s < v || s > (v = n[2 * i + 1])) && (s = v); p[i] = s } if (f > 0) { f--; d[l] = p } a.set(p, r) } else a.set(m, r) } } }; var c = function () { function e(e) { this.stack = e ? Array.prototype.slice.call(e, 0) : [] } e.prototype = { push: function (e) { if (this.stack.length >= 100) throw new Error("PostScript function stack overflow."); this.stack.push(e) }, pop: function () { if (this.stack.length <= 0) throw new Error("PostScript function stack underflow."); return this.stack.pop() }, copy: function (e) { if (this.stack.length + e >= 100) throw new Error("PostScript function stack overflow."); for (var t = this.stack, a = t.length - e, r = e - 1; r >= 0; r--, a++)t.push(t[a]) }, index: function (e) { this.push(this.stack[this.stack.length - e - 1]) }, roll: function (e, t) { var a, r, i, n = this.stack, s = n.length - e, o = n.length - 1, c = s + (t - Math.floor(t / e) * e); for (a = s, r = o; a < r; a++, r--) { i = n[a]; n[a] = n[r]; n[r] = i } for (a = s, r = c - 1; a < r; a++, r--) { i = n[a]; n[a] = n[r]; n[r] = i } for (a = c, r = o; a < r; a++, r--) { i = n[a]; n[a] = n[r]; n[r] = i } } }; return e }(), l = function () { function e(e) { this.operators = e } e.prototype = { execute: function (e) { for (var t, a, i, n = new c(e), s = 0, o = this.operators, l = o.length; s < l;)if ("number" != typeof (t = o[s++])) switch (t) { case "jz": i = n.pop(); (a = n.pop()) || (s = i); break; case "j": s = a = n.pop(); break; case "abs": a = n.pop(); n.push(Math.abs(a)); break; case "add": i = n.pop(); a = n.pop(); n.push(a + i); break; case "and": i = n.pop(); a = n.pop(); (0, r.isBool)(a) && (0, r.isBool)(i) ? n.push(a && i) : n.push(a & i); break; case "atan": a = n.pop(); n.push(Math.atan(a)); break; case "bitshift": i = n.pop(); (a = n.pop()) > 0 ? n.push(a << i) : n.push(a >> i); break; case "ceiling": a = n.pop(); n.push(Math.ceil(a)); break; case "copy": a = n.pop(); n.copy(a); break; case "cos": a = n.pop(); n.push(Math.cos(a)); break; case "cvi": a = 0 | n.pop(); n.push(a); break; case "cvr": break; case "div": i = n.pop(); a = n.pop(); n.push(a / i); break; case "dup": n.copy(1); break; case "eq": i = n.pop(); a = n.pop(); n.push(a === i); break; case "exch": n.roll(2, 1); break; case "exp": i = n.pop(); a = n.pop(); n.push(a ** i); break; case "false": n.push(!1); break; case "floor": a = n.pop(); n.push(Math.floor(a)); break; case "ge": i = n.pop(); a = n.pop(); n.push(a >= i); break; case "gt": i = n.pop(); a = n.pop(); n.push(a > i); break; case "idiv": i = n.pop(); a = n.pop(); n.push(a / i | 0); break; case "index": a = n.pop(); n.index(a); break; case "le": i = n.pop(); a = n.pop(); n.push(a <= i); break; case "ln": a = n.pop(); n.push(Math.log(a)); break; case "log": a = n.pop(); n.push(Math.log(a) / Math.LN10); break; case "lt": i = n.pop(); a = n.pop(); n.push(a < i); break; case "mod": i = n.pop(); a = n.pop(); n.push(a % i); break; case "mul": i = n.pop(); a = n.pop(); n.push(a * i); break; case "ne": i = n.pop(); a = n.pop(); n.push(a !== i); break; case "neg": a = n.pop(); n.push(-a); break; case "not": a = n.pop(); (0, r.isBool)(a) ? n.push(!a) : n.push(~a); break; case "or": i = n.pop(); a = n.pop(); (0, r.isBool)(a) && (0, r.isBool)(i) ? n.push(a || i) : n.push(a | i); break; case "pop": n.pop(); break; case "roll": i = n.pop(); a = n.pop(); n.roll(a, i); break; case "round": a = n.pop(); n.push(Math.round(a)); break; case "sin": a = n.pop(); n.push(Math.sin(a)); break; case "sqrt": a = n.pop(); n.push(Math.sqrt(a)); break; case "sub": i = n.pop(); a = n.pop(); n.push(a - i); break; case "true": n.push(!0); break; case "truncate": a = (a = n.pop()) < 0 ? Math.ceil(a) : Math.floor(a); n.push(a); break; case "xor": i = n.pop(); a = n.pop(); (0, r.isBool)(a) && (0, r.isBool)(i) ? n.push(a !== i) : n.push(a ^ i); break; default: throw new r.FormatError(`Unknown operator ${t}`) } else n.push(t); return n.stack } }; return e }(); t.PostScriptEvaluator = l; var h = function () { function e(e) { this.type = e } e.prototype.visit = function (e) { (0, r.unreachable)("abstract method") }; function t(t, a, r) { e.call(this, "args"); this.index = t; this.min = a; this.max = r } t.prototype = Object.create(e.prototype); t.prototype.visit = function (e) { e.visitArgument(this) }; function a(t) { e.call(this, "literal"); this.number = t; this.min = t; this.max = t } a.prototype = Object.create(e.prototype); a.prototype.visit = function (e) { e.visitLiteral(this) }; function i(t, a, r, i, n) { e.call(this, "binary"); this.op = t; this.arg1 = a; this.arg2 = r; this.min = i; this.max = n } i.prototype = Object.create(e.prototype); i.prototype.visit = function (e) { e.visitBinaryOperation(this) }; function n(t, a) { e.call(this, "max"); this.arg = t; this.min = t.min; this.max = a } n.prototype = Object.create(e.prototype); n.prototype.visit = function (e) { e.visitMin(this) }; function s(t, a, r) { e.call(this, "var"); this.index = t; this.min = a; this.max = r } s.prototype = Object.create(e.prototype); s.prototype.visit = function (e) { e.visitVariable(this) }; function o(t, a) { e.call(this, "definition"); this.variable = t; this.arg = a } o.prototype = Object.create(e.prototype); o.prototype.visit = function (e) { e.visitVariableDefinition(this) }; function c() { this.parts = [] } c.prototype = { visitArgument(e) { this.parts.push("Math.max(", e.min, ", Math.min(", e.max, ", src[srcOffset + ", e.index, "]))") }, visitVariable(e) { this.parts.push("v", e.index) }, visitLiteral(e) { this.parts.push(e.number) }, visitBinaryOperation(e) { this.parts.push("("); e.arg1.visit(this); this.parts.push(" ", e.op, " "); e.arg2.visit(this); this.parts.push(")") }, visitVariableDefinition(e) { this.parts.push("var "); e.variable.visit(this); this.parts.push(" = "); e.arg.visit(this); this.parts.push(";") }, visitMin(e) { this.parts.push("Math.min("); e.arg.visit(this); this.parts.push(", ", e.max, ")") }, toString() { return this.parts.join("") } }; function l(e, t) { return "literal" === t.type && 0 === t.number ? e : "literal" === e.type && 0 === e.number ? t : "literal" === t.type && "literal" === e.type ? new a(e.number + t.number) : new i("+", e, t, e.min + t.min, e.max + t.max) } function h(e, t) { if ("literal" === t.type) { if (0 === t.number) return new a(0); if (1 === t.number) return e; if ("literal" === e.type) return new a(e.number * t.number) } if ("literal" === e.type) { if (0 === e.number) return new a(0); if (1 === e.number) return t } return new i("*", e, t, Math.min(e.min * t.min, e.min * t.max, e.max * t.min, e.max * t.max), Math.max(e.min * t.min, e.min * t.max, e.max * t.min, e.max * t.max)) } function u(e, t) { if ("literal" === t.type) { if (0 === t.number) return e; if ("literal" === e.type) return new a(e.number - t.number) } return "binary" === t.type && "-" === t.op && "literal" === e.type && 1 === e.number && "literal" === t.arg1.type && 1 === t.arg1.number ? t.arg2 : new i("-", e, t, e.min - t.max, e.max - t.min) } function d(e, t) { return e.min >= t ? new a(t) : e.max <= t ? e : new n(e, t) } function f() { } f.prototype = { compile: function (e, r, i) { var n, f, g, m, p, b, y, v, w, k, S = [], C = [], x = r.length >> 1, A = i.length >> 1, I = 0; for (n = 0; n < x; n++)S.push(new t(n, r[2 * n], r[2 * n + 1])); for (n = 0, f = e.length; n < f; n++)if ("number" != typeof (k = e[n])) switch (k) { case "add": if (S.length < 2) return null; b = S.pop(); p = S.pop(); S.push(l(p, b)); break; case "cvr": if (S.length < 1) return null; break; case "mul": if (S.length < 2) return null; b = S.pop(); p = S.pop(); S.push(h(p, b)); break; case "sub": if (S.length < 2) return null; b = S.pop(); p = S.pop(); S.push(u(p, b)); break; case "exch": if (S.length < 2) return null; y = S.pop(); v = S.pop(); S.push(y, v); break; case "pop": if (S.length < 1) return null; S.pop(); break; case "index": if (S.length < 1) return null; if ("literal" !== (p = S.pop()).type) return null; if ((g = p.number) < 0 || !Number.isInteger(g) || S.length < g) return null; if ("literal" === (y = S[S.length - g - 1]).type || "var" === y.type) { S.push(y); break } w = new s(I++, y.min, y.max); S[S.length - g - 1] = w; S.push(w); C.push(new o(w, y)); break; case "dup": if (S.length < 1) return null; if ("number" == typeof e[n + 1] && "gt" === e[n + 2] && e[n + 3] === n + 7 && "jz" === e[n + 4] && "pop" === e[n + 5] && e[n + 6] === e[n + 1]) { p = S.pop(); S.push(d(p, e[n + 1])); n += 6; break } if ("literal" === (y = S[S.length - 1]).type || "var" === y.type) { S.push(y); break } w = new s(I++, y.min, y.max); S[S.length - 1] = w; S.push(w); C.push(new o(w, y)); break; case "roll": if (S.length < 2) return null; b = S.pop(); p = S.pop(); if ("literal" !== b.type || "literal" !== p.type) return null; m = b.number; if ((g = p.number) <= 0 || !Number.isInteger(g) || !Number.isInteger(m) || S.length < g) return null; if (0 === (m = (m % g + g) % g)) break; Array.prototype.push.apply(S, S.splice(S.length - g, g - m)); break; default: return null } else S.push(new a(k)); if (S.length !== A) return null; var F = []; C.forEach((function (e) { var t = new c; e.visit(t); F.push(t.toString()) })); S.forEach((function (e, t) { var a = new c; e.visit(a); var r = i[2 * t], n = i[2 * t + 1], s = [a.toString()]; if (r > e.min) { s.unshift("Math.max(", r, ", "); s.push(")") } if (n < e.max) { s.unshift("Math.min(", n, ", "); s.push(")") } s.unshift("dest[destOffset + ", t, "] = "); s.push(";"); F.push(s.join("")) })); return F.join("\n") } }; return f }(); t.PostScriptCompiler = h }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PostScriptParser = t.PostScriptLexer = void 0; var r = a(2), i = a(4), n = a(7); t.PostScriptParser = class { constructor(e) { this.lexer = e; this.operators = []; this.token = null; this.prev = null } nextToken() { this.prev = this.token; this.token = this.lexer.getToken() } accept(e) { if (this.token.type === e) { this.nextToken(); return !0 } return !1 } expect(e) { if (this.accept(e)) return !0; throw new r.FormatError(`Unexpected symbol: found ${this.token.type} expected ${e}.`) } parse() { this.nextToken(); this.expect(s.LBRACE); this.parseBlock(); this.expect(s.RBRACE); return this.operators } parseBlock() { for (; ;)if (this.accept(s.NUMBER)) this.operators.push(this.prev.value); else if (this.accept(s.OPERATOR)) this.operators.push(this.prev.value); else { if (!this.accept(s.LBRACE)) return; this.parseCondition() } } parseCondition() { const e = this.operators.length; this.operators.push(null, null); this.parseBlock(); this.expect(s.RBRACE); if (this.accept(s.IF)) { this.operators[e] = this.operators.length; this.operators[e + 1] = "jz" } else { if (!this.accept(s.LBRACE)) throw new r.FormatError("PS Function: error parsing conditional."); { const t = this.operators.length; this.operators.push(null, null); const a = this.operators.length; this.parseBlock(); this.expect(s.RBRACE); this.expect(s.IFELSE); this.operators[t] = this.operators.length; this.operators[t + 1] = "j"; this.operators[e] = a; this.operators[e + 1] = "jz" } } } }; const s = { LBRACE: 0, RBRACE: 1, NUMBER: 2, OPERATOR: 3, IF: 4, IFELSE: 5 }, o = function () { const e = Object.create(null); class t { constructor(e, t) { this.type = e; this.value = t } static getOperator(a) { const r = e[a]; return r || (e[a] = new t(s.OPERATOR, a)) } static get LBRACE() { return (0, r.shadow)(this, "LBRACE", new t(s.LBRACE, "{")) } static get RBRACE() { return (0, r.shadow)(this, "RBRACE", new t(s.RBRACE, "}")) } static get IF() { return (0, r.shadow)(this, "IF", new t(s.IF, "IF")) } static get IFELSE() { return (0, r.shadow)(this, "IFELSE", new t(s.IFELSE, "IFELSE")) } } return t }(); t.PostScriptLexer = class { constructor(e) { this.stream = e; this.nextChar(); this.strBuf = [] } nextChar() { return this.currentChar = this.stream.getByte() } getToken() { let e = !1, t = this.currentChar; for (; ;) { if (t < 0) return i.EOF; if (e) 10 !== t && 13 !== t || (e = !1); else if (37 === t) e = !0; else if (!(0, n.isWhiteSpace)(t)) break; t = this.nextChar() } switch (0 | t) { case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 43: case 45: case 46: return new o(s.NUMBER, this.getNumber()); case 123: this.nextChar(); return o.LBRACE; case 125: this.nextChar(); return o.RBRACE }const a = this.strBuf; a.length = 0; a[0] = String.fromCharCode(t); for (; (t = this.nextChar()) >= 0 && (t >= 65 && t <= 90 || t >= 97 && t <= 122);)a.push(String.fromCharCode(t)); const r = a.join(""); switch (r.toLowerCase()) { case "if": return o.IF; case "ifelse": return o.IFELSE; default: return o.getOperator(r) } } getNumber() { let e = this.currentChar; const t = this.strBuf; t.length = 0; t[0] = String.fromCharCode(e); for (; (e = this.nextChar()) >= 0 && (e >= 48 && e <= 57 || 45 === e || 46 === e);)t.push(String.fromCharCode(e)); const a = parseFloat(t.join("")); if (isNaN(a)) throw new r.FormatError(`Invalid floating point number: ${a}`); return a } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.MurmurHash3_64 = void 0; var r = a(2); t.MurmurHash3_64 = class { constructor(e) { this.h1 = e ? 4294967295 & e : 3285377520; this.h2 = e ? 4294967295 & e : 3285377520 } update(e) { let t, a; if ((0, r.isString)(e)) { t = new Uint8Array(2 * e.length); a = 0; for (let r = 0, i = e.length; r < i; r++) { const i = e.charCodeAt(r); if (i <= 255) t[a++] = i; else { t[a++] = i >>> 8; t[a++] = 255 & i } } } else { if (!(0, r.isArrayBuffer)(e)) throw new Error("Wrong data format in MurmurHash3_64_update. Input must be a string or array."); t = e; a = t.byteLength } const i = a >> 2, n = a - 4 * i, s = new Uint32Array(t.buffer, 0, i); let o = 0, c = 0, l = this.h1, h = this.h2; const u = 3432918353, d = 461845907; for (let e = 0; e < i; e++)if (1 & e) { o = s[e]; o = o * u & 4294901760 | 11601 * o & 65535; o = o << 15 | o >>> 17; o = o * d & 4294901760 | 13715 * o & 65535; l ^= o; l = l << 13 | l >>> 19; l = 5 * l + 3864292196 } else { c = s[e]; c = c * u & 4294901760 | 11601 * c & 65535; c = c << 15 | c >>> 17; c = c * d & 4294901760 | 13715 * c & 65535; h ^= c; h = h << 13 | h >>> 19; h = 5 * h + 3864292196 } o = 0; switch (n) { case 3: o ^= t[4 * i + 2] << 16; case 2: o ^= t[4 * i + 1] << 8; case 1: o ^= t[4 * i]; o = o * u & 4294901760 | 11601 * o & 65535; o = o << 15 | o >>> 17; o = o * d & 4294901760 | 13715 * o & 65535; 1 & i ? l ^= o : h ^= o }this.h1 = l; this.h2 = h } hexdigest() { let e = this.h1, t = this.h2; e ^= t >>> 1; e = 3981806797 * e & 4294901760 | 36045 * e & 65535; t = 4283543511 * t & 4294901760 | (2950163797 * (t << 16 | e >>> 16) & 4294901760) >>> 16; e ^= t >>> 1; e = 444984403 * e & 4294901760 | 60499 * e & 65535; t = 3301882366 * t & 4294901760 | (3120437893 * (t << 16 | e >>> 16) & 4294901760) >>> 16; e ^= t >>> 1; const a = (e >>> 0).toString(16), r = (t >>> 0).toString(16); return a.padStart(8, "0") + r.padStart(8, "0") } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.NativeImageDecoder = void 0; var r = a(22), i = a(17), n = a(11); class s { constructor({ xref: e, resources: t, handler: a, forceDataSchema: r = !1, pdfFunctionFactory: i }) { this.xref = e; this.resources = t; this.handler = a; this.forceDataSchema = r; this.pdfFunctionFactory = i } canDecode(e) { return e instanceof i.JpegStream && s.isDecodable(e, this.xref, this.resources, this.pdfFunctionFactory) && e.maybeValidDimensions } decode(e) { const t = e.dict; let a = t.get("ColorSpace", "CS"); a = r.ColorSpace.parse(a, this.xref, this.resources, this.pdfFunctionFactory); return this.handler.sendWithPromise("JpegDecode", [e.getIR(this.forceDataSchema), a.numComps]).then((function ({ data: e, width: a, height: r }) { return new n.Stream(e, 0, e.length, t) })) } static isSupported(e, t, a, i) { const n = e.dict; if (n.has("DecodeParms") || n.has("DP")) return !1; const s = r.ColorSpace.parse(n.get("ColorSpace", "CS"), t, a, i); return ("DeviceGray" === s.name || "DeviceRGB" === s.name) && s.isDefaultDecode(n.getArray("Decode", "D")) } static isDecodable(e, t, a, i) { const n = e.dict; if (n.has("DecodeParms") || n.has("DP")) return !1; const s = r.ColorSpace.parse(n.get("ColorSpace", "CS"), t, a, i), o = n.get("BitsPerComponent", "BPC") || 1; return (1 === s.numComps || 3 === s.numComps) && s.isDefaultDecode(n.getArray("Decode", "D"), o) } } t.NativeImageDecoder = s }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PDFImage = void 0; var r = a(2), i = a(4), n = a(22), s = a(11), o = a(17), c = a(20), l = function () { function e(e, t) { return t && t.canDecode(e) ? t.decode(e).catch(t => { (0, r.warn)("Native image decoding failed -- trying to recover: " + (t && t.message)); return e }) : Promise.resolve(e) } function t(e, t, a, r) { (e = t + e * a) < 0 ? e = 0 : e > r && (e = r); return e } function a(e, t, a, r, i, n) { var s = i * n; let o; o = t <= 8 ? new Uint8Array(s) : t <= 16 ? new Uint16Array(s) : new Uint32Array(s); var c, l, h, u, d = a / i, f = r / n, g = 0, m = new Uint16Array(i), p = a; for (c = 0; c < i; c++)m[c] = Math.floor(c * d); for (c = 0; c < n; c++) { h = Math.floor(c * f) * p; for (l = 0; l < i; l++) { u = h + m[l]; o[g++] = e[u] } } return o } function l({ xref: e, res: t, image: a, isInline: s = !1, smask: o = null, mask: h = null, isMask: u = !1, pdfFunctionFactory: d }) { this.image = a; var f = a.dict; const g = f.get("Filter"); if ((0, i.isName)(g)) switch (g.name) { case "JPXDecode": var m = new c.JpxImage; m.parseImageProperties(a.stream); a.stream.reset(); a.width = m.width; a.height = m.height; a.bitsPerComponent = m.bitsPerComponent; a.numComps = m.componentsCount; break; case "JBIG2Decode": a.bitsPerComponent = 1; a.numComps = 1 }let p = f.get("Width", "W"), b = f.get("Height", "H"); if (Number.isInteger(a.width) && a.width > 0 && Number.isInteger(a.height) && a.height > 0 && (a.width !== p || a.height !== b)) { (0, r.warn)("PDFImage - using the Width/Height of the image data, rather than the image dictionary."); p = a.width; b = a.height } if (p < 1 || b < 1) throw new r.FormatError(`Invalid image width: ${p} or height: ${b}`); this.width = p; this.height = b; this.interpolate = f.get("Interpolate", "I") || !1; this.imageMask = f.get("ImageMask", "IM") || !1; this.matte = f.get("Matte") || !1; var y = a.bitsPerComponent; if (!y && !(y = f.get("BitsPerComponent", "BPC"))) { if (!this.imageMask) throw new r.FormatError(`Bits per component missing in image: ${this.imageMask}`); y = 1 } this.bpc = y; if (!this.imageMask) { var v = f.get("ColorSpace", "CS"); if (!v) { (0, r.info)("JPX images (which do not require color spaces)"); switch (a.numComps) { case 1: v = i.Name.get("DeviceGray"); break; case 3: v = i.Name.get("DeviceRGB"); break; case 4: v = i.Name.get("DeviceCMYK"); break; default: throw new Error(`JPX images with ${a.numComps} ` + "color components not supported.") } } const o = s ? t : null; this.colorSpace = n.ColorSpace.parse(v, e, o, d); this.numComps = this.colorSpace.numComps } this.decode = f.getArray("Decode", "D"); this.needsDecode = !1; if (this.decode && (this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode, y) || u && !n.ColorSpace.isDefaultDecode(this.decode, 1))) { this.needsDecode = !0; var w = (1 << y) - 1; this.decodeCoefficients = []; this.decodeAddends = []; const e = this.colorSpace && "Indexed" === this.colorSpace.name; for (var k = 0, S = 0; k < this.decode.length; k += 2, ++S) { var C = this.decode[k], x = this.decode[k + 1]; this.decodeCoefficients[S] = e ? (x - C) / w : x - C; this.decodeAddends[S] = e ? C : w * C } } if (o) this.smask = new l({ xref: e, res: t, image: o, isInline: s, pdfFunctionFactory: d }); else if (h) if ((0, i.isStream)(h)) { h.dict.get("ImageMask", "IM") ? this.mask = new l({ xref: e, res: t, image: h, isInline: s, isMask: !0, pdfFunctionFactory: d }) : (0, r.warn)("Ignoring /Mask in image without /ImageMask.") } else this.mask = h } l.buildImage = function ({ handler: t, xref: a, res: n, image: s, isInline: o = !1, nativeDecoder: c = null, pdfFunctionFactory: h }) { var u, d, f = e(s, c), g = s.dict.get("SMask"), m = s.dict.get("Mask"); if (g) { u = e(g, c); d = Promise.resolve(null) } else { u = Promise.resolve(null); if (m) if ((0, i.isStream)(m)) d = e(m, c); else if (Array.isArray(m)) d = Promise.resolve(m); else { (0, r.warn)("Unsupported mask format."); d = Promise.resolve(null) } else d = Promise.resolve(null) } return Promise.all([f, u, d]).then((function ([e, t, r]) { return new l({ xref: a, res: n, image: e, isInline: o, smask: t, mask: r, pdfFunctionFactory: h }) })) }; l.createMask = function ({ imgArray: e, width: t, height: a, imageIsFromDecodeStream: r, inverseDecode: i }) { var n, s, o = (t + 7 >> 3) * a, c = e.byteLength; if (!r || i && !(o === c)) if (i) { (n = new Uint8ClampedArray(o)).set(e); for (s = c; s < o; s++)n[s] = 255 } else (n = new Uint8ClampedArray(c)).set(e); else n = e; if (i) for (s = 0; s < c; s++)n[s] ^= 255; return { data: n, width: t, height: a } }; l.prototype = { get drawWidth() { return Math.max(this.width, this.smask && this.smask.width || 0, this.mask && this.mask.width || 0) }, get drawHeight() { return Math.max(this.height, this.smask && this.smask.height || 0, this.mask && this.mask.height || 0) }, decodeBuffer(e) { var a, r, i = this.bpc, n = this.numComps, s = this.decodeAddends, o = this.decodeCoefficients, c = (1 << i) - 1; if (1 !== i) { var l = 0; for (a = 0, r = this.width * this.height; a < r; a++)for (var h = 0; h < n; h++) { e[l] = t(e[l], s[h], o[h], c); l++ } } else for (a = 0, r = e.length; a < r; a++)e[a] = +!e[a] }, getComponents(e) { var t = this.bpc; if (8 === t) return e; var a = this.width, r = this.height, i = this.numComps, n = a * r * i, s = 0; let o; o = t <= 8 ? new Uint8Array(n) : t <= 16 ? new Uint16Array(n) : new Uint32Array(n); var c, l, h = a * i, u = (1 << t) - 1, d = 0; if (1 === t) for (var f, g, m, p = 0; p < r; p++) { g = d + (-8 & h); m = d + h; for (; d < g;) { l = e[s++]; o[d] = l >> 7 & 1; o[d + 1] = l >> 6 & 1; o[d + 2] = l >> 5 & 1; o[d + 3] = l >> 4 & 1; o[d + 4] = l >> 3 & 1; o[d + 5] = l >> 2 & 1; o[d + 6] = l >> 1 & 1; o[d + 7] = 1 & l; d += 8 } if (d < m) { l = e[s++]; f = 128; for (; d < m;) { o[d++] = +!!(l & f); f >>= 1 } } } else { var b = 0; l = 0; for (d = 0, c = n; d < c; ++d) { if (d % h == 0) { l = 0; b = 0 } for (; b < t;) { l = l << 8 | e[s++]; b += 8 } var y = b - t; let a = l >> y; a < 0 ? a = 0 : a > u && (a = u); o[d] = a; l &= (1 << y) - 1; b = y } } return o }, fillOpacity(e, t, i, n, s) { var o, c, h, u, d, f, g = this.smask, m = this.mask; if (g) { c = g.width; h = g.height; o = new Uint8ClampedArray(c * h); g.fillGrayBuffer(o); c === t && h === i || (o = a(o, g.bpc, c, h, t, i)) } else if (m) if (m instanceof l) { c = m.width; h = m.height; o = new Uint8ClampedArray(c * h); m.numComps = 1; m.fillGrayBuffer(o); for (u = 0, d = c * h; u < d; ++u)o[u] = 255 - o[u]; c === t && h === i || (o = a(o, m.bpc, c, h, t, i)) } else { if (!Array.isArray(m)) throw new r.FormatError("Unknown mask format."); o = new Uint8ClampedArray(t * i); var p = this.numComps; for (u = 0, d = t * i; u < d; ++u) { var b = 0, y = u * p; for (f = 0; f < p; ++f) { var v = s[y + f], w = 2 * f; if (v < m[w] || v > m[w + 1]) { b = 255; break } } o[u] = b } } if (o) for (u = 0, f = 3, d = t * n; u < d; ++u, f += 4)e[f] = o[u]; else for (u = 0, f = 3, d = t * n; u < d; ++u, f += 4)e[f] = 255 }, undoPreblend(e, t, a) { var r = this.smask && this.smask.matte; if (r) for (var i = this.colorSpace.getRgb(r, 0), n = i[0], s = i[1], o = i[2], c = t * a * 4, l = 0; l < c; l += 4) { var h = e[l + 3]; if (0 !== h) { var u = 255 / h; e[l] = (e[l] - n) * u + n; e[l + 1] = (e[l + 1] - s) * u + s; e[l + 2] = (e[l + 2] - o) * u + o } else { e[l] = 255; e[l + 1] = 255; e[l + 2] = 255 } } }, createImageData(e = !1) { var t, a = this.drawWidth, i = this.drawHeight, n = { width: a, height: i, kind: 0, data: null }, c = this.numComps, l = this.width, h = this.height, u = this.bpc, d = l * c * u + 7 >> 3; if (!e) { var f; "DeviceGray" === this.colorSpace.name && 1 === u ? f = r.ImageKind.GRAYSCALE_1BPP : "DeviceRGB" !== this.colorSpace.name || 8 !== u || this.needsDecode || (f = r.ImageKind.RGB_24BPP); if (f && !this.smask && !this.mask && a === l && i === h) { n.kind = f; t = this.getImageBytes(h * d); if (this.image instanceof s.DecodeStream) n.data = t; else { var g = new Uint8ClampedArray(t.length); g.set(t); n.data = g } if (this.needsDecode) { (0, r.assert)(f === r.ImageKind.GRAYSCALE_1BPP, "PDFImage.createImageData: The image must be grayscale."); for (var m = n.data, p = 0, b = m.length; p < b; p++)m[p] ^= 255 } return n } if (this.image instanceof o.JpegStream && !this.smask && !this.mask) { let e = h * d; switch (this.colorSpace.name) { case "DeviceGray": e *= 3; case "DeviceRGB": case "DeviceCMYK": n.kind = r.ImageKind.RGB_24BPP; n.data = this.getImageBytes(e, a, i, !0); return n } } } var y, v, w = 0 | (t = this.getImageBytes(h * d)).length / d * i / h, k = this.getComponents(t); if (e || this.smask || this.mask) { n.kind = r.ImageKind.RGBA_32BPP; n.data = new Uint8ClampedArray(a * i * 4); y = 1; v = !0; this.fillOpacity(n.data, a, i, w, k) } else { n.kind = r.ImageKind.RGB_24BPP; n.data = new Uint8ClampedArray(a * i * 3); y = 0; v = !1 } this.needsDecode && this.decodeBuffer(k); this.colorSpace.fillRgb(n.data, l, h, a, i, w, u, k, y); v && this.undoPreblend(n.data, a, w); return n }, fillGrayBuffer(e) { var t = this.numComps; if (1 !== t) throw new r.FormatError(`Reading gray scale from a color image: ${t}`); var a, i, n = this.width, s = this.height, o = this.bpc, c = n * t * o + 7 >> 3, l = this.getImageBytes(s * c), h = this.getComponents(l); if (1 !== o) { this.needsDecode && this.decodeBuffer(h); i = n * s; var u = 255 / ((1 << o) - 1); for (a = 0; a < i; ++a)e[a] = u * h[a] } else { i = n * s; if (this.needsDecode) for (a = 0; a < i; ++a)e[a] = h[a] - 1 & 255; else for (a = 0; a < i; ++a)e[a] = 255 & -h[a] } }, getImageBytes(e, t, a, r = !1) { this.image.reset(); this.image.drawWidth = t || this.width; this.image.drawHeight = a || this.height; this.image.forceRGB = !!r; return this.image.getBytes(e, !0) } }; return l }(); t.PDFImage = l }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.isNodeJS = void 0; const r = "object" == typeof process && process + "" == "[object process]" && !process.versions.nw && !process.versions.electron; t.isNodeJS = r }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.MessageHandler = void 0; var r = a(2); const i = 1, n = 2, s = 1, o = 2, c = 3, l = 4, h = 5, u = 6, d = 7, f = 8; function g(e) { if ("object" != typeof e || null === e) return e; switch (e.name) { case "AbortException": return new r.AbortException(e.message); case "MissingPDFException": return new r.MissingPDFException(e.message); case "UnexpectedResponseException": return new r.UnexpectedResponseException(e.message, e.status); case "UnknownErrorException": return new r.UnknownErrorException(e.message, e.details); default: return new r.UnknownErrorException(e.message, e.toString()) } } t.MessageHandler = class { constructor(e, t, a) { this.sourceName = e; this.targetName = t; this.comObj = a; this.callbackId = 1; this.streamId = 1; this.postMessageTransfers = !0; this.streamSinks = Object.create(null); this.streamControllers = Object.create(null); this.callbackCapabilities = Object.create(null); this.actionHandler = Object.create(null); this._onComObjOnMessage = e => { const t = e.data; if (t.targetName !== this.sourceName) return; if (t.stream) { this._processStreamMessage(t); return } if (t.callback) { const e = t.callbackId, a = this.callbackCapabilities[e]; if (!a) throw new Error(`Cannot resolve callback ${e}`); delete this.callbackCapabilities[e]; if (t.callback === i) a.resolve(t.data); else { if (t.callback !== n) throw new Error("Unexpected callback case"); a.reject(g(t.reason)) } return } const r = this.actionHandler[t.action]; if (!r) throw new Error(`Unknown action from worker: ${t.action}`); if (t.callbackId) { const e = this.sourceName, s = t.sourceName; new Promise((function (e) { e(r(t.data)) })).then((function (r) { a.postMessage({ sourceName: e, targetName: s, callback: i, callbackId: t.callbackId, data: r }) }), (function (r) { a.postMessage({ sourceName: e, targetName: s, callback: n, callbackId: t.callbackId, reason: g(r) }) })) } else t.streamId ? this._createStreamSink(t) : r(t.data) }; a.addEventListener("message", this._onComObjOnMessage) } on(e, t) { const a = this.actionHandler; if (a[e]) throw new Error(`There is already an actionName called "${e}"`); a[e] = t } send(e, t, a) { this._postMessage({ sourceName: this.sourceName, targetName: this.targetName, action: e, data: t }, a) } sendWithPromise(e, t, a) { const i = this.callbackId++, n = (0, r.createPromiseCapability)(); this.callbackCapabilities[i] = n; try { this._postMessage({ sourceName: this.sourceName, targetName: this.targetName, action: e, callbackId: i, data: t }, a) } catch (e) { n.reject(e) } return n.promise } sendWithStream(e, t, a, i) { const n = this.streamId++, o = this.sourceName, c = this.targetName, l = this.comObj; return new ReadableStream({ start: a => { const s = (0, r.createPromiseCapability)(); this.streamControllers[n] = { controller: a, startCall: s, pullCall: null, cancelCall: null, isClosed: !1 }; this._postMessage({ sourceName: o, targetName: c, action: e, streamId: n, data: t, desiredSize: a.desiredSize }, i); return s.promise }, pull: e => { const t = (0, r.createPromiseCapability)(); this.streamControllers[n].pullCall = t; l.postMessage({ sourceName: o, targetName: c, stream: u, streamId: n, desiredSize: e.desiredSize }); return t.promise }, cancel: e => { (0, r.assert)(e instanceof Error, "cancel must have a valid reason"); const t = (0, r.createPromiseCapability)(); this.streamControllers[n].cancelCall = t; this.streamControllers[n].isClosed = !0; l.postMessage({ sourceName: o, targetName: c, stream: s, streamId: n, reason: g(e) }); return t.promise } }, a) } _createStreamSink(e) { const t = this, a = this.actionHandler[e.action], i = e.streamId, n = this.sourceName, s = e.sourceName, o = this.comObj, u = { enqueue(e, a = 1, o) { if (this.isCancelled) return; const c = this.desiredSize; this.desiredSize -= a; if (c > 0 && this.desiredSize <= 0) { this.sinkCapability = (0, r.createPromiseCapability)(); this.ready = this.sinkCapability.promise } t._postMessage({ sourceName: n, targetName: s, stream: l, streamId: i, chunk: e }, o) }, close() { if (!this.isCancelled) { this.isCancelled = !0; o.postMessage({ sourceName: n, targetName: s, stream: c, streamId: i }); delete t.streamSinks[i] } }, error(e) { (0, r.assert)(e instanceof Error, "error must have a valid reason"); if (!this.isCancelled) { this.isCancelled = !0; o.postMessage({ sourceName: n, targetName: s, stream: h, streamId: i, reason: g(e) }) } }, sinkCapability: (0, r.createPromiseCapability)(), onPull: null, onCancel: null, isCancelled: !1, desiredSize: e.desiredSize, ready: null }; u.sinkCapability.resolve(); u.ready = u.sinkCapability.promise; this.streamSinks[i] = u; new Promise((function (t) { t(a(e.data, u)) })).then((function () { o.postMessage({ sourceName: n, targetName: s, stream: f, streamId: i, success: !0 }) }), (function (e) { o.postMessage({ sourceName: n, targetName: s, stream: f, streamId: i, reason: g(e) }) })) } _processStreamMessage(e) { const t = e.streamId, a = this.sourceName, i = e.sourceName, n = this.comObj; switch (e.stream) { case f: e.success ? this.streamControllers[t].startCall.resolve() : this.streamControllers[t].startCall.reject(g(e.reason)); break; case d: e.success ? this.streamControllers[t].pullCall.resolve() : this.streamControllers[t].pullCall.reject(g(e.reason)); break; case u: if (!this.streamSinks[t]) { n.postMessage({ sourceName: a, targetName: i, stream: d, streamId: t, success: !0 }); break } this.streamSinks[t].desiredSize <= 0 && e.desiredSize > 0 && this.streamSinks[t].sinkCapability.resolve(); this.streamSinks[t].desiredSize = e.desiredSize; const { onPull: m } = this.streamSinks[e.streamId]; new Promise((function (e) { e(m && m()) })).then((function () { n.postMessage({ sourceName: a, targetName: i, stream: d, streamId: t, success: !0 }) }), (function (e) { n.postMessage({ sourceName: a, targetName: i, stream: d, streamId: t, reason: g(e) }) })); break; case l: (0, r.assert)(this.streamControllers[t], "enqueue should have stream controller"); if (this.streamControllers[t].isClosed) break; this.streamControllers[t].controller.enqueue(e.chunk); break; case c: (0, r.assert)(this.streamControllers[t], "close should have stream controller"); if (this.streamControllers[t].isClosed) break; this.streamControllers[t].isClosed = !0; this.streamControllers[t].controller.close(); this._deleteStreamController(t); break; case h: (0, r.assert)(this.streamControllers[t], "error should have stream controller"); this.streamControllers[t].controller.error(g(e.reason)); this._deleteStreamController(t); break; case o: e.success ? this.streamControllers[t].cancelCall.resolve() : this.streamControllers[t].cancelCall.reject(g(e.reason)); this._deleteStreamController(t); break; case s: if (!this.streamSinks[t]) break; const { onCancel: p } = this.streamSinks[e.streamId]; new Promise((function (t) { t(p && p(g(e.reason))) })).then((function () { n.postMessage({ sourceName: a, targetName: i, stream: o, streamId: t, success: !0 }) }), (function (e) { n.postMessage({ sourceName: a, targetName: i, stream: o, streamId: t, reason: g(e) }) })); this.streamSinks[t].sinkCapability.reject(g(e.reason)); this.streamSinks[t].isCancelled = !0; delete this.streamSinks[t]; break; default: throw new Error("Unexpected stream case") } } async _deleteStreamController(e) { await Promise.allSettled([this.streamControllers[e].startCall, this.streamControllers[e].pullCall, this.streamControllers[e].cancelCall].map((function (e) { return e && e.promise }))); delete this.streamControllers[e] } _postMessage(e, t) { t && this.postMessageTransfers ? this.comObj.postMessage(e, t) : this.comObj.postMessage(e) } destroy() { this.comObj.removeEventListener("message", this._onComObjOnMessage) } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PDFWorkerStream = void 0; var r = a(2); t.PDFWorkerStream = class { constructor(e) { this._msgHandler = e; this._contentLength = null; this._fullRequestReader = null; this._rangeRequestReaders = [] } getFullReader() { (0, r.assert)(!this._fullRequestReader); this._fullRequestReader = new i(this._msgHandler); return this._fullRequestReader } getRangeReader(e, t) { const a = new n(e, t, this._msgHandler); this._rangeRequestReaders.push(a); return a } cancelAllRequests(e) { this._fullRequestReader && this._fullRequestReader.cancel(e); this._rangeRequestReaders.slice(0).forEach((function (t) { t.cancel(e) })) } }; class i { constructor(e) { this._msgHandler = e; this.onProgress = null; this._contentLength = null; this._isRangeSupported = !1; this._isStreamingSupported = !1; const t = this._msgHandler.sendWithStream("GetReader"); this._reader = t.getReader(); this._headersReady = this._msgHandler.sendWithPromise("ReaderHeadersReady").then(e => { this._isStreamingSupported = e.isStreamingSupported; this._isRangeSupported = e.isRangeSupported; this._contentLength = e.contentLength }) } get headersReady() { return this._headersReady } get contentLength() { return this._contentLength } get isStreamingSupported() { return this._isStreamingSupported } get isRangeSupported() { return this._isRangeSupported } async read() { const { value: e, done: t } = await this._reader.read(); return t ? { value: void 0, done: !0 } : { value: e.buffer, done: !1 } } cancel(e) { this._reader.cancel(e) } } class n { constructor(e, t, a) { this._msgHandler = a; this.onProgress = null; const r = this._msgHandler.sendWithStream("GetRangeReader", { begin: e, end: t }); this._reader = r.getReader() } get isStreamingSupported() { return !1 } async read() { const { value: e, done: t } = await this._reader.read(); return t ? { value: void 0, done: !0 } : { value: e.buffer, done: !1 } } cancel(e) { this._reader.cancel(e) } } }]) })); \ No newline at end of file
diff --git a/deploy/assets/pdf.worker.js b/deploy/assets/pdf.worker.js
deleted file mode 100644
index 1b4424b03..000000000
--- a/deploy/assets/pdf.worker.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * @licstart The following is the entire license notice for the
- * Javascript code in this page
- *
- * Copyright 2020 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * Javascript code in this page
- */
-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("pdfjs-dist/build/pdf.worker",[],t):"object"==typeof exports?exports["pdfjs-dist/build/pdf.worker"]=t():e["pdfjs-dist/build/pdf.worker"]=e.pdfjsWorker=t()}(this,(function(){return function(e){var t={};function a(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};e[r].call(i.exports,i,i.exports,a);i.l=!0;return i.exports}a.m=e;a.c=t;a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})};a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});Object.defineProperty(e,"__esModule",{value:!0})};a.t=function(e,t){1&t&&(e=a(e));if(8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);a.r(r);Object.defineProperty(r,"default",{enumerable:!0,value:e});if(2&t&&"string"!=typeof e)for(var i in e)a.d(r,i,function(t){return e[t]}.bind(null,i));return r};a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};a.d(t,"a",t);return t};a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};a.p="";return a(a.s=0)}([function(e,t,a){"use strict";const r=a(1);t.WorkerMessageHandler=r.WorkerMessageHandler},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.WorkerMessageHandler=t.WorkerTask=void 0;var r=a(2),i=a(4),n=a(5),s=a(44),o=a(45),c=a(46),l=a(7),h=function(){function e(e){this.name=e;this.terminated=!1;this._capability=(0,r.createPromiseCapability)()}e.prototype={get finished(){return this._capability.promise},finish(){this._capability.resolve()},terminate(){this.terminated=!0},ensureNotTerminated(){if(this.terminated)throw new Error("Worker task was terminated")}};return e}();t.WorkerTask=h;var u,d={setup(e,t){var a=!1;e.on("test",(function(t){if(a)return;a=!0;if(!(t instanceof Uint8Array)){e.send("test",null);return}const r=255===t[0];e.postMessageTransfers=r;e.send("test",{supportTransfers:r})}));e.on("configure",(function(e){(0,r.setVerbosityLevel)(e.verbosity)}));e.on("GetDocRequest",(function(e){return d.createDocumentHandler(e,t)}))},createDocumentHandler(e,t){var a,s=!1,u=null,d=[];const f=(0,r.getVerbosityLevel)(),g=e.apiVersion;if("2.4.456"!==g)throw new Error(`The API version "${g}" does not match `+'the Worker version "2.4.456".');const m=[];for(const e in[])m.push(e);if(m.length)throw new Error("The `Array.prototype` contains unexpected enumerable properties: "+m.join(", ")+"; thus breaking e.g. `for...in` iteration of `Array`s.");var p=e.docId,b=e.docBaseUrl,y=e.docId+"_worker",v=new o.MessageHandler(y,p,t);v.postMessageTransfers=e.postMessageTransfers;function w(){if(s)throw new Error("Worker was terminated")}function k(e){d.push(e)}function S(e){e.finish();var t=d.indexOf(e);d.splice(t,1)}async function C(e){await a.ensureDoc("checkHeader");await a.ensureDoc("parseStartXRef");await a.ensureDoc("parse",[e]);e||await a.ensureDoc("checkFirstPage");const[t,r]=await Promise.all([a.ensureDoc("numPages"),a.ensureDoc("fingerprint")]);return{numPages:t,fingerprint:r}}function x(e,t){var a,i=(0,r.createPromiseCapability)(),s=e.source;if(s.data){try{a=new n.LocalPdfManager(p,s.data,s.password,t,b);i.resolve(a)}catch(e){i.reject(e)}return i.promise}var o,l=[];try{o=new c.PDFWorkerStream(v)}catch(e){i.reject(e);return i.promise}var h=o.getFullReader();h.headersReady.then((function(){if(h.isRangeSupported){var e=s.disableAutoFetch||h.isStreamingSupported;a=new n.NetworkPdfManager(p,o,{msgHandler:v,password:s.password,length:h.contentLength,disableAutoFetch:e,rangeChunkSize:s.rangeChunkSize},t,b);for(let e=0;e<l.length;e++)a.sendProgressiveData(l[e]);l=[];i.resolve(a);u=null}})).catch((function(e){i.reject(e);u=null}));var d=0;new Promise((function(e,o){var c=function(e){try{w();if(e.done){a||function(){var e=(0,r.arraysToBytes)(l);s.length&&e.length!==s.length&&(0,r.warn)("reported HTTP length is different from actual");try{a=new n.LocalPdfManager(p,e,s.password,t,b);i.resolve(a)}catch(e){i.reject(e)}l=[]}();u=null;return}var f=e.value;d+=(0,r.arrayByteLength)(f);h.isStreamingSupported||v.send("DocProgress",{loaded:d,total:Math.max(d,h.contentLength||0)});a?a.sendProgressiveData(f):l.push(f);h.read().then(c,o)}catch(e){o(e)}};h.read().then(c,o)})).catch((function(e){i.reject(e);u=null}));u=function(e){o.cancelAllRequests(e)};return i.promise}v.on("GetPage",(function(e){return a.getPage(e.pageIndex).then((function(e){return Promise.all([a.ensure(e,"rotate"),a.ensure(e,"ref"),a.ensure(e,"userUnit"),a.ensure(e,"view")]).then((function([e,t,a,r]){return{rotate:e,ref:t,userUnit:a,view:r}}))}))}));v.on("GetPageIndex",(function(e){var t=i.Ref.get(e.ref.num,e.ref.gen);return a.pdfDocument.catalog.getPageIndex(t)}));v.on("GetDestinations",(function(e){return a.ensureCatalog("destinations")}));v.on("GetDestination",(function(e){return a.ensureCatalog("getDestination",[e.id])}));v.on("GetPageLabels",(function(e){return a.ensureCatalog("pageLabels")}));v.on("GetPageLayout",(function(e){return a.ensureCatalog("pageLayout")}));v.on("GetPageMode",(function(e){return a.ensureCatalog("pageMode")}));v.on("GetViewerPreferences",(function(e){return a.ensureCatalog("viewerPreferences")}));v.on("GetOpenAction",(function(e){return a.ensureCatalog("openAction")}));v.on("GetAttachments",(function(e){return a.ensureCatalog("attachments")}));v.on("GetJavaScript",(function(e){return a.ensureCatalog("javaScript")}));v.on("GetOutline",(function(e){return a.ensureCatalog("documentOutline")}));v.on("GetPermissions",(function(e){return a.ensureCatalog("permissions")}));v.on("GetMetadata",(function(e){return Promise.all([a.ensureDoc("documentInfo"),a.ensureCatalog("metadata")])}));v.on("GetData",(function(e){a.requestLoadedStream();return a.onLoadedStream().then((function(e){return e.bytes}))}));v.on("GetStats",(function(e){return a.pdfDocument.xref.stats}));v.on("GetAnnotations",(function({pageIndex:e,intent:t}){return a.getPage(e).then((function(e){return e.getAnnotationsData(t)}))}));v.on("GetOperatorList",(function(e,t){var i=e.pageIndex;a.getPage(i).then((function(a){var n=new h(`GetOperatorList: page ${i}`);k(n);const s=f>=r.VerbosityLevel.INFOS?Date.now():0;a.getOperatorList({handler:v,sink:t,task:n,intent:e.intent,renderInteractiveForms:e.renderInteractiveForms}).then((function(e){S(n);s&&(0,r.info)(`page=${i+1} - getOperatorList: time=`+`${Date.now()-s}ms, len=${e.length}`);t.close()}),(function(e){S(n);if(!n.terminated){v.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});t.error(e)}}))}))}),this);v.on("GetTextContent",(function(e,t){var i=e.pageIndex;t.onPull=function(e){};t.onCancel=function(e){};a.getPage(i).then((function(a){var n=new h("GetTextContent: page "+i);k(n);const s=f>=r.VerbosityLevel.INFOS?Date.now():0;a.extractTextContent({handler:v,task:n,sink:t,normalizeWhitespace:e.normalizeWhitespace,combineTextItems:e.combineTextItems}).then((function(){S(n);s&&(0,r.info)(`page=${i+1} - getTextContent: time=`+`${Date.now()-s}ms`);t.close()}),(function(e){S(n);n.terminated||t.error(e)}))}))}));v.on("FontFallback",(function(e){return a.fontFallback(e.id,v)}));v.on("Cleanup",(function(e){return a.cleanup()}));v.on("Terminate",(function(e){s=!0;const t=[];if(a){a.terminate(new r.AbortException("Worker was terminated."));const e=a.cleanup();t.push(e);a=null}else(0,i.clearPrimitiveCaches)();u&&u(new r.AbortException("Worker was terminated."));d.forEach((function(e){t.push(e.finished);e.terminate()}));return Promise.all(t).then((function(){v.destroy();v=null}))}));v.on("Ready",(function(t){!function(e){function t(e){w();v.send("GetDoc",{pdfInfo:e})}function i(e){w();if(e instanceof r.PasswordException){var t=new h(`PasswordException: response ${e.code}`);k(t);v.sendWithPromise("PasswordRequest",e).then((function(e){S(t);a.updatePassword(e.password);n()})).catch((function(){S(t);v.send("DocException",e)}))}else e instanceof r.InvalidPDFException||e instanceof r.MissingPDFException||e instanceof r.UnexpectedResponseException||e instanceof r.UnknownErrorException?v.send("DocException",e):v.send("DocException",new r.UnknownErrorException(e.message,e.toString()))}function n(){w();C(!1).then(t,(function(e){w();if(e instanceof l.XRefParseException){a.requestLoadedStream();a.onLoadedStream().then((function(){w();C(!0).then(t,i)}))}else i(e)}),i)}w();x(e,{forceDataSchema:e.disableCreateObjectURL,maxImageSize:e.maxImageSize,disableFontFace:e.disableFontFace,nativeImageDecoderSupport:e.nativeImageDecoderSupport,ignoreErrors:e.ignoreErrors,isEvalSupported:e.isEvalSupported}).then((function(e){if(s){e.terminate(new r.AbortException("Worker was terminated."));throw new Error("Worker was terminated")}(a=e).onLoadedStream().then((function(e){v.send("DataLoaded",{length:e.bytes.byteLength})}))})).then(n,i)}(e);e=null}));return y},initializeFromPort(e){var t=new o.MessageHandler("worker","main",e);d.setup(t,e);t.send("ready",null)}};t.WorkerMessageHandler=d;"undefined"==typeof window&&!s.isNodeJS&&"undefined"!=typeof self&&("function"==typeof(u=self).postMessage&&"onmessage"in u)&&d.initializeFromPort(self)},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.arrayByteLength=d;t.arraysToBytes=function(e){const t=e.length;if(1===t&&e[0]instanceof Uint8Array)return e[0];let a=0;for(let r=0;r<t;r++)a+=d(e[r]);let r=0;const i=new Uint8Array(a);for(let a=0;a<t;a++){let t=e[a];t instanceof Uint8Array||(t="string"==typeof t?u(t):new Uint8Array(t));const n=t.byteLength;i.set(t,r);r+=n}return i};t.assert=o;t.bytesToString=function(e){o(null!==e&&"object"==typeof e&&void 0!==e.length,"Invalid argument for bytesToString");const t=e.length;if(t<8192)return String.fromCharCode.apply(null,e);const a=[];for(let r=0;r<t;r+=8192){const i=Math.min(r+8192,t),n=e.subarray(r,i);a.push(String.fromCharCode.apply(null,n))}return a.join("")};t.createPromiseCapability=function(){const e=Object.create(null);let t=!1;Object.defineProperty(e,"settled",{get:()=>t});e.promise=new Promise((function(a,r){e.resolve=function(e){t=!0;a(e)};e.reject=function(e){t=!0;r(e)}}));return e};t.getVerbosityLevel=function(){return i};t.info=function(e){i>=r.INFOS&&console.log(`Info: ${e}`)};t.isArrayBuffer=function(e){return"object"==typeof e&&null!==e&&void 0!==e.byteLength};t.isArrayEqual=function(e,t){if(e.length!==t.length)return!1;return e.every((function(e,a){return e===t[a]}))};t.isBool=function(e){return"boolean"==typeof e};t.isEmptyObj=function(e){for(const t in e)return!1;return!0};t.isNum=function(e){return"number"==typeof e};t.isString=function(e){return"string"==typeof e};t.isSameOrigin=function(e,t){let a;try{a=new URL(e);if(!a.origin||"null"===a.origin)return!1}catch(e){return!1}const r=new URL(t,a);return a.origin===r.origin};t.createValidAbsoluteUrl=function(e,t){if(!e)return null;try{const a=t?new URL(e,t):new URL(e);if(function(e){if(!e)return!1;switch(e.protocol){case"http:":case"https:":case"ftp:":case"mailto:":case"tel:":return!0;default:return!1}}(a))return a}catch(e){}return null};t.removeNullCharacters=function(e){if("string"!=typeof e){n("The argument for removeNullCharacters must be a string.");return e}return e.replace(h,"")};t.setVerbosityLevel=function(e){Number.isInteger(e)&&(i=e)};t.shadow=c;t.string32=function(e){return String.fromCharCode(e>>24&255,e>>16&255,e>>8&255,255&e)};t.stringToBytes=u;t.stringToPDFString=function(e){const t=e.length,a=[];if("þ"===e[0]&&"ÿ"===e[1])for(let r=2;r<t;r+=2)a.push(String.fromCharCode(e.charCodeAt(r)<<8|e.charCodeAt(r+1)));else if("ÿ"===e[0]&&"þ"===e[1])for(let r=2;r<t;r+=2)a.push(String.fromCharCode(e.charCodeAt(r+1)<<8|e.charCodeAt(r)));else for(let r=0;r<t;++r){const t=b[e.charCodeAt(r)];a.push(t?String.fromCharCode(t):e.charAt(r))}return a.join("")};t.stringToUTF8String=function(e){return decodeURIComponent(escape(e))};t.utf8StringToString=function(e){return unescape(encodeURIComponent(e))};t.warn=n;t.unreachable=s;t.IsEvalSupportedCached=t.IsLittleEndianCached=t.createObjectURL=t.FormatError=t.Util=t.UnknownErrorException=t.UnexpectedResponseException=t.TextRenderingMode=t.StreamType=t.PermissionFlag=t.PasswordResponses=t.PasswordException=t.NativeImageDecoding=t.MissingPDFException=t.InvalidPDFException=t.AbortException=t.CMapCompressionType=t.ImageKind=t.FontType=t.AnnotationType=t.AnnotationStateModelType=t.AnnotationReviewState=t.AnnotationReplyType=t.AnnotationMarkedState=t.AnnotationFlag=t.AnnotationFieldFlag=t.AnnotationBorderStyleType=t.UNSUPPORTED_FEATURES=t.VerbosityLevel=t.OPS=t.IDENTITY_MATRIX=t.FONT_IDENTITY_MATRIX=t.BaseException=void 0;a(3);t.IDENTITY_MATRIX=[1,0,0,1,0,0];t.FONT_IDENTITY_MATRIX=[.001,0,0,.001,0,0];t.NativeImageDecoding={NONE:"none",DECODE:"decode",DISPLAY:"display"};t.PermissionFlag={PRINT:4,MODIFY_CONTENTS:8,COPY:16,MODIFY_ANNOTATIONS:32,FILL_INTERACTIVE_FORMS:256,COPY_FOR_ACCESSIBILITY:512,ASSEMBLE:1024,PRINT_HIGH_QUALITY:2048};t.TextRenderingMode={FILL:0,STROKE:1,FILL_STROKE:2,INVISIBLE:3,FILL_ADD_TO_PATH:4,STROKE_ADD_TO_PATH:5,FILL_STROKE_ADD_TO_PATH:6,ADD_TO_PATH:7,FILL_STROKE_MASK:3,ADD_TO_PATH_FLAG:4};t.ImageKind={GRAYSCALE_1BPP:1,RGB_24BPP:2,RGBA_32BPP:3};t.AnnotationType={TEXT:1,LINK:2,FREETEXT:3,LINE:4,SQUARE:5,CIRCLE:6,POLYGON:7,POLYLINE:8,HIGHLIGHT:9,UNDERLINE:10,SQUIGGLY:11,STRIKEOUT:12,STAMP:13,CARET:14,INK:15,POPUP:16,FILEATTACHMENT:17,SOUND:18,MOVIE:19,WIDGET:20,SCREEN:21,PRINTERMARK:22,TRAPNET:23,WATERMARK:24,THREED:25,REDACT:26};t.AnnotationStateModelType={MARKED:"Marked",REVIEW:"Review"};t.AnnotationMarkedState={MARKED:"Marked",UNMARKED:"Unmarked"};t.AnnotationReviewState={ACCEPTED:"Accepted",REJECTED:"Rejected",CANCELLED:"Cancelled",COMPLETED:"Completed",NONE:"None"};t.AnnotationReplyType={GROUP:"Group",REPLY:"R"};t.AnnotationFlag={INVISIBLE:1,HIDDEN:2,PRINT:4,NOZOOM:8,NOROTATE:16,NOVIEW:32,READONLY:64,LOCKED:128,TOGGLENOVIEW:256,LOCKEDCONTENTS:512};t.AnnotationFieldFlag={READONLY:1,REQUIRED:2,NOEXPORT:4,MULTILINE:4096,PASSWORD:8192,NOTOGGLETOOFF:16384,RADIO:32768,PUSHBUTTON:65536,COMBO:131072,EDIT:262144,SORT:524288,FILESELECT:1048576,MULTISELECT:2097152,DONOTSPELLCHECK:4194304,DONOTSCROLL:8388608,COMB:16777216,RICHTEXT:33554432,RADIOSINUNISON:33554432,COMMITONSELCHANGE:67108864};t.AnnotationBorderStyleType={SOLID:1,DASHED:2,BEVELED:3,INSET:4,UNDERLINE:5};t.StreamType={UNKNOWN:"UNKNOWN",FLATE:"FLATE",LZW:"LZW",DCT:"DCT",JPX:"JPX",JBIG:"JBIG",A85:"A85",AHX:"AHX",CCF:"CCF",RLX:"RLX"};t.FontType={UNKNOWN:"UNKNOWN",TYPE1:"TYPE1",TYPE1C:"TYPE1C",CIDFONTTYPE0:"CIDFONTTYPE0",CIDFONTTYPE0C:"CIDFONTTYPE0C",TRUETYPE:"TRUETYPE",CIDFONTTYPE2:"CIDFONTTYPE2",TYPE3:"TYPE3",OPENTYPE:"OPENTYPE",TYPE0:"TYPE0",MMTYPE1:"MMTYPE1"};const r={ERRORS:0,WARNINGS:1,INFOS:5};t.VerbosityLevel=r;t.CMapCompressionType={NONE:0,BINARY:1,STREAM:2};t.OPS={dependency:1,setLineWidth:2,setLineCap:3,setLineJoin:4,setMiterLimit:5,setDash:6,setRenderingIntent:7,setFlatness:8,setGState:9,save:10,restore:11,transform:12,moveTo:13,lineTo:14,curveTo:15,curveTo2:16,curveTo3:17,closePath:18,rectangle:19,stroke:20,closeStroke:21,fill:22,eoFill:23,fillStroke:24,eoFillStroke:25,closeFillStroke:26,closeEOFillStroke:27,endPath:28,clip:29,eoClip:30,beginText:31,endText:32,setCharSpacing:33,setWordSpacing:34,setHScale:35,setLeading:36,setFont:37,setTextRenderingMode:38,setTextRise:39,moveText:40,setLeadingMoveText:41,setTextMatrix:42,nextLine:43,showText:44,showSpacedText:45,nextLineShowText:46,nextLineSetSpacingShowText:47,setCharWidth:48,setCharWidthAndBounds:49,setStrokeColorSpace:50,setFillColorSpace:51,setStrokeColor:52,setStrokeColorN:53,setFillColor:54,setFillColorN:55,setStrokeGray:56,setFillGray:57,setStrokeRGBColor:58,setFillRGBColor:59,setStrokeCMYKColor:60,setFillCMYKColor:61,shadingFill:62,beginInlineImage:63,beginImageData:64,endInlineImage:65,paintXObject:66,markPoint:67,markPointProps:68,beginMarkedContent:69,beginMarkedContentProps:70,endMarkedContent:71,beginCompat:72,endCompat:73,paintFormXObjectBegin:74,paintFormXObjectEnd:75,beginGroup:76,endGroup:77,beginAnnotations:78,endAnnotations:79,beginAnnotation:80,endAnnotation:81,paintJpegXObject:82,paintImageMaskXObject:83,paintImageMaskXObjectGroup:84,paintImageXObject:85,paintInlineImageXObject:86,paintInlineImageXObjectGroup:87,paintImageXObjectRepeat:88,paintImageMaskXObjectRepeat:89,paintSolidColorImageMask:90,constructPath:91};t.UNSUPPORTED_FEATURES={unknown:"unknown",forms:"forms",javaScript:"javaScript",smask:"smask",shadingPattern:"shadingPattern",font:"font"};t.PasswordResponses={NEED_PASSWORD:1,INCORRECT_PASSWORD:2};let i=r.WARNINGS;function n(e){i>=r.WARNINGS&&console.log(`Warning: ${e}`)}function s(e){throw new Error(e)}function o(e,t){e||s(t)}function c(e,t,a){Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!1});return a}const l=function(){function e(t){this.constructor===e&&s("Cannot initialize BaseException.");this.message=t;this.name=this.constructor.name}e.prototype=new Error;e.constructor=e;return e}();t.BaseException=l;t.PasswordException=class extends l{constructor(e,t){super(e);this.code=t}};t.UnknownErrorException=class extends l{constructor(e,t){super(e);this.details=t}};t.InvalidPDFException=class extends l{};t.MissingPDFException=class extends l{};t.UnexpectedResponseException=class extends l{constructor(e,t){super(e);this.status=t}};t.FormatError=class extends l{};t.AbortException=class extends l{};const h=/\x00/g;function u(e){o("string"==typeof e,"Invalid argument for stringToBytes");const t=e.length,a=new Uint8Array(t);for(let r=0;r<t;++r)a[r]=255&e.charCodeAt(r);return a}function d(e){if(void 0!==e.length)return e.length;o(void 0!==e.byteLength);return e.byteLength}const f={get value(){return c(this,"value",function(){const e=new Uint8Array(4);e[0]=1;return 1===new Uint32Array(e.buffer,0,1)[0]}())}};t.IsLittleEndianCached=f;const g={get value(){return c(this,"value",function(){try{new Function("");return!0}catch(e){return!1}}())}};t.IsEvalSupportedCached=g;const m=["rgb(",0,",",0,",",0,")"];class p{static makeCssRgb(e,t,a){m[1]=e;m[3]=t;m[5]=a;return m.join("")}static transform(e,t){return[e[0]*t[0]+e[2]*t[1],e[1]*t[0]+e[3]*t[1],e[0]*t[2]+e[2]*t[3],e[1]*t[2]+e[3]*t[3],e[0]*t[4]+e[2]*t[5]+e[4],e[1]*t[4]+e[3]*t[5]+e[5]]}static applyTransform(e,t){return[e[0]*t[0]+e[1]*t[2]+t[4],e[0]*t[1]+e[1]*t[3]+t[5]]}static applyInverseTransform(e,t){const a=t[0]*t[3]-t[1]*t[2];return[(e[0]*t[3]-e[1]*t[2]+t[2]*t[5]-t[4]*t[3])/a,(-e[0]*t[1]+e[1]*t[0]+t[4]*t[1]-t[5]*t[0])/a]}static getAxialAlignedBoundingBox(e,t){const a=p.applyTransform(e,t),r=p.applyTransform(e.slice(2,4),t),i=p.applyTransform([e[0],e[3]],t),n=p.applyTransform([e[2],e[1]],t);return[Math.min(a[0],r[0],i[0],n[0]),Math.min(a[1],r[1],i[1],n[1]),Math.max(a[0],r[0],i[0],n[0]),Math.max(a[1],r[1],i[1],n[1])]}static inverseTransform(e){const t=e[0]*e[3]-e[1]*e[2];return[e[3]/t,-e[1]/t,-e[2]/t,e[0]/t,(e[2]*e[5]-e[4]*e[3])/t,(e[4]*e[1]-e[5]*e[0])/t]}static apply3dTransform(e,t){return[e[0]*t[0]+e[1]*t[1]+e[2]*t[2],e[3]*t[0]+e[4]*t[1]+e[5]*t[2],e[6]*t[0]+e[7]*t[1]+e[8]*t[2]]}static singularValueDecompose2dScale(e){const t=[e[0],e[2],e[1],e[3]],a=e[0]*t[0]+e[1]*t[2],r=e[0]*t[1]+e[1]*t[3],i=e[2]*t[0]+e[3]*t[2],n=e[2]*t[1]+e[3]*t[3],s=(a+n)/2,o=Math.sqrt((a+n)*(a+n)-4*(a*n-i*r))/2,c=s+o||1,l=s-o||1;return[Math.sqrt(c),Math.sqrt(l)]}static normalizeRect(e){const t=e.slice(0);if(e[0]>e[2]){t[0]=e[2];t[2]=e[0]}if(e[1]>e[3]){t[1]=e[3];t[3]=e[1]}return t}static intersect(e,t){function a(e,t){return e-t}const r=[e[0],e[2],t[0],t[2]].sort(a),i=[e[1],e[3],t[1],t[3]].sort(a),n=[];e=p.normalizeRect(e);t=p.normalizeRect(t);if(!(r[0]===e[0]&&r[1]===t[0]||r[0]===t[0]&&r[1]===e[0]))return null;n[0]=r[1];n[2]=r[2];if(!(i[0]===e[1]&&i[1]===t[1]||i[0]===t[1]&&i[1]===e[1]))return null;n[1]=i[1];n[3]=i[2];return n}}t.Util=p;const b=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,728,711,710,729,733,731,730,732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8226,8224,8225,8230,8212,8211,402,8260,8249,8250,8722,8240,8222,8220,8221,8216,8217,8218,8482,64257,64258,321,338,352,376,381,305,322,339,353,382,0,8364];const y=function(){const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return function(t,a,r=!1){if(!r&&URL.createObjectURL){const e=new Blob([t],{type:a});return URL.createObjectURL(e)}let i=`data:${a};base64,`;for(let a=0,r=t.length;a<r;a+=3){const n=255&t[a],s=255&t[a+1],o=255&t[a+2];i+=e[n>>2]+e[(3&n)<<4|s>>4]+e[a+1<r?(15&s)<<2|o>>6:64]+e[a+2<r?63&o:64]}return i}}();t.createObjectURL=y},function(e,t,a){},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.clearPrimitiveCaches=function(){n._clearCache();i._clearCache();o._clearCache()};t.isEOF=function(e){return e===r};t.isCmd=function(e,t){return e instanceof n&&(void 0===t||e.cmd===t)};t.isDict=u;t.isName=h;t.isRef=function(e){return e instanceof o};t.isRefsEqual=function(e,t){return e.num===t.num&&e.gen===t.gen};t.isStream=function(e){return"object"==typeof e&&null!==e&&void 0!==e.getBytes};t.RefSetCache=t.RefSet=t.Ref=t.Name=t.Dict=t.Cmd=t.EOF=void 0;a(2);var r={};t.EOF=r;var i=function(){let e=Object.create(null);function t(e){this.name=e}t.prototype={};t.get=function(a){var r=e[a];return r||(e[a]=new t(a))};t._clearCache=function(){e=Object.create(null)};return t}();t.Name=i;var n=function(){let e=Object.create(null);function t(e){this.cmd=e}t.prototype={};t.get=function(a){var r=e[a];return r||(e[a]=new t(a))};t._clearCache=function(){e=Object.create(null)};return t}();t.Cmd=n;var s=function(){var e=function(){return e};function t(t){this._map=Object.create(null);this.xref=t;this.objId=null;this.suppressEncryption=!1;this.__nonSerializable__=e}t.prototype={assignXref:function(e){this.xref=e},get(e,t,a){let r=this._map[e];if(void 0===r&&void 0!==t){r=this._map[t];void 0===r&&void 0!==a&&(r=this._map[a])}return r instanceof o&&this.xref?this.xref.fetch(r,this.suppressEncryption):r},async getAsync(e,t,a){let r=this._map[e];if(void 0===r&&void 0!==t){r=this._map[t];void 0===r&&void 0!==a&&(r=this._map[a])}return r instanceof o&&this.xref?this.xref.fetchAsync(r,this.suppressEncryption):r},getArray(e,t,a){let r=this.get(e,t,a);if(!Array.isArray(r)||!this.xref)return r;r=r.slice();for(let e=0,t=r.length;e<t;e++)r[e]instanceof o&&(r[e]=this.xref.fetch(r[e],this.suppressEncryption));return r},getRaw:function(e){return this._map[e]},getKeys:function(){return Object.keys(this._map)},set:function(e,t){this._map[e]=t},has:function(e){return void 0!==this._map[e]},forEach:function(e){for(var t in this._map)e(t,this.get(t))}};t.empty=new t(null);t.merge=function(e,a){const r=new t(e);for(let e=0,t=a.length;e<t;e++){const t=a[e];if(u(t))for(const e in t._map)void 0===r._map[e]&&(r._map[e]=t._map[e])}return r};return t}();t.Dict=s;var o=function(){let e=Object.create(null);function t(e,t){this.num=e;this.gen=t}t.prototype={toString:function(){return 0===this.gen?`${this.num}R`:`${this.num}R${this.gen}`}};t.get=function(a,r){const i=0===r?`${a}R`:`${a}R${r}`,n=e[i];return n||(e[i]=new t(a,r))};t._clearCache=function(){e=Object.create(null)};return t}();t.Ref=o;var c=function(){function e(){this.dict=Object.create(null)}e.prototype={has:function(e){return e.toString()in this.dict},put:function(e){this.dict[e.toString()]=!0},remove:function(e){delete this.dict[e.toString()]}};return e}();t.RefSet=c;var l=function(){function e(){this.dict=Object.create(null)}e.prototype={get:function(e){return this.dict[e.toString()]},has:function(e){return e.toString()in this.dict},put:function(e,t){this.dict[e.toString()]=t},putAlias:function(e,t){this.dict[e.toString()]=this.get(t)},forEach:function(e){for(const t in this.dict)e(this.dict[t])},clear:function(){this.dict=Object.create(null)}};return e}();t.RefSetCache=l;function h(e,t){return e instanceof i&&(void 0===t||e.name===t)}function u(e,t){return e instanceof s&&(void 0===t||h(e.get("Type"),t))}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.NetworkPdfManager=t.LocalPdfManager=void 0;var r=a(2),i=a(6),n=a(7),s=a(8),o=a(11);class c{constructor(){this.constructor===c&&(0,r.unreachable)("Cannot initialize BasePdfManager.")}get docId(){return this._docId}get password(){return this._password}get docBaseUrl(){let e=null;if(this._docBaseUrl){const t=(0,r.createValidAbsoluteUrl)(this._docBaseUrl);t?e=t.href:(0,r.warn)(`Invalid absolute docBaseUrl: "${this._docBaseUrl}".`)}return(0,r.shadow)(this,"docBaseUrl",e)}onLoadedStream(){(0,r.unreachable)("Abstract method `onLoadedStream` called")}ensureDoc(e,t){return this.ensure(this.pdfDocument,e,t)}ensureXRef(e,t){return this.ensure(this.pdfDocument.xref,e,t)}ensureCatalog(e,t){return this.ensure(this.pdfDocument.catalog,e,t)}getPage(e){return this.pdfDocument.getPage(e)}fontFallback(e,t){return this.pdfDocument.fontFallback(e,t)}cleanup(){return this.pdfDocument.cleanup()}async ensure(e,t,a){(0,r.unreachable)("Abstract method `ensure` called")}requestRange(e,t){(0,r.unreachable)("Abstract method `requestRange` called")}requestLoadedStream(){(0,r.unreachable)("Abstract method `requestLoadedStream` called")}sendProgressiveData(e){(0,r.unreachable)("Abstract method `sendProgressiveData` called")}updatePassword(e){this._password=e}terminate(e){(0,r.unreachable)("Abstract method `terminate` called")}}t.LocalPdfManager=class extends c{constructor(e,t,a,r,i){super();this._docId=e;this._password=a;this._docBaseUrl=i;this.evaluatorOptions=r;const n=new o.Stream(t);this.pdfDocument=new s.PDFDocument(this,n);this._loadedStreamPromise=Promise.resolve(n)}async ensure(e,t,a){const r=e[t];return"function"==typeof r?r.apply(e,a):r}requestRange(e,t){return Promise.resolve()}requestLoadedStream(){}onLoadedStream(){return this._loadedStreamPromise}terminate(e){}};t.NetworkPdfManager=class extends c{constructor(e,t,a,r,n){super();this._docId=e;this._password=a.password;this._docBaseUrl=n;this.msgHandler=a.msgHandler;this.evaluatorOptions=r;this.streamManager=new i.ChunkedStreamManager(t,{msgHandler:a.msgHandler,length:a.length,disableAutoFetch:a.disableAutoFetch,rangeChunkSize:a.rangeChunkSize});this.pdfDocument=new s.PDFDocument(this,this.streamManager.getStream())}async ensure(e,t,a){try{const r=e[t];return"function"==typeof r?r.apply(e,a):r}catch(r){if(!(r instanceof n.MissingDataException))throw r;await this.requestRange(r.begin,r.end);return this.ensure(e,t,a)}}requestRange(e,t){return this.streamManager.requestRange(e,t)}requestLoadedStream(){this.streamManager.requestAllChunks()}sendProgressiveData(e){this.streamManager.onReceiveData({chunk:e})}onLoadedStream(){return this.streamManager.onLoadedStream()}terminate(e){this.streamManager.abort(e)}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.ChunkedStreamManager=t.ChunkedStream=void 0;var r=a(2),i=a(7);class n{constructor(e,t,a){this.bytes=new Uint8Array(e);this.start=0;this.pos=0;this.end=e;this.chunkSize=t;this.loadedChunks=[];this.numChunksLoaded=0;this.numChunks=Math.ceil(e/t);this.manager=a;this.progressiveDataLength=0;this.lastSuccessfulEnsureByteChunk=-1}getMissingChunks(){const e=[];for(let t=0,a=this.numChunks;t<a;++t)this.loadedChunks[t]||e.push(t);return e}getBaseStreams(){return[this]}allChunksLoaded(){return this.numChunksLoaded===this.numChunks}onReceiveData(e,t){const a=this.chunkSize;if(e%a!=0)throw new Error(`Bad begin offset: ${e}`);const r=e+t.byteLength;if(r%a!=0&&r!==this.bytes.length)throw new Error(`Bad end offset: ${r}`);this.bytes.set(new Uint8Array(t),e);const i=Math.floor(e/a),n=Math.floor((r-1)/a)+1;for(let e=i;e<n;++e)if(!this.loadedChunks[e]){this.loadedChunks[e]=!0;++this.numChunksLoaded}}onReceiveProgressiveData(e){let t=this.progressiveDataLength;const a=Math.floor(t/this.chunkSize);this.bytes.set(new Uint8Array(e),t);t+=e.byteLength;this.progressiveDataLength=t;const r=t>=this.end?this.numChunks:Math.floor(t/this.chunkSize);for(let e=a;e<r;++e)if(!this.loadedChunks[e]){this.loadedChunks[e]=!0;++this.numChunksLoaded}}ensureByte(e){if(e<this.progressiveDataLength)return;const t=Math.floor(e/this.chunkSize);if(t!==this.lastSuccessfulEnsureByteChunk){if(!this.loadedChunks[t])throw new i.MissingDataException(e,e+1);this.lastSuccessfulEnsureByteChunk=t}}ensureRange(e,t){if(e>=t)return;if(t<=this.progressiveDataLength)return;const a=this.chunkSize,r=Math.floor(e/a),n=Math.floor((t-1)/a)+1;for(let a=r;a<n;++a)if(!this.loadedChunks[a])throw new i.MissingDataException(e,t)}nextEmptyChunk(e){const t=this.numChunks;for(let a=0;a<t;++a){const r=(e+a)%t;if(!this.loadedChunks[r])return r}return null}hasChunk(e){return!!this.loadedChunks[e]}get length(){return this.end-this.start}get isEmpty(){return 0===this.length}getByte(){const e=this.pos;if(e>=this.end)return-1;e>=this.progressiveDataLength&&this.ensureByte(e);return this.bytes[this.pos++]}getUint16(){const e=this.getByte(),t=this.getByte();return-1===e||-1===t?-1:(e<<8)+t}getInt32(){return(this.getByte()<<24)+(this.getByte()<<16)+(this.getByte()<<8)+this.getByte()}getBytes(e,t=!1){const a=this.bytes,r=this.pos,i=this.end;if(!e){i>this.progressiveDataLength&&this.ensureRange(r,i);const e=a.subarray(r,i);return t?new Uint8ClampedArray(e):e}let n=r+e;n>i&&(n=i);n>this.progressiveDataLength&&this.ensureRange(r,n);this.pos=n;const s=a.subarray(r,n);return t?new Uint8ClampedArray(s):s}peekByte(){const e=this.getByte();-1!==e&&this.pos--;return e}peekBytes(e,t=!1){const a=this.getBytes(e,t);this.pos-=a.length;return a}getByteRange(e,t){e<0&&(e=0);t>this.end&&(t=this.end);t>this.progressiveDataLength&&this.ensureRange(e,t);return this.bytes.subarray(e,t)}skip(e){e||(e=1);this.pos+=e}reset(){this.pos=this.start}moveStart(){this.start=this.pos}makeSubStream(e,t,a){t?e+t>this.progressiveDataLength&&this.ensureRange(e,e+t):e>=this.progressiveDataLength&&this.ensureByte(e);function r(){}r.prototype=Object.create(this);r.prototype.getMissingChunks=function(){const e=this.chunkSize,t=Math.floor(this.start/e),a=Math.floor((this.end-1)/e)+1,r=[];for(let e=t;e<a;++e)this.loadedChunks[e]||r.push(e);return r};r.prototype.allChunksLoaded=function(){return this.numChunksLoaded===this.numChunks||0===this.getMissingChunks().length};const i=new r;i.pos=i.start=e;i.end=e+t||this.end;i.dict=a;return i}}t.ChunkedStream=n;t.ChunkedStreamManager=class{constructor(e,t){this.length=t.length;this.chunkSize=t.rangeChunkSize;this.stream=new n(this.length,this.chunkSize,this);this.pdfNetworkStream=e;this.disableAutoFetch=t.disableAutoFetch;this.msgHandler=t.msgHandler;this.currRequestId=0;this.chunksNeededByRequest=Object.create(null);this.requestsByChunk=Object.create(null);this.promisesByRequest=Object.create(null);this.progressiveDataLength=0;this.aborted=!1;this._loadedStreamCapability=(0,r.createPromiseCapability)()}onLoadedStream(){return this._loadedStreamCapability.promise}sendRequest(e,t){const a=this.pdfNetworkStream.getRangeReader(e,t);a.isStreamingSupported||(a.onProgress=this.onProgress.bind(this));let i=[],n=0;new Promise((e,t)=>{const s=o=>{try{if(!o.done){const e=o.value;i.push(e);n+=(0,r.arrayByteLength)(e);a.isStreamingSupported&&this.onProgress({loaded:n});a.read().then(s,t);return}const c=(0,r.arraysToBytes)(i);i=null;e(c)}catch(e){t(e)}};a.read().then(s,t)}).then(t=>{this.aborted||this.onReceiveData({chunk:t,begin:e})})}requestAllChunks(){const e=this.stream.getMissingChunks();this._requestChunks(e);return this._loadedStreamCapability.promise}_requestChunks(e){const t=this.currRequestId++,a=Object.create(null);this.chunksNeededByRequest[t]=a;for(const t of e)this.stream.hasChunk(t)||(a[t]=!0);if((0,r.isEmptyObj)(a))return Promise.resolve();const i=(0,r.createPromiseCapability)();this.promisesByRequest[t]=i;const n=[];for(let e in a){e|=0;if(!(e in this.requestsByChunk)){this.requestsByChunk[e]=[];n.push(e)}this.requestsByChunk[e].push(t)}if(!n.length)return i.promise;const s=this.groupChunks(n);for(const e of s){const t=e.beginChunk*this.chunkSize,a=Math.min(e.endChunk*this.chunkSize,this.length);this.sendRequest(t,a)}return i.promise}getStream(){return this.stream}requestRange(e,t){t=Math.min(t,this.length);const a=this.getBeginChunk(e),r=this.getEndChunk(t),i=[];for(let e=a;e<r;++e)i.push(e);return this._requestChunks(i)}requestRanges(e=[]){const t=[];for(const a of e){const e=this.getBeginChunk(a.begin),r=this.getEndChunk(a.end);for(let a=e;a<r;++a)t.includes(a)||t.push(a)}t.sort((function(e,t){return e-t}));return this._requestChunks(t)}groupChunks(e){const t=[];let a=-1,r=-1;for(let i=0,n=e.length;i<n;++i){const n=e[i];a<0&&(a=n);if(r>=0&&r+1!==n){t.push({beginChunk:a,endChunk:r+1});a=n}i+1===e.length&&t.push({beginChunk:a,endChunk:n+1});r=n}return t}onProgress(e){this.msgHandler.send("DocProgress",{loaded:this.stream.numChunksLoaded*this.chunkSize+e.loaded,total:this.length})}onReceiveData(e){const t=e.chunk,a=void 0===e.begin,i=a?this.progressiveDataLength:e.begin,n=i+t.byteLength,s=Math.floor(i/this.chunkSize),o=n<this.length?Math.floor(n/this.chunkSize):Math.ceil(n/this.chunkSize);if(a){this.stream.onReceiveProgressiveData(t);this.progressiveDataLength=n}else this.stream.onReceiveData(i,t);this.stream.allChunksLoaded()&&this._loadedStreamCapability.resolve(this.stream);const c=[];for(let e=s;e<o;++e){const t=this.requestsByChunk[e]||[];delete this.requestsByChunk[e];for(const a of t){const t=this.chunksNeededByRequest[a];e in t&&delete t[e];(0,r.isEmptyObj)(t)&&c.push(a)}}if(!this.disableAutoFetch&&(0,r.isEmptyObj)(this.requestsByChunk)){let e;if(1===this.stream.numChunksLoaded){const t=this.stream.numChunks-1;this.stream.hasChunk(t)||(e=t)}else e=this.stream.nextEmptyChunk(o);Number.isInteger(e)&&this._requestChunks([e])}for(const e of c){const t=this.promisesByRequest[e];delete this.promisesByRequest[e];t.resolve()}this.msgHandler.send("DocProgress",{loaded:this.stream.numChunksLoaded*this.chunkSize,total:this.length})}onError(e){this._loadedStreamCapability.reject(e)}getBeginChunk(e){return Math.floor(e/this.chunkSize)}getEndChunk(e){return Math.floor((e-1)/this.chunkSize)+1}abort(e){this.aborted=!0;this.pdfNetworkStream&&this.pdfNetworkStream.cancelAllRequests(e);for(const t in this.promisesByRequest)this.promisesByRequest[t].reject(e)}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getLookupTableFactory=function(e){let t;return function(){if(e){t=Object.create(null);e(t);e=null}return t}};t.getInheritableProperty=function({dict:e,key:t,getArray:a=!1,stopWhenFound:i=!0}){let n,s=0;for(;e;){const o=a?e.getArray(t):e.get(t);if(void 0!==o){if(i)return o;n||(n=[]);n.push(o)}if(++s>100){(0,r.warn)(`getInheritableProperty: maximum loop count exceeded for "${t}"`);break}e=e.get("Parent")}return n};t.toRomanNumerals=function(e,t=!1){(0,r.assert)(Number.isInteger(e)&&e>0,"The number should be a positive integer.");const a=[];let i;for(;e>=1e3;){e-=1e3;a.push("M")}i=e/100|0;e%=100;a.push(o[i]);i=e/10|0;e%=10;a.push(o[10+i]);a.push(o[20+e]);const n=a.join("");return t?n.toLowerCase():n};t.log2=function(e){if(e<=0)return 0;return Math.ceil(Math.log2(e))};t.readInt8=function(e,t){return e[t]<<24>>24};t.readUint16=function(e,t){return e[t]<<8|e[t+1]};t.readUint32=function(e,t){return(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])>>>0};t.isWhiteSpace=function(e){return 32===e||9===e||13===e||10===e};t.XRefParseException=t.XRefEntryException=t.MissingDataException=void 0;var r=a(2);class i extends r.BaseException{constructor(e,t){super(`Missing data [${e}, ${t})`);this.begin=e;this.end=t}}t.MissingDataException=i;class n extends r.BaseException{}t.XRefEntryException=n;class s extends r.BaseException{}t.XRefParseException=s;const o=["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM","","X","XX","XXX","XL","L","LX","LXX","LXXX","XC","","I","II","III","IV","V","VI","VII","VIII","IX"]},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PDFDocument=t.Page=void 0;var r=a(2),i=a(9),n=a(4),s=a(7),o=a(11),c=a(23),l=a(21),h=a(10),u=a(24),d=a(25),f=a(39);const g=[0,0,612,792];function m(e,t){return"display"===t&&e.viewable||"print"===t&&e.printable}class p{constructor({pdfManager:e,xref:t,pageIndex:a,pageDict:r,ref:i,fontCache:n,builtInCMapCache:s,pdfFunctionFactory:o}){this.pdfManager=e;this.pageIndex=a;this.pageDict=r;this.xref=t;this.ref=i;this.fontCache=n;this.builtInCMapCache=s;this.pdfFunctionFactory=o;this.evaluatorOptions=e.evaluatorOptions;this.resourcesPromise=null;const c={obj:0};this.idFactory={createObjId:()=>`p${a}_${++c.obj}`,getDocId:()=>`g_${e.docId}`}}_getInheritableProperty(e,t=!1){const a=(0,s.getInheritableProperty)({dict:this.pageDict,key:e,getArray:t,stopWhenFound:!1});return Array.isArray(a)?1!==a.length&&(0,n.isDict)(a[0])?n.Dict.merge(this.xref,a):a[0]:a}get content(){return this.pageDict.get("Contents")}get resources(){return(0,r.shadow)(this,"resources",this._getInheritableProperty("Resources")||n.Dict.empty)}_getBoundingBox(e){const t=this._getInheritableProperty(e,!0);if(Array.isArray(t)&&4===t.length){if(t[2]-t[0]!=0&&t[3]-t[1]!=0)return t;(0,r.warn)(`Empty /${e} entry.`)}return null}get mediaBox(){return(0,r.shadow)(this,"mediaBox",this._getBoundingBox("MediaBox")||g)}get cropBox(){return(0,r.shadow)(this,"cropBox",this._getBoundingBox("CropBox")||this.mediaBox)}get userUnit(){let e=this.pageDict.get("UserUnit");(!(0,r.isNum)(e)||e<=0)&&(e=1);return(0,r.shadow)(this,"userUnit",e)}get view(){const{cropBox:e,mediaBox:t}=this;let a;if(e===t||(0,r.isArrayEqual)(e,t))a=t;else{const i=r.Util.intersect(e,t);i&&i[2]-i[0]!=0&&i[3]-i[1]!=0?a=i:(0,r.warn)("Empty /CropBox and /MediaBox intersection.")}return(0,r.shadow)(this,"view",a||t)}get rotate(){let e=this._getInheritableProperty("Rotate")||0;e%90!=0?e=0:e>=360?e%=360:e<0&&(e=(e%360+360)%360);return(0,r.shadow)(this,"rotate",e)}getContentStream(){const e=this.content;let t;if(Array.isArray(e)){const a=this.xref,r=[];for(const t of e)r.push(a.fetchIfRef(t));t=new o.StreamsSequenceStream(r)}else t=(0,n.isStream)(e)?e:new o.NullStream;return t}loadResources(e){this.resourcesPromise||(this.resourcesPromise=this.pdfManager.ensure(this,"resources"));return this.resourcesPromise.then(()=>new i.ObjectLoader(this.resources,e,this.xref).load())}getOperatorList({handler:e,sink:t,task:a,intent:i,renderInteractiveForms:n}){const s=this.pdfManager.ensure(this,"getContentStream"),o=this.loadResources(["ExtGState","ColorSpace","Pattern","Shading","XObject","Font"]),c=new d.PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this.idFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,options:this.evaluatorOptions,pdfFunctionFactory:this.pdfFunctionFactory}),l=Promise.all([s,o]).then(([r])=>{const n=new u.OperatorList(i,t,this.pageIndex);e.send("StartRenderPage",{transparency:c.hasBlendModes(this.resources),pageIndex:this.pageIndex,intent:i});return c.getOperatorList({stream:r,task:a,resources:this.resources,operatorList:n}).then((function(){return n}))});return Promise.all([l,this._parsedAnnotations]).then((function([e,t]){if(0===t.length){e.flush(!0);return{length:e.totalLength}}const s=[];for(const e of t)m(e,i)&&s.push(e.getOperatorList(c,a,n));return Promise.all(s).then((function(t){e.addOp(r.OPS.beginAnnotations,[]);for(const a of t)e.addOpList(a);e.addOp(r.OPS.endAnnotations,[]);e.flush(!0);return{length:e.totalLength}}))}))}extractTextContent({handler:e,task:t,normalizeWhitespace:a,sink:r,combineTextItems:i}){const n=this.pdfManager.ensure(this,"getContentStream"),s=this.loadResources(["ExtGState","XObject","Font"]);return Promise.all([n,s]).then(([n])=>new d.PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this.idFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,options:this.evaluatorOptions,pdfFunctionFactory:this.pdfFunctionFactory}).getTextContent({stream:n,task:t,resources:this.resources,normalizeWhitespace:a,combineTextItems:i,sink:r}))}getAnnotationsData(e){return this._parsedAnnotations.then((function(t){const a=[];for(let r=0,i=t.length;r<i;r++)e&&!m(t[r],e)||a.push(t[r].data);return a}))}get annotations(){return(0,r.shadow)(this,"annotations",this._getInheritableProperty("Annots")||[])}get _parsedAnnotations(){const e=this.pdfManager.ensure(this,"annotations").then(()=>{const e=this.annotations,t=[];for(let a=0,r=e.length;a<r;a++)t.push(c.AnnotationFactory.create(this.xref,e[a],this.pdfManager,this.idFactory));return Promise.all(t).then((function(e){return e.filter((function(e){return!!e}))}),(function(e){(0,r.warn)(`_parsedAnnotations: "${e}".`);return[]}))});return(0,r.shadow)(this,"_parsedAnnotations",e)}}t.Page=p;const b=new Uint8Array([37,80,68,70,45]),y=new Uint8Array([115,116,97,114,116,120,114,101,102]),v=new Uint8Array([101,110,100,111,98,106]),w=/^[1-9]\.[0-9]$/;function k(e,t,a=1024,r=!1){const i=t.length,n=e.peekBytes(a),s=n.length-i;if(s<=0)return!1;if(r){const a=i-1;let r=n.length-1;for(;r>=a;){let s=0;for(;s<i&&n[r-s]===t[a-s];)s++;if(s>=i){e.pos+=r-a;return!0}r--}}else{let a=0;for(;a<=s;){let r=0;for(;r<i&&n[a+r]===t[r];)r++;if(r>=i){e.pos+=a;return!0}a++}}return!1}t.PDFDocument=class{constructor(e,t){let a;if((0,n.isStream)(t))a=t;else{if(!(0,r.isArrayBuffer)(t))throw new Error("PDFDocument: Unknown argument type");a=new o.Stream(t)}if(a.length<=0)throw new r.InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes.");this.pdfManager=e;this.stream=a;this.xref=new i.XRef(a,e);this.pdfFunctionFactory=new f.PDFFunctionFactory({xref:this.xref,isEvalSupported:e.evaluatorOptions.isEvalSupported});this._pagePromises=[]}parse(e){this.setup(e);const t=this.catalog.catDict.get("Version");(0,n.isName)(t)&&(this.pdfFormatVersion=t.name);try{this.acroForm=this.catalog.catDict.get("AcroForm");if(this.acroForm){this.xfa=this.acroForm.get("XFA");const e=this.acroForm.get("Fields");Array.isArray(e)&&0!==e.length||this.xfa||(this.acroForm=null)}}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("Cannot fetch AcroForm entry; assuming no AcroForms are present");this.acroForm=null}try{const e=this.catalog.catDict.get("Collection");(0,n.isDict)(e)&&e.getKeys().length>0&&(this.collection=e)}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("Cannot fetch Collection dictionary.")}}get linearization(){let e=null;try{e=h.Linearization.create(this.stream)}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)(e)}return(0,r.shadow)(this,"linearization",e)}get startXRef(){const e=this.stream;let t=0;if(this.linearization){e.reset();k(e,v)&&(t=e.pos+6-e.start)}else{const a=1024,r=y.length;let i=!1,n=e.end;for(;!i&&n>0;){n-=a-r;n<0&&(n=0);e.pos=n;i=k(e,y,a,!0)}if(i){e.skip(9);let a;do{a=e.getByte()}while((0,s.isWhiteSpace)(a));let r="";for(;a>=32&&a<=57;){r+=String.fromCharCode(a);a=e.getByte()}t=parseInt(r,10);isNaN(t)&&(t=0)}}return(0,r.shadow)(this,"startXRef",t)}checkHeader(){const e=this.stream;e.reset();if(!k(e,b))return;e.moveStart();let t,a="";for(;(t=e.getByte())>32&&!(a.length>=12);)a+=String.fromCharCode(t);this.pdfFormatVersion||(this.pdfFormatVersion=a.substring(5))}parseStartXRef(){this.xref.setStartXRef(this.startXRef)}setup(e){this.xref.parse(e);this.catalog=new i.Catalog(this.pdfManager,this.xref)}get numPages(){const e=this.linearization,t=e?e.numPages:this.catalog.numPages;return(0,r.shadow)(this,"numPages",t)}get documentInfo(){const e={Title:r.isString,Author:r.isString,Subject:r.isString,Keywords:r.isString,Creator:r.isString,Producer:r.isString,CreationDate:r.isString,ModDate:r.isString,Trapped:n.isName};let t=this.pdfFormatVersion;if("string"!=typeof t||!w.test(t)){(0,r.warn)(`Invalid PDF header version number: ${t}`);t=null}const a={PDFFormatVersion:t,IsLinearized:!!this.linearization,IsAcroFormPresent:!!this.acroForm,IsXFAPresent:!!this.xfa,IsCollectionPresent:!!this.collection};let i;try{i=this.xref.trailer.get("Info")}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("The document information dictionary is invalid.")}if((0,n.isDict)(i))for(const t of i.getKeys()){const s=i.get(t);if(e[t])e[t](s)?a[t]="string"!=typeof s?s:(0,r.stringToPDFString)(s):(0,r.info)(`Bad value in document info for "${t}".`);else if("string"==typeof t){let e;if((0,r.isString)(s))e=(0,r.stringToPDFString)(s);else{if(!((0,n.isName)(s)||(0,r.isNum)(s)||(0,r.isBool)(s))){(0,r.info)(`Unsupported value in document info for (custom) "${t}".`);continue}e=s}a.Custom||(a.Custom=Object.create(null));a.Custom[t]=e}}return(0,r.shadow)(this,"documentInfo",a)}get fingerprint(){let e;const t=this.xref.trailer.get("ID");e=Array.isArray(t)&&t[0]&&(0,r.isString)(t[0])&&"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"!==t[0]?(0,r.stringToBytes)(t[0]):(0,l.calculateMD5)(this.stream.getByteRange(0,1024),0,1024);const a=[];for(let t=0,r=e.length;t<r;t++){const r=e[t].toString(16);a.push(r.padStart(2,"0"))}return(0,r.shadow)(this,"fingerprint",a.join(""))}_getLinearizationPage(e){const{catalog:t,linearization:a}=this;(0,r.assert)(a&&a.pageFirst===e);const i=n.Ref.get(a.objectNumberFirst,0);return this.xref.fetchAsync(i).then(e=>{if((0,n.isDict)(e,"Page")||(0,n.isDict)(e)&&!e.has("Type")&&e.has("Contents")){i&&!t.pageKidsCountCache.has(i)&&t.pageKidsCountCache.put(i,1);return[e,i]}throw new r.FormatError("The Linearization dictionary doesn't point to a valid Page dictionary.")}).catch(a=>{(0,r.info)(a);return t.getPageDict(e)})}getPage(e){if(void 0!==this._pagePromises[e])return this._pagePromises[e];const{catalog:t,linearization:a}=this,r=a&&a.pageFirst===e?this._getLinearizationPage(e):t.getPageDict(e);return this._pagePromises[e]=r.then(([a,r])=>new p({pdfManager:this.pdfManager,xref:this.xref,pageIndex:e,pageDict:a,ref:r,fontCache:t.fontCache,builtInCMapCache:t.builtInCMapCache,pdfFunctionFactory:this.pdfFunctionFactory}))}checkFirstPage(){return this.getPage(0).catch(async e=>{if(e instanceof s.XRefEntryException){this._pagePromises.length=0;await this.cleanup();throw new s.XRefParseException}})}fontFallback(e,t){return this.catalog.fontFallback(e,t)}async cleanup(){return this.catalog?this.catalog.cleanup():(0,n.clearPrimitiveCaches)()}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.FileSpec=t.XRef=t.ObjectLoader=t.Catalog=void 0;var r=a(2),i=a(4),n=a(10),s=a(7),o=a(21),c=a(22);function l(e){return(0,i.isDict)(e)?e.get("D"):e}class h{constructor(e,t){this.pdfManager=e;this.xref=t;this.catDict=t.getCatalogObj();if(!(0,i.isDict)(this.catDict))throw new r.FormatError("Catalog object is not a dictionary.");this.fontCache=new i.RefSetCache;this.builtInCMapCache=new Map;this.pageKidsCountCache=new i.RefSetCache}get metadata(){const e=this.catDict.getRaw("Metadata");if(!(0,i.isRef)(e))return(0,r.shadow)(this,"metadata",null);const t=!(this.xref.encrypt&&this.xref.encrypt.encryptMetadata),a=this.xref.fetch(e,t);let n;if(a&&(0,i.isDict)(a.dict)){const e=a.dict.get("Type"),t=a.dict.get("Subtype");if((0,i.isName)(e,"Metadata")&&(0,i.isName)(t,"XML"))try{n=(0,r.stringToUTF8String)((0,r.bytesToString)(a.getBytes()))}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("Skipping invalid metadata.")}}return(0,r.shadow)(this,"metadata",n)}get toplevelPagesDict(){const e=this.catDict.get("Pages");if(!(0,i.isDict)(e))throw new r.FormatError("Invalid top-level pages dictionary.");return(0,r.shadow)(this,"toplevelPagesDict",e)}get documentOutline(){let e=null;try{e=this._readDocumentOutline()}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)("Unable to read document outline.")}return(0,r.shadow)(this,"documentOutline",e)}_readDocumentOutline(){let e=this.catDict.get("Outlines");if(!(0,i.isDict)(e))return null;e=e.getRaw("First");if(!(0,i.isRef)(e))return null;const t={items:[]},a=[{obj:e,parent:t}],n=new i.RefSet;n.put(e);const s=this.xref,o=new Uint8ClampedArray(3);for(;a.length>0;){const t=a.shift(),l=s.fetchIfRef(t.obj);if(null===l)continue;if(!l.has("Title"))throw new r.FormatError("Invalid outline item encountered.");const u={url:null,dest:null};h.parseDestDictionary({destDict:l,resultObj:u,docBaseUrl:this.pdfManager.docBaseUrl});const d=l.get("Title"),f=l.get("F")||0,g=l.getArray("C"),m=l.get("Count");let p=o;!Array.isArray(g)||3!==g.length||0===g[0]&&0===g[1]&&0===g[2]||(p=c.ColorSpace.singletons.rgb.getRgb(g,0));const b={dest:u.dest,url:u.url,unsafeUrl:u.unsafeUrl,newWindow:u.newWindow,title:(0,r.stringToPDFString)(d),color:p,count:Number.isInteger(m)?m:void 0,bold:!!(2&f),italic:!!(1&f),items:[]};t.parent.items.push(b);e=l.getRaw("First");if((0,i.isRef)(e)&&!n.has(e)){a.push({obj:e,parent:b});n.put(e)}e=l.getRaw("Next");if((0,i.isRef)(e)&&!n.has(e)){a.push({obj:e,parent:t.parent});n.put(e)}}return t.items.length>0?t.items:null}get permissions(){let e=null;try{e=this._readPermissions()}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)("Unable to read permissions.")}return(0,r.shadow)(this,"permissions",e)}_readPermissions(){const e=this.xref.trailer.get("Encrypt");if(!(0,i.isDict)(e))return null;let t=e.get("P");if(!(0,r.isNum)(t))return null;t+=2**32;const a=[];for(const e in r.PermissionFlag){const i=r.PermissionFlag[e];t&i&&a.push(i)}return a}get numPages(){const e=this.toplevelPagesDict.get("Count");if(!Number.isInteger(e))throw new r.FormatError("Page count in top-level pages dictionary is not an integer.");return(0,r.shadow)(this,"numPages",e)}get destinations(){const e=this._readDests(),t=Object.create(null);if(e instanceof f){const a=e.getAll();for(const e in a)t[e]=l(a[e])}else e instanceof i.Dict&&e.forEach((function(e,a){a&&(t[e]=l(a))}));return(0,r.shadow)(this,"destinations",t)}getDestination(e){const t=this._readDests();return t instanceof f||t instanceof i.Dict?l(t.get(e)||null):null}_readDests(){const e=this.catDict.get("Names");return e&&e.has("Dests")?new f(e.getRaw("Dests"),this.xref):this.catDict.has("Dests")?this.catDict.get("Dests"):void 0}get pageLabels(){let e=null;try{e=this._readPageLabels()}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)("Unable to read page labels.")}return(0,r.shadow)(this,"pageLabels",e)}_readPageLabels(){const e=this.catDict.getRaw("PageLabels");if(!e)return null;const t=new Array(this.numPages);let a=null,n="";const o=new g(e,this.xref).getAll();let c="",l=1;for(let e=0,h=this.numPages;e<h;e++){if(e in o){const t=o[e];if(!(0,i.isDict)(t))throw new r.FormatError("PageLabel is not a dictionary.");if(t.has("Type")&&!(0,i.isName)(t.get("Type"),"PageLabel"))throw new r.FormatError("Invalid type in PageLabel dictionary.");if(t.has("S")){const e=t.get("S");if(!(0,i.isName)(e))throw new r.FormatError("Invalid style in PageLabel dictionary.");a=e.name}else a=null;if(t.has("P")){const e=t.get("P");if(!(0,r.isString)(e))throw new r.FormatError("Invalid prefix in PageLabel dictionary.");n=(0,r.stringToPDFString)(e)}else n="";if(t.has("St")){const e=t.get("St");if(!(Number.isInteger(e)&&e>=1))throw new r.FormatError("Invalid start in PageLabel dictionary.");l=e}else l=1}switch(a){case"D":c=l;break;case"R":case"r":c=(0,s.toRomanNumerals)(l,"r"===a);break;case"A":case"a":const e=26,t=65,i=97,n="a"===a?i:t,o=l-1,h=String.fromCharCode(n+o%e),u=[];for(let t=0,a=o/e|0;t<=a;t++)u.push(h);c=u.join("");break;default:if(a)throw new r.FormatError(`Invalid style "${a}" in PageLabel dictionary.`);c=""}t[e]=n+c;l++}return t}get pageLayout(){const e=this.catDict.get("PageLayout");let t="";if((0,i.isName)(e))switch(e.name){case"SinglePage":case"OneColumn":case"TwoColumnLeft":case"TwoColumnRight":case"TwoPageLeft":case"TwoPageRight":t=e.name}return(0,r.shadow)(this,"pageLayout",t)}get pageMode(){const e=this.catDict.get("PageMode");let t="UseNone";if((0,i.isName)(e))switch(e.name){case"UseNone":case"UseOutlines":case"UseThumbs":case"FullScreen":case"UseOC":case"UseAttachments":t=e.name}return(0,r.shadow)(this,"pageMode",t)}get viewerPreferences(){const e={HideToolbar:r.isBool,HideMenubar:r.isBool,HideWindowUI:r.isBool,FitWindow:r.isBool,CenterWindow:r.isBool,DisplayDocTitle:r.isBool,NonFullScreenPageMode:i.isName,Direction:i.isName,ViewArea:i.isName,ViewClip:i.isName,PrintArea:i.isName,PrintClip:i.isName,PrintScaling:i.isName,Duplex:i.isName,PickTrayByPDFSize:r.isBool,PrintPageRange:Array.isArray,NumCopies:Number.isInteger},t=this.catDict.get("ViewerPreferences"),a=Object.create(null);if((0,i.isDict)(t))for(const i in e){if(!t.has(i))continue;const n=t.get(i);if(!e[i](n)){(0,r.info)(`Bad value in ViewerPreferences for "${i}".`);continue}let s;switch(i){case"NonFullScreenPageMode":switch(n.name){case"UseNone":case"UseOutlines":case"UseThumbs":case"UseOC":s=n.name;break;default:s="UseNone"}break;case"Direction":switch(n.name){case"L2R":case"R2L":s=n.name;break;default:s="L2R"}break;case"ViewArea":case"ViewClip":case"PrintArea":case"PrintClip":switch(n.name){case"MediaBox":case"CropBox":case"BleedBox":case"TrimBox":case"ArtBox":s=n.name;break;default:s="CropBox"}break;case"PrintScaling":switch(n.name){case"None":case"AppDefault":s=n.name;break;default:s="AppDefault"}break;case"Duplex":switch(n.name){case"Simplex":case"DuplexFlipShortEdge":case"DuplexFlipLongEdge":s=n.name;break;default:s="None"}break;case"PrintPageRange":if(n.length%2!=0)break;n.every((e,t,a)=>Number.isInteger(e)&&e>0&&(0===t||e>=a[t-1])&&e<=this.numPages)&&(s=n);break;case"NumCopies":n>0&&(s=n);break;default:(0,r.assert)("boolean"==typeof n);s=n}void 0!==s?a[i]=s:(0,r.info)(`Bad value in ViewerPreferences for "${i}".`)}return(0,r.shadow)(this,"viewerPreferences",a)}get openAction(){const e=this.catDict.get("OpenAction");let t=null;if((0,i.isDict)(e)){const a=new i.Dict(this.xref);a.set("A",e);const r={url:null,dest:null,action:null};h.parseDestDictionary({destDict:a,resultObj:r});if(Array.isArray(r.dest)){t||(t=Object.create(null));t.dest=r.dest}else if(r.action){t||(t=Object.create(null));t.action=r.action}}else if(Array.isArray(e)){t||(t=Object.create(null));t.dest=e}return(0,r.shadow)(this,"openAction",t)}get attachments(){const e=this.catDict.get("Names");let t=null;if(e&&e.has("EmbeddedFiles")){const a=new f(e.getRaw("EmbeddedFiles"),this.xref).getAll();for(const e in a){const i=new m(a[e],this.xref);t||(t=Object.create(null));t[(0,r.stringToPDFString)(e)]=i.serializable}}return(0,r.shadow)(this,"attachments",t)}get javaScript(){const e=this.catDict.get("Names");let t=null;function a(e){const a=e.get("S");if(!(0,i.isName)(a,"JavaScript"))return;let n=e.get("JS");if((0,i.isStream)(n))n=(0,r.bytesToString)(n.getBytes());else if(!(0,r.isString)(n))return;t||(t=[]);t.push((0,r.stringToPDFString)(n))}if(e&&e.has("JavaScript")){const t=new f(e.getRaw("JavaScript"),this.xref).getAll();for(const e in t){const r=t[e];(0,i.isDict)(r)&&a(r)}}const n=this.catDict.get("OpenAction");(0,i.isDict)(n)&&(0,i.isName)(n.get("S"),"JavaScript")&&a(n);return(0,r.shadow)(this,"javaScript",t)}fontFallback(e,t){const a=[];this.fontCache.forEach((function(e){a.push(e)}));return Promise.all(a).then(a=>{for(const r of a)if(r.loadedName===e){r.fallback(t);return}})}cleanup(){(0,i.clearPrimitiveCaches)();this.pageKidsCountCache.clear();const e=[];this.fontCache.forEach((function(t){e.push(t)}));return Promise.all(e).then(e=>{for(const{dict:t}of e)delete t.translated;this.fontCache.clear();this.builtInCMapCache.clear()})}getPageDict(e){const t=(0,r.createPromiseCapability)(),a=[this.catDict.getRaw("Pages")],n=new i.RefSet,s=this.xref,o=this.pageKidsCountCache;let c,l=0;!function h(){for(;a.length;){const u=a.pop();if((0,i.isRef)(u)){c=o.get(u);if(c>0&&l+c<e){l+=c;continue}if(n.has(u)){t.reject(new r.FormatError("Pages tree contains circular reference."));return}n.put(u);s.fetchAsync(u).then((function(r){if((0,i.isDict)(r,"Page")||(0,i.isDict)(r)&&!r.has("Kids"))if(e===l){u&&!o.has(u)&&o.put(u,1);t.resolve([r,u])}else{l++;h()}else{a.push(r);h()}}),t.reject);return}if(!(0,i.isDict)(u)){t.reject(new r.FormatError("Page dictionary kid reference points to wrong type of object."));return}c=u.get("Count");if(Number.isInteger(c)&&c>=0){const t=u.objId;t&&!o.has(t)&&o.put(t,c);if(l+c<=e){l+=c;continue}}const d=u.get("Kids");if(!Array.isArray(d)){if((0,i.isName)(u.get("Type"),"Page")||!u.has("Type")&&u.has("Contents")){if(l===e){t.resolve([u,null]);return}l++;continue}t.reject(new r.FormatError("Page dictionary kids object is not an array."));return}for(let e=d.length-1;e>=0;e--)a.push(d[e])}t.reject(new Error(`Page index ${e} not found.`))}();return t.promise}getPageIndex(e){const t=this.xref;let a=0;return function n(s){return function(a){let n,s=0;return t.fetchAsync(a).then((function(t){if((0,i.isRefsEqual)(a,e)&&!(0,i.isDict)(t,"Page")&&(!(0,i.isDict)(t)||t.has("Type")||!t.has("Contents")))throw new r.FormatError("The reference does not point to a /Page dictionary.");if(!t)return null;if(!(0,i.isDict)(t))throw new r.FormatError("Node must be a dictionary.");n=t.getRaw("Parent");return t.getAsync("Parent")})).then((function(e){if(!e)return null;if(!(0,i.isDict)(e))throw new r.FormatError("Parent must be a dictionary.");return e.getAsync("Kids")})).then((function(e){if(!e)return null;const o=[];let c=!1;for(let n=0,l=e.length;n<l;n++){const l=e[n];if(!(0,i.isRef)(l))throw new r.FormatError("Kid must be a reference.");if((0,i.isRefsEqual)(l,a)){c=!0;break}o.push(t.fetchAsync(l).then((function(e){if(!(0,i.isDict)(e))throw new r.FormatError("Kid node must be a dictionary.");e.has("Count")?s+=e.get("Count"):s++})))}if(!c)throw new r.FormatError("Kid reference not found in parent's kids.");return Promise.all(o).then((function(){return[s,n]}))}))}(s).then((function(e){if(!e)return a;const[t,r]=e;a+=t;return n(r)}))}(e)}static parseDestDictionary(e){const t=e.destDict;if(!(0,i.isDict)(t)){(0,r.warn)("parseDestDictionary: `destDict` must be a dictionary.");return}const a=e.resultObj;if("object"!=typeof a){(0,r.warn)("parseDestDictionary: `resultObj` must be an object.");return}const n=e.docBaseUrl||null;let s,o,c=t.get("A");!(0,i.isDict)(c)&&t.has("Dest")&&(c=t.get("Dest"));if((0,i.isDict)(c)){const e=c.get("S");if(!(0,i.isName)(e)){(0,r.warn)("parseDestDictionary: Invalid type in Action dictionary.");return}const t=e.name;switch(t){case"URI":s=c.get("URI");(0,i.isName)(s)?s="/"+s.name:(0,r.isString)(s)&&(s=function(e){return e.startsWith("www.")?`http://${e}`:e}(s));break;case"GoTo":o=c.get("D");break;case"Launch":case"GoToR":const e=c.get("F");(0,i.isDict)(e)?s=e.get("F")||null:(0,r.isString)(e)&&(s=e);let n=c.get("D");if(n){(0,i.isName)(n)&&(n=n.name);if((0,r.isString)(s)){const e=s.split("#")[0];(0,r.isString)(n)?s=e+"#"+n:Array.isArray(n)&&(s=e+"#"+JSON.stringify(n))}}const l=c.get("NewWindow");(0,r.isBool)(l)&&(a.newWindow=l);break;case"Named":const h=c.get("N");(0,i.isName)(h)&&(a.action=h.name);break;case"JavaScript":const u=c.get("JS");let d;(0,i.isStream)(u)?d=(0,r.bytesToString)(u.getBytes()):(0,r.isString)(u)&&(d=u);if(d){const e=new RegExp("^\\s*("+["app.launchURL","window.open"].join("|").split(".").join("\\.")+")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))","i").exec((0,r.stringToPDFString)(d));if(e&&e[2]){s=e[2];"true"===e[3]&&"app.launchURL"===e[1]&&(a.newWindow=!0);break}}default:(0,r.warn)(`parseDestDictionary: unsupported action type "${t}".`)}}else t.has("Dest")&&(o=t.get("Dest"));if((0,r.isString)(s)){s=function(e){try{return(0,r.stringToUTF8String)(e)}catch(t){return e}}(s);const e=(0,r.createValidAbsoluteUrl)(s,n);e&&(a.url=e.href);a.unsafeUrl=s}if(o){(0,i.isName)(o)&&(o=o.name);((0,r.isString)(o)||Array.isArray(o))&&(a.dest=o)}}}t.Catalog=h;var u=function(){function e(e,t){this.stream=e;this.pdfManager=t;this.entries=[];this.xrefstms=Object.create(null);this._cacheMap=new Map;this.stats={streamTypes:Object.create(null),fontTypes:Object.create(null)}}e.prototype={setStartXRef:function(e){this.startXRefQueue=[e]},parse:function(e){var t;if(e){(0,r.warn)("Indexing all PDF objects");t=this.indexObjects()}else t=this.readXRef();t.assignXref(this);this.trailer=t;let a,n;try{a=t.get("Encrypt")}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)(`XRef.parse - Invalid "Encrypt" reference: "${e}".`)}if((0,i.isDict)(a)){var c=t.get("ID"),l=c&&c.length?c[0]:"";a.suppressEncryption=!0;this.encrypt=new o.CipherTransformFactory(a,l,this.pdfManager.password)}try{n=t.get("Root")}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)(`XRef.parse - Invalid "Root" reference: "${e}".`)}if(!(0,i.isDict)(n)||!n.has("Pages")){if(!e)throw new s.XRefParseException;throw new r.FormatError("Invalid root reference")}this.root=n},processXRefTable:function(e){"tableState"in this||(this.tableState={entryNum:0,streamPos:e.lexer.stream.pos,parserBuf1:e.buf1,parserBuf2:e.buf2});var t=this.readXRefTable(e);if(!(0,i.isCmd)(t,"trailer"))throw new r.FormatError("Invalid XRef table: could not find trailer dictionary");var a=e.getObj();!(0,i.isDict)(a)&&a.dict&&(a=a.dict);if(!(0,i.isDict)(a))throw new r.FormatError("Invalid XRef table: could not parse trailer dictionary");delete this.tableState;return a},readXRefTable:function(e){var t,a=e.lexer.stream,n=this.tableState;a.pos=n.streamPos;e.buf1=n.parserBuf1;e.buf2=n.parserBuf2;for(;;){if(!("firstEntryNum"in n)||!("entryCount"in n)){if((0,i.isCmd)(t=e.getObj(),"trailer"))break;n.firstEntryNum=t;n.entryCount=e.getObj()}var s=n.firstEntryNum,o=n.entryCount;if(!Number.isInteger(s)||!Number.isInteger(o))throw new r.FormatError("Invalid XRef table: wrong types in subsection header");for(var c=n.entryNum;c<o;c++){n.streamPos=a.pos;n.entryNum=c;n.parserBuf1=e.buf1;n.parserBuf2=e.buf2;var l={};l.offset=e.getObj();l.gen=e.getObj();var h=e.getObj();if(h instanceof i.Cmd)switch(h.cmd){case"f":l.free=!0;break;case"n":l.uncompressed=!0}if(!Number.isInteger(l.offset)||!Number.isInteger(l.gen)||!l.free&&!l.uncompressed)throw new r.FormatError(`Invalid entry in XRef subsection: ${s}, ${o}`);0===c&&l.free&&1===s&&(s=0);this.entries[c+s]||(this.entries[c+s]=l)}n.entryNum=0;n.streamPos=a.pos;n.parserBuf1=e.buf1;n.parserBuf2=e.buf2;delete n.firstEntryNum;delete n.entryCount}if(this.entries[0]&&!this.entries[0].free)throw new r.FormatError("Invalid XRef table: unexpected first object");return t},processXRefStream:function(e){if(!("streamState"in this)){var t=e.dict,a=t.get("W"),r=t.get("Index");r||(r=[0,t.get("Size")]);this.streamState={entryRanges:r,byteWidths:a,entryNum:0,streamPos:e.pos}}this.readXRefStream(e);delete this.streamState;return e.dict},readXRefStream:function(e){var t,a,i=this.streamState;e.pos=i.streamPos;for(var n=i.byteWidths,s=n[0],o=n[1],c=n[2],l=i.entryRanges;l.length>0;){var h=l[0],u=l[1];if(!Number.isInteger(h)||!Number.isInteger(u))throw new r.FormatError(`Invalid XRef range fields: ${h}, ${u}`);if(!Number.isInteger(s)||!Number.isInteger(o)||!Number.isInteger(c))throw new r.FormatError(`Invalid XRef entry fields length: ${h}, ${u}`);for(t=i.entryNum;t<u;++t){i.entryNum=t;i.streamPos=e.pos;var d=0,f=0,g=0;for(a=0;a<s;++a)d=d<<8|e.getByte();0===s&&(d=1);for(a=0;a<o;++a)f=f<<8|e.getByte();for(a=0;a<c;++a)g=g<<8|e.getByte();var m={};m.offset=f;m.gen=g;switch(d){case 0:m.free=!0;break;case 1:m.uncompressed=!0;break;case 2:break;default:throw new r.FormatError(`Invalid XRef entry type: ${d}`)}this.entries[h+t]||(this.entries[h+t]=m)}i.entryNum=0;i.streamPos=e.pos;l.splice(0,2)}},indexObjects:function(){function e(e,t){for(var a="",r=e[t];10!==r&&13!==r&&60!==r&&!(++t>=e.length);){a+=String.fromCharCode(r);r=e[t]}return a}function t(e,t,a){for(var r=a.length,i=e.length,n=0;t<i;){for(var s=0;s<r&&e[t+s]===a[s];)++s;if(s>=r)break;t++;n++}return n}var a=/^(\d+)\s+(\d+)\s+obj\b/;const o=/\bendobj[\b\s]$/,c=/\s+(\d+\s+\d+\s+obj[\b\s<])$/;var l=new Uint8Array([116,114,97,105,108,101,114]),h=new Uint8Array([115,116,97,114,116,120,114,101,102]);const u=new Uint8Array([111,98,106]);var d=new Uint8Array([47,88,82,101,102]);this.entries.length=0;var f=this.stream;f.pos=0;for(var g,m,p=f.getBytes(),b=f.start,y=p.length,v=[],w=[];b<y;){var k=p[b];if(9!==k&&10!==k&&13!==k&&32!==k)if(37!==k){var S,C=e(p,b);if(C.startsWith("xref")&&(4===C.length||/\s/.test(C[4]))){b+=t(p,b,l);v.push(b);b+=t(p,b,h)}else if(S=a.exec(C)){const e=0|S[1],a=0|S[2];this.entries[e]&&this.entries[e].gen!==a||(this.entries[e]={offset:b-f.start,gen:a,uncompressed:!0});let i,n=b+C.length;for(;n<p.length;){const e=n+t(p,n,u)+4;i=e-b;const a=Math.max(e-25,n),s=(0,r.bytesToString)(p.subarray(a,e));if(o.test(s))break;{const e=c.exec(s);if(e&&e[1]){(0,r.warn)('indexObjects: Found new "obj" inside of another "obj", caused by missing "endobj" -- trying to recover.');i-=e[1].length;break}}n=e}const s=p.subarray(b,b+i);var x=t(s,0,d);if(x<i&&s[x+5]<64){w.push(b-f.start);this.xrefstms[b-f.start]=1}b+=i}else if(C.startsWith("trailer")&&(7===C.length||/\s/.test(C[7]))){v.push(b);b+=t(p,b,h)}else b+=C.length+1}else do{if(++b>=y)break;k=p[b]}while(10!==k&&13!==k);else++b}for(g=0,m=w.length;g<m;++g){this.startXRefQueue.push(w[g]);this.readXRef(!0)}let A;for(g=0,m=v.length;g<m;++g){f.pos=v[g];const e=new n.Parser({lexer:new n.Lexer(f),xref:this,allowStreams:!0,recoveryMode:!0});var I=e.getObj();if(!(0,i.isCmd)(I,"trailer"))continue;const t=e.getObj();if(!(0,i.isDict)(t))continue;let a;try{a=t.get("Root")}catch(e){if(e instanceof s.MissingDataException)throw e;continue}if((0,i.isDict)(a)&&a.has("Pages")){if(t.has("ID"))return t;A=t}}if(A)return A;throw new r.InvalidPDFException("Invalid PDF structure.")},readXRef:function(e){var t=this.stream;const a=Object.create(null);try{for(;this.startXRefQueue.length;){var o=this.startXRefQueue[0];if(a[o]){(0,r.warn)("readXRef - skipping XRef table since it was already parsed.");this.startXRefQueue.shift();continue}a[o]=!0;t.pos=o+t.start;const e=new n.Parser({lexer:new n.Lexer(t),xref:this,allowStreams:!0});var c,l=e.getObj();if((0,i.isCmd)(l,"xref")){c=this.processXRefTable(e);this.topDict||(this.topDict=c);l=c.get("XRefStm");if(Number.isInteger(l)){var h=l;if(!(h in this.xrefstms)){this.xrefstms[h]=1;this.startXRefQueue.push(h)}}}else{if(!Number.isInteger(l))throw new r.FormatError("Invalid XRef stream header");if(!Number.isInteger(e.getObj())||!(0,i.isCmd)(e.getObj(),"obj")||!(0,i.isStream)(l=e.getObj()))throw new r.FormatError("Invalid XRef stream");c=this.processXRefStream(l);this.topDict||(this.topDict=c);if(!c)throw new r.FormatError("Failed to read XRef stream")}l=c.get("Prev");Number.isInteger(l)?this.startXRefQueue.push(l):(0,i.isRef)(l)&&this.startXRefQueue.push(l.num);this.startXRefQueue.shift()}return this.topDict}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("(while reading XRef): "+e)}if(!e)throw new s.XRefParseException},getEntry:function(e){var t=this.entries[e];return t&&!t.free&&t.offset?t:null},fetchIfRef:function(e,t){return e instanceof i.Ref?this.fetch(e,t):e},fetch:function(e,t){if(!(e instanceof i.Ref))throw new Error("ref object is not a reference");const a=e.num,r=this._cacheMap.get(a);if(void 0!==r){r instanceof i.Dict&&!r.objId&&(r.objId=e.toString());return r}let n=this.getEntry(a);if(null===n){this._cacheMap.set(a,n);return n}n=n.uncompressed?this.fetchUncompressed(e,n,t):this.fetchCompressed(e,n,t);(0,i.isDict)(n)?n.objId=e.toString():(0,i.isStream)(n)&&(n.dict.objId=e.toString());return n},fetchUncompressed(e,t,a=!1){var r=e.gen,o=e.num;if(t.gen!==r)throw new s.XRefEntryException(`Inconsistent generation in XRef: ${e}`);var c=this.stream.makeSubStream(t.offset+this.stream.start);const l=new n.Parser({lexer:new n.Lexer(c),xref:this,allowStreams:!0});var h=l.getObj(),u=l.getObj(),d=l.getObj();if(h!==o||u!==r||!(d instanceof i.Cmd))throw new s.XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`);if("obj"!==d.cmd){if(d.cmd.startsWith("obj")){o=parseInt(d.cmd.substring(3),10);if(!Number.isNaN(o))return o}throw new s.XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`)}t=this.encrypt&&!a?l.getObj(this.encrypt.createCipherTransform(o,r)):l.getObj();(0,i.isStream)(t)||this._cacheMap.set(o,t);return t},fetchCompressed(e,t,a=!1){const o=t.offset,c=this.fetch(i.Ref.get(o,0));if(!(0,i.isStream)(c))throw new r.FormatError("bad ObjStm stream");const l=c.dict.get("First"),h=c.dict.get("N");if(!Number.isInteger(l)||!Number.isInteger(h))throw new r.FormatError("invalid first and n parameters for ObjStm stream");const u=new n.Parser({lexer:new n.Lexer(c),xref:this,allowStreams:!0}),d=new Array(h);for(let e=0;e<h;++e){const t=u.getObj();if(!Number.isInteger(t))throw new r.FormatError(`invalid object number in the ObjStm stream: ${t}`);const a=u.getObj();if(!Number.isInteger(a))throw new r.FormatError(`invalid object offset in the ObjStm stream: ${a}`);d[e]=t}const f=new Array(h);for(let e=0;e<h;++e){const t=u.getObj();f[e]=t;u.buf1 instanceof i.Cmd&&"endobj"===u.buf1.cmd&&u.shift();if((0,i.isStream)(t))continue;const a=d[e],r=this.entries[a];r&&r.offset===o&&r.gen===e&&this._cacheMap.set(a,t)}if(void 0===(t=f[t.gen]))throw new s.XRefEntryException(`Bad (compressed) XRef entry: ${e}`);return t},async fetchIfRefAsync(e,t){return e instanceof i.Ref?this.fetchAsync(e,t):e},async fetchAsync(e,t){try{return this.fetch(e,t)}catch(a){if(!(a instanceof s.MissingDataException))throw a;await this.pdfManager.requestRange(a.begin,a.end);return this.fetchAsync(e,t)}},getCatalogObj:function(){return this.root}};return e}();t.XRef=u;class d{constructor(e,t,a){this.constructor===d&&(0,r.unreachable)("Cannot initialize NameOrNumberTree.");this.root=e;this.xref=t;this._type=a}getAll(){const e=Object.create(null);if(!this.root)return e;const t=this.xref,a=new i.RefSet;a.put(this.root);const n=[this.root];for(;n.length>0;){const s=t.fetchIfRef(n.shift());if(!(0,i.isDict)(s))continue;if(s.has("Kids")){const e=s.get("Kids");for(let t=0,i=e.length;t<i;t++){const i=e[t];if(a.has(i))throw new r.FormatError(`Duplicate entry in "${this._type}" tree.`);n.push(i);a.put(i)}continue}const o=s.get(this._type);if(Array.isArray(o))for(let a=0,r=o.length;a<r;a+=2)e[t.fetchIfRef(o[a])]=t.fetchIfRef(o[a+1])}return e}get(e){if(!this.root)return null;const t=this.xref;let a=t.fetchIfRef(this.root),i=0;for(;a.has("Kids");){if(++i>10){(0,r.warn)(`Search depth limit reached for "${this._type}" tree.`);return null}const n=a.get("Kids");if(!Array.isArray(n))return null;let s=0,o=n.length-1;for(;s<=o;){const r=s+o>>1,i=t.fetchIfRef(n[r]).get("Limits");if(e<t.fetchIfRef(i[0]))o=r-1;else{if(!(e>t.fetchIfRef(i[1]))){a=t.fetchIfRef(n[r]);break}s=r+1}}if(s>o)return null}const n=a.get(this._type);if(Array.isArray(n)){let a=0,i=n.length-2;for(;a<=i;){const r=a+i>>1,s=r+(1&r),o=t.fetchIfRef(n[s]);if(e<o)i=s-2;else{if(!(e>o))return t.fetchIfRef(n[s+1]);a=s+2}}(0,r.info)(`Falling back to an exhaustive search, for key "${e}", `+`in "${this._type}" tree.`);for(let a=0,i=n.length;a<i;a+=2){if(t.fetchIfRef(n[a])===e){(0,r.warn)(`The "${e}" key was found at an incorrect, `+`i.e. out-of-order, position in "${this._type}" tree.`);return t.fetchIfRef(n[a+1])}}}return null}}class f extends d{constructor(e,t){super(e,t,"Names")}}class g extends d{constructor(e,t){super(e,t,"Nums")}}var m=function(){function e(e,t){if(e&&(0,i.isDict)(e)){this.xref=t;this.root=e;e.has("FS")&&(this.fs=e.get("FS"));this.description=e.has("Desc")?(0,r.stringToPDFString)(e.get("Desc")):"";e.has("RF")&&(0,r.warn)("Related file specifications are not supported");this.contentAvailable=!0;if(!e.has("EF")){this.contentAvailable=!1;(0,r.warn)("Non-embedded file specifications are not supported")}}}function t(e){return e.has("UF")?e.get("UF"):e.has("F")?e.get("F"):e.has("Unix")?e.get("Unix"):e.has("Mac")?e.get("Mac"):e.has("DOS")?e.get("DOS"):null}e.prototype={get filename(){if(!this._filename&&this.root){var e=t(this.root)||"unnamed";this._filename=(0,r.stringToPDFString)(e).replace(/\\\\/g,"\\").replace(/\\\//g,"/").replace(/\\/g,"/")}return this._filename},get content(){if(!this.contentAvailable)return null;!this.contentRef&&this.root&&(this.contentRef=t(this.root.get("EF")));var e=null;if(this.contentRef){var a=this.xref.fetchIfRef(this.contentRef);a&&(0,i.isStream)(a)?e=a.getBytes():(0,r.warn)("Embedded file specification points to non-existing/invalid content")}else(0,r.warn)("Embedded file specification does not have a content");return e},get serializable(){return{filename:this.filename,content:this.content}}};return e}();t.FileSpec=m;const p=function(){function e(e){return e instanceof i.Ref||e instanceof i.Dict||Array.isArray(e)||(0,i.isStream)(e)}function t(t,a){if(t instanceof i.Dict||(0,i.isStream)(t)){const r=t instanceof i.Dict?t:t.dict,n=r.getKeys();for(let t=0,i=n.length;t<i;t++){const i=r.getRaw(n[t]);e(i)&&a.push(i)}}else if(Array.isArray(t))for(let r=0,i=t.length;r<i;r++){const i=t[r];e(i)&&a.push(i)}}function a(e,t,a){this.dict=e;this.keys=t;this.xref=a;this.refSet=null}a.prototype={async load(){if(!this.xref.stream.allChunksLoaded||this.xref.stream.allChunksLoaded())return;const{keys:e,dict:t}=this;this.refSet=new i.RefSet;const a=[];for(let r=0,i=e.length;r<i;r++){const i=t.getRaw(e[r]);void 0!==i&&a.push(i)}return this._walk(a)},async _walk(e){const a=[],r=[];for(;e.length;){let n=e.pop();if(n instanceof i.Ref){if(this.refSet.has(n))continue;try{this.refSet.put(n);n=this.xref.fetch(n)}catch(e){if(!(e instanceof s.MissingDataException))throw e;a.push(n);r.push({begin:e.begin,end:e.end})}}if(n&&n.getBaseStreams){const e=n.getBaseStreams();let t=!1;for(let a=0,i=e.length;a<i;a++){const i=e[a];if(i.allChunksLoaded&&!i.allChunksLoaded()){t=!0;r.push({begin:i.start,end:i.end})}}t&&a.push(n)}t(n,e)}if(r.length){await this.xref.stream.manager.requestRanges(r);for(let e=0,t=a.length;e<t;e++){const t=a[e];t instanceof i.Ref&&this.refSet.remove(t)}return this._walk(a)}this.refSet=null}};return a}();t.ObjectLoader=p},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Parser=t.Linearization=t.Lexer=void 0;var r=a(11),i=a(2),n=a(4),s=a(7),o=a(12),c=a(14),l=a(17),h=a(19);function u(e){const t=e.length;let a=1,r=0;for(let i=0;i<t;++i){a+=255&e[i];r+=a}return r%65521<<16|a%65521}class d{constructor({lexer:e,xref:t,allowStreams:a=!1,recoveryMode:r=!1}){this.lexer=e;this.xref=t;this.allowStreams=a;this.recoveryMode=r;this.imageCache=Object.create(null);this.refill()}refill(){this.buf1=this.lexer.getObj();this.buf2=this.lexer.getObj()}shift(){if(this.buf2 instanceof n.Cmd&&"ID"===this.buf2.cmd){this.buf1=this.buf2;this.buf2=null}else{this.buf1=this.buf2;this.buf2=this.lexer.getObj()}}tryShift(){try{this.shift();return!0}catch(e){if(e instanceof s.MissingDataException)throw e;return!1}}getObj(e=null){const t=this.buf1;this.shift();if(t instanceof n.Cmd)switch(t.cmd){case"BI":return this.makeInlineImage(e);case"[":const a=[];for(;!(0,n.isCmd)(this.buf1,"]")&&!(0,n.isEOF)(this.buf1);)a.push(this.getObj(e));if((0,n.isEOF)(this.buf1)){if(!this.recoveryMode)throw new i.FormatError("End of file inside array");return a}this.shift();return a;case"<<":const r=new n.Dict(this.xref);for(;!(0,n.isCmd)(this.buf1,">>")&&!(0,n.isEOF)(this.buf1);){if(!(0,n.isName)(this.buf1)){(0,i.info)("Malformed dictionary: key must be a name object");this.shift();continue}const t=this.buf1.name;this.shift();if((0,n.isEOF)(this.buf1))break;r.set(t,this.getObj(e))}if((0,n.isEOF)(this.buf1)){if(!this.recoveryMode)throw new i.FormatError("End of file inside dictionary");return r}if((0,n.isCmd)(this.buf2,"stream"))return this.allowStreams?this.makeStream(r,e):r;this.shift();return r;default:return t}if(Number.isInteger(t)){if(Number.isInteger(this.buf1)&&(0,n.isCmd)(this.buf2,"R")){const e=n.Ref.get(t,this.buf1);this.shift();this.shift();return e}return t}return"string"==typeof t&&e?e.decryptString(t):t}findDefaultInlineStreamEnd(e){const t=e.pos;let a,r,n=0;for(;-1!==(a=e.getByte());)if(0===n)n=69===a?1:0;else if(1===n)n=73===a?2:0;else{(0,i.assert)(2===n);if(32===a||10===a||13===a){r=e.pos;const t=e.peekBytes(10);for(let e=0,r=t.length;e<r;e++){a=t[e];if((0!==a||0===t[e+1])&&(10!==a&&13!==a&&(a<32||a>127))){n=0;break}}if(2===n)break}else n=0}if(-1===a){(0,i.warn)("findDefaultInlineStreamEnd: Reached the end of the stream without finding a valid EI marker");if(r){(0,i.warn)('... trying to recover by using the last "EI" occurrence.');e.skip(-(e.pos-r))}}let o=4;e.skip(-o);a=e.peekByte();e.skip(o);(0,s.isWhiteSpace)(a)||o--;return e.pos-o-t}findDCTDecodeInlineStreamEnd(e){const t=e.pos;let a,r,n=!1;for(;-1!==(a=e.getByte());)if(255===a){switch(e.getByte()){case 0:break;case 255:e.skip(-1);break;case 217:n=!0;break;case 192:case 193:case 194:case 195:case 197:case 198:case 199:case 201:case 202:case 203:case 205:case 206:case 207:case 196:case 204:case 218:case 219:case 220:case 221:case 222:case 223:case 224:case 225:case 226:case 227:case 228:case 229:case 230:case 231:case 232:case 233:case 234:case 235:case 236:case 237:case 238:case 239:case 254:r=e.getUint16();r>2?e.skip(r-2):e.skip(-2)}if(n)break}const s=e.pos-t;if(-1===a){(0,i.warn)("Inline DCTDecode image stream: EOI marker not found, searching for /EI/ instead.");e.skip(-s);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return s}findASCII85DecodeInlineStreamEnd(e){const t=e.pos;let a;for(;-1!==(a=e.getByte());)if(126===a){const t=e.pos;a=e.peekByte();for(;(0,s.isWhiteSpace)(a);){e.skip();a=e.peekByte()}if(62===a){e.skip();break}if(e.pos>t){const t=e.peekBytes(2);if(69===t[0]&&73===t[1])break}}const r=e.pos-t;if(-1===a){(0,i.warn)("Inline ASCII85Decode image stream: EOD marker not found, searching for /EI/ instead.");e.skip(-r);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return r}findASCIIHexDecodeInlineStreamEnd(e){const t=e.pos;let a;for(;-1!==(a=e.getByte())&&62!==a;);const r=e.pos-t;if(-1===a){(0,i.warn)("Inline ASCIIHexDecode image stream: EOD marker not found, searching for /EI/ instead.");e.skip(-r);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return r}inlineStreamSkipEI(e){let t,a=0;for(;-1!==(t=e.getByte());)if(0===a)a=69===t?1:0;else if(1===a)a=73===t?2:0;else if(2===a)break}makeInlineImage(e){const t=this.lexer,a=t.stream,r=new n.Dict(this.xref);let s;for(;!(0,n.isCmd)(this.buf1,"ID")&&!(0,n.isEOF)(this.buf1);){if(!(0,n.isName)(this.buf1))throw new i.FormatError("Dictionary key must be a name object");const t=this.buf1.name;this.shift();if((0,n.isEOF)(this.buf1))break;r.set(t,this.getObj(e))}-1!==t.beginInlineImagePos&&(s=a.pos-t.beginInlineImagePos);const o=r.get("Filter","F");let c;if((0,n.isName)(o))c=o.name;else if(Array.isArray(o)){const e=this.xref.fetchIfRef(o[0]);(0,n.isName)(e)&&(c=e.name)}const l=a.pos;let h;h="DCTDecode"===c||"DCT"===c?this.findDCTDecodeInlineStreamEnd(a):"ASCII85Decode"===c||"A85"===c?this.findASCII85DecodeInlineStreamEnd(a):"ASCIIHexDecode"===c||"AHx"===c?this.findASCIIHexDecodeInlineStreamEnd(a):this.findDefaultInlineStreamEnd(a);let d,f=a.makeSubStream(l,h,r);if(h<1e3&&s<5552){const e=f.getBytes();f.reset();const r=a.pos;a.pos=t.beginInlineImagePos;const i=a.getBytes(s);a.pos=r;d=u(e)+"_"+u(i);const o=this.imageCache[d];if(void 0!==o){this.buf2=n.Cmd.get("EI");this.shift();o.reset();return o}}e&&(f=e.createStream(f,h));f=this.filter(f,r,h);f.dict=r;if(void 0!==d){f.cacheKey=`inline_${h}_${d}`;this.imageCache[d]=f}this.buf2=n.Cmd.get("EI");this.shift();return f}_findStreamLength(e,t){const{stream:a}=this.lexer;a.pos=e;const r=t.length;for(;a.pos<a.end;){const i=a.peekBytes(2048),n=i.length-r;if(n<=0)break;let s=0;for(;s<n;){let n=0;for(;n<r&&i[s+n]===t[n];)n++;if(n>=r){a.pos+=s;return a.pos-e}s++}a.pos+=n}return-1}makeStream(e,t){const a=this.lexer;let r=a.stream;a.skipToNextLine();const o=r.pos-1;let c=e.get("Length");if(!Number.isInteger(c)){(0,i.info)(`Bad length "${c}" in stream`);c=0}r.pos=o+c;a.nextChar();if(this.tryShift()&&(0,n.isCmd)(this.buf2,"endstream"))this.shift();else{const e=new Uint8Array([101,110,100,115,116,114,101,97,109]);let t=this._findStreamLength(o,e);if(t<0){const a=1;for(let n=1;n<=a;n++){const a=e.length-n,c=e.slice(0,a),l=this._findStreamLength(o,c);if(l>=0){const e=r.peekBytes(a+1)[a];if(!(0,s.isWhiteSpace)(e))break;(0,i.info)(`Found "${(0,i.bytesToString)(c)}" when `+"searching for endstream command.");t=l;break}}if(t<0)throw new i.FormatError("Missing endstream command.")}c=t;a.nextChar();this.shift();this.shift()}this.shift();r=r.makeSubStream(o,c,e);t&&(r=t.createStream(r,c));r=this.filter(r,e,c);r.dict=e;return r}filter(e,t,a){let r=t.get("Filter","F"),s=t.get("DecodeParms","DP");if((0,n.isName)(r)){Array.isArray(s)&&(0,i.warn)("/DecodeParms should not contain an Array, when /Filter contains a Name.");return this.makeFilter(e,r.name,a,s)}let o=a;if(Array.isArray(r)){const t=r,a=s;for(let c=0,l=t.length;c<l;++c){r=this.xref.fetchIfRef(t[c]);if(!(0,n.isName)(r))throw new i.FormatError(`Bad filter name "${r}"`);s=null;Array.isArray(a)&&c in a&&(s=this.xref.fetchIfRef(a[c]));e=this.makeFilter(e,r.name,o,s);o=null}}return e}makeFilter(e,t,a,n){if(0===a){(0,i.warn)(`Empty "${t}" stream.`);return new r.NullStream}try{const s=this.xref.stats.streamTypes;if("FlateDecode"===t||"Fl"===t){s[i.StreamType.FLATE]=!0;return n?new r.PredictorStream(new r.FlateStream(e,a),a,n):new r.FlateStream(e,a)}if("LZWDecode"===t||"LZW"===t){s[i.StreamType.LZW]=!0;let t=1;if(n){n.has("EarlyChange")&&(t=n.get("EarlyChange"));return new r.PredictorStream(new r.LZWStream(e,a,t),a,n)}return new r.LZWStream(e,a,t)}if("DCTDecode"===t||"DCT"===t){s[i.StreamType.DCT]=!0;return new l.JpegStream(e,a,e.dict,n)}if("JPXDecode"===t||"JPX"===t){s[i.StreamType.JPX]=!0;return new h.JpxStream(e,a,e.dict,n)}if("ASCII85Decode"===t||"A85"===t){s[i.StreamType.A85]=!0;return new r.Ascii85Stream(e,a)}if("ASCIIHexDecode"===t||"AHx"===t){s[i.StreamType.AHX]=!0;return new r.AsciiHexStream(e,a)}if("CCITTFaxDecode"===t||"CCF"===t){s[i.StreamType.CCF]=!0;return new o.CCITTFaxStream(e,a,n)}if("RunLengthDecode"===t||"RL"===t){s[i.StreamType.RLX]=!0;return new r.RunLengthStream(e,a)}if("JBIG2Decode"===t){s[i.StreamType.JBIG]=!0;return new c.Jbig2Stream(e,a,e.dict,n)}(0,i.warn)(`Filter "${t}" is not supported.`);return e}catch(e){if(e instanceof s.MissingDataException)throw e;(0,i.warn)(`Invalid stream: "${e}"`);return new r.NullStream}}}t.Parser=d;const f=[1,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];function g(e){return e>=48&&e<=57?15&e:e>=65&&e<=70||e>=97&&e<=102?9+(15&e):-1}class m{constructor(e,t=null){this.stream=e;this.nextChar();this.strBuf=[];this.knownCommands=t;this._hexStringNumWarn=0;this.beginInlineImagePos=-1}nextChar(){return this.currentChar=this.stream.getByte()}peekChar(){return this.stream.peekByte()}getNumber(){let e=this.currentChar,t=!1,a=0,r=0;if(45===e){r=-1;e=this.nextChar();45===e&&(e=this.nextChar())}else if(43===e){r=1;e=this.nextChar()}if(10===e||13===e)do{e=this.nextChar()}while(10===e||13===e);if(46===e){a=10;e=this.nextChar()}if(e<48||e>57){if(10===a&&0===r&&((0,s.isWhiteSpace)(e)||-1===e)){(0,i.warn)("Lexer.getNumber - treating a single decimal point as zero.");return 0}throw new i.FormatError(`Invalid number: ${String.fromCharCode(e)} (charCode ${e})`)}r=r||1;let n=e-48,o=0,c=1;for(;(e=this.nextChar())>=0;)if(e>=48&&e<=57){const r=e-48;if(t)o=10*o+r;else{0!==a&&(a*=10);n=10*n+r}}else if(46===e){if(0!==a)break;a=1}else if(45===e)(0,i.warn)("Badly formatted number: minus sign in the middle");else{if(69!==e&&101!==e)break;e=this.peekChar();if(43===e||45===e){c=45===e?-1:1;this.nextChar()}else if(e<48||e>57)break;t=!0}0!==a&&(n/=a);t&&(n*=10**(c*o));return r*n}getString(){let e=1,t=!1;const a=this.strBuf;a.length=0;let r=this.nextChar();for(;;){let n=!1;switch(0|r){case-1:(0,i.warn)("Unterminated string");t=!0;break;case 40:++e;a.push("(");break;case 41:if(0==--e){this.nextChar();t=!0}else a.push(")");break;case 92:r=this.nextChar();switch(r){case-1:(0,i.warn)("Unterminated string");t=!0;break;case 110:a.push("\n");break;case 114:a.push("\r");break;case 116:a.push("\t");break;case 98:a.push("\b");break;case 102:a.push("\f");break;case 92:case 40:case 41:a.push(String.fromCharCode(r));break;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:let e=15&r;r=this.nextChar();n=!0;if(r>=48&&r<=55){e=(e<<3)+(15&r);r=this.nextChar();if(r>=48&&r<=55){n=!1;e=(e<<3)+(15&r)}}a.push(String.fromCharCode(e));break;case 13:10===this.peekChar()&&this.nextChar();break;case 10:break;default:a.push(String.fromCharCode(r))}break;default:a.push(String.fromCharCode(r))}if(t)break;n||(r=this.nextChar())}return a.join("")}getName(){let e,t;const a=this.strBuf;a.length=0;for(;(e=this.nextChar())>=0&&!f[e];)if(35===e){e=this.nextChar();if(f[e]){(0,i.warn)("Lexer_getName: NUMBER SIGN (#) should be followed by a hexadecimal number.");a.push("#");break}const r=g(e);if(-1!==r){t=e;e=this.nextChar();const n=g(e);if(-1===n){(0,i.warn)(`Lexer_getName: Illegal digit (${String.fromCharCode(e)}) `+"in hexadecimal number.");a.push("#",String.fromCharCode(t));if(f[e])break;a.push(String.fromCharCode(e));continue}a.push(String.fromCharCode(r<<4|n))}else a.push("#",String.fromCharCode(e))}else a.push(String.fromCharCode(e));a.length>127&&(0,i.warn)(`Name token is longer than allowed by the spec: ${a.length}`);return n.Name.get(a.join(""))}_hexStringWarn(e){5!=this._hexStringNumWarn++?this._hexStringNumWarn>5||(0,i.warn)(`getHexString - ignoring invalid character: ${e}`):(0,i.warn)("getHexString - ignoring additional invalid characters.")}getHexString(){const e=this.strBuf;e.length=0;let t,a,r=this.currentChar,n=!0;this._hexStringNumWarn=0;for(;;){if(r<0){(0,i.warn)("Unterminated hex string");break}if(62===r){this.nextChar();break}if(1!==f[r]){if(n){t=g(r);if(-1===t){this._hexStringWarn(r);r=this.nextChar();continue}}else{a=g(r);if(-1===a){this._hexStringWarn(r);r=this.nextChar();continue}e.push(String.fromCharCode(t<<4|a))}n=!n;r=this.nextChar()}else r=this.nextChar()}return e.join("")}getObj(){let e=!1,t=this.currentChar;for(;;){if(t<0)return n.EOF;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(1!==f[t])break;t=this.nextChar()}switch(0|t){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return this.getNumber();case 40:return this.getString();case 47:return this.getName();case 91:this.nextChar();return n.Cmd.get("[");case 93:this.nextChar();return n.Cmd.get("]");case 60:t=this.nextChar();if(60===t){this.nextChar();return n.Cmd.get("<<")}return this.getHexString();case 62:t=this.nextChar();if(62===t){this.nextChar();return n.Cmd.get(">>")}return n.Cmd.get(">");case 123:this.nextChar();return n.Cmd.get("{");case 125:this.nextChar();return n.Cmd.get("}");case 41:this.nextChar();throw new i.FormatError(`Illegal character: ${t}`)}let a=String.fromCharCode(t);const r=this.knownCommands;let s=r&&void 0!==r[a];for(;(t=this.nextChar())>=0&&!f[t];){const e=a+String.fromCharCode(t);if(s&&void 0===r[e])break;if(128===a.length)throw new i.FormatError(`Command token too long: ${a.length}`);a=e;s=r&&void 0!==r[a]}if("true"===a)return!0;if("false"===a)return!1;if("null"===a)return null;"BI"===a&&(this.beginInlineImagePos=this.stream.pos);return n.Cmd.get(a)}skipToNextLine(){let e=this.currentChar;for(;e>=0;){if(13===e){e=this.nextChar();10===e&&this.nextChar();break}if(10===e){this.nextChar();break}e=this.nextChar()}}}t.Lexer=m;t.Linearization=class{static create(e){function t(e,t,a=!1){const r=e.get(t);if(Number.isInteger(r)&&(a?r>=0:r>0))return r;throw new Error(`The "${t}" parameter in the linearization `+"dictionary is invalid.")}const a=new d({lexer:new m(e),xref:null}),r=a.getObj(),s=a.getObj(),o=a.getObj(),c=a.getObj();let l,h;if(!(Number.isInteger(r)&&Number.isInteger(s)&&(0,n.isCmd)(o,"obj")&&(0,n.isDict)(c)&&(0,i.isNum)(l=c.get("Linearized"))&&l>0))return null;if((h=t(c,"L"))!==e.length)throw new Error('The "L" parameter in the linearization dictionary does not equal the stream length.');return{length:h,hints:function(e){const t=e.get("H");let a;if(Array.isArray(t)&&(2===(a=t.length)||4===a)){for(let e=0;e<a;e++){const a=t[e];if(!(Number.isInteger(a)&&a>0))throw new Error(`Hint (${e}) in the linearization dictionary is invalid.`)}return t}throw new Error("Hint array in the linearization dictionary is invalid.")}(c),objectNumberFirst:t(c,"O"),endFirst:t(c,"E"),numPages:t(c,"N"),mainXRefEntriesOffset:t(c,"T"),pageFirst:c.has("P")?t(c,"P",!0):0}}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.LZWStream=t.StringStream=t.StreamsSequenceStream=t.Stream=t.RunLengthStream=t.PredictorStream=t.NullStream=t.FlateStream=t.DecodeStream=t.DecryptStream=t.AsciiHexStream=t.Ascii85Stream=void 0;var r=a(2),i=a(4),n=a(7),s=function(){function e(e,t,a,r){this.bytes=e instanceof Uint8Array?e:new Uint8Array(e);this.start=t||0;this.pos=this.start;this.end=t+a||this.bytes.length;this.dict=r}e.prototype={get length(){return this.end-this.start},get isEmpty(){return 0===this.length},getByte:function(){return this.pos>=this.end?-1:this.bytes[this.pos++]},getUint16:function(){var e=this.getByte(),t=this.getByte();return-1===e||-1===t?-1:(e<<8)+t},getInt32:function(){return(this.getByte()<<24)+(this.getByte()<<16)+(this.getByte()<<8)+this.getByte()},getBytes(e,t=!1){var a=this.bytes,r=this.pos,i=this.end;if(!e){const e=a.subarray(r,i);return t?new Uint8ClampedArray(e):e}var n=r+e;n>i&&(n=i);this.pos=n;const s=a.subarray(r,n);return t?new Uint8ClampedArray(s):s},peekByte:function(){var e=this.getByte();-1!==e&&this.pos--;return e},peekBytes(e,t=!1){var a=this.getBytes(e,t);this.pos-=a.length;return a},getByteRange(e,t){e<0&&(e=0);t>this.end&&(t=this.end);return this.bytes.subarray(e,t)},skip:function(e){e||(e=1);this.pos+=e},reset:function(){this.pos=this.start},moveStart:function(){this.start=this.pos},makeSubStream:function(t,a,r){return new e(this.bytes.buffer,t,a,r)}};return e}();t.Stream=s;var o=function(){function e(e){const t=(0,r.stringToBytes)(e);s.call(this,t)}e.prototype=s.prototype;return e}();t.StringStream=o;var c=function(){var e=new Uint8Array(0);function t(t){this._rawMinBufferLength=t||0;this.pos=0;this.bufferLength=0;this.eof=!1;this.buffer=e;this.minBufferLength=512;if(t)for(;this.minBufferLength<t;)this.minBufferLength*=2}t.prototype={get isEmpty(){for(;!this.eof&&0===this.bufferLength;)this.readBlock();return 0===this.bufferLength},ensureBuffer:function(e){var t=this.buffer;if(e<=t.byteLength)return t;for(var a=this.minBufferLength;a<e;)a*=2;var r=new Uint8Array(a);r.set(t);return this.buffer=r},getByte:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return-1;this.readBlock()}return this.buffer[this.pos++]},getUint16:function(){var e=this.getByte(),t=this.getByte();return-1===e||-1===t?-1:(e<<8)+t},getInt32:function(){return(this.getByte()<<24)+(this.getByte()<<16)+(this.getByte()<<8)+this.getByte()},getBytes(e,t=!1){var a,r=this.pos;if(e){this.ensureBuffer(r+e);a=r+e;for(;!this.eof&&this.bufferLength<a;)this.readBlock();var i=this.bufferLength;a>i&&(a=i)}else{for(;!this.eof;)this.readBlock();a=this.bufferLength}this.pos=a;const n=this.buffer.subarray(r,a);return!t||n instanceof Uint8ClampedArray?n:new Uint8ClampedArray(n)},peekByte:function(){var e=this.getByte();-1!==e&&this.pos--;return e},peekBytes(e,t=!1){var a=this.getBytes(e,t);this.pos-=a.length;return a},makeSubStream:function(e,t,a){for(var r=e+t;this.bufferLength<=r&&!this.eof;)this.readBlock();return new s(this.buffer,e,t,a)},getByteRange(e,t){(0,r.unreachable)("Should not call DecodeStream.getByteRange")},skip:function(e){e||(e=1);this.pos+=e},reset:function(){this.pos=0},getBaseStreams:function(){return this.str&&this.str.getBaseStreams?this.str.getBaseStreams():[]}};return t}();t.DecodeStream=c;var l=function(){function e(e){this.streams=e;let t=0;for(let a=0,r=e.length;a<r;a++){const r=e[a];t+=r instanceof c?r._rawMinBufferLength:r.length}c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){var e=this.streams;if(0!==e.length){var t=e.shift().getBytes(),a=this.bufferLength,r=a+t.length;this.ensureBuffer(r).set(t,a);this.bufferLength=r}else this.eof=!0};e.prototype.getBaseStreams=function(){for(var e=[],t=0,a=this.streams.length;t<a;t++){var r=this.streams[t];r.getBaseStreams&&e.push(...r.getBaseStreams())}return e};return e}();t.StreamsSequenceStream=l;var h=function(){var e=new Int32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),t=new Int32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),a=new Int32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),i=[new Int32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],n=[new Int32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];function s(e,t){this.str=e;this.dict=e.dict;var a=e.getByte(),i=e.getByte();if(-1===a||-1===i)throw new r.FormatError(`Invalid header in flate stream: ${a}, ${i}`);if(8!=(15&a))throw new r.FormatError(`Unknown compression method in flate stream: ${a}, ${i}`);if(((a<<8)+i)%31!=0)throw new r.FormatError(`Bad FCHECK in flate stream: ${a}, ${i}`);if(32&i)throw new r.FormatError(`FDICT bit set in flate stream: ${a}, ${i}`);this.codeSize=0;this.codeBuf=0;c.call(this,t)}s.prototype=Object.create(c.prototype);s.prototype.getBits=function(e){for(var t,a=this.str,i=this.codeSize,n=this.codeBuf;i<e;){if(-1===(t=a.getByte()))throw new r.FormatError("Bad encoding in flate stream");n|=t<<i;i+=8}t=n&(1<<e)-1;this.codeBuf=n>>e;this.codeSize=i-=e;return t};s.prototype.getCode=function(e){for(var t,a=this.str,i=e[0],n=e[1],s=this.codeSize,o=this.codeBuf;s<n&&-1!==(t=a.getByte());){o|=t<<s;s+=8}var c=i[o&(1<<n)-1],l=c>>16,h=65535&c;if(l<1||s<l)throw new r.FormatError("Bad encoding in flate stream");this.codeBuf=o>>l;this.codeSize=s-l;return h};s.prototype.generateHuffmanTable=function(e){var t,a=e.length,r=0;for(t=0;t<a;++t)e[t]>r&&(r=e[t]);for(var i=1<<r,n=new Int32Array(i),s=1,o=0,c=2;s<=r;++s,o<<=1,c<<=1)for(var l=0;l<a;++l)if(e[l]===s){var h=0,u=o;for(t=0;t<s;++t){h=h<<1|1&u;u>>=1}for(t=h;t<i;t+=c)n[t]=s<<16|l;++o}return[n,r]};s.prototype.readBlock=function(){var s,o,c=this.str,l=this.getBits(3);1&l&&(this.eof=!0);if(0!==(l>>=1)){var h,u;if(1===l){h=i;u=n}else{if(2!==l)throw new r.FormatError("Unknown block type in flate stream");var d,f=this.getBits(5)+257,g=this.getBits(5)+1,m=this.getBits(4)+4,p=new Uint8Array(e.length);for(d=0;d<m;++d)p[e[d]]=this.getBits(3);var b=this.generateHuffmanTable(p);o=0;d=0;for(var y,v,w,k=f+g,S=new Uint8Array(k);d<k;){var C=this.getCode(b);if(16===C){y=2;v=3;w=o}else if(17===C){y=3;v=3;w=o=0}else{if(18!==C){S[d++]=o=C;continue}y=7;v=11;w=o=0}for(var x=this.getBits(y)+v;x-- >0;)S[d++]=w}h=this.generateHuffmanTable(S.subarray(0,f));u=this.generateHuffmanTable(S.subarray(f,k))}for(var A=(s=this.buffer)?s.length:0,I=this.bufferLength;;){var F=this.getCode(h);if(F<256){I+1>=A&&(A=(s=this.ensureBuffer(I+1)).length);s[I++]=F}else{if(256===F){this.bufferLength=I;return}var T=(F=t[F-=257])>>16;T>0&&(T=this.getBits(T));o=(65535&F)+T;F=this.getCode(u);(T=(F=a[F])>>16)>0&&(T=this.getBits(T));var E=(65535&F)+T;I+o>=A&&(A=(s=this.ensureBuffer(I+o)).length);for(var O=0;O<o;++O,++I)s[I]=s[I-E]}}}else{var P;if(-1===(P=c.getByte()))throw new r.FormatError("Bad block header in flate stream");var B=P;if(-1===(P=c.getByte()))throw new r.FormatError("Bad block header in flate stream");B|=P<<8;if(-1===(P=c.getByte()))throw new r.FormatError("Bad block header in flate stream");var D=P;if(-1===(P=c.getByte()))throw new r.FormatError("Bad block header in flate stream");if((D|=P<<8)!==(65535&~B)&&(0!==B||0!==D))throw new r.FormatError("Bad uncompressed block length in flate stream");this.codeBuf=0;this.codeSize=0;const e=this.bufferLength,t=e+B;s=this.ensureBuffer(t);this.bufferLength=t;if(0===B)-1===c.peekByte()&&(this.eof=!0);else{const t=c.getBytes(B);s.set(t,e);t.length<B&&(this.eof=!0)}}};return s}();t.FlateStream=h;var u=function(){function e(e,t,a){if(!(0,i.isDict)(a))return e;var n=this.predictor=a.get("Predictor")||1;if(n<=1)return e;if(2!==n&&(n<10||n>15))throw new r.FormatError(`Unsupported predictor: ${n}`);this.readBlock=2===n?this.readBlockTiff:this.readBlockPng;this.str=e;this.dict=e.dict;var s=this.colors=a.get("Colors")||1,o=this.bits=a.get("BitsPerComponent")||8,l=this.columns=a.get("Columns")||1;this.pixBytes=s*o+7>>3;this.rowBytes=l*s*o+7>>3;c.call(this,t);return this}e.prototype=Object.create(c.prototype);e.prototype.readBlockTiff=function(){var e=this.rowBytes,t=this.bufferLength,a=this.ensureBuffer(t+e),r=this.bits,i=this.colors,n=this.str.getBytes(e);this.eof=!n.length;if(!this.eof){var s,o=0,c=0,l=0,h=0,u=t;if(1===r&&1===i)for(s=0;s<e;++s){var d=n[s]^o;d^=d>>1;d^=d>>2;o=(1&(d^=d>>4))<<7;a[u++]=d}else if(8===r){for(s=0;s<i;++s)a[u++]=n[s];for(;s<e;++s){a[u]=a[u-i]+n[s];u++}}else if(16===r){var f=2*i;for(s=0;s<f;++s)a[u++]=n[s];for(;s<e;s+=2){var g=((255&n[s])<<8)+(255&n[s+1])+((255&a[u-f])<<8)+(255&a[u-f+1]);a[u++]=g>>8&255;a[u++]=255&g}}else{var m=new Uint8Array(i+1),p=(1<<r)-1,b=0,y=t,v=this.columns;for(s=0;s<v;++s)for(var w=0;w<i;++w){if(l<r){o=o<<8|255&n[b++];l+=8}m[w]=m[w]+(o>>l-r)&p;l-=r;c=c<<r|m[w];if((h+=r)>=8){a[y++]=c>>h-8&255;h-=8}}h>0&&(a[y++]=(c<<8-h)+(o&(1<<8-h)-1))}this.bufferLength+=e}};e.prototype.readBlockPng=function(){var e=this.rowBytes,t=this.pixBytes,a=this.str.getByte(),i=this.str.getBytes(e);this.eof=!i.length;if(!this.eof){var n=this.bufferLength,s=this.ensureBuffer(n+e),o=s.subarray(n-e,n);0===o.length&&(o=new Uint8Array(e));var c,l,h,u=n;switch(a){case 0:for(c=0;c<e;++c)s[u++]=i[c];break;case 1:for(c=0;c<t;++c)s[u++]=i[c];for(;c<e;++c){s[u]=s[u-t]+i[c]&255;u++}break;case 2:for(c=0;c<e;++c)s[u++]=o[c]+i[c]&255;break;case 3:for(c=0;c<t;++c)s[u++]=(o[c]>>1)+i[c];for(;c<e;++c){s[u]=(o[c]+s[u-t]>>1)+i[c]&255;u++}break;case 4:for(c=0;c<t;++c){l=o[c];h=i[c];s[u++]=l+h}for(;c<e;++c){l=o[c];var d=o[c-t],f=s[u-t],g=f+l-d,m=g-f;m<0&&(m=-m);var p=g-l;p<0&&(p=-p);var b=g-d;b<0&&(b=-b);h=i[c];s[u++]=m<=p&&m<=b?f+h:p<=b?l+h:d+h}break;default:throw new r.FormatError(`Unsupported predictor: ${a}`)}this.bufferLength+=e}};return e}();t.PredictorStream=u;var d=function(){function e(e,t,a){this.str=e;this.dict=e.dict;this.decrypt=a;this.nextChunk=null;this.initialized=!1;c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){var e;if(this.initialized)e=this.nextChunk;else{e=this.str.getBytes(512);this.initialized=!0}if(e&&0!==e.length){this.nextChunk=this.str.getBytes(512);var t=this.nextChunk&&this.nextChunk.length>0;e=(0,this.decrypt)(e,!t);var a,r=this.bufferLength,i=e.length,n=this.ensureBuffer(r+i);for(a=0;a<i;a++)n[r++]=e[a];this.bufferLength=r}else this.eof=!0};return e}();t.DecryptStream=d;var f=function(){function e(e,t){this.str=e;this.dict=e.dict;this.input=new Uint8Array(5);t&&(t*=.8);c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){for(var e=this.str,t=e.getByte();(0,n.isWhiteSpace)(t);)t=e.getByte();if(-1!==t&&126!==t){var a,r,i=this.bufferLength;if(122===t){a=this.ensureBuffer(i+4);for(r=0;r<4;++r)a[i+r]=0;this.bufferLength+=4}else{var s=this.input;s[0]=t;for(r=1;r<5;++r){t=e.getByte();for(;(0,n.isWhiteSpace)(t);)t=e.getByte();s[r]=t;if(-1===t||126===t)break}a=this.ensureBuffer(i+r-1);this.bufferLength+=r-1;if(r<5){for(;r<5;++r)s[r]=117;this.eof=!0}var o=0;for(r=0;r<5;++r)o=85*o+(s[r]-33);for(r=3;r>=0;--r){a[i+r]=255&o;o>>=8}}}else this.eof=!0};return e}();t.Ascii85Stream=f;var g=function(){function e(e,t){this.str=e;this.dict=e.dict;this.firstDigit=-1;t&&(t*=.5);c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){var e=this.str.getBytes(8e3);if(e.length){for(var t=e.length+1>>1,a=this.ensureBuffer(this.bufferLength+t),r=this.bufferLength,i=this.firstDigit,n=0,s=e.length;n<s;n++){var o,c=e[n];if(c>=48&&c<=57)o=15&c;else{if(!(c>=65&&c<=70||c>=97&&c<=102)){if(62===c){this.eof=!0;break}continue}o=9+(15&c)}if(i<0)i=o;else{a[r++]=i<<4|o;i=-1}}if(i>=0&&this.eof){a[r++]=i<<4;i=-1}this.firstDigit=i;this.bufferLength=r}else this.eof=!0};return e}();t.AsciiHexStream=g;var m=function(){function e(e,t){this.str=e;this.dict=e.dict;c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){var e=this.str.getBytes(2);if(!e||e.length<2||128===e[0])this.eof=!0;else{var t,a=this.bufferLength,r=e[0];if(r<128){(t=this.ensureBuffer(a+r+1))[a++]=e[1];if(r>0){var i=this.str.getBytes(r);t.set(i,a);a+=r}}else{r=257-r;var n=e[1];t=this.ensureBuffer(a+r+1);for(var s=0;s<r;s++)t[a++]=n}this.bufferLength=a}};return e}();t.RunLengthStream=m;var p=function(){function e(e,t,a){this.str=e;this.dict=e.dict;this.cachedData=0;this.bitsCached=0;for(var r={earlyChange:a,codeLength:9,nextCode:258,dictionaryValues:new Uint8Array(4096),dictionaryLengths:new Uint16Array(4096),dictionaryPrevCodes:new Uint16Array(4096),currentSequence:new Uint8Array(4096),currentSequenceLength:0},i=0;i<256;++i){r.dictionaryValues[i]=i;r.dictionaryLengths[i]=1}this.lzwState=r;c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBits=function(e){for(var t=this.bitsCached,a=this.cachedData;t<e;){var r=this.str.getByte();if(-1===r){this.eof=!0;return null}a=a<<8|r;t+=8}this.bitsCached=t-=e;this.cachedData=a;this.lastCode=null;return a>>>t&(1<<e)-1};e.prototype.readBlock=function(){var e,t,a,r=1024,i=this.lzwState;if(i){var n=i.earlyChange,s=i.nextCode,o=i.dictionaryValues,c=i.dictionaryLengths,l=i.dictionaryPrevCodes,h=i.codeLength,u=i.prevCode,d=i.currentSequence,f=i.currentSequenceLength,g=0,m=this.bufferLength,p=this.ensureBuffer(this.bufferLength+r);for(e=0;e<512;e++){var b=this.readBits(h),y=f>0;if(b<256){d[0]=b;f=1}else{if(!(b>=258)){if(256===b){h=9;s=258;f=0;continue}this.eof=!0;delete this.lzwState;break}if(b<s)for(t=(f=c[b])-1,a=b;t>=0;t--){d[t]=o[a];a=l[a]}else d[f++]=d[0]}if(y){l[s]=u;c[s]=c[u]+1;o[s]=d[0];h=++s+n&s+n-1?h:0|Math.min(Math.log(s+n)/.6931471805599453+1,12)}u=b;if(r<(g+=f)){do{r+=512}while(r<g);p=this.ensureBuffer(this.bufferLength+r)}for(t=0;t<f;t++)p[m++]=d[t]}i.nextCode=s;i.codeLength=h;i.prevCode=u;i.currentSequenceLength=f;this.bufferLength=m}};return e}();t.LZWStream=p;var b=function(){function e(){s.call(this,new Uint8Array(0))}e.prototype=s.prototype;return e}();t.NullStream=b},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.CCITTFaxStream=void 0;var r=a(4),i=a(13),n=a(11),s=function(){function e(e,t,a){this.str=e;this.dict=e.dict;(0,r.isDict)(a)||(a=r.Dict.empty);const s={next:()=>e.getByte()};this.ccittFaxDecoder=new i.CCITTFaxDecoder(s,{K:a.get("K"),EndOfLine:a.get("EndOfLine"),EncodedByteAlign:a.get("EncodedByteAlign"),Columns:a.get("Columns"),Rows:a.get("Rows"),EndOfBlock:a.get("EndOfBlock"),BlackIs1:a.get("BlackIs1")});n.DecodeStream.call(this,t)}e.prototype=Object.create(n.DecodeStream.prototype);e.prototype.readBlock=function(){for(;!this.eof;){const e=this.ccittFaxDecoder.readNextChar();if(-1===e){this.eof=!0;return}this.ensureBuffer(this.bufferLength+1);this.buffer[this.bufferLength++]=e}};return e}();t.CCITTFaxStream=s},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.CCITTFaxDecoder=void 0;var r=a(2);const i=function(){const e=[[-1,-1],[-1,-1],[7,8],[7,7],[6,6],[6,6],[6,5],[6,5],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2]],t=[[-1,-1],[12,-2],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[11,1792],[11,1792],[12,1984],[12,2048],[12,2112],[12,2176],[12,2240],[12,2304],[11,1856],[11,1856],[11,1920],[11,1920],[12,2368],[12,2432],[12,2496],[12,2560]],a=[[-1,-1],[-1,-1],[-1,-1],[-1,-1],[8,29],[8,29],[8,30],[8,30],[8,45],[8,45],[8,46],[8,46],[7,22],[7,22],[7,22],[7,22],[7,23],[7,23],[7,23],[7,23],[8,47],[8,47],[8,48],[8,48],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[7,20],[7,20],[7,20],[7,20],[8,33],[8,33],[8,34],[8,34],[8,35],[8,35],[8,36],[8,36],[8,37],[8,37],[8,38],[8,38],[7,19],[7,19],[7,19],[7,19],[8,31],[8,31],[8,32],[8,32],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[8,53],[8,53],[8,54],[8,54],[7,26],[7,26],[7,26],[7,26],[8,39],[8,39],[8,40],[8,40],[8,41],[8,41],[8,42],[8,42],[8,43],[8,43],[8,44],[8,44],[7,21],[7,21],[7,21],[7,21],[7,28],[7,28],[7,28],[7,28],[8,61],[8,61],[8,62],[8,62],[8,63],[8,63],[8,0],[8,0],[8,320],[8,320],[8,384],[8,384],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[7,27],[7,27],[7,27],[7,27],[8,59],[8,59],[8,60],[8,60],[9,1472],[9,1536],[9,1600],[9,1728],[7,18],[7,18],[7,18],[7,18],[7,24],[7,24],[7,24],[7,24],[8,49],[8,49],[8,50],[8,50],[8,51],[8,51],[8,52],[8,52],[7,25],[7,25],[7,25],[7,25],[8,55],[8,55],[8,56],[8,56],[8,57],[8,57],[8,58],[8,58],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[8,448],[8,448],[8,512],[8,512],[9,704],[9,768],[8,640],[8,640],[8,576],[8,576],[9,832],[9,896],[9,960],[9,1024],[9,1088],[9,1152],[9,1216],[9,1280],[9,1344],[9,1408],[7,256],[7,256],[7,256],[7,256],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7]],i=[[-1,-1],[-1,-1],[12,-2],[12,-2],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[11,1792],[11,1792],[11,1792],[11,1792],[12,1984],[12,1984],[12,2048],[12,2048],[12,2112],[12,2112],[12,2176],[12,2176],[12,2240],[12,2240],[12,2304],[12,2304],[11,1856],[11,1856],[11,1856],[11,1856],[11,1920],[11,1920],[11,1920],[11,1920],[12,2368],[12,2368],[12,2432],[12,2432],[12,2496],[12,2496],[12,2560],[12,2560],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[12,52],[12,52],[13,640],[13,704],[13,768],[13,832],[12,55],[12,55],[12,56],[12,56],[13,1280],[13,1344],[13,1408],[13,1472],[12,59],[12,59],[12,60],[12,60],[13,1536],[13,1600],[11,24],[11,24],[11,24],[11,24],[11,25],[11,25],[11,25],[11,25],[13,1664],[13,1728],[12,320],[12,320],[12,384],[12,384],[12,448],[12,448],[13,512],[13,576],[12,53],[12,53],[12,54],[12,54],[13,896],[13,960],[13,1024],[13,1088],[13,1152],[13,1216],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64]],n=[[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[11,23],[11,23],[12,50],[12,51],[12,44],[12,45],[12,46],[12,47],[12,57],[12,58],[12,61],[12,256],[10,16],[10,16],[10,16],[10,16],[10,17],[10,17],[10,17],[10,17],[12,48],[12,49],[12,62],[12,63],[12,30],[12,31],[12,32],[12,33],[12,40],[12,41],[11,22],[11,22],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[12,128],[12,192],[12,26],[12,27],[12,28],[12,29],[11,19],[11,19],[11,20],[11,20],[12,34],[12,35],[12,36],[12,37],[12,38],[12,39],[11,21],[11,21],[12,42],[12,43],[10,0],[10,0],[10,0],[10,0],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12]],s=[[-1,-1],[-1,-1],[-1,-1],[-1,-1],[6,9],[6,8],[5,7],[5,7],[4,6],[4,6],[4,6],[4,6],[4,5],[4,5],[4,5],[4,5],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2]];function o(e,t={}){if(!e||"function"!=typeof e.next)throw new Error('CCITTFaxDecoder - invalid "source" parameter.');this.source=e;this.eof=!1;this.encoding=t.K||0;this.eoline=t.EndOfLine||!1;this.byteAlign=t.EncodedByteAlign||!1;this.columns=t.Columns||1728;this.rows=t.Rows||0;let a,r=t.EndOfBlock;null==r&&(r=!0);this.eoblock=r;this.black=t.BlackIs1||!1;this.codingLine=new Uint32Array(this.columns+1);this.refLine=new Uint32Array(this.columns+2);this.codingLine[0]=this.columns;this.codingPos=0;this.row=0;this.nextLine2D=this.encoding<0;this.inputBits=0;this.inputBuf=0;this.outputBits=0;this.rowsDone=!1;for(;0===(a=this._lookBits(12));)this._eatBits(1);1===a&&this._eatBits(12);if(this.encoding>0){this.nextLine2D=!this._lookBits(1);this._eatBits(1)}}o.prototype={readNextChar(){if(this.eof)return-1;const e=this.refLine,t=this.codingLine,a=this.columns;let i,n,s,o,c;if(0===this.outputBits){this.rowsDone&&(this.eof=!0);if(this.eof)return-1;this.err=!1;let s,c,l;if(this.nextLine2D){for(o=0;t[o]<a;++o)e[o]=t[o];e[o++]=a;e[o]=a;t[0]=0;this.codingPos=0;i=0;n=0;for(;t[this.codingPos]<a;){s=this._getTwoDimCode();switch(s){case 0:this._addPixels(e[i+1],n);e[i+1]<a&&(i+=2);break;case 1:s=c=0;if(n){do{s+=l=this._getBlackCode()}while(l>=64);do{c+=l=this._getWhiteCode()}while(l>=64)}else{do{s+=l=this._getWhiteCode()}while(l>=64);do{c+=l=this._getBlackCode()}while(l>=64)}this._addPixels(t[this.codingPos]+s,n);t[this.codingPos]<a&&this._addPixels(t[this.codingPos]+c,1^n);for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2;break;case 7:this._addPixels(e[i]+3,n);n^=1;if(t[this.codingPos]<a){++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 5:this._addPixels(e[i]+2,n);n^=1;if(t[this.codingPos]<a){++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 3:this._addPixels(e[i]+1,n);n^=1;if(t[this.codingPos]<a){++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 2:this._addPixels(e[i],n);n^=1;if(t[this.codingPos]<a){++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 8:this._addPixelsNeg(e[i]-3,n);n^=1;if(t[this.codingPos]<a){i>0?--i:++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 6:this._addPixelsNeg(e[i]-2,n);n^=1;if(t[this.codingPos]<a){i>0?--i:++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 4:this._addPixelsNeg(e[i]-1,n);n^=1;if(t[this.codingPos]<a){i>0?--i:++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case-1:this._addPixels(a,0);this.eof=!0;break;default:(0,r.info)("bad 2d code");this._addPixels(a,0);this.err=!0}}}else{t[0]=0;this.codingPos=0;n=0;for(;t[this.codingPos]<a;){s=0;if(n)do{s+=l=this._getBlackCode()}while(l>=64);else do{s+=l=this._getWhiteCode()}while(l>=64);this._addPixels(t[this.codingPos]+s,n);n^=1}}let h=!1;this.byteAlign&&(this.inputBits&=-8);if(this.eoblock||this.row!==this.rows-1){s=this._lookBits(12);if(this.eoline)for(;-1!==s&&1!==s;){this._eatBits(1);s=this._lookBits(12)}else for(;0===s;){this._eatBits(1);s=this._lookBits(12)}if(1===s){this._eatBits(12);h=!0}else-1===s&&(this.eof=!0)}else this.rowsDone=!0;if(!this.eof&&this.encoding>0&&!this.rowsDone){this.nextLine2D=!this._lookBits(1);this._eatBits(1)}if(this.eoblock&&h&&this.byteAlign){s=this._lookBits(12);if(1===s){this._eatBits(12);if(this.encoding>0){this._lookBits(1);this._eatBits(1)}if(this.encoding>=0)for(o=0;o<4;++o){s=this._lookBits(12);1!==s&&(0,r.info)("bad rtc code: "+s);this._eatBits(12);if(this.encoding>0){this._lookBits(1);this._eatBits(1)}}this.eof=!0}}else if(this.err&&this.eoline){for(;;){s=this._lookBits(13);if(-1===s){this.eof=!0;return-1}if(s>>1==1)break;this._eatBits(1)}this._eatBits(12);if(this.encoding>0){this._eatBits(1);this.nextLine2D=!(1&s)}}t[0]>0?this.outputBits=t[this.codingPos=0]:this.outputBits=t[this.codingPos=1];this.row++}if(this.outputBits>=8){c=1&this.codingPos?0:255;this.outputBits-=8;if(0===this.outputBits&&t[this.codingPos]<a){this.codingPos++;this.outputBits=t[this.codingPos]-t[this.codingPos-1]}}else{s=8;c=0;do{if(this.outputBits>s){c<<=s;1&this.codingPos||(c|=255>>8-s);this.outputBits-=s;s=0}else{c<<=this.outputBits;1&this.codingPos||(c|=255>>8-this.outputBits);s-=this.outputBits;this.outputBits=0;if(t[this.codingPos]<a){this.codingPos++;this.outputBits=t[this.codingPos]-t[this.codingPos-1]}else if(s>0){c<<=s;s=0}}}while(s)}this.black&&(c^=255);return c},_addPixels(e,t){const a=this.codingLine;let i=this.codingPos;if(e>a[i]){if(e>this.columns){(0,r.info)("row is wrong length");this.err=!0;e=this.columns}1&i^t&&++i;a[i]=e}this.codingPos=i},_addPixelsNeg(e,t){const a=this.codingLine;let i=this.codingPos;if(e>a[i]){if(e>this.columns){(0,r.info)("row is wrong length");this.err=!0;e=this.columns}1&i^t&&++i;a[i]=e}else if(e<a[i]){if(e<0){(0,r.info)("invalid code");this.err=!0;e=0}for(;i>0&&e<a[i-1];)--i;a[i]=e}this.codingPos=i},_findTableCode(e,t,a,r){const i=r||0;for(let r=e;r<=t;++r){let e=this._lookBits(r);if(-1===e)return[!0,1,!1];r<t&&(e<<=t-r);if(!i||e>=i){const t=a[e-i];if(t[0]===r){this._eatBits(r);return[!0,t[1],!0]}}}return[!1,0,!1]},_getTwoDimCode(){let t,a=0;if(this.eoblock){a=this._lookBits(7);t=e[a];if(t&&t[0]>0){this._eatBits(t[0]);return t[1]}}else{const t=this._findTableCode(1,7,e);if(t[0]&&t[2])return t[1]}(0,r.info)("Bad two dim code");return-1},_getWhiteCode(){let e,i=0;if(this.eoblock){i=this._lookBits(12);if(-1===i)return 1;e=i>>5==0?t[i]:a[i>>3];if(e[0]>0){this._eatBits(e[0]);return e[1]}}else{let e=this._findTableCode(1,9,a);if(e[0])return e[1];e=this._findTableCode(11,12,t);if(e[0])return e[1]}(0,r.info)("bad white code");this._eatBits(1);return 1},_getBlackCode(){let e,t;if(this.eoblock){e=this._lookBits(13);if(-1===e)return 1;t=e>>7==0?i[e]:e>>9==0&&e>>7!=0?n[(e>>1)-64]:s[e>>7];if(t[0]>0){this._eatBits(t[0]);return t[1]}}else{let e=this._findTableCode(2,6,s);if(e[0])return e[1];e=this._findTableCode(7,12,n,64);if(e[0])return e[1];e=this._findTableCode(10,13,i);if(e[0])return e[1]}(0,r.info)("bad black code");this._eatBits(1);return 1},_lookBits(e){let t;for(;this.inputBits<e;){if(-1===(t=this.source.next()))return 0===this.inputBits?-1:this.inputBuf<<e-this.inputBits&65535>>16-e;this.inputBuf=this.inputBuf<<8|t;this.inputBits+=8}return this.inputBuf>>this.inputBits-e&65535>>16-e},_eatBits(e){(this.inputBits-=e)<0&&(this.inputBits=0)}};return o}();t.CCITTFaxDecoder=i},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Jbig2Stream=void 0;var r=a(4),i=a(11),n=a(15),s=a(2);const o=function(){function e(e,t,a,r){this.stream=e;this.maybeLength=t;this.dict=a;this.params=r;i.DecodeStream.call(this,t)}e.prototype=Object.create(i.DecodeStream.prototype);Object.defineProperty(e.prototype,"bytes",{get(){return(0,s.shadow)(this,"bytes",this.stream.getBytes(this.maybeLength))},configurable:!0});e.prototype.ensureBuffer=function(e){};e.prototype.readBlock=function(){if(this.eof)return;const e=new n.Jbig2Image,t=[];if((0,r.isDict)(this.params)){const e=this.params.get("JBIG2Globals");if((0,r.isStream)(e)){const a=e.getBytes();t.push({data:a,start:0,end:a.length})}}t.push({data:this.bytes,start:0,end:this.bytes.length});const a=e.parseChunks(t),i=a.length;for(let e=0;e<i;e++)a[e]^=255;this.buffer=a;this.bufferLength=i;this.eof=!0};return e}();t.Jbig2Stream=o},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Jbig2Image=void 0;var r=a(2),i=a(7),n=a(16),s=a(13);class o extends r.BaseException{constructor(e){super(`JBIG2 error: ${e}`)}}var c=function(){function e(){}e.prototype={getContexts(e){return e in this?this[e]:this[e]=new Int8Array(65536)}};function t(e,t,a){this.data=e;this.start=t;this.end=a}t.prototype={get decoder(){var e=new n.ArithmeticDecoder(this.data,this.start,this.end);return(0,r.shadow)(this,"decoder",e)},get contextCache(){var t=new e;return(0,r.shadow)(this,"contextCache",t)}};function a(e,t,a){var r=e.getContexts(t),i=1;function n(e){for(var t=0,n=0;n<e;n++){var s=a.readBit(r,i);i=i<256?i<<1|s:511&(i<<1|s)|256;t=t<<1|s}return t>>>0}var s=n(1),o=n(1)?n(1)?n(1)?n(1)?n(1)?n(32)+4436:n(12)+340:n(8)+84:n(6)+20:n(4)+4:n(2);return 0===s?o:o>0?-o:null}function c(e,t,a){for(var r=e.getContexts("IAID"),i=1,n=0;n<a;n++){i=i<<1|t.readBit(r,i)}return a<31?i&(1<<a)-1:2147483647&i}var l=["SymbolDictionary",null,null,null,"IntermediateTextRegion",null,"ImmediateTextRegion","ImmediateLosslessTextRegion",null,null,null,null,null,null,null,null,"PatternDictionary",null,null,null,"IntermediateHalftoneRegion",null,"ImmediateHalftoneRegion","ImmediateLosslessHalftoneRegion",null,null,null,null,null,null,null,null,null,null,null,null,"IntermediateGenericRegion",null,"ImmediateGenericRegion","ImmediateLosslessGenericRegion","IntermediateGenericRefinementRegion",null,"ImmediateGenericRefinementRegion","ImmediateLosslessGenericRefinementRegion",null,null,null,null,"PageInformation","EndOfPage","EndOfStripe","EndOfFile","Profiles","Tables",null,null,null,null,null,null,null,null,"Extension"],h=[[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:2,y:-1},{x:-4,y:0},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}],[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:2,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:2,y:-1},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}],[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-2,y:0},{x:-1,y:0}],[{x:-3,y:-1},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-4,y:0},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}]],u=[{coding:[{x:0,y:-1},{x:1,y:-1},{x:-1,y:0}],reference:[{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:0,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}]},{coding:[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0}],reference:[{x:0,y:-1},{x:-1,y:0},{x:0,y:0},{x:1,y:0},{x:0,y:1},{x:1,y:1}]}],d=[39717,1941,229,405],f=[32,8];function g(e,t,a,r,i,n,s,o){if(e){return B(new E(o.data,o.start,o.end),t,a,!1)}if(0===r&&!n&&!i&&4===s.length&&3===s[0].x&&-1===s[0].y&&-3===s[1].x&&-1===s[1].y&&2===s[2].x&&-2===s[2].y&&-2===s[3].x&&-2===s[3].y)return function(e,t,a){var r,i,n,s,o,c,l,h=a.decoder,u=a.contextCache.getContexts("GB"),d=[];for(i=0;i<t;i++){o=d[i]=new Uint8Array(e);c=i<1?o:d[i-1];r=(l=i<2?o:d[i-2])[0]<<13|l[1]<<12|l[2]<<11|c[0]<<7|c[1]<<6|c[2]<<5|c[3]<<4;for(n=0;n<e;n++){o[n]=s=h.readBit(u,r);r=(31735&r)<<1|(n+3<e?l[n+3]<<11:0)|(n+4<e?c[n+4]<<4:0)|s}}return d}(t,a,o);var c=!!n,l=h[r].concat(s);l.sort((function(e,t){return e.y-t.y||e.x-t.x}));var u,f,g=l.length,m=new Int8Array(g),p=new Int8Array(g),b=[],y=0,v=0,w=0,k=0;for(f=0;f<g;f++){m[f]=l[f].x;p[f]=l[f].y;v=Math.min(v,l[f].x);w=Math.max(w,l[f].x);k=Math.min(k,l[f].y);f<g-1&&l[f].y===l[f+1].y&&l[f].x===l[f+1].x-1?y|=1<<g-1-f:b.push(f)}var S=b.length,C=new Int8Array(S),x=new Int8Array(S),A=new Uint16Array(S);for(u=0;u<S;u++){f=b[u];C[u]=l[f].x;x[u]=l[f].y;A[u]=1<<g-1-f}for(var I,F,T,O,P,D=-v,N=-k,M=t-w,L=d[r],R=new Uint8Array(t),U=[],q=o.decoder,j=o.contextCache.getContexts("GB"),_=0,z=0,H=0;H<a;H++){if(i){if(_^=q.readBit(j,L)){U.push(R);continue}}R=new Uint8Array(R);U.push(R);for(I=0;I<t;I++)if(c&&n[H][I])R[I]=0;else{if(I>=D&&I<M&&H>=N){z=z<<1&y;for(f=0;f<S;f++){F=H+x[f];T=I+C[f];(O=U[F][T])&&(z|=O=A[f])}}else{z=0;P=g-1;for(f=0;f<g;f++,P--)(T=I+m[f])>=0&&T<t&&(F=H+p[f])>=0&&(O=U[F][T])&&(z|=O<<P)}var G=q.readBit(j,z);R[I]=G}}return U}function m(e,t,a,r,i,n,s,c,l){var h=u[a].coding;0===a&&(h=h.concat([c[0]]));var d,g=h.length,m=new Int32Array(g),p=new Int32Array(g);for(d=0;d<g;d++){m[d]=h[d].x;p[d]=h[d].y}var b=u[a].reference;0===a&&(b=b.concat([c[1]]));var y=b.length,v=new Int32Array(y),w=new Int32Array(y);for(d=0;d<y;d++){v[d]=b[d].x;w[d]=b[d].y}for(var k=r[0].length,S=r.length,C=f[a],x=[],A=l.decoder,I=l.contextCache.getContexts("GR"),F=0,T=0;T<t;T++){if(s){if(F^=A.readBit(I,C))throw new o("prediction is not supported")}var E=new Uint8Array(e);x.push(E);for(var O=0;O<e;O++){var P,B,D=0;for(d=0;d<g;d++){P=T+p[d];B=O+m[d];P<0||B<0||B>=e?D<<=1:D=D<<1|x[P][B]}for(d=0;d<y;d++){P=T+w[d]-n;B=O+v[d]-i;P<0||P>=S||B<0||B>=k?D<<=1:D=D<<1|r[P][B]}var N=A.readBit(I,D);E[O]=N}}return x}function p(e,t,r,i,n,s,l,h,u,d,f,g,p,b,y,v,w,k,S){if(e&&t)throw new o("refinement with Huffman is not supported");var C,x,A=[];for(C=0;C<i;C++){x=new Uint8Array(r);if(n)for(var I=0;I<r;I++)x[I]=n;A.push(x)}var F=w.decoder,T=w.contextCache,E=e?-b.tableDeltaT.decode(S):-a(T,"IADT",F),O=0;C=0;for(;C<s;){E+=e?b.tableDeltaT.decode(S):a(T,"IADT",F);for(var P=O+=e?b.tableFirstS.decode(S):a(T,"IAFS",F);;){let i=0;l>1&&(i=e?S.readBits(k):a(T,"IAIT",F));var B=l*E+i,D=e?b.symbolIDTable.decode(S):c(T,F,u),N=t&&(e?S.readBit():a(T,"IARI",F)),M=h[D],L=M[0].length,R=M.length;if(N){var U=a(T,"IARDW",F),q=a(T,"IARDH",F);M=m(L+=U,R+=q,y,M,(U>>1)+a(T,"IARDX",F),(q>>1)+a(T,"IARDY",F),!1,v,w)}var j,_,z,H=B-(1&g?0:R-1),G=P-(2&g?L-1:0);if(d){for(j=0;j<R;j++)if(x=A[G+j]){z=M[j];var W=Math.min(r-H,L);switch(p){case 0:for(_=0;_<W;_++)x[H+_]|=z[_];break;case 2:for(_=0;_<W;_++)x[H+_]^=z[_];break;default:throw new o(`operator ${p} is not supported`)}}P+=R-1}else{for(_=0;_<R;_++)if(x=A[H+_]){z=M[_];switch(p){case 0:for(j=0;j<L;j++)x[G+j]|=z[j];break;case 2:for(j=0;j<L;j++)x[G+j]^=z[j];break;default:throw new o(`operator ${p} is not supported`)}}P+=L-1}C++;var X=e?b.tableDeltaS.decode(S):a(T,"IADS",F);if(null===X)break;P+=X+f}}return A}function b(e,t){var a={};a.number=(0,i.readUint32)(e,t);var r=e[t+4],n=63&r;if(!l[n])throw new o("invalid segment type: "+n);a.type=n;a.typeName=l[n];a.deferredNonRetain=!!(128&r);var s=!!(64&r),c=e[t+5],h=c>>5&7,u=[31&c],d=t+6;if(7===c){h=536870911&(0,i.readUint32)(e,d-1);d+=3;var f=h+7>>3;u[0]=e[d++];for(;--f>0;)u.push(e[d++])}else if(5===c||6===c)throw new o("invalid referred-to flags");a.retainBits=u;let g=4;a.number<=256?g=1:a.number<=65536&&(g=2);var m,p,b=[];for(m=0;m<h;m++){let t;t=1===g?e[d]:2===g?(0,i.readUint16)(e,d):(0,i.readUint32)(e,d);b.push(t);d+=g}a.referredTo=b;if(s){a.pageAssociation=(0,i.readUint32)(e,d);d+=4}else a.pageAssociation=e[d++];a.length=(0,i.readUint32)(e,d);d+=4;if(4294967295===a.length){if(38!==n)throw new o("invalid unknown segment length");var y=v(e,d),k=!!(1&e[d+w]),S=new Uint8Array(6);if(!k){S[0]=255;S[1]=172}S[2]=y.height>>>24&255;S[3]=y.height>>16&255;S[4]=y.height>>8&255;S[5]=255&y.height;for(m=d,p=e.length;m<p;m++){for(var C=0;C<6&&S[C]===e[m+C];)C++;if(6===C){a.length=m+6;break}}if(4294967295===a.length)throw new o("segment end was not found")}a.headerEnd=d;return a}function y(e,t,a,r){for(var i=[],n=a;n<r;){var s=b(t,n);n=s.headerEnd;var o={header:s,data:t};if(!e.randomAccess){o.start=n;n+=s.length;o.end=n}i.push(o);if(51===s.type)break}if(e.randomAccess)for(var c=0,l=i.length;c<l;c++){i[c].start=n;n+=i[c].header.length;i[c].end=n}return i}function v(e,t){return{width:(0,i.readUint32)(e,t),height:(0,i.readUint32)(e,t+4),x:(0,i.readUint32)(e,t+8),y:(0,i.readUint32)(e,t+12),combinationOperator:7&e[t+16]}}var w=17;function k(e,t){var a,r,n,s,c=e.header,l=e.data,h=e.start,u=e.end;switch(c.type){case 0:var d={},f=(0,i.readUint16)(l,h);d.huffman=!!(1&f);d.refinement=!!(2&f);d.huffmanDHSelector=f>>2&3;d.huffmanDWSelector=f>>4&3;d.bitmapSizeSelector=f>>6&1;d.aggregationInstancesSelector=f>>7&1;d.bitmapCodingContextUsed=!!(256&f);d.bitmapCodingContextRetained=!!(512&f);d.template=f>>10&3;d.refinementTemplate=f>>12&1;h+=2;if(!d.huffman){s=0===d.template?4:1;r=[];for(n=0;n<s;n++){r.push({x:(0,i.readInt8)(l,h),y:(0,i.readInt8)(l,h+1)});h+=2}d.at=r}if(d.refinement&&!d.refinementTemplate){r=[];for(n=0;n<2;n++){r.push({x:(0,i.readInt8)(l,h),y:(0,i.readInt8)(l,h+1)});h+=2}d.refinementAt=r}d.numberOfExportedSymbols=(0,i.readUint32)(l,h);h+=4;d.numberOfNewSymbols=(0,i.readUint32)(l,h);h+=4;a=[d,c.number,c.referredTo,l,h,u];break;case 6:case 7:var g={};g.info=v(l,h);h+=w;var m=(0,i.readUint16)(l,h);h+=2;g.huffman=!!(1&m);g.refinement=!!(2&m);g.logStripSize=m>>2&3;g.stripSize=1<<g.logStripSize;g.referenceCorner=m>>4&3;g.transposed=!!(64&m);g.combinationOperator=m>>7&3;g.defaultPixelValue=m>>9&1;g.dsOffset=m<<17>>27;g.refinementTemplate=m>>15&1;if(g.huffman){var p=(0,i.readUint16)(l,h);h+=2;g.huffmanFS=3&p;g.huffmanDS=p>>2&3;g.huffmanDT=p>>4&3;g.huffmanRefinementDW=p>>6&3;g.huffmanRefinementDH=p>>8&3;g.huffmanRefinementDX=p>>10&3;g.huffmanRefinementDY=p>>12&3;g.huffmanRefinementSizeSelector=!!(16384&p)}if(g.refinement&&!g.refinementTemplate){r=[];for(n=0;n<2;n++){r.push({x:(0,i.readInt8)(l,h),y:(0,i.readInt8)(l,h+1)});h+=2}g.refinementAt=r}g.numberOfSymbolInstances=(0,i.readUint32)(l,h);h+=4;a=[g,c.referredTo,l,h,u];break;case 16:const e={},t=l[h++];e.mmr=!!(1&t);e.template=t>>1&3;e.patternWidth=l[h++];e.patternHeight=l[h++];e.maxPatternIndex=(0,i.readUint32)(l,h);h+=4;a=[e,c.number,l,h,u];break;case 22:case 23:const C={};C.info=v(l,h);h+=w;const x=l[h++];C.mmr=!!(1&x);C.template=x>>1&3;C.enableSkip=!!(8&x);C.combinationOperator=x>>4&7;C.defaultPixelValue=x>>7&1;C.gridWidth=(0,i.readUint32)(l,h);h+=4;C.gridHeight=(0,i.readUint32)(l,h);h+=4;C.gridOffsetX=4294967295&(0,i.readUint32)(l,h);h+=4;C.gridOffsetY=4294967295&(0,i.readUint32)(l,h);h+=4;C.gridVectorX=(0,i.readUint16)(l,h);h+=2;C.gridVectorY=(0,i.readUint16)(l,h);h+=2;a=[C,c.referredTo,l,h,u];break;case 38:case 39:var b={};b.info=v(l,h);h+=w;var y=l[h++];b.mmr=!!(1&y);b.template=y>>1&3;b.prediction=!!(8&y);if(!b.mmr){s=0===b.template?4:1;r=[];for(n=0;n<s;n++){r.push({x:(0,i.readInt8)(l,h),y:(0,i.readInt8)(l,h+1)});h+=2}b.at=r}a=[b,l,h,u];break;case 48:var k={width:(0,i.readUint32)(l,h),height:(0,i.readUint32)(l,h+4),resolutionX:(0,i.readUint32)(l,h+8),resolutionY:(0,i.readUint32)(l,h+12)};4294967295===k.height&&delete k.height;var S=l[h+16];(0,i.readUint16)(l,h+17);k.lossless=!!(1&S);k.refinement=!!(2&S);k.defaultPixelValue=S>>2&1;k.combinationOperator=S>>3&3;k.requiresBuffer=!!(32&S);k.combinationOperatorOverride=!!(64&S);a=[k];break;case 49:case 50:case 51:break;case 53:a=[c.number,l,h,u];break;case 62:break;default:throw new o(`segment type ${c.typeName}(${c.type})`+" is not implemented")}var C="on"+c.typeName;C in t&&t[C].apply(t,a)}function S(e,t){for(var a=0,r=e.length;a<r;a++)k(e[a],t)}function C(){}C.prototype={onPageInformation:function(e){this.currentPageInfo=e;var t=e.width+7>>3,a=new Uint8ClampedArray(t*e.height);if(e.defaultPixelValue)for(var r=0,i=a.length;r<i;r++)a[r]=255;this.buffer=a},drawBitmap:function(e,t){var a,r,i,n,s=this.currentPageInfo,c=e.width,l=e.height,h=s.width+7>>3,u=s.combinationOperatorOverride?e.combinationOperator:s.combinationOperator,d=this.buffer,f=128>>(7&e.x),g=e.y*h+(e.x>>3);switch(u){case 0:for(a=0;a<l;a++){i=f;n=g;for(r=0;r<c;r++){t[a][r]&&(d[n]|=i);if(!(i>>=1)){i=128;n++}}g+=h}break;case 2:for(a=0;a<l;a++){i=f;n=g;for(r=0;r<c;r++){t[a][r]&&(d[n]^=i);if(!(i>>=1)){i=128;n++}}g+=h}break;default:throw new o(`operator ${u} is not supported`)}},onImmediateGenericRegion:function(e,a,r,i){var n=e.info,s=new t(a,r,i),o=g(e.mmr,n.width,n.height,e.template,e.prediction,null,e.at,s);this.drawBitmap(n,o)},onImmediateLosslessGenericRegion:function(){this.onImmediateGenericRegion.apply(this,arguments)},onSymbolDictionary:function(e,r,n,s,l,h){let u,d;if(e.huffman){u=function(e,t,a){let r,i,n,s,c=0;switch(e.huffmanDHSelector){case 0:case 1:r=T(e.huffmanDHSelector+4);break;case 3:r=O(c,t,a);c++;break;default:throw new o("invalid Huffman DH selector")}switch(e.huffmanDWSelector){case 0:case 1:i=T(e.huffmanDWSelector+2);break;case 3:i=O(c,t,a);c++;break;default:throw new o("invalid Huffman DW selector")}if(e.bitmapSizeSelector){n=O(c,t,a);c++}else n=T(1);s=e.aggregationInstancesSelector?O(c,t,a):T(1);return{tableDeltaHeight:r,tableDeltaWidth:i,tableBitmapSize:n,tableAggregateInstances:s}}(e,n,this.customTables);d=new E(s,l,h)}var f=this.symbols;f||(this.symbols=f={});for(var b=[],y=0,v=n.length;y<v;y++){const e=f[n[y]];e&&(b=b.concat(e))}var w=new t(s,l,h);f[r]=function(e,t,r,n,s,l,h,u,d,f,b,y){if(e&&t)throw new o("symbol refinement with Huffman is not supported");var v=[],w=0,k=(0,i.log2)(r.length+n),S=b.decoder,C=b.contextCache;let x,A;if(e){x=T(1);A=[];k=Math.max(k,1)}for(;v.length<n;){w+=e?l.tableDeltaHeight.decode(y):a(C,"IADH",S);let i=0,n=0;const s=e?A.length:0;for(;;){var I,F=e?l.tableDeltaWidth.decode(y):a(C,"IADW",S);if(null===F)break;i+=F;n+=i;if(t){var E=a(C,"IAAI",S);if(E>1)I=p(e,t,i,w,0,E,1,r.concat(v),k,0,0,1,0,l,d,f,b,0,y);else{var O=c(C,S,k),D=a(C,"IARDX",S),N=a(C,"IARDY",S);I=m(i,w,d,O<r.length?r[O]:v[O-r.length],D,N,!1,f,b)}v.push(I)}else if(e)A.push(i);else{I=g(!1,i,w,h,!1,null,u,b);v.push(I)}}if(e&&!t){const e=l.tableBitmapSize.decode(y);y.byteAlign();let t;if(0===e)t=P(y,n,w);else{const a=y.end,r=y.position+e;y.end=r;t=B(y,n,w,!1);y.end=a;y.position=r}const a=A.length;if(s===a-1)v.push(t);else{let e,r,i,n,o,c=0;for(e=s;e<a;e++){n=A[e];i=c+n;o=[];for(r=0;r<w;r++)o.push(t[r].subarray(c,i));v.push(o);c=i}}}}for(var M=[],L=[],R=!1,U=r.length+n;L.length<U;){for(var q=e?x.decode(y):a(C,"IAEX",S);q--;)L.push(R);R=!R}for(var j=0,_=r.length;j<_;j++)L[j]&&M.push(r[j]);for(var z=0;z<n;j++,z++)L[j]&&M.push(v[z]);return M}(e.huffman,e.refinement,b,e.numberOfNewSymbols,e.numberOfExportedSymbols,u,e.template,e.at,e.refinementTemplate,e.refinementAt,w,d)},onImmediateTextRegion:function(e,a,r,n,s){var c=e.info;let l,h;for(var u=this.symbols,d=[],f=0,g=a.length;f<g;f++){const e=u[a[f]];e&&(d=d.concat(e))}var m=(0,i.log2)(d.length);if(e.huffman){h=new E(r,n,s);l=function(e,t,a,r,i){const n=[];for(let e=0;e<=34;e++){const t=i.readBits(4);n.push(new x([e,t,0,0]))}const s=new I(n,!1);n.length=0;for(let e=0;e<r;){const t=s.decode(i);if(t>=32){let a,r,s;switch(t){case 32:if(0===e)throw new o("no previous value in symbol ID table");r=i.readBits(2)+3;a=n[e-1].prefixLength;break;case 33:r=i.readBits(3)+3;a=0;break;case 34:r=i.readBits(7)+11;a=0;break;default:throw new o("invalid code length in symbol ID table")}for(s=0;s<r;s++){n.push(new x([e,a,0,0]));e++}}else{n.push(new x([e,t,0,0]));e++}}i.byteAlign();const c=new I(n,!1);let l,h,u,d=0;switch(e.huffmanFS){case 0:case 1:l=T(e.huffmanFS+6);break;case 3:l=O(d,t,a);d++;break;default:throw new o("invalid Huffman FS selector")}switch(e.huffmanDS){case 0:case 1:case 2:h=T(e.huffmanDS+8);break;case 3:h=O(d,t,a);d++;break;default:throw new o("invalid Huffman DS selector")}switch(e.huffmanDT){case 0:case 1:case 2:u=T(e.huffmanDT+11);break;case 3:u=O(d,t,a);d++;break;default:throw new o("invalid Huffman DT selector")}if(e.refinement)throw new o("refinement with Huffman is not supported");return{symbolIDTable:c,tableFirstS:l,tableDeltaS:h,tableDeltaT:u}}(e,a,this.customTables,d.length,h)}var b=new t(r,n,s),y=p(e.huffman,e.refinement,c.width,c.height,e.defaultPixelValue,e.numberOfSymbolInstances,e.stripSize,d,m,e.transposed,e.dsOffset,e.referenceCorner,e.combinationOperator,l,e.refinementTemplate,e.refinementAt,b,e.logStripSize,h);this.drawBitmap(c,y)},onImmediateLosslessTextRegion:function(){this.onImmediateTextRegion.apply(this,arguments)},onPatternDictionary(e,a,r,i,n){let s=this.patterns;s||(this.patterns=s={});const o=new t(r,i,n);s[a]=function(e,t,a,r,i,n){const s=[];if(!e){s.push({x:-t,y:0});if(0===i){s.push({x:-3,y:-1});s.push({x:2,y:-2});s.push({x:-2,y:-2})}}const o=g(e,(r+1)*t,a,i,!1,null,s,n),c=[];for(let e=0;e<=r;e++){const r=[],i=t*e,n=i+t;for(let e=0;e<a;e++)r.push(o[e].subarray(i,n));c.push(r)}return c}(e.mmr,e.patternWidth,e.patternHeight,e.maxPatternIndex,e.template,o)},onImmediateHalftoneRegion(e,a,r,n,s){const c=this.patterns[a[0]],l=e.info,h=new t(r,n,s),u=function(e,t,a,r,n,s,c,l,h,u,d,f,m,p,b){if(c)throw new o("skip is not supported");if(0!==l)throw new o("operator "+l+" is not supported in halftone region");const y=[];let v,w,k;for(v=0;v<n;v++){k=new Uint8Array(r);if(s)for(w=0;w<r;w++)k[w]=s;y.push(k)}const S=t.length,C=t[0],x=C[0].length,A=C.length,I=(0,i.log2)(S),F=[];if(!e){F.push({x:a<=1?3:2,y:-1});if(0===a){F.push({x:-3,y:-1});F.push({x:2,y:-2});F.push({x:-2,y:-2})}}const T=[];let O,P,D,N,M,L,R,U,q,j,_;e&&(O=new E(b.data,b.start,b.end));for(v=I-1;v>=0;v--){P=e?B(O,h,u,!0):g(!1,h,u,a,!1,null,F,b);T[v]=P}for(D=0;D<u;D++)for(N=0;N<h;N++){M=0;L=0;for(w=I-1;w>=0;w--){M=T[w][D][N]^M;L|=M<<w}R=t[L];U=d+D*p+N*m>>8;q=f+D*m-N*p>>8;if(U>=0&&U+x<=r&&q>=0&&q+A<=n)for(v=0;v<A;v++){_=y[q+v];j=R[v];for(w=0;w<x;w++)_[U+w]|=j[w]}else{let e,t;for(v=0;v<A;v++){t=q+v;if(!(t<0||t>=n)){_=y[t];j=R[v];for(w=0;w<x;w++){e=U+w;e>=0&&e<r&&(_[e]|=j[w])}}}}}return y}(e.mmr,c,e.template,l.width,l.height,e.defaultPixelValue,e.enableSkip,e.combinationOperator,e.gridWidth,e.gridHeight,e.gridOffsetX,e.gridOffsetY,e.gridVectorX,e.gridVectorY,h);this.drawBitmap(l,u)},onImmediateLosslessHalftoneRegion(){this.onImmediateHalftoneRegion.apply(this,arguments)},onTables(e,t,a,r){let n=this.customTables;n||(this.customTables=n={});n[e]=function(e,t,a){const r=e[t],n=4294967295&(0,i.readUint32)(e,t+1),s=4294967295&(0,i.readUint32)(e,t+5),o=new E(e,t+9,a),c=1+(r>>1&7),l=1+(r>>4&7),h=[];let u,d,f=n;do{u=o.readBits(c);d=o.readBits(l);h.push(new x([f,u,d,0]));f+=1<<d}while(f<s);u=o.readBits(c);h.push(new x([n-1,u,32,0,"lower"]));u=o.readBits(c);h.push(new x([s,u,32,0]));if(1&r){u=o.readBits(c);h.push(new x([u,0]))}return new I(h,!1)}(t,a,r)}};function x(e){if(2===e.length){this.isOOB=!0;this.rangeLow=0;this.prefixLength=e[0];this.rangeLength=0;this.prefixCode=e[1];this.isLowerRange=!1}else{this.isOOB=!1;this.rangeLow=e[0];this.prefixLength=e[1];this.rangeLength=e[2];this.prefixCode=e[3];this.isLowerRange="lower"===e[4]}}function A(e){this.children=[];if(e){this.isLeaf=!0;this.rangeLength=e.rangeLength;this.rangeLow=e.rangeLow;this.isLowerRange=e.isLowerRange;this.isOOB=e.isOOB}else this.isLeaf=!1}A.prototype={buildTree(e,t){const a=e.prefixCode>>t&1;if(t<=0)this.children[a]=new A(e);else{let r=this.children[a];r||(this.children[a]=r=new A(null));r.buildTree(e,t-1)}},decodeNode(e){if(this.isLeaf){if(this.isOOB)return null;const t=e.readBits(this.rangeLength);return this.rangeLow+(this.isLowerRange?-t:t)}const t=this.children[e.readBit()];if(!t)throw new o("invalid Huffman data");return t.decodeNode(e)}};function I(e,t){t||this.assignPrefixCodes(e);this.rootNode=new A(null);for(let t=0,a=e.length;t<a;t++){const a=e[t];a.prefixLength>0&&this.rootNode.buildTree(a,a.prefixLength-1)}}I.prototype={decode(e){return this.rootNode.decodeNode(e)},assignPrefixCodes(e){const t=e.length;let a=0;for(let r=0;r<t;r++)a=Math.max(a,e[r].prefixLength);const r=new Uint32Array(a+1);for(let a=0;a<t;a++)r[e[a].prefixLength]++;let i,n,s,o=1,c=0;r[0]=0;for(;o<=a;){c=c+r[o-1]<<1;i=c;n=0;for(;n<t;){s=e[n];if(s.prefixLength===o){s.prefixCode=i;i++}n++}o++}}};const F={};function T(e){let t,a=F[e];if(a)return a;switch(e){case 1:t=[[0,1,4,0],[16,2,8,2],[272,3,16,6],[65808,3,32,7]];break;case 2:t=[[0,1,0,0],[1,2,0,2],[2,3,0,6],[3,4,3,14],[11,5,6,30],[75,6,32,62],[6,63]];break;case 3:t=[[-256,8,8,254],[0,1,0,0],[1,2,0,2],[2,3,0,6],[3,4,3,14],[11,5,6,30],[-257,8,32,255,"lower"],[75,7,32,126],[6,62]];break;case 4:t=[[1,1,0,0],[2,2,0,2],[3,3,0,6],[4,4,3,14],[12,5,6,30],[76,5,32,31]];break;case 5:t=[[-255,7,8,126],[1,1,0,0],[2,2,0,2],[3,3,0,6],[4,4,3,14],[12,5,6,30],[-256,7,32,127,"lower"],[76,6,32,62]];break;case 6:t=[[-2048,5,10,28],[-1024,4,9,8],[-512,4,8,9],[-256,4,7,10],[-128,5,6,29],[-64,5,5,30],[-32,4,5,11],[0,2,7,0],[128,3,7,2],[256,3,8,3],[512,4,9,12],[1024,4,10,13],[-2049,6,32,62,"lower"],[2048,6,32,63]];break;case 7:t=[[-1024,4,9,8],[-512,3,8,0],[-256,4,7,9],[-128,5,6,26],[-64,5,5,27],[-32,4,5,10],[0,4,5,11],[32,5,5,28],[64,5,6,29],[128,4,7,12],[256,3,8,1],[512,3,9,2],[1024,3,10,3],[-1025,5,32,30,"lower"],[2048,5,32,31]];break;case 8:t=[[-15,8,3,252],[-7,9,1,508],[-5,8,1,253],[-3,9,0,509],[-2,7,0,124],[-1,4,0,10],[0,2,1,0],[2,5,0,26],[3,6,0,58],[4,3,4,4],[20,6,1,59],[22,4,4,11],[38,4,5,12],[70,5,6,27],[134,5,7,28],[262,6,7,60],[390,7,8,125],[646,6,10,61],[-16,9,32,510,"lower"],[1670,9,32,511],[2,1]];break;case 9:t=[[-31,8,4,252],[-15,9,2,508],[-11,8,2,253],[-7,9,1,509],[-5,7,1,124],[-3,4,1,10],[-1,3,1,2],[1,3,1,3],[3,5,1,26],[5,6,1,58],[7,3,5,4],[39,6,2,59],[43,4,5,11],[75,4,6,12],[139,5,7,27],[267,5,8,28],[523,6,8,60],[779,7,9,125],[1291,6,11,61],[-32,9,32,510,"lower"],[3339,9,32,511],[2,0]];break;case 10:t=[[-21,7,4,122],[-5,8,0,252],[-4,7,0,123],[-3,5,0,24],[-2,2,2,0],[2,5,0,25],[3,6,0,54],[4,7,0,124],[5,8,0,253],[6,2,6,1],[70,5,5,26],[102,6,5,55],[134,6,6,56],[198,6,7,57],[326,6,8,58],[582,6,9,59],[1094,6,10,60],[2118,7,11,125],[-22,8,32,254,"lower"],[4166,8,32,255],[2,2]];break;case 11:t=[[1,1,0,0],[2,2,1,2],[4,4,0,12],[5,4,1,13],[7,5,1,28],[9,5,2,29],[13,6,2,60],[17,7,2,122],[21,7,3,123],[29,7,4,124],[45,7,5,125],[77,7,6,126],[141,7,32,127]];break;case 12:t=[[1,1,0,0],[2,2,0,2],[3,3,1,6],[5,5,0,28],[6,5,1,29],[8,6,1,60],[10,7,0,122],[11,7,1,123],[13,7,2,124],[17,7,3,125],[25,7,4,126],[41,8,5,254],[73,8,32,255]];break;case 13:t=[[1,1,0,0],[2,3,0,4],[3,4,0,12],[4,5,0,28],[5,4,1,13],[7,3,3,5],[15,6,1,58],[17,6,2,59],[21,6,3,60],[29,6,4,61],[45,6,5,62],[77,7,6,126],[141,7,32,127]];break;case 14:t=[[-2,3,0,4],[-1,3,0,5],[0,1,0,0],[1,3,0,6],[2,3,0,7]];break;case 15:t=[[-24,7,4,124],[-8,6,2,60],[-4,5,1,28],[-2,4,0,12],[-1,3,0,4],[0,1,0,0],[1,3,0,5],[2,4,0,13],[3,5,1,29],[5,6,2,61],[9,7,4,125],[-25,7,32,126,"lower"],[25,7,32,127]];break;default:throw new o(`standard table B.${e} does not exist`)}for(let e=0,a=t.length;e<a;e++)t[e]=new x(t[e]);a=new I(t,!0);F[e]=a;return a}function E(e,t,a){this.data=e;this.start=t;this.end=a;this.position=t;this.shift=-1;this.currentByte=0}E.prototype={readBit(){if(this.shift<0){if(this.position>=this.end)throw new o("end of data while reading bit");this.currentByte=this.data[this.position++];this.shift=7}const e=this.currentByte>>this.shift&1;this.shift--;return e},readBits(e){let t,a=0;for(t=e-1;t>=0;t--)a|=this.readBit()<<t;return a},byteAlign(){this.shift=-1},next(){return this.position>=this.end?-1:this.data[this.position++]}};function O(e,t,a){let r=0;for(let i=0,n=t.length;i<n;i++){const n=a[t[i]];if(n){if(e===r)return n;r++}}throw new o("can't find custom Huffman table")}function P(e,t,a){const r=[];for(let i=0;i<a;i++){const a=new Uint8Array(t);r.push(a);for(let r=0;r<t;r++)a[r]=e.readBit();e.byteAlign()}return r}function B(e,t,a,r){const i={K:-1,Columns:t,Rows:a,BlackIs1:!0,EndOfBlock:r},n=new s.CCITTFaxDecoder(e,i),o=[];let c,l=!1;for(let e=0;e<a;e++){const e=new Uint8Array(t);o.push(e);let a=-1;for(let r=0;r<t;r++){if(a<0){c=n.readNextChar();if(-1===c){c=0;l=!0}a=7}e[r]=c>>a&1;a--}}if(r&&!l){const e=5;for(let t=0;t<e&&-1!==n.readNextChar();t++);}return o}function D(){}D.prototype={parseChunks:e=>function(e){for(var t=new C,a=0,r=e.length;a<r;a++){var i=e[a];S(y({},i.data,i.start,i.end),t)}return t.buffer}(e),parse(e){const{imgData:t,width:a,height:r}=function(e){const t=e.length;let a=0;if(151!==e[a]||74!==e[a+1]||66!==e[a+2]||50!==e[a+3]||13!==e[a+4]||10!==e[a+5]||26!==e[a+6]||10!==e[a+7])throw new o("parseJbig2 - invalid header.");const r=Object.create(null);a+=8;const n=e[a++];r.randomAccess=!(1&n);if(!(2&n)){r.numberOfPages=(0,i.readUint32)(e,a);a+=4}const s=y(r,e,a,t),c=new C;S(s,c);const{width:l,height:h}=c.currentPageInfo,u=c.buffer,d=new Uint8ClampedArray(l*h);let f=0,g=0;for(let e=0;e<h;e++){let e,t=0;for(let a=0;a<l;a++){if(!t){t=128;e=u[g++]}d[f++]=e&t?0:255;t>>=1}}return{imgData:d,width:l,height:h}}(e);this.width=a;this.height=r;return t}};return D}();t.Jbig2Image=c},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.ArithmeticDecoder=void 0;const r=[{qe:22017,nmps:1,nlps:1,switchFlag:1},{qe:13313,nmps:2,nlps:6,switchFlag:0},{qe:6145,nmps:3,nlps:9,switchFlag:0},{qe:2753,nmps:4,nlps:12,switchFlag:0},{qe:1313,nmps:5,nlps:29,switchFlag:0},{qe:545,nmps:38,nlps:33,switchFlag:0},{qe:22017,nmps:7,nlps:6,switchFlag:1},{qe:21505,nmps:8,nlps:14,switchFlag:0},{qe:18433,nmps:9,nlps:14,switchFlag:0},{qe:14337,nmps:10,nlps:14,switchFlag:0},{qe:12289,nmps:11,nlps:17,switchFlag:0},{qe:9217,nmps:12,nlps:18,switchFlag:0},{qe:7169,nmps:13,nlps:20,switchFlag:0},{qe:5633,nmps:29,nlps:21,switchFlag:0},{qe:22017,nmps:15,nlps:14,switchFlag:1},{qe:21505,nmps:16,nlps:14,switchFlag:0},{qe:20737,nmps:17,nlps:15,switchFlag:0},{qe:18433,nmps:18,nlps:16,switchFlag:0},{qe:14337,nmps:19,nlps:17,switchFlag:0},{qe:13313,nmps:20,nlps:18,switchFlag:0},{qe:12289,nmps:21,nlps:19,switchFlag:0},{qe:10241,nmps:22,nlps:19,switchFlag:0},{qe:9217,nmps:23,nlps:20,switchFlag:0},{qe:8705,nmps:24,nlps:21,switchFlag:0},{qe:7169,nmps:25,nlps:22,switchFlag:0},{qe:6145,nmps:26,nlps:23,switchFlag:0},{qe:5633,nmps:27,nlps:24,switchFlag:0},{qe:5121,nmps:28,nlps:25,switchFlag:0},{qe:4609,nmps:29,nlps:26,switchFlag:0},{qe:4353,nmps:30,nlps:27,switchFlag:0},{qe:2753,nmps:31,nlps:28,switchFlag:0},{qe:2497,nmps:32,nlps:29,switchFlag:0},{qe:2209,nmps:33,nlps:30,switchFlag:0},{qe:1313,nmps:34,nlps:31,switchFlag:0},{qe:1089,nmps:35,nlps:32,switchFlag:0},{qe:673,nmps:36,nlps:33,switchFlag:0},{qe:545,nmps:37,nlps:34,switchFlag:0},{qe:321,nmps:38,nlps:35,switchFlag:0},{qe:273,nmps:39,nlps:36,switchFlag:0},{qe:133,nmps:40,nlps:37,switchFlag:0},{qe:73,nmps:41,nlps:38,switchFlag:0},{qe:37,nmps:42,nlps:39,switchFlag:0},{qe:21,nmps:43,nlps:40,switchFlag:0},{qe:9,nmps:44,nlps:41,switchFlag:0},{qe:5,nmps:45,nlps:42,switchFlag:0},{qe:1,nmps:45,nlps:43,switchFlag:0},{qe:22017,nmps:46,nlps:46,switchFlag:0}];t.ArithmeticDecoder=class{constructor(e,t,a){this.data=e;this.bp=t;this.dataEnd=a;this.chigh=e[t];this.clow=0;this.byteIn();this.chigh=this.chigh<<7&65535|this.clow>>9&127;this.clow=this.clow<<7&65535;this.ct-=7;this.a=32768}byteIn(){const e=this.data;let t=this.bp;if(255===e[t])if(e[t+1]>143){this.clow+=65280;this.ct=8}else{t++;this.clow+=e[t]<<9;this.ct=7;this.bp=t}else{t++;this.clow+=t<this.dataEnd?e[t]<<8:65280;this.ct=8;this.bp=t}if(this.clow>65535){this.chigh+=this.clow>>16;this.clow&=65535}}readBit(e,t){let a=e[t]>>1,i=1&e[t];const n=r[a],s=n.qe;let o,c=this.a-s;if(this.chigh<s)if(c<s){c=s;o=i;a=n.nmps}else{c=s;o=1^i;1===n.switchFlag&&(i=o);a=n.nlps}else{this.chigh-=s;if(0!=(32768&c)){this.a=c;return i}if(c<s){o=1^i;1===n.switchFlag&&(i=o);a=n.nlps}else{o=i;a=n.nmps}}do{0===this.ct&&this.byteIn();c<<=1;this.chigh=this.chigh<<1&65535|this.clow>>15&1;this.clow=this.clow<<1&65535;this.ct--}while(0==(32768&c));this.a=c;e[t]=a<<1|i;return o}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.JpegStream=void 0;var r=a(2),i=a(11),n=a(4),s=a(18);const o=function(){function e(e,t,a,r){let n;for(;-1!==(n=e.getByte());)if(255===n){e.skip(-1);break}this.stream=e;this.maybeLength=t;this.dict=a;this.params=r;i.DecodeStream.call(this,t)}e.prototype=Object.create(i.DecodeStream.prototype);Object.defineProperty(e.prototype,"bytes",{get:function(){return(0,r.shadow)(this,"bytes",this.stream.getBytes(this.maybeLength))},configurable:!0});e.prototype.ensureBuffer=function(e){};e.prototype.readBlock=function(){if(this.eof)return;const e={decodeTransform:void 0,colorTransform:void 0},t=this.dict.getArray("Decode","D");if(this.forceRGB&&Array.isArray(t)){const a=this.dict.get("BitsPerComponent")||8,r=t.length,i=new Int32Array(r);let n=!1;const s=(1<<a)-1;for(let e=0;e<r;e+=2){i[e]=256*(t[e+1]-t[e])|0;i[e+1]=t[e]*s|0;256===i[e]&&0===i[e+1]||(n=!0)}n&&(e.decodeTransform=i)}if((0,n.isDict)(this.params)){const t=this.params.get("ColorTransform");Number.isInteger(t)&&(e.colorTransform=t)}const a=new s.JpegImage(e);a.parse(this.bytes);const r=a.getData({width:this.drawWidth,height:this.drawHeight,forceRGB:this.forceRGB,isSourcePDF:!0});this.buffer=r;this.bufferLength=r.length;this.eof=!0};Object.defineProperty(e.prototype,"maybeValidDimensions",{get:function(){const{dict:e,stream:t}=this,a=e.get("Height","H"),i=t.pos;let n,s=!0,o=!1;for(;-1!==(n=t.getByte());)if(255===n){switch(t.getByte()){case 192:case 193:case 194:o=!0;t.pos+=2;t.pos+=1;const e=t.getUint16();if(e===a)break;if(0===e){s=!1;break}if(e>10*a){s=!1;break}break;case 195:case 197:case 198:case 199:case 201:case 202:case 203:case 205:case 206:case 207:o=!0;break;case 196:case 204:case 218:case 219:case 220:case 221:case 222:case 223:case 224:case 225:case 226:case 227:case 228:case 229:case 230:case 231:case 232:case 233:case 234:case 235:case 236:case 237:case 238:case 239:case 254:const r=t.getUint16();r>2?t.skip(r-2):t.skip(-2);break;case 255:t.skip(-1);break;case 217:o=!0}if(o)break}t.pos=i;return(0,r.shadow)(this,"maybeValidDimensions",s)},configurable:!0});e.prototype.getIR=function(e=!1){return(0,r.createObjectURL)(this.bytes,"image/jpeg",e)};return e}();t.JpegStream=o},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.JpegImage=void 0;var r=a(2),i=a(7);class n extends r.BaseException{constructor(e){super(`JPEG error: ${e}`)}}class s extends r.BaseException{constructor(e,t){super(e);this.scanLines=t}}class o extends r.BaseException{}var c=function(){var e=new Uint8Array([0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63]);function t({decodeTransform:e=null,colorTransform:t=-1}={}){this._decodeTransform=e;this._colorTransform=t}function a(e,t){for(var a,r,i=0,n=[],s=16;s>0&&!e[s-1];)s--;n.push({children:[],index:0});var o,c=n[0];for(a=0;a<s;a++){for(r=0;r<e[a];r++){(c=n.pop()).children[c.index]=t[i];for(;c.index>0;)c=n.pop();c.index++;n.push(c);for(;n.length<=a;){n.push(o={children:[],index:0});c.children[c.index]=o.children;c=o}i++}if(a+1<s){n.push(o={children:[],index:0});c.children[c.index]=o.children;c=o}}return n[0].children}function c(e,t,a){return 64*((e.blocksPerLine+1)*t+a)}function l(t,a,l,h,u,f,g,m,p,b=!1){var y=l.mcusPerLine,v=l.progressive,w=a,k=0,S=0;function C(){if(S>0){S--;return k>>S&1}if(255===(k=t[a++])){var e=t[a++];if(e){if(220===e&&b){a+=2;const e=(0,i.readUint16)(t,a);a+=2;if(e>0&&e!==l.scanLines)throw new s("Found DNL marker (0xFFDC) while parsing scan data",e)}else if(217===e){if(b){const e=8*O;if(e>0&&e<l.scanLines/10)throw new s("Found EOI marker (0xFFD9) while parsing scan data, possibly caused by incorrect `scanLines` parameter",e)}throw new o("Found EOI marker (0xFFD9) while parsing scan data")}throw new n(`unexpected marker ${(k<<8|e).toString(16)}`)}}S=7;return k>>>7}function x(e){for(var t=e;;){switch(typeof(t=t[C()])){case"number":return t;case"object":continue}throw new n("invalid huffman sequence")}}function A(e){for(var t=0;e>0;){t=t<<1|C();e--}return t}function I(e){if(1===e)return 1===C()?1:-1;var t=A(e);return t>=1<<e-1?t:t+(-1<<e)+1}var F=0;var T,E=0;let O=0;function P(e,t,a,r,i){var n=a%y;O=(a/y|0)*e.v+r;var s=n*e.h+i;t(e,c(e,O,s))}function B(e,t,a){O=a/e.blocksPerLine|0;var r=a%e.blocksPerLine;t(e,c(e,O,r))}var D,N,M,L,R,U,q=h.length;U=v?0===f?0===m?function(e,t){var a=x(e.huffmanTableDC),r=0===a?0:I(a)<<p;e.blockData[t]=e.pred+=r}:function(e,t){e.blockData[t]|=C()<<p}:0===m?function(t,a){if(F>0)F--;else for(var r=f,i=g;r<=i;){var n=x(t.huffmanTableAC),s=15&n,o=n>>4;if(0!==s){var c=e[r+=o];t.blockData[a+c]=I(s)*(1<<p);r++}else{if(o<15){F=A(o)+(1<<o)-1;break}r+=16}}}:function(t,a){for(var r,i,s=f,o=g,c=0;s<=o;){const o=a+e[s],l=t.blockData[o]<0?-1:1;switch(E){case 0:c=(i=x(t.huffmanTableAC))>>4;if(0===(r=15&i))if(c<15){F=A(c)+(1<<c);E=4}else{c=16;E=1}else{if(1!==r)throw new n("invalid ACn encoding");T=I(r);E=c?2:3}continue;case 1:case 2:t.blockData[o]?t.blockData[o]+=l*(C()<<p):0===--c&&(E=2===E?3:0);break;case 3:if(t.blockData[o])t.blockData[o]+=l*(C()<<p);else{t.blockData[o]=T<<p;E=0}break;case 4:t.blockData[o]&&(t.blockData[o]+=l*(C()<<p))}s++}4===E&&0===--F&&(E=0)}:function(t,a){var r=x(t.huffmanTableDC),i=0===r?0:I(r);t.blockData[a]=t.pred+=i;for(var n=1;n<64;){var s=x(t.huffmanTableAC),o=15&s,c=s>>4;if(0!==o){var l=e[n+=c];t.blockData[a+l]=I(o);n++}else{if(c<15)break;n+=16}}};var j,_,z,H,G=0;_=1===q?h[0].blocksPerLine*h[0].blocksPerColumn:y*l.mcusPerColumn;for(;G<_;){var W=u?Math.min(_-G,u):_;for(N=0;N<q;N++)h[N].pred=0;F=0;if(1===q){D=h[0];for(R=0;R<W;R++){B(D,U,G);G++}}else for(R=0;R<W;R++){for(N=0;N<q;N++){z=(D=h[N]).h;H=D.v;for(M=0;M<H;M++)for(L=0;L<z;L++)P(D,U,G,M,L)}G++}S=0;if(!(j=d(t,a)))break;if(j.invalid){(0,r.warn)("decodeScan - unexpected MCU data, current marker is: "+j.invalid);a=j.offset}var X=j&&j.marker;if(!X||X<=65280)throw new n("decodeScan - a valid marker was not found.");if(!(X>=65488&&X<=65495))break;a+=2}if((j=d(t,a))&&j.invalid){(0,r.warn)("decodeScan - unexpected Scan data, current marker is: "+j.invalid);a=j.offset}return a-w}function h(e,t,a){var r,i,s,o,c,l,h,u,d,f,g,m,p,b,y,v,w,k=e.quantizationTable,S=e.blockData;if(!k)throw new n("missing required Quantization Table.");for(var C=0;C<64;C+=8){d=S[t+C];f=S[t+C+1];g=S[t+C+2];m=S[t+C+3];p=S[t+C+4];b=S[t+C+5];y=S[t+C+6];v=S[t+C+7];d*=k[C];if(0!=(f|g|m|p|b|y|v)){f*=k[C+1];g*=k[C+2];m*=k[C+3];p*=k[C+4];b*=k[C+5];i=(r=(r=5793*d+128>>8)+(i=5793*p+128>>8)+1>>1)-i;w=3784*(s=g)+1567*(o=y*=k[C+6])+128>>8;s=1567*s-3784*o+128>>8;h=(c=(c=2896*(f-(v*=k[C+7]))+128>>8)+(h=b<<4)+1>>1)-h;l=(u=(u=2896*(f+v)+128>>8)+(l=m<<4)+1>>1)-l;o=(r=r+(o=w)+1>>1)-o;s=(i=i+s+1>>1)-s;w=2276*c+3406*u+2048>>12;c=3406*c-2276*u+2048>>12;u=w;w=799*l+4017*h+2048>>12;l=4017*l-799*h+2048>>12;h=w;a[C]=r+u;a[C+7]=r-u;a[C+1]=i+h;a[C+6]=i-h;a[C+2]=s+l;a[C+5]=s-l;a[C+3]=o+c;a[C+4]=o-c}else{w=5793*d+512>>10;a[C]=w;a[C+1]=w;a[C+2]=w;a[C+3]=w;a[C+4]=w;a[C+5]=w;a[C+6]=w;a[C+7]=w}}for(var x=0;x<8;++x){d=a[x];if(0!=((f=a[x+8])|(g=a[x+16])|(m=a[x+24])|(p=a[x+32])|(b=a[x+40])|(y=a[x+48])|(v=a[x+56]))){i=(r=4112+((r=5793*d+2048>>12)+(i=5793*p+2048>>12)+1>>1))-i;w=3784*(s=g)+1567*(o=y)+2048>>12;s=1567*s-3784*o+2048>>12;o=w;h=(c=(c=2896*(f-v)+2048>>12)+(h=b)+1>>1)-h;l=(u=(u=2896*(f+v)+2048>>12)+(l=m)+1>>1)-l;w=2276*c+3406*u+2048>>12;c=3406*c-2276*u+2048>>12;u=w;w=799*l+4017*h+2048>>12;l=4017*l-799*h+2048>>12;(d=(r=r+o+1>>1)+u)<16?d=0:d>=4080?d=255:d>>=4;(f=(i=i+s+1>>1)+(h=w))<16?f=0:f>=4080?f=255:f>>=4;(g=(s=i-s)+l)<16?g=0:g>=4080?g=255:g>>=4;(m=(o=r-o)+c)<16?m=0:m>=4080?m=255:m>>=4;(p=o-c)<16?p=0:p>=4080?p=255:p>>=4;(b=s-l)<16?b=0:b>=4080?b=255:b>>=4;(y=i-h)<16?y=0:y>=4080?y=255:y>>=4;(v=r-u)<16?v=0:v>=4080?v=255:v>>=4;S[t+x]=d;S[t+x+8]=f;S[t+x+16]=g;S[t+x+24]=m;S[t+x+32]=p;S[t+x+40]=b;S[t+x+48]=y;S[t+x+56]=v}else{w=(w=5793*d+8192>>14)<-2040?0:w>=2024?255:w+2056>>4;S[t+x]=w;S[t+x+8]=w;S[t+x+16]=w;S[t+x+24]=w;S[t+x+32]=w;S[t+x+40]=w;S[t+x+48]=w;S[t+x+56]=w}}}function u(e,t){for(var a=t.blocksPerLine,r=t.blocksPerColumn,i=new Int16Array(64),n=0;n<r;n++)for(var s=0;s<a;s++){h(t,c(t,n,s),i)}return t.blockData}function d(e,t,a=t){const r=e.length-1;var n=a<t?a:t;if(t>=r)return null;var s=(0,i.readUint16)(e,t);if(s>=65472&&s<=65534)return{invalid:null,marker:s,offset:t};for(var o=(0,i.readUint16)(e,n);!(o>=65472&&o<=65534);){if(++n>=r)return null;o=(0,i.readUint16)(e,n)}return{invalid:s.toString(16),marker:o,offset:n}}t.prototype={parse(t,{dnlScanLines:c=null}={}){function h(){const e=(0,i.readUint16)(t,p);let a=(p+=2)+e-2;var n=d(t,a,p);if(n&&n.invalid){(0,r.warn)("readDataBlock - incorrect length, current marker is: "+n.invalid);a=n.offset}var s=t.subarray(p,a);p+=s.length;return s}function f(e){for(var t=Math.ceil(e.samplesPerLine/8/e.maxH),a=Math.ceil(e.scanLines/8/e.maxV),r=0;r<e.components.length;r++){z=e.components[r];var i=Math.ceil(Math.ceil(e.samplesPerLine/8)*z.h/e.maxH),n=Math.ceil(Math.ceil(e.scanLines/8)*z.v/e.maxV),s=t*z.h,o=64*(a*z.v)*(s+1);z.blockData=new Int16Array(o);z.blocksPerLine=i;z.blocksPerColumn=n}e.mcusPerLine=t;e.mcusPerColumn=a}var g,m,p=0,b=null,y=null;let v=0;var w=[],k=[],S=[];let C=(0,i.readUint16)(t,p);p+=2;if(65496!==C)throw new n("SOI not found");C=(0,i.readUint16)(t,p);p+=2;e:for(;65497!==C;){var x,A,I;switch(C){case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:case 65534:var F=h();65504===C&&74===F[0]&&70===F[1]&&73===F[2]&&70===F[3]&&0===F[4]&&(b={version:{major:F[5],minor:F[6]},densityUnits:F[7],xDensity:F[8]<<8|F[9],yDensity:F[10]<<8|F[11],thumbWidth:F[12],thumbHeight:F[13],thumbData:F.subarray(14,14+3*F[12]*F[13])});65518===C&&65===F[0]&&100===F[1]&&111===F[2]&&98===F[3]&&101===F[4]&&(y={version:F[5]<<8|F[6],flags0:F[7]<<8|F[8],flags1:F[9]<<8|F[10],transformCode:F[11]});break;case 65499:for(var T=(0,i.readUint16)(t,p)+(p+=2)-2;p<T;){var E=t[p++],O=new Uint16Array(64);if(E>>4==0)for(A=0;A<64;A++)O[e[A]]=t[p++];else{if(E>>4!=1)throw new n("DQT - invalid table spec");for(A=0;A<64;A++){O[e[A]]=(0,i.readUint16)(t,p);p+=2}}w[15&E]=O}break;case 65472:case 65473:case 65474:if(g)throw new n("Only single frame JPEGs supported");p+=2;(g={}).extended=65473===C;g.progressive=65474===C;g.precision=t[p++];const u=(0,i.readUint16)(t,p);p+=2;g.scanLines=c||u;g.samplesPerLine=(0,i.readUint16)(t,p);p+=2;g.components=[];g.componentIds={};var P,B=t[p++],D=0,N=0;for(x=0;x<B;x++){P=t[p];var M=t[p+1]>>4,L=15&t[p+1];D<M&&(D=M);N<L&&(N=L);var R=t[p+2];I=g.components.push({h:M,v:L,quantizationId:R,quantizationTable:null});g.componentIds[P]=I-1;p+=3}g.maxH=D;g.maxV=N;f(g);break;case 65476:const J=(0,i.readUint16)(t,p);p+=2;for(x=2;x<J;){var U=t[p++],q=new Uint8Array(16),j=0;for(A=0;A<16;A++,p++)j+=q[A]=t[p];var _=new Uint8Array(j);for(A=0;A<j;A++,p++)_[A]=t[p];x+=17+j;(U>>4==0?S:k)[15&U]=a(q,_)}break;case 65501:p+=2;m=(0,i.readUint16)(t,p);p+=2;break;case 65498:const Z=1==++v&&!c;p+=2;var z,H=t[p++],G=[];for(x=0;x<H;x++){var W=g.componentIds[t[p++]];z=g.components[W];var X=t[p++];z.huffmanTableDC=S[X>>4];z.huffmanTableAC=k[15&X];G.push(z)}var V=t[p++],K=t[p++],Y=t[p++];try{var $=l(t,p,g,G,m,V,K,Y>>4,15&Y,Z);p+=$}catch(e){if(e instanceof s){(0,r.warn)(`${e.message} -- attempting to re-parse the JPEG image.`);return this.parse(t,{dnlScanLines:e.scanLines})}if(e instanceof o){(0,r.warn)(`${e.message} -- ignoring the rest of the image data.`);break e}throw e}break;case 65500:p+=4;break;case 65535:255!==t[p]&&p--;break;default:const Q=d(t,p-2,p-3);if(Q&&Q.invalid){(0,r.warn)("JpegImage.parse - unexpected data, current marker is: "+Q.invalid);p=Q.offset;break}if(p>=t.length-1){(0,r.warn)("JpegImage.parse - reached the end of the image data without finding an EOI marker (0xFFD9).");break e}throw new n("JpegImage.parse - unknown marker: "+C.toString(16))}C=(0,i.readUint16)(t,p);p+=2}this.width=g.samplesPerLine;this.height=g.scanLines;this.jfif=b;this.adobe=y;this.components=[];for(x=0;x<g.components.length;x++){var J=w[(z=g.components[x]).quantizationId];J&&(z.quantizationTable=J);this.components.push({output:u(0,z),scaleX:z.h/g.maxH,scaleY:z.v/g.maxV,blocksPerLine:z.blocksPerLine,blocksPerColumn:z.blocksPerColumn})}this.numComponents=this.components.length},_getLinearizedBlockData(e,t,a=!1){var r,i,n,s,o,c,l,h,u,d,f,g=this.width/e,m=this.height/t,p=0,b=this.components.length,y=e*t*b,v=new Uint8ClampedArray(y),w=new Uint32Array(e);let k;for(l=0;l<b;l++){i=(r=this.components[l]).scaleX*g;n=r.scaleY*m;p=l;f=r.output;s=r.blocksPerLine+1<<3;if(i!==k){for(o=0;o<e;o++){h=0|o*i;w[o]=(4294967288&h)<<3|7&h}k=i}for(c=0;c<t;c++){d=s*(4294967288&(h=0|c*n))|(7&h)<<3;for(o=0;o<e;o++){v[p]=f[d+w[o]];p+=b}}}let S=this._decodeTransform;a||4!==b||S||(S=new Int32Array([-256,255,-256,255,-256,255,-256,255]));if(S)for(l=0;l<y;)for(h=0,u=0;h<b;h++,l++,u+=2)v[l]=(v[l]*S[u]>>8)+S[u+1];return v},get _isColorConversionNeeded(){return this.adobe?!!this.adobe.transformCode:3===this.numComponents?0!==this._colorTransform:1===this._colorTransform},_convertYccToRgb:function(e){for(var t,a,r,i=0,n=e.length;i<n;i+=3){t=e[i];a=e[i+1];r=e[i+2];e[i]=t-179.456+1.402*r;e[i+1]=t+135.459-.344*a-.714*r;e[i+2]=t-226.816+1.772*a}return e},_convertYcckToRgb:function(e){for(var t,a,r,i,n=0,s=0,o=e.length;s<o;s+=4){t=e[s];a=e[s+1];r=e[s+2];i=e[s+3];e[n++]=a*(-660635669420364e-19*a+.000437130475926232*r-54080610064599e-18*t+.00048449797120281*i-.154362151871126)-122.67195406894+r*(-.000957964378445773*r+.000817076911346625*t-.00477271405408747*i+1.53380253221734)+t*(.000961250184130688*t-.00266257332283933*i+.48357088451265)+i*(-.000336197177618394*i+.484791561490776);e[n++]=107.268039397724+a*(219927104525741e-19*a-.000640992018297945*r+.000659397001245577*t+.000426105652938837*i-.176491792462875)+r*(-.000778269941513683*r+.00130872261408275*t+.000770482631801132*i-.151051492775562)+t*(.00126935368114843*t-.00265090189010898*i+.25802910206845)+i*(-.000318913117588328*i-.213742400323665);e[n++]=a*(-.000570115196973677*a-263409051004589e-19*r+.0020741088115012*t-.00288260236853442*i+.814272968359295)-20.810012546947+r*(-153496057440975e-19*r-.000132689043961446*t+.000560833691242812*i-.195152027534049)+t*(.00174418132927582*t-.00255243321439347*i+.116935020465145)+i*(-.000343531996510555*i+.24165260232407)}return e.subarray(0,n)},_convertYcckToCmyk:function(e){for(var t,a,r,i=0,n=e.length;i<n;i+=4){t=e[i];a=e[i+1];r=e[i+2];e[i]=434.456-t-1.402*r;e[i+1]=119.541-t+.344*a+.714*r;e[i+2]=481.816-t-1.772*a}return e},_convertCmykToRgb:function(e){for(var t,a,r,i,n=0,s=0,o=e.length;s<o;s+=4){t=e[s];a=e[s+1];r=e[s+2];i=e[s+3];e[n++]=255+t*(-6747147073602441e-20*t+.0008379262121013727*a+.0002894718188643294*r+.003264231057537806*i-1.1185611867203937)+a*(26374107616089405e-21*a-8626949158638572e-20*r-.0002748769067499491*i-.02155688794978967)+r*(-3878099212869363e-20*r-.0003267808279485286*i+.0686742238595345)-i*(.0003361971776183937*i+.7430659151342254);e[n++]=255+t*(.00013596372813588848*t+.000924537132573585*a+.00010567359618683593*r+.0004791864687436512*i-.3109689587515875)+a*(-.00023545346108370344*a+.0002702845253534714*r+.0020200308977307156*i-.7488052167015494)+r*(6834815998235662e-20*r+.00015168452363460973*i-.09751927774728933)-i*(.0003189131175883281*i+.7364883807733168);e[n++]=255+t*(13598650411385307e-21*t+.00012423956175490851*a+.0004751985097583589*r-36729317476630422e-22*i-.05562186980264034)+a*(.00016141380598724676*a+.0009692239130725186*r+.0007782692450036253*i-.44015232367526463)+r*(5.068882914068769e-7*r+.0017778369011375071*i-.7591454649749609)-i*(.0003435319965105553*i+.7063770186160144)}return e.subarray(0,n)},getData({width:e,height:t,forceRGB:a=!1,isSourcePDF:r=!1}){if(this.numComponents>4)throw new n("Unsupported color mode");var i=this._getLinearizedBlockData(e,t,r);if(1===this.numComponents&&a){for(var s=i.length,o=new Uint8ClampedArray(3*s),c=0,l=0;l<s;l++){var h=i[l];o[c++]=h;o[c++]=h;o[c++]=h}return o}if(3===this.numComponents&&this._isColorConversionNeeded)return this._convertYccToRgb(i);if(4===this.numComponents){if(this._isColorConversionNeeded)return a?this._convertYcckToRgb(i):this._convertYcckToCmyk(i);if(a)return this._convertCmykToRgb(i)}return i}};return t}();t.JpegImage=c},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.JpxStream=void 0;var r=a(11),i=a(20),n=a(2);const s=function(){function e(e,t,a,i){this.stream=e;this.maybeLength=t;this.dict=a;this.params=i;r.DecodeStream.call(this,t)}e.prototype=Object.create(r.DecodeStream.prototype);Object.defineProperty(e.prototype,"bytes",{get:function(){return(0,n.shadow)(this,"bytes",this.stream.getBytes(this.maybeLength))},configurable:!0});e.prototype.ensureBuffer=function(e){};e.prototype.readBlock=function(){if(this.eof)return;const e=new i.JpxImage;e.parse(this.bytes);const t=e.width,a=e.height,r=e.componentsCount,n=e.tiles.length;if(1===n)this.buffer=e.tiles[0].items;else{const i=new Uint8ClampedArray(t*a*r);for(let a=0;a<n;a++){const n=e.tiles[a],s=n.width,o=n.height,c=n.left,l=n.top,h=n.items;let u=0,d=(t*l+c)*r;const f=t*r,g=s*r;for(let e=0;e<o;e++){const e=h.subarray(u,u+g);i.set(e,d);u+=g;d+=f}}this.buffer=i}this.bufferLength=this.buffer.length;this.eof=!0};return e}();t.JpxStream=s},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.JpxImage=void 0;var r=a(2),i=a(7),n=a(16);class s extends r.BaseException{constructor(e){super(`JPX error: ${e}`)}}var o=function(){var e={LL:0,LH:1,HL:1,HH:2};function t(){this.failOnCorruptedImage=!1}t.prototype={parse:function(e){if(65359!==(0,i.readUint16)(e,0))for(var t=0,a=e.length;t<a;){var n=8,o=(0,i.readUint32)(e,t),c=(0,i.readUint32)(e,t+4);t+=n;if(1===o){o=4294967296*(0,i.readUint32)(e,t)+(0,i.readUint32)(e,t+4);t+=8;n+=8}0===o&&(o=a-t+n);if(o<n)throw new s("Invalid box field size");var l=o-n,h=!0;switch(c){case 1785737832:h=!1;break;case 1668246642:var u=e[t];if(1===u){var d=(0,i.readUint32)(e,t+3);switch(d){case 16:case 17:case 18:break;default:(0,r.warn)("Unknown colorspace "+d)}}else 2===u&&(0,r.info)("ICC profile not supported");break;case 1785737827:this.parseCodestream(e,t,t+l);break;case 1783636e3:218793738!==(0,i.readUint32)(e,t)&&(0,r.warn)("Invalid JP2 signature");break;case 1783634458:case 1718909296:case 1920099697:case 1919251232:case 1768449138:break;default:var f=String.fromCharCode(c>>24&255,c>>16&255,c>>8&255,255&c);(0,r.warn)("Unsupported header type "+c+" ("+f+")")}h&&(t+=l)}else this.parseCodestream(e,0,e.length)},parseImageProperties:function(e){for(var t=e.getByte();t>=0;){if(65361===(t<<8|(t=e.getByte()))){e.skip(4);var a=e.getInt32()>>>0,r=e.getInt32()>>>0,i=e.getInt32()>>>0,n=e.getInt32()>>>0;e.skip(16);var o=e.getUint16();this.width=a-i;this.height=r-n;this.componentsCount=o;this.bitsPerComponent=8;return}}throw new s("No size marker found in JPX stream")},parseCodestream:function(e,t,n){var c={},l=!1;try{for(var h=t;h+1<n;){var u=(0,i.readUint16)(e,h);h+=2;var d,f,g,m,p,b,y=0;switch(u){case 65359:c.mainHeader=!0;break;case 65497:break;case 65361:y=(0,i.readUint16)(e,h);var k={};k.Xsiz=(0,i.readUint32)(e,h+4);k.Ysiz=(0,i.readUint32)(e,h+8);k.XOsiz=(0,i.readUint32)(e,h+12);k.YOsiz=(0,i.readUint32)(e,h+16);k.XTsiz=(0,i.readUint32)(e,h+20);k.YTsiz=(0,i.readUint32)(e,h+24);k.XTOsiz=(0,i.readUint32)(e,h+28);k.YTOsiz=(0,i.readUint32)(e,h+32);var x=(0,i.readUint16)(e,h+36);k.Csiz=x;var A=[];d=h+38;for(var I=0;I<x;I++){var F={precision:1+(127&e[d]),isSigned:!!(128&e[d]),XRsiz:e[d+1],YRsiz:e[d+2]};d+=3;a(F,k);A.push(F)}c.SIZ=k;c.components=A;o(c,A);c.QCC=[];c.COC=[];break;case 65372:y=(0,i.readUint16)(e,h);var T={};d=h+2;switch(31&(f=e[d++])){case 0:m=8;p=!0;break;case 1:m=16;p=!1;break;case 2:m=16;p=!0;break;default:throw new Error("Invalid SQcd value "+f)}T.noQuantization=8===m;T.scalarExpounded=p;T.guardBits=f>>5;g=[];for(;d<y+h;){var E={};if(8===m){E.epsilon=e[d++]>>3;E.mu=0}else{E.epsilon=e[d]>>3;E.mu=(7&e[d])<<8|e[d+1];d+=2}g.push(E)}T.SPqcds=g;if(c.mainHeader)c.QCD=T;else{c.currentTile.QCD=T;c.currentTile.QCC=[]}break;case 65373:y=(0,i.readUint16)(e,h);var O,P={};d=h+2;if(c.SIZ.Csiz<257)O=e[d++];else{O=(0,i.readUint16)(e,d);d+=2}switch(31&(f=e[d++])){case 0:m=8;p=!0;break;case 1:m=16;p=!1;break;case 2:m=16;p=!0;break;default:throw new Error("Invalid SQcd value "+f)}P.noQuantization=8===m;P.scalarExpounded=p;P.guardBits=f>>5;g=[];for(;d<y+h;){E={};if(8===m){E.epsilon=e[d++]>>3;E.mu=0}else{E.epsilon=e[d]>>3;E.mu=(7&e[d])<<8|e[d+1];d+=2}g.push(E)}P.SPqcds=g;c.mainHeader?c.QCC[O]=P:c.currentTile.QCC[O]=P;break;case 65362:y=(0,i.readUint16)(e,h);var B={};d=h+2;var D=e[d++];B.entropyCoderWithCustomPrecincts=!!(1&D);B.sopMarkerUsed=!!(2&D);B.ephMarkerUsed=!!(4&D);B.progressionOrder=e[d++];B.layersCount=(0,i.readUint16)(e,d);d+=2;B.multipleComponentTransform=e[d++];B.decompositionLevelsCount=e[d++];B.xcb=2+(15&e[d++]);B.ycb=2+(15&e[d++]);var N=e[d++];B.selectiveArithmeticCodingBypass=!!(1&N);B.resetContextProbabilities=!!(2&N);B.terminationOnEachCodingPass=!!(4&N);B.verticallyStripe=!!(8&N);B.predictableTermination=!!(16&N);B.segmentationSymbolUsed=!!(32&N);B.reversibleTransformation=e[d++];if(B.entropyCoderWithCustomPrecincts){for(var M=[];d<y+h;){var L=e[d++];M.push({PPx:15&L,PPy:L>>4})}B.precinctsSizes=M}var R=[];B.selectiveArithmeticCodingBypass&&R.push("selectiveArithmeticCodingBypass");B.resetContextProbabilities&&R.push("resetContextProbabilities");B.terminationOnEachCodingPass&&R.push("terminationOnEachCodingPass");B.verticallyStripe&&R.push("verticallyStripe");B.predictableTermination&&R.push("predictableTermination");if(R.length>0){l=!0;throw new Error("Unsupported COD options ("+R.join(", ")+")")}if(c.mainHeader)c.COD=B;else{c.currentTile.COD=B;c.currentTile.COC=[]}break;case 65424:y=(0,i.readUint16)(e,h);(b={}).index=(0,i.readUint16)(e,h+2);b.length=(0,i.readUint32)(e,h+4);b.dataEnd=b.length+h-2;b.partIndex=e[h+8];b.partsCount=e[h+9];c.mainHeader=!1;if(0===b.partIndex){b.COD=c.COD;b.COC=c.COC.slice(0);b.QCD=c.QCD;b.QCC=c.QCC.slice(0)}c.currentTile=b;break;case 65427:if(0===(b=c.currentTile).partIndex){C(c,b.index);v(c)}w(c,e,h,y=b.dataEnd-h);break;case 65365:case 65367:case 65368:case 65380:y=(0,i.readUint16)(e,h);break;case 65363:throw new Error("Codestream code 0xFF53 (COC) is not implemented");default:throw new Error("Unknown codestream code: "+u.toString(16))}h+=y}}catch(e){if(l||this.failOnCorruptedImage)throw new s(e.message);(0,r.warn)("JPX: Trying to recover from: "+e.message)}this.tiles=function(e){for(var t=e.SIZ,a=e.components,r=t.Csiz,i=[],n=0,s=e.tiles.length;n<s;n++){var o,c=e.tiles[n],l=[];for(o=0;o<r;o++)l[o]=S(e,c,o);var h,u,d,f,g,m,p,b=l[0],y=new Uint8ClampedArray(b.items.length*r),v={left:b.left,top:b.top,width:b.width,height:b.height,items:y},w=0;if(c.codingStyleDefaultParameters.multipleComponentTransform){var k=4===r,C=l[0].items,x=l[1].items,A=l[2].items,I=k?l[3].items:null;h=a[0].precision-8;u=.5+(128<<h);var F=c.components[0],T=r-3;f=C.length;if(F.codingStyleParameters.reversibleTransformation)for(d=0;d<f;d++,w+=T){g=C[d]+u;m=x[d];p=A[d];const e=g-(p+m>>2);y[w++]=e+p>>h;y[w++]=e>>h;y[w++]=e+m>>h}else for(d=0;d<f;d++,w+=T){g=C[d]+u;m=x[d];p=A[d];y[w++]=g+1.402*p>>h;y[w++]=g-.34413*m-.71414*p>>h;y[w++]=g+1.772*m>>h}if(k)for(d=0,w=3;d<f;d++,w+=4)y[w]=I[d]+u>>h}else for(o=0;o<r;o++){var E=l[o].items;h=a[o].precision-8;u=.5+(128<<h);for(w=o,d=0,f=E.length;d<f;d++){y[w]=E[d]+u>>h;w+=r}}i.push(v)}return i}(c);this.width=c.SIZ.Xsiz-c.SIZ.XOsiz;this.height=c.SIZ.Ysiz-c.SIZ.YOsiz;this.componentsCount=c.SIZ.Csiz}};function a(e,t){e.x0=Math.ceil(t.XOsiz/e.XRsiz);e.x1=Math.ceil(t.Xsiz/e.XRsiz);e.y0=Math.ceil(t.YOsiz/e.YRsiz);e.y1=Math.ceil(t.Ysiz/e.YRsiz);e.width=e.x1-e.x0;e.height=e.y1-e.y0}function o(e,t){for(var a,r=e.SIZ,i=[],n=Math.ceil((r.Xsiz-r.XTOsiz)/r.XTsiz),s=Math.ceil((r.Ysiz-r.YTOsiz)/r.YTsiz),o=0;o<s;o++)for(var c=0;c<n;c++){(a={}).tx0=Math.max(r.XTOsiz+c*r.XTsiz,r.XOsiz);a.ty0=Math.max(r.YTOsiz+o*r.YTsiz,r.YOsiz);a.tx1=Math.min(r.XTOsiz+(c+1)*r.XTsiz,r.Xsiz);a.ty1=Math.min(r.YTOsiz+(o+1)*r.YTsiz,r.Ysiz);a.width=a.tx1-a.tx0;a.height=a.ty1-a.ty0;a.components=[];i.push(a)}e.tiles=i;for(var l=0,h=r.Csiz;l<h;l++)for(var u=t[l],d=0,f=i.length;d<f;d++){var g={};a=i[d];g.tcx0=Math.ceil(a.tx0/u.XRsiz);g.tcy0=Math.ceil(a.ty0/u.YRsiz);g.tcx1=Math.ceil(a.tx1/u.XRsiz);g.tcy1=Math.ceil(a.ty1/u.YRsiz);g.width=g.tcx1-g.tcx0;g.height=g.tcy1-g.tcy0;a.components[l]=g}}function c(e,t,a){var r=t.codingStyleParameters,i={};if(r.entropyCoderWithCustomPrecincts){i.PPx=r.precinctsSizes[a].PPx;i.PPy=r.precinctsSizes[a].PPy}else{i.PPx=15;i.PPy=15}i.xcb_=a>0?Math.min(r.xcb,i.PPx-1):Math.min(r.xcb,i.PPx);i.ycb_=a>0?Math.min(r.ycb,i.PPy-1):Math.min(r.ycb,i.PPy);return i}function l(e,t,a){var r=1<<a.PPx,i=1<<a.PPy,n=0===t.resLevel,s=1<<a.PPx+(n?0:-1),o=1<<a.PPy+(n?0:-1),c=t.trx1>t.trx0?Math.ceil(t.trx1/r)-Math.floor(t.trx0/r):0,l=t.try1>t.try0?Math.ceil(t.try1/i)-Math.floor(t.try0/i):0,h=c*l;t.precinctParameters={precinctWidth:r,precinctHeight:i,numprecinctswide:c,numprecinctshigh:l,numprecincts:h,precinctWidthInSubband:s,precinctHeightInSubband:o}}function h(e,t,a){var r,i,n,s,o=a.xcb_,c=a.ycb_,l=1<<o,h=1<<c,u=t.tbx0>>o,d=t.tby0>>c,f=t.tbx1+l-1>>o,g=t.tby1+h-1>>c,m=t.resolution.precinctParameters,p=[],b=[];for(i=d;i<g;i++)for(r=u;r<f;r++){(n={cbx:r,cby:i,tbx0:l*r,tby0:h*i,tbx1:l*(r+1),tby1:h*(i+1)}).tbx0_=Math.max(t.tbx0,n.tbx0);n.tby0_=Math.max(t.tby0,n.tby0);n.tbx1_=Math.min(t.tbx1,n.tbx1);n.tby1_=Math.min(t.tby1,n.tby1);s=Math.floor((n.tbx0_-t.tbx0)/m.precinctWidthInSubband)+Math.floor((n.tby0_-t.tby0)/m.precinctHeightInSubband)*m.numprecinctswide;n.precinctNumber=s;n.subbandType=t.type;n.Lblock=3;if(!(n.tbx1_<=n.tbx0_||n.tby1_<=n.tby0_)){p.push(n);var y=b[s];if(void 0!==y){r<y.cbxMin?y.cbxMin=r:r>y.cbxMax&&(y.cbxMax=r);i<y.cbyMin?y.cbxMin=i:i>y.cbyMax&&(y.cbyMax=i)}else b[s]=y={cbxMin:r,cbyMin:i,cbxMax:r,cbyMax:i};n.precinct=y}}t.codeblockParameters={codeblockWidth:o,codeblockHeight:c,numcodeblockwide:f-u+1,numcodeblockhigh:g-d+1};t.codeblocks=p;t.precincts=b}function u(e,t,a){for(var r=[],i=e.subbands,n=0,s=i.length;n<s;n++)for(var o=i[n].codeblocks,c=0,l=o.length;c<l;c++){var h=o[c];h.precinctNumber===t&&r.push(h)}return{layerNumber:a,codeblocks:r}}function d(e){for(var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=r.codingStyleDefaultParameters.layersCount,n=t.Csiz,o=0,c=0;c<n;c++)o=Math.max(o,r.components[c].codingStyleParameters.decompositionLevelsCount);var l=0,h=0,d=0,f=0;this.nextPacket=function(){for(;l<i;l++){for(;h<=o;h++){for(;d<n;d++){var e=r.components[d];if(!(h>e.codingStyleParameters.decompositionLevelsCount)){for(var t=e.resolutions[h],a=t.precinctParameters.numprecincts;f<a;){var c=u(t,f,l);f++;return c}f=0}}d=0}h=0}throw new s("Out of packets")}}function f(e){for(var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=r.codingStyleDefaultParameters.layersCount,n=t.Csiz,o=0,c=0;c<n;c++)o=Math.max(o,r.components[c].codingStyleParameters.decompositionLevelsCount);var l=0,h=0,d=0,f=0;this.nextPacket=function(){for(;l<=o;l++){for(;h<i;h++){for(;d<n;d++){var e=r.components[d];if(!(l>e.codingStyleParameters.decompositionLevelsCount)){for(var t=e.resolutions[l],a=t.precinctParameters.numprecincts;f<a;){var c=u(t,f,h);f++;return c}f=0}}d=0}h=0}throw new s("Out of packets")}}function g(e){var t,a,r,i,n=e.SIZ,o=e.currentTile.index,c=e.tiles[o],l=c.codingStyleDefaultParameters.layersCount,h=n.Csiz,d=0;for(r=0;r<h;r++){var f=c.components[r];d=Math.max(d,f.codingStyleParameters.decompositionLevelsCount)}var g=new Int32Array(d+1);for(a=0;a<=d;++a){var m=0;for(r=0;r<h;++r){var p=c.components[r].resolutions;a<p.length&&(m=Math.max(m,p[a].precinctParameters.numprecincts))}g[a]=m}t=0;a=0;r=0;i=0;this.nextPacket=function(){for(;a<=d;a++){for(;i<g[a];i++){for(;r<h;r++){var e=c.components[r];if(!(a>e.codingStyleParameters.decompositionLevelsCount)){var n=e.resolutions[a],o=n.precinctParameters.numprecincts;if(!(i>=o)){for(;t<l;){var f=u(n,i,t);t++;return f}t=0}}}r=0}i=0}throw new s("Out of packets")}}function m(e){var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=r.codingStyleDefaultParameters.layersCount,n=t.Csiz,o=y(r),c=o,l=0,h=0,d=0,f=0,g=0;this.nextPacket=function(){for(;g<c.maxNumHigh;g++){for(;f<c.maxNumWide;f++){for(;d<n;d++){for(var e=r.components[d],t=e.codingStyleParameters.decompositionLevelsCount;h<=t;h++){var a=e.resolutions[h],m=o.components[d].resolutions[h],p=b(f,g,m,c,a);if(null!==p){for(;l<i;){var y=u(a,p,l);l++;return y}l=0}}h=0}d=0}f=0}throw new s("Out of packets")}}function p(e){var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=r.codingStyleDefaultParameters.layersCount,n=t.Csiz,o=y(r),c=0,l=0,h=0,d=0,f=0;this.nextPacket=function(){for(;h<n;++h){for(var e=r.components[h],t=o.components[h],a=e.codingStyleParameters.decompositionLevelsCount;f<t.maxNumHigh;f++){for(;d<t.maxNumWide;d++){for(;l<=a;l++){var g=e.resolutions[l],m=t.resolutions[l],p=b(d,f,m,t,g);if(null!==p){for(;c<i;){var y=u(g,p,c);c++;return y}c=0}}l=0}d=0}f=0}throw new s("Out of packets")}}function b(e,t,a,r,i){var n=e*r.minWidth,s=t*r.minHeight;if(n%a.width!=0||s%a.height!=0)return null;var o=s/a.width*i.precinctParameters.numprecinctswide;return n/a.height+o}function y(e){for(var t=e.components.length,a=Number.MAX_VALUE,r=Number.MAX_VALUE,i=0,n=0,s=new Array(t),o=0;o<t;o++){for(var c=e.components[o],l=c.codingStyleParameters.decompositionLevelsCount,h=new Array(l+1),u=Number.MAX_VALUE,d=Number.MAX_VALUE,f=0,g=0,m=1,p=l;p>=0;--p){var b=c.resolutions[p],y=m*b.precinctParameters.precinctWidth,v=m*b.precinctParameters.precinctHeight;u=Math.min(u,y);d=Math.min(d,v);f=Math.max(f,b.precinctParameters.numprecinctswide);g=Math.max(g,b.precinctParameters.numprecinctshigh);h[p]={width:y,height:v};m<<=1}a=Math.min(a,u);r=Math.min(r,d);i=Math.max(i,f);n=Math.max(n,g);s[o]={resolutions:h,minWidth:u,minHeight:d,maxNumWide:f,maxNumHigh:g}}return{components:s,minWidth:a,minHeight:r,maxNumWide:i,maxNumHigh:n}}function v(e){for(var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=t.Csiz,n=0;n<i;n++){for(var o=r.components[n],u=o.codingStyleParameters.decompositionLevelsCount,b=[],y=[],v=0;v<=u;v++){var w,k=c(0,o,v),S={},C=1<<u-v;S.trx0=Math.ceil(o.tcx0/C);S.try0=Math.ceil(o.tcy0/C);S.trx1=Math.ceil(o.tcx1/C);S.try1=Math.ceil(o.tcy1/C);S.resLevel=v;l(0,S,k);b.push(S);if(0===v){(w={}).type="LL";w.tbx0=Math.ceil(o.tcx0/C);w.tby0=Math.ceil(o.tcy0/C);w.tbx1=Math.ceil(o.tcx1/C);w.tby1=Math.ceil(o.tcy1/C);w.resolution=S;h(0,w,k);y.push(w);S.subbands=[w]}else{var x=1<<u-v+1,A=[];(w={}).type="HL";w.tbx0=Math.ceil(o.tcx0/x-.5);w.tby0=Math.ceil(o.tcy0/x);w.tbx1=Math.ceil(o.tcx1/x-.5);w.tby1=Math.ceil(o.tcy1/x);w.resolution=S;h(0,w,k);y.push(w);A.push(w);(w={}).type="LH";w.tbx0=Math.ceil(o.tcx0/x);w.tby0=Math.ceil(o.tcy0/x-.5);w.tbx1=Math.ceil(o.tcx1/x);w.tby1=Math.ceil(o.tcy1/x-.5);w.resolution=S;h(0,w,k);y.push(w);A.push(w);(w={}).type="HH";w.tbx0=Math.ceil(o.tcx0/x-.5);w.tby0=Math.ceil(o.tcy0/x-.5);w.tbx1=Math.ceil(o.tcx1/x-.5);w.tby1=Math.ceil(o.tcy1/x-.5);w.resolution=S;h(0,w,k);y.push(w);A.push(w);S.subbands=A}}o.resolutions=b;o.subbands=y}var I=r.codingStyleDefaultParameters.progressionOrder;switch(I){case 0:r.packetsIterator=new d(e);break;case 1:r.packetsIterator=new f(e);break;case 2:r.packetsIterator=new g(e);break;case 3:r.packetsIterator=new m(e);break;case 4:r.packetsIterator=new p(e);break;default:throw new s(`Unsupported progression order ${I}`)}}function w(e,t,a,r){var n,s=0,o=0,c=!1;function l(e){for(;o<e;){var r=t[a+s];s++;if(c){n=n<<7|r;o+=7;c=!1}else{n=n<<8|r;o+=8}255===r&&(c=!0)}return n>>>(o-=e)&(1<<e)-1}function h(e){if(255===t[a+s-1]&&t[a+s]===e){u(1);return!0}if(255===t[a+s]&&t[a+s+1]===e){u(2);return!0}return!1}function u(e){s+=e}function d(){o=0;if(c){s++;c=!1}}function f(){if(0===l(1))return 1;if(0===l(1))return 2;var e=l(2);return e<3?e+3:(e=l(5))<31?e+6:(e=l(7))+37}for(var g=e.currentTile.index,m=e.tiles[g],p=e.COD.sopMarkerUsed,b=e.COD.ephMarkerUsed,y=m.packetsIterator;s<r;){d();p&&h(145)&&u(4);var v=y.nextPacket();if(l(1)){for(var w,k=v.layerNumber,S=[],C=0,I=v.codeblocks.length;C<I;C++){var F=(w=v.codeblocks[C]).precinct,T=w.cbx-F.cbxMin,E=w.cby-F.cbyMin,O=!1,P=!1;if(void 0!==w.included)O=!!l(1);else{var B,D;if(void 0!==(F=w.precinct).inclusionTree)B=F.inclusionTree;else{var N=F.cbxMax-F.cbxMin+1,M=F.cbyMax-F.cbyMin+1;B=new A(N,M,k);D=new x(N,M);F.inclusionTree=B;F.zeroBitPlanesTree=D}if(B.reset(T,E,k))for(;;){if(!l(1)){B.incrementValue(k);break}if(!B.nextLevel()){w.included=!0;O=P=!0;break}}}if(O){if(P){(D=F.zeroBitPlanesTree).reset(T,E);for(;;)if(l(1)){if(!D.nextLevel())break}else D.incrementValue();w.zeroBitPlanes=D.value}for(var L=f();l(1);)w.Lblock++;var R=(0,i.log2)(L),U=l((L<1<<R?R-1:R)+w.Lblock);S.push({codeblock:w,codingpasses:L,dataLength:U})}}d();b&&h(146);for(;S.length>0;){var q=S.shift();void 0===(w=q.codeblock).data&&(w.data=[]);w.data.push({data:t,start:a+s,end:a+s+q.dataLength,codingpasses:q.codingpasses});s+=q.dataLength}}}return s}function k(e,t,a,r,i,s,o,c){for(var l=r.tbx0,h=r.tby0,u=r.tbx1-r.tbx0,d=r.codeblocks,f="H"===r.type.charAt(0)?1:0,g="H"===r.type.charAt(1)?t:0,m=0,p=d.length;m<p;++m){var b=d[m],y=b.tbx1_-b.tbx0_,v=b.tby1_-b.tby0_;if(0!==y&&0!==v&&void 0!==b.data){var w,k;w=new I(y,v,b.subbandType,b.zeroBitPlanes,s);k=2;var S,C,x,A=b.data,F=0,T=0;for(S=0,C=A.length;S<C;S++){F+=(x=A[S]).end-x.start;T+=x.codingpasses}var E=new Uint8Array(F),O=0;for(S=0,C=A.length;S<C;S++){var P=(x=A[S]).data.subarray(x.start,x.end);E.set(P,O);O+=P.length}var B=new n.ArithmeticDecoder(E,0,F);w.setDecoder(B);for(S=0;S<T;S++){switch(k){case 0:w.runSignificancePropagationPass();break;case 1:w.runMagnitudeRefinementPass();break;case 2:w.runCleanupPass();c&&w.checkSegmentationSymbol()}k=(k+1)%3}var D,N,M,L=b.tbx0_-l+(b.tby0_-h)*u,R=w.coefficentsSign,U=w.coefficentsMagnitude,q=w.bitsDecoded,j=o?0:.5;O=0;var _="LL"!==r.type;for(S=0;S<v;S++){var z=2*(L/u|0)*(t-u)+f+g;for(D=0;D<y;D++){if(0!==(N=U[O])){N=(N+j)*i;0!==R[O]&&(N=-N);M=q[O];var H=_?z+(L<<1):L;e[H]=o&&M>=s?N:N*(1<<s-M)}L++;O++}L+=u-y}}}}function S(t,a,r){for(var i=a.components[r],n=i.codingStyleParameters,s=i.quantizationParameters,o=n.decompositionLevelsCount,c=s.SPqcds,l=s.scalarExpounded,h=s.guardBits,u=n.segmentationSymbolUsed,d=t.components[r].precision,f=n.reversibleTransformation,g=f?new E:new T,m=[],p=0,b=0;b<=o;b++){for(var y=i.resolutions[b],v=y.trx1-y.trx0,w=y.try1-y.try0,S=new Float32Array(v*w),C=0,x=y.subbands.length;C<x;C++){var A,I;if(l){A=c[p].mu;I=c[p].epsilon;p++}else{A=c[0].mu;I=c[0].epsilon+(b>0?1-b:0)}var F=y.subbands[C],O=e[F.type];k(S,v,0,F,f?1:2**(d+O-I)*(1+A/2048),h+I-1,f,u)}m.push({width:v,height:w,items:S})}var P=g.calculate(m,i.tcx0,i.tcy0);return{left:i.tcx0,top:i.tcy0,width:P.width,height:P.height,items:P.items}}function C(e,t){for(var a=e.SIZ.Csiz,r=e.tiles[t],i=0;i<a;i++){var n=r.components[i],s=void 0!==e.currentTile.QCC[i]?e.currentTile.QCC[i]:e.currentTile.QCD;n.quantizationParameters=s;var o=void 0!==e.currentTile.COC[i]?e.currentTile.COC[i]:e.currentTile.COD;n.codingStyleParameters=o}r.codingStyleDefaultParameters=e.currentTile.COD}var x=function(){function e(e,t){var a=(0,i.log2)(Math.max(e,t))+1;this.levels=[];for(var r=0;r<a;r++){var n={width:e,height:t,items:[]};this.levels.push(n);e=Math.ceil(e/2);t=Math.ceil(t/2)}}e.prototype={reset:function(e,t){for(var a,r=0,i=0;r<this.levels.length;){var n=e+t*(a=this.levels[r]).width;if(void 0!==a.items[n]){i=a.items[n];break}a.index=n;e>>=1;t>>=1;r++}r--;(a=this.levels[r]).items[a.index]=i;this.currentLevel=r;delete this.value},incrementValue:function(){var e=this.levels[this.currentLevel];e.items[e.index]++},nextLevel:function(){var e=this.currentLevel,t=this.levels[e],a=t.items[t.index];if(--e<0){this.value=a;return!1}this.currentLevel=e;(t=this.levels[e]).items[t.index]=a;return!0}};return e}(),A=function(){function e(e,t,a){var r=(0,i.log2)(Math.max(e,t))+1;this.levels=[];for(var n=0;n<r;n++){for(var s=new Uint8Array(e*t),o=0,c=s.length;o<c;o++)s[o]=a;var l={width:e,height:t,items:s};this.levels.push(l);e=Math.ceil(e/2);t=Math.ceil(t/2)}}e.prototype={reset:function(e,t,a){for(var r=0;r<this.levels.length;){var i=this.levels[r],n=e+t*i.width;i.index=n;var s=i.items[n];if(255===s)break;if(s>a){this.currentLevel=r;this.propagateValues();return!1}e>>=1;t>>=1;r++}this.currentLevel=r-1;return!0},incrementValue:function(e){var t=this.levels[this.currentLevel];t.items[t.index]=e+1;this.propagateValues()},propagateValues:function(){for(var e=this.currentLevel,t=this.levels[e],a=t.items[t.index];--e>=0;)(t=this.levels[e]).items[t.index]=a},nextLevel:function(){var e=this.currentLevel,t=this.levels[e],a=t.items[t.index];t.items[t.index]=255;if(--e<0)return!1;this.currentLevel=e;(t=this.levels[e]).items[t.index]=a;return!0}};return e}(),I=function(){var e=new Uint8Array([0,5,8,0,3,7,8,0,4,7,8,0,0,0,0,0,1,6,8,0,3,7,8,0,4,7,8,0,0,0,0,0,2,6,8,0,3,7,8,0,4,7,8,0,0,0,0,0,2,6,8,0,3,7,8,0,4,7,8,0,0,0,0,0,2,6,8,0,3,7,8,0,4,7,8]),t=new Uint8Array([0,3,4,0,5,7,7,0,8,8,8,0,0,0,0,0,1,3,4,0,6,7,7,0,8,8,8,0,0,0,0,0,2,3,4,0,6,7,7,0,8,8,8,0,0,0,0,0,2,3,4,0,6,7,7,0,8,8,8,0,0,0,0,0,2,3,4,0,6,7,7,0,8,8,8]),a=new Uint8Array([0,1,2,0,1,2,2,0,2,2,2,0,0,0,0,0,3,4,5,0,4,5,5,0,5,5,5,0,0,0,0,0,6,7,7,0,7,7,7,0,7,7,7,0,0,0,0,0,8,8,8,0,8,8,8,0,8,8,8,0,0,0,0,0,8,8,8,0,8,8,8,0,8,8,8]);function r(r,i,n,s,o){this.width=r;this.height=i;let c;c="HH"===n?a:"HL"===n?t:e;this.contextLabelTable=c;var l=r*i;this.neighborsSignificance=new Uint8Array(l);this.coefficentsSign=new Uint8Array(l);let h;h=o>14?new Uint32Array(l):o>6?new Uint16Array(l):new Uint8Array(l);this.coefficentsMagnitude=h;this.processingFlags=new Uint8Array(l);var u=new Uint8Array(l);if(0!==s)for(var d=0;d<l;d++)u[d]=s;this.bitsDecoded=u;this.reset()}r.prototype={setDecoder:function(e){this.decoder=e},reset:function(){this.contexts=new Int8Array(19);this.contexts[0]=8;this.contexts[17]=92;this.contexts[18]=6},setNeighborsSignificance:function(e,t,a){var r,i=this.neighborsSignificance,n=this.width,s=this.height,o=t>0,c=t+1<n;if(e>0){r=a-n;o&&(i[r-1]+=16);c&&(i[r+1]+=16);i[r]+=4}if(e+1<s){r=a+n;o&&(i[r-1]+=16);c&&(i[r+1]+=16);i[r]+=4}o&&(i[a-1]+=1);c&&(i[a+1]+=1);i[a]|=128},runSignificancePropagationPass:function(){for(var e=this.decoder,t=this.width,a=this.height,r=this.coefficentsMagnitude,i=this.coefficentsSign,n=this.neighborsSignificance,s=this.processingFlags,o=this.contexts,c=this.contextLabelTable,l=this.bitsDecoded,h=0;h<a;h+=4)for(var u=0;u<t;u++)for(var d=h*t+u,f=0;f<4;f++,d+=t){var g=h+f;if(g>=a)break;s[d]&=-2;if(!r[d]&&n[d]){var m=c[n[d]];if(e.readBit(o,m)){var p=this.decodeSignBit(g,u,d);i[d]=p;r[d]=1;this.setNeighborsSignificance(g,u,d);s[d]|=2}l[d]++;s[d]|=1}}},decodeSignBit:function(e,t,a){var r,i,n,s,o,c,l=this.width,h=this.height,u=this.coefficentsMagnitude,d=this.coefficentsSign;s=t>0&&0!==u[a-1];if(t+1<l&&0!==u[a+1]){n=d[a+1];r=s?1-n-(i=d[a-1]):1-n-n}else r=s?1-(i=d[a-1])-i:0;var f=3*r;s=e>0&&0!==u[a-l];if(e+1<h&&0!==u[a+l]){n=d[a+l];r=s?1-n-(i=d[a-l])+f:1-n-n+f}else r=s?1-(i=d[a-l])-i+f:f;if(r>=0){o=9+r;c=this.decoder.readBit(this.contexts,o)}else{o=9-r;c=1^this.decoder.readBit(this.contexts,o)}return c},runMagnitudeRefinementPass:function(){for(var e,t=this.decoder,a=this.width,r=this.height,i=this.coefficentsMagnitude,n=this.neighborsSignificance,s=this.contexts,o=this.bitsDecoded,c=this.processingFlags,l=a*r,h=4*a,u=0;u<l;u=e){e=Math.min(l,u+h);for(var d=0;d<a;d++)for(var f=u+d;f<e;f+=a)if(i[f]&&0==(1&c[f])){var g=16;if(0!=(2&c[f])){c[f]^=2;g=0===(127&n[f])?15:14}var m=t.readBit(s,g);i[f]=i[f]<<1|m;o[f]++;c[f]|=1}}},runCleanupPass:function(){for(var e,t=this.decoder,a=this.width,r=this.height,i=this.neighborsSignificance,n=this.coefficentsMagnitude,s=this.coefficentsSign,o=this.contexts,c=this.contextLabelTable,l=this.bitsDecoded,h=this.processingFlags,u=a,d=2*a,f=3*a,g=0;g<r;g=e){e=Math.min(g+4,r);for(var m=g*a,p=g+3<r,b=0;b<a;b++){var y,v=m+b,w=0,k=v,S=g;if(p&&0===h[v]&&0===h[v+u]&&0===h[v+d]&&0===h[v+f]&&0===i[v]&&0===i[v+u]&&0===i[v+d]&&0===i[v+f]){if(!t.readBit(o,18)){l[v]++;l[v+u]++;l[v+d]++;l[v+f]++;continue}if(0!==(w=t.readBit(o,17)<<1|t.readBit(o,17))){S=g+w;k+=w*a}y=this.decodeSignBit(S,b,k);s[k]=y;n[k]=1;this.setNeighborsSignificance(S,b,k);h[k]|=2;k=v;for(var C=g;C<=S;C++,k+=a)l[k]++;w++}for(S=g+w;S<e;S++,k+=a)if(!n[k]&&0==(1&h[k])){var x=c[i[k]];if(1===t.readBit(o,x)){y=this.decodeSignBit(S,b,k);s[k]=y;n[k]=1;this.setNeighborsSignificance(S,b,k);h[k]|=2}l[k]++}}}},checkSegmentationSymbol:function(){var e=this.decoder,t=this.contexts;if(10!==(e.readBit(t,17)<<3|e.readBit(t,17)<<2|e.readBit(t,17)<<1|e.readBit(t,17)))throw new s("Invalid segmentation symbol")}};return r}(),F=function(){function e(){}e.prototype.calculate=function(e,t,a){for(var r=e[0],i=1,n=e.length;i<n;i++)r=this.iterate(r,e[i],t,a);return r};e.prototype.extend=function(e,t,a){var r=t-1,i=t+1,n=t+a-2,s=t+a;e[r--]=e[i++];e[s++]=e[n--];e[r--]=e[i++];e[s++]=e[n--];e[r--]=e[i++];e[s++]=e[n--];e[r]=e[i];e[s]=e[n]};e.prototype.iterate=function(e,t,a,r){var i,n,s,o,c,l,h=e.width,u=e.height,d=e.items,f=t.width,g=t.height,m=t.items;for(s=0,i=0;i<u;i++){o=2*i*f;for(n=0;n<h;n++,s++,o+=2)m[o]=d[s]}d=e.items=null;var p=new Float32Array(f+8);if(1===f){if(0!=(1&a))for(l=0,s=0;l<g;l++,s+=f)m[s]*=.5}else for(l=0,s=0;l<g;l++,s+=f){p.set(m.subarray(s,s+f),4);this.extend(p,4,f);this.filter(p,4,f);m.set(p.subarray(4,4+f),s)}var b=16,y=[];for(i=0;i<b;i++)y.push(new Float32Array(g+8));var v,w=0;e=4+g;if(1===g){if(0!=(1&r))for(c=0;c<f;c++)m[c]*=.5}else for(c=0;c<f;c++){if(0===w){b=Math.min(f-c,b);for(s=c,o=4;o<e;s+=f,o++)for(v=0;v<b;v++)y[v][o]=m[s+v];w=b}var k=y[--w];this.extend(k,4,g);this.filter(k,4,g);if(0===w){s=c-b+1;for(o=4;o<e;s+=f,o++)for(v=0;v<b;v++)m[s+v]=y[v][o]}}return{width:f,height:g,items:m}};return e}(),T=function(){function e(){F.call(this)}e.prototype=Object.create(F.prototype);e.prototype.filter=function(e,t,a){var r,i,n,s,o=a>>1,c=-1.586134342059924,l=-.052980118572961,h=.882911075530934,u=.443506852043971,d=1.230174104914001;r=(t|=0)-3;for(i=o+4;i--;r+=2)e[r]*=.8128930661159609;n=u*e[(r=t-2)-1];for(i=o+3;i--;r+=2){s=u*e[r+1];e[r]=d*e[r]-n-s;if(!i--)break;n=u*e[(r+=2)+1];e[r]=d*e[r]-n-s}n=h*e[(r=t-1)-1];for(i=o+2;i--;r+=2){s=h*e[r+1];e[r]-=n+s;if(!i--)break;n=h*e[(r+=2)+1];e[r]-=n+s}n=l*e[(r=t)-1];for(i=o+1;i--;r+=2){s=l*e[r+1];e[r]-=n+s;if(!i--)break;n=l*e[(r+=2)+1];e[r]-=n+s}if(0!==o){n=c*e[(r=t+1)-1];for(i=o;i--;r+=2){s=c*e[r+1];e[r]-=n+s;if(!i--)break;n=c*e[(r+=2)+1];e[r]-=n+s}}};return e}(),E=function(){function e(){F.call(this)}e.prototype=Object.create(F.prototype);e.prototype.filter=function(e,t,a){var r,i,n=a>>1;for(r=t|=0,i=n+1;i--;r+=2)e[r]-=e[r-1]+e[r+1]+2>>2;for(r=t+1,i=n;i--;r+=2)e[r]+=e[r-1]+e[r+1]>>1};return e}();return t}();t.JpxImage=o},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.calculateSHA512=t.calculateSHA384=t.calculateSHA256=t.calculateMD5=t.PDF20=t.PDF17=t.CipherTransformFactory=t.ARCFourCipher=t.AES256Cipher=t.AES128Cipher=void 0;var r=a(2),i=a(4),n=a(11),s=function(){function e(e){this.a=0;this.b=0;var t,a,r=new Uint8Array(256),i=0,n=e.length;for(t=0;t<256;++t)r[t]=t;for(t=0;t<256;++t){i=i+(a=r[t])+e[t%n]&255;r[t]=r[i];r[i]=a}this.s=r}e.prototype={encryptBlock:function(e){var t,a,r,i=e.length,n=this.a,s=this.b,o=this.s,c=new Uint8Array(i);for(t=0;t<i;++t){r=o[s=s+(a=o[n=n+1&255])&255];o[n]=r;o[s]=a;c[t]=e[t]^o[a+r&255]}this.a=n;this.b=s;return c}};e.prototype.decryptBlock=e.prototype.encryptBlock;return e}();t.ARCFourCipher=s;var o,c,l=(o=new Uint8Array([7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21]),c=new Int32Array([-680876936,-389564586,606105819,-1044525330,-176418897,1200080426,-1473231341,-45705983,1770035416,-1958414417,-42063,-1990404162,1804603682,-40341101,-1502002290,1236535329,-165796510,-1069501632,643717713,-373897302,-701558691,38016083,-660478335,-405537848,568446438,-1019803690,-187363961,1163531501,-1444681467,-51403784,1735328473,-1926607734,-378558,-2022574463,1839030562,-35309556,-1530992060,1272893353,-155497632,-1094730640,681279174,-358537222,-722521979,76029189,-640364487,-421815835,530742520,-995338651,-198630844,1126891415,-1416354905,-57434055,1700485571,-1894986606,-1051523,-2054922799,1873313359,-30611744,-1560198380,1309151649,-145523070,-1120210379,718787259,-343485551]),function(e,t,a){var r,i,n,s=1732584193,l=-271733879,h=-1732584194,u=271733878,d=a+72&-64,f=new Uint8Array(d);for(r=0;r<a;++r)f[r]=e[t++];f[r++]=128;n=d-8;for(;r<n;)f[r++]=0;f[r++]=a<<3&255;f[r++]=a>>5&255;f[r++]=a>>13&255;f[r++]=a>>21&255;f[r++]=a>>>29&255;f[r++]=0;f[r++]=0;f[r++]=0;var g=new Int32Array(16);for(r=0;r<d;){for(i=0;i<16;++i,r+=4)g[i]=f[r]|f[r+1]<<8|f[r+2]<<16|f[r+3]<<24;var m,p,b=s,y=l,v=h,w=u;for(i=0;i<64;++i){if(i<16){m=y&v|~y&w;p=i}else if(i<32){m=w&y|~w&v;p=5*i+1&15}else if(i<48){m=y^v^w;p=3*i+5&15}else{m=v^(y|~w);p=7*i&15}var k=w,S=b+m+c[i]+g[p]|0,C=o[i];w=v;v=y;y=y+(S<<C|S>>>32-C)|0;b=k}s=s+b|0;l=l+y|0;h=h+v|0;u=u+w|0}return new Uint8Array([255&s,s>>8&255,s>>16&255,s>>>24&255,255&l,l>>8&255,l>>16&255,l>>>24&255,255&h,h>>8&255,h>>16&255,h>>>24&255,255&u,u>>8&255,u>>16&255,u>>>24&255])});t.calculateMD5=l;var h=function(){function e(e,t){this.high=0|e;this.low=0|t}e.prototype={and:function(e){this.high&=e.high;this.low&=e.low},xor:function(e){this.high^=e.high;this.low^=e.low},or:function(e){this.high|=e.high;this.low|=e.low},shiftRight:function(e){if(e>=32){this.low=this.high>>>e-32|0;this.high=0}else{this.low=this.low>>>e|this.high<<32-e;this.high=this.high>>>e|0}},shiftLeft:function(e){if(e>=32){this.high=this.low<<e-32;this.low=0}else{this.high=this.high<<e|this.low>>>32-e;this.low=this.low<<e}},rotateRight:function(e){var t,a;if(32&e){a=this.low;t=this.high}else{t=this.low;a=this.high}e&=31;this.low=t>>>e|a<<32-e;this.high=a>>>e|t<<32-e},not:function(){this.high=~this.high;this.low=~this.low},add:function(e){var t=(this.low>>>0)+(e.low>>>0),a=(this.high>>>0)+(e.high>>>0);t>4294967295&&(a+=1);this.low=0|t;this.high=0|a},copyTo:function(e,t){e[t]=this.high>>>24&255;e[t+1]=this.high>>16&255;e[t+2]=this.high>>8&255;e[t+3]=255&this.high;e[t+4]=this.low>>>24&255;e[t+5]=this.low>>16&255;e[t+6]=this.low>>8&255;e[t+7]=255&this.low},assign:function(e){this.high=e.high;this.low=e.low}};return e}(),u=function(){function e(e,t){return e>>>t|e<<32-t}function t(e,t,a){return e&t^~e&a}function a(e,t,a){return e&t^e&a^t&a}function r(t){return e(t,2)^e(t,13)^e(t,22)}function i(t){return e(t,6)^e(t,11)^e(t,25)}function n(t){return e(t,7)^e(t,18)^t>>>3}var s=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];return function(o,c,l){var h,u,d,f=1779033703,g=3144134277,m=1013904242,p=2773480762,b=1359893119,y=2600822924,v=528734635,w=1541459225,k=64*Math.ceil((l+9)/64),S=new Uint8Array(k);for(h=0;h<l;++h)S[h]=o[c++];S[h++]=128;d=k-8;for(;h<d;)S[h++]=0;S[h++]=0;S[h++]=0;S[h++]=0;S[h++]=l>>>29&255;S[h++]=l>>21&255;S[h++]=l>>13&255;S[h++]=l>>5&255;S[h++]=l<<3&255;var C,x=new Uint32Array(64);for(h=0;h<k;){for(u=0;u<16;++u){x[u]=S[h]<<24|S[h+1]<<16|S[h+2]<<8|S[h+3];h+=4}for(u=16;u<64;++u)x[u]=(e(C=x[u-2],17)^e(C,19)^C>>>10)+x[u-7]+n(x[u-15])+x[u-16]|0;var A,I,F=f,T=g,E=m,O=p,P=b,B=y,D=v,N=w;for(u=0;u<64;++u){A=N+i(P)+t(P,B,D)+s[u]+x[u];I=r(F)+a(F,T,E);N=D;D=B;B=P;P=O+A|0;O=E;E=T;T=F;F=A+I|0}f=f+F|0;g=g+T|0;m=m+E|0;p=p+O|0;b=b+P|0;y=y+B|0;v=v+D|0;w=w+N|0}return new Uint8Array([f>>24&255,f>>16&255,f>>8&255,255&f,g>>24&255,g>>16&255,g>>8&255,255&g,m>>24&255,m>>16&255,m>>8&255,255&m,p>>24&255,p>>16&255,p>>8&255,255&p,b>>24&255,b>>16&255,b>>8&255,255&b,y>>24&255,y>>16&255,y>>8&255,255&y,v>>24&255,v>>16&255,v>>8&255,255&v,w>>24&255,w>>16&255,w>>8&255,255&w])}}();t.calculateSHA256=u;var d=function(){function e(e,t,a,r,i){e.assign(t);e.and(a);i.assign(t);i.not();i.and(r);e.xor(i)}function t(e,t,a,r,i){e.assign(t);e.and(a);i.assign(t);i.and(r);e.xor(i);i.assign(a);i.and(r);e.xor(i)}function a(e,t,a){e.assign(t);e.rotateRight(28);a.assign(t);a.rotateRight(34);e.xor(a);a.assign(t);a.rotateRight(39);e.xor(a)}function r(e,t,a){e.assign(t);e.rotateRight(14);a.assign(t);a.rotateRight(18);e.xor(a);a.assign(t);a.rotateRight(41);e.xor(a)}function i(e,t,a){e.assign(t);e.rotateRight(1);a.assign(t);a.rotateRight(8);e.xor(a);a.assign(t);a.shiftRight(7);e.xor(a)}function n(e,t,a){e.assign(t);e.rotateRight(19);a.assign(t);a.rotateRight(61);e.xor(a);a.assign(t);a.shiftRight(6);e.xor(a)}var s=[new h(1116352408,3609767458),new h(1899447441,602891725),new h(3049323471,3964484399),new h(3921009573,2173295548),new h(961987163,4081628472),new h(1508970993,3053834265),new h(2453635748,2937671579),new h(2870763221,3664609560),new h(3624381080,2734883394),new h(310598401,1164996542),new h(607225278,1323610764),new h(1426881987,3590304994),new h(1925078388,4068182383),new h(2162078206,991336113),new h(2614888103,633803317),new h(3248222580,3479774868),new h(3835390401,2666613458),new h(4022224774,944711139),new h(264347078,2341262773),new h(604807628,2007800933),new h(770255983,1495990901),new h(1249150122,1856431235),new h(1555081692,3175218132),new h(1996064986,2198950837),new h(2554220882,3999719339),new h(2821834349,766784016),new h(2952996808,2566594879),new h(3210313671,3203337956),new h(3336571891,1034457026),new h(3584528711,2466948901),new h(113926993,3758326383),new h(338241895,168717936),new h(666307205,1188179964),new h(773529912,1546045734),new h(1294757372,1522805485),new h(1396182291,2643833823),new h(1695183700,2343527390),new h(1986661051,1014477480),new h(2177026350,1206759142),new h(2456956037,344077627),new h(2730485921,1290863460),new h(2820302411,3158454273),new h(3259730800,3505952657),new h(3345764771,106217008),new h(3516065817,3606008344),new h(3600352804,1432725776),new h(4094571909,1467031594),new h(275423344,851169720),new h(430227734,3100823752),new h(506948616,1363258195),new h(659060556,3750685593),new h(883997877,3785050280),new h(958139571,3318307427),new h(1322822218,3812723403),new h(1537002063,2003034995),new h(1747873779,3602036899),new h(1955562222,1575990012),new h(2024104815,1125592928),new h(2227730452,2716904306),new h(2361852424,442776044),new h(2428436474,593698344),new h(2756734187,3733110249),new h(3204031479,2999351573),new h(3329325298,3815920427),new h(3391569614,3928383900),new h(3515267271,566280711),new h(3940187606,3454069534),new h(4118630271,4000239992),new h(116418474,1914138554),new h(174292421,2731055270),new h(289380356,3203993006),new h(460393269,320620315),new h(685471733,587496836),new h(852142971,1086792851),new h(1017036298,365543100),new h(1126000580,2618297676),new h(1288033470,3409855158),new h(1501505948,4234509866),new h(1607167915,987167468),new h(1816402316,1246189591)];return function(o,c,l,u){var d,f,g,m,p,b,y,v;if(u=!!u){d=new h(3418070365,3238371032);f=new h(1654270250,914150663);g=new h(2438529370,812702999);m=new h(355462360,4144912697);p=new h(1731405415,4290775857);b=new h(2394180231,1750603025);y=new h(3675008525,1694076839);v=new h(1203062813,3204075428)}else{d=new h(1779033703,4089235720);f=new h(3144134277,2227873595);g=new h(1013904242,4271175723);m=new h(2773480762,1595750129);p=new h(1359893119,2917565137);b=new h(2600822924,725511199);y=new h(528734635,4215389547);v=new h(1541459225,327033209)}var w,k,S,C=128*Math.ceil((l+17)/128),x=new Uint8Array(C);for(w=0;w<l;++w)x[w]=o[c++];x[w++]=128;S=C-16;for(;w<S;)x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=l>>>29&255;x[w++]=l>>21&255;x[w++]=l>>13&255;x[w++]=l>>5&255;x[w++]=l<<3&255;var A=new Array(80);for(w=0;w<80;w++)A[w]=new h(0,0);var I,F,T=new h(0,0),E=new h(0,0),O=new h(0,0),P=new h(0,0),B=new h(0,0),D=new h(0,0),N=new h(0,0),M=new h(0,0),L=new h(0,0),R=new h(0,0),U=new h(0,0),q=new h(0,0);for(w=0;w<C;){for(k=0;k<16;++k){A[k].high=x[w]<<24|x[w+1]<<16|x[w+2]<<8|x[w+3];A[k].low=x[w+4]<<24|x[w+5]<<16|x[w+6]<<8|x[w+7];w+=8}for(k=16;k<80;++k){n(I=A[k],A[k-2],q);I.add(A[k-7]);i(U,A[k-15],q);I.add(U);I.add(A[k-16])}T.assign(d);E.assign(f);O.assign(g);P.assign(m);B.assign(p);D.assign(b);N.assign(y);M.assign(v);for(k=0;k<80;++k){L.assign(M);r(U,B,q);L.add(U);e(U,B,D,N,q);L.add(U);L.add(s[k]);L.add(A[k]);a(R,T,q);t(U,T,E,O,q);R.add(U);I=M;M=N;N=D;D=B;P.add(L);B=P;P=O;O=E;E=T;I.assign(L);I.add(R);T=I}d.add(T);f.add(E);g.add(O);m.add(P);p.add(B);b.add(D);y.add(N);v.add(M)}if(u){F=new Uint8Array(48);d.copyTo(F,0);f.copyTo(F,8);g.copyTo(F,16);m.copyTo(F,24);p.copyTo(F,32);b.copyTo(F,40)}else{F=new Uint8Array(64);d.copyTo(F,0);f.copyTo(F,8);g.copyTo(F,16);m.copyTo(F,24);p.copyTo(F,32);b.copyTo(F,40);y.copyTo(F,48);v.copyTo(F,56)}return F}}();t.calculateSHA512=d;var f=function(e,t,a){return d(e,t,a,!0)};t.calculateSHA384=f;var g=function(){function e(){}e.prototype={decryptBlock:function(e){return e}};return e}();class m{constructor(){this.constructor===m&&(0,r.unreachable)("Cannot initialize AESBaseCipher.");this._s=new Uint8Array([99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22]);this._inv_s=new Uint8Array([82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,124,227,57,130,155,47,255,135,52,142,67,68,196,222,233,203,84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,46,161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,248,246,100,134,104,152,22,212,164,92,204,93,101,182,146,108,112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,216,171,0,140,188,211,10,247,228,88,5,184,179,69,6,208,44,30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,79,103,220,234,151,242,207,206,240,180,230,115,150,172,116,34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,113,29,41,197,137,111,183,98,14,170,24,190,27,252,86,62,75,198,210,121,32,154,219,192,254,120,205,90,244,31,221,168,51,136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181,74,13,45,229,122,159,147,201,156,239,160,224,59,77,174,42,245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,214,38,225,105,20,99,85,33,12,125]);this._mix=new Uint32Array([0,235474187,470948374,303765277,941896748,908933415,607530554,708780849,1883793496,2118214995,1817866830,1649639237,1215061108,1181045119,1417561698,1517767529,3767586992,4003061179,4236429990,4069246893,3635733660,3602770327,3299278474,3400528769,2430122216,2664543715,2362090238,2193862645,2835123396,2801107407,3035535058,3135740889,3678124923,3576870512,3341394285,3374361702,3810496343,3977675356,4279080257,4043610186,2876494627,2776292904,3076639029,3110650942,2472011535,2640243204,2403728665,2169303058,1001089995,899835584,666464733,699432150,59727847,226906860,530400753,294930682,1273168787,1172967064,1475418501,1509430414,1942435775,2110667444,1876241833,1641816226,2910219766,2743034109,2976151520,3211623147,2505202138,2606453969,2302690252,2269728455,3711829422,3543599269,3240894392,3475313331,3843699074,3943906441,4178062228,4144047775,1306967366,1139781709,1374988112,1610459739,1975683434,2076935265,1775276924,1742315127,1034867998,866637845,566021896,800440835,92987698,193195065,429456164,395441711,1984812685,2017778566,1784663195,1683407248,1315562145,1080094634,1383856311,1551037884,101039829,135050206,437757123,337553864,1042385657,807962610,573804783,742039012,2531067453,2564033334,2328828971,2227573024,2935566865,2700099354,3001755655,3168937228,3868552805,3902563182,4203181171,4102977912,3736164937,3501741890,3265478751,3433712980,1106041591,1340463100,1576976609,1408749034,2043211483,2009195472,1708848333,1809054150,832877231,1068351396,766945465,599762354,159417987,126454664,361929877,463180190,2709260871,2943682380,3178106961,3009879386,2572697195,2538681184,2236228733,2336434550,3509871135,3745345300,3441850377,3274667266,3910161971,3877198648,4110568485,4211818798,2597806476,2497604743,2261089178,2295101073,2733856160,2902087851,3202437046,2968011453,3936291284,3835036895,4136440770,4169408201,3535486456,3702665459,3467192302,3231722213,2051518780,1951317047,1716890410,1750902305,1113818384,1282050075,1584504582,1350078989,168810852,67556463,371049330,404016761,841739592,1008918595,775550814,540080725,3969562369,3801332234,4035489047,4269907996,3569255213,3669462566,3366754619,3332740144,2631065433,2463879762,2160117071,2395588676,2767645557,2868897406,3102011747,3069049960,202008497,33778362,270040487,504459436,875451293,975658646,675039627,641025152,2084704233,1917518562,1615861247,1851332852,1147550661,1248802510,1484005843,1451044056,933301370,967311729,733156972,632953703,260388950,25965917,328671808,496906059,1206477858,1239443753,1543208500,1441952575,2144161806,1908694277,1675577880,1842759443,3610369226,3644379585,3408119516,3307916247,4011190502,3776767469,4077384432,4245618683,2809771154,2842737049,3144396420,3043140495,2673705150,2438237621,2203032232,2370213795]);this._mixCol=new Uint8Array(256);for(let e=0;e<256;e++)this._mixCol[e]=e<128?e<<1:e<<1^27;this.buffer=new Uint8Array(16);this.bufferPosition=0}_expandKey(e){(0,r.unreachable)("Cannot call `_expandKey` on the base class")}_decrypt(e,t){let a,r,i;const n=new Uint8Array(16);n.set(e);for(let e=0,a=this._keySize;e<16;++e,++a)n[e]^=t[a];for(let e=this._cyclesOfRepetition-1;e>=1;--e){a=n[13];n[13]=n[9];n[9]=n[5];n[5]=n[1];n[1]=a;a=n[14];r=n[10];n[14]=n[6];n[10]=n[2];n[6]=a;n[2]=r;a=n[15];r=n[11];i=n[7];n[15]=n[3];n[11]=a;n[7]=r;n[3]=i;for(let e=0;e<16;++e)n[e]=this._inv_s[n[e]];for(let a=0,r=16*e;a<16;++a,++r)n[a]^=t[r];for(let e=0;e<16;e+=4){const t=this._mix[n[e]],r=this._mix[n[e+1]],i=this._mix[n[e+2]],s=this._mix[n[e+3]];a=t^r>>>8^r<<24^i>>>16^i<<16^s>>>24^s<<8;n[e]=a>>>24&255;n[e+1]=a>>16&255;n[e+2]=a>>8&255;n[e+3]=255&a}}a=n[13];n[13]=n[9];n[9]=n[5];n[5]=n[1];n[1]=a;a=n[14];r=n[10];n[14]=n[6];n[10]=n[2];n[6]=a;n[2]=r;a=n[15];r=n[11];i=n[7];n[15]=n[3];n[11]=a;n[7]=r;n[3]=i;for(let e=0;e<16;++e){n[e]=this._inv_s[n[e]];n[e]^=t[e]}return n}_encrypt(e,t){const a=this._s;let r,i,n;const s=new Uint8Array(16);s.set(e);for(let e=0;e<16;++e)s[e]^=t[e];for(let e=1;e<this._cyclesOfRepetition;e++){for(let e=0;e<16;++e)s[e]=a[s[e]];n=s[1];s[1]=s[5];s[5]=s[9];s[9]=s[13];s[13]=n;n=s[2];i=s[6];s[2]=s[10];s[6]=s[14];s[10]=n;s[14]=i;n=s[3];i=s[7];r=s[11];s[3]=s[15];s[7]=n;s[11]=i;s[15]=r;for(let e=0;e<16;e+=4){const t=s[e+0],a=s[e+1],i=s[e+2],n=s[e+3];r=t^a^i^n;s[e+0]^=r^this._mixCol[t^a];s[e+1]^=r^this._mixCol[a^i];s[e+2]^=r^this._mixCol[i^n];s[e+3]^=r^this._mixCol[n^t]}for(let a=0,r=16*e;a<16;++a,++r)s[a]^=t[r]}for(let e=0;e<16;++e)s[e]=a[s[e]];n=s[1];s[1]=s[5];s[5]=s[9];s[9]=s[13];s[13]=n;n=s[2];i=s[6];s[2]=s[10];s[6]=s[14];s[10]=n;s[14]=i;n=s[3];i=s[7];r=s[11];s[3]=s[15];s[7]=n;s[11]=i;s[15]=r;for(let e=0,a=this._keySize;e<16;++e,++a)s[e]^=t[a];return s}_decryptBlock2(e,t){const a=e.length;let r=this.buffer,i=this.bufferPosition;const n=[];let s=this.iv;for(let t=0;t<a;++t){r[i]=e[t];++i;if(i<16)continue;const a=this._decrypt(r,this._key);for(let e=0;e<16;++e)a[e]^=s[e];s=r;n.push(a);r=new Uint8Array(16);i=0}this.buffer=r;this.bufferLength=i;this.iv=s;if(0===n.length)return new Uint8Array(0);let o=16*n.length;if(t){const e=n[n.length-1];let t=e[15];if(t<=16){for(let a=15,r=16-t;a>=r;--a)if(e[a]!==t){t=0;break}o-=t;n[n.length-1]=e.subarray(0,16-t)}}const c=new Uint8Array(o);for(let e=0,t=0,a=n.length;e<a;++e,t+=16)c.set(n[e],t);return c}decryptBlock(e,t,a=null){const r=e.length,i=this.buffer;let n=this.bufferPosition;if(a)this.iv=a;else{for(let t=0;n<16&&t<r;++t,++n)i[n]=e[t];if(n<16){this.bufferLength=n;return new Uint8Array(0)}this.iv=i;e=e.subarray(16)}this.buffer=new Uint8Array(16);this.bufferLength=0;this.decryptBlock=this._decryptBlock2;return this.decryptBlock(e,t)}encrypt(e,t){const a=e.length;let r=this.buffer,i=this.bufferPosition;const n=[];t||(t=new Uint8Array(16));for(let s=0;s<a;++s){r[i]=e[s];++i;if(i<16)continue;for(let e=0;e<16;++e)r[e]^=t[e];const a=this._encrypt(r,this._key);t=a;n.push(a);r=new Uint8Array(16);i=0}this.buffer=r;this.bufferLength=i;this.iv=t;if(0===n.length)return new Uint8Array(0);const s=16*n.length,o=new Uint8Array(s);for(let e=0,t=0,a=n.length;e<a;++e,t+=16)o.set(n[e],t);return o}}class p extends m{constructor(e){super();this._cyclesOfRepetition=10;this._keySize=160;this._rcon=new Uint8Array([141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141]);this._key=this._expandKey(e)}_expandKey(e){const t=this._s,a=this._rcon,r=new Uint8Array(176);r.set(e);for(let e=16,i=1;e<176;++i){let n=r[e-3],s=r[e-2],o=r[e-1],c=r[e-4];n=t[n];s=t[s];o=t[o];c=t[c];n^=a[i];for(let t=0;t<4;++t){r[e]=n^=r[e-16];e++;r[e]=s^=r[e-16];e++;r[e]=o^=r[e-16];e++;r[e]=c^=r[e-16];e++}}return r}}t.AES128Cipher=p;class b extends m{constructor(e){super();this._cyclesOfRepetition=14;this._keySize=224;this._key=this._expandKey(e)}_expandKey(e){const t=this._s,a=new Uint8Array(240);a.set(e);let r,i,n,s,o=1;for(let e=32,c=1;e<240;++c){if(e%32==16){r=t[r];i=t[i];n=t[n];s=t[s]}else if(e%32==0){r=a[e-3];i=a[e-2];n=a[e-1];s=a[e-4];r=t[r];i=t[i];n=t[n];s=t[s];r^=o;(o<<=1)>=256&&(o=255&(27^o))}for(let t=0;t<4;++t){a[e]=r^=a[e-32];e++;a[e]=i^=a[e-32];e++;a[e]=n^=a[e-32];e++;a[e]=s^=a[e-32];e++}}return a}}t.AES256Cipher=b;var y=function(){function e(e,t){if(e.length!==t.length)return!1;for(var a=0;a<e.length;a++)if(e[a]!==t[a])return!1;return!0}function t(){}t.prototype={checkOwnerPassword:function(t,a,r,i){var n=new Uint8Array(t.length+56);n.set(t,0);n.set(a,t.length);n.set(r,t.length+a.length);return e(u(n,0,n.length),i)},checkUserPassword:function(t,a,r){var i=new Uint8Array(t.length+8);i.set(t,0);i.set(a,t.length);return e(u(i,0,i.length),r)},getOwnerKey:function(e,t,a,r){var i=new Uint8Array(e.length+56);i.set(e,0);i.set(t,e.length);i.set(a,e.length+t.length);var n=u(i,0,i.length);return new b(n).decryptBlock(r,!1,new Uint8Array(16))},getUserKey:function(e,t,a){var r=new Uint8Array(e.length+8);r.set(e,0);r.set(t,e.length);var i=u(r,0,r.length);return new b(i).decryptBlock(a,!1,new Uint8Array(16))}};return t}();t.PDF17=y;var v=function(){function e(e,t){var a=new Uint8Array(e.length+t.length);a.set(e,0);a.set(t,e.length);return a}function t(t,a,r){for(var i=u(a,0,a.length).subarray(0,32),n=[0],s=0;s<64||n[n.length-1]>s-32;){var o=t.length+i.length+r.length,c=new Uint8Array(64*o),l=e(t,i);l=e(l,r);for(var h=0,g=0;h<64;h++,g+=o)c.set(l,g);n=new p(i.subarray(0,16)).encrypt(c,i.subarray(16,32));for(var m=0,b=0;b<16;b++){m*=1;m%=3;m+=(n[b]>>>0)%3;m%=3}0===m?i=u(n,0,n.length):1===m?i=f(n,0,n.length):2===m&&(i=d(n,0,n.length));s++}return i.subarray(0,32)}function a(){}function r(e,t){if(e.length!==t.length)return!1;for(var a=0;a<e.length;a++)if(e[a]!==t[a])return!1;return!0}a.prototype={hash:function(e,a,r){return t(e,a,r)},checkOwnerPassword:function(e,a,i,n){var s=new Uint8Array(e.length+56);s.set(e,0);s.set(a,e.length);s.set(i,e.length+a.length);return r(t(e,s,i),n)},checkUserPassword:function(e,a,i){var n=new Uint8Array(e.length+8);n.set(e,0);n.set(a,e.length);return r(t(e,n,[]),i)},getOwnerKey:function(e,a,r,i){var n=new Uint8Array(e.length+56);n.set(e,0);n.set(a,e.length);n.set(r,e.length+a.length);var s=t(e,n,r);return new b(s).decryptBlock(i,!1,new Uint8Array(16))},getUserKey:function(e,a,r){var i=new Uint8Array(e.length+8);i.set(e,0);i.set(a,e.length);var n=t(e,i,[]);return new b(n).decryptBlock(r,!1,new Uint8Array(16))}};return a}();t.PDF20=v;var w=function(){function e(e,t){this.StringCipherConstructor=e;this.StreamCipherConstructor=t}e.prototype={createStream:function(e,t){var a=new this.StreamCipherConstructor;return new n.DecryptStream(e,t,(function(e,t){return a.decryptBlock(e,t)}))},decryptString:function(e){var t=new this.StringCipherConstructor,a=(0,r.stringToBytes)(e);a=t.decryptBlock(a,!0);return(0,r.bytesToString)(a)}};return e}(),k=function(){var e=new Uint8Array([40,191,78,94,78,117,138,65,100,0,78,86,255,250,1,8,46,46,0,182,208,104,62,128,47,12,169,254,100,83,105,122]);function t(t,a,r,i,n,o,c,h){var u,d,f=40+r.length+t.length,g=new Uint8Array(f),m=0;if(a){d=Math.min(32,a.length);for(;m<d;++m)g[m]=a[m]}u=0;for(;m<32;)g[m++]=e[u++];for(u=0,d=r.length;u<d;++u)g[m++]=r[u];g[m++]=255&n;g[m++]=n>>8&255;g[m++]=n>>16&255;g[m++]=n>>>24&255;for(u=0,d=t.length;u<d;++u)g[m++]=t[u];if(o>=4&&!h){g[m++]=255;g[m++]=255;g[m++]=255;g[m++]=255}var p=l(g,0,m),b=c>>3;if(o>=3)for(u=0;u<50;++u)p=l(p,0,b);var y,v=p.subarray(0,b);if(o>=3){for(m=0;m<32;++m)g[m]=e[m];for(u=0,d=t.length;u<d;++u)g[m++]=t[u];y=new s(v).encryptBlock(l(g,0,m));d=v.length;var w,k=new Uint8Array(d);for(u=1;u<=19;++u){for(w=0;w<d;++w)k[w]=v[w]^u;y=new s(k).encryptBlock(y)}for(u=0,d=y.length;u<d;++u)if(i[u]!==y[u])return null}else for(u=0,d=(y=new s(v).encryptBlock(e)).length;u<d;++u)if(i[u]!==y[u])return null;return v}var a=i.Name.get("Identity");function n(n,o,c){var h=n.get("Filter");if(!(0,i.isName)(h,"Standard"))throw new r.FormatError("unknown encryption method");this.dict=n;var u=n.get("V");if(!Number.isInteger(u)||1!==u&&2!==u&&4!==u&&5!==u)throw new r.FormatError("unsupported encryption algorithm");this.algorithm=u;var d=n.get("Length");if(!d)if(u<=3)d=40;else{var f=n.get("CF"),g=n.get("StmF");if((0,i.isDict)(f)&&(0,i.isName)(g)){f.suppressEncryption=!0;var m=f.get(g.name);(d=m&&m.get("Length")||128)<40&&(d<<=3)}}if(!Number.isInteger(d)||d<40||d%8!=0)throw new r.FormatError("invalid key length");var p=(0,r.stringToBytes)(n.get("O")).subarray(0,32),b=(0,r.stringToBytes)(n.get("U")).subarray(0,32),w=n.get("P"),k=n.get("R"),S=(4===u||5===u)&&!1!==n.get("EncryptMetadata");this.encryptMetadata=S;var C,x,A=(0,r.stringToBytes)(o);if(c){if(6===k)try{c=(0,r.utf8StringToString)(c)}catch(e){(0,r.warn)("CipherTransformFactory: Unable to convert UTF8 encoded password.")}C=(0,r.stringToBytes)(c)}if(5!==u)x=t(A,C,p,b,w,k,d,S);else{var I=(0,r.stringToBytes)(n.get("O")).subarray(32,40),F=(0,r.stringToBytes)(n.get("O")).subarray(40,48),T=(0,r.stringToBytes)(n.get("U")).subarray(0,48),E=(0,r.stringToBytes)(n.get("U")).subarray(32,40),O=(0,r.stringToBytes)(n.get("U")).subarray(40,48),P=(0,r.stringToBytes)(n.get("OE")),B=(0,r.stringToBytes)(n.get("UE"));(0,r.stringToBytes)(n.get("Perms"));x=function(e,t,a,r,i,n,s,o,c,l,h,u){if(t){var d=Math.min(127,t.length);t=t.subarray(0,d)}else t=[];var f;return(f=6===e?new v:new y).checkUserPassword(t,o,s)?f.getUserKey(t,c,h):t.length&&f.checkOwnerPassword(t,r,n,a)?f.getOwnerKey(t,i,n,l):null}(k,C,p,I,F,T,b,E,O,P,B)}if(!x&&!c)throw new r.PasswordException("No password given",r.PasswordResponses.NEED_PASSWORD);if(!x&&c){x=t(A,function(t,a,r,i){var n,o,c=new Uint8Array(32),h=0;o=Math.min(32,t.length);for(;h<o;++h)c[h]=t[h];n=0;for(;h<32;)c[h++]=e[n++];var u,d=l(c,0,h),f=i>>3;if(r>=3)for(n=0;n<50;++n)d=l(d,0,d.length);if(r>=3){u=a;var g,m=new Uint8Array(f);for(n=19;n>=0;n--){for(g=0;g<f;++g)m[g]=d[g]^n;u=new s(m).encryptBlock(u)}}else u=new s(d.subarray(0,f)).encryptBlock(a);return u}(C,p,k,d),p,b,w,k,d,S)}if(!x)throw new r.PasswordException("Incorrect Password",r.PasswordResponses.INCORRECT_PASSWORD);this.encryptionKey=x;if(u>=4){var D=n.get("CF");(0,i.isDict)(D)&&(D.suppressEncryption=!0);this.cf=D;this.stmf=n.get("StmF")||a;this.strf=n.get("StrF")||a;this.eff=n.get("EFF")||this.stmf}}function o(e,t,a,r){var i,n,s=new Uint8Array(a.length+9);for(i=0,n=a.length;i<n;++i)s[i]=a[i];s[i++]=255&e;s[i++]=e>>8&255;s[i++]=e>>16&255;s[i++]=255&t;s[i++]=t>>8&255;if(r){s[i++]=115;s[i++]=65;s[i++]=108;s[i++]=84}return l(s,0,i).subarray(0,Math.min(a.length+5,16))}function c(e,t,a,n,c){if(!(0,i.isName)(t))throw new r.FormatError("Invalid crypt filter name.");var l,h=e.get(t.name);null!=h&&(l=h.get("CFM"));if(!l||"None"===l.name)return function(){return new g};if("V2"===l.name)return function(){return new s(o(a,n,c,!1))};if("AESV2"===l.name)return function(){return new p(o(a,n,c,!0))};if("AESV3"===l.name)return function(){return new b(c)};throw new r.FormatError("Unknown crypto method")}n.prototype={createCipherTransform:function(e,t){if(4===this.algorithm||5===this.algorithm)return new w(c(this.cf,this.stmf,e,t,this.encryptionKey),c(this.cf,this.strf,e,t,this.encryptionKey));var a=o(e,t,this.encryptionKey,!1),r=function(){return new s(a)};return new w(r,r)}};return n}();t.CipherTransformFactory=k},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.ColorSpace=void 0;var r=a(2),i=a(4);class n{constructor(e,t){this.constructor===n&&(0,r.unreachable)("Cannot initialize ColorSpace.");this.name=e;this.numComps=t}getRgb(e,t){const a=new Uint8ClampedArray(3);this.getRgbItem(e,t,a,0);return a}getRgbItem(e,t,a,i){(0,r.unreachable)("Should not call ColorSpace.getRgbItem")}getRgbBuffer(e,t,a,i,n,s,o){(0,r.unreachable)("Should not call ColorSpace.getRgbBuffer")}getOutputLength(e,t){(0,r.unreachable)("Should not call ColorSpace.getOutputLength")}isPassthrough(e){return!1}isDefaultDecode(e,t){return n.isDefaultDecode(e,this.numComps)}fillRgb(e,t,a,r,i,n,s,o,c){const l=t*a;let h=null;const u=1<<s,d=a!==i||t!==r;if(this.isPassthrough(s))h=o;else if(1===this.numComps&&l>u&&"DeviceGray"!==this.name&&"DeviceRGB"!==this.name){const t=s<=8?new Uint8Array(u):new Uint16Array(u);for(let e=0;e<u;e++)t[e]=e;const a=new Uint8ClampedArray(3*u);this.getRgbBuffer(t,0,u,a,0,s,0);if(d){h=new Uint8Array(3*l);let e=0;for(let t=0;t<l;++t){const r=3*o[t];h[e++]=a[r];h[e++]=a[r+1];h[e++]=a[r+2]}}else{let t=0;for(let r=0;r<l;++r){const i=3*o[r];e[t++]=a[i];e[t++]=a[i+1];e[t++]=a[i+2];t+=c}}}else if(d){h=new Uint8ClampedArray(3*l);this.getRgbBuffer(o,0,l,h,0,s,0)}else this.getRgbBuffer(o,0,r*n,e,0,s,c);if(h)if(d)!function(e,t,a,r,i,n,s){s=1!==s?0:s;const o=a/i,c=r/n;let l,h=0;const u=new Uint16Array(i),d=3*a;for(let e=0;e<i;e++)u[e]=3*Math.floor(e*o);for(let a=0;a<n;a++){const r=Math.floor(a*c)*d;for(let a=0;a<i;a++){l=r+u[a];t[h++]=e[l++];t[h++]=e[l++];t[h++]=e[l++];h+=s}}}(h,e,t,a,r,i,c);else{let t=0,a=0;for(let i=0,s=r*n;i<s;i++){e[t++]=h[a++];e[t++]=h[a++];e[t++]=h[a++];t+=c}}}get usesZeroToOneRange(){return(0,r.shadow)(this,"usesZeroToOneRange",!0)}static parse(e,t,a,r){const i=this.parseToIR(e,t,a,r);return this.fromIR(i)}static fromIR(e){const t=Array.isArray(e)?e[0]:e;let a,i,n;switch(t){case"DeviceGrayCS":return this.singletons.gray;case"DeviceRgbCS":return this.singletons.rgb;case"DeviceCmykCS":return this.singletons.cmyk;case"CalGrayCS":a=e[1];i=e[2];n=e[3];return new d(a,i,n);case"CalRGBCS":a=e[1];i=e[2];n=e[3];const l=e[4];return new f(a,i,n,l);case"PatternCS":let h=e[1];h&&(h=this.fromIR(h));return new o(h);case"IndexedCS":const u=e[1],m=e[2],p=e[3];return new c(this.fromIR(u),m,p);case"AlternateCS":const b=e[1],y=e[2],v=e[3];return new s(b,this.fromIR(y),v);case"LabCS":a=e[1];i=e[2];const w=e[3];return new g(a,i,w);default:throw new r.FormatError(`Unknown colorspace name: ${t}`)}}static parseToIR(e,t,a=null,n){e=t.fetchIfRef(e);if((0,i.isName)(e))switch(e.name){case"DeviceGray":case"G":return"DeviceGrayCS";case"DeviceRGB":case"RGB":return"DeviceRgbCS";case"DeviceCMYK":case"CMYK":return"DeviceCmykCS";case"Pattern":return["PatternCS",null];default:if((0,i.isDict)(a)){const r=a.get("ColorSpace");if((0,i.isDict)(r)){const s=r.get(e.name);if(s){if((0,i.isName)(s))return this.parseToIR(s,t,a,n);e=s;break}}}throw new r.FormatError(`unrecognized colorspace ${e.name}`)}if(Array.isArray(e)){const s=t.fetchIfRef(e[0]).name;let o,c,l,h,u,d;switch(s){case"DeviceGray":case"G":return"DeviceGrayCS";case"DeviceRGB":case"RGB":return"DeviceRgbCS";case"DeviceCMYK":case"CMYK":return"DeviceCmykCS";case"CalGray":c=t.fetchIfRef(e[1]);h=c.getArray("WhitePoint");u=c.getArray("BlackPoint");d=c.get("Gamma");return["CalGrayCS",h,u,d];case"CalRGB":c=t.fetchIfRef(e[1]);h=c.getArray("WhitePoint");u=c.getArray("BlackPoint");d=c.getArray("Gamma");return["CalRGBCS",h,u,d,c.getArray("Matrix")];case"ICCBased":const f=t.fetchIfRef(e[1]).dict;o=f.get("N");l=f.get("Alternate");if(l){const e=this.parseToIR(l,t,a,n);if(this.fromIR(e,n).numComps===o)return e;(0,r.warn)("ICCBased color space: Ignoring incorrect /Alternate entry.")}if(1===o)return"DeviceGrayCS";if(3===o)return"DeviceRgbCS";if(4===o)return"DeviceCmykCS";break;case"Pattern":let g=e[1]||null;g&&(g=this.parseToIR(g,t,a,n));return["PatternCS",g];case"Indexed":case"I":const m=this.parseToIR(e[1],t,a,n),p=t.fetchIfRef(e[2])+1;let b=t.fetchIfRef(e[3]);(0,i.isStream)(b)&&(b=b.getBytes());return["IndexedCS",m,p,b];case"Separation":case"DeviceN":const y=t.fetchIfRef(e[1]);o=Array.isArray(y)?y.length:1;l=this.parseToIR(e[2],t,a,n);return["AlternateCS",o,l,n.create(t.fetchIfRef(e[3]))];case"Lab":c=t.fetchIfRef(e[1]);h=c.getArray("WhitePoint");u=c.getArray("BlackPoint");return["LabCS",h,u,c.getArray("Range")];default:throw new r.FormatError(`unimplemented color space object "${s}"`)}}throw new r.FormatError(`unrecognized color space object: "${e}"`)}static isDefaultDecode(e,t){if(!Array.isArray(e))return!0;if(2*t!==e.length){(0,r.warn)("The decode map is not the correct length");return!0}for(let t=0,a=e.length;t<a;t+=2)if(0!==e[t]||1!==e[t+1])return!1;return!0}static get singletons(){return(0,r.shadow)(this,"singletons",{get gray(){return(0,r.shadow)(this,"gray",new l)},get rgb(){return(0,r.shadow)(this,"rgb",new h)},get cmyk(){return(0,r.shadow)(this,"cmyk",new u)}})}}t.ColorSpace=n;class s extends n{constructor(e,t,a){super("Alternate",e);this.base=t;this.tintFn=a;this.tmpBuf=new Float32Array(t.numComps)}getRgbItem(e,t,a,r){const i=this.tmpBuf;this.tintFn(e,t,i,0);this.base.getRgbItem(i,0,a,r)}getRgbBuffer(e,t,a,r,i,n,s){const o=this.tintFn,c=this.base,l=1/((1<<n)-1),h=c.numComps,u=c.usesZeroToOneRange,d=(c.isPassthrough(8)||!u)&&0===s;let f=d?i:0;const g=d?r:new Uint8ClampedArray(h*a),m=this.numComps,p=new Float32Array(m),b=new Float32Array(h);let y,v;for(y=0;y<a;y++){for(v=0;v<m;v++)p[v]=e[t++]*l;o(p,0,b,0);if(u)for(v=0;v<h;v++)g[f++]=255*b[v];else{c.getRgbItem(b,0,g,f);f+=h}}d||c.getRgbBuffer(g,0,a,r,i,8,s)}getOutputLength(e,t){return this.base.getOutputLength(e*this.base.numComps/this.numComps,t)}}class o extends n{constructor(e){super("Pattern",null);this.base=e}isDefaultDecode(e,t){(0,r.unreachable)("Should not call PatternCS.isDefaultDecode")}}class c extends n{constructor(e,t,a){super("Indexed",1);this.base=e;this.highVal=t;const n=e.numComps*t;if((0,i.isStream)(a)){this.lookup=new Uint8Array(n);const e=a.getBytes(n);this.lookup.set(e)}else if((0,r.isString)(a)){this.lookup=new Uint8Array(n);for(let e=0;e<n;++e)this.lookup[e]=a.charCodeAt(e)}else{if(!(a instanceof Uint8Array))throw new r.FormatError(`Unrecognized lookup table: ${a}`);this.lookup=a}}getRgbItem(e,t,a,r){const i=this.base.numComps,n=e[t]*i;this.base.getRgbBuffer(this.lookup,n,1,a,r,8,0)}getRgbBuffer(e,t,a,r,i,n,s){const o=this.base,c=o.numComps,l=o.getOutputLength(c,s),h=this.lookup;for(let n=0;n<a;++n){const a=e[t++]*c;o.getRgbBuffer(h,a,1,r,i,8,s);i+=l}}getOutputLength(e,t){return this.base.getOutputLength(e*this.base.numComps,t)}isDefaultDecode(e,t){if(!Array.isArray(e))return!0;if(2!==e.length){(0,r.warn)("Decode map length is not correct");return!0}if(!Number.isInteger(t)||t<1){(0,r.warn)("Bits per component is not correct");return!0}return 0===e[0]&&e[1]===(1<<t)-1}}class l extends n{constructor(){super("DeviceGray",1)}getRgbItem(e,t,a,r){const i=255*e[t];a[r]=a[r+1]=a[r+2]=i}getRgbBuffer(e,t,a,r,i,n,s){const o=255/((1<<n)-1);let c=t,l=i;for(let t=0;t<a;++t){const t=o*e[c++];r[l++]=t;r[l++]=t;r[l++]=t;l+=s}}getOutputLength(e,t){return e*(3+t)}}class h extends n{constructor(){super("DeviceRGB",3)}getRgbItem(e,t,a,r){a[r]=255*e[t];a[r+1]=255*e[t+1];a[r+2]=255*e[t+2]}getRgbBuffer(e,t,a,r,i,n,s){if(8===n&&0===s){r.set(e.subarray(t,t+3*a),i);return}const o=255/((1<<n)-1);let c=t,l=i;for(let t=0;t<a;++t){r[l++]=o*e[c++];r[l++]=o*e[c++];r[l++]=o*e[c++];l+=s}}getOutputLength(e,t){return e*(3+t)/3|0}isPassthrough(e){return 8===e}}const u=function(){function e(e,t,a,r,i){const n=e[t]*a,s=e[t+1]*a,o=e[t+2]*a,c=e[t+3]*a;r[i]=255+n*(-4.387332384609988*n+54.48615194189176*s+18.82290502165302*o+212.25662451639585*c-285.2331026137004)+s*(1.7149763477362134*s-5.6096736904047315*o+-17.873870861415444*c-5.497006427196366)+o*(-2.5217340131683033*o-21.248923337353073*c+17.5119270841813)+c*(-21.86122147463605*c-189.48180835922747);r[i+1]=255+n*(8.841041422036149*n+60.118027045597366*s+6.871425592049007*o+31.159100130055922*c-79.2970844816548)+s*(-15.310361306967817*s+17.575251261109482*o+131.35250912493976*c-190.9453302588951)+o*(4.444339102852739*o+9.8632861493405*c-24.86741582555878)+c*(-20.737325471181034*c-187.80453709719578);r[i+2]=255+n*(.8842522430003296*n+8.078677503112928*s+30.89978309703729*o-.23883238689178934*c-14.183576799673286)+s*(10.49593273432072*s+63.02378494754052*o+50.606957656360734*c-112.23884253719248)+o*(.03296041114873217*o+115.60384449646641*c-193.58209356861505)+c*(-22.33816807309886*c-180.12613974708367)}return class extends n{constructor(){super("DeviceCMYK",4)}getRgbItem(t,a,r,i){e(t,a,1,r,i)}getRgbBuffer(t,a,r,i,n,s,o){const c=1/((1<<s)-1);for(let s=0;s<r;s++){e(t,a,c,i,n);a+=4;n+=3+o}}getOutputLength(e,t){return e/4*(3+t)|0}}}(),d=function(){function e(e,t,a,r,i,n){const s=(t[a]*n)**e.G,o=e.YW*s,c=Math.max(295.8*o**.3333333333333333-40.8,0);r[i]=c;r[i+1]=c;r[i+2]=c}return class extends n{constructor(e,t,a){super("CalGray",1);if(!e)throw new r.FormatError("WhitePoint missing - required for color space CalGray");t=t||[0,0,0];a=a||1;this.XW=e[0];this.YW=e[1];this.ZW=e[2];this.XB=t[0];this.YB=t[1];this.ZB=t[2];this.G=a;if(this.XW<0||this.ZW<0||1!==this.YW)throw new r.FormatError(`Invalid WhitePoint components for ${this.name}`+", no fallback available");if(this.XB<0||this.YB<0||this.ZB<0){(0,r.info)(`Invalid BlackPoint for ${this.name}, falling back to default.`);this.XB=this.YB=this.ZB=0}0===this.XB&&0===this.YB&&0===this.ZB||(0,r.warn)(`${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, `+`ZB: ${this.ZB}, only default values are supported.`);if(this.G<1){(0,r.info)(`Invalid Gamma: ${this.G} for ${this.name}, `+"falling back to default.");this.G=1}}getRgbItem(t,a,r,i){e(this,t,a,r,i,1)}getRgbBuffer(t,a,r,i,n,s,o){const c=1/((1<<s)-1);for(let s=0;s<r;++s){e(this,t,a,i,n,c);a+=1;n+=3+o}}getOutputLength(e,t){return e*(3+t)}}}(),f=function(){const e=new Float32Array([.8951,.2664,-.1614,-.7502,1.7135,.0367,.0389,-.0685,1.0296]),t=new Float32Array([.9869929,-.1470543,.1599627,.4323053,.5183603,.0492912,-.0085287,.0400428,.9684867]),a=new Float32Array([3.2404542,-1.5371385,-.4985314,-.969266,1.8760108,.041556,.0556434,-.2040259,1.0572252]),i=new Float32Array([1,1,1]),s=new Float32Array(3),o=new Float32Array(3),c=new Float32Array(3);function l(e,t,a){a[0]=e[0]*t[0]+e[1]*t[1]+e[2]*t[2];a[1]=e[3]*t[0]+e[4]*t[1]+e[5]*t[2];a[2]=e[6]*t[0]+e[7]*t[1]+e[8]*t[2]}function h(e){return u(0,1,e<=.0031308?12.92*e:1.055*e**(1/2.4)-.055)}function u(e,t,a){return Math.max(e,Math.min(t,a))}function d(e){return e<0?-d(-e):e>8?((e+16)/116)**3:e*((24/116)**3/8)}function f(r,n,f,g,m,p){const b=u(0,1,n[f]*p),y=u(0,1,n[f+1]*p),v=u(0,1,n[f+2]*p),w=b**r.GR,k=y**r.GG,S=v**r.GB,C=r.MXA*w+r.MXB*k+r.MXC*S,x=r.MYA*w+r.MYB*k+r.MYC*S,A=r.MZA*w+r.MZB*k+r.MZC*S,I=o;I[0]=C;I[1]=x;I[2]=A;const F=c;!function(a,r,i){if(1===a[0]&&1===a[2]){i[0]=r[0];i[1]=r[1];i[2]=r[2];return}const n=i;l(e,r,n);const o=s;!function(e,t,a){a[0]=1*t[0]/e[0];a[1]=1*t[1]/e[1];a[2]=1*t[2]/e[2]}(a,n,o);l(t,o,i)}(r.whitePoint,I,F);const T=o;!function(e,t,a){if(0===e[0]&&0===e[1]&&0===e[2]){a[0]=t[0];a[1]=t[1];a[2]=t[2];return}const r=d(0),i=(1-r)/(1-d(e[0])),n=1-i,s=(1-r)/(1-d(e[1])),o=1-s,c=(1-r)/(1-d(e[2])),l=1-c;a[0]=t[0]*i+n;a[1]=t[1]*s+o;a[2]=t[2]*c+l}(r.blackPoint,F,T);const E=c;!function(a,r,i){const n=i;l(e,r,n);const o=s;!function(e,t,a){a[0]=.95047*t[0]/e[0];a[1]=1*t[1]/e[1];a[2]=1.08883*t[2]/e[2]}(a,n,o);l(t,o,i)}(i,T,E);const O=o;l(a,E,O);g[m]=255*h(O[0]);g[m+1]=255*h(O[1]);g[m+2]=255*h(O[2])}return class extends n{constructor(e,t,a,i){super("CalRGB",3);if(!e)throw new r.FormatError("WhitePoint missing - required for color space CalRGB");t=t||new Float32Array(3);a=a||new Float32Array([1,1,1]);i=i||new Float32Array([1,0,0,0,1,0,0,0,1]);const n=e[0],s=e[1],o=e[2];this.whitePoint=e;const c=t[0],l=t[1],h=t[2];this.blackPoint=t;this.GR=a[0];this.GG=a[1];this.GB=a[2];this.MXA=i[0];this.MYA=i[1];this.MZA=i[2];this.MXB=i[3];this.MYB=i[4];this.MZB=i[5];this.MXC=i[6];this.MYC=i[7];this.MZC=i[8];if(n<0||o<0||1!==s)throw new r.FormatError(`Invalid WhitePoint components for ${this.name}`+", no fallback available");if(c<0||l<0||h<0){(0,r.info)(`Invalid BlackPoint for ${this.name} [${c}, ${l}, ${h}], `+"falling back to default.");this.blackPoint=new Float32Array(3)}if(this.GR<0||this.GG<0||this.GB<0){(0,r.info)(`Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for `+`${this.name}, falling back to default.`);this.GR=this.GG=this.GB=1}}getRgbItem(e,t,a,r){f(this,e,t,a,r,1)}getRgbBuffer(e,t,a,r,i,n,s){const o=1/((1<<n)-1);for(let n=0;n<a;++n){f(this,e,t,r,i,o);t+=3;i+=3+s}}getOutputLength(e,t){return e*(3+t)/3|0}}}(),g=function(){function e(e){let t;t=e>=6/29?e*e*e:108/841*(e-4/29);return t}function t(e,t,a,r){return a+e*(r-a)/t}function a(a,r,i,n,s,o){let c=r[i],l=r[i+1],h=r[i+2];if(!1!==n){c=t(c,n,0,100);l=t(l,n,a.amin,a.amax);h=t(h,n,a.bmin,a.bmax)}l>a.amax?l=a.amax:l<a.amin&&(l=a.amin);h>a.bmax?h=a.bmax:h<a.bmin&&(h=a.bmin);const u=(c+16)/116,d=u+l/500,f=u-h/200,g=a.XW*e(d),m=a.YW*e(u),p=a.ZW*e(f);let b,y,v;if(a.ZW<1){b=3.1339*g+-1.617*m+-.4906*p;y=-.9785*g+1.916*m+.0333*p;v=.072*g+-.229*m+1.4057*p}else{b=3.2406*g+-1.5372*m+-.4986*p;y=-.9689*g+1.8758*m+.0415*p;v=.0557*g+-.204*m+1.057*p}s[o]=255*Math.sqrt(b);s[o+1]=255*Math.sqrt(y);s[o+2]=255*Math.sqrt(v)}return class extends n{constructor(e,t,a){super("Lab",3);if(!e)throw new r.FormatError("WhitePoint missing - required for color space Lab");t=t||[0,0,0];a=a||[-100,100,-100,100];this.XW=e[0];this.YW=e[1];this.ZW=e[2];this.amin=a[0];this.amax=a[1];this.bmin=a[2];this.bmax=a[3];this.XB=t[0];this.YB=t[1];this.ZB=t[2];if(this.XW<0||this.ZW<0||1!==this.YW)throw new r.FormatError("Invalid WhitePoint components, no fallback available");if(this.XB<0||this.YB<0||this.ZB<0){(0,r.info)("Invalid BlackPoint, falling back to default");this.XB=this.YB=this.ZB=0}if(this.amin>this.amax||this.bmin>this.bmax){(0,r.info)("Invalid Range, falling back to defaults");this.amin=-100;this.amax=100;this.bmin=-100;this.bmax=100}}getRgbItem(e,t,r,i){a(this,e,t,!1,r,i)}getRgbBuffer(e,t,r,i,n,s,o){const c=(1<<s)-1;for(let s=0;s<r;s++){a(this,e,t,c,i,n);t+=3;n+=3+o}}getOutputLength(e,t){return e*(3+t)/3|0}isDefaultDecode(e,t){return!0}get usesZeroToOneRange(){return(0,r.shadow)(this,"usesZeroToOneRange",!1)}}}()},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getQuadPoints=h;t.MarkupAnnotation=t.AnnotationFactory=t.AnnotationBorderStyle=t.Annotation=void 0;var r=a(2),i=a(9),n=a(4),s=a(22),o=a(7),c=a(24),l=a(11);t.AnnotationFactory=class{static create(e,t,a,r){return a.ensure(this,"_create",[e,t,a,r])}static _create(e,t,a,i){const s=e.fetchIfRef(t);if(!(0,n.isDict)(s))return;const c=(0,n.isRef)(t)?t.toString():`annot_${i.createObjId()}`;let l=s.get("Subtype");l=(0,n.isName)(l)?l.name:null;const h={xref:e,dict:s,subtype:l,id:c,pdfManager:a};switch(l){case"Link":return new v(h);case"Text":return new y(h);case"Widget":let e=(0,o.getInheritableProperty)({dict:s,key:"FT"});e=(0,n.isName)(e)?e.name:null;switch(e){case"Tx":return new m(h);case"Btn":return new p(h);case"Ch":return new b(h)}(0,r.warn)('Unimplemented widget field type "'+e+'", falling back to base field type.');return new g(h);case"Popup":return new w(h);case"FreeText":return new k(h);case"Line":return new S(h);case"Square":return new C(h);case"Circle":return new x(h);case"PolyLine":return new A(h);case"Polygon":return new I(h);case"Caret":return new F(h);case"Ink":return new T(h);case"Highlight":return new E(h);case"Underline":return new O(h);case"Squiggly":return new P(h);case"StrikeOut":return new B(h);case"Stamp":return new D(h);case"FileAttachment":return new N(h);default:l?(0,r.warn)('Unimplemented annotation type "'+l+'", falling back to base annotation.'):(0,r.warn)("Annotation is missing the required /Subtype.");return new u(h)}}};function h(e,t){if(!e.has("QuadPoints"))return null;const a=e.getArray("QuadPoints");if(!Array.isArray(a)||a.length%8>0)return null;const r=[];for(let e=0,i=a.length/8;e<i;e++){r.push([]);for(let i=8*e,n=8*e+8;i<n;i+=2){const n=a[i],s=a[i+1];if(n<t[0]||n>t[2]||s<t[1]||s>t[3])return null;r[e].push({x:n,y:s})}}return r}class u{constructor(e){const t=e.dict;this.setContents(t.get("Contents"));this.setModificationDate(t.get("M"));this.setFlags(t.get("F"));this.setRectangle(t.getArray("Rect"));this.setColor(t.getArray("C"));this.setBorderStyle(t);this.setAppearance(t);this.data={annotationFlags:this.flags,borderStyle:this.borderStyle,color:this.color,contents:this.contents,hasAppearance:!!this.appearance,id:e.id,modificationDate:this.modificationDate,rect:this.rectangle,subtype:e.subtype}}_hasFlag(e,t){return!!(e&t)}_isViewable(e){return!this._hasFlag(e,r.AnnotationFlag.INVISIBLE)&&!this._hasFlag(e,r.AnnotationFlag.HIDDEN)&&!this._hasFlag(e,r.AnnotationFlag.NOVIEW)}_isPrintable(e){return this._hasFlag(e,r.AnnotationFlag.PRINT)&&!this._hasFlag(e,r.AnnotationFlag.INVISIBLE)&&!this._hasFlag(e,r.AnnotationFlag.HIDDEN)}get viewable(){return 0===this.flags||this._isViewable(this.flags)}get printable(){return 0!==this.flags&&this._isPrintable(this.flags)}setContents(e){this.contents=(0,r.stringToPDFString)(e||"")}setModificationDate(e){this.modificationDate=(0,r.isString)(e)?e:null}setFlags(e){this.flags=Number.isInteger(e)&&e>0?e:0}hasFlag(e){return this._hasFlag(this.flags,e)}setRectangle(e){Array.isArray(e)&&4===e.length?this.rectangle=r.Util.normalizeRect(e):this.rectangle=[0,0,0,0]}setColor(e){const t=new Uint8ClampedArray(3);if(Array.isArray(e))switch(e.length){case 0:this.color=null;break;case 1:s.ColorSpace.singletons.gray.getRgbItem(e,0,t,0);this.color=t;break;case 3:s.ColorSpace.singletons.rgb.getRgbItem(e,0,t,0);this.color=t;break;case 4:s.ColorSpace.singletons.cmyk.getRgbItem(e,0,t,0);this.color=t;break;default:this.color=t}else this.color=t}setBorderStyle(e){this.borderStyle=new d;if((0,n.isDict)(e))if(e.has("BS")){const t=e.get("BS"),a=t.get("Type");if(!a||(0,n.isName)(a,"Border")){this.borderStyle.setWidth(t.get("W"),this.rectangle);this.borderStyle.setStyle(t.get("S"));this.borderStyle.setDashArray(t.getArray("D"))}}else if(e.has("Border")){const t=e.getArray("Border");if(Array.isArray(t)&&t.length>=3){this.borderStyle.setHorizontalCornerRadius(t[0]);this.borderStyle.setVerticalCornerRadius(t[1]);this.borderStyle.setWidth(t[2],this.rectangle);4===t.length&&this.borderStyle.setDashArray(t[3])}}else this.borderStyle.setWidth(0)}setAppearance(e){this.appearance=null;const t=e.get("AP");if(!(0,n.isDict)(t))return;const a=t.get("N");if((0,n.isStream)(a)){this.appearance=a;return}if(!(0,n.isDict)(a))return;const r=e.get("AS");(0,n.isName)(r)&&a.has(r.name)&&(this.appearance=a.get(r.name))}loadResources(e){return this.appearance.dict.getAsync("Resources").then(t=>{if(!t)return;return new i.ObjectLoader(t,e,t.xref).load().then((function(){return t}))})}getOperatorList(e,t,a){if(!this.appearance)return Promise.resolve(new c.OperatorList);const i=this.data,n=this.appearance.dict,s=this.loadResources(["ExtGState","ColorSpace","Pattern","Shading","XObject","Font"]),o=n.getArray("BBox")||[0,0,1,1],l=n.getArray("Matrix")||[1,0,0,1,0,0],h=function(e,t,a){const[i,n,s,o]=r.Util.getAxialAlignedBoundingBox(t,a);if(i===s||n===o)return[1,0,0,1,e[0],e[1]];const c=(e[2]-e[0])/(s-i),l=(e[3]-e[1])/(o-n);return[c,0,0,l,e[0]-i*c,e[1]-n*l]}(i.rect,o,l);return s.then(a=>{const n=new c.OperatorList;n.addOp(r.OPS.beginAnnotation,[i.rect,h,l]);return e.getOperatorList({stream:this.appearance,task:t,resources:a,operatorList:n}).then(()=>{n.addOp(r.OPS.endAnnotation,[]);this.appearance.reset();return n})})}}t.Annotation=u;class d{constructor(){this.width=1;this.style=r.AnnotationBorderStyleType.SOLID;this.dashArray=[3];this.horizontalCornerRadius=0;this.verticalCornerRadius=0}setWidth(e,t=[0,0,0,0]){if((0,n.isName)(e))this.width=0;else if(Number.isInteger(e)){if(e>0){const a=(t[2]-t[0])/2,i=(t[3]-t[1])/2;if(a>0&&i>0&&(e>a||e>i)){(0,r.warn)(`AnnotationBorderStyle.setWidth - ignoring width: ${e}`);e=1}}this.width=e}}setStyle(e){if((0,n.isName)(e))switch(e.name){case"S":this.style=r.AnnotationBorderStyleType.SOLID;break;case"D":this.style=r.AnnotationBorderStyleType.DASHED;break;case"B":this.style=r.AnnotationBorderStyleType.BEVELED;break;case"I":this.style=r.AnnotationBorderStyleType.INSET;break;case"U":this.style=r.AnnotationBorderStyleType.UNDERLINE}}setDashArray(e){if(Array.isArray(e)&&e.length>0){let t=!0,a=!0;for(const r of e){if(!(+r>=0)){t=!1;break}r>0&&(a=!1)}t&&!a?this.dashArray=e:this.width=0}else e&&(this.width=0)}setHorizontalCornerRadius(e){Number.isInteger(e)&&(this.horizontalCornerRadius=e)}setVerticalCornerRadius(e){Number.isInteger(e)&&(this.verticalCornerRadius=e)}}t.AnnotationBorderStyle=d;class f extends u{constructor(e){super(e);const t=e.dict;if(t.has("IRT")){const e=t.getRaw("IRT");this.data.inReplyTo=(0,n.isRef)(e)?e.toString():null;const a=t.get("RT");this.data.replyType=(0,n.isName)(a)?a.name:r.AnnotationReplyType.REPLY}if(this.data.replyType===r.AnnotationReplyType.GROUP){const e=t.get("IRT");this.data.title=(0,r.stringToPDFString)(e.get("T")||"");this.setContents(e.get("Contents"));this.data.contents=this.contents;if(e.has("CreationDate")){this.setCreationDate(e.get("CreationDate"));this.data.creationDate=this.creationDate}else this.data.creationDate=null;if(e.has("M")){this.setModificationDate(e.get("M"));this.data.modificationDate=this.modificationDate}else this.data.modificationDate=null;this.data.hasPopup=e.has("Popup");if(e.has("C")){this.setColor(e.getArray("C"));this.data.color=this.color}else this.data.color=null}else{this.data.title=(0,r.stringToPDFString)(t.get("T")||"");this.setCreationDate(t.get("CreationDate"));this.data.creationDate=this.creationDate;this.data.hasPopup=t.has("Popup");t.has("C")||(this.data.color=null)}}setCreationDate(e){this.creationDate=(0,r.isString)(e)?e:null}}t.MarkupAnnotation=f;class g extends u{constructor(e){super(e);const t=e.dict,a=this.data;a.annotationType=r.AnnotationType.WIDGET;a.fieldName=this._constructFieldName(t);a.fieldValue=(0,o.getInheritableProperty)({dict:t,key:"V",getArray:!0});a.alternativeText=(0,r.stringToPDFString)(t.get("TU")||"");a.defaultAppearance=(0,o.getInheritableProperty)({dict:t,key:"DA"})||"";const i=(0,o.getInheritableProperty)({dict:t,key:"FT"});a.fieldType=(0,n.isName)(i)?i.name:null;this.fieldResources=(0,o.getInheritableProperty)({dict:t,key:"DR"})||n.Dict.empty;a.fieldFlags=(0,o.getInheritableProperty)({dict:t,key:"Ff"});(!Number.isInteger(a.fieldFlags)||a.fieldFlags<0)&&(a.fieldFlags=0);a.readOnly=this.hasFieldFlag(r.AnnotationFieldFlag.READONLY);if("Sig"===a.fieldType){a.fieldValue=null;this.setFlags(r.AnnotationFlag.HIDDEN)}}_constructFieldName(e){if(!e.has("T")&&!e.has("Parent")){(0,r.warn)("Unknown field name, falling back to empty field name.");return""}if(!e.has("Parent"))return(0,r.stringToPDFString)(e.get("T"));const t=[];e.has("T")&&t.unshift((0,r.stringToPDFString)(e.get("T")));let a=e;for(;a.has("Parent");){a=a.get("Parent");if(!(0,n.isDict)(a))break;a.has("T")&&t.unshift((0,r.stringToPDFString)(a.get("T")))}return t.join(".")}hasFieldFlag(e){return!!(this.data.fieldFlags&e)}getOperatorList(e,t,a){return a?Promise.resolve(new c.OperatorList):super.getOperatorList(e,t,a)}}class m extends g{constructor(e){super(e);const t=e.dict;this.data.fieldValue=(0,r.stringToPDFString)(this.data.fieldValue||"");let a=(0,o.getInheritableProperty)({dict:t,key:"Q"});(!Number.isInteger(a)||a<0||a>2)&&(a=null);this.data.textAlignment=a;let i=(0,o.getInheritableProperty)({dict:t,key:"MaxLen"});(!Number.isInteger(i)||i<0)&&(i=null);this.data.maxLen=i;this.data.multiLine=this.hasFieldFlag(r.AnnotationFieldFlag.MULTILINE);this.data.comb=this.hasFieldFlag(r.AnnotationFieldFlag.COMB)&&!this.hasFieldFlag(r.AnnotationFieldFlag.MULTILINE)&&!this.hasFieldFlag(r.AnnotationFieldFlag.PASSWORD)&&!this.hasFieldFlag(r.AnnotationFieldFlag.FILESELECT)&&null!==this.data.maxLen}getOperatorList(e,t,a){if(a||this.appearance)return super.getOperatorList(e,t,a);const i=new c.OperatorList;if(!this.data.defaultAppearance)return Promise.resolve(i);const n=new l.Stream((0,r.stringToBytes)(this.data.defaultAppearance));return e.getOperatorList({stream:n,task:t,resources:this.fieldResources,operatorList:i}).then((function(){return i}))}}class p extends g{constructor(e){super(e);this.data.checkBox=!this.hasFieldFlag(r.AnnotationFieldFlag.RADIO)&&!this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON);this.data.radioButton=this.hasFieldFlag(r.AnnotationFieldFlag.RADIO)&&!this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON);this.data.pushButton=this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON);this.data.checkBox?this._processCheckBox(e):this.data.radioButton?this._processRadioButton(e):this.data.pushButton?this._processPushButton(e):(0,r.warn)("Invalid field flags for button widget annotation")}_processCheckBox(e){(0,n.isName)(this.data.fieldValue)&&(this.data.fieldValue=this.data.fieldValue.name);const t=e.dict.get("AP");if(!(0,n.isDict)(t))return;const a=t.get("D");if(!(0,n.isDict)(a))return;const r=a.getKeys();2===r.length&&(this.data.exportValue="Off"===r[0]?r[1]:r[0])}_processRadioButton(e){this.data.fieldValue=this.data.buttonValue=null;const t=e.dict.get("Parent");if((0,n.isDict)(t)&&t.has("V")){const e=t.get("V");(0,n.isName)(e)&&(this.data.fieldValue=e.name)}const a=e.dict.get("AP");if(!(0,n.isDict)(a))return;const r=a.get("N");if((0,n.isDict)(r))for(const e of r.getKeys())if("Off"!==e){this.data.buttonValue=e;break}}_processPushButton(e){e.dict.has("A")?i.Catalog.parseDestDictionary({destDict:e.dict,resultObj:this.data,docBaseUrl:e.pdfManager.docBaseUrl}):(0,r.warn)("Push buttons without action dictionaries are not supported")}}class b extends g{constructor(e){super(e);this.data.options=[];const t=(0,o.getInheritableProperty)({dict:e.dict,key:"Opt"});if(Array.isArray(t)){const a=e.xref;for(let e=0,i=t.length;e<i;e++){const i=a.fetchIfRef(t[e]),n=Array.isArray(i);this.data.options[e]={exportValue:n?a.fetchIfRef(i[0]):i,displayValue:(0,r.stringToPDFString)(n?a.fetchIfRef(i[1]):i)}}}Array.isArray(this.data.fieldValue)||(this.data.fieldValue=[this.data.fieldValue]);this.data.combo=this.hasFieldFlag(r.AnnotationFieldFlag.COMBO);this.data.multiSelect=this.hasFieldFlag(r.AnnotationFieldFlag.MULTISELECT)}}class y extends f{constructor(e){super(e);const t=e.dict;this.data.annotationType=r.AnnotationType.TEXT;if(this.data.hasAppearance)this.data.name="NoIcon";else{this.data.rect[1]=this.data.rect[3]-22;this.data.rect[2]=this.data.rect[0]+22;this.data.name=t.has("Name")?t.get("Name").name:"Note"}if(t.has("State")){this.data.state=t.get("State")||null;this.data.stateModel=t.get("StateModel")||null}else{this.data.state=null;this.data.stateModel=null}}}class v extends u{constructor(e){super(e);this.data.annotationType=r.AnnotationType.LINK;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t);i.Catalog.parseDestDictionary({destDict:e.dict,resultObj:this.data,docBaseUrl:e.pdfManager.docBaseUrl})}}class w extends u{constructor(e){super(e);this.data.annotationType=r.AnnotationType.POPUP;let t=e.dict.get("Parent");if(!t){(0,r.warn)("Popup annotation has a missing or invalid parent annotation.");return}const a=t.get("Subtype");this.data.parentType=(0,n.isName)(a)?a.name:null;const i=e.dict.getRaw("Parent");this.data.parentId=(0,n.isRef)(i)?i.toString():null;const s=t.get("RT");(0,n.isName)(s,r.AnnotationReplyType.GROUP)&&(t=t.get("IRT"));if(t.has("M")){this.setModificationDate(t.get("M"));this.data.modificationDate=this.modificationDate}else this.data.modificationDate=null;if(t.has("C")){this.setColor(t.getArray("C"));this.data.color=this.color}else this.data.color=null;if(!this.viewable){const e=t.get("F");this._isViewable(e)&&this.setFlags(e)}this.data.title=(0,r.stringToPDFString)(t.get("T")||"");this.data.contents=(0,r.stringToPDFString)(t.get("Contents")||"")}}class k extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.FREETEXT}}class S extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.LINE;this.data.lineCoordinates=r.Util.normalizeRect(e.dict.getArray("L"))}}class C extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.SQUARE}}class x extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.CIRCLE}}class A extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.POLYLINE;const t=e.dict.getArray("Vertices");this.data.vertices=[];for(let e=0,a=t.length;e<a;e+=2)this.data.vertices.push({x:t[e],y:t[e+1]})}}class I extends A{constructor(e){super(e);this.data.annotationType=r.AnnotationType.POLYGON}}class F extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.CARET}}class T extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.INK;const t=e.xref,a=e.dict.getArray("InkList");this.data.inkLists=[];for(let e=0,r=a.length;e<r;++e){this.data.inkLists.push([]);for(let r=0,i=a[e].length;r<i;r+=2)this.data.inkLists[e].push({x:t.fetchIfRef(a[e][r]),y:t.fetchIfRef(a[e][r+1])})}}}class E extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.HIGHLIGHT;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t)}}class O extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.UNDERLINE;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t)}}class P extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.SQUIGGLY;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t)}}class B extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.STRIKEOUT;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t)}}class D extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.STAMP}}class N extends f{constructor(e){super(e);const t=new i.FileSpec(e.dict.get("FS"),e.xref);this.data.annotationType=r.AnnotationType.FILEATTACHMENT;this.data.file=t.serializable}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.OperatorList=void 0;var r=a(2),i=function(){function e(e,t,a,r,i){for(var n=e,s=0,o=t.length-1;s<o;s++){var c=t[s];n=n[c]||(n[c]=[])}n[t[t.length-1]]={checkFn:a,iterateFn:r,processFn:i}}var t=[];e(t,[r.OPS.save,r.OPS.transform,r.OPS.paintInlineImageXObject,r.OPS.restore],null,(function(e,t){var a=e.fnArray,i=(t-(e.iCurr-3))%4;switch(i){case 0:return a[t]===r.OPS.save;case 1:return a[t]===r.OPS.transform;case 2:return a[t]===r.OPS.paintInlineImageXObject;case 3:return a[t]===r.OPS.restore}throw new Error(`iterateInlineImageGroup - invalid pos: ${i}`)}),(function(e,t){var a=e.fnArray,i=e.argsArray,n=e.iCurr,s=n-3,o=n-2,c=n-1,l=Math.min(Math.floor((t-s)/4),200);if(l<10)return t-(t-s)%4;var h,u=0,d=[],f=0,g=1,m=1;for(h=0;h<l;h++){var p=i[o+(h<<2)],b=i[c+(h<<2)][0];if(g+b.width>1e3){u=Math.max(u,g);m+=f+2;g=0;f=0}d.push({transform:p,x:g,y:m,w:b.width,h:b.height});g+=b.width+2;f=Math.max(f,b.height)}var y=Math.max(u,g)+1,v=m+f+1,w=new Uint8ClampedArray(y*v*4),k=y<<2;for(h=0;h<l;h++){var S=i[c+(h<<2)][0].data,C=d[h].w<<2,x=0,A=d[h].x+d[h].y*y<<2;w.set(S.subarray(0,C),A-k);for(var I=0,F=d[h].h;I<F;I++){w.set(S.subarray(x,x+C),A);x+=C;A+=k}w.set(S.subarray(x-C,x),A);for(;A>=0;){S[A-4]=S[A];S[A-3]=S[A+1];S[A-2]=S[A+2];S[A-1]=S[A+3];S[A+C]=S[A+C-4];S[A+C+1]=S[A+C-3];S[A+C+2]=S[A+C-2];S[A+C+3]=S[A+C-1];A-=k}}a.splice(s,4*l,r.OPS.paintInlineImageXObjectGroup);i.splice(s,4*l,[{width:y,height:v,kind:r.ImageKind.RGBA_32BPP,data:w},d]);return s+1}));e(t,[r.OPS.save,r.OPS.transform,r.OPS.paintImageMaskXObject,r.OPS.restore],null,(function(e,t){var a=e.fnArray,i=(t-(e.iCurr-3))%4;switch(i){case 0:return a[t]===r.OPS.save;case 1:return a[t]===r.OPS.transform;case 2:return a[t]===r.OPS.paintImageMaskXObject;case 3:return a[t]===r.OPS.restore}throw new Error(`iterateImageMaskGroup - invalid pos: ${i}`)}),(function(e,t){var a,i=e.fnArray,n=e.argsArray,s=e.iCurr,o=s-3,c=s-2,l=s-1,h=Math.floor((t-o)/4);if((h=function(e,t,a,i){for(var n=e+2,s=0;s<t;s++){var o=i[n+4*s],c=1===o.length&&o[0];if(!c||1!==c.width||1!==c.height||c.data.length&&(1!==c.data.length||0!==c.data[0]))break;a[n+4*s]=r.OPS.paintSolidColorImageMask}return t-s}(o,h,i,n))<10)return t-(t-o)%4;var u,d,f=!1,g=n[l][0];if(0===n[c][1]&&0===n[c][2]){f=!0;var m=n[c][0],p=n[c][3];u=c+4;var b=l+4;for(a=1;a<h;a++,u+=4,b+=4){d=n[u];if(n[b][0]!==g||d[0]!==m||0!==d[1]||0!==d[2]||d[3]!==p){a<10?f=!1:h=a;break}}}if(f){h=Math.min(h,1e3);var y=new Float32Array(2*h);u=c;for(a=0;a<h;a++,u+=4){d=n[u];y[a<<1]=d[4];y[1+(a<<1)]=d[5]}i.splice(o,4*h,r.OPS.paintImageMaskXObjectRepeat);n.splice(o,4*h,[g,m,p,y])}else{h=Math.min(h,100);var v=[];for(a=0;a<h;a++){d=n[c+(a<<2)];var w=n[l+(a<<2)][0];v.push({data:w.data,width:w.width,height:w.height,transform:d})}i.splice(o,4*h,r.OPS.paintImageMaskXObjectGroup);n.splice(o,4*h,[v])}return o+1}));e(t,[r.OPS.save,r.OPS.transform,r.OPS.paintImageXObject,r.OPS.restore],(function(e){var t=e.argsArray,a=e.iCurr-2;return 0===t[a][1]&&0===t[a][2]}),(function(e,t){var a=e.fnArray,i=e.argsArray,n=(t-(e.iCurr-3))%4;switch(n){case 0:return a[t]===r.OPS.save;case 1:if(a[t]!==r.OPS.transform)return!1;var s=e.iCurr-2,o=i[s][0],c=i[s][3];return i[t][0]===o&&0===i[t][1]&&0===i[t][2]&&i[t][3]===c;case 2:if(a[t]!==r.OPS.paintImageXObject)return!1;var l=i[e.iCurr-1][0];return i[t][0]===l;case 3:return a[t]===r.OPS.restore}throw new Error(`iterateImageGroup - invalid pos: ${n}`)}),(function(e,t){var a=e.fnArray,i=e.argsArray,n=e.iCurr,s=n-3,o=n-2,c=i[n-1][0],l=i[o][0],h=i[o][3],u=Math.min(Math.floor((t-s)/4),1e3);if(u<3)return t-(t-s)%4;for(var d=new Float32Array(2*u),f=o,g=0;g<u;g++,f+=4){var m=i[f];d[g<<1]=m[4];d[1+(g<<1)]=m[5]}var p=[c,l,h,d];a.splice(s,4*u,r.OPS.paintImageXObjectRepeat);i.splice(s,4*u,p);return s+1}));e(t,[r.OPS.beginText,r.OPS.setFont,r.OPS.setTextMatrix,r.OPS.showText,r.OPS.endText],null,(function(e,t){var a=e.fnArray,i=e.argsArray,n=(t-(e.iCurr-4))%5;switch(n){case 0:return a[t]===r.OPS.beginText;case 1:return a[t]===r.OPS.setFont;case 2:return a[t]===r.OPS.setTextMatrix;case 3:if(a[t]!==r.OPS.showText)return!1;var s=e.iCurr-3,o=i[s][0],c=i[s][1];return i[t][0]===o&&i[t][1]===c;case 4:return a[t]===r.OPS.endText}throw new Error(`iterateShowTextGroup - invalid pos: ${n}`)}),(function(e,t){var a=e.fnArray,r=e.argsArray,i=e.iCurr,n=i-4,s=i-3,o=i-2,c=i-1,l=i,h=r[s][0],u=r[s][1],d=Math.min(Math.floor((t-n)/5),1e3);if(d<3)return t-(t-n)%5;var f=n;if(n>=4&&a[n-4]===a[s]&&a[n-3]===a[o]&&a[n-2]===a[c]&&a[n-1]===a[l]&&r[n-4][0]===h&&r[n-4][1]===u){d++;f-=5}for(var g=f+4,m=1;m<d;m++){a.splice(g,3);r.splice(g,3);g+=2}return g+1}));function a(e){this.queue=e;this.state=null;this.context={iCurr:0,fnArray:e.fnArray,argsArray:e.argsArray};this.match=null;this.lastProcessed=0}a.prototype={_optimize(){const e=this.queue.fnArray;let a=this.lastProcessed,r=e.length,i=this.state,n=this.match;if(!i&&!n&&a+1===r&&!t[e[a]]){this.lastProcessed=r;return}const s=this.context;for(;a<r;){if(n){if((0,n.iterateFn)(s,a)){a++;continue}a=(0,n.processFn)(s,a+1);r=e.length;n=null;i=null;if(a>=r)break}i=(i||t)[e[a]];if(i&&!Array.isArray(i)){s.iCurr=a;a++;if(!i.checkFn||(0,i.checkFn)(s)){n=i;i=null}else i=null}else a++}this.state=i;this.match=n;this.lastProcessed=a},push(e,t){this.queue.fnArray.push(e);this.queue.argsArray.push(t);this._optimize()},flush(){for(;this.match;){const e=this.queue.fnArray.length;this.lastProcessed=(0,this.match.processFn)(this.context,e);this.match=null;this.state=null;this._optimize()}},reset(){this.state=null;this.match=null;this.lastProcessed=0}};return a}(),n=function(){function e(e){this.queue=e}e.prototype={push(e,t){this.queue.fnArray.push(e);this.queue.argsArray.push(t)},flush(){},reset(){}};return e}(),s=function(){function e(e,t,a){this._streamSink=t;this.fnArray=[];this.argsArray=[];this.optimizer=t&&"oplist"!==e?new i(this):new n(this);this.dependencies=Object.create(null);this._totalLength=0;this.pageIndex=a;this.intent=e;this.weight=0;this._resolved=t?null:Promise.resolve()}e.prototype={get length(){return this.argsArray.length},get ready(){return this._resolved||this._streamSink.ready},get totalLength(){return this._totalLength+this.length},addOp(e,t){this.optimizer.push(e,t);this.weight++;this._streamSink&&(this.weight>=1e3||this.weight>=995&&(e===r.OPS.restore||e===r.OPS.endText))&&this.flush()},addDependency(e){if(!(e in this.dependencies)){this.dependencies[e]=!0;this.addOp(r.OPS.dependency,[e])}},addDependencies(e){for(var t in e)this.addDependency(t)},addOpList(e){Object.assign(this.dependencies,e.dependencies);for(var t=0,a=e.length;t<a;t++)this.addOp(e.fnArray[t],e.argsArray[t])},getIR(){return{fnArray:this.fnArray,argsArray:this.argsArray,length:this.length}},get _transfers(){const e=[],{fnArray:t,argsArray:a,length:i}=this;for(let n=0;n<i;n++)switch(t[n]){case r.OPS.paintInlineImageXObject:case r.OPS.paintInlineImageXObjectGroup:case r.OPS.paintImageMaskXObject:const t=a[n][0];t.cached||e.push(t.data.buffer)}return e},flush(e=!1){this.optimizer.flush();const t=this.length;this._totalLength+=t;this._streamSink.enqueue({fnArray:this.fnArray,argsArray:this.argsArray,lastChunk:e,length:t},1,this._transfers);this.dependencies=Object.create(null);this.fnArray.length=0;this.argsArray.length=0;this.weight=0;this.optimizer.reset()}};return e}();t.OperatorList=s},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PartialEvaluator=void 0;var r=a(2),i=a(26),n=a(4),s=a(27),o=a(30),c=a(7),l=a(33),h=a(32),u=a(36),d=a(10),f=a(37),g=a(22),m=a(11),p=a(31),b=a(38),y=a(39),v=a(17),w=a(41),k=a(42),S=a(24),C=a(43),x=function(){const e={forceDataSchema:!1,maxImageSize:-1,disableFontFace:!1,nativeImageDecoderSupport:r.NativeImageDecoding.DECODE,ignoreErrors:!1,isEvalSupported:!0};function t({xref:t,handler:a,pageIndex:i,idFactory:n,fontCache:s,builtInCMapCache:o,options:c=null,pdfFunctionFactory:l}){this.xref=t;this.handler=a;this.pageIndex=i;this.idFactory=n;this.fontCache=s;this.builtInCMapCache=o;this.options=c||e;this.pdfFunctionFactory=l;this.parsingType3Font=!1;this.fetchBuiltInCMap=async e=>{if(this.builtInCMapCache.has(e))return this.builtInCMapCache.get(e);const t=this.handler.sendWithStream("FetchBuiltInCMap",{name:e}).getReader(),a=await new Promise((function(e,a){!function r(){t.read().then((function({value:t,done:a}){if(!a){e(t);r()}}),a)}()}));a.compressionType!==r.CMapCompressionType.NONE&&this.builtInCMapCache.set(e,a);return a}}function a(){this.reset()}a.prototype={check:function(){if(++this.checked<100)return!1;this.checked=0;return this.endTime<=Date.now()},reset:function(){this.endTime=Date.now()+20;this.checked=0}};function d(e,t=!1){if(Array.isArray(e)){for(let t=0,a=e.length;t<a;t++){const a=d(e[t],!0);if(a)return a}(0,r.warn)(`Unsupported blend mode Array: ${e}`);return"source-over"}if(!(0,n.isName)(e))return t?null:"source-over";switch(e.name){case"Normal":case"Compatible":return"source-over";case"Multiply":return"multiply";case"Screen":return"screen";case"Overlay":return"overlay";case"Darken":return"darken";case"Lighten":return"lighten";case"ColorDodge":return"color-dodge";case"ColorBurn":return"color-burn";case"HardLight":return"hard-light";case"SoftLight":return"soft-light";case"Difference":return"difference";case"Exclusion":return"exclusion";case"Hue":return"hue";case"Saturation":return"saturation";case"Color":return"color";case"Luminosity":return"luminosity"}if(t)return null;(0,r.warn)(`Unsupported blend mode: ${e.name}`);return"source-over"}var x=Promise.resolve();t.prototype={clone(t=e){var a=Object.create(this);a.options=t;return a},hasBlendModes:function(e){if(!(e instanceof n.Dict))return!1;var t=Object.create(null);e.objId&&(t[e.objId]=!0);for(var a=[e],i=this.xref;a.length;){var s=a.shift(),o=s.get("ExtGState");if(o instanceof n.Dict){var l=o.getKeys();for(let e=0,a=l.length;e<a;e++){const a=l[e];let s=o.getRaw(a);if(s instanceof n.Ref){if(t[s.toString()])continue;try{s=i.fetch(s)}catch(e){if(e instanceof c.MissingDataException)throw e;if(this.options.ignoreErrors){s instanceof n.Ref&&(t[s.toString()]=!0);this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`hasBlendModes - ignoring ExtGState: "${e}".`);continue}throw e}}if(!(s instanceof n.Dict))continue;s.objId&&(t[s.objId]=!0);const h=s.get("BM");if(h instanceof n.Name){if("Normal"!==h.name)return!0}else if(void 0!==h&&Array.isArray(h))for(let e=0,t=h.length;e<t;e++)if(h[e]instanceof n.Name&&"Normal"!==h[e].name)return!0}}var h=s.get("XObject");if(h instanceof n.Dict){var u=h.getKeys();for(let e=0,s=u.length;e<s;e++){const s=u[e];var d=h.getRaw(s);if(d instanceof n.Ref){if(t[d.toString()])continue;try{d=i.fetch(d)}catch(e){if(e instanceof c.MissingDataException)throw e;if(this.options.ignoreErrors){d instanceof n.Ref&&(t[d.toString()]=!0);this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`hasBlendModes - ignoring XObject: "${e}".`);continue}throw e}}if((0,n.isStream)(d)){if(d.dict.objId){if(t[d.dict.objId])continue;t[d.dict.objId]=!0}var f=d.dict.get("Resources");if(f instanceof n.Dict&&(!f.objId||!t[f.objId])){a.push(f);f.objId&&(t[f.objId]=!0)}}}}}return!1},async buildFormXObject(e,t,a,i,s,o){var c=t.dict,l=c.getArray("Matrix"),h=c.getArray("BBox");h=Array.isArray(h)&&4===h.length?r.Util.normalizeRect(h):null;var u=c.get("Group");if(u){var d={matrix:l,bbox:h,smask:a,isolated:!1,knockout:!1},f=u.get("S"),m=null;if((0,n.isName)(f,"Transparency")){d.isolated=u.get("I")||!1;d.knockout=u.get("K")||!1;u.has("CS")&&(m=await this.parseColorSpace({cs:u.get("CS"),resources:e}))}if(a&&a.backdrop){m=m||g.ColorSpace.singletons.rgb;a.backdrop=m.getRgb(a.backdrop,0)}i.addOp(r.OPS.beginGroup,[d])}i.addOp(r.OPS.paintFormXObjectBegin,[l,h]);return this.getOperatorList({stream:t,task:s,resources:c.get("Resources")||e,operatorList:i,initialState:o}).then((function(){i.addOp(r.OPS.paintFormXObjectEnd,[]);u&&i.addOp(r.OPS.endGroup,[d])}))},async buildPaintImageXObject({resources:e,image:t,isInline:a=!1,operatorList:i,cacheKey:n,imageCache:s,forceDisableNativeImageDecoder:o=!1}){var c=t.dict,l=c.get("Width","W"),h=c.get("Height","H");if(!(l&&(0,r.isNum)(l)&&h&&(0,r.isNum)(h))){(0,r.warn)("Image dimensions are missing, or not numbers.");return}var u,d,f=this.options.maxImageSize;if(-1!==f&&l*h>f){(0,r.warn)("Image exceeded maximum allowed size and was removed.");return}if(c.get("ImageMask","IM")||!1){var g=c.get("Width","W"),p=c.get("Height","H"),b=g+7>>3,y=t.getBytes(b*p,!0),w=c.getArray("Decode","D");(u=C.PDFImage.createMask({imgArray:y,width:g,height:p,imageIsFromDecodeStream:t instanceof m.DecodeStream,inverseDecode:!!w&&w[0]>0})).cached=!!n;d=[u];i.addOp(r.OPS.paintImageMaskXObject,d);n&&(s[n]={fn:r.OPS.paintImageMaskXObject,args:d});return}var S=c.get("SMask","SM")||!1,x=c.get("Mask")||!1;if(a&&!S&&!x&&!(t instanceof v.JpegStream)&&l+h<200){u=new C.PDFImage({xref:this.xref,res:e,image:t,isInline:a,pdfFunctionFactory:this.pdfFunctionFactory}).createImageData(!0);i.addOp(r.OPS.paintInlineImageXObject,[u]);return}const A=o?r.NativeImageDecoding.NONE:this.options.nativeImageDecoderSupport;let I=`img_${this.idFactory.createObjId()}`;if(this.parsingType3Font){(0,r.assert)(A===r.NativeImageDecoding.NONE,"Type3 image resources should be completely decoded in the worker.");I=`${this.idFactory.getDocId()}_type3res_${I}`}if(A!==r.NativeImageDecoding.NONE&&!S&&!x&&t instanceof v.JpegStream&&k.NativeImageDecoder.isSupported(t,this.xref,e,this.pdfFunctionFactory)&&t.maybeValidDimensions)return this.handler.sendWithPromise("obj",[I,this.pageIndex,"JpegStream",t.getIR(this.options.forceDataSchema)]).then((function(){i.addDependency(I);d=[I,l,h];i.addOp(r.OPS.paintJpegXObject,d);n&&(s[n]={fn:r.OPS.paintJpegXObject,args:d})}),o=>{(0,r.warn)("Native JPEG decoding failed -- trying to recover: "+(o&&o.message));return this.buildPaintImageXObject({resources:e,image:t,isInline:a,operatorList:i,cacheKey:n,imageCache:s,forceDisableNativeImageDecoder:!0})});var F=null;A===r.NativeImageDecoding.DECODE&&(t instanceof v.JpegStream||x instanceof v.JpegStream||S instanceof v.JpegStream)&&(F=new k.NativeImageDecoder({xref:this.xref,resources:e,handler:this.handler,forceDataSchema:this.options.forceDataSchema,pdfFunctionFactory:this.pdfFunctionFactory}));i.addDependency(I);d=[I,l,h];const T=C.PDFImage.buildImage({handler:this.handler,xref:this.xref,res:e,image:t,isInline:a,nativeDecoder:F,pdfFunctionFactory:this.pdfFunctionFactory}).then(e=>{var t=e.createImageData(!1);if(this.parsingType3Font)return this.handler.sendWithPromise("commonobj",[I,"FontType3Res",t],[t.data.buffer]);this.handler.send("obj",[I,this.pageIndex,"Image",t],[t.data.buffer])}).catch(e=>{(0,r.warn)("Unable to decode image: "+e);if(this.parsingType3Font)return this.handler.sendWithPromise("commonobj",[I,"FontType3Res",null]);this.handler.send("obj",[I,this.pageIndex,"Image",null])});this.parsingType3Font&&await T;i.addOp(r.OPS.paintImageXObject,d);n&&(s[n]={fn:r.OPS.paintImageXObject,args:d})},handleSMask:function(e,t,a,r,i){var n=e.get("G"),s={subtype:e.get("S").name,backdrop:e.get("BC")},o=e.get("TR");if((0,y.isPDFFunction)(o)){const e=this.pdfFunctionFactory.create(o);for(var c=new Uint8Array(256),l=new Float32Array(1),h=0;h<256;h++){l[0]=h/255;e(l,0,l,0);c[h]=255*l[0]|0}s.transferMap=c}return this.buildFormXObject(t,n,s,a,r,i.state.clone())},handleTilingType(e,t,a,i,s,o,c){const l=new S.OperatorList,h=[s.get("Resources"),a],d=n.Dict.merge(this.xref,h);return this.getOperatorList({stream:i,task:c,resources:d,operatorList:l}).then((function(){return(0,u.getTilingPatternIR)({fnArray:l.fnArray,argsArray:l.argsArray},s,t)})).then((function(t){o.addDependencies(l.dependencies);o.addOp(e,t)}),e=>{if(!(e instanceof r.AbortException)){if(!this.options.ignoreErrors)throw e;this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`handleTilingType - ignoring pattern: "${e}".`)}})},handleSetFont:function(e,t,a,i,n,o){var c;t&&(c=(t=t.slice())[0].name);return this.loadFont(c,a,e).then(t=>t.font.isType3Font?t.loadType3Data(this,e,i,n).then((function(){return t})).catch(e=>{this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});return new A("g_font_error",new s.ErrorFont("Type3 font load error: "+e),t.font)}):t).then(e=>{o.font=e.font;e.send(this.handler);return e.loadedName})},handleText(e,a){const i=a.font,n=i.charsToGlyphs(e);if(i.data){(!!(a.textRenderingMode&r.TextRenderingMode.ADD_TO_PATH_FLAG)||"Pattern"===a.fillColorSpace.name||i.disableFontFace||this.options.disableFontFace)&&t.buildFontPaths(i,n,this.handler)}return n},ensureStateFont(e){if(e.font)return;const t=new r.FormatError("Missing setFont (Tf) operator before text rendering operator.");if(!this.options.ignoreErrors)throw t;this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});(0,r.warn)(`ensureStateFont: "${t}".`)},setGState:function(e,t,a,i,s){for(var o=[],c=t.getKeys(),l=Promise.resolve(),h=0,u=c.length;h<u;h++){const u=c[h],f=t.get(u);switch(u){case"Type":break;case"LW":case"LC":case"LJ":case"ML":case"D":case"RI":case"FL":case"CA":case"ca":o.push([u,f]);break;case"Font":l=l.then(()=>this.handleSetFont(e,null,f[0],a,i,s.state).then((function(e){a.addDependency(e);o.push([u,[e,f[1]]])})));break;case"BM":o.push([u,d(f)]);break;case"SMask":if((0,n.isName)(f,"None")){o.push([u,!1]);break}if((0,n.isDict)(f)){l=l.then(()=>this.handleSMask(f,e,a,i,s));o.push([u,!0])}else(0,r.warn)("Unsupported SMask type");break;case"OP":case"op":case"OPM":case"BG":case"BG2":case"UCR":case"UCR2":case"TR":case"TR2":case"HT":case"SM":case"SA":case"AIS":case"TK":(0,r.info)("graphic state operator "+u);break;default:(0,r.info)("Unknown graphic state operator "+u)}}return l.then((function(){o.length>0&&a.addOp(r.OPS.setGState,[o])}))},loadFont:function(e,a,i){function o(){return Promise.resolve(new A("g_font_error",new s.ErrorFont("Font "+e+" is not available"),a))}var c,l=this.xref;if(a){if(!(0,n.isRef)(a))throw new r.FormatError('The "font" object should be a reference.');c=a}else{var h=i.get("Font");h&&(c=h.getRaw(e))}if(!c){const i=`Font "${e||a&&a.toString()}" is not available`;if(!this.options.ignoreErrors&&!this.parsingType3Font){(0,r.warn)(`${i}.`);return o()}this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});(0,r.warn)(`${i} -- attempting to fallback to a default font.`);c=t.getFallbackFontDict()}if(this.fontCache.has(c))return this.fontCache.get(c);a=l.fetchIfRef(c);if(!(0,n.isDict)(a))return o();if(a.translated)return a.translated;var u=(0,r.createPromiseCapability)(),d=this.preEvaluateFont(a);const{descriptor:f,hash:g}=d;var m,p,b=(0,n.isRef)(c);b&&(m=c.toString());if(g&&(0,n.isDict)(f)){f.fontAliases||(f.fontAliases=Object.create(null));var y=f.fontAliases;if(y[g]){var v=y[g].aliasRef;if(b&&v&&this.fontCache.has(v)){this.fontCache.putAlias(c,v);return this.fontCache.get(c)}}else y[g]={fontID:s.Font.getFontID()};b&&(y[g].aliasRef=c);m=y[g].fontID}if(b)this.fontCache.put(c,u.promise);else{m||(m=this.idFactory.createObjId());this.fontCache.put(`id_${m}`,u.promise)}(0,r.assert)(m,'The "fontID" must be defined.');a.loadedName=`${this.idFactory.getDocId()}_f${m}`;a.translated=u.promise;try{p=this.translateFont(d)}catch(e){p=Promise.reject(e)}p.then((function(e){if(void 0!==e.fontType){l.stats.fontTypes[e.fontType]=!0}u.resolve(new A(a.loadedName,e,a))})).catch(e=>{this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});try{var t=f&&f.get("FontFile3"),i=t&&t.get("Subtype"),n=(0,s.getFontType)(d.type,i&&i.name);l.stats.fontTypes[n]=!0}catch(e){}u.resolve(new A(a.loadedName,new s.ErrorFont(e instanceof Error?e.message:e),a))});return u.promise},buildPath(e,t,a,i=!1){var n=e.length-1;a||(a=[]);if(n<0||e.fnArray[n]!==r.OPS.constructPath){if(i){(0,r.warn)(`Encountered path operator "${t}" inside of a text object.`);e.addOp(r.OPS.save,null)}e.addOp(r.OPS.constructPath,[[t],a]);i&&e.addOp(r.OPS.restore,null)}else{var s=e.argsArray[n];s[0].push(t);Array.prototype.push.apply(s[1],a)}},parseColorSpace({cs:e,resources:t}){return new Promise(a=>{a(g.ColorSpace.parse(e,this.xref,t,this.pdfFunctionFactory))}).catch(e=>{if(e instanceof r.AbortException)return null;if(this.options.ignoreErrors){this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`parseColorSpace - ignoring ColorSpace: "${e}".`);return null}throw e})},async handleColorN(e,t,a,i,s,o,c){var l,h=a[a.length-1];if((0,n.isName)(h)&&(l=s.get(h.name))){var d=(0,n.isStream)(l)?l.dict:l,f=d.get("PatternType");if(1===f){var g=i.base?i.base.getRgb(a,0):null;return this.handleTilingType(t,g,o,l,d,e,c)}if(2===f){var m=d.get("Shading"),p=d.getArray("Matrix");l=u.Pattern.parseShading(m,p,this.xref,o,this.handler,this.pdfFunctionFactory);e.addOp(t,l.getIR());return}throw new r.FormatError(`Unknown PatternType: ${f}`)}throw new r.FormatError(`Unknown PatternName: ${h}`)},getOperatorList({stream:e,task:t,resources:i,operatorList:s,initialState:o=null}){i=i||n.Dict.empty;o=o||new T;if(!s)throw new Error('getOperatorList: missing "operatorList" parameter');var c=this,l=this.xref;let h=!1;var d=Object.create(null),f=i.get("XObject")||n.Dict.empty,m=i.get("Pattern")||n.Dict.empty,p=new I(o),b=new E(e,l,p),y=new a;function v(e){for(var t=0,a=b.savedStatesDepth;t<a;t++)s.addOp(r.OPS.restore,[])}return new Promise((function e(a,o){const w=function(t){Promise.all([t,s.ready]).then((function(){try{e(a,o)}catch(e){o(e)}}),o)};t.ensureNotTerminated();y.reset();for(var k,S,C,A,I={};!(k=y.check());){I.args=null;if(!b.read(I))break;var F=I.args,T=I.fn;switch(0|T){case r.OPS.paintXObject:var E=F[0].name;if(E&&void 0!==d[E]){s.addOp(d[E].fn,d[E].args);F=null;continue}w(new Promise((function(e,a){if(!E)throw new r.FormatError("XObject must be referred to by name.");const o=f.get(E);if(!o){s.addOp(T,F);e();return}if(!(0,n.isStream)(o))throw new r.FormatError("XObject should be a stream");const l=o.dict.get("Subtype");if(!(0,n.isName)(l))throw new r.FormatError("XObject should have a Name subtype");if("Form"!==l.name)if("Image"!==l.name){if("PS"!==l.name)throw new r.FormatError(`Unhandled XObject subtype ${l.name}`);(0,r.info)("Ignored XObject subtype PS");e()}else c.buildPaintImageXObject({resources:i,image:o,operatorList:s,cacheKey:E,imageCache:d}).then(e,a);else{p.save();c.buildFormXObject(i,o,null,s,t,p.state.clone()).then((function(){p.restore();e()}),a)}})).catch((function(e){if(!(e instanceof r.AbortException)){if(!c.options.ignoreErrors)throw e;c.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`getOperatorList - ignoring XObject: "${e}".`)}})));return;case r.OPS.setFont:var O=F[1];w(c.handleSetFont(i,F,null,s,t,p.state).then((function(e){s.addDependency(e);s.addOp(r.OPS.setFont,[e,O])})));return;case r.OPS.beginText:h=!0;break;case r.OPS.endText:h=!1;break;case r.OPS.endInlineImage:var P=F[0].cacheKey;if(P){var B=d[P];if(void 0!==B){s.addOp(B.fn,B.args);F=null;continue}}w(c.buildPaintImageXObject({resources:i,image:F[0],isInline:!0,operatorList:s,cacheKey:P,imageCache:d}));return;case r.OPS.showText:if(!p.state.font){c.ensureStateFont(p.state);continue}F[0]=c.handleText(F[0],p.state);break;case r.OPS.showSpacedText:if(!p.state.font){c.ensureStateFont(p.state);continue}var D=F[0],N=[],M=D.length,L=p.state;for(S=0;S<M;++S){var R=D[S];(0,r.isString)(R)?Array.prototype.push.apply(N,c.handleText(R,L)):(0,r.isNum)(R)&&N.push(R)}F[0]=N;T=r.OPS.showText;break;case r.OPS.nextLineShowText:if(!p.state.font){c.ensureStateFont(p.state);continue}s.addOp(r.OPS.nextLine);F[0]=c.handleText(F[0],p.state);T=r.OPS.showText;break;case r.OPS.nextLineSetSpacingShowText:if(!p.state.font){c.ensureStateFont(p.state);continue}s.addOp(r.OPS.nextLine);s.addOp(r.OPS.setWordSpacing,[F.shift()]);s.addOp(r.OPS.setCharSpacing,[F.shift()]);F[0]=c.handleText(F[0],p.state);T=r.OPS.showText;break;case r.OPS.setTextRenderingMode:p.state.textRenderingMode=F[0];break;case r.OPS.setFillColorSpace:w(c.parseColorSpace({cs:F[0],resources:i}).then((function(e){e&&(p.state.fillColorSpace=e)})));return;case r.OPS.setStrokeColorSpace:w(c.parseColorSpace({cs:F[0],resources:i}).then((function(e){e&&(p.state.strokeColorSpace=e)})));return;case r.OPS.setFillColor:A=p.state.fillColorSpace;F=A.getRgb(F,0);T=r.OPS.setFillRGBColor;break;case r.OPS.setStrokeColor:A=p.state.strokeColorSpace;F=A.getRgb(F,0);T=r.OPS.setStrokeRGBColor;break;case r.OPS.setFillGray:p.state.fillColorSpace=g.ColorSpace.singletons.gray;F=g.ColorSpace.singletons.gray.getRgb(F,0);T=r.OPS.setFillRGBColor;break;case r.OPS.setStrokeGray:p.state.strokeColorSpace=g.ColorSpace.singletons.gray;F=g.ColorSpace.singletons.gray.getRgb(F,0);T=r.OPS.setStrokeRGBColor;break;case r.OPS.setFillCMYKColor:p.state.fillColorSpace=g.ColorSpace.singletons.cmyk;F=g.ColorSpace.singletons.cmyk.getRgb(F,0);T=r.OPS.setFillRGBColor;break;case r.OPS.setStrokeCMYKColor:p.state.strokeColorSpace=g.ColorSpace.singletons.cmyk;F=g.ColorSpace.singletons.cmyk.getRgb(F,0);T=r.OPS.setStrokeRGBColor;break;case r.OPS.setFillRGBColor:p.state.fillColorSpace=g.ColorSpace.singletons.rgb;F=g.ColorSpace.singletons.rgb.getRgb(F,0);break;case r.OPS.setStrokeRGBColor:p.state.strokeColorSpace=g.ColorSpace.singletons.rgb;F=g.ColorSpace.singletons.rgb.getRgb(F,0);break;case r.OPS.setFillColorN:if("Pattern"===(A=p.state.fillColorSpace).name){w(c.handleColorN(s,r.OPS.setFillColorN,F,A,m,i,t));return}F=A.getRgb(F,0);T=r.OPS.setFillRGBColor;break;case r.OPS.setStrokeColorN:if("Pattern"===(A=p.state.strokeColorSpace).name){w(c.handleColorN(s,r.OPS.setStrokeColorN,F,A,m,i,t));return}F=A.getRgb(F,0);T=r.OPS.setStrokeRGBColor;break;case r.OPS.shadingFill:var U=i.get("Shading");if(!U)throw new r.FormatError("No shading resource found");var q=U.get(F[0].name);if(!q)throw new r.FormatError("No shading object found");var j=u.Pattern.parseShading(q,null,l,i,c.handler,c.pdfFunctionFactory).getIR();F=[j];T=r.OPS.shadingFill;break;case r.OPS.setGState:var _=F[0],z=i.get("ExtGState");if(!(0,n.isDict)(z)||!z.has(_.name))break;var H=z.get(_.name);w(c.setGState(i,H,s,t,p));return;case r.OPS.moveTo:case r.OPS.lineTo:case r.OPS.curveTo:case r.OPS.curveTo2:case r.OPS.curveTo3:case r.OPS.closePath:case r.OPS.rectangle:c.buildPath(s,T,F,h);continue;case r.OPS.markPoint:case r.OPS.markPointProps:case r.OPS.beginMarkedContent:case r.OPS.beginMarkedContentProps:case r.OPS.endMarkedContent:case r.OPS.beginCompat:case r.OPS.endCompat:continue;default:if(null!==F){for(S=0,C=F.length;S<C&&!(F[S]instanceof n.Dict);S++);if(S<C){(0,r.warn)("getOperatorList - ignoring operator: "+T);continue}}}s.addOp(T,F)}if(k)w(x);else{v();a()}})).catch(e=>{if(!(e instanceof r.AbortException)){if(!this.options.ignoreErrors)throw e;this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`getOperatorList - ignoring errors during "${t.name}" `+`task: "${e}".`);v()}})},getTextContent({stream:e,task:t,resources:i,stateManager:s=null,normalizeWhitespace:o=!1,combineTextItems:c=!1,sink:h,seenStyles:u=Object.create(null)}){i=i||n.Dict.empty;s=s||new I(new F);var d,g=/\s/g,m={items:[],styles:Object.create(null)},p={initialized:!1,str:[],width:0,height:0,vertical:!1,lastAdvanceWidth:0,lastAdvanceHeight:0,textAdvanceScale:0,spaceWidth:0,fakeSpaceMin:1/0,fakeMultiSpaceMin:1/0,fakeMultiSpaceMax:-0,textRunBreakAllowed:!1,transform:null,fontName:null},b=this,y=this.xref,v=null,w=Object.create(null),k=new E(e,y,s);function S(){if(p.initialized)return p;var e=d.font;if(!(e.loadedName in u)){u[e.loadedName]=!0;m.styles[e.loadedName]={fontFamily:e.fallbackName,ascent:e.ascent,descent:e.descent,vertical:!!e.vertical}}p.fontName=e.loadedName;var t=[d.fontSize*d.textHScale,0,0,d.fontSize,0,d.textRise];if(e.isType3Font&&d.fontSize<=1&&!(0,r.isArrayEqual)(d.fontMatrix,r.FONT_IDENTITY_MATRIX)){const a=e.bbox[3]-e.bbox[1];a>0&&(t[3]*=a*d.fontMatrix[3])}var a=r.Util.transform(d.ctm,r.Util.transform(d.textMatrix,t));p.transform=a;if(e.vertical){p.width=Math.sqrt(a[0]*a[0]+a[1]*a[1]);p.height=0;p.vertical=!0}else{p.width=0;p.height=Math.sqrt(a[2]*a[2]+a[3]*a[3]);p.vertical=!1}var i=d.textLineMatrix[0],n=d.textLineMatrix[1],s=Math.sqrt(i*i+n*n);i=d.ctm[0];n=d.ctm[1];var o=Math.sqrt(i*i+n*n);p.textAdvanceScale=o*s;p.lastAdvanceWidth=0;p.lastAdvanceHeight=0;var c=e.spaceWidth/1e3*d.fontSize;if(c){p.spaceWidth=c;p.fakeSpaceMin=.3*c;p.fakeMultiSpaceMin=1.5*c;p.fakeMultiSpaceMax=4*c;p.textRunBreakAllowed=!e.isMonospace}else{p.spaceWidth=0;p.fakeSpaceMin=1/0;p.fakeMultiSpaceMin=1/0;p.fakeMultiSpaceMax=0;p.textRunBreakAllowed=!1}p.initialized=!0;return p}function C(e){for(var t,a=0,r=e.length;a<r&&(t=e.charCodeAt(a))>=32&&t<=127;)a++;return a<r?e.replace(g," "):e}function A(e,t){return b.loadFont(e,t,i).then((function(e){d.font=e.font;d.fontMatrix=e.font.fontMatrix||r.FONT_IDENTITY_MATRIX}))}function T(e){for(var t=d.font,a=S(),r=0,i=0,n=t.charsToGlyphs(e),s=0;s<n.length;s++){var o=n[s],c=null;c=t.vertical&&o.vmetric?o.vmetric[0]:o.width;var h=o.unicode,u=(0,l.getNormalizedUnicodes)();void 0!==u[h]&&(h=u[h]);h=(0,l.reverseIfRtl)(h);var f=d.charSpacing;if(o.isSpace){var g=d.wordSpacing;f+=g;g>0&&O(g,a.str)}var m=0,p=0;if(t.vertical){i+=p=c*d.fontMatrix[0]*d.fontSize+f}else{r+=m=(c*d.fontMatrix[0]*d.fontSize+f)*d.textHScale}d.translateTextMatrix(m,p);a.str.push(h)}if(t.vertical){a.lastAdvanceHeight=i;a.height+=Math.abs(i)}else{a.lastAdvanceWidth=r;a.width+=r}return a}function O(e,t){if(!(e<p.fakeSpaceMin))if(e<p.fakeMultiSpaceMin)t.push(" ");else for(var a=Math.round(e/p.spaceWidth);a-- >0;)t.push(" ")}function P(){if(p.initialized){p.vertical?p.height*=p.textAdvanceScale:p.width*=p.textAdvanceScale;m.items.push((t=(e=p).str.join(""),a=(0,f.bidi)(t,-1,e.vertical),{str:o?C(a.str):a.str,dir:a.dir,width:e.width,height:e.height,transform:e.transform,fontName:e.fontName}));var e,t,a;p.initialized=!1;p.str.length=0}}function B(){const e=m.items.length;if(e>0){h.enqueue(m,e);m.items=[];m.styles=Object.create(null)}}var D=new a;return new Promise((function e(a,l){const f=function(t){B();Promise.all([t,h.ready]).then((function(){try{e(a,l)}catch(e){l(e)}}),l)};t.ensureNotTerminated();D.reset();for(var g,y={},C=[];!(g=D.check());){C.length=0;y.args=C;if(!k.read(y))break;d=s.state;var F,E=y.fn;C=y.args;switch(0|E){case r.OPS.setFont:var N=C[0].name,M=C[1];if(d.font&&N===d.fontName&&M===d.fontSize)break;P();d.fontName=N;d.fontSize=M;f(A(N,null));return;case r.OPS.setTextRise:P();d.textRise=C[0];break;case r.OPS.setHScale:P();d.textHScale=C[0]/100;break;case r.OPS.setLeading:P();d.leading=C[0];break;case r.OPS.moveText:var L=!!d.font&&0===(d.font.vertical?C[0]:C[1]);F=C[0]-C[1];if(c&&L&&p.initialized&&F>0&&F<=p.fakeMultiSpaceMax){d.translateTextLineMatrix(C[0],C[1]);p.width+=C[0]-p.lastAdvanceWidth;p.height+=C[1]-p.lastAdvanceHeight;O(C[0]-p.lastAdvanceWidth-(C[1]-p.lastAdvanceHeight),p.str);break}P();d.translateTextLineMatrix(C[0],C[1]);d.textMatrix=d.textLineMatrix.slice();break;case r.OPS.setLeadingMoveText:P();d.leading=-C[1];d.translateTextLineMatrix(C[0],C[1]);d.textMatrix=d.textLineMatrix.slice();break;case r.OPS.nextLine:P();d.carriageReturn();break;case r.OPS.setTextMatrix:F=d.calcTextLineMatrixAdvance(C[0],C[1],C[2],C[3],C[4],C[5]);if(c&&null!==F&&p.initialized&&F.value>0&&F.value<=p.fakeMultiSpaceMax){d.translateTextLineMatrix(F.width,F.height);p.width+=F.width-p.lastAdvanceWidth;p.height+=F.height-p.lastAdvanceHeight;O(F.width-p.lastAdvanceWidth-(F.height-p.lastAdvanceHeight),p.str);break}P();d.setTextMatrix(C[0],C[1],C[2],C[3],C[4],C[5]);d.setTextLineMatrix(C[0],C[1],C[2],C[3],C[4],C[5]);break;case r.OPS.setCharSpacing:d.charSpacing=C[0];break;case r.OPS.setWordSpacing:d.wordSpacing=C[0];break;case r.OPS.beginText:P();d.textMatrix=r.IDENTITY_MATRIX.slice();d.textLineMatrix=r.IDENTITY_MATRIX.slice();break;case r.OPS.showSpacedText:if(!s.state.font){b.ensureStateFont(s.state);continue}for(var R,U=C[0],q=0,j=U.length;q<j;q++)if("string"==typeof U[q])T(U[q]);else if((0,r.isNum)(U[q])){S();F=U[q]*d.fontSize/1e3;var _=!1;if(d.font.vertical){R=F;d.translateTextMatrix(0,R);(_=p.textRunBreakAllowed&&F>p.fakeMultiSpaceMax)||(p.height+=R)}else{R=(F=-F)*d.textHScale;d.translateTextMatrix(R,0);(_=p.textRunBreakAllowed&&F>p.fakeMultiSpaceMax)||(p.width+=R)}_?P():F>0&&O(F,p.str)}break;case r.OPS.showText:if(!s.state.font){b.ensureStateFont(s.state);continue}T(C[0]);break;case r.OPS.nextLineShowText:if(!s.state.font){b.ensureStateFont(s.state);continue}P();d.carriageReturn();T(C[0]);break;case r.OPS.nextLineSetSpacingShowText:if(!s.state.font){b.ensureStateFont(s.state);continue}P();d.wordSpacing=C[0];d.charSpacing=C[1];d.carriageReturn();T(C[2]);break;case r.OPS.paintXObject:P();v||(v=i.get("XObject")||n.Dict.empty);var z=C[0].name;if(z&&void 0!==w[z])break;f(new Promise((function(e,a){if(!z)throw new r.FormatError("XObject must be referred to by name.");const l=v.get(z);if(!l){e();return}if(!(0,n.isStream)(l))throw new r.FormatError("XObject should be a stream");const d=l.dict.get("Subtype");if(!(0,n.isName)(d))throw new r.FormatError("XObject should have a Name subtype");if("Form"!==d.name){w[z]=!0;e();return}const f=s.state.clone(),g=new I(f),m=l.dict.getArray("Matrix");Array.isArray(m)&&6===m.length&&g.transform(m);B();const p={enqueueInvoked:!1,enqueue(e,t){this.enqueueInvoked=!0;h.enqueue(e,t)},get desiredSize(){return h.desiredSize},get ready(){return h.ready}};b.getTextContent({stream:l,task:t,resources:l.dict.get("Resources")||i,stateManager:g,normalizeWhitespace:o,combineTextItems:c,sink:p,seenStyles:u}).then((function(){p.enqueueInvoked||(w[z]=!0);e()}),a)})).catch((function(e){if(!(e instanceof r.AbortException)){if(!b.options.ignoreErrors)throw e;(0,r.warn)(`getTextContent - ignoring XObject: "${e}".`)}})));return;case r.OPS.setGState:P();var H=C[0],G=i.get("ExtGState");if(!(0,n.isDict)(G)||!(0,n.isName)(H))break;var W=G.get(H.name);if(!(0,n.isDict)(W))break;var X=W.get("Font");if(X){d.fontName=null;d.fontSize=X[1];f(A(null,X[0]));return}}if(m.items.length>=h.desiredSize){g=!0;break}}if(g)f(x);else{P();B();a()}})).catch(e=>{if(!(e instanceof r.AbortException)){if(!this.options.ignoreErrors)throw e;(0,r.warn)(`getTextContent - ignoring errors during "${t.name}" `+`task: "${e}".`);P();B()}})},extractDataStructures:function(e,t,a){const i=this.xref;let c;var l=e.get("ToUnicode")||t.get("ToUnicode"),h=l?this.readToUnicode(l):Promise.resolve(void 0);if(a.composite){var u=e.get("CIDSystemInfo");(0,n.isDict)(u)&&(a.cidSystemInfo={registry:(0,r.stringToPDFString)(u.get("Registry")),ordering:(0,r.stringToPDFString)(u.get("Ordering")),supplement:u.get("Supplement")});var d=e.get("CIDToGIDMap");(0,n.isStream)(d)&&(c=d.getBytes())}var f,g=[],m=null;if(e.has("Encoding")){f=e.get("Encoding");if((0,n.isDict)(f)){m=f.get("BaseEncoding");m=(0,n.isName)(m)?m.name:null;if(f.has("Differences"))for(var p=f.get("Differences"),b=0,y=0,v=p.length;y<v;y++){var w=i.fetchIfRef(p[y]);if((0,r.isNum)(w))b=w;else{if(!(0,n.isName)(w))throw new r.FormatError(`Invalid entry in 'Differences' array: ${w}`);g[b++]=w.name}}}else{if(!(0,n.isName)(f))throw new r.FormatError("Encoding is not a Name nor a Dict");m=f.name}"MacRomanEncoding"!==m&&"MacExpertEncoding"!==m&&"WinAnsiEncoding"!==m&&(m=null)}if(m)a.defaultEncoding=(0,o.getEncoding)(m).slice();else{var k=!!(a.flags&s.FontFlags.Symbolic),S=!!(a.flags&s.FontFlags.Nonsymbolic);f=o.StandardEncoding;"TrueType"!==a.type||S||(f=o.WinAnsiEncoding);if(k){f=o.MacRomanEncoding;a.file||(/Symbol/i.test(a.name)?f=o.SymbolSetEncoding:/Dingbats|Wingdings/i.test(a.name)&&(f=o.ZapfDingbatsEncoding))}a.defaultEncoding=f}a.differences=g;a.baseEncodingName=m;a.hasEncoding=!!m||g.length>0;a.dict=e;return h.then(e=>{a.toUnicode=e;return this.buildToUnicode(a)}).then(e=>{a.toUnicode=e;c&&(a.cidToGidMap=this.readCidToGidMap(c,e));return a})},_buildSimpleFontToUnicode(e,t=!1){(0,r.assert)(!e.composite,"Must be a simple font.");const a=[],i=e.defaultEncoding.slice(),n=e.baseEncodingName,c=e.differences;for(const e in c){const t=c[e];".notdef"!==t&&(i[e]=t)}const h=(0,p.getGlyphsUnicode)();for(const r in i){let s=i[r];if(""!==s)if(void 0!==h[s])a[r]=String.fromCharCode(h[s]);else{let i=0;switch(s[0]){case"G":3===s.length&&(i=parseInt(s.substring(1),16));break;case"g":5===s.length&&(i=parseInt(s.substring(1),16));break;case"C":case"c":if(s.length>=3&&s.length<=4){const a=s.substring(1);if(t){i=parseInt(a,16);break}i=+a;if(Number.isNaN(i)&&Number.isInteger(parseInt(a,16)))return this._buildSimpleFontToUnicode(e,!0)}break;default:const a=(0,l.getUnicodeForGlyph)(s,h);-1!==a&&(i=a)}if(i>0&&Number.isInteger(i)){if(n&&i===+r){const e=(0,o.getEncoding)(n);if(e&&(s=e[r])){a[r]=String.fromCharCode(h[s]);continue}}a[r]=String.fromCodePoint(i)}}}return new s.ToUnicodeMap(a)},buildToUnicode(e){e.hasIncludedToUnicodeMap=!!e.toUnicode&&e.toUnicode.length>0;if(e.hasIncludedToUnicodeMap){!e.composite&&e.hasEncoding&&(e.fallbackToUnicode=this._buildSimpleFontToUnicode(e));return Promise.resolve(e.toUnicode)}if(!e.composite)return Promise.resolve(this._buildSimpleFontToUnicode(e));if(e.composite&&(e.cMap.builtInCMap&&!(e.cMap instanceof i.IdentityCMap)||"Adobe"===e.cidSystemInfo.registry&&("GB1"===e.cidSystemInfo.ordering||"CNS1"===e.cidSystemInfo.ordering||"Japan1"===e.cidSystemInfo.ordering||"Korea1"===e.cidSystemInfo.ordering))){const t=e.cidSystemInfo.registry,a=e.cidSystemInfo.ordering,o=n.Name.get(t+"-"+a+"-UCS2");return i.CMapFactory.create({encoding:o,fetchBuiltInCMap:this.fetchBuiltInCMap,useCMap:null}).then((function(t){const a=e.cMap,i=[];a.forEach((function(e,a){if(a>65535)throw new r.FormatError("Max size of CID is 65,535");const n=t.lookup(a);n&&(i[e]=String.fromCharCode((n.charCodeAt(0)<<8)+n.charCodeAt(1)))}));return new s.ToUnicodeMap(i)}))}return Promise.resolve(new s.IdentityToUnicodeMap(e.firstChar,e.lastChar))},readToUnicode:function(e){var t=e;return(0,n.isName)(t)?i.CMapFactory.create({encoding:t,fetchBuiltInCMap:this.fetchBuiltInCMap,useCMap:null}).then((function(e){return e instanceof i.IdentityCMap?new s.IdentityToUnicodeMap(0,65535):new s.ToUnicodeMap(e.getMap())})):(0,n.isStream)(t)?i.CMapFactory.create({encoding:t,fetchBuiltInCMap:this.fetchBuiltInCMap,useCMap:null}).then((function(e){if(e instanceof i.IdentityCMap)return new s.IdentityToUnicodeMap(0,65535);var t=new Array(e.length);e.forEach((function(e,a){for(var r=[],i=0;i<a.length;i+=2){var n=a.charCodeAt(i)<<8|a.charCodeAt(i+1);if(55296==(63488&n)){i+=2;var s=a.charCodeAt(i)<<8|a.charCodeAt(i+1);r.push(((1023&n)<<10)+(1023&s)+65536)}else r.push(n)}t[e]=String.fromCodePoint.apply(String,r)}));return new s.ToUnicodeMap(t)}),e=>{if(e instanceof r.AbortException)return null;if(this.options.ignoreErrors){this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});(0,r.warn)(`readToUnicode - ignoring ToUnicode data: "${e}".`);return null}throw e}):Promise.resolve(null)},readCidToGidMap(e,t){for(var a=[],r=0,i=e.length;r<i;r++){var n=e[r++]<<8|e[r];const i=r>>1;(0!==n||t.has(i))&&(a[i]=n)}return a},extractWidths:function(e,t,a){var r,i,o,c,l,h,u,d,f=this.xref,g=[],m=0,p=[];if(a.composite){m=e.has("DW")?e.get("DW"):1e3;if(d=e.get("W"))for(i=0,o=d.length;i<o;i++){h=f.fetchIfRef(d[i++]);u=f.fetchIfRef(d[i]);if(Array.isArray(u))for(c=0,l=u.length;c<l;c++)g[h++]=f.fetchIfRef(u[c]);else{var b=f.fetchIfRef(d[++i]);for(c=h;c<=u;c++)g[c]=b}}if(a.vertical){var y=e.getArray("DW2")||[880,-1e3];r=[y[1],.5*m,y[0]];if(y=e.get("W2"))for(i=0,o=y.length;i<o;i++){h=f.fetchIfRef(y[i++]);u=f.fetchIfRef(y[i]);if(Array.isArray(u))for(c=0,l=u.length;c<l;c++)p[h++]=[f.fetchIfRef(u[c++]),f.fetchIfRef(u[c++]),f.fetchIfRef(u[c])];else{var v=[f.fetchIfRef(y[++i]),f.fetchIfRef(y[++i]),f.fetchIfRef(y[++i])];for(c=h;c<=u;c++)p[c]=v}}}}else{var w=a.firstChar;if(d=e.get("Widths")){c=w;for(i=0,o=d.length;i<o;i++)g[c++]=f.fetchIfRef(d[i]);m=parseFloat(t.get("MissingWidth"))||0}else{var k=e.get("BaseFont");if((0,n.isName)(k)){var S=this.getBaseFontMetrics(k.name);g=this.buildCharCodeToWidth(S.widths,a);m=S.defaultWidth}}}var C=!0,x=m;for(var A in g){var I=g[A];if(I)if(x){if(x!==I){C=!1;break}}else x=I}C&&(a.flags|=s.FontFlags.FixedPitch);a.defaultWidth=m;a.widths=g;a.defaultVMetrics=r;a.vmetrics=p},isSerifFont:function(e){var t=e.split("-")[0];return t in(0,h.getSerifFonts)()||-1!==t.search(/serif/gi)},getBaseFontMetrics:function(e){var t=0,a=[],i=!1,n=(0,h.getStdFontMap)()[e]||e,s=(0,b.getMetrics)();n in s||(n=this.isSerifFont(e)?"Times-Roman":"Helvetica");var o=s[n];if((0,r.isNum)(o)){t=o;i=!0}else a=o();return{defaultWidth:t,monospace:i,widths:a}},buildCharCodeToWidth:function(e,t){for(var a=Object.create(null),r=t.differences,i=t.defaultEncoding,n=0;n<256;n++)n in r&&e[r[n]]?a[n]=e[r[n]]:n in i&&e[i[n]]&&(a[n]=e[i[n]]);return a},preEvaluateFont:function(e){var t=e,a=e.get("Subtype");if(!(0,n.isName)(a))throw new r.FormatError("invalid font Subtype");var i,s=!1;if("Type0"===a.name){var o=e.get("DescendantFonts");if(!o)throw new r.FormatError("Descendant fonts are not specified");a=(e=Array.isArray(o)?this.xref.fetchIfRef(o[0]):o).get("Subtype");if(!(0,n.isName)(a))throw new r.FormatError("invalid font Subtype");s=!0}var c=e.get("FontDescriptor");if(c){var l=new w.MurmurHash3_64,h=t.getRaw("Encoding");if((0,n.isName)(h))l.update(h.name);else if((0,n.isRef)(h))l.update(h.toString());else if((0,n.isDict)(h))for(var u=h.getKeys(),d=0,f=u.length;d<f;d++){var g=h.getRaw(u[d]);if((0,n.isName)(g))l.update(g.name);else if((0,n.isRef)(g))l.update(g.toString());else if(Array.isArray(g)){for(var m=g.length,p=new Array(m),b=0;b<m;b++){var y=g[b];(0,n.isName)(y)?p[b]=y.name:((0,r.isNum)(y)||(0,n.isRef)(y))&&(p[b]=y.toString())}l.update(p.join())}}const a=e.get("FirstChar")||0,o=e.get("LastChar")||(s?65535:255);l.update(`${a}-${o}`);var v=e.get("ToUnicode")||t.get("ToUnicode");if((0,n.isStream)(v)){var k=v.str||v;i=k.buffer?new Uint8Array(k.buffer.buffer,0,k.bufferLength):new Uint8Array(k.bytes.buffer,k.start,k.end-k.start);l.update(i)}else(0,n.isName)(v)&&l.update(v.name);var S=e.get("Widths")||t.get("Widths");if(S){i=new Uint8Array(new Uint32Array(S).buffer);l.update(i)}}return{descriptor:c,dict:e,baseDict:t,composite:s,type:a.name,hash:l?l.hexdigest():""}},translateFont:function(e){var t,a=e.baseDict,o=e.dict,c=e.composite,l=e.descriptor,u=e.type,d=c?65535:255;const f=o.get("FirstChar")||0,g=o.get("LastChar")||d;if(!l){if("Type3"!==u){var m=o.get("BaseFont");if(!(0,n.isName)(m))throw new r.FormatError("Base font is not specified");m=m.name.replace(/[,_]/g,"-");var p=this.getBaseFontMetrics(m),b=m.split("-")[0],y=(this.isSerifFont(b)?s.FontFlags.Serif:0)|(p.monospace?s.FontFlags.FixedPitch:0)|((0,h.getSymbolsFonts)()[b]?s.FontFlags.Symbolic:s.FontFlags.Nonsymbolic);t={type:u,name:m,widths:p.widths,defaultWidth:p.defaultWidth,flags:y,firstChar:f,lastChar:g};const e=o.get("Widths");return this.extractDataStructures(o,o,t).then(t=>{if(e){const a=[];let r=f;for(let t=0,i=e.length;t<i;t++)a[r++]=this.xref.fetchIfRef(e[t]);t.widths=a}else t.widths=this.buildCharCodeToWidth(p.widths,t);return new s.Font(m,null,t)})}(l=new n.Dict(null)).set("FontName",n.Name.get(u));l.set("FontBBox",o.getArray("FontBBox")||[0,0,0,0])}var v=l.get("FontName"),w=o.get("BaseFont");(0,r.isString)(v)&&(v=n.Name.get(v));(0,r.isString)(w)&&(w=n.Name.get(w));if("Type3"!==u){var k=v&&v.name,S=w&&w.name;if(k!==S){(0,r.info)(`The FontDescriptor's FontName is "${k}" but `+`should be the same as the Font's BaseFont "${S}".`);k&&S&&S.startsWith(k)&&(v=w)}}v=v||w;if(!(0,n.isName)(v))throw new r.FormatError("invalid font name");var C,x=l.get("FontFile","FontFile2","FontFile3");if(x&&x.dict){var A=x.dict.get("Subtype");A&&(A=A.name);var I=x.dict.get("Length1"),F=x.dict.get("Length2"),T=x.dict.get("Length3")}t={type:u,name:v.name,subtype:A,file:x,length1:I,length2:F,length3:T,loadedName:a.loadedName,composite:c,wideChars:c,fixedPitch:!1,fontMatrix:o.getArray("FontMatrix")||r.FONT_IDENTITY_MATRIX,firstChar:f||0,lastChar:g||d,bbox:l.getArray("FontBBox"),ascent:l.get("Ascent"),descent:l.get("Descent"),xHeight:l.get("XHeight"),capHeight:l.get("CapHeight"),flags:l.get("Flags"),italicAngle:l.get("ItalicAngle"),isType3Font:!1};if(c){var E=a.get("Encoding");(0,n.isName)(E)&&(t.cidEncoding=E.name);C=i.CMapFactory.create({encoding:E,fetchBuiltInCMap:this.fetchBuiltInCMap,useCMap:null}).then((function(e){t.cMap=e;t.vertical=t.cMap.vertical}))}else C=Promise.resolve(void 0);return C.then(()=>this.extractDataStructures(o,a,t)).then(e=>{this.extractWidths(o,l,e);"Type3"===u&&(e.isType3Font=!0);return new s.Font(v.name,x,e)})}};t.buildFontPaths=function(e,t,a){function r(t){e.renderer.hasBuiltPath(t)||a.send("commonobj",[`${e.loadedName}_path_${t}`,"FontPath",e.renderer.getPathJs(t)])}for(const e of t){r(e.fontChar);const t=e.accent;t&&t.fontChar&&r(t.fontChar)}};t.getFallbackFontDict=function(){if(this._fallbackFontDict)return this._fallbackFontDict;const e=new n.Dict;e.set("BaseFont",n.Name.get("PDFJS-FallbackFont"));e.set("Type",n.Name.get("FallbackType"));e.set("Subtype",n.Name.get("FallbackType"));e.set("Encoding",n.Name.get("WinAnsiEncoding"));return this._fallbackFontDict=e};return t}();t.PartialEvaluator=x;var A=function(){function e(e,t,a){this.loadedName=e;this.font=t;this.dict=a;this.type3Loaded=null;this.sent=!1}e.prototype={send(e){if(!this.sent){this.sent=!0;e.send("commonobj",[this.loadedName,"Font",this.font.exportData()])}},fallback(e){if(!this.font.data)return;this.font.disableFontFace=!0;const t=this.font.glyphCacheValues;x.buildFontPaths(this.font,t,e)},loadType3Data(e,t,a,i){if(!this.font.isType3Font)throw new Error("Must be a Type3 font.");if(this.type3Loaded)return this.type3Loaded;var n=Object.create(e.options);n.ignoreErrors=!1;n.nativeImageDecoderSupport=r.NativeImageDecoding.NONE;var s=e.clone(n);s.parsingType3Font=!0;for(var o=this.font,c=Promise.resolve(),l=this.dict.get("CharProcs"),h=this.dict.get("Resources")||t,u=l.getKeys(),d=Object.create(null),f=0,g=u.length;f<g;++f){const e=u[f];c=c.then((function(){var t=l.get(e),n=new S.OperatorList;return s.getOperatorList({stream:t,task:i,resources:h,operatorList:n}).then((function(){d[e]=n.getIR();a.addDependencies(n.dependencies)})).catch((function(t){(0,r.warn)(`Type3 font resource "${e}" is not available.`);var a=new S.OperatorList;d[e]=a.getIR()}))}))}this.type3Loaded=c.then((function(){o.charProcOperatorList=d}));return this.type3Loaded}};return e}(),I=function(){function e(e){this.state=e;this.stateStack=[]}e.prototype={save(){var e=this.state;this.stateStack.push(this.state);this.state=e.clone()},restore(){var e=this.stateStack.pop();e&&(this.state=e)},transform(e){this.state.ctm=r.Util.transform(this.state.ctm,e)}};return e}(),F=function(){function e(){this.ctm=new Float32Array(r.IDENTITY_MATRIX);this.fontName=null;this.fontSize=0;this.font=null;this.fontMatrix=r.FONT_IDENTITY_MATRIX;this.textMatrix=r.IDENTITY_MATRIX.slice();this.textLineMatrix=r.IDENTITY_MATRIX.slice();this.charSpacing=0;this.wordSpacing=0;this.leading=0;this.textHScale=1;this.textRise=0}e.prototype={setTextMatrix:function(e,t,a,r,i,n){var s=this.textMatrix;s[0]=e;s[1]=t;s[2]=a;s[3]=r;s[4]=i;s[5]=n},setTextLineMatrix:function(e,t,a,r,i,n){var s=this.textLineMatrix;s[0]=e;s[1]=t;s[2]=a;s[3]=r;s[4]=i;s[5]=n},translateTextMatrix:function(e,t){var a=this.textMatrix;a[4]=a[0]*e+a[2]*t+a[4];a[5]=a[1]*e+a[3]*t+a[5]},translateTextLineMatrix:function(e,t){var a=this.textLineMatrix;a[4]=a[0]*e+a[2]*t+a[4];a[5]=a[1]*e+a[3]*t+a[5]},calcTextLineMatrixAdvance:function(e,t,a,r,i,n){var s=this.font;if(!s)return null;var o=this.textLineMatrix;if(e!==o[0]||t!==o[1]||a!==o[2]||r!==o[3])return null;var c=i-o[4],l=n-o[5];if(s.vertical&&0!==c||!s.vertical&&0!==l)return null;var h,u,d=e*r-t*a;if(s.vertical){h=-l*a/d;u=l*e/d}else{h=c*r/d;u=-c*t/d}return{width:h,height:u,value:s.vertical?u:h}},calcRenderMatrix:function(e){var t=[this.fontSize*this.textHScale,0,0,this.fontSize,0,this.textRise];return r.Util.transform(e,r.Util.transform(this.textMatrix,t))},carriageReturn:function(){this.translateTextLineMatrix(0,-this.leading);this.textMatrix=this.textLineMatrix.slice()},clone:function(){var e=Object.create(this);e.textMatrix=this.textMatrix.slice();e.textLineMatrix=this.textLineMatrix.slice();e.fontMatrix=this.fontMatrix.slice();return e}};return e}(),T=function(){function e(){this.ctm=new Float32Array(r.IDENTITY_MATRIX);this.font=null;this.textRenderingMode=r.TextRenderingMode.FILL;this.fillColorSpace=g.ColorSpace.singletons.gray;this.strokeColorSpace=g.ColorSpace.singletons.gray}e.prototype={clone:function(){return Object.create(this)}};return e}(),E=function(){var e=(0,c.getLookupTableFactory)((function(e){e.w={id:r.OPS.setLineWidth,numArgs:1,variableArgs:!1};e.J={id:r.OPS.setLineCap,numArgs:1,variableArgs:!1};e.j={id:r.OPS.setLineJoin,numArgs:1,variableArgs:!1};e.M={id:r.OPS.setMiterLimit,numArgs:1,variableArgs:!1};e.d={id:r.OPS.setDash,numArgs:2,variableArgs:!1};e.ri={id:r.OPS.setRenderingIntent,numArgs:1,variableArgs:!1};e.i={id:r.OPS.setFlatness,numArgs:1,variableArgs:!1};e.gs={id:r.OPS.setGState,numArgs:1,variableArgs:!1};e.q={id:r.OPS.save,numArgs:0,variableArgs:!1};e.Q={id:r.OPS.restore,numArgs:0,variableArgs:!1};e.cm={id:r.OPS.transform,numArgs:6,variableArgs:!1};e.m={id:r.OPS.moveTo,numArgs:2,variableArgs:!1};e.l={id:r.OPS.lineTo,numArgs:2,variableArgs:!1};e.c={id:r.OPS.curveTo,numArgs:6,variableArgs:!1};e.v={id:r.OPS.curveTo2,numArgs:4,variableArgs:!1};e.y={id:r.OPS.curveTo3,numArgs:4,variableArgs:!1};e.h={id:r.OPS.closePath,numArgs:0,variableArgs:!1};e.re={id:r.OPS.rectangle,numArgs:4,variableArgs:!1};e.S={id:r.OPS.stroke,numArgs:0,variableArgs:!1};e.s={id:r.OPS.closeStroke,numArgs:0,variableArgs:!1};e.f={id:r.OPS.fill,numArgs:0,variableArgs:!1};e.F={id:r.OPS.fill,numArgs:0,variableArgs:!1};e["f*"]={id:r.OPS.eoFill,numArgs:0,variableArgs:!1};e.B={id:r.OPS.fillStroke,numArgs:0,variableArgs:!1};e["B*"]={id:r.OPS.eoFillStroke,numArgs:0,variableArgs:!1};e.b={id:r.OPS.closeFillStroke,numArgs:0,variableArgs:!1};e["b*"]={id:r.OPS.closeEOFillStroke,numArgs:0,variableArgs:!1};e.n={id:r.OPS.endPath,numArgs:0,variableArgs:!1};e.W={id:r.OPS.clip,numArgs:0,variableArgs:!1};e["W*"]={id:r.OPS.eoClip,numArgs:0,variableArgs:!1};e.BT={id:r.OPS.beginText,numArgs:0,variableArgs:!1};e.ET={id:r.OPS.endText,numArgs:0,variableArgs:!1};e.Tc={id:r.OPS.setCharSpacing,numArgs:1,variableArgs:!1};e.Tw={id:r.OPS.setWordSpacing,numArgs:1,variableArgs:!1};e.Tz={id:r.OPS.setHScale,numArgs:1,variableArgs:!1};e.TL={id:r.OPS.setLeading,numArgs:1,variableArgs:!1};e.Tf={id:r.OPS.setFont,numArgs:2,variableArgs:!1};e.Tr={id:r.OPS.setTextRenderingMode,numArgs:1,variableArgs:!1};e.Ts={id:r.OPS.setTextRise,numArgs:1,variableArgs:!1};e.Td={id:r.OPS.moveText,numArgs:2,variableArgs:!1};e.TD={id:r.OPS.setLeadingMoveText,numArgs:2,variableArgs:!1};e.Tm={id:r.OPS.setTextMatrix,numArgs:6,variableArgs:!1};e["T*"]={id:r.OPS.nextLine,numArgs:0,variableArgs:!1};e.Tj={id:r.OPS.showText,numArgs:1,variableArgs:!1};e.TJ={id:r.OPS.showSpacedText,numArgs:1,variableArgs:!1};e["'"]={id:r.OPS.nextLineShowText,numArgs:1,variableArgs:!1};e['"']={id:r.OPS.nextLineSetSpacingShowText,numArgs:3,variableArgs:!1};e.d0={id:r.OPS.setCharWidth,numArgs:2,variableArgs:!1};e.d1={id:r.OPS.setCharWidthAndBounds,numArgs:6,variableArgs:!1};e.CS={id:r.OPS.setStrokeColorSpace,numArgs:1,variableArgs:!1};e.cs={id:r.OPS.setFillColorSpace,numArgs:1,variableArgs:!1};e.SC={id:r.OPS.setStrokeColor,numArgs:4,variableArgs:!0};e.SCN={id:r.OPS.setStrokeColorN,numArgs:33,variableArgs:!0};e.sc={id:r.OPS.setFillColor,numArgs:4,variableArgs:!0};e.scn={id:r.OPS.setFillColorN,numArgs:33,variableArgs:!0};e.G={id:r.OPS.setStrokeGray,numArgs:1,variableArgs:!1};e.g={id:r.OPS.setFillGray,numArgs:1,variableArgs:!1};e.RG={id:r.OPS.setStrokeRGBColor,numArgs:3,variableArgs:!1};e.rg={id:r.OPS.setFillRGBColor,numArgs:3,variableArgs:!1};e.K={id:r.OPS.setStrokeCMYKColor,numArgs:4,variableArgs:!1};e.k={id:r.OPS.setFillCMYKColor,numArgs:4,variableArgs:!1};e.sh={id:r.OPS.shadingFill,numArgs:1,variableArgs:!1};e.BI={id:r.OPS.beginInlineImage,numArgs:0,variableArgs:!1};e.ID={id:r.OPS.beginImageData,numArgs:0,variableArgs:!1};e.EI={id:r.OPS.endInlineImage,numArgs:1,variableArgs:!1};e.Do={id:r.OPS.paintXObject,numArgs:1,variableArgs:!1};e.MP={id:r.OPS.markPoint,numArgs:1,variableArgs:!1};e.DP={id:r.OPS.markPointProps,numArgs:2,variableArgs:!1};e.BMC={id:r.OPS.beginMarkedContent,numArgs:1,variableArgs:!1};e.BDC={id:r.OPS.beginMarkedContentProps,numArgs:2,variableArgs:!1};e.EMC={id:r.OPS.endMarkedContent,numArgs:0,variableArgs:!1};e.BX={id:r.OPS.beginCompat,numArgs:0,variableArgs:!1};e.EX={id:r.OPS.endCompat,numArgs:0,variableArgs:!1};e.BM=null;e.BD=null;e.true=null;e.fa=null;e.fal=null;e.fals=null;e.false=null;e.nu=null;e.nul=null;e.null=null}));function t(t,a,r){this.opMap=e();this.parser=new d.Parser({lexer:new d.Lexer(t,this.opMap),xref:a});this.stateManager=r;this.nonProcessedArgs=[];this._numInvalidPathOPS=0}t.prototype={get savedStatesDepth(){return this.stateManager.stateStack.length},read:function(e){for(var t=e.args;;){var a=this.parser.getObj();if(a instanceof n.Cmd){var i=a.cmd,s=this.opMap[i];if(!s){(0,r.warn)(`Unknown command "${i}".`);continue}var o=s.id,c=s.numArgs,l=null!==t?t.length:0;if(s.variableArgs)l>c&&(0,r.info)(`Command ${i}: expected [0, ${c}] args, `+`but received ${l} args.`);else{if(l!==c){for(var h=this.nonProcessedArgs;l>c;){h.push(t.shift());l--}for(;l<c&&0!==h.length;){null===t&&(t=[]);t.unshift(h.pop());l++}}if(l<c){const e=`command ${i}: expected ${c} args, `+`but received ${l} args.`;if(o>=r.OPS.moveTo&&o<=r.OPS.endPath&&++this._numInvalidPathOPS>20)throw new r.FormatError(`Invalid ${e}`);(0,r.warn)(`Skipping ${e}`);null!==t&&(t.length=0);continue}}this.preprocessCommand(o,t);e.fn=o;e.args=t;return!0}if(a===n.EOF)return!1;if(null!==a){null===t&&(t=[]);t.push(a);if(t.length>33)throw new r.FormatError("Too many arguments")}}},preprocessCommand:function(e,t){switch(0|e){case r.OPS.save:this.stateManager.save();break;case r.OPS.restore:this.stateManager.restore();break;case r.OPS.transform:this.stateManager.transform(t)}}};return t}()},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.CMapFactory=t.IdentityCMap=t.CMap=void 0;var r=a(2),i=a(4),n=a(10),s=a(7),o=a(11),c=["Adobe-GB1-UCS2","Adobe-CNS1-UCS2","Adobe-Japan1-UCS2","Adobe-Korea1-UCS2","78-EUC-H","78-EUC-V","78-H","78-RKSJ-H","78-RKSJ-V","78-V","78ms-RKSJ-H","78ms-RKSJ-V","83pv-RKSJ-H","90ms-RKSJ-H","90ms-RKSJ-V","90msp-RKSJ-H","90msp-RKSJ-V","90pv-RKSJ-H","90pv-RKSJ-V","Add-H","Add-RKSJ-H","Add-RKSJ-V","Add-V","Adobe-CNS1-0","Adobe-CNS1-1","Adobe-CNS1-2","Adobe-CNS1-3","Adobe-CNS1-4","Adobe-CNS1-5","Adobe-CNS1-6","Adobe-GB1-0","Adobe-GB1-1","Adobe-GB1-2","Adobe-GB1-3","Adobe-GB1-4","Adobe-GB1-5","Adobe-Japan1-0","Adobe-Japan1-1","Adobe-Japan1-2","Adobe-Japan1-3","Adobe-Japan1-4","Adobe-Japan1-5","Adobe-Japan1-6","Adobe-Korea1-0","Adobe-Korea1-1","Adobe-Korea1-2","B5-H","B5-V","B5pc-H","B5pc-V","CNS-EUC-H","CNS-EUC-V","CNS1-H","CNS1-V","CNS2-H","CNS2-V","ETHK-B5-H","ETHK-B5-V","ETen-B5-H","ETen-B5-V","ETenms-B5-H","ETenms-B5-V","EUC-H","EUC-V","Ext-H","Ext-RKSJ-H","Ext-RKSJ-V","Ext-V","GB-EUC-H","GB-EUC-V","GB-H","GB-V","GBK-EUC-H","GBK-EUC-V","GBK2K-H","GBK2K-V","GBKp-EUC-H","GBKp-EUC-V","GBT-EUC-H","GBT-EUC-V","GBT-H","GBT-V","GBTpc-EUC-H","GBTpc-EUC-V","GBpc-EUC-H","GBpc-EUC-V","H","HKdla-B5-H","HKdla-B5-V","HKdlb-B5-H","HKdlb-B5-V","HKgccs-B5-H","HKgccs-B5-V","HKm314-B5-H","HKm314-B5-V","HKm471-B5-H","HKm471-B5-V","HKscs-B5-H","HKscs-B5-V","Hankaku","Hiragana","KSC-EUC-H","KSC-EUC-V","KSC-H","KSC-Johab-H","KSC-Johab-V","KSC-V","KSCms-UHC-H","KSCms-UHC-HW-H","KSCms-UHC-HW-V","KSCms-UHC-V","KSCpc-EUC-H","KSCpc-EUC-V","Katakana","NWP-H","NWP-V","RKSJ-H","RKSJ-V","Roman","UniCNS-UCS2-H","UniCNS-UCS2-V","UniCNS-UTF16-H","UniCNS-UTF16-V","UniCNS-UTF32-H","UniCNS-UTF32-V","UniCNS-UTF8-H","UniCNS-UTF8-V","UniGB-UCS2-H","UniGB-UCS2-V","UniGB-UTF16-H","UniGB-UTF16-V","UniGB-UTF32-H","UniGB-UTF32-V","UniGB-UTF8-H","UniGB-UTF8-V","UniJIS-UCS2-H","UniJIS-UCS2-HW-H","UniJIS-UCS2-HW-V","UniJIS-UCS2-V","UniJIS-UTF16-H","UniJIS-UTF16-V","UniJIS-UTF32-H","UniJIS-UTF32-V","UniJIS-UTF8-H","UniJIS-UTF8-V","UniJIS2004-UTF16-H","UniJIS2004-UTF16-V","UniJIS2004-UTF32-H","UniJIS2004-UTF32-V","UniJIS2004-UTF8-H","UniJIS2004-UTF8-V","UniJISPro-UCS2-HW-V","UniJISPro-UCS2-V","UniJISPro-UTF8-V","UniJISX0213-UTF32-H","UniJISX0213-UTF32-V","UniJISX02132004-UTF32-H","UniJISX02132004-UTF32-V","UniKS-UCS2-H","UniKS-UCS2-V","UniKS-UTF16-H","UniKS-UTF16-V","UniKS-UTF32-H","UniKS-UTF32-V","UniKS-UTF8-H","UniKS-UTF8-V","V","WP-Symbol"];class l{constructor(e=!1){this.codespaceRanges=[[],[],[],[]];this.numCodespaceRanges=0;this._map=[];this.name="";this.vertical=!1;this.useCMap=null;this.builtInCMap=e}addCodespaceRange(e,t,a){this.codespaceRanges[e-1].push(t,a);this.numCodespaceRanges++}mapCidRange(e,t,a){for(;e<=t;)this._map[e++]=a++}mapBfRange(e,t,a){for(var r=a.length-1;e<=t;){this._map[e++]=a;a=a.substring(0,r)+String.fromCharCode(a.charCodeAt(r)+1)}}mapBfRangeToArray(e,t,a){const r=a.length;let i=0;for(;e<=t&&i<r;){this._map[e]=a[i++];++e}}mapOne(e,t){this._map[e]=t}lookup(e){return this._map[e]}contains(e){return void 0!==this._map[e]}forEach(e){const t=this._map,a=t.length;if(a<=65536)for(let r=0;r<a;r++)void 0!==t[r]&&e(r,t[r]);else for(const a in t)e(a,t[a])}charCodeOf(e){const t=this._map;if(t.length<=65536)return t.indexOf(e);for(const a in t)if(t[a]===e)return 0|a;return-1}getMap(){return this._map}readCharCode(e,t,a){let r=0;const i=this.codespaceRanges;for(let n=0,s=i.length;n<s;n++){r=(r<<8|e.charCodeAt(t+n))>>>0;const s=i[n];for(let e=0,t=s.length;e<t;){const t=s[e++],i=s[e++];if(r>=t&&r<=i){a.charcode=r;a.length=n+1;return}}}a.charcode=0;a.length=1}get length(){return this._map.length}get isIdentityCMap(){if("Identity-H"!==this.name&&"Identity-V"!==this.name)return!1;if(65536!==this._map.length)return!1;for(let e=0;e<65536;e++)if(this._map[e]!==e)return!1;return!0}}t.CMap=l;class h extends l{constructor(e,t){super();this.vertical=e;this.addCodespaceRange(t,0,65535)}mapCidRange(e,t,a){(0,r.unreachable)("should not call mapCidRange")}mapBfRange(e,t,a){(0,r.unreachable)("should not call mapBfRange")}mapBfRangeToArray(e,t,a){(0,r.unreachable)("should not call mapBfRangeToArray")}mapOne(e,t){(0,r.unreachable)("should not call mapCidOne")}lookup(e){return Number.isInteger(e)&&e<=65535?e:void 0}contains(e){return Number.isInteger(e)&&e<=65535}forEach(e){for(let t=0;t<=65535;t++)e(t,t)}charCodeOf(e){return Number.isInteger(e)&&e<=65535?e:-1}getMap(){const e=new Array(65536);for(let t=0;t<=65535;t++)e[t]=t;return e}get length(){return 65536}get isIdentityCMap(){(0,r.unreachable)("should not access .isIdentityCMap")}}t.IdentityCMap=h;var u=function(){function e(e,t){for(var a=0,r=0;r<=t;r++)a=a<<8|e[r];return a>>>0}function t(e,t){return 1===t?String.fromCharCode(e[0],e[1]):3===t?String.fromCharCode(e[0],e[1],e[2],e[3]):String.fromCharCode.apply(null,e.subarray(0,t+1))}function a(e,t,a){for(var r=0,i=a;i>=0;i--){r+=e[i]+t[i];e[i]=255&r;r>>=8}}function i(e,t){for(var a=1,r=t;r>=0&&a>0;r--){a+=e[r];e[r]=255&a;a>>=8}}function n(e){this.buffer=e;this.pos=0;this.end=e.length;this.tmpBuf=new Uint8Array(19)}n.prototype={readByte(){return this.pos>=this.end?-1:this.buffer[this.pos++]},readNumber(){var e,t=0;do{var a=this.readByte();if(a<0)throw new r.FormatError("unexpected EOF in bcmap");e=!(128&a);t=t<<7|127&a}while(!e);return t},readSigned(){var e=this.readNumber();return 1&e?~(e>>>1):e>>>1},readHex(e,t){e.set(this.buffer.subarray(this.pos,this.pos+t+1));this.pos+=t+1},readHexNumber(e,t){var a,i=this.tmpBuf,n=0;do{var s=this.readByte();if(s<0)throw new r.FormatError("unexpected EOF in bcmap");a=!(128&s);i[n++]=127&s}while(!a);for(var o=t,c=0,l=0;o>=0;){for(;l<8&&i.length>0;){c=i[--n]<<l|c;l+=7}e[o]=255&c;o--;c>>=8;l-=8}},readHexSigned(e,t){this.readHexNumber(e,t);for(var a=1&e[t]?255:0,r=0,i=0;i<=t;i++){r=(1&r)<<8|e[i];e[i]=r>>1^a}},readString(){for(var e=this.readNumber(),t="",a=0;a<e;a++)t+=String.fromCharCode(this.readNumber());return t}};function s(){}s.prototype={process:function(r,s,o){return new Promise((function(c,l){var h=new n(r),u=h.readByte();s.vertical=!!(1&u);for(var d,f,g=null,m=new Uint8Array(16),p=new Uint8Array(16),b=new Uint8Array(16),y=new Uint8Array(16),v=new Uint8Array(16);(f=h.readByte())>=0;){var w=f>>5;if(7!==w){var k=!!(16&f),S=15&f;if(S+1>16)throw new Error("processBinaryCMap: Invalid dataSize.");var C,x=h.readNumber();switch(w){case 0:h.readHex(m,S);h.readHexNumber(p,S);a(p,m,S);s.addCodespaceRange(S+1,e(m,S),e(p,S));for(C=1;C<x;C++){i(p,S);h.readHexNumber(m,S);a(m,p,S);h.readHexNumber(p,S);a(p,m,S);s.addCodespaceRange(S+1,e(m,S),e(p,S))}break;case 1:h.readHex(m,S);h.readHexNumber(p,S);a(p,m,S);h.readNumber();for(C=1;C<x;C++){i(p,S);h.readHexNumber(m,S);a(m,p,S);h.readHexNumber(p,S);a(p,m,S);h.readNumber()}break;case 2:h.readHex(b,S);d=h.readNumber();s.mapOne(e(b,S),d);for(C=1;C<x;C++){i(b,S);if(!k){h.readHexNumber(v,S);a(b,v,S)}d=h.readSigned()+(d+1);s.mapOne(e(b,S),d)}break;case 3:h.readHex(m,S);h.readHexNumber(p,S);a(p,m,S);d=h.readNumber();s.mapCidRange(e(m,S),e(p,S),d);for(C=1;C<x;C++){i(p,S);if(k)m.set(p);else{h.readHexNumber(m,S);a(m,p,S)}h.readHexNumber(p,S);a(p,m,S);d=h.readNumber();s.mapCidRange(e(m,S),e(p,S),d)}break;case 4:h.readHex(b,1);h.readHex(y,S);s.mapOne(e(b,1),t(y,S));for(C=1;C<x;C++){i(b,1);if(!k){h.readHexNumber(v,1);a(b,v,1)}i(y,S);h.readHexSigned(v,S);a(y,v,S);s.mapOne(e(b,1),t(y,S))}break;case 5:h.readHex(m,1);h.readHexNumber(p,1);a(p,m,1);h.readHex(y,S);s.mapBfRange(e(m,1),e(p,1),t(y,S));for(C=1;C<x;C++){i(p,1);if(k)m.set(p);else{h.readHexNumber(m,1);a(m,p,1)}h.readHexNumber(p,1);a(p,m,1);h.readHex(y,S);s.mapBfRange(e(m,1),e(p,1),t(y,S))}break;default:l(new Error("processBinaryCMap: Unknown type: "+w));return}}else switch(31&f){case 0:h.readString();break;case 1:g=h.readString()}}c(g?o(g):s)}))}};return s}(),d=function(){function e(e){for(var t=0,a=0;a<e.length;a++)t=t<<8|e.charCodeAt(a);return t>>>0}function t(e){if(!(0,r.isString)(e))throw new r.FormatError("Malformed CMap: expected string.")}function a(e){if(!Number.isInteger(e))throw new r.FormatError("Malformed CMap: expected int.")}function d(a,r){for(;;){var n=r.getObj();if((0,i.isEOF)(n))break;if((0,i.isCmd)(n,"endbfchar"))return;t(n);var s=e(n);t(n=r.getObj());var o=n;a.mapOne(s,o)}}function f(a,n){for(;;){var s=n.getObj();if((0,i.isEOF)(s))break;if((0,i.isCmd)(s,"endbfrange"))return;t(s);var o=e(s);t(s=n.getObj());var c=e(s);s=n.getObj();if(Number.isInteger(s)||(0,r.isString)(s)){var l=Number.isInteger(s)?String.fromCharCode(s):s;a.mapBfRange(o,c,l)}else{if(!(0,i.isCmd)(s,"["))break;s=n.getObj();for(var h=[];!(0,i.isCmd)(s,"]")&&!(0,i.isEOF)(s);){h.push(s);s=n.getObj()}a.mapBfRangeToArray(o,c,h)}}throw new r.FormatError("Invalid bf range.")}function g(r,n){for(;;){var s=n.getObj();if((0,i.isEOF)(s))break;if((0,i.isCmd)(s,"endcidchar"))return;t(s);var o=e(s);a(s=n.getObj());var c=s;r.mapOne(o,c)}}function m(r,n){for(;;){var s=n.getObj();if((0,i.isEOF)(s))break;if((0,i.isCmd)(s,"endcidrange"))return;t(s);var o=e(s);t(s=n.getObj());var c=e(s);a(s=n.getObj());var l=s;r.mapCidRange(o,c,l)}}function p(t,a){for(;;){var n=a.getObj();if((0,i.isEOF)(n))break;if((0,i.isCmd)(n,"endcodespacerange"))return;if(!(0,r.isString)(n))break;var s=e(n);n=a.getObj();if(!(0,r.isString)(n))break;var o=e(n);t.addCodespaceRange(n.length,s,o)}throw new r.FormatError("Invalid codespace range.")}function b(e,t){var a=t.getObj();Number.isInteger(a)&&(e.vertical=!!a)}function y(e,t){var a=t.getObj();(0,i.isName)(a)&&(0,r.isString)(a.name)&&(e.name=a.name)}function v(e,t,a,n){var o,c;e:for(;;)try{var l=t.getObj();if((0,i.isEOF)(l))break;if((0,i.isName)(l)){"WMode"===l.name?b(e,t):"CMapName"===l.name&&y(e,t);o=l}else if((0,i.isCmd)(l))switch(l.cmd){case"endcmap":break e;case"usecmap":(0,i.isName)(o)&&(c=o.name);break;case"begincodespacerange":p(e,t);break;case"beginbfchar":d(e,t);break;case"begincidchar":g(e,t);break;case"beginbfrange":f(e,t);break;case"begincidrange":m(e,t)}}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)("Invalid cMap data: "+e);continue}!n&&c&&(n=c);return n?w(e,a,n):Promise.resolve(e)}function w(e,t,a){return k(a,t).then((function(t){e.useCMap=t;if(0===e.numCodespaceRanges){for(var a=e.useCMap.codespaceRanges,r=0;r<a.length;r++)e.codespaceRanges[r]=a[r].slice();e.numCodespaceRanges=e.useCMap.numCodespaceRanges}e.useCMap.forEach((function(t,a){e.contains(t)||e.mapOne(t,e.useCMap.lookup(t))}));return e}))}function k(e,t){return"Identity-H"===e?Promise.resolve(new h(!1,2)):"Identity-V"===e?Promise.resolve(new h(!0,2)):c.includes(e)?t?t(e).then((function(e){var a=e.cMapData,i=e.compressionType,s=new l(!0);if(i===r.CMapCompressionType.BINARY)return(new u).process(a,s,(function(e){return w(s,t,e)}));if(i===r.CMapCompressionType.NONE){var c=new n.Lexer(new o.Stream(a));return v(s,c,t,null)}return Promise.reject(new Error("TODO: Only BINARY/NONE CMap compression is currently supported."))})):Promise.reject(new Error("Built-in CMap parameters are not provided.")):Promise.reject(new Error("Unknown CMap name: "+e))}return{async create(e){var t=e.encoding,a=e.fetchBuiltInCMap,r=e.useCMap;if((0,i.isName)(t))return k(t.name,a);if((0,i.isStream)(t)){return v(new l,new n.Lexer(t),a,r).then((function(e){return e.isIdentityCMap?k(e.name,a):e}))}throw new Error("Encoding required.")}}}();t.CMapFactory=d},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getFontType=y;t.IdentityToUnicodeMap=t.ToUnicodeMap=t.FontFlags=t.Font=t.ErrorFont=t.SEAC_ANALYSIS_ENABLED=void 0;var r=a(2),i=a(28),n=a(31),s=a(30),o=a(32),c=a(33),l=a(7),h=a(34),u=a(26),d=a(11),f=a(35);const g=[[57344,63743],[1048576,1114109]];t.SEAC_ANALYSIS_ENABLED=!0;var m={FixedPitch:1,Serif:2,Symbolic:4,Script:8,Nonsymbolic:32,Italic:64,AllCap:65536,SmallCap:131072,ForceBold:262144};t.FontFlags=m;var p=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"];function b(e){if(e.fontMatrix&&e.fontMatrix[0]!==r.FONT_IDENTITY_MATRIX[0]){var t=.001/e.fontMatrix[0],a=e.widths;for(var i in a)a[i]*=t;e.defaultWidth*=t}}function y(e,t){switch(e){case"Type1":return"Type1C"===t?r.FontType.TYPE1C:r.FontType.TYPE1;case"CIDFontType0":return"CIDFontType0C"===t?r.FontType.CIDFONTTYPE0C:r.FontType.CIDFONTTYPE0;case"OpenType":return r.FontType.OPENTYPE;case"TrueType":return r.FontType.TRUETYPE;case"CIDFontType2":return r.FontType.CIDFONTTYPE2;case"MMType1":return r.FontType.MMTYPE1;case"Type0":return r.FontType.TYPE0;default:return r.FontType.UNKNOWN}}function v(e,t){if(void 0!==t[e])return e;var a=(0,c.getUnicodeForGlyph)(e,t);if(-1!==a)for(var i in t)if(t[i]===a)return i;(0,r.info)("Unable to recover a standard glyph name for: "+e);return e}var w=function(){function e(e,t,a,r,i,n,s,o){this.fontChar=e;this.unicode=t;this.accent=a;this.width=r;this.vmetric=i;this.operatorListId=n;this.isSpace=s;this.isInFont=o}e.prototype.matchesForCache=function(e,t,a,r,i,n,s,o){return this.fontChar===e&&this.unicode===t&&this.accent===a&&this.width===r&&this.vmetric===i&&this.operatorListId===n&&this.isSpace===s&&this.isInFont===o};return e}(),k=function(){function e(e=[]){this._map=e}e.prototype={get length(){return this._map.length},forEach(e){for(var t in this._map)e(t,this._map[t].charCodeAt(0))},has(e){return void 0!==this._map[e]},get(e){return this._map[e]},charCodeOf(e){const t=this._map;if(t.length<=65536)return t.indexOf(e);for(const a in t)if(t[a]===e)return 0|a;return-1},amend(e){for(var t in e)this._map[t]=e[t]}};return e}();t.ToUnicodeMap=k;var S=function(){function e(e,t){this.firstChar=e;this.lastChar=t}e.prototype={get length(){return this.lastChar+1-this.firstChar},forEach(e){for(var t=this.firstChar,a=this.lastChar;t<=a;t++)e(t,t)},has(e){return this.firstChar<=e&&e<=this.lastChar},get(e){if(this.firstChar<=e&&e<=this.lastChar)return String.fromCharCode(e)},charCodeOf(e){return Number.isInteger(e)&&e>=this.firstChar&&e<=this.lastChar?e:-1},amend(e){(0,r.unreachable)("Should not call amend()")}};return e}();t.IdentityToUnicodeMap=S;var C=function(){function e(e,t,a){e[t]=a>>8&255;e[t+1]=255&a}function t(e,t,a){e[t]=a>>24&255;e[t+1]=a>>16&255;e[t+2]=a>>8&255;e[t+3]=255&a}function a(e,t,a){var r,i;if(a instanceof Uint8Array)e.set(a,t);else if("string"==typeof a)for(r=0,i=a.length;r<i;r++)e[t++]=255&a.charCodeAt(r);else for(r=0,i=a.length;r<i;r++)e[t++]=255&a[r]}function i(e){this.sfnt=e;this.tables=Object.create(null)}i.getSearchParams=function(e,t){for(var a=1,r=0;(a^e)>a;){a<<=1;r++}var i=a*t;return{range:i,entry:r,rangeShift:t*e-i}};i.prototype={toArray:function(){var n=this.sfnt,s=this.tables,o=Object.keys(s);o.sort();var c,h,u,d,f,g=o.length,m=12+16*g,p=[m];for(c=0;c<g;c++){m+=((d=s[o[c]]).length+3&-4)>>>0;p.push(m)}var b=new Uint8Array(m);for(c=0;c<g;c++){d=s[o[c]];a(b,p[c],d)}"true"===n&&(n=(0,r.string32)(65536));b[0]=255&n.charCodeAt(0);b[1]=255&n.charCodeAt(1);b[2]=255&n.charCodeAt(2);b[3]=255&n.charCodeAt(3);e(b,4,g);var y=i.getSearchParams(g,16);e(b,6,y.range);e(b,8,y.entry);e(b,10,y.rangeShift);m=12;for(c=0;c<g;c++){f=o[c];b[m]=255&f.charCodeAt(0);b[m+1]=255&f.charCodeAt(1);b[m+2]=255&f.charCodeAt(2);b[m+3]=255&f.charCodeAt(3);var v=0;for(h=p[c],u=p[c+1];h<u;h+=4){v=v+(0,l.readUint32)(b,h)>>>0}t(b,m+4,v);t(b,m+8,p[c]);t(b,m+12,s[f].length);m+=16}return b},addTable:function(e,t){if(e in this.tables)throw new Error("Table "+e+" already exists");this.tables[e]=t}};return i}(),x=function(){function e(e,t,a){var i;this.name=e;this.loadedName=a.loadedName;this.isType3Font=a.isType3Font;this.sizes=[];this.missingFile=!1;this.glyphCache=Object.create(null);this.isSerifFont=!!(a.flags&m.Serif);this.isSymbolicFont=!!(a.flags&m.Symbolic);this.isMonospace=!!(a.flags&m.FixedPitch);var n=a.type,s=a.subtype;this.type=n;this.subtype=s;let o="sans-serif";this.isMonospace?o="monospace":this.isSerifFont&&(o="serif");this.fallbackName=o;this.differences=a.differences;this.widths=a.widths;this.defaultWidth=a.defaultWidth;this.composite=a.composite;this.wideChars=a.wideChars;this.cMap=a.cMap;this.ascent=a.ascent/1e3;this.descent=a.descent/1e3;this.fontMatrix=a.fontMatrix;this.bbox=a.bbox;this.defaultEncoding=a.defaultEncoding;this.toUnicode=a.toUnicode;this.fallbackToUnicode=a.fallbackToUnicode||new k;this.toFontChar=[];if("Type3"!==a.type){this.cidEncoding=a.cidEncoding;this.vertical=a.vertical;if(this.vertical){this.vmetrics=a.vmetrics;this.defaultVMetrics=a.defaultVMetrics}if(t&&!t.isEmpty){[n,s]=function(e,{type:t,subtype:a,composite:i}){let n,s;if(function(e){var t=e.peekBytes(4);return 65536===(0,l.readUint32)(t,0)||"true"===(0,r.bytesToString)(t)}(e)||I(e))n=i?"CIDFontType2":"TrueType";else if(function(e){var t=e.peekBytes(4);return"OTTO"===(0,r.bytesToString)(t)}(e))n=i?"CIDFontType2":"OpenType";else if(function(e){var t=e.peekBytes(2);if(37===t[0]&&33===t[1])return!0;if(128===t[0]&&1===t[1])return!0;return!1}(e))n=i?"CIDFontType0":"MMType1"===t?"MMType1":"Type1";else if(function(e){const t=e.peekBytes(4);if(t[0]>=1&&t[3]>=1&&t[3]<=4)return!0;return!1}(e))if(i){n="CIDFontType0";s="CIDFontType0C"}else{n="MMType1"===t?"MMType1":"Type1";s="Type1C"}else{(0,r.warn)("getFontFileType: Unable to detect correct font file Type/Subtype.");n=t;s=a}return[n,s]}(t,a);n===this.type&&s===this.subtype||(0,r.info)("Inconsistent font file Type/SubType, expected: "+`${this.type}/${this.subtype} but found: ${n}/${s}.`);try{var c;switch(n){case"MMType1":(0,r.info)("MMType1 font ("+e+"), falling back to Type1.");case"Type1":case"CIDFontType0":this.mimetype="font/opentype";var h="Type1C"===s||"CIDFontType0C"===s?new T(t,a):new F(e,t,a);b(a);c=this.convert(e,h,a);break;case"OpenType":case"TrueType":case"CIDFontType2":this.mimetype="font/opentype";c=this.checkAndRepair(e,t,a);if(this.isOpenType){b(a);n="OpenType"}break;default:throw new r.FormatError(`Font ${n} is not supported`)}}catch(e){(0,r.warn)(e);this.fallbackToSystemFont();return}this.data=c;this.fontType=y(n,s);this.fontMatrix=a.fontMatrix;this.widths=a.widths;this.defaultWidth=a.defaultWidth;this.toUnicode=a.toUnicode;this.encoding=a.baseEncoding;this.seacMap=a.seacMap}else{t&&(0,r.warn)('Font file is empty in "'+e+'" ('+this.loadedName+")");this.fallbackToSystemFont()}}else{for(i=0;i<256;i++)this.toFontChar[i]=this.differences[i]||a.defaultEncoding[i];this.fontType=r.FontType.TYPE3}}e.getFontID=(t=1,function(){return String(t++)});var t;function a(e,t){return(e<<8)+t}function f(e,t){var a=(e<<8)+t;return 32768&a?a-65536:a}function x(e){return String.fromCharCode(e>>8&255,255&e)}function A(e){e>32767?e=32767:e<-32768&&(e=-32768);return String.fromCharCode(e>>8&255,255&e)}function I(e){const t=e.peekBytes(4);return"ttcf"===(0,r.bytesToString)(t)}function E(e,t,a){for(var r,i=[],n=0,s=e.length;n<s;n++)-1!==(r=(0,c.getUnicodeForGlyph)(e[n],t))&&(i[n]=r);for(var o in a)-1!==(r=(0,c.getUnicodeForGlyph)(a[o],t))&&(i[+o]=r);return i}function O(e,t,a){var i=Object.create(null),n=[],s=0,o=g[s][0],c=g[s][1];for(var l in e){var h=e[l|=0];if(t(h)){if(o>c){if(++s>=g.length){(0,r.warn)("Ran out of space in font private use area.");break}o=g[s][0];c=g[s][1]}var u=o++;0===h&&(h=a);i[u]=h;n[l]=u}}return{toFontChar:n,charCodeToGlyphId:i,nextAvailableFontCharCode:o}}function P(e,t){var a,i,n,s,o=function(e,t){var a=[];for(var r in e)e[r]>=t||a.push({fontCharCode:0|r,glyphId:e[r]});0===a.length&&a.push({fontCharCode:0,glyphId:0});a.sort((function(e,t){return e.fontCharCode-t.fontCharCode}));for(var i=[],n=a.length,s=0;s<n;){var o=a[s].fontCharCode,c=[a[s].glyphId];++s;for(var l=o;s<n&&l+1===a[s].fontCharCode;){c.push(a[s].glyphId);++s;if(65535===++l)break}i.push([o,l,c])}return i}(e,t),c=o[o.length-1][1]>65535?2:1,l="\0\0"+x(c)+"\0\0"+(0,r.string32)(4+8*c);for(a=o.length-1;a>=0&&!(o[a][0]<=65535);--a);var h=a+1;o[a][0]<65535&&65535===o[a][1]&&(o[a][1]=65534);var u,d,f,g,m=o[a][1]<65535?1:0,p=h+m,b=C.getSearchParams(p,2),y="",v="",w="",k="",S="",A=0;for(a=0,i=h;a<i;a++){d=(u=o[a])[0];f=u[1];y+=x(d);v+=x(f);var I=!0;for(n=1,s=(g=u[2]).length;n<s;++n)if(g[n]!==g[n-1]+1){I=!1;break}if(I){w+=x(g[0]-d&65535);k+=x(0)}else{var F=2*(p-a)+2*A;A+=f-d+1;w+=x(0);k+=x(F);for(n=0,s=g.length;n<s;++n)S+=x(g[n])}}if(m>0){v+="ÿÿ";y+="ÿÿ";w+="\0";k+="\0\0"}var T="\0\0"+x(2*p)+x(b.range)+x(b.entry)+x(b.rangeShift)+v+"\0\0"+y+w+k+S,E="",O="";if(c>1){l+="\0\0\n"+(0,r.string32)(4+8*c+4+T.length);E="";for(a=0,i=o.length;a<i;a++){d=(u=o[a])[0];var P=(g=u[2])[0];for(n=1,s=g.length;n<s;++n)if(g[n]!==g[n-1]+1){f=u[0]+n-1;E+=(0,r.string32)(d)+(0,r.string32)(f)+(0,r.string32)(P);d=f+1;P=g[n]}E+=(0,r.string32)(d)+(0,r.string32)(u[1])+(0,r.string32)(P)}O="\0\f\0\0"+(0,r.string32)(E.length+16)+"\0\0\0\0"+(0,r.string32)(E.length/12)}return l+"\0"+x(T.length+4)+T+O+E}function B(e,t,a){a=a||{unitsPerEm:0,yMax:0,yMin:0,ascent:0,descent:0};var i=0,n=0,s=0,o=0,l=null,h=0;if(t){for(var u in t){(l>(u|=0)||!l)&&(l=u);h<u&&(h=u);var d=(0,c.getUnicodeRangeFor)(u);if(d<32)i|=1<<d;else if(d<64)n|=1<<d-32;else if(d<96)s|=1<<d-64;else{if(!(d<123))throw new r.FormatError("Unicode ranges Bits > 123 are reserved for internal usage");o|=1<<d-96}}h>65535&&(h=65535)}else{l=0;h=255}var f=e.bbox||[0,0,0,0],g=a.unitsPerEm||1/(e.fontMatrix||r.FONT_IDENTITY_MATRIX)[0],m=e.ascentScaled?1:g/1e3,p=a.ascent||Math.round(m*(e.ascent||f[3])),b=a.descent||Math.round(m*(e.descent||f[1]));b>0&&e.descent>0&&f[1]<0&&(b=-b);var y=a.yMax||p,v=-a.yMin||-b;return"\0$ô\0\0\0Š»\0\0\0ŒŠ»\0\0ß\x001\0\0\0\0"+String.fromCharCode(e.fixedPitch?9:0)+"\0\0\0\0\0\0"+(0,r.string32)(i)+(0,r.string32)(n)+(0,r.string32)(s)+(0,r.string32)(o)+"*21*"+x(e.italicAngle?1:0)+x(l||e.firstChar)+x(h||e.lastChar)+x(p)+x(b)+"\0d"+x(y)+x(v)+"\0\0\0\0\0\0\0\0"+x(e.xHeight)+x(e.capHeight)+x(0)+x(l||e.firstChar)+"\0"}function D(e){var t=Math.floor(65536*e.italicAngle);return"\0\0\0"+(0,r.string32)(t)+"\0\0\0\0"+(0,r.string32)(e.fixedPitch)+"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}function N(e,t){t||(t=[[],[]]);var a,r,i,n,s,o=[t[0][0]||"Original licence",t[0][1]||e,t[0][2]||"Unknown",t[0][3]||"uniqueID",t[0][4]||e,t[0][5]||"Version 0.11",t[0][6]||"",t[0][7]||"Unknown",t[0][8]||"Unknown",t[0][9]||"Unknown"],c=[];for(a=0,r=o.length;a<r;a++){var l=[];for(i=0,n=(s=t[1][a]||o[a]).length;i<n;i++)l.push(x(s.charCodeAt(i)));c.push(l.join(""))}var h=[o,c],u=["\0","\0"],d=["\0\0","\0"],f=["\0\0","\t"],g=o.length*u.length,m="\0\0"+x(g)+x(12*g+6),p=0;for(a=0,r=u.length;a<r;a++){var b=h[a];for(i=0,n=b.length;i<n;i++){s=b[i];m+=u[a]+d[a]+f[a]+x(i)+x(s.length)+x(p);p+=s.length}}return m+=o.join("")+c.join("")}e.prototype={name:null,font:null,mimetype:null,encoding:null,disableFontFace:!1,get renderer(){var e=h.FontRendererFactory.create(this,!0);return(0,r.shadow)(this,"renderer",e)},exportData:function(){var e={};for(var t in this)this.hasOwnProperty(t)&&(e[t]=this[t]);return e},fallbackToSystemFont:function(){this.missingFile=!0;var e,t,a=this.name,i=this.type,l=this.subtype;let h=a.replace(/[,_]/g,"-").replace(/\s/g,"");var u=(0,o.getStdFontMap)(),d=(0,o.getNonStdFontMap)(),f=!!u[h]||!(!d[h]||!u[d[h]]);h=u[h]||d[h]||h;this.bold=-1!==h.search(/bold/gi);this.italic=-1!==h.search(/oblique/gi)||-1!==h.search(/italic/gi);this.black=-1!==a.search(/Black/g);this.remeasure=Object.keys(this.widths).length>0;if(f&&"CIDFontType2"===i&&this.cidEncoding.startsWith("Identity-")){const t=(0,o.getGlyphMapForStandardFonts)(),r=[];for(e in t)r[+e]=t[e];if(/Arial-?Black/i.test(a)){var g=(0,o.getSupplementalGlyphMapForArialBlack)();for(e in g)r[+e]=g[e]}else if(/Calibri/i.test(a)){const t=(0,o.getSupplementalGlyphMapForCalibri)();for(e in t)r[+e]=t[e]}this.toUnicode instanceof S||this.toUnicode.forEach((function(e,t){r[+e]=t}));this.toFontChar=r;this.toUnicode=new k(r)}else if(/Symbol/i.test(h))this.toFontChar=E(s.SymbolSetEncoding,(0,n.getGlyphsUnicode)(),this.differences);else if(/Dingbats/i.test(h)){/Wingdings/i.test(a)&&(0,r.warn)("Non-embedded Wingdings font, falling back to ZapfDingbats.");this.toFontChar=E(s.ZapfDingbatsEncoding,(0,n.getDingbatsGlyphsUnicode)(),this.differences)}else if(f)this.toFontChar=E(this.defaultEncoding,(0,n.getGlyphsUnicode)(),this.differences);else{const r=(0,n.getGlyphsUnicode)(),i=[];this.toUnicode.forEach((e,a)=>{if(!this.composite){var n=this.differences[e]||this.defaultEncoding[e];-1!==(t=(0,c.getUnicodeForGlyph)(n,r))&&(a=t)}i[+e]=a});if(this.composite&&this.toUnicode instanceof S&&/Verdana/i.test(a)){const t=(0,o.getGlyphMapForStandardFonts)();for(e in t)i[+e]=t[e]}this.toFontChar=i}this.loadedName=h.split("-")[0];this.fontType=y(i,l)},checkAndRepair:function(e,t,o){const c=["OS/2","cmap","head","hhea","hmtx","maxp","name","post","loca","glyf","fpgm","prep","cvt ","CFF "];function l(e,a){const r=Object.create(null);r["OS/2"]=null;r.cmap=null;r.head=null;r.hhea=null;r.hmtx=null;r.maxp=null;r.name=null;r.post=null;for(let e=0;e<a;e++){const e=h(t);c.includes(e.tag)&&(0!==e.length&&(r[e.tag]=e))}return r}function h(e){var t=(0,r.bytesToString)(e.getBytes(4)),a=e.getInt32()>>>0,i=e.getInt32()>>>0,n=e.getInt32()>>>0,s=e.pos;e.pos=e.start?e.start:0;e.skip(i);var o=e.getBytes(n);e.pos=s;if("head"===t){o[8]=o[9]=o[10]=o[11]=0;o[17]|=32}return{tag:t,checksum:a,length:n,offset:i,data:o}}function g(e){return{version:(0,r.bytesToString)(e.getBytes(4)),numTables:e.getUint16(),searchRange:e.getUint16(),entrySelector:e.getUint16(),rangeShift:e.getUint16()}}function m(e,t,a,r,i,n){var s={length:0,sizeOfInstructions:0};if(a-t<=12)return s;var o=e.subarray(t,a),c=f(o[0],o[1]);if(c<0){!function(e,t,a){e[t+1]=a;e[t]=a>>>8}(o,0,c=-1);r.set(o,i);s.length=o.length;return s}var l,h=10,u=0;for(l=0;l<c;l++){u=(o[h]<<8|o[h+1])+1;h+=2}var d=h,g=o[h]<<8|o[h+1];s.sizeOfInstructions=g;var m=h+=2+g,p=0;for(l=0;l<u;l++){var b=o[h++];192&b&&(o[h-1]=63&b);let e=2;2&b?e=1:16&b&&(e=0);let t=2;4&b?t=1:32&b&&(t=0);const a=e+t;p+=a;if(8&b){var y=o[h++];l+=y;p+=y*a}}if(0===p)return s;var v=h+p;if(v>o.length)return s;if(!n&&g>0){r.set(o.subarray(0,d),i);r.set([0,0],i+d);r.set(o.subarray(m,v),i+d+2);v-=g;o.length-v>3&&(v=v+3&-4);s.length=v;return s}if(o.length-v>3){v=v+3&-4;r.set(o.subarray(0,v),i);s.length=v;return s}r.set(o,i);s.length=o.length;return s}function y(e){var a=(t.start?t.start:0)+e.offset;t.pos=a;var i=[[],[]],n=e.length,s=a+n;if(0!==t.getUint16()||n<6)return i;var o,c,l=t.getUint16(),h=t.getUint16(),u=[];for(o=0;o<l&&t.pos+12<=s;o++){var d={platform:t.getUint16(),encoding:t.getUint16(),language:t.getUint16(),name:t.getUint16(),length:t.getUint16(),offset:t.getUint16()};(1===d.platform&&0===d.encoding&&0===d.language||3===d.platform&&1===d.encoding&&1033===d.language)&&u.push(d)}for(o=0,c=u.length;o<c;o++){var f=u[o];if(!(f.length<=0)){var g=a+h+f.offset;if(!(g+f.length>s)){t.pos=g;var m=f.name;if(f.encoding){for(var p="",b=0,y=f.length;b<y;b+=2)p+=String.fromCharCode(t.getUint16());i[1][m]=p}else i[0][m]=(0,r.bytesToString)(t.getBytes(f.length))}}}return i}var w=[0,0,0,0,0,0,0,0,-2,-2,-2,-2,0,0,-2,-5,-1,-1,-1,-1,-1,-1,-1,-1,0,0,-1,0,-1,-1,-1,-1,1,-1,-999,0,1,0,-1,-2,0,-1,-2,-1,-1,0,-1,-1,0,0,-999,-999,-1,-1,-1,-1,-2,-999,-2,-2,-999,0,-2,-2,0,0,-2,0,-2,0,0,0,-2,-1,-1,1,1,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,-1,0,-1,-1,0,-999,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,-2,-999,-999,-999,-999,-999,-1,-1,-2,-2,0,0,0,0,-1,-1,-999,-2,-2,0,0,-1,-2,-2,0,0,0,-1,-1,-1,-2];function k(e,t){for(var a,i,n,s,o,c=e.data,l=0,h=0,u=0,d=[],f=[],g=[],m=t.tooComplexToFollowFunctions,p=!1,b=0,y=0,v=c.length;l<v;){var k=c[l++];if(64===k){i=c[l++];if(p||y)l+=i;else for(a=0;a<i;a++)d.push(c[l++])}else if(65===k){i=c[l++];if(p||y)l+=2*i;else for(a=0;a<i;a++){n=c[l++];d.push(n<<8|c[l++])}}else if(176==(248&k)){i=k-176+1;if(p||y)l+=i;else for(a=0;a<i;a++)d.push(c[l++])}else if(184==(248&k)){i=k-184+1;if(p||y)l+=2*i;else for(a=0;a<i;a++){n=c[l++];d.push(n<<8|c[l++])}}else if(43!==k||m)if(44!==k||m){if(45===k)if(p){p=!1;h=l}else{if(!(o=f.pop())){(0,r.warn)("TT: ENDF bad stack");t.hintsValid=!1;return}s=g.pop();c=o.data;l=o.i;t.functionsStackDeltas[s]=d.length-o.stackTop}else if(137===k){if(p||y){(0,r.warn)("TT: nested IDEFs not allowed");m=!0}p=!0;u=l}else if(88===k)++b;else if(27===k)y=b;else if(89===k){y===b&&(y=0);--b}else if(28===k&&!p&&!y){var S=d[d.length-1];S>0&&(l+=S-1)}}else{if(p||y){(0,r.warn)("TT: nested FDEFs not allowed");m=!0}p=!0;u=l;s=d.pop();t.functionsDefined[s]={data:c,i:l}}else if(!p&&!y){s=d[d.length-1];if(isNaN(s))(0,r.info)("TT: CALL empty stack (or invalid entry).");else{t.functionsUsed[s]=!0;if(s in t.functionsStackDeltas){const e=d.length+t.functionsStackDeltas[s];if(e<0){(0,r.warn)("TT: CALL invalid functions stack delta.");t.hintsValid=!1;return}d.length=e}else if(s in t.functionsDefined&&!g.includes(s)){f.push({data:c,i:l,stackTop:d.length-1});g.push(s);if(!(o=t.functionsDefined[s])){(0,r.warn)("TT: CALL non-existent function");t.hintsValid=!1;return}c=o.data;l=o.i}}}if(!p&&!y){let e=0;k<=142?e=w[k]:k>=192&&k<=223?e=-1:k>=224&&(e=-2);if(k>=113&&k<=117){i=d.pop();isNaN(i)||(e=2*-i)}for(;e<0&&d.length>0;){d.pop();e++}for(;e>0;){d.push(NaN);e--}}}t.tooComplexToFollowFunctions=m;var C=[c];l>c.length&&C.push(new Uint8Array(l-c.length));if(u>h){(0,r.warn)("TT: complementing a missing function tail");C.push(new Uint8Array([34,45]))}!function(e,t){if(t.length>1){var a,r,i=0;for(a=0,r=t.length;a<r;a++)i+=t[a].length;i=i+3&-4;var n=new Uint8Array(i),s=0;for(a=0,r=t.length;a<r;a++){n.set(t[a],s);s+=t[a].length}e.data=n;e.length=i}}(e,C)}let S,x,A,F;if(I(t=new d.Stream(new Uint8Array(t.getBytes())))){const e=function(e,t){const{numFonts:a,offsetTable:i}=function(e){const t=(0,r.bytesToString)(e.getBytes(4));(0,r.assert)("ttcf"===t,"Must be a TrueType Collection font.");const a=e.getUint16(),i=e.getUint16(),n=e.getInt32()>>>0,s=[];for(let t=0;t<n;t++)s.push(e.getInt32()>>>0);const o={ttcTag:t,majorVersion:a,minorVersion:i,numFonts:n,offsetTable:s};switch(a){case 1:return o;case 2:o.dsigTag=e.getInt32()>>>0;o.dsigLength=e.getInt32()>>>0;o.dsigOffset=e.getInt32()>>>0;return o}throw new r.FormatError(`Invalid TrueType Collection majorVersion: ${a}.`)}(e);for(let n=0;n<a;n++){e.pos=(e.start||0)+i[n];const a=g(e),s=l(0,a.numTables);if(!s.name)throw new r.FormatError('TrueType Collection font must contain a "name" table.');const o=y(s.name);for(let e=0,r=o.length;e<r;e++)for(let r=0,i=o[e].length;r<i;r++){const i=o[e][r];if(i&&i.replace(/\s/g,"")===t)return{header:a,tables:s}}}throw new r.FormatError(`TrueType Collection does not contain "${t}" font.`)}(t,this.name);S=e.header;x=e.tables}else{S=g(t);x=l(0,S.numTables)}var E=!x["CFF "];if(E){if(!x.loca)throw new r.FormatError('Required "loca" table is not found');if(!x.glyf){(0,r.warn)('Required "glyf" table is not found -- trying to recover.');x.glyf={tag:"glyf",data:new Uint8Array(0)}}this.isOpenType=!1}else{const t=o.composite&&((o.cidToGidMap||[]).length>0||!(o.cMap instanceof u.IdentityCMap));if("OTTO"===S.version&&!t||!x.head||!x.hhea||!x.maxp||!x.post){F=new d.Stream(x["CFF "].data);A=new T(F,o);b(o);return this.convert(e,A,o)}delete x.glyf;delete x.loca;delete x.fpgm;delete x.prep;delete x["cvt "];this.isOpenType=!0}if(!x.maxp)throw new r.FormatError('Required "maxp" table is not found');t.pos=(t.start||0)+x.maxp.offset;var M=t.getInt32();const L=t.getUint16();let R=L+1,U=!0;if(R>65535){U=!1;R=L;(0,r.warn)("Not enough space in glyfs to duplicate first glyph.")}var q=0,j=0;if(M>=65536&&x.maxp.length>=22){t.pos+=8;if(t.getUint16()>2){x.maxp.data[14]=0;x.maxp.data[15]=2}t.pos+=4;q=t.getUint16();t.pos+=4;j=t.getUint16()}x.maxp.data[4]=R>>8;x.maxp.data[5]=255&R;var _=function(e,t,a,i){var n={functionsDefined:[],functionsUsed:[],functionsStackDeltas:[],tooComplexToFollowFunctions:!1,hintsValid:!0};e&&k(e,n);t&&k(t,n);e&&function(e,t){if(!e.tooComplexToFollowFunctions)if(e.functionsDefined.length>t){(0,r.warn)("TT: more functions defined than expected");e.hintsValid=!1}else for(var a=0,i=e.functionsUsed.length;a<i;a++){if(a>t){(0,r.warn)("TT: invalid function id: "+a);e.hintsValid=!1;return}if(e.functionsUsed[a]&&!e.functionsDefined[a]){(0,r.warn)("TT: undefined function: "+a);e.hintsValid=!1;return}}}(n,i);if(a&&1&a.length){var s=new Uint8Array(a.length+1);s.set(a.data);a.data=s}return n.hintsValid}(x.fpgm,x.prep,x["cvt "],q);if(!_){delete x.fpgm;delete x.prep;delete x["cvt "]}!function(e,t,a,i,n){if(t){e.pos=(e.start?e.start:0)+t.offset;e.pos+=4;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=8;e.pos+=2;var s=e.getUint16();if(s>i){(0,r.info)("The numOfMetrics ("+s+") should not be greater than the numGlyphs ("+i+")");s=i;t.data[34]=(65280&s)>>8;t.data[35]=255&s}var o=i-s-(a.length-4*s>>1);if(o>0){var c=new Uint8Array(a.length+2*o);c.set(a.data);if(n){c[a.length]=a.data[2];c[a.length+1]=a.data[3]}a.data=c}}else a&&(a.data=null)}(t,x.hhea,x.hmtx,R,U);if(!x.head)throw new r.FormatError('Required "head" table is not found');!function(e,t,i){var n,s,o,c,l=e.data,h=(n=l[0],s=l[1],o=l[2],c=l[3],(n<<24)+(s<<16)+(o<<8)+c);if(h>>16!=1){(0,r.info)("Attempting to fix invalid version in head table: "+h);l[0]=0;l[1]=1;l[2]=0;l[3]=0}var u=a(l[50],l[51]);if(u<0||u>1){(0,r.info)("Attempting to fix invalid indexToLocFormat in head table: "+u);var d=t+1;if(i===d<<1){l[50]=0;l[51]=0}else{if(i!==d<<2)throw new r.FormatError("Could not fix indexToLocFormat: "+u);l[50]=0;l[51]=1}}}(x.head,L,E?x.loca.length:0);var z=Object.create(null);if(E){var H=a(x.head.data[50],x.head.data[51]),G=function(e,t,a,r,i,n,s){var o,c,l;if(r){o=4;c=function(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]};l=function(e,t,a){e[t]=a>>>24&255;e[t+1]=a>>16&255;e[t+2]=a>>8&255;e[t+3]=255&a}}else{o=2;c=function(e,t){return e[t]<<9|e[t+1]<<1};l=function(e,t,a){e[t]=a>>9&255;e[t+1]=a>>1&255}}var h=n?a+1:a,u=o*(1+h),d=new Uint8Array(u);d.set(e.data.subarray(0,u));e.data=d;var f,g,p=t.data,b=p.length,y=new Uint8Array(b),v=c(d,0),w=0,k=Object.create(null);l(d,0,w);for(f=0,g=o;f<a;f++,g+=o){var S=c(d,g);0===S&&(S=v);S>b&&(b+3&-4)===S&&(S=b);S>b&&(v=S);var C=m(p,v,S,y,w,i),x=C.length;0===x&&(k[f]=!0);C.sizeOfInstructions>s&&(s=C.sizeOfInstructions);l(d,g,w+=x);v=S}if(0===w){var A=new Uint8Array([0,1,0,0,0,0,0,0,0,0,0,0,0,0,49,0]);for(f=0,g=o;f<h;f++,g+=o)l(d,g,A.length);t.data=A}else if(n){var I=c(d,o);if(y.length>I+w)t.data=y.subarray(0,I+w);else{t.data=new Uint8Array(I+w);t.data.set(y.subarray(0,w))}t.data.set(y.subarray(0,I),w);l(e.data,d.length-o,w+I)}else t.data=y.subarray(0,w);return{missingGlyphs:k,maxSizeOfInstructions:s}}(x.loca,x.glyf,L,H,_,U,j);z=G.missingGlyphs;if(M>=65536&&x.maxp.length>=22){x.maxp.data[26]=G.maxSizeOfInstructions>>8;x.maxp.data[27]=255&G.maxSizeOfInstructions}}if(!x.hhea)throw new r.FormatError('Required "hhea" table is not found');if(0===x.hhea.data[10]&&0===x.hhea.data[11]){x.hhea.data[10]=255;x.hhea.data[11]=255}var W={unitsPerEm:a(x.head.data[18],x.head.data[19]),yMax:a(x.head.data[42],x.head.data[43]),yMin:f(x.head.data[38],x.head.data[39]),ascent:a(x.hhea.data[4],x.hhea.data[5]),descent:f(x.hhea.data[6],x.hhea.data[7])};this.ascent=W.ascent/W.unitsPerEm;this.descent=W.descent/W.unitsPerEm;x.post&&function(e,a,i){var n=(t.start?t.start:0)+e.offset;t.pos=n;var s,o=n+e.length,c=t.getInt32();t.getBytes(28);var l,h=!0;switch(c){case 65536:s=p;break;case 131072:var u=t.getUint16();if(u!==i){h=!1;break}var d=[];for(l=0;l<u;++l){var f=t.getUint16();if(f>=32768){h=!1;break}d.push(f)}if(!h)break;for(var g=[],m=[];t.pos<o;){var b=t.getByte();m.length=b;for(l=0;l<b;++l)m[l]=String.fromCharCode(t.getByte());g.push(m.join(""))}s=[];for(l=0;l<u;++l){var y=d[l];y<258?s.push(p[y]):s.push(g[y-258])}break;case 196608:break;default:(0,r.warn)("Unknown/unsupported post table version "+c);h=!1;a.defaultEncoding&&(s=a.defaultEncoding)}a.glyphNames=s}(x.post,o,L);x.post={tag:"post",data:D(o)};var X,V=[];function K(e){return!z[e]}if(o.composite){var Y=o.cidToGidMap||[],$=0===Y.length;o.cMap.forEach((function(e,t){if(t>65535)throw new r.FormatError("Max size of CID is 65,535");var a=-1;$?a=t:void 0!==Y[t]&&(a=Y[t]);a>=0&&a<L&&K(a)&&(V[e]=a)}))}else{var J=function(e,t,a,i){if(!e){(0,r.warn)("No cmap table available.");return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}var n,s=(t.start?t.start:0)+e.offset;t.pos=s;t.getUint16();for(var o,c=t.getUint16(),l=!1,h=0;h<c;h++){var u=t.getUint16(),d=t.getUint16(),f=t.getInt32()>>>0,g=!1;if(!o||o.platformId!==u||o.encodingId!==d){if(0===u&&0===d)g=!0;else if(1===u&&0===d)g=!0;else if(3!==u||1!==d||!i&&o){if(a&&3===u&&0===d){g=!0;l=!0}}else{g=!0;a||(l=!0)}g&&(o={platformId:u,encodingId:d,offset:f});if(l)break}}o&&(t.pos=s+o.offset);if(!o||-1===t.peekByte()){(0,r.warn)("Could not find a preferred cmap table.");return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}var m=t.getUint16();t.getUint16();t.getUint16();var p,b,y=!1,v=[];if(0===m){for(p=0;p<256;p++){var w=t.getByte();w&&v.push({charCode:p,glyphId:w})}y=!0}else if(4===m){var k=t.getUint16()>>1;t.getBytes(6);var S,C=[];for(S=0;S<k;S++)C.push({end:t.getUint16()});t.getUint16();for(S=0;S<k;S++)C[S].start=t.getUint16();for(S=0;S<k;S++)C[S].delta=t.getUint16();var x=0;for(S=0;S<k;S++){n=C[S];var A=t.getUint16();if(A){var I=(A>>1)-(k-S);n.offsetIndex=I;x=Math.max(x,I+n.end-n.start+1)}else n.offsetIndex=-1}var F=[];for(p=0;p<x;p++)F.push(t.getUint16());for(S=0;S<k;S++){s=(n=C[S]).start;var T=n.end,E=n.delta;I=n.offsetIndex;for(p=s;p<=T;p++)if(65535!==p){b=(b=I<0?p:F[I+p-s])+E&65535;v.push({charCode:p,glyphId:b})}}}else{if(6!==m){(0,r.warn)("cmap table has unsupported format: "+m);return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}var O=t.getUint16(),P=t.getUint16();for(p=0;p<P;p++){b=t.getUint16();var B=O+p;v.push({charCode:B,glyphId:b})}}v.sort((function(e,t){return e.charCode-t.charCode}));for(h=1;h<v.length;h++)if(v[h-1].charCode===v[h].charCode){v.splice(h,1);h--}return{platformId:o.platformId,encodingId:o.encodingId,mappings:v,hasShortCmap:y}}(x.cmap,t,this.isSymbolicFont,o.hasEncoding),Z=J.platformId,Q=J.encodingId,ee=J.mappings,te=ee.length;if(o.hasEncoding&&(3===Z&&1===Q||1===Z&&0===Q)||-1===Z&&-1===Q&&(0,s.getEncoding)(o.baseEncodingName)){var ae=[];"MacRomanEncoding"!==o.baseEncodingName&&"WinAnsiEncoding"!==o.baseEncodingName||(ae=(0,s.getEncoding)(o.baseEncodingName));var re=(0,n.getGlyphsUnicode)();for(X=0;X<256;X++){var ie,ne;if(ie=this.differences&&X in this.differences?this.differences[X]:X in ae&&""!==ae[X]?ae[X]:s.StandardEncoding[X]){ne=v(ie,re);var se;3===Z&&1===Q?se=re[ne]:1===Z&&0===Q&&(se=s.MacRomanEncoding.indexOf(ne));var oe=!1;for(let e=0;e<te;++e)if(ee[e].charCode===se){V[X]=ee[e].glyphId;oe=!0;break}if(!oe&&o.glyphNames){var ce=o.glyphNames.indexOf(ie);-1===ce&&ne!==ie&&(ce=o.glyphNames.indexOf(ne));ce>0&&K(ce)&&(V[X]=ce)}}}}else if(0===Z&&0===Q)for(let e=0;e<te;++e)V[ee[e].charCode]=ee[e].glyphId;else for(let e=0;e<te;++e){X=ee[e].charCode;3===Z&&X>=61440&&X<=61695&&(X&=255);V[X]=ee[e].glyphId}}0===V.length&&(V[0]=0);let le=R-1;U||(le=0);var he=O(V,K,le);this.toFontChar=he.toFontChar;x.cmap={tag:"cmap",data:P(he.charCodeToGlyphId,R)};x["OS/2"]&&function(e){var t=new d.Stream(e.data),a=t.getUint16();t.getBytes(60);var r=t.getUint16();if(a<4&&768&r)return!1;if(t.getUint16()>t.getUint16())return!1;t.getBytes(6);if(0===t.getUint16())return!1;e.data[8]=e.data[9]=0;return!0}(x["OS/2"])||(x["OS/2"]={tag:"OS/2",data:B(o,he.charCodeToGlyphId,W)});if(!E)try{F=new d.Stream(x["CFF "].data);A=new i.CFFParser(F,o,!0).parse();A.duplicateFirstGlyph();var ue=new i.CFFCompiler(A);x["CFF "].data=ue.compile()}catch(e){(0,r.warn)("Failed to compile font "+o.loadedName)}if(x.name){var de=y(x.name);x.name.data=N(e,de)}else x.name={tag:"name",data:N(this.name)};var fe=new C(S.version);for(var ge in x)fe.addTable(ge,x[ge].data);return fe.toArray()},convert:function(e,t,a){a.fixedPitch=!1;a.builtInEncoding&&function(e,t){if(!e.hasIncludedToUnicodeMap&&!(e.hasEncoding||t===e.defaultEncoding||e.toUnicode instanceof S)){var a=[],r=(0,n.getGlyphsUnicode)();for(var i in t){var s=t[i],o=(0,c.getUnicodeForGlyph)(s,r);-1!==o&&(a[i]=String.fromCharCode(o))}e.toUnicode.amend(a)}}(a,a.builtInEncoding);let i=1;t instanceof T&&(i=t.numGlyphs-1);var o=t.getGlyphMapping(a),l=O(o,t.hasGlyphId.bind(t),i);this.toFontChar=l.toFontChar;var h=t.numGlyphs;function u(e,t){var a=null;for(var r in e)if(t===e[r]){a||(a=[]);a.push(0|r)}return a}function d(e,t){for(var a in e)if(t===e[a])return 0|a;l.charCodeToGlyphId[l.nextAvailableFontCharCode]=t;return l.nextAvailableFontCharCode++}var f=t.seacs;if(f&&f.length){var g=a.fontMatrix||r.FONT_IDENTITY_MATRIX,m=t.getCharset(),p=Object.create(null);for(var b in f){var y=f[b|=0],v=s.StandardEncoding[y[2]],w=s.StandardEncoding[y[3]],k=m.indexOf(v),I=m.indexOf(w);if(!(k<0||I<0)){var F={x:y[0]*g[0]+y[1]*g[2]+g[4],y:y[0]*g[1]+y[1]*g[3]+g[5]},E=u(o,b);if(E)for(var M=0,L=E.length;M<L;M++){var R=E[M],U=l.charCodeToGlyphId,q=d(U,k),j=d(U,I);p[R]={baseFontCharCode:q,accentFontCharCode:j,accentOffset:F}}}}a.seacMap=p}var _=1/(a.fontMatrix||r.FONT_IDENTITY_MATRIX)[0],z=new C("OTTO");z.addTable("CFF ",t.data);z.addTable("OS/2",B(a,l.charCodeToGlyphId));z.addTable("cmap",P(l.charCodeToGlyphId,h));z.addTable("head","\0\0\0\0\0\0\0\0\0\0_<õ\0\0"+A(_)+"\0\0\0\0ž\v~'\0\0\0\0ž\v~'\0\0"+A(a.descent)+"ÿ"+A(a.ascent)+x(a.italicAngle?2:0)+"\0\0\0\0\0\0\0");z.addTable("hhea","\0\0\0"+A(a.ascent)+A(a.descent)+"\0\0ÿÿ\0\0\0\0\0\0"+A(a.capHeight)+A(Math.tan(a.italicAngle)*a.xHeight)+"\0\0\0\0\0\0\0\0\0\0\0\0"+x(h));z.addTable("hmtx",function(){for(var e=t.charstrings,a=t.cff?t.cff.widths:null,r="\0\0\0\0",i=1,n=h;i<n;i++){var s=0;if(e){var o=e[i-1];s="width"in o?o.width:0}else a&&(s=Math.ceil(a[i]||0));r+=x(s)+x(0)}return r}());z.addTable("maxp","\0\0P\0"+x(h));z.addTable("name",N(e));z.addTable("post",D(a));return z.toArray()},get spaceWidth(){if("_shadowWidth"in this)return this._shadowWidth;for(var e,t=["space","minus","one","i","I"],a=0,r=t.length;a<r;a++){var i=t[a];if(i in this.widths){e=this.widths[i];break}var s=(0,n.getGlyphsUnicode)()[i],o=0;this.composite&&this.cMap.contains(s)&&(o=this.cMap.lookup(s));!o&&this.toUnicode&&(o=this.toUnicode.charCodeOf(s));o<=0&&(o=s);if(e=this.widths[o])break}e=e||this.defaultWidth;this._shadowWidth=e;return e},charToGlyph:function(e,t){var a,i,n,s=e;this.cMap&&this.cMap.contains(e)&&(s=this.cMap.lookup(e));i=this.widths[s];i=(0,r.isNum)(i)?i:this.defaultWidth;var o=this.vmetrics&&this.vmetrics[s];let l=this.toUnicode.get(e)||this.fallbackToUnicode.get(e)||e;"number"==typeof l&&(l=String.fromCharCode(l));var h=e in this.toFontChar;a=this.toFontChar[e]||e;if(this.missingFile){const t=this.differences[e]||this.defaultEncoding[e];".notdef"!==t&&""!==t||"Type1"!==this.type||(a=32);a=(0,c.mapSpecialUnicodeValues)(a)}this.isType3Font&&(n=a);var u=null;if(this.seacMap&&this.seacMap[e]){h=!0;var d=this.seacMap[e];a=d.baseFontCharCode;u={fontChar:String.fromCodePoint(d.accentFontCharCode),offset:d.accentOffset}}var f="number"==typeof a?String.fromCodePoint(a):"",g=this.glyphCache[e];if(!g||!g.matchesForCache(f,l,u,i,o,n,t,h)){g=new w(f,l,u,i,o,n,t,h);this.glyphCache[e]=g}return g},charsToGlyphs:function(e){var t,a,r,i=this.charsCache;if(i&&(t=i[e]))return t;i||(i=this.charsCache=Object.create(null));t=[];var n,s=e,o=0;if(this.cMap)for(var c=Object.create(null);o<e.length;){this.cMap.readCharCode(e,o,c);r=c.charcode;var l=c.length;o+=l;var h=1===l&&32===e.charCodeAt(o-1);a=this.charToGlyph(r,h);t.push(a)}else for(o=0,n=e.length;o<n;++o){r=e.charCodeAt(o);a=this.charToGlyph(r,32===r);t.push(a)}return i[s]=t},get glyphCacheValues(){return Object.values(this.glyphCache)}};return e}();t.Font=x;var A=function(){function e(e){this.error=e;this.loadedName="g_font_error";this.missingFile=!0}e.prototype={charsToGlyphs:function(){return[]},exportData:function(){return{error:this.error}}};return e}();t.ErrorFont=A;function I(e,t,a){var r,i,o,c=Object.create(null),l=!!(e.flags&m.Symbolic);if(e.baseEncodingName){o=(0,s.getEncoding)(e.baseEncodingName);for(i=0;i<o.length;i++){r=a.indexOf(o[i]);c[i]=r>=0?r:0}}else if(l)for(i in t)c[i]=t[i];else{o=s.StandardEncoding;for(i=0;i<o.length;i++){r=a.indexOf(o[i]);c[i]=r>=0?r:0}}var h,u=e.differences;if(u)for(i in u){var d=u[i];if(-1===(r=a.indexOf(d))){h||(h=(0,n.getGlyphsUnicode)());var f=v(d,h);f!==d&&(r=a.indexOf(f))}c[i]=r>=0?r:0}return c}var F=function(){function e(e,t,a){for(var r,i=e.length,n=t.length,s=i-n,o=a,c=!1;o<s;){r=0;for(;r<n&&e[o+r]===t[r];)r++;if(r>=n){o+=r;for(;o<i&&(0,l.isWhiteSpace)(e[o]);)o++;c=!0;break}o++}return{found:c,length:o}}function t(t,a,i){var n=i.length1,s=(i.length2,a.peekBytes(6)),o=128===s[0]&&1===s[1];if(o){a.skip(6);n=s[5]<<24|s[4]<<16|s[3]<<8|s[2]}var c=function(t,a){var i,n,s,o,c=[101,101,120,101,99],h=t.pos;try{n=(i=t.getBytes(a)).length}catch(e){if(e instanceof l.MissingDataException)throw e}if(n===a&&(s=e(i,c,a-2*c.length)).found&&s.length===a)return{stream:new d.Stream(i),length:a};(0,r.warn)('Invalid "Length1" property in Type1 font -- trying to recover.');t.pos=h;for(;;){if(0===(s=e(t.peekBytes(2048),c,0)).length)break;t.pos+=s.length;if(s.found){o=t.pos-h;break}}t.pos=h;if(o)return{stream:new d.Stream(t.getBytes(o)),length:o};(0,r.warn)('Unable to recover "Length1" property in Type1 font -- using as is.');return{stream:new d.Stream(t.getBytes(a)),length:a}}(a,n);new f.Type1Parser(c.stream,!1,!0).extractFontHeader(i);o&&(s=a.getBytes(6))[5]<<24|s[4]<<16|s[3]<<8|s[2];var h,u=(h=a.getBytes(),{stream:new d.Stream(h),length:h.length}),g=new f.Type1Parser(u.stream,!0,!0).extractFontProgram(i);for(var m in g.properties)i[m]=g.properties[m];var p=g.charstrings,b=this.getType2Charstrings(p),y=this.getType2Subrs(g.subrs);this.charstrings=p;this.data=this.wrap(t,b,this.charstrings,y,i);this.seacs=this.getSeacs(g.charstrings)}t.prototype={get numGlyphs(){return this.charstrings.length+1},getCharset:function(){for(var e=[".notdef"],t=this.charstrings,a=0;a<t.length;a++)e.push(t[a].glyphName);return e},getGlyphMapping:function(e){var t,a=this.charstrings,r=[".notdef"];for(t=0;t<a.length;t++)r.push(a[t].glyphName);var i=e.builtInEncoding;if(i){var n=Object.create(null);for(var s in i)(t=r.indexOf(i[s]))>=0&&(n[s]=t)}return I(e,n,r)},hasGlyphId:function(e){return!(e<0||e>=this.numGlyphs)&&(0===e||this.charstrings[e-1].charstring.length>0)},getSeacs:function(e){var t,a,r=[];for(t=0,a=e.length;t<a;t++){var i=e[t];i.seac&&(r[t+1]=i.seac)}return r},getType2Charstrings:function(e){for(var t=[],a=0,r=e.length;a<r;a++)t.push(e[a].charstring);return t},getType2Subrs:function(e){var t=0,a=e.length;t=a<1133?107:a<33769?1131:32768;var r,i=[];for(r=0;r<t;r++)i.push([11]);for(r=0;r<a;r++)i.push(e[r]);return i},wrap:function(e,t,a,r,n){var s=new i.CFF;s.header=new i.CFFHeader(1,0,4,4);s.names=[e];var o=new i.CFFTopDict;o.setByName("version",391);o.setByName("Notice",392);o.setByName("FullName",393);o.setByName("FamilyName",394);o.setByName("Weight",395);o.setByName("Encoding",null);o.setByName("FontMatrix",n.fontMatrix);o.setByName("FontBBox",n.bbox);o.setByName("charset",null);o.setByName("CharStrings",null);o.setByName("Private",null);s.topDict=o;var c=new i.CFFStrings;c.add("Version 0.11");c.add("See original notice");c.add(e);c.add(e);c.add("Medium");s.strings=c;s.globalSubrIndex=new i.CFFIndex;var l,h,u=t.length,d=[".notdef"];for(l=0;l<u;l++){const e=a[l].glyphName;-1===i.CFFStandardStrings.indexOf(e)&&c.add(e);d.push(e)}s.charset=new i.CFFCharset(!1,0,d);var f=new i.CFFIndex;f.add([139,14]);for(l=0;l<u;l++)f.add(t[l]);s.charStrings=f;var g=new i.CFFPrivateDict;g.setByName("Subrs",null);var m=["BlueValues","OtherBlues","FamilyBlues","FamilyOtherBlues","StemSnapH","StemSnapV","BlueShift","BlueFuzz","BlueScale","LanguageGroup","ExpansionFactor","ForceBold","StdHW","StdVW"];for(l=0,h=m.length;l<h;l++){var p=m[l];if(p in n.privateData){var b=n.privateData[p];if(Array.isArray(b))for(var y=b.length-1;y>0;y--)b[y]-=b[y-1];g.setByName(p,b)}}s.topDict.privateDict=g;var v=new i.CFFIndex;for(l=0,h=r.length;l<h;l++)v.add(r[l]);g.subrsIndex=v;return new i.CFFCompiler(s).compile()}};return t}(),T=function(){function e(e,t){this.properties=t;var a=new i.CFFParser(e,t,!0);this.cff=a.parse();this.cff.duplicateFirstGlyph();var n=new i.CFFCompiler(this.cff);this.seacs=this.cff.seacs;try{this.data=n.compile()}catch(a){(0,r.warn)("Failed to compile font "+t.loadedName);this.data=e}}e.prototype={get numGlyphs(){return this.cff.charStrings.count},getCharset:function(){return this.cff.charset.charset},getGlyphMapping:function(){var e,t,a=this.cff,r=this.properties,i=a.charset.charset;if(r.composite){e=Object.create(null);let s;if(a.isCIDFont)for(t=0;t<i.length;t++){var n=i[t];s=r.cMap.charCodeOf(n);e[s]=t}else for(t=0;t<a.charStrings.count;t++){s=r.cMap.charCodeOf(t);e[s]=t}return e}return e=I(r,a.encoding?a.encoding.encoding:null,i)},hasGlyphId:function(e){return this.cff.hasGlyphId(e)}};return e}()},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.CFFFDSelect=t.CFFCompiler=t.CFFPrivateDict=t.CFFTopDict=t.CFFCharset=t.CFFIndex=t.CFFStrings=t.CFFHeader=t.CFF=t.CFFParser=t.CFFStandardStrings=void 0;var r=a(2),i=a(29),n=a(30),s=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003","Black","Bold","Book","Light","Medium","Regular","Roman","Semibold"];t.CFFStandardStrings=s;var o=function(){var e=[null,{id:"hstem",min:2,stackClearing:!0,stem:!0},null,{id:"vstem",min:2,stackClearing:!0,stem:!0},{id:"vmoveto",min:1,stackClearing:!0},{id:"rlineto",min:2,resetStack:!0},{id:"hlineto",min:1,resetStack:!0},{id:"vlineto",min:1,resetStack:!0},{id:"rrcurveto",min:6,resetStack:!0},null,{id:"callsubr",min:1,undefStack:!0},{id:"return",min:0,undefStack:!0},null,null,{id:"endchar",min:0,stackClearing:!0},null,null,null,{id:"hstemhm",min:2,stackClearing:!0,stem:!0},{id:"hintmask",min:0,stackClearing:!0},{id:"cntrmask",min:0,stackClearing:!0},{id:"rmoveto",min:2,stackClearing:!0},{id:"hmoveto",min:1,stackClearing:!0},{id:"vstemhm",min:2,stackClearing:!0,stem:!0},{id:"rcurveline",min:8,resetStack:!0},{id:"rlinecurve",min:8,resetStack:!0},{id:"vvcurveto",min:4,resetStack:!0},{id:"hhcurveto",min:4,resetStack:!0},null,{id:"callgsubr",min:1,undefStack:!0},{id:"vhcurveto",min:4,resetStack:!0},{id:"hvcurveto",min:4,resetStack:!0}],t=[null,null,null,{id:"and",min:2,stackDelta:-1},{id:"or",min:2,stackDelta:-1},{id:"not",min:1,stackDelta:0},null,null,null,{id:"abs",min:1,stackDelta:0},{id:"add",min:2,stackDelta:-1,stackFn:function(e,t){e[t-2]=e[t-2]+e[t-1]}},{id:"sub",min:2,stackDelta:-1,stackFn:function(e,t){e[t-2]=e[t-2]-e[t-1]}},{id:"div",min:2,stackDelta:-1,stackFn:function(e,t){e[t-2]=e[t-2]/e[t-1]}},null,{id:"neg",min:1,stackDelta:0,stackFn:function(e,t){e[t-1]=-e[t-1]}},{id:"eq",min:2,stackDelta:-1},null,null,{id:"drop",min:1,stackDelta:-1},null,{id:"put",min:2,stackDelta:-2},{id:"get",min:1,stackDelta:0},{id:"ifelse",min:4,stackDelta:-3},{id:"random",min:0,stackDelta:1},{id:"mul",min:2,stackDelta:-1,stackFn:function(e,t){e[t-2]=e[t-2]*e[t-1]}},null,{id:"sqrt",min:1,stackDelta:0},{id:"dup",min:1,stackDelta:1},{id:"exch",min:2,stackDelta:0},{id:"index",min:2,stackDelta:0},{id:"roll",min:3,stackDelta:-2},null,null,null,{id:"hflex",min:7,resetStack:!0},{id:"flex",min:13,resetStack:!0},{id:"hflex1",min:9,resetStack:!0},{id:"flex1",min:11,resetStack:!0}];function a(e,t,a){this.bytes=e.getBytes();this.properties=t;this.seacAnalysisEnabled=!!a}a.prototype={parse:function(){var e=this.properties,t=new c;this.cff=t;var a=this.parseHeader(),r=this.parseIndex(a.endPos),i=this.parseIndex(r.endPos),n=this.parseIndex(i.endPos),s=this.parseIndex(n.endPos),o=this.parseDict(i.obj.get(0)),l=this.createDict(f,o,t.strings);t.header=a.obj;t.names=this.parseNameIndex(r.obj);t.strings=this.parseStringIndex(n.obj);t.topDict=l;t.globalSubrIndex=s.obj;this.parsePrivateDict(t.topDict);t.isCIDFont=l.hasName("ROS");var h=l.getByName("CharStrings"),u=this.parseIndex(h).obj,d=l.getByName("FontMatrix");d&&(e.fontMatrix=d);var g,m,p=l.getByName("FontBBox");if(p){e.ascent=Math.max(p[3],p[1]);e.descent=Math.min(p[1],p[3]);e.ascentScaled=!0}if(t.isCIDFont){for(var b=this.parseIndex(l.getByName("FDArray")).obj,y=0,v=b.count;y<v;++y){var w=b.get(y),k=this.createDict(f,this.parseDict(w),t.strings);this.parsePrivateDict(k);t.fdArray.push(k)}m=null;g=this.parseCharsets(l.getByName("charset"),u.count,t.strings,!0);t.fdSelect=this.parseFDSelect(l.getByName("FDSelect"),u.count)}else{g=this.parseCharsets(l.getByName("charset"),u.count,t.strings,!1);m=this.parseEncoding(l.getByName("Encoding"),e,t.strings,g.charset)}t.charset=g;t.encoding=m;var S=this.parseCharStrings({charStrings:u,localSubrIndex:l.privateDict.subrsIndex,globalSubrIndex:s.obj,fdSelect:t.fdSelect,fdArray:t.fdArray,privateDict:l.privateDict});t.charStrings=S.charStrings;t.seacs=S.seacs;t.widths=S.widths;return t},parseHeader:function(){for(var e=this.bytes,t=e.length,a=0;a<t&&1!==e[a];)++a;if(a>=t)throw new r.FormatError("Invalid CFF header");if(0!==a){(0,r.info)("cff data is shifted");e=e.subarray(a);this.bytes=e}var i=e[0],n=e[1],s=e[2],o=e[3];return{obj:new l(i,n,s,o),endPos:s}},parseDict:function(e){var t=0;function a(){var a=e[t++];if(30===a)return function(){var a="";const r=["0","1","2","3","4","5","6","7","8","9",".","E","E-",null,"-"];var i=e.length;for(;t<i;){var n=e[t++],s=n>>4,o=15&n;if(15===s)break;a+=r[s];if(15===o)break;a+=r[o]}return parseFloat(a)}();if(28===a)return a=((a=e[t++])<<24|e[t++]<<16)>>16;if(29===a)return a=(a=(a=(a=e[t++])<<8|e[t++])<<8|e[t++])<<8|e[t++];if(a>=32&&a<=246)return a-139;if(a>=247&&a<=250)return 256*(a-247)+e[t++]+108;if(a>=251&&a<=254)return-256*(a-251)-e[t++]-108;(0,r.warn)('CFFParser_parseDict: "'+a+'" is a reserved command.');return NaN}var i=[],n=[];t=0;for(var s=e.length;t<s;){var o=e[t];if(o<=21){12===o&&(o=o<<8|e[++t]);n.push([o,i]);i=[];++t}else i.push(a())}return n},parseIndex:function(e){var t,a,r=new u,i=this.bytes,n=i[e++]<<8|i[e++],s=[],o=e;if(0!==n){var c=i[e++],l=e+(n+1)*c-1;for(t=0,a=n+1;t<a;++t){for(var h=0,d=0;d<c;++d){h<<=8;h+=i[e++]}s.push(l+h)}o=s[n]}for(t=0,a=s.length-1;t<a;++t){var f=s[t],g=s[t+1];r.add(i.subarray(f,g))}return{obj:r,endPos:o}},parseNameIndex:function(e){for(var t=[],a=0,i=e.count;a<i;++a){var n=e.get(a);t.push((0,r.bytesToString)(n))}return t},parseStringIndex:function(e){for(var t=new h,a=0,i=e.count;a<i;++a){var n=e.get(a);t.add((0,r.bytesToString)(n))}return t},createDict:function(e,t,a){for(var r=new e(a),i=0,n=t.length;i<n;++i){var s=t[i],o=s[0],c=s[1];r.setByKey(o,c)}return r},parseCharString:function(a,i,n,s){if(!i||a.callDepth>10)return!1;for(var o=a.stackSize,c=a.stack,l=i.length,h=0;h<l;){var u=i[h++],d=null;if(12===u){var f=i[h++];if(0===f){i[h-2]=139;i[h-1]=22;o=0}else d=t[f]}else if(28===u){c[o]=(i[h]<<24|i[h+1]<<16)>>16;h+=2;o++}else if(14===u){if(o>=4){o-=4;if(this.seacAnalysisEnabled){a.seac=c.slice(o,o+4);return!1}}d=e[u]}else if(u>=32&&u<=246){c[o]=u-139;o++}else if(u>=247&&u<=254){c[o]=u<251?(u-247<<8)+i[h]+108:-(u-251<<8)-i[h]-108;h++;o++}else if(255===u){c[o]=(i[h]<<24|i[h+1]<<16|i[h+2]<<8|i[h+3])/65536;h+=4;o++}else if(19===u||20===u){a.hints+=o>>1;h+=a.hints+7>>3;o%=2;d=e[u]}else{if(10===u||29===u){var g;if(!(g=10===u?n:s)){d=e[u];(0,r.warn)("Missing subrsIndex for "+d.id);return!1}var m=32768;g.count<1240?m=107:g.count<33900&&(m=1131);var p=c[--o]+m;if(p<0||p>=g.count||isNaN(p)){d=e[u];(0,r.warn)("Out of bounds subrIndex for "+d.id);return!1}a.stackSize=o;a.callDepth++;if(!this.parseCharString(a,g.get(p),n,s))return!1;a.callDepth--;o=a.stackSize;continue}if(11===u){a.stackSize=o;return!0}d=e[u]}if(d){if(d.stem){a.hints+=o>>1;if(3===u||23===u)a.hasVStems=!0;else if(a.hasVStems&&(1===u||18===u)){(0,r.warn)("CFF stem hints are in wrong order");i[h-1]=1===u?3:23}}if("min"in d&&!a.undefStack&&o<d.min){(0,r.warn)("Not enough parameters for "+d.id+"; actual: "+o+", expected: "+d.min);return!1}if(a.firstStackClearing&&d.stackClearing){a.firstStackClearing=!1;(o-=d.min)>=2&&d.stem?o%=2:o>1&&(0,r.warn)("Found too many parameters for stack-clearing command");o>0&&c[o-1]>=0&&(a.width=c[o-1])}if("stackDelta"in d){"stackFn"in d&&d.stackFn(c,o);o+=d.stackDelta}else if(d.stackClearing)o=0;else if(d.resetStack){o=0;a.undefStack=!1}else if(d.undefStack){o=0;a.undefStack=!0;a.firstStackClearing=!1}}}a.stackSize=o;return!0},parseCharStrings({charStrings:e,localSubrIndex:t,globalSubrIndex:a,fdSelect:i,fdArray:n,privateDict:s}){for(var o=[],c=[],l=e.count,h=0;h<l;h++){var u=e.get(h),d={callDepth:0,stackSize:0,stack:[],undefStack:!0,hints:0,firstStackClearing:!0,seac:null,width:null,hasVStems:!1},f=!0,g=null,m=s;if(i&&n.length){var p=i.getFDIndex(h);if(-1===p){(0,r.warn)("Glyph index is not in fd select.");f=!1}if(p>=n.length){(0,r.warn)("Invalid fd index for glyph index.");f=!1}f&&(g=(m=n[p].privateDict).subrsIndex)}else t&&(g=t);f&&(f=this.parseCharString(d,u,g,a));if(null!==d.width){const e=m.getByName("nominalWidthX");c[h]=e+d.width}else{const e=m.getByName("defaultWidthX");c[h]=e}null!==d.seac&&(o[h]=d.seac);f||e.set(h,new Uint8Array([14]))}return{charStrings:e,seacs:o,widths:c}},emptyPrivateDictionary:function(e){var t=this.createDict(g,[],e.strings);e.setByKey(18,[0,0]);e.privateDict=t},parsePrivateDict:function(e){if(e.hasName("Private")){var t=e.getByName("Private");if(Array.isArray(t)&&2===t.length){var a=t[0],r=t[1];if(0===a||r>=this.bytes.length)this.emptyPrivateDictionary(e);else{var i=r+a,n=this.bytes.subarray(r,i),s=this.parseDict(n),o=this.createDict(g,s,e.strings);e.privateDict=o;if(o.getByName("Subrs")){var c=o.getByName("Subrs"),l=r+c;if(0===c||l>=this.bytes.length)this.emptyPrivateDictionary(e);else{var h=this.parseIndex(l);o.subrsIndex=h.obj}}}}else e.removeByName("Private")}else this.emptyPrivateDictionary(e)},parseCharsets:function(e,t,a,n){if(0===e)return new p(!0,m.ISO_ADOBE,i.ISOAdobeCharset);if(1===e)return new p(!0,m.EXPERT,i.ExpertCharset);if(2===e)return new p(!0,m.EXPERT_SUBSET,i.ExpertSubsetCharset);var s,o,c,l=this.bytes,h=e,u=l[e++],d=[".notdef"];t-=1;switch(u){case 0:for(c=0;c<t;c++){s=l[e++]<<8|l[e++];d.push(n?s:a.get(s))}break;case 1:for(;d.length<=t;){s=l[e++]<<8|l[e++];o=l[e++];for(c=0;c<=o;c++)d.push(n?s++:a.get(s++))}break;case 2:for(;d.length<=t;){s=l[e++]<<8|l[e++];o=l[e++]<<8|l[e++];for(c=0;c<=o;c++)d.push(n?s++:a.get(s++))}break;default:throw new r.FormatError("Unknown charset format")}var f=e,g=l.subarray(h,f);return new p(!1,u,d,g)},parseEncoding:function(e,t,a,i){var s,o,c,l=Object.create(null),h=this.bytes,u=!1,d=null;if(0===e||1===e){u=!0;s=e;var f=e?n.ExpertEncoding:n.StandardEncoding;for(o=0,c=i.length;o<c;o++){var g=f.indexOf(i[o]);-1!==g&&(l[g]=o)}}else{var m=e;switch(127&(s=h[e++])){case 0:var p=h[e++];for(o=1;o<=p;o++)l[h[e++]]=o;break;case 1:var y=h[e++],v=1;for(o=0;o<y;o++)for(var w=h[e++],k=h[e++],S=w;S<=w+k;S++)l[S]=v++;break;default:throw new r.FormatError(`Unknown encoding format: ${s} in CFF`)}var C=e;if(128&s){h[m]&=127;!function(){var t=h[e++];for(o=0;o<t;o++){var r=h[e++],n=(h[e++]<<8)+(255&h[e++]);l[r]=i.indexOf(a.get(n))}}()}d=h.subarray(m,C)}return new b(u,s&=127,l,d)},parseFDSelect:function(e,t){var a,i=this.bytes,n=i[e++],s=[];switch(n){case 0:for(a=0;a<t;++a){var o=i[e++];s.push(o)}break;case 3:var c=i[e++]<<8|i[e++];for(a=0;a<c;++a){var l=i[e++]<<8|i[e++];if(0===a&&0!==l){(0,r.warn)("parseFDSelect: The first range must have a first GID of 0 -- trying to recover.");l=0}for(var h=i[e++],u=i[e]<<8|i[e+1],d=l;d<u;++d)s.push(h)}e+=2;break;default:throw new r.FormatError(`parseFDSelect: Unknown format "${n}".`)}if(s.length!==t)throw new r.FormatError("parseFDSelect: Invalid font data.");return new y(n,s)}};return a}();t.CFFParser=o;var c=function(){function e(){this.header=null;this.names=[];this.topDict=null;this.strings=new h;this.globalSubrIndex=null;this.encoding=null;this.charset=null;this.charStrings=null;this.fdArray=[];this.fdSelect=null;this.isCIDFont=!1}e.prototype={duplicateFirstGlyph:function(){if(this.charStrings.count>=65535)(0,r.warn)("Not enough space in charstrings to duplicate first glyph.");else{var e=this.charStrings.get(0);this.charStrings.add(e);this.isCIDFont&&this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0])}},hasGlyphId:function(e){return!(e<0||e>=this.charStrings.count)&&this.charStrings.get(e).length>0}};return e}();t.CFF=c;var l=function(e,t,a,r){this.major=e;this.minor=t;this.hdrSize=a;this.offSize=r};t.CFFHeader=l;var h=function(){function e(){this.strings=[]}e.prototype={get:function(e){return e>=0&&e<=390?s[e]:e-391<=this.strings.length?this.strings[e-391]:s[0]},getSID:function(e){let t=s.indexOf(e);if(-1!==t)return t;t=this.strings.indexOf(e);return-1!==t?t+391:-1},add:function(e){this.strings.push(e)},get count(){return this.strings.length}};return e}();t.CFFStrings=h;var u=function(){function e(){this.objects=[];this.length=0}e.prototype={add:function(e){this.length+=e.length;this.objects.push(e)},set:function(e,t){this.length+=t.length-this.objects[e].length;this.objects[e]=t},get:function(e){return this.objects[e]},get count(){return this.objects.length}};return e}();t.CFFIndex=u;var d=function(){function e(e,t){this.keyToNameMap=e.keyToNameMap;this.nameToKeyMap=e.nameToKeyMap;this.defaults=e.defaults;this.types=e.types;this.opcodes=e.opcodes;this.order=e.order;this.strings=t;this.values=Object.create(null)}e.prototype={setByKey:function(e,t){if(!(e in this.keyToNameMap))return!1;var a=t.length;if(0===a)return!0;for(var i=0;i<a;i++)if(isNaN(t[i])){(0,r.warn)('Invalid CFFDict value: "'+t+'" for key "'+e+'".');return!0}var n=this.types[e];"num"!==n&&"sid"!==n&&"offset"!==n||(t=t[0]);this.values[e]=t;return!0},setByName:function(e,t){if(!(e in this.nameToKeyMap))throw new r.FormatError(`Invalid dictionary name "${e}"`);this.values[this.nameToKeyMap[e]]=t},hasName:function(e){return this.nameToKeyMap[e]in this.values},getByName:function(e){if(!(e in this.nameToKeyMap))throw new r.FormatError(`Invalid dictionary name ${e}"`);var t=this.nameToKeyMap[e];return t in this.values?this.values[t]:this.defaults[t]},removeByName:function(e){delete this.values[this.nameToKeyMap[e]]}};e.createTables=function(e){for(var t={keyToNameMap:{},nameToKeyMap:{},defaults:{},types:{},opcodes:{},order:[]},a=0,r=e.length;a<r;++a){var i=e[a],n=Array.isArray(i[0])?(i[0][0]<<8)+i[0][1]:i[0];t.keyToNameMap[n]=i[1];t.nameToKeyMap[i[1]]=n;t.types[n]=i[2];t.defaults[n]=i[3];t.opcodes[n]=Array.isArray(i[0])?i[0]:[i[0]];t.order.push(n)}return t};return e}(),f=function(){var e=[[[12,30],"ROS",["sid","sid","num"],null],[[12,20],"SyntheticBase","num",null],[0,"version","sid",null],[1,"Notice","sid",null],[[12,0],"Copyright","sid",null],[2,"FullName","sid",null],[3,"FamilyName","sid",null],[4,"Weight","sid",null],[[12,1],"isFixedPitch","num",0],[[12,2],"ItalicAngle","num",0],[[12,3],"UnderlinePosition","num",-100],[[12,4],"UnderlineThickness","num",50],[[12,5],"PaintType","num",0],[[12,6],"CharstringType","num",2],[[12,7],"FontMatrix",["num","num","num","num","num","num"],[.001,0,0,.001,0,0]],[13,"UniqueID","num",null],[5,"FontBBox",["num","num","num","num"],[0,0,0,0]],[[12,8],"StrokeWidth","num",0],[14,"XUID","array",null],[15,"charset","offset",0],[16,"Encoding","offset",0],[17,"CharStrings","offset",0],[18,"Private",["offset","offset"],null],[[12,21],"PostScript","sid",null],[[12,22],"BaseFontName","sid",null],[[12,23],"BaseFontBlend","delta",null],[[12,31],"CIDFontVersion","num",0],[[12,32],"CIDFontRevision","num",0],[[12,33],"CIDFontType","num",0],[[12,34],"CIDCount","num",8720],[[12,35],"UIDBase","num",null],[[12,37],"FDSelect","offset",null],[[12,36],"FDArray","offset",null],[[12,38],"FontName","sid",null]],t=null;function a(a){null===t&&(t=d.createTables(e));d.call(this,t,a);this.privateDict=null}a.prototype=Object.create(d.prototype);return a}();t.CFFTopDict=f;var g=function(){var e=[[6,"BlueValues","delta",null],[7,"OtherBlues","delta",null],[8,"FamilyBlues","delta",null],[9,"FamilyOtherBlues","delta",null],[[12,9],"BlueScale","num",.039625],[[12,10],"BlueShift","num",7],[[12,11],"BlueFuzz","num",1],[10,"StdHW","num",null],[11,"StdVW","num",null],[[12,12],"StemSnapH","delta",null],[[12,13],"StemSnapV","delta",null],[[12,14],"ForceBold","num",0],[[12,17],"LanguageGroup","num",0],[[12,18],"ExpansionFactor","num",.06],[[12,19],"initialRandomSeed","num",0],[20,"defaultWidthX","num",0],[21,"nominalWidthX","num",0],[19,"Subrs","offset",null]],t=null;function a(a){null===t&&(t=d.createTables(e));d.call(this,t,a);this.subrsIndex=null}a.prototype=Object.create(d.prototype);return a}();t.CFFPrivateDict=g;var m={ISO_ADOBE:0,EXPERT:1,EXPERT_SUBSET:2},p=function(e,t,a,r){this.predefined=e;this.format=t;this.charset=a;this.raw=r};t.CFFCharset=p;var b=function(e,t,a,r){this.predefined=e;this.format=t;this.encoding=a;this.raw=r},y=function(){function e(e,t){this.format=e;this.fdSelect=t}e.prototype={getFDIndex:function(e){return e<0||e>=this.fdSelect.length?-1:this.fdSelect[e]}};return e}();t.CFFFDSelect=y;var v=function(){function e(){this.offsets=Object.create(null)}e.prototype={isTracking:function(e){return e in this.offsets},track:function(e,t){if(e in this.offsets)throw new r.FormatError(`Already tracking location of ${e}`);this.offsets[e]=t},offset:function(e){for(var t in this.offsets)this.offsets[t]+=e},setEntryLocation:function(e,t,a){if(!(e in this.offsets))throw new r.FormatError(`Not tracking location of ${e}`);for(var i=a.data,n=this.offsets[e],s=0,o=t.length;s<o;++s){var c=5*s+n,l=c+1,h=c+2,u=c+3,d=c+4;if(29!==i[c]||0!==i[l]||0!==i[h]||0!==i[u]||0!==i[d])throw new r.FormatError("writing to an offset that is not empty");var f=t[s];i[c]=29;i[l]=f>>24&255;i[h]=f>>16&255;i[u]=f>>8&255;i[d]=255&f}}};return e}(),w=function(){function e(e){this.cff=e}e.prototype={compile:function(){var e=this.cff,t={data:[],length:0,add:function(e){this.data=this.data.concat(e);this.length=this.data.length}},a=this.compileHeader(e.header);t.add(a);var i=this.compileNameIndex(e.names);t.add(i);if(e.isCIDFont&&e.topDict.hasName("FontMatrix")){var n=e.topDict.getByName("FontMatrix");e.topDict.removeByName("FontMatrix");for(var s=0,o=e.fdArray.length;s<o;s++){var c=e.fdArray[s],l=n.slice(0);c.hasName("FontMatrix")&&(l=r.Util.transform(l,c.getByName("FontMatrix")));c.setByName("FontMatrix",l)}}e.topDict.setByName("charset",0);var h=this.compileTopDicts([e.topDict],t.length,e.isCIDFont);t.add(h.output);var u=h.trackers[0],d=this.compileStringIndex(e.strings.strings);t.add(d);var f=this.compileIndex(e.globalSubrIndex);t.add(f);if(e.encoding&&e.topDict.hasName("Encoding"))if(e.encoding.predefined)u.setEntryLocation("Encoding",[e.encoding.format],t);else{var g=this.compileEncoding(e.encoding);u.setEntryLocation("Encoding",[t.length],t);t.add(g)}var m=this.compileCharset(e.charset,e.charStrings.count,e.strings,e.isCIDFont);u.setEntryLocation("charset",[t.length],t);t.add(m);var p=this.compileCharStrings(e.charStrings);u.setEntryLocation("CharStrings",[t.length],t);t.add(p);if(e.isCIDFont){u.setEntryLocation("FDSelect",[t.length],t);var b=this.compileFDSelect(e.fdSelect);t.add(b);h=this.compileTopDicts(e.fdArray,t.length,!0);u.setEntryLocation("FDArray",[t.length],t);t.add(h.output);var y=h.trackers;this.compilePrivateDicts(e.fdArray,y,t)}this.compilePrivateDicts([e.topDict],[u],t);t.add([0]);return t.data},encodeNumber:function(e){return parseFloat(e)!==parseInt(e,10)||isNaN(e)?this.encodeFloat(e):this.encodeInteger(e)},encodeFloat:function(e){var t=e.toString(),a=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(t);if(a){var r=parseFloat("1e"+((a[2]?+a[2]:0)+a[1].length));t=(Math.round(e*r)/r).toString()}var i,n,s="";for(i=0,n=t.length;i<n;++i){var o=t[i];s+="e"===o?"-"===t[++i]?"c":"b":"."===o?"a":"-"===o?"e":o}var c=[30];for(i=0,n=(s+=1&s.length?"f":"ff").length;i<n;i+=2)c.push(parseInt(s.substring(i,i+2),16));return c},encodeInteger:function(e){return e>=-107&&e<=107?[e+139]:e>=108&&e<=1131?[247+((e-=108)>>8),255&e]:e>=-1131&&e<=-108?[251+((e=-e-108)>>8),255&e]:e>=-32768&&e<=32767?[28,e>>8&255,255&e]:[29,e>>24&255,e>>16&255,e>>8&255,255&e]},compileHeader:function(e){return[e.major,e.minor,e.hdrSize,e.offSize]},compileNameIndex:function(e){for(var t=new u,a=0,i=e.length;a<i;++a){for(var n=e[a],s=Math.min(n.length,127),o=new Array(s),c=0;c<s;c++){var l=n[c];(l<"!"||l>"~"||"["===l||"]"===l||"("===l||")"===l||"{"===l||"}"===l||"<"===l||">"===l||"/"===l||"%"===l)&&(l="_");o[c]=l}""===(o=o.join(""))&&(o="Bad_Font_Name");t.add((0,r.stringToBytes)(o))}return this.compileIndex(t)},compileTopDicts:function(e,t,a){for(var r=[],i=new u,n=0,s=e.length;n<s;++n){var o=e[n];if(a){o.removeByName("CIDFontVersion");o.removeByName("CIDFontRevision");o.removeByName("CIDFontType");o.removeByName("CIDCount");o.removeByName("UIDBase")}var c=new v,l=this.compileDict(o,c);r.push(c);i.add(l);c.offset(t)}return{trackers:r,output:i=this.compileIndex(i,r)}},compilePrivateDicts:function(e,t,a){for(var i=0,n=e.length;i<n;++i){var s=e[i],o=s.privateDict;if(!o||!s.hasName("Private"))throw new r.FormatError("There must be a private dictionary.");var c=new v,l=this.compileDict(o,c),h=a.length;c.offset(h);l.length||(h=0);t[i].setEntryLocation("Private",[l.length,h],a);a.add(l);if(o.subrsIndex&&o.hasName("Subrs")){var u=this.compileIndex(o.subrsIndex);c.setEntryLocation("Subrs",[l.length],a);a.add(u)}}},compileDict:function(e,t){for(var a=[],i=e.order,n=0;n<i.length;++n){var s=i[n];if(s in e.values){var o=e.values[s],c=e.types[s];Array.isArray(c)||(c=[c]);Array.isArray(o)||(o=[o]);if(0!==o.length){for(var l=0,h=c.length;l<h;++l){var u=c[l],d=o[l];switch(u){case"num":case"sid":a=a.concat(this.encodeNumber(d));break;case"offset":var f=e.keyToNameMap[s];t.isTracking(f)||t.track(f,a.length);a=a.concat([29,0,0,0,0]);break;case"array":case"delta":a=a.concat(this.encodeNumber(d));for(var g=1,m=o.length;g<m;++g)a=a.concat(this.encodeNumber(o[g]));break;default:throw new r.FormatError(`Unknown data type of ${u}`)}}a=a.concat(e.opcodes[s])}}}return a},compileStringIndex:function(e){for(var t=new u,a=0,i=e.length;a<i;++a)t.add((0,r.stringToBytes)(e[a]));return this.compileIndex(t)},compileGlobalSubrIndex:function(){var e=this.cff.globalSubrIndex;this.out.writeByteArray(this.compileIndex(e))},compileCharStrings:function(e){for(var t=new u,a=0;a<e.count;a++){var r=e.get(a);0!==r.length?t.add(r):t.add(new Uint8Array([139,14]))}return this.compileIndex(t)},compileCharset:function(e,t,a,i){let n;const s=t-1;if(i)n=new Uint8Array([2,0,0,s>>8&255,255&s]);else{n=new Uint8Array(1+2*s);n[0]=0;let t=0;const i=e.charset.length;let o=!1;for(let s=1;s<n.length;s+=2){let c=0;if(t<i){const i=e.charset[t++];c=a.getSID(i);if(-1===c){c=0;if(!o){o=!0;(0,r.warn)(`Couldn't find ${i} in CFF strings`)}}}n[s]=c>>8&255;n[s+1]=255&c}}return this.compileTypedArray(n)},compileEncoding:function(e){return this.compileTypedArray(e.raw)},compileFDSelect:function(e){const t=e.format;let a,r;switch(t){case 0:a=new Uint8Array(1+e.fdSelect.length);a[0]=t;for(r=0;r<e.fdSelect.length;r++)a[r+1]=e.fdSelect[r];break;case 3:const i=0;let n=e.fdSelect[0];const s=[t,0,0,i>>8&255,255&i,n];for(r=1;r<e.fdSelect.length;r++){const t=e.fdSelect[r];if(t!==n){s.push(r>>8&255,255&r,t);n=t}}const o=(s.length-3)/3;s[1]=o>>8&255;s[2]=255&o;s.push(r>>8&255,255&r);a=new Uint8Array(s)}return this.compileTypedArray(a)},compileTypedArray:function(e){for(var t=[],a=0,r=e.length;a<r;++a)t[a]=e[a];return t},compileIndex:function(e,t){t=t||[];var a=e.objects,r=a.length;if(0===r)return[0,0,0];var i,n,s=[r>>8&255,255&r],o=1;for(i=0;i<r;++i)o+=a[i].length;n=o<256?1:o<65536?2:o<16777216?3:4;s.push(n);var c=1;for(i=0;i<r+1;i++){1===n?s.push(255&c):2===n?s.push(c>>8&255,255&c):3===n?s.push(c>>16&255,c>>8&255,255&c):s.push(c>>>24&255,c>>16&255,c>>8&255,255&c);a[i]&&(c+=a[i].length)}for(i=0;i<r;i++){t[i]&&t[i].offset(s.length);for(var l=0,h=a[i].length;l<h;l++)s.push(a[i][l])}return s}};return e}();t.CFFCompiler=w},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.ExpertSubsetCharset=t.ExpertCharset=t.ISOAdobeCharset=void 0;t.ISOAdobeCharset=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron"];t.ExpertCharset=[".notdef","space","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","fi","fl","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"];t.ExpertSubsetCharset=[".notdef","space","dollaroldstyle","dollarsuperior","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","fi","fl","ffi","ffl","parenleftinferior","parenrightinferior","hyphensuperior","colonmonetary","onefitted","rupiah","centoldstyle","figuredash","hypheninferior","onequarter","onehalf","threequarters","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior"]},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getEncoding=function(e){switch(e){case"WinAnsiEncoding":return o;case"StandardEncoding":return s;case"MacRomanEncoding":return n;case"SymbolSetEncoding":return c;case"ZapfDingbatsEncoding":return l;case"ExpertEncoding":return r;case"MacExpertEncoding":return i;default:return null}};t.ExpertEncoding=t.ZapfDingbatsEncoding=t.SymbolSetEncoding=t.MacRomanEncoding=t.StandardEncoding=t.WinAnsiEncoding=void 0;const r=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclamsmall","Hungarumlautsmall","","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","","asuperior","bsuperior","centsuperior","dsuperior","esuperior","","","","isuperior","","","lsuperior","msuperior","nsuperior","osuperior","","","rsuperior","ssuperior","tsuperior","","ff","fi","fl","ffi","ffl","parenleftinferior","","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdownsmall","centoldstyle","Lslashsmall","","","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","","Dotaccentsmall","","","Macronsmall","","","figuredash","hypheninferior","","","Ogoneksmall","Ringsmall","Cedillasmall","","","","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","","","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"];t.ExpertEncoding=r;const i=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclamsmall","Hungarumlautsmall","centoldstyle","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","","threequartersemdash","","questionsmall","","","","","Ethsmall","","","onequarter","onehalf","threequarters","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","","","","","","","ff","fi","fl","ffi","ffl","parenleftinferior","","parenrightinferior","Circumflexsmall","hypheninferior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","","","asuperior","centsuperior","","","","","Aacutesmall","Agravesmall","Acircumflexsmall","Adieresissmall","Atildesmall","Aringsmall","Ccedillasmall","Eacutesmall","Egravesmall","Ecircumflexsmall","Edieresissmall","Iacutesmall","Igravesmall","Icircumflexsmall","Idieresissmall","Ntildesmall","Oacutesmall","Ogravesmall","Ocircumflexsmall","Odieresissmall","Otildesmall","Uacutesmall","Ugravesmall","Ucircumflexsmall","Udieresissmall","","eightsuperior","fourinferior","threeinferior","sixinferior","eightinferior","seveninferior","Scaronsmall","","centinferior","twoinferior","","Dieresissmall","","Caronsmall","osuperior","fiveinferior","","commainferior","periodinferior","Yacutesmall","","dollarinferior","","","Thornsmall","","nineinferior","zeroinferior","Zcaronsmall","AEsmall","Oslashsmall","questiondownsmall","oneinferior","Lslashsmall","","","","","","","Cedillasmall","","","","","","OEsmall","figuredash","hyphensuperior","","","","","exclamdownsmall","","Ydieresissmall","","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","ninesuperior","zerosuperior","","esuperior","rsuperior","tsuperior","","","isuperior","ssuperior","dsuperior","","","","","","lsuperior","Ogoneksmall","Brevesmall","Macronsmall","bsuperior","nsuperior","msuperior","commasuperior","periodsuperior","Dotaccentsmall","Ringsmall","","","",""],n=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","space","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron"];t.MacRomanEncoding=n;const s=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","","endash","dagger","daggerdbl","periodcentered","","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","","questiondown","","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","","ring","cedilla","","hungarumlaut","ogonek","caron","emdash","","","","","","","","","","","","","","","","","AE","","ordfeminine","","","","","Lslash","Oslash","OE","ordmasculine","","","","","","ae","","","","dotlessi","","","lslash","oslash","oe","germandbls","","","",""];t.StandardEncoding=s;const o=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","bullet","Euro","bullet","quotesinglbase","florin","quotedblbase","ellipsis","dagger","daggerdbl","circumflex","perthousand","Scaron","guilsinglleft","OE","bullet","Zcaron","bullet","bullet","quoteleft","quoteright","quotedblleft","quotedblright","bullet","endash","emdash","tilde","trademark","scaron","guilsinglright","oe","bullet","zcaron","Ydieresis","space","exclamdown","cent","sterling","currency","yen","brokenbar","section","dieresis","copyright","ordfeminine","guillemotleft","logicalnot","hyphen","registered","macron","degree","plusminus","twosuperior","threesuperior","acute","mu","paragraph","periodcentered","cedilla","onesuperior","ordmasculine","guillemotright","onequarter","onehalf","threequarters","questiondown","Agrave","Aacute","Acircumflex","Atilde","Adieresis","Aring","AE","Ccedilla","Egrave","Eacute","Ecircumflex","Edieresis","Igrave","Iacute","Icircumflex","Idieresis","Eth","Ntilde","Ograve","Oacute","Ocircumflex","Otilde","Odieresis","multiply","Oslash","Ugrave","Uacute","Ucircumflex","Udieresis","Yacute","Thorn","germandbls","agrave","aacute","acircumflex","atilde","adieresis","aring","ae","ccedilla","egrave","eacute","ecircumflex","edieresis","igrave","iacute","icircumflex","idieresis","eth","ntilde","ograve","oacute","ocircumflex","otilde","odieresis","divide","oslash","ugrave","uacute","ucircumflex","udieresis","yacute","thorn","ydieresis"];t.WinAnsiEncoding=o;const c=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","universal","numbersign","existential","percent","ampersand","suchthat","parenleft","parenright","asteriskmath","plus","comma","minus","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","congruent","Alpha","Beta","Chi","Delta","Epsilon","Phi","Gamma","Eta","Iota","theta1","Kappa","Lambda","Mu","Nu","Omicron","Pi","Theta","Rho","Sigma","Tau","Upsilon","sigma1","Omega","Xi","Psi","Zeta","bracketleft","therefore","bracketright","perpendicular","underscore","radicalex","alpha","beta","chi","delta","epsilon","phi","gamma","eta","iota","phi1","kappa","lambda","mu","nu","omicron","pi","theta","rho","sigma","tau","upsilon","omega1","omega","xi","psi","zeta","braceleft","bar","braceright","similar","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Euro","Upsilon1","minute","lessequal","fraction","infinity","florin","club","diamond","heart","spade","arrowboth","arrowleft","arrowup","arrowright","arrowdown","degree","plusminus","second","greaterequal","multiply","proportional","partialdiff","bullet","divide","notequal","equivalence","approxequal","ellipsis","arrowvertex","arrowhorizex","carriagereturn","aleph","Ifraktur","Rfraktur","weierstrass","circlemultiply","circleplus","emptyset","intersection","union","propersuperset","reflexsuperset","notsubset","propersubset","reflexsubset","element","notelement","angle","gradient","registerserif","copyrightserif","trademarkserif","product","radical","dotmath","logicalnot","logicaland","logicalor","arrowdblboth","arrowdblleft","arrowdblup","arrowdblright","arrowdbldown","lozenge","angleleft","registersans","copyrightsans","trademarksans","summation","parenlefttp","parenleftex","parenleftbt","bracketlefttp","bracketleftex","bracketleftbt","bracelefttp","braceleftmid","braceleftbt","braceex","","angleright","integral","integraltp","integralex","integralbt","parenrighttp","parenrightex","parenrightbt","bracketrighttp","bracketrightex","bracketrightbt","bracerighttp","bracerightmid","bracerightbt",""];t.SymbolSetEncoding=c;const l=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","a1","a2","a202","a3","a4","a5","a119","a118","a117","a11","a12","a13","a14","a15","a16","a105","a17","a18","a19","a20","a21","a22","a23","a24","a25","a26","a27","a28","a6","a7","a8","a9","a10","a29","a30","a31","a32","a33","a34","a35","a36","a37","a38","a39","a40","a41","a42","a43","a44","a45","a46","a47","a48","a49","a50","a51","a52","a53","a54","a55","a56","a57","a58","a59","a60","a61","a62","a63","a64","a65","a66","a67","a68","a69","a70","a71","a72","a73","a74","a203","a75","a204","a76","a77","a78","a79","a81","a82","a83","a84","a97","a98","a99","a100","","a89","a90","a93","a94","a91","a92","a205","a85","a206","a86","a87","a88","a95","a96","","","","","","","","","","","","","","","","","","","","a101","a102","a103","a104","a106","a107","a108","a112","a111","a110","a109","a120","a121","a122","a123","a124","a125","a126","a127","a128","a129","a130","a131","a132","a133","a134","a135","a136","a137","a138","a139","a140","a141","a142","a143","a144","a145","a146","a147","a148","a149","a150","a151","a152","a153","a154","a155","a156","a157","a158","a159","a160","a161","a163","a164","a196","a165","a192","a166","a167","a168","a169","a170","a171","a172","a173","a162","a174","a175","a176","a177","a178","a179","a193","a180","a199","a181","a200","a182","","a201","a183","a184","a197","a185","a194","a198","a186","a195","a187","a188","a189","a190","a191",""];t.ZapfDingbatsEncoding=l},function(e,t,a){var r=a(7).getLookupTableFactory,i=r((function(e){e.A=65;e.AE=198;e.AEacute=508;e.AEmacron=482;e.AEsmall=63462;e.Aacute=193;e.Aacutesmall=63457;e.Abreve=258;e.Abreveacute=7854;e.Abrevecyrillic=1232;e.Abrevedotbelow=7862;e.Abrevegrave=7856;e.Abrevehookabove=7858;e.Abrevetilde=7860;e.Acaron=461;e.Acircle=9398;e.Acircumflex=194;e.Acircumflexacute=7844;e.Acircumflexdotbelow=7852;e.Acircumflexgrave=7846;e.Acircumflexhookabove=7848;e.Acircumflexsmall=63458;e.Acircumflextilde=7850;e.Acute=63177;e.Acutesmall=63412;e.Acyrillic=1040;e.Adblgrave=512;e.Adieresis=196;e.Adieresiscyrillic=1234;e.Adieresismacron=478;e.Adieresissmall=63460;e.Adotbelow=7840;e.Adotmacron=480;e.Agrave=192;e.Agravesmall=63456;e.Ahookabove=7842;e.Aiecyrillic=1236;e.Ainvertedbreve=514;e.Alpha=913;e.Alphatonos=902;e.Amacron=256;e.Amonospace=65313;e.Aogonek=260;e.Aring=197;e.Aringacute=506;e.Aringbelow=7680;e.Aringsmall=63461;e.Asmall=63329;e.Atilde=195;e.Atildesmall=63459;e.Aybarmenian=1329;e.B=66;e.Bcircle=9399;e.Bdotaccent=7682;e.Bdotbelow=7684;e.Becyrillic=1041;e.Benarmenian=1330;e.Beta=914;e.Bhook=385;e.Blinebelow=7686;e.Bmonospace=65314;e.Brevesmall=63220;e.Bsmall=63330;e.Btopbar=386;e.C=67;e.Caarmenian=1342;e.Cacute=262;e.Caron=63178;e.Caronsmall=63221;e.Ccaron=268;e.Ccedilla=199;e.Ccedillaacute=7688;e.Ccedillasmall=63463;e.Ccircle=9400;e.Ccircumflex=264;e.Cdot=266;e.Cdotaccent=266;e.Cedillasmall=63416;e.Chaarmenian=1353;e.Cheabkhasiancyrillic=1212;e.Checyrillic=1063;e.Chedescenderabkhasiancyrillic=1214;e.Chedescendercyrillic=1206;e.Chedieresiscyrillic=1268;e.Cheharmenian=1347;e.Chekhakassiancyrillic=1227;e.Cheverticalstrokecyrillic=1208;e.Chi=935;e.Chook=391;e.Circumflexsmall=63222;e.Cmonospace=65315;e.Coarmenian=1361;e.Csmall=63331;e.D=68;e.DZ=497;e.DZcaron=452;e.Daarmenian=1332;e.Dafrican=393;e.Dcaron=270;e.Dcedilla=7696;e.Dcircle=9401;e.Dcircumflexbelow=7698;e.Dcroat=272;e.Ddotaccent=7690;e.Ddotbelow=7692;e.Decyrillic=1044;e.Deicoptic=1006;e.Delta=8710;e.Deltagreek=916;e.Dhook=394;e.Dieresis=63179;e.DieresisAcute=63180;e.DieresisGrave=63181;e.Dieresissmall=63400;e.Digammagreek=988;e.Djecyrillic=1026;e.Dlinebelow=7694;e.Dmonospace=65316;e.Dotaccentsmall=63223;e.Dslash=272;e.Dsmall=63332;e.Dtopbar=395;e.Dz=498;e.Dzcaron=453;e.Dzeabkhasiancyrillic=1248;e.Dzecyrillic=1029;e.Dzhecyrillic=1039;e.E=69;e.Eacute=201;e.Eacutesmall=63465;e.Ebreve=276;e.Ecaron=282;e.Ecedillabreve=7708;e.Echarmenian=1333;e.Ecircle=9402;e.Ecircumflex=202;e.Ecircumflexacute=7870;e.Ecircumflexbelow=7704;e.Ecircumflexdotbelow=7878;e.Ecircumflexgrave=7872;e.Ecircumflexhookabove=7874;e.Ecircumflexsmall=63466;e.Ecircumflextilde=7876;e.Ecyrillic=1028;e.Edblgrave=516;e.Edieresis=203;e.Edieresissmall=63467;e.Edot=278;e.Edotaccent=278;e.Edotbelow=7864;e.Efcyrillic=1060;e.Egrave=200;e.Egravesmall=63464;e.Eharmenian=1335;e.Ehookabove=7866;e.Eightroman=8551;e.Einvertedbreve=518;e.Eiotifiedcyrillic=1124;e.Elcyrillic=1051;e.Elevenroman=8554;e.Emacron=274;e.Emacronacute=7702;e.Emacrongrave=7700;e.Emcyrillic=1052;e.Emonospace=65317;e.Encyrillic=1053;e.Endescendercyrillic=1186;e.Eng=330;e.Enghecyrillic=1188;e.Enhookcyrillic=1223;e.Eogonek=280;e.Eopen=400;e.Epsilon=917;e.Epsilontonos=904;e.Ercyrillic=1056;e.Ereversed=398;e.Ereversedcyrillic=1069;e.Escyrillic=1057;e.Esdescendercyrillic=1194;e.Esh=425;e.Esmall=63333;e.Eta=919;e.Etarmenian=1336;e.Etatonos=905;e.Eth=208;e.Ethsmall=63472;e.Etilde=7868;e.Etildebelow=7706;e.Euro=8364;e.Ezh=439;e.Ezhcaron=494;e.Ezhreversed=440;e.F=70;e.Fcircle=9403;e.Fdotaccent=7710;e.Feharmenian=1366;e.Feicoptic=996;e.Fhook=401;e.Fitacyrillic=1138;e.Fiveroman=8548;e.Fmonospace=65318;e.Fourroman=8547;e.Fsmall=63334;e.G=71;e.GBsquare=13191;e.Gacute=500;e.Gamma=915;e.Gammaafrican=404;e.Gangiacoptic=1002;e.Gbreve=286;e.Gcaron=486;e.Gcedilla=290;e.Gcircle=9404;e.Gcircumflex=284;e.Gcommaaccent=290;e.Gdot=288;e.Gdotaccent=288;e.Gecyrillic=1043;e.Ghadarmenian=1346;e.Ghemiddlehookcyrillic=1172;e.Ghestrokecyrillic=1170;e.Gheupturncyrillic=1168;e.Ghook=403;e.Gimarmenian=1331;e.Gjecyrillic=1027;e.Gmacron=7712;e.Gmonospace=65319;e.Grave=63182;e.Gravesmall=63328;e.Gsmall=63335;e.Gsmallhook=667;e.Gstroke=484;e.H=72;e.H18533=9679;e.H18543=9642;e.H18551=9643;e.H22073=9633;e.HPsquare=13259;e.Haabkhasiancyrillic=1192;e.Hadescendercyrillic=1202;e.Hardsigncyrillic=1066;e.Hbar=294;e.Hbrevebelow=7722;e.Hcedilla=7720;e.Hcircle=9405;e.Hcircumflex=292;e.Hdieresis=7718;e.Hdotaccent=7714;e.Hdotbelow=7716;e.Hmonospace=65320;e.Hoarmenian=1344;e.Horicoptic=1e3;e.Hsmall=63336;e.Hungarumlaut=63183;e.Hungarumlautsmall=63224;e.Hzsquare=13200;e.I=73;e.IAcyrillic=1071;e.IJ=306;e.IUcyrillic=1070;e.Iacute=205;e.Iacutesmall=63469;e.Ibreve=300;e.Icaron=463;e.Icircle=9406;e.Icircumflex=206;e.Icircumflexsmall=63470;e.Icyrillic=1030;e.Idblgrave=520;e.Idieresis=207;e.Idieresisacute=7726;e.Idieresiscyrillic=1252;e.Idieresissmall=63471;e.Idot=304;e.Idotaccent=304;e.Idotbelow=7882;e.Iebrevecyrillic=1238;e.Iecyrillic=1045;e.Ifraktur=8465;e.Igrave=204;e.Igravesmall=63468;e.Ihookabove=7880;e.Iicyrillic=1048;e.Iinvertedbreve=522;e.Iishortcyrillic=1049;e.Imacron=298;e.Imacroncyrillic=1250;e.Imonospace=65321;e.Iniarmenian=1339;e.Iocyrillic=1025;e.Iogonek=302;e.Iota=921;e.Iotaafrican=406;e.Iotadieresis=938;e.Iotatonos=906;e.Ismall=63337;e.Istroke=407;e.Itilde=296;e.Itildebelow=7724;e.Izhitsacyrillic=1140;e.Izhitsadblgravecyrillic=1142;e.J=74;e.Jaarmenian=1345;e.Jcircle=9407;e.Jcircumflex=308;e.Jecyrillic=1032;e.Jheharmenian=1355;e.Jmonospace=65322;e.Jsmall=63338;e.K=75;e.KBsquare=13189;e.KKsquare=13261;e.Kabashkircyrillic=1184;e.Kacute=7728;e.Kacyrillic=1050;e.Kadescendercyrillic=1178;e.Kahookcyrillic=1219;e.Kappa=922;e.Kastrokecyrillic=1182;e.Kaverticalstrokecyrillic=1180;e.Kcaron=488;e.Kcedilla=310;e.Kcircle=9408;e.Kcommaaccent=310;e.Kdotbelow=7730;e.Keharmenian=1364;e.Kenarmenian=1343;e.Khacyrillic=1061;e.Kheicoptic=998;e.Khook=408;e.Kjecyrillic=1036;e.Klinebelow=7732;e.Kmonospace=65323;e.Koppacyrillic=1152;e.Koppagreek=990;e.Ksicyrillic=1134;e.Ksmall=63339;e.L=76;e.LJ=455;e.LL=63167;e.Lacute=313;e.Lambda=923;e.Lcaron=317;e.Lcedilla=315;e.Lcircle=9409;e.Lcircumflexbelow=7740;e.Lcommaaccent=315;e.Ldot=319;e.Ldotaccent=319;e.Ldotbelow=7734;e.Ldotbelowmacron=7736;e.Liwnarmenian=1340;e.Lj=456;e.Ljecyrillic=1033;e.Llinebelow=7738;e.Lmonospace=65324;e.Lslash=321;e.Lslashsmall=63225;e.Lsmall=63340;e.M=77;e.MBsquare=13190;e.Macron=63184;e.Macronsmall=63407;e.Macute=7742;e.Mcircle=9410;e.Mdotaccent=7744;e.Mdotbelow=7746;e.Menarmenian=1348;e.Mmonospace=65325;e.Msmall=63341;e.Mturned=412;e.Mu=924;e.N=78;e.NJ=458;e.Nacute=323;e.Ncaron=327;e.Ncedilla=325;e.Ncircle=9411;e.Ncircumflexbelow=7754;e.Ncommaaccent=325;e.Ndotaccent=7748;e.Ndotbelow=7750;e.Nhookleft=413;e.Nineroman=8552;e.Nj=459;e.Njecyrillic=1034;e.Nlinebelow=7752;e.Nmonospace=65326;e.Nowarmenian=1350;e.Nsmall=63342;e.Ntilde=209;e.Ntildesmall=63473;e.Nu=925;e.O=79;e.OE=338;e.OEsmall=63226;e.Oacute=211;e.Oacutesmall=63475;e.Obarredcyrillic=1256;e.Obarreddieresiscyrillic=1258;e.Obreve=334;e.Ocaron=465;e.Ocenteredtilde=415;e.Ocircle=9412;e.Ocircumflex=212;e.Ocircumflexacute=7888;e.Ocircumflexdotbelow=7896;e.Ocircumflexgrave=7890;e.Ocircumflexhookabove=7892;e.Ocircumflexsmall=63476;e.Ocircumflextilde=7894;e.Ocyrillic=1054;e.Odblacute=336;e.Odblgrave=524;e.Odieresis=214;e.Odieresiscyrillic=1254;e.Odieresissmall=63478;e.Odotbelow=7884;e.Ogoneksmall=63227;e.Ograve=210;e.Ogravesmall=63474;e.Oharmenian=1365;e.Ohm=8486;e.Ohookabove=7886;e.Ohorn=416;e.Ohornacute=7898;e.Ohorndotbelow=7906;e.Ohorngrave=7900;e.Ohornhookabove=7902;e.Ohorntilde=7904;e.Ohungarumlaut=336;e.Oi=418;e.Oinvertedbreve=526;e.Omacron=332;e.Omacronacute=7762;e.Omacrongrave=7760;e.Omega=8486;e.Omegacyrillic=1120;e.Omegagreek=937;e.Omegaroundcyrillic=1146;e.Omegatitlocyrillic=1148;e.Omegatonos=911;e.Omicron=927;e.Omicrontonos=908;e.Omonospace=65327;e.Oneroman=8544;e.Oogonek=490;e.Oogonekmacron=492;e.Oopen=390;e.Oslash=216;e.Oslashacute=510;e.Oslashsmall=63480;e.Osmall=63343;e.Ostrokeacute=510;e.Otcyrillic=1150;e.Otilde=213;e.Otildeacute=7756;e.Otildedieresis=7758;e.Otildesmall=63477;e.P=80;e.Pacute=7764;e.Pcircle=9413;e.Pdotaccent=7766;e.Pecyrillic=1055;e.Peharmenian=1354;e.Pemiddlehookcyrillic=1190;e.Phi=934;e.Phook=420;e.Pi=928;e.Piwrarmenian=1363;e.Pmonospace=65328;e.Psi=936;e.Psicyrillic=1136;e.Psmall=63344;e.Q=81;e.Qcircle=9414;e.Qmonospace=65329;e.Qsmall=63345;e.R=82;e.Raarmenian=1356;e.Racute=340;e.Rcaron=344;e.Rcedilla=342;e.Rcircle=9415;e.Rcommaaccent=342;e.Rdblgrave=528;e.Rdotaccent=7768;e.Rdotbelow=7770;e.Rdotbelowmacron=7772;e.Reharmenian=1360;e.Rfraktur=8476;e.Rho=929;e.Ringsmall=63228;e.Rinvertedbreve=530;e.Rlinebelow=7774;e.Rmonospace=65330;e.Rsmall=63346;e.Rsmallinverted=641;e.Rsmallinvertedsuperior=694;e.S=83;e.SF010000=9484;e.SF020000=9492;e.SF030000=9488;e.SF040000=9496;e.SF050000=9532;e.SF060000=9516;e.SF070000=9524;e.SF080000=9500;e.SF090000=9508;e.SF100000=9472;e.SF110000=9474;e.SF190000=9569;e.SF200000=9570;e.SF210000=9558;e.SF220000=9557;e.SF230000=9571;e.SF240000=9553;e.SF250000=9559;e.SF260000=9565;e.SF270000=9564;e.SF280000=9563;e.SF360000=9566;e.SF370000=9567;e.SF380000=9562;e.SF390000=9556;e.SF400000=9577;e.SF410000=9574;e.SF420000=9568;e.SF430000=9552;e.SF440000=9580;e.SF450000=9575;e.SF460000=9576;e.SF470000=9572;e.SF480000=9573;e.SF490000=9561;e.SF500000=9560;e.SF510000=9554;e.SF520000=9555;e.SF530000=9579;e.SF540000=9578;e.Sacute=346;e.Sacutedotaccent=7780;e.Sampigreek=992;e.Scaron=352;e.Scarondotaccent=7782;e.Scaronsmall=63229;e.Scedilla=350;e.Schwa=399;e.Schwacyrillic=1240;e.Schwadieresiscyrillic=1242;e.Scircle=9416;e.Scircumflex=348;e.Scommaaccent=536;e.Sdotaccent=7776;e.Sdotbelow=7778;e.Sdotbelowdotaccent=7784;e.Seharmenian=1357;e.Sevenroman=8550;e.Shaarmenian=1351;e.Shacyrillic=1064;e.Shchacyrillic=1065;e.Sheicoptic=994;e.Shhacyrillic=1210;e.Shimacoptic=1004;e.Sigma=931;e.Sixroman=8549;e.Smonospace=65331;e.Softsigncyrillic=1068;e.Ssmall=63347;e.Stigmagreek=986;e.T=84;e.Tau=932;e.Tbar=358;e.Tcaron=356;e.Tcedilla=354;e.Tcircle=9417;e.Tcircumflexbelow=7792;e.Tcommaaccent=354;e.Tdotaccent=7786;e.Tdotbelow=7788;e.Tecyrillic=1058;e.Tedescendercyrillic=1196;e.Tenroman=8553;e.Tetsecyrillic=1204;e.Theta=920;e.Thook=428;e.Thorn=222;e.Thornsmall=63486;e.Threeroman=8546;e.Tildesmall=63230;e.Tiwnarmenian=1359;e.Tlinebelow=7790;e.Tmonospace=65332;e.Toarmenian=1337;e.Tonefive=444;e.Tonesix=388;e.Tonetwo=423;e.Tretroflexhook=430;e.Tsecyrillic=1062;e.Tshecyrillic=1035;e.Tsmall=63348;e.Twelveroman=8555;e.Tworoman=8545;e.U=85;e.Uacute=218;e.Uacutesmall=63482;e.Ubreve=364;e.Ucaron=467;e.Ucircle=9418;e.Ucircumflex=219;e.Ucircumflexbelow=7798;e.Ucircumflexsmall=63483;e.Ucyrillic=1059;e.Udblacute=368;e.Udblgrave=532;e.Udieresis=220;e.Udieresisacute=471;e.Udieresisbelow=7794;e.Udieresiscaron=473;e.Udieresiscyrillic=1264;e.Udieresisgrave=475;e.Udieresismacron=469;e.Udieresissmall=63484;e.Udotbelow=7908;e.Ugrave=217;e.Ugravesmall=63481;e.Uhookabove=7910;e.Uhorn=431;e.Uhornacute=7912;e.Uhorndotbelow=7920;e.Uhorngrave=7914;e.Uhornhookabove=7916;e.Uhorntilde=7918;e.Uhungarumlaut=368;e.Uhungarumlautcyrillic=1266;e.Uinvertedbreve=534;e.Ukcyrillic=1144;e.Umacron=362;e.Umacroncyrillic=1262;e.Umacrondieresis=7802;e.Umonospace=65333;e.Uogonek=370;e.Upsilon=933;e.Upsilon1=978;e.Upsilonacutehooksymbolgreek=979;e.Upsilonafrican=433;e.Upsilondieresis=939;e.Upsilondieresishooksymbolgreek=980;e.Upsilonhooksymbol=978;e.Upsilontonos=910;e.Uring=366;e.Ushortcyrillic=1038;e.Usmall=63349;e.Ustraightcyrillic=1198;e.Ustraightstrokecyrillic=1200;e.Utilde=360;e.Utildeacute=7800;e.Utildebelow=7796;e.V=86;e.Vcircle=9419;e.Vdotbelow=7806;e.Vecyrillic=1042;e.Vewarmenian=1358;e.Vhook=434;e.Vmonospace=65334;e.Voarmenian=1352;e.Vsmall=63350;e.Vtilde=7804;e.W=87;e.Wacute=7810;e.Wcircle=9420;e.Wcircumflex=372;e.Wdieresis=7812;e.Wdotaccent=7814;e.Wdotbelow=7816;e.Wgrave=7808;e.Wmonospace=65335;e.Wsmall=63351;e.X=88;e.Xcircle=9421;e.Xdieresis=7820;e.Xdotaccent=7818;e.Xeharmenian=1341;e.Xi=926;e.Xmonospace=65336;e.Xsmall=63352;e.Y=89;e.Yacute=221;e.Yacutesmall=63485;e.Yatcyrillic=1122;e.Ycircle=9422;e.Ycircumflex=374;e.Ydieresis=376;e.Ydieresissmall=63487;e.Ydotaccent=7822;e.Ydotbelow=7924;e.Yericyrillic=1067;e.Yerudieresiscyrillic=1272;e.Ygrave=7922;e.Yhook=435;e.Yhookabove=7926;e.Yiarmenian=1349;e.Yicyrillic=1031;e.Yiwnarmenian=1362;e.Ymonospace=65337;e.Ysmall=63353;e.Ytilde=7928;e.Yusbigcyrillic=1130;e.Yusbigiotifiedcyrillic=1132;e.Yuslittlecyrillic=1126;e.Yuslittleiotifiedcyrillic=1128;e.Z=90;e.Zaarmenian=1334;e.Zacute=377;e.Zcaron=381;e.Zcaronsmall=63231;e.Zcircle=9423;e.Zcircumflex=7824;e.Zdot=379;e.Zdotaccent=379;e.Zdotbelow=7826;e.Zecyrillic=1047;e.Zedescendercyrillic=1176;e.Zedieresiscyrillic=1246;e.Zeta=918;e.Zhearmenian=1338;e.Zhebrevecyrillic=1217;e.Zhecyrillic=1046;e.Zhedescendercyrillic=1174;e.Zhedieresiscyrillic=1244;e.Zlinebelow=7828;e.Zmonospace=65338;e.Zsmall=63354;e.Zstroke=437;e.a=97;e.aabengali=2438;e.aacute=225;e.aadeva=2310;e.aagujarati=2694;e.aagurmukhi=2566;e.aamatragurmukhi=2622;e.aarusquare=13059;e.aavowelsignbengali=2494;e.aavowelsigndeva=2366;e.aavowelsigngujarati=2750;e.abbreviationmarkarmenian=1375;e.abbreviationsigndeva=2416;e.abengali=2437;e.abopomofo=12570;e.abreve=259;e.abreveacute=7855;e.abrevecyrillic=1233;e.abrevedotbelow=7863;e.abrevegrave=7857;e.abrevehookabove=7859;e.abrevetilde=7861;e.acaron=462;e.acircle=9424;e.acircumflex=226;e.acircumflexacute=7845;e.acircumflexdotbelow=7853;e.acircumflexgrave=7847;e.acircumflexhookabove=7849;e.acircumflextilde=7851;e.acute=180;e.acutebelowcmb=791;e.acutecmb=769;e.acutecomb=769;e.acutedeva=2388;e.acutelowmod=719;e.acutetonecmb=833;e.acyrillic=1072;e.adblgrave=513;e.addakgurmukhi=2673;e.adeva=2309;e.adieresis=228;e.adieresiscyrillic=1235;e.adieresismacron=479;e.adotbelow=7841;e.adotmacron=481;e.ae=230;e.aeacute=509;e.aekorean=12624;e.aemacron=483;e.afii00208=8213;e.afii08941=8356;e.afii10017=1040;e.afii10018=1041;e.afii10019=1042;e.afii10020=1043;e.afii10021=1044;e.afii10022=1045;e.afii10023=1025;e.afii10024=1046;e.afii10025=1047;e.afii10026=1048;e.afii10027=1049;e.afii10028=1050;e.afii10029=1051;e.afii10030=1052;e.afii10031=1053;e.afii10032=1054;e.afii10033=1055;e.afii10034=1056;e.afii10035=1057;e.afii10036=1058;e.afii10037=1059;e.afii10038=1060;e.afii10039=1061;e.afii10040=1062;e.afii10041=1063;e.afii10042=1064;e.afii10043=1065;e.afii10044=1066;e.afii10045=1067;e.afii10046=1068;e.afii10047=1069;e.afii10048=1070;e.afii10049=1071;e.afii10050=1168;e.afii10051=1026;e.afii10052=1027;e.afii10053=1028;e.afii10054=1029;e.afii10055=1030;e.afii10056=1031;e.afii10057=1032;e.afii10058=1033;e.afii10059=1034;e.afii10060=1035;e.afii10061=1036;e.afii10062=1038;e.afii10063=63172;e.afii10064=63173;e.afii10065=1072;e.afii10066=1073;e.afii10067=1074;e.afii10068=1075;e.afii10069=1076;e.afii10070=1077;e.afii10071=1105;e.afii10072=1078;e.afii10073=1079;e.afii10074=1080;e.afii10075=1081;e.afii10076=1082;e.afii10077=1083;e.afii10078=1084;e.afii10079=1085;e.afii10080=1086;e.afii10081=1087;e.afii10082=1088;e.afii10083=1089;e.afii10084=1090;e.afii10085=1091;e.afii10086=1092;e.afii10087=1093;e.afii10088=1094;e.afii10089=1095;e.afii10090=1096;e.afii10091=1097;e.afii10092=1098;e.afii10093=1099;e.afii10094=1100;e.afii10095=1101;e.afii10096=1102;e.afii10097=1103;e.afii10098=1169;e.afii10099=1106;e.afii10100=1107;e.afii10101=1108;e.afii10102=1109;e.afii10103=1110;e.afii10104=1111;e.afii10105=1112;e.afii10106=1113;e.afii10107=1114;e.afii10108=1115;e.afii10109=1116;e.afii10110=1118;e.afii10145=1039;e.afii10146=1122;e.afii10147=1138;e.afii10148=1140;e.afii10192=63174;e.afii10193=1119;e.afii10194=1123;e.afii10195=1139;e.afii10196=1141;e.afii10831=63175;e.afii10832=63176;e.afii10846=1241;e.afii299=8206;e.afii300=8207;e.afii301=8205;e.afii57381=1642;e.afii57388=1548;e.afii57392=1632;e.afii57393=1633;e.afii57394=1634;e.afii57395=1635;e.afii57396=1636;e.afii57397=1637;e.afii57398=1638;e.afii57399=1639;e.afii57400=1640;e.afii57401=1641;e.afii57403=1563;e.afii57407=1567;e.afii57409=1569;e.afii57410=1570;e.afii57411=1571;e.afii57412=1572;e.afii57413=1573;e.afii57414=1574;e.afii57415=1575;e.afii57416=1576;e.afii57417=1577;e.afii57418=1578;e.afii57419=1579;e.afii57420=1580;e.afii57421=1581;e.afii57422=1582;e.afii57423=1583;e.afii57424=1584;e.afii57425=1585;e.afii57426=1586;e.afii57427=1587;e.afii57428=1588;e.afii57429=1589;e.afii57430=1590;e.afii57431=1591;e.afii57432=1592;e.afii57433=1593;e.afii57434=1594;e.afii57440=1600;e.afii57441=1601;e.afii57442=1602;e.afii57443=1603;e.afii57444=1604;e.afii57445=1605;e.afii57446=1606;e.afii57448=1608;e.afii57449=1609;e.afii57450=1610;e.afii57451=1611;e.afii57452=1612;e.afii57453=1613;e.afii57454=1614;e.afii57455=1615;e.afii57456=1616;e.afii57457=1617;e.afii57458=1618;e.afii57470=1607;e.afii57505=1700;e.afii57506=1662;e.afii57507=1670;e.afii57508=1688;e.afii57509=1711;e.afii57511=1657;e.afii57512=1672;e.afii57513=1681;e.afii57514=1722;e.afii57519=1746;e.afii57534=1749;e.afii57636=8362;e.afii57645=1470;e.afii57658=1475;e.afii57664=1488;e.afii57665=1489;e.afii57666=1490;e.afii57667=1491;e.afii57668=1492;e.afii57669=1493;e.afii57670=1494;e.afii57671=1495;e.afii57672=1496;e.afii57673=1497;e.afii57674=1498;e.afii57675=1499;e.afii57676=1500;e.afii57677=1501;e.afii57678=1502;e.afii57679=1503;e.afii57680=1504;e.afii57681=1505;e.afii57682=1506;e.afii57683=1507;e.afii57684=1508;e.afii57685=1509;e.afii57686=1510;e.afii57687=1511;e.afii57688=1512;e.afii57689=1513;e.afii57690=1514;e.afii57694=64298;e.afii57695=64299;e.afii57700=64331;e.afii57705=64287;e.afii57716=1520;e.afii57717=1521;e.afii57718=1522;e.afii57723=64309;e.afii57793=1460;e.afii57794=1461;e.afii57795=1462;e.afii57796=1467;e.afii57797=1464;e.afii57798=1463;e.afii57799=1456;e.afii57800=1458;e.afii57801=1457;e.afii57802=1459;e.afii57803=1474;e.afii57804=1473;e.afii57806=1465;e.afii57807=1468;e.afii57839=1469;e.afii57841=1471;e.afii57842=1472;e.afii57929=700;e.afii61248=8453;e.afii61289=8467;e.afii61352=8470;e.afii61573=8236;e.afii61574=8237;e.afii61575=8238;e.afii61664=8204;e.afii63167=1645;e.afii64937=701;e.agrave=224;e.agujarati=2693;e.agurmukhi=2565;e.ahiragana=12354;e.ahookabove=7843;e.aibengali=2448;e.aibopomofo=12574;e.aideva=2320;e.aiecyrillic=1237;e.aigujarati=2704;e.aigurmukhi=2576;e.aimatragurmukhi=2632;e.ainarabic=1593;e.ainfinalarabic=65226;e.aininitialarabic=65227;e.ainmedialarabic=65228;e.ainvertedbreve=515;e.aivowelsignbengali=2504;e.aivowelsigndeva=2376;e.aivowelsigngujarati=2760;e.akatakana=12450;e.akatakanahalfwidth=65393;e.akorean=12623;e.alef=1488;e.alefarabic=1575;e.alefdageshhebrew=64304;e.aleffinalarabic=65166;e.alefhamzaabovearabic=1571;e.alefhamzaabovefinalarabic=65156;e.alefhamzabelowarabic=1573;e.alefhamzabelowfinalarabic=65160;e.alefhebrew=1488;e.aleflamedhebrew=64335;e.alefmaddaabovearabic=1570;e.alefmaddaabovefinalarabic=65154;e.alefmaksuraarabic=1609;e.alefmaksurafinalarabic=65264;e.alefmaksurainitialarabic=65267;e.alefmaksuramedialarabic=65268;e.alefpatahhebrew=64302;e.alefqamatshebrew=64303;e.aleph=8501;e.allequal=8780;e.alpha=945;e.alphatonos=940;e.amacron=257;e.amonospace=65345;e.ampersand=38;e.ampersandmonospace=65286;e.ampersandsmall=63270;e.amsquare=13250;e.anbopomofo=12578;e.angbopomofo=12580;e.angbracketleft=12296;e.angbracketright=12297;e.angkhankhuthai=3674;e.angle=8736;e.anglebracketleft=12296;e.anglebracketleftvertical=65087;e.anglebracketright=12297;e.anglebracketrightvertical=65088;e.angleleft=9001;e.angleright=9002;e.angstrom=8491;e.anoteleia=903;e.anudattadeva=2386;e.anusvarabengali=2434;e.anusvaradeva=2306;e.anusvaragujarati=2690;e.aogonek=261;e.apaatosquare=13056;e.aparen=9372;e.apostrophearmenian=1370;e.apostrophemod=700;e.apple=63743;e.approaches=8784;e.approxequal=8776;e.approxequalorimage=8786;e.approximatelyequal=8773;e.araeaekorean=12686;e.araeakorean=12685;e.arc=8978;e.arighthalfring=7834;e.aring=229;e.aringacute=507;e.aringbelow=7681;e.arrowboth=8596;e.arrowdashdown=8675;e.arrowdashleft=8672;e.arrowdashright=8674;e.arrowdashup=8673;e.arrowdblboth=8660;e.arrowdbldown=8659;e.arrowdblleft=8656;e.arrowdblright=8658;e.arrowdblup=8657;e.arrowdown=8595;e.arrowdownleft=8601;e.arrowdownright=8600;e.arrowdownwhite=8681;e.arrowheaddownmod=709;e.arrowheadleftmod=706;e.arrowheadrightmod=707;e.arrowheadupmod=708;e.arrowhorizex=63719;e.arrowleft=8592;e.arrowleftdbl=8656;e.arrowleftdblstroke=8653;e.arrowleftoverright=8646;e.arrowleftwhite=8678;e.arrowright=8594;e.arrowrightdblstroke=8655;e.arrowrightheavy=10142;e.arrowrightoverleft=8644;e.arrowrightwhite=8680;e.arrowtableft=8676;e.arrowtabright=8677;e.arrowup=8593;e.arrowupdn=8597;e.arrowupdnbse=8616;e.arrowupdownbase=8616;e.arrowupleft=8598;e.arrowupleftofdown=8645;e.arrowupright=8599;e.arrowupwhite=8679;e.arrowvertex=63718;e.asciicircum=94;e.asciicircummonospace=65342;e.asciitilde=126;e.asciitildemonospace=65374;e.ascript=593;e.ascriptturned=594;e.asmallhiragana=12353;e.asmallkatakana=12449;e.asmallkatakanahalfwidth=65383;e.asterisk=42;e.asteriskaltonearabic=1645;e.asteriskarabic=1645;e.asteriskmath=8727;e.asteriskmonospace=65290;e.asterisksmall=65121;e.asterism=8258;e.asuperior=63209;e.asymptoticallyequal=8771;e.at=64;e.atilde=227;e.atmonospace=65312;e.atsmall=65131;e.aturned=592;e.aubengali=2452;e.aubopomofo=12576;e.audeva=2324;e.augujarati=2708;e.augurmukhi=2580;e.aulengthmarkbengali=2519;e.aumatragurmukhi=2636;e.auvowelsignbengali=2508;e.auvowelsigndeva=2380;e.auvowelsigngujarati=2764;e.avagrahadeva=2365;e.aybarmenian=1377;e.ayin=1506;e.ayinaltonehebrew=64288;e.ayinhebrew=1506;e.b=98;e.babengali=2476;e.backslash=92;e.backslashmonospace=65340;e.badeva=2348;e.bagujarati=2732;e.bagurmukhi=2604;e.bahiragana=12400;e.bahtthai=3647;e.bakatakana=12496;e.bar=124;e.barmonospace=65372;e.bbopomofo=12549;e.bcircle=9425;e.bdotaccent=7683;e.bdotbelow=7685;e.beamedsixteenthnotes=9836;e.because=8757;e.becyrillic=1073;e.beharabic=1576;e.behfinalarabic=65168;e.behinitialarabic=65169;e.behiragana=12409;e.behmedialarabic=65170;e.behmeeminitialarabic=64671;e.behmeemisolatedarabic=64520;e.behnoonfinalarabic=64621;e.bekatakana=12505;e.benarmenian=1378;e.bet=1489;e.beta=946;e.betasymbolgreek=976;e.betdagesh=64305;e.betdageshhebrew=64305;e.bethebrew=1489;e.betrafehebrew=64332;e.bhabengali=2477;e.bhadeva=2349;e.bhagujarati=2733;e.bhagurmukhi=2605;e.bhook=595;e.bihiragana=12403;e.bikatakana=12499;e.bilabialclick=664;e.bindigurmukhi=2562;e.birusquare=13105;e.blackcircle=9679;e.blackdiamond=9670;e.blackdownpointingtriangle=9660;e.blackleftpointingpointer=9668;e.blackleftpointingtriangle=9664;e.blacklenticularbracketleft=12304;e.blacklenticularbracketleftvertical=65083;e.blacklenticularbracketright=12305;e.blacklenticularbracketrightvertical=65084;e.blacklowerlefttriangle=9699;e.blacklowerrighttriangle=9698;e.blackrectangle=9644;e.blackrightpointingpointer=9658;e.blackrightpointingtriangle=9654;e.blacksmallsquare=9642;e.blacksmilingface=9787;e.blacksquare=9632;e.blackstar=9733;e.blackupperlefttriangle=9700;e.blackupperrighttriangle=9701;e.blackuppointingsmalltriangle=9652;e.blackuppointingtriangle=9650;e.blank=9251;e.blinebelow=7687;e.block=9608;e.bmonospace=65346;e.bobaimaithai=3610;e.bohiragana=12412;e.bokatakana=12508;e.bparen=9373;e.bqsquare=13251;e.braceex=63732;e.braceleft=123;e.braceleftbt=63731;e.braceleftmid=63730;e.braceleftmonospace=65371;e.braceleftsmall=65115;e.bracelefttp=63729;e.braceleftvertical=65079;e.braceright=125;e.bracerightbt=63742;e.bracerightmid=63741;e.bracerightmonospace=65373;e.bracerightsmall=65116;e.bracerighttp=63740;e.bracerightvertical=65080;e.bracketleft=91;e.bracketleftbt=63728;e.bracketleftex=63727;e.bracketleftmonospace=65339;e.bracketlefttp=63726;e.bracketright=93;e.bracketrightbt=63739;e.bracketrightex=63738;e.bracketrightmonospace=65341;e.bracketrighttp=63737;e.breve=728;e.brevebelowcmb=814;e.brevecmb=774;e.breveinvertedbelowcmb=815;e.breveinvertedcmb=785;e.breveinverteddoublecmb=865;e.bridgebelowcmb=810;e.bridgeinvertedbelowcmb=826;e.brokenbar=166;e.bstroke=384;e.bsuperior=63210;e.btopbar=387;e.buhiragana=12406;e.bukatakana=12502;e.bullet=8226;e.bulletinverse=9688;e.bulletoperator=8729;e.bullseye=9678;e.c=99;e.caarmenian=1390;e.cabengali=2458;e.cacute=263;e.cadeva=2330;e.cagujarati=2714;e.cagurmukhi=2586;e.calsquare=13192;e.candrabindubengali=2433;e.candrabinducmb=784;e.candrabindudeva=2305;e.candrabindugujarati=2689;e.capslock=8682;e.careof=8453;e.caron=711;e.caronbelowcmb=812;e.caroncmb=780;e.carriagereturn=8629;e.cbopomofo=12568;e.ccaron=269;e.ccedilla=231;e.ccedillaacute=7689;e.ccircle=9426;e.ccircumflex=265;e.ccurl=597;e.cdot=267;e.cdotaccent=267;e.cdsquare=13253;e.cedilla=184;e.cedillacmb=807;e.cent=162;e.centigrade=8451;e.centinferior=63199;e.centmonospace=65504;e.centoldstyle=63394;e.centsuperior=63200;e.chaarmenian=1401;e.chabengali=2459;e.chadeva=2331;e.chagujarati=2715;e.chagurmukhi=2587;e.chbopomofo=12564;e.cheabkhasiancyrillic=1213;e.checkmark=10003;e.checyrillic=1095;e.chedescenderabkhasiancyrillic=1215;e.chedescendercyrillic=1207;e.chedieresiscyrillic=1269;e.cheharmenian=1395;e.chekhakassiancyrillic=1228;e.cheverticalstrokecyrillic=1209;e.chi=967;e.chieuchacirclekorean=12919;e.chieuchaparenkorean=12823;e.chieuchcirclekorean=12905;e.chieuchkorean=12618;e.chieuchparenkorean=12809;e.chochangthai=3594;e.chochanthai=3592;e.chochingthai=3593;e.chochoethai=3596;e.chook=392;e.cieucacirclekorean=12918;e.cieucaparenkorean=12822;e.cieuccirclekorean=12904;e.cieuckorean=12616;e.cieucparenkorean=12808;e.cieucuparenkorean=12828;e.circle=9675;e.circlecopyrt=169;e.circlemultiply=8855;e.circleot=8857;e.circleplus=8853;e.circlepostalmark=12342;e.circlewithlefthalfblack=9680;e.circlewithrighthalfblack=9681;e.circumflex=710;e.circumflexbelowcmb=813;e.circumflexcmb=770;e.clear=8999;e.clickalveolar=450;e.clickdental=448;e.clicklateral=449;e.clickretroflex=451;e.club=9827;e.clubsuitblack=9827;e.clubsuitwhite=9831;e.cmcubedsquare=13220;e.cmonospace=65347;e.cmsquaredsquare=13216;e.coarmenian=1409;e.colon=58;e.colonmonetary=8353;e.colonmonospace=65306;e.colonsign=8353;e.colonsmall=65109;e.colontriangularhalfmod=721;e.colontriangularmod=720;e.comma=44;e.commaabovecmb=787;e.commaaboverightcmb=789;e.commaaccent=63171;e.commaarabic=1548;e.commaarmenian=1373;e.commainferior=63201;e.commamonospace=65292;e.commareversedabovecmb=788;e.commareversedmod=701;e.commasmall=65104;e.commasuperior=63202;e.commaturnedabovecmb=786;e.commaturnedmod=699;e.compass=9788;e.congruent=8773;e.contourintegral=8750;e.control=8963;e.controlACK=6;e.controlBEL=7;e.controlBS=8;e.controlCAN=24;e.controlCR=13;e.controlDC1=17;e.controlDC2=18;e.controlDC3=19;e.controlDC4=20;e.controlDEL=127;e.controlDLE=16;e.controlEM=25;e.controlENQ=5;e.controlEOT=4;e.controlESC=27;e.controlETB=23;e.controlETX=3;e.controlFF=12;e.controlFS=28;e.controlGS=29;e.controlHT=9;e.controlLF=10;e.controlNAK=21;e.controlNULL=0;e.controlRS=30;e.controlSI=15;e.controlSO=14;e.controlSOT=2;e.controlSTX=1;e.controlSUB=26;e.controlSYN=22;e.controlUS=31;e.controlVT=11;e.copyright=169;e.copyrightsans=63721;e.copyrightserif=63193;e.cornerbracketleft=12300;e.cornerbracketlefthalfwidth=65378;e.cornerbracketleftvertical=65089;e.cornerbracketright=12301;e.cornerbracketrighthalfwidth=65379;e.cornerbracketrightvertical=65090;e.corporationsquare=13183;e.cosquare=13255;e.coverkgsquare=13254;e.cparen=9374;e.cruzeiro=8354;e.cstretched=663;e.curlyand=8911;e.curlyor=8910;e.currency=164;e.cyrBreve=63185;e.cyrFlex=63186;e.cyrbreve=63188;e.cyrflex=63189;e.d=100;e.daarmenian=1380;e.dabengali=2470;e.dadarabic=1590;e.dadeva=2342;e.dadfinalarabic=65214;e.dadinitialarabic=65215;e.dadmedialarabic=65216;e.dagesh=1468;e.dageshhebrew=1468;e.dagger=8224;e.daggerdbl=8225;e.dagujarati=2726;e.dagurmukhi=2598;e.dahiragana=12384;e.dakatakana=12480;e.dalarabic=1583;e.dalet=1491;e.daletdagesh=64307;e.daletdageshhebrew=64307;e.dalethebrew=1491;e.dalfinalarabic=65194;e.dammaarabic=1615;e.dammalowarabic=1615;e.dammatanaltonearabic=1612;e.dammatanarabic=1612;e.danda=2404;e.dargahebrew=1447;e.dargalefthebrew=1447;e.dasiapneumatacyrilliccmb=1157;e.dblGrave=63187;e.dblanglebracketleft=12298;e.dblanglebracketleftvertical=65085;e.dblanglebracketright=12299;e.dblanglebracketrightvertical=65086;e.dblarchinvertedbelowcmb=811;e.dblarrowleft=8660;e.dblarrowright=8658;e.dbldanda=2405;e.dblgrave=63190;e.dblgravecmb=783;e.dblintegral=8748;e.dbllowline=8215;e.dbllowlinecmb=819;e.dbloverlinecmb=831;e.dblprimemod=698;e.dblverticalbar=8214;e.dblverticallineabovecmb=782;e.dbopomofo=12553;e.dbsquare=13256;e.dcaron=271;e.dcedilla=7697;e.dcircle=9427;e.dcircumflexbelow=7699;e.dcroat=273;e.ddabengali=2465;e.ddadeva=2337;e.ddagujarati=2721;e.ddagurmukhi=2593;e.ddalarabic=1672;e.ddalfinalarabic=64393;e.dddhadeva=2396;e.ddhabengali=2466;e.ddhadeva=2338;e.ddhagujarati=2722;e.ddhagurmukhi=2594;e.ddotaccent=7691;e.ddotbelow=7693;e.decimalseparatorarabic=1643;e.decimalseparatorpersian=1643;e.decyrillic=1076;e.degree=176;e.dehihebrew=1453;e.dehiragana=12391;e.deicoptic=1007;e.dekatakana=12487;e.deleteleft=9003;e.deleteright=8998;e.delta=948;e.deltaturned=397;e.denominatorminusonenumeratorbengali=2552;e.dezh=676;e.dhabengali=2471;e.dhadeva=2343;e.dhagujarati=2727;e.dhagurmukhi=2599;e.dhook=599;e.dialytikatonos=901;e.dialytikatonoscmb=836;e.diamond=9830;e.diamondsuitwhite=9826;e.dieresis=168;e.dieresisacute=63191;e.dieresisbelowcmb=804;e.dieresiscmb=776;e.dieresisgrave=63192;e.dieresistonos=901;e.dihiragana=12386;e.dikatakana=12482;e.dittomark=12291;e.divide=247;e.divides=8739;e.divisionslash=8725;e.djecyrillic=1106;e.dkshade=9619;e.dlinebelow=7695;e.dlsquare=13207;e.dmacron=273;e.dmonospace=65348;e.dnblock=9604;e.dochadathai=3598;e.dodekthai=3604;e.dohiragana=12393;e.dokatakana=12489;e.dollar=36;e.dollarinferior=63203;e.dollarmonospace=65284;e.dollaroldstyle=63268;e.dollarsmall=65129;e.dollarsuperior=63204;e.dong=8363;e.dorusquare=13094;e.dotaccent=729;e.dotaccentcmb=775;e.dotbelowcmb=803;e.dotbelowcomb=803;e.dotkatakana=12539;e.dotlessi=305;e.dotlessj=63166;e.dotlessjstrokehook=644;e.dotmath=8901;e.dottedcircle=9676;e.doubleyodpatah=64287;e.doubleyodpatahhebrew=64287;e.downtackbelowcmb=798;e.downtackmod=725;e.dparen=9375;e.dsuperior=63211;e.dtail=598;e.dtopbar=396;e.duhiragana=12389;e.dukatakana=12485;e.dz=499;e.dzaltone=675;e.dzcaron=454;e.dzcurl=677;e.dzeabkhasiancyrillic=1249;e.dzecyrillic=1109;e.dzhecyrillic=1119;e.e=101;e.eacute=233;e.earth=9793;e.ebengali=2447;e.ebopomofo=12572;e.ebreve=277;e.ecandradeva=2317;e.ecandragujarati=2701;e.ecandravowelsigndeva=2373;e.ecandravowelsigngujarati=2757;e.ecaron=283;e.ecedillabreve=7709;e.echarmenian=1381;e.echyiwnarmenian=1415;e.ecircle=9428;e.ecircumflex=234;e.ecircumflexacute=7871;e.ecircumflexbelow=7705;e.ecircumflexdotbelow=7879;e.ecircumflexgrave=7873;e.ecircumflexhookabove=7875;e.ecircumflextilde=7877;e.ecyrillic=1108;e.edblgrave=517;e.edeva=2319;e.edieresis=235;e.edot=279;e.edotaccent=279;e.edotbelow=7865;e.eegurmukhi=2575;e.eematragurmukhi=2631;e.efcyrillic=1092;e.egrave=232;e.egujarati=2703;e.eharmenian=1383;e.ehbopomofo=12573;e.ehiragana=12360;e.ehookabove=7867;e.eibopomofo=12575;e.eight=56;e.eightarabic=1640;e.eightbengali=2542;e.eightcircle=9319;e.eightcircleinversesansserif=10129;e.eightdeva=2414;e.eighteencircle=9329;e.eighteenparen=9349;e.eighteenperiod=9369;e.eightgujarati=2798;e.eightgurmukhi=2670;e.eighthackarabic=1640;e.eighthangzhou=12328;e.eighthnotebeamed=9835;e.eightideographicparen=12839;e.eightinferior=8328;e.eightmonospace=65304;e.eightoldstyle=63288;e.eightparen=9339;e.eightperiod=9359;e.eightpersian=1784;e.eightroman=8567;e.eightsuperior=8312;e.eightthai=3672;e.einvertedbreve=519;e.eiotifiedcyrillic=1125;e.ekatakana=12456;e.ekatakanahalfwidth=65396;e.ekonkargurmukhi=2676;e.ekorean=12628;e.elcyrillic=1083;e.element=8712;e.elevencircle=9322;e.elevenparen=9342;e.elevenperiod=9362;e.elevenroman=8570;e.ellipsis=8230;e.ellipsisvertical=8942;e.emacron=275;e.emacronacute=7703;e.emacrongrave=7701;e.emcyrillic=1084;e.emdash=8212;e.emdashvertical=65073;e.emonospace=65349;e.emphasismarkarmenian=1371;e.emptyset=8709;e.enbopomofo=12579;e.encyrillic=1085;e.endash=8211;e.endashvertical=65074;e.endescendercyrillic=1187;e.eng=331;e.engbopomofo=12581;e.enghecyrillic=1189;e.enhookcyrillic=1224;e.enspace=8194;e.eogonek=281;e.eokorean=12627;e.eopen=603;e.eopenclosed=666;e.eopenreversed=604;e.eopenreversedclosed=606;e.eopenreversedhook=605;e.eparen=9376;e.epsilon=949;e.epsilontonos=941;e.equal=61;e.equalmonospace=65309;e.equalsmall=65126;e.equalsuperior=8316;e.equivalence=8801;e.erbopomofo=12582;e.ercyrillic=1088;e.ereversed=600;e.ereversedcyrillic=1101;e.escyrillic=1089;e.esdescendercyrillic=1195;e.esh=643;e.eshcurl=646;e.eshortdeva=2318;e.eshortvowelsigndeva=2374;e.eshreversedloop=426;e.eshsquatreversed=645;e.esmallhiragana=12359;e.esmallkatakana=12455;e.esmallkatakanahalfwidth=65386;e.estimated=8494;e.esuperior=63212;e.eta=951;e.etarmenian=1384;e.etatonos=942;e.eth=240;e.etilde=7869;e.etildebelow=7707;e.etnahtafoukhhebrew=1425;e.etnahtafoukhlefthebrew=1425;e.etnahtahebrew=1425;e.etnahtalefthebrew=1425;e.eturned=477;e.eukorean=12641;e.euro=8364;e.evowelsignbengali=2503;e.evowelsigndeva=2375;e.evowelsigngujarati=2759;e.exclam=33;e.exclamarmenian=1372;e.exclamdbl=8252;e.exclamdown=161;e.exclamdownsmall=63393;e.exclammonospace=65281;e.exclamsmall=63265;e.existential=8707;e.ezh=658;e.ezhcaron=495;e.ezhcurl=659;e.ezhreversed=441;e.ezhtail=442;e.f=102;e.fadeva=2398;e.fagurmukhi=2654;e.fahrenheit=8457;e.fathaarabic=1614;e.fathalowarabic=1614;e.fathatanarabic=1611;e.fbopomofo=12552;e.fcircle=9429;e.fdotaccent=7711;e.feharabic=1601;e.feharmenian=1414;e.fehfinalarabic=65234;e.fehinitialarabic=65235;e.fehmedialarabic=65236;e.feicoptic=997;e.female=9792;e.ff=64256;e.f_f=64256;e.ffi=64259;e.ffl=64260;e.fi=64257;e.fifteencircle=9326;e.fifteenparen=9346;e.fifteenperiod=9366;e.figuredash=8210;e.filledbox=9632;e.filledrect=9644;e.finalkaf=1498;e.finalkafdagesh=64314;e.finalkafdageshhebrew=64314;e.finalkafhebrew=1498;e.finalmem=1501;e.finalmemhebrew=1501;e.finalnun=1503;e.finalnunhebrew=1503;e.finalpe=1507;e.finalpehebrew=1507;e.finaltsadi=1509;e.finaltsadihebrew=1509;e.firsttonechinese=713;e.fisheye=9673;e.fitacyrillic=1139;e.five=53;e.fivearabic=1637;e.fivebengali=2539;e.fivecircle=9316;e.fivecircleinversesansserif=10126;e.fivedeva=2411;e.fiveeighths=8541;e.fivegujarati=2795;e.fivegurmukhi=2667;e.fivehackarabic=1637;e.fivehangzhou=12325;e.fiveideographicparen=12836;e.fiveinferior=8325;e.fivemonospace=65301;e.fiveoldstyle=63285;e.fiveparen=9336;e.fiveperiod=9356;e.fivepersian=1781;e.fiveroman=8564;e.fivesuperior=8309;e.fivethai=3669;e.fl=64258;e.florin=402;e.fmonospace=65350;e.fmsquare=13209;e.fofanthai=3615;e.fofathai=3613;e.fongmanthai=3663;e.forall=8704;e.four=52;e.fourarabic=1636;e.fourbengali=2538;e.fourcircle=9315;e.fourcircleinversesansserif=10125;e.fourdeva=2410;e.fourgujarati=2794;e.fourgurmukhi=2666;e.fourhackarabic=1636;e.fourhangzhou=12324;e.fourideographicparen=12835;e.fourinferior=8324;e.fourmonospace=65300;e.fournumeratorbengali=2551;e.fouroldstyle=63284;e.fourparen=9335;e.fourperiod=9355;e.fourpersian=1780;e.fourroman=8563;e.foursuperior=8308;e.fourteencircle=9325;e.fourteenparen=9345;e.fourteenperiod=9365;e.fourthai=3668;e.fourthtonechinese=715;e.fparen=9377;e.fraction=8260;e.franc=8355;e.g=103;e.gabengali=2455;e.gacute=501;e.gadeva=2327;e.gafarabic=1711;e.gaffinalarabic=64403;e.gafinitialarabic=64404;e.gafmedialarabic=64405;e.gagujarati=2711;e.gagurmukhi=2583;e.gahiragana=12364;e.gakatakana=12460;e.gamma=947;e.gammalatinsmall=611;e.gammasuperior=736;e.gangiacoptic=1003;e.gbopomofo=12557;e.gbreve=287;e.gcaron=487;e.gcedilla=291;e.gcircle=9430;e.gcircumflex=285;e.gcommaaccent=291;e.gdot=289;e.gdotaccent=289;e.gecyrillic=1075;e.gehiragana=12370;e.gekatakana=12466;e.geometricallyequal=8785;e.gereshaccenthebrew=1436;e.gereshhebrew=1523;e.gereshmuqdamhebrew=1437;e.germandbls=223;e.gershayimaccenthebrew=1438;e.gershayimhebrew=1524;e.getamark=12307;e.ghabengali=2456;e.ghadarmenian=1394;e.ghadeva=2328;e.ghagujarati=2712;e.ghagurmukhi=2584;e.ghainarabic=1594;e.ghainfinalarabic=65230;e.ghaininitialarabic=65231;e.ghainmedialarabic=65232;e.ghemiddlehookcyrillic=1173;e.ghestrokecyrillic=1171;e.gheupturncyrillic=1169;e.ghhadeva=2394;e.ghhagurmukhi=2650;e.ghook=608;e.ghzsquare=13203;e.gihiragana=12366;e.gikatakana=12462;e.gimarmenian=1379;e.gimel=1490;e.gimeldagesh=64306;e.gimeldageshhebrew=64306;e.gimelhebrew=1490;e.gjecyrillic=1107;e.glottalinvertedstroke=446;e.glottalstop=660;e.glottalstopinverted=662;e.glottalstopmod=704;e.glottalstopreversed=661;e.glottalstopreversedmod=705;e.glottalstopreversedsuperior=740;e.glottalstopstroke=673;e.glottalstopstrokereversed=674;e.gmacron=7713;e.gmonospace=65351;e.gohiragana=12372;e.gokatakana=12468;e.gparen=9378;e.gpasquare=13228;e.gradient=8711;e.grave=96;e.gravebelowcmb=790;e.gravecmb=768;e.gravecomb=768;e.gravedeva=2387;e.gravelowmod=718;e.gravemonospace=65344;e.gravetonecmb=832;e.greater=62;e.greaterequal=8805;e.greaterequalorless=8923;e.greatermonospace=65310;e.greaterorequivalent=8819;e.greaterorless=8823;e.greateroverequal=8807;e.greatersmall=65125;e.gscript=609;e.gstroke=485;e.guhiragana=12368;e.guillemotleft=171;e.guillemotright=187;e.guilsinglleft=8249;e.guilsinglright=8250;e.gukatakana=12464;e.guramusquare=13080;e.gysquare=13257;e.h=104;e.haabkhasiancyrillic=1193;e.haaltonearabic=1729;e.habengali=2489;e.hadescendercyrillic=1203;e.hadeva=2361;e.hagujarati=2745;e.hagurmukhi=2617;e.haharabic=1581;e.hahfinalarabic=65186;e.hahinitialarabic=65187;e.hahiragana=12399;e.hahmedialarabic=65188;e.haitusquare=13098;e.hakatakana=12495;e.hakatakanahalfwidth=65418;e.halantgurmukhi=2637;e.hamzaarabic=1569;e.hamzalowarabic=1569;e.hangulfiller=12644;e.hardsigncyrillic=1098;e.harpoonleftbarbup=8636;e.harpoonrightbarbup=8640;e.hasquare=13258;e.hatafpatah=1458;e.hatafpatah16=1458;e.hatafpatah23=1458;e.hatafpatah2f=1458;e.hatafpatahhebrew=1458;e.hatafpatahnarrowhebrew=1458;e.hatafpatahquarterhebrew=1458;e.hatafpatahwidehebrew=1458;e.hatafqamats=1459;e.hatafqamats1b=1459;e.hatafqamats28=1459;e.hatafqamats34=1459;e.hatafqamatshebrew=1459;e.hatafqamatsnarrowhebrew=1459;e.hatafqamatsquarterhebrew=1459;e.hatafqamatswidehebrew=1459;e.hatafsegol=1457;e.hatafsegol17=1457;e.hatafsegol24=1457;e.hatafsegol30=1457;e.hatafsegolhebrew=1457;e.hatafsegolnarrowhebrew=1457;e.hatafsegolquarterhebrew=1457;e.hatafsegolwidehebrew=1457;e.hbar=295;e.hbopomofo=12559;e.hbrevebelow=7723;e.hcedilla=7721;e.hcircle=9431;e.hcircumflex=293;e.hdieresis=7719;e.hdotaccent=7715;e.hdotbelow=7717;e.he=1492;e.heart=9829;e.heartsuitblack=9829;e.heartsuitwhite=9825;e.hedagesh=64308;e.hedageshhebrew=64308;e.hehaltonearabic=1729;e.heharabic=1607;e.hehebrew=1492;e.hehfinalaltonearabic=64423;e.hehfinalalttwoarabic=65258;e.hehfinalarabic=65258;e.hehhamzaabovefinalarabic=64421;e.hehhamzaaboveisolatedarabic=64420;e.hehinitialaltonearabic=64424;e.hehinitialarabic=65259;e.hehiragana=12408;e.hehmedialaltonearabic=64425;e.hehmedialarabic=65260;e.heiseierasquare=13179;e.hekatakana=12504;e.hekatakanahalfwidth=65421;e.hekutaarusquare=13110;e.henghook=615;e.herutusquare=13113;e.het=1495;e.hethebrew=1495;e.hhook=614;e.hhooksuperior=689;e.hieuhacirclekorean=12923;e.hieuhaparenkorean=12827;e.hieuhcirclekorean=12909;e.hieuhkorean=12622;e.hieuhparenkorean=12813;e.hihiragana=12402;e.hikatakana=12498;e.hikatakanahalfwidth=65419;e.hiriq=1460;e.hiriq14=1460;e.hiriq21=1460;e.hiriq2d=1460;e.hiriqhebrew=1460;e.hiriqnarrowhebrew=1460;e.hiriqquarterhebrew=1460;e.hiriqwidehebrew=1460;e.hlinebelow=7830;e.hmonospace=65352;e.hoarmenian=1392;e.hohipthai=3627;e.hohiragana=12411;e.hokatakana=12507;e.hokatakanahalfwidth=65422;e.holam=1465;e.holam19=1465;e.holam26=1465;e.holam32=1465;e.holamhebrew=1465;e.holamnarrowhebrew=1465;e.holamquarterhebrew=1465;e.holamwidehebrew=1465;e.honokhukthai=3630;e.hookabovecomb=777;e.hookcmb=777;e.hookpalatalizedbelowcmb=801;e.hookretroflexbelowcmb=802;e.hoonsquare=13122;e.horicoptic=1001;e.horizontalbar=8213;e.horncmb=795;e.hotsprings=9832;e.house=8962;e.hparen=9379;e.hsuperior=688;e.hturned=613;e.huhiragana=12405;e.huiitosquare=13107;e.hukatakana=12501;e.hukatakanahalfwidth=65420;e.hungarumlaut=733;e.hungarumlautcmb=779;e.hv=405;e.hyphen=45;e.hypheninferior=63205;e.hyphenmonospace=65293;e.hyphensmall=65123;e.hyphensuperior=63206;e.hyphentwo=8208;e.i=105;e.iacute=237;e.iacyrillic=1103;e.ibengali=2439;e.ibopomofo=12583;e.ibreve=301;e.icaron=464;e.icircle=9432;e.icircumflex=238;e.icyrillic=1110;e.idblgrave=521;e.ideographearthcircle=12943;e.ideographfirecircle=12939;e.ideographicallianceparen=12863;e.ideographiccallparen=12858;e.ideographiccentrecircle=12965;e.ideographicclose=12294;e.ideographiccomma=12289;e.ideographiccommaleft=65380;e.ideographiccongratulationparen=12855;e.ideographiccorrectcircle=12963;e.ideographicearthparen=12847;e.ideographicenterpriseparen=12861;e.ideographicexcellentcircle=12957;e.ideographicfestivalparen=12864;e.ideographicfinancialcircle=12950;e.ideographicfinancialparen=12854;e.ideographicfireparen=12843;e.ideographichaveparen=12850;e.ideographichighcircle=12964;e.ideographiciterationmark=12293;e.ideographiclaborcircle=12952;e.ideographiclaborparen=12856;e.ideographicleftcircle=12967;e.ideographiclowcircle=12966;e.ideographicmedicinecircle=12969;e.ideographicmetalparen=12846;e.ideographicmoonparen=12842;e.ideographicnameparen=12852;e.ideographicperiod=12290;e.ideographicprintcircle=12958;e.ideographicreachparen=12867;e.ideographicrepresentparen=12857;e.ideographicresourceparen=12862;e.ideographicrightcircle=12968;e.ideographicsecretcircle=12953;e.ideographicselfparen=12866;e.ideographicsocietyparen=12851;e.ideographicspace=12288;e.ideographicspecialparen=12853;e.ideographicstockparen=12849;e.ideographicstudyparen=12859;e.ideographicsunparen=12848;e.ideographicsuperviseparen=12860;e.ideographicwaterparen=12844;e.ideographicwoodparen=12845;e.ideographiczero=12295;e.ideographmetalcircle=12942;e.ideographmooncircle=12938;e.ideographnamecircle=12948;e.ideographsuncircle=12944;e.ideographwatercircle=12940;e.ideographwoodcircle=12941;e.ideva=2311;e.idieresis=239;e.idieresisacute=7727;e.idieresiscyrillic=1253;e.idotbelow=7883;e.iebrevecyrillic=1239;e.iecyrillic=1077;e.ieungacirclekorean=12917;e.ieungaparenkorean=12821;e.ieungcirclekorean=12903;e.ieungkorean=12615;e.ieungparenkorean=12807;e.igrave=236;e.igujarati=2695;e.igurmukhi=2567;e.ihiragana=12356;e.ihookabove=7881;e.iibengali=2440;e.iicyrillic=1080;e.iideva=2312;e.iigujarati=2696;e.iigurmukhi=2568;e.iimatragurmukhi=2624;e.iinvertedbreve=523;e.iishortcyrillic=1081;e.iivowelsignbengali=2496;e.iivowelsigndeva=2368;e.iivowelsigngujarati=2752;e.ij=307;e.ikatakana=12452;e.ikatakanahalfwidth=65394;e.ikorean=12643;e.ilde=732;e.iluyhebrew=1452;e.imacron=299;e.imacroncyrillic=1251;e.imageorapproximatelyequal=8787;e.imatragurmukhi=2623;e.imonospace=65353;e.increment=8710;e.infinity=8734;e.iniarmenian=1387;e.integral=8747;e.integralbottom=8993;e.integralbt=8993;e.integralex=63733;e.integraltop=8992;e.integraltp=8992;e.intersection=8745;e.intisquare=13061;e.invbullet=9688;e.invcircle=9689;e.invsmileface=9787;e.iocyrillic=1105;e.iogonek=303;e.iota=953;e.iotadieresis=970;e.iotadieresistonos=912;e.iotalatin=617;e.iotatonos=943;e.iparen=9380;e.irigurmukhi=2674;e.ismallhiragana=12355;e.ismallkatakana=12451;e.ismallkatakanahalfwidth=65384;e.issharbengali=2554;e.istroke=616;e.isuperior=63213;e.iterationhiragana=12445;e.iterationkatakana=12541;e.itilde=297;e.itildebelow=7725;e.iubopomofo=12585;e.iucyrillic=1102;e.ivowelsignbengali=2495;e.ivowelsigndeva=2367;e.ivowelsigngujarati=2751;e.izhitsacyrillic=1141;e.izhitsadblgravecyrillic=1143;e.j=106;e.jaarmenian=1393;e.jabengali=2460;e.jadeva=2332;e.jagujarati=2716;e.jagurmukhi=2588;e.jbopomofo=12560;e.jcaron=496;e.jcircle=9433;e.jcircumflex=309;e.jcrossedtail=669;e.jdotlessstroke=607;e.jecyrillic=1112;e.jeemarabic=1580;e.jeemfinalarabic=65182;e.jeeminitialarabic=65183;e.jeemmedialarabic=65184;e.jeharabic=1688;e.jehfinalarabic=64395;e.jhabengali=2461;e.jhadeva=2333;e.jhagujarati=2717;e.jhagurmukhi=2589;e.jheharmenian=1403;e.jis=12292;e.jmonospace=65354;e.jparen=9381;e.jsuperior=690;e.k=107;e.kabashkircyrillic=1185;e.kabengali=2453;e.kacute=7729;e.kacyrillic=1082;e.kadescendercyrillic=1179;e.kadeva=2325;e.kaf=1499;e.kafarabic=1603;e.kafdagesh=64315;e.kafdageshhebrew=64315;e.kaffinalarabic=65242;e.kafhebrew=1499;e.kafinitialarabic=65243;e.kafmedialarabic=65244;e.kafrafehebrew=64333;e.kagujarati=2709;e.kagurmukhi=2581;e.kahiragana=12363;e.kahookcyrillic=1220;e.kakatakana=12459;e.kakatakanahalfwidth=65398;e.kappa=954;e.kappasymbolgreek=1008;e.kapyeounmieumkorean=12657;e.kapyeounphieuphkorean=12676;e.kapyeounpieupkorean=12664;e.kapyeounssangpieupkorean=12665;e.karoriisquare=13069;e.kashidaautoarabic=1600;e.kashidaautonosidebearingarabic=1600;e.kasmallkatakana=12533;e.kasquare=13188;e.kasraarabic=1616;e.kasratanarabic=1613;e.kastrokecyrillic=1183;e.katahiraprolongmarkhalfwidth=65392;e.kaverticalstrokecyrillic=1181;e.kbopomofo=12558;e.kcalsquare=13193;e.kcaron=489;e.kcedilla=311;e.kcircle=9434;e.kcommaaccent=311;e.kdotbelow=7731;e.keharmenian=1412;e.kehiragana=12369;e.kekatakana=12465;e.kekatakanahalfwidth=65401;e.kenarmenian=1391;e.kesmallkatakana=12534;e.kgreenlandic=312;e.khabengali=2454;e.khacyrillic=1093;e.khadeva=2326;e.khagujarati=2710;e.khagurmukhi=2582;e.khaharabic=1582;e.khahfinalarabic=65190;e.khahinitialarabic=65191;e.khahmedialarabic=65192;e.kheicoptic=999;e.khhadeva=2393;e.khhagurmukhi=2649;e.khieukhacirclekorean=12920;e.khieukhaparenkorean=12824;e.khieukhcirclekorean=12906;e.khieukhkorean=12619;e.khieukhparenkorean=12810;e.khokhaithai=3586;e.khokhonthai=3589;e.khokhuatthai=3587;e.khokhwaithai=3588;e.khomutthai=3675;e.khook=409;e.khorakhangthai=3590;e.khzsquare=13201;e.kihiragana=12365;e.kikatakana=12461;e.kikatakanahalfwidth=65399;e.kiroguramusquare=13077;e.kiromeetorusquare=13078;e.kirosquare=13076;e.kiyeokacirclekorean=12910;e.kiyeokaparenkorean=12814;e.kiyeokcirclekorean=12896;e.kiyeokkorean=12593;e.kiyeokparenkorean=12800;e.kiyeoksioskorean=12595;e.kjecyrillic=1116;e.klinebelow=7733;e.klsquare=13208;e.kmcubedsquare=13222;e.kmonospace=65355;e.kmsquaredsquare=13218;e.kohiragana=12371;e.kohmsquare=13248;e.kokaithai=3585;e.kokatakana=12467;e.kokatakanahalfwidth=65402;e.kooposquare=13086;e.koppacyrillic=1153;e.koreanstandardsymbol=12927;e.koroniscmb=835;e.kparen=9382;e.kpasquare=13226;e.ksicyrillic=1135;e.ktsquare=13263;e.kturned=670;e.kuhiragana=12367;e.kukatakana=12463;e.kukatakanahalfwidth=65400;e.kvsquare=13240;e.kwsquare=13246;e.l=108;e.labengali=2482;e.lacute=314;e.ladeva=2354;e.lagujarati=2738;e.lagurmukhi=2610;e.lakkhangyaothai=3653;e.lamaleffinalarabic=65276;e.lamalefhamzaabovefinalarabic=65272;e.lamalefhamzaaboveisolatedarabic=65271;e.lamalefhamzabelowfinalarabic=65274;e.lamalefhamzabelowisolatedarabic=65273;e.lamalefisolatedarabic=65275;e.lamalefmaddaabovefinalarabic=65270;e.lamalefmaddaaboveisolatedarabic=65269;e.lamarabic=1604;e.lambda=955;e.lambdastroke=411;e.lamed=1500;e.lameddagesh=64316;e.lameddageshhebrew=64316;e.lamedhebrew=1500;e.lamfinalarabic=65246;e.lamhahinitialarabic=64714;e.laminitialarabic=65247;e.lamjeeminitialarabic=64713;e.lamkhahinitialarabic=64715;e.lamlamhehisolatedarabic=65010;e.lammedialarabic=65248;e.lammeemhahinitialarabic=64904;e.lammeeminitialarabic=64716;e.largecircle=9711;e.lbar=410;e.lbelt=620;e.lbopomofo=12556;e.lcaron=318;e.lcedilla=316;e.lcircle=9435;e.lcircumflexbelow=7741;e.lcommaaccent=316;e.ldot=320;e.ldotaccent=320;e.ldotbelow=7735;e.ldotbelowmacron=7737;e.leftangleabovecmb=794;e.lefttackbelowcmb=792;e.less=60;e.lessequal=8804;e.lessequalorgreater=8922;e.lessmonospace=65308;e.lessorequivalent=8818;e.lessorgreater=8822;e.lessoverequal=8806;e.lesssmall=65124;e.lezh=622;e.lfblock=9612;e.lhookretroflex=621;e.lira=8356;e.liwnarmenian=1388;e.lj=457;e.ljecyrillic=1113;e.ll=63168;e.lladeva=2355;e.llagujarati=2739;e.llinebelow=7739;e.llladeva=2356;e.llvocalicbengali=2529;e.llvocalicdeva=2401;e.llvocalicvowelsignbengali=2531;e.llvocalicvowelsigndeva=2403;e.lmiddletilde=619;e.lmonospace=65356;e.lmsquare=13264;e.lochulathai=3628;e.logicaland=8743;e.logicalnot=172;e.logicalnotreversed=8976;e.logicalor=8744;e.lolingthai=3621;e.longs=383;e.lowlinecenterline=65102;e.lowlinecmb=818;e.lowlinedashed=65101;e.lozenge=9674;e.lparen=9383;e.lslash=322;e.lsquare=8467;e.lsuperior=63214;e.ltshade=9617;e.luthai=3622;e.lvocalicbengali=2444;e.lvocalicdeva=2316;e.lvocalicvowelsignbengali=2530;e.lvocalicvowelsigndeva=2402;e.lxsquare=13267;e.m=109;e.mabengali=2478;e.macron=175;e.macronbelowcmb=817;e.macroncmb=772;e.macronlowmod=717;e.macronmonospace=65507;e.macute=7743;e.madeva=2350;e.magujarati=2734;e.magurmukhi=2606;e.mahapakhhebrew=1444;e.mahapakhlefthebrew=1444;e.mahiragana=12414;e.maichattawalowleftthai=63637;e.maichattawalowrightthai=63636;e.maichattawathai=3659;e.maichattawaupperleftthai=63635;e.maieklowleftthai=63628;e.maieklowrightthai=63627;e.maiekthai=3656;e.maiekupperleftthai=63626;e.maihanakatleftthai=63620;e.maihanakatthai=3633;e.maitaikhuleftthai=63625;e.maitaikhuthai=3655;e.maitholowleftthai=63631;e.maitholowrightthai=63630;e.maithothai=3657;e.maithoupperleftthai=63629;e.maitrilowleftthai=63634;e.maitrilowrightthai=63633;e.maitrithai=3658;e.maitriupperleftthai=63632;e.maiyamokthai=3654;e.makatakana=12510;e.makatakanahalfwidth=65423;e.male=9794;e.mansyonsquare=13127;e.maqafhebrew=1470;e.mars=9794;e.masoracirclehebrew=1455;e.masquare=13187;e.mbopomofo=12551;e.mbsquare=13268;e.mcircle=9436;e.mcubedsquare=13221;e.mdotaccent=7745;e.mdotbelow=7747;e.meemarabic=1605;e.meemfinalarabic=65250;e.meeminitialarabic=65251;e.meemmedialarabic=65252;e.meemmeeminitialarabic=64721;e.meemmeemisolatedarabic=64584;e.meetorusquare=13133;e.mehiragana=12417;e.meizierasquare=13182;e.mekatakana=12513;e.mekatakanahalfwidth=65426;e.mem=1502;e.memdagesh=64318;e.memdageshhebrew=64318;e.memhebrew=1502;e.menarmenian=1396;e.merkhahebrew=1445;e.merkhakefulahebrew=1446;e.merkhakefulalefthebrew=1446;e.merkhalefthebrew=1445;e.mhook=625;e.mhzsquare=13202;e.middledotkatakanahalfwidth=65381;e.middot=183;e.mieumacirclekorean=12914;e.mieumaparenkorean=12818;e.mieumcirclekorean=12900;e.mieumkorean=12609;e.mieumpansioskorean=12656;e.mieumparenkorean=12804;e.mieumpieupkorean=12654;e.mieumsioskorean=12655;e.mihiragana=12415;e.mikatakana=12511;e.mikatakanahalfwidth=65424;e.minus=8722;e.minusbelowcmb=800;e.minuscircle=8854;e.minusmod=727;e.minusplus=8723;e.minute=8242;e.miribaarusquare=13130;e.mirisquare=13129;e.mlonglegturned=624;e.mlsquare=13206;e.mmcubedsquare=13219;e.mmonospace=65357;e.mmsquaredsquare=13215;e.mohiragana=12418;e.mohmsquare=13249;e.mokatakana=12514;e.mokatakanahalfwidth=65427;e.molsquare=13270;e.momathai=3617;e.moverssquare=13223;e.moverssquaredsquare=13224;e.mparen=9384;e.mpasquare=13227;e.mssquare=13235;e.msuperior=63215;e.mturned=623;e.mu=181;e.mu1=181;e.muasquare=13186;e.muchgreater=8811;e.muchless=8810;e.mufsquare=13196;e.mugreek=956;e.mugsquare=13197;e.muhiragana=12416;e.mukatakana=12512;e.mukatakanahalfwidth=65425;e.mulsquare=13205;e.multiply=215;e.mumsquare=13211;e.munahhebrew=1443;e.munahlefthebrew=1443;e.musicalnote=9834;e.musicalnotedbl=9835;e.musicflatsign=9837;e.musicsharpsign=9839;e.mussquare=13234;e.muvsquare=13238;e.muwsquare=13244;e.mvmegasquare=13241;e.mvsquare=13239;e.mwmegasquare=13247;e.mwsquare=13245;e.n=110;e.nabengali=2472;e.nabla=8711;e.nacute=324;e.nadeva=2344;e.nagujarati=2728;e.nagurmukhi=2600;e.nahiragana=12394;e.nakatakana=12490;e.nakatakanahalfwidth=65413;e.napostrophe=329;e.nasquare=13185;e.nbopomofo=12555;e.nbspace=160;e.ncaron=328;e.ncedilla=326;e.ncircle=9437;e.ncircumflexbelow=7755;e.ncommaaccent=326;e.ndotaccent=7749;e.ndotbelow=7751;e.nehiragana=12397;e.nekatakana=12493;e.nekatakanahalfwidth=65416;e.newsheqelsign=8362;e.nfsquare=13195;e.ngabengali=2457;e.ngadeva=2329;e.ngagujarati=2713;e.ngagurmukhi=2585;e.ngonguthai=3591;e.nhiragana=12435;e.nhookleft=626;e.nhookretroflex=627;e.nieunacirclekorean=12911;e.nieunaparenkorean=12815;e.nieuncieuckorean=12597;e.nieuncirclekorean=12897;e.nieunhieuhkorean=12598;e.nieunkorean=12596;e.nieunpansioskorean=12648;e.nieunparenkorean=12801;e.nieunsioskorean=12647;e.nieuntikeutkorean=12646;e.nihiragana=12395;e.nikatakana=12491;e.nikatakanahalfwidth=65414;e.nikhahitleftthai=63641;e.nikhahitthai=3661;e.nine=57;e.ninearabic=1641;e.ninebengali=2543;e.ninecircle=9320;e.ninecircleinversesansserif=10130;e.ninedeva=2415;e.ninegujarati=2799;e.ninegurmukhi=2671;e.ninehackarabic=1641;e.ninehangzhou=12329;e.nineideographicparen=12840;e.nineinferior=8329;e.ninemonospace=65305;e.nineoldstyle=63289;e.nineparen=9340;e.nineperiod=9360;e.ninepersian=1785;e.nineroman=8568;e.ninesuperior=8313;e.nineteencircle=9330;e.nineteenparen=9350;e.nineteenperiod=9370;e.ninethai=3673;e.nj=460;e.njecyrillic=1114;e.nkatakana=12531;e.nkatakanahalfwidth=65437;e.nlegrightlong=414;e.nlinebelow=7753;e.nmonospace=65358;e.nmsquare=13210;e.nnabengali=2467;e.nnadeva=2339;e.nnagujarati=2723;e.nnagurmukhi=2595;e.nnnadeva=2345;e.nohiragana=12398;e.nokatakana=12494;e.nokatakanahalfwidth=65417;e.nonbreakingspace=160;e.nonenthai=3603;e.nonuthai=3609;e.noonarabic=1606;e.noonfinalarabic=65254;e.noonghunnaarabic=1722;e.noonghunnafinalarabic=64415;e.nooninitialarabic=65255;e.noonjeeminitialarabic=64722;e.noonjeemisolatedarabic=64587;e.noonmedialarabic=65256;e.noonmeeminitialarabic=64725;e.noonmeemisolatedarabic=64590;e.noonnoonfinalarabic=64653;e.notcontains=8716;e.notelement=8713;e.notelementof=8713;e.notequal=8800;e.notgreater=8815;e.notgreaternorequal=8817;e.notgreaternorless=8825;e.notidentical=8802;e.notless=8814;e.notlessnorequal=8816;e.notparallel=8742;e.notprecedes=8832;e.notsubset=8836;e.notsucceeds=8833;e.notsuperset=8837;e.nowarmenian=1398;e.nparen=9385;e.nssquare=13233;e.nsuperior=8319;e.ntilde=241;e.nu=957;e.nuhiragana=12396;e.nukatakana=12492;e.nukatakanahalfwidth=65415;e.nuktabengali=2492;e.nuktadeva=2364;e.nuktagujarati=2748;e.nuktagurmukhi=2620;e.numbersign=35;e.numbersignmonospace=65283;e.numbersignsmall=65119;e.numeralsigngreek=884;e.numeralsignlowergreek=885;e.numero=8470;e.nun=1504;e.nundagesh=64320;e.nundageshhebrew=64320;e.nunhebrew=1504;e.nvsquare=13237;e.nwsquare=13243;e.nyabengali=2462;e.nyadeva=2334;e.nyagujarati=2718;e.nyagurmukhi=2590;e.o=111;e.oacute=243;e.oangthai=3629;e.obarred=629;e.obarredcyrillic=1257;e.obarreddieresiscyrillic=1259;e.obengali=2451;e.obopomofo=12571;e.obreve=335;e.ocandradeva=2321;e.ocandragujarati=2705;e.ocandravowelsigndeva=2377;e.ocandravowelsigngujarati=2761;e.ocaron=466;e.ocircle=9438;e.ocircumflex=244;e.ocircumflexacute=7889;e.ocircumflexdotbelow=7897;e.ocircumflexgrave=7891;e.ocircumflexhookabove=7893;e.ocircumflextilde=7895;e.ocyrillic=1086;e.odblacute=337;e.odblgrave=525;e.odeva=2323;e.odieresis=246;e.odieresiscyrillic=1255;e.odotbelow=7885;e.oe=339;e.oekorean=12634;e.ogonek=731;e.ogonekcmb=808;e.ograve=242;e.ogujarati=2707;e.oharmenian=1413;e.ohiragana=12362;e.ohookabove=7887;e.ohorn=417;e.ohornacute=7899;e.ohorndotbelow=7907;e.ohorngrave=7901;e.ohornhookabove=7903;e.ohorntilde=7905;e.ohungarumlaut=337;e.oi=419;e.oinvertedbreve=527;e.okatakana=12458;e.okatakanahalfwidth=65397;e.okorean=12631;e.olehebrew=1451;e.omacron=333;e.omacronacute=7763;e.omacrongrave=7761;e.omdeva=2384;e.omega=969;e.omega1=982;e.omegacyrillic=1121;e.omegalatinclosed=631;e.omegaroundcyrillic=1147;e.omegatitlocyrillic=1149;e.omegatonos=974;e.omgujarati=2768;e.omicron=959;e.omicrontonos=972;e.omonospace=65359;e.one=49;e.onearabic=1633;e.onebengali=2535;e.onecircle=9312;e.onecircleinversesansserif=10122;e.onedeva=2407;e.onedotenleader=8228;e.oneeighth=8539;e.onefitted=63196;e.onegujarati=2791;e.onegurmukhi=2663;e.onehackarabic=1633;e.onehalf=189;e.onehangzhou=12321;e.oneideographicparen=12832;e.oneinferior=8321;e.onemonospace=65297;e.onenumeratorbengali=2548;e.oneoldstyle=63281;e.oneparen=9332;e.oneperiod=9352;e.onepersian=1777;e.onequarter=188;e.oneroman=8560;e.onesuperior=185;e.onethai=3665;e.onethird=8531;e.oogonek=491;e.oogonekmacron=493;e.oogurmukhi=2579;e.oomatragurmukhi=2635;e.oopen=596;e.oparen=9386;e.openbullet=9702;e.option=8997;e.ordfeminine=170;e.ordmasculine=186;e.orthogonal=8735;e.oshortdeva=2322;e.oshortvowelsigndeva=2378;e.oslash=248;e.oslashacute=511;e.osmallhiragana=12361;e.osmallkatakana=12457;e.osmallkatakanahalfwidth=65387;e.ostrokeacute=511;e.osuperior=63216;e.otcyrillic=1151;e.otilde=245;e.otildeacute=7757;e.otildedieresis=7759;e.oubopomofo=12577;e.overline=8254;e.overlinecenterline=65098;e.overlinecmb=773;e.overlinedashed=65097;e.overlinedblwavy=65100;e.overlinewavy=65099;e.overscore=175;e.ovowelsignbengali=2507;e.ovowelsigndeva=2379;e.ovowelsigngujarati=2763;e.p=112;e.paampssquare=13184;e.paasentosquare=13099;e.pabengali=2474;e.pacute=7765;e.padeva=2346;e.pagedown=8671;e.pageup=8670;e.pagujarati=2730;e.pagurmukhi=2602;e.pahiragana=12401;e.paiyannoithai=3631;e.pakatakana=12497;e.palatalizationcyrilliccmb=1156;e.palochkacyrillic=1216;e.pansioskorean=12671;e.paragraph=182;e.parallel=8741;e.parenleft=40;e.parenleftaltonearabic=64830;e.parenleftbt=63725;e.parenleftex=63724;e.parenleftinferior=8333;e.parenleftmonospace=65288;e.parenleftsmall=65113;e.parenleftsuperior=8317;e.parenlefttp=63723;e.parenleftvertical=65077;e.parenright=41;e.parenrightaltonearabic=64831;e.parenrightbt=63736;e.parenrightex=63735;e.parenrightinferior=8334;e.parenrightmonospace=65289;e.parenrightsmall=65114;e.parenrightsuperior=8318;e.parenrighttp=63734;e.parenrightvertical=65078;e.partialdiff=8706;e.paseqhebrew=1472;e.pashtahebrew=1433;e.pasquare=13225;e.patah=1463;e.patah11=1463;e.patah1d=1463;e.patah2a=1463;e.patahhebrew=1463;e.patahnarrowhebrew=1463;e.patahquarterhebrew=1463;e.patahwidehebrew=1463;e.pazerhebrew=1441;e.pbopomofo=12550;e.pcircle=9439;e.pdotaccent=7767;e.pe=1508;e.pecyrillic=1087;e.pedagesh=64324;e.pedageshhebrew=64324;e.peezisquare=13115;e.pefinaldageshhebrew=64323;e.peharabic=1662;e.peharmenian=1402;e.pehebrew=1508;e.pehfinalarabic=64343;e.pehinitialarabic=64344;e.pehiragana=12410;e.pehmedialarabic=64345;e.pekatakana=12506;e.pemiddlehookcyrillic=1191;e.perafehebrew=64334;e.percent=37;e.percentarabic=1642;e.percentmonospace=65285;e.percentsmall=65130;e.period=46;e.periodarmenian=1417;e.periodcentered=183;e.periodhalfwidth=65377;e.periodinferior=63207;e.periodmonospace=65294;e.periodsmall=65106;e.periodsuperior=63208;e.perispomenigreekcmb=834;e.perpendicular=8869;e.perthousand=8240;e.peseta=8359;e.pfsquare=13194;e.phabengali=2475;e.phadeva=2347;e.phagujarati=2731;e.phagurmukhi=2603;e.phi=966;e.phi1=981;e.phieuphacirclekorean=12922;e.phieuphaparenkorean=12826;e.phieuphcirclekorean=12908;e.phieuphkorean=12621;e.phieuphparenkorean=12812;e.philatin=632;e.phinthuthai=3642;e.phisymbolgreek=981;e.phook=421;e.phophanthai=3614;e.phophungthai=3612;e.phosamphaothai=3616;e.pi=960;e.pieupacirclekorean=12915;e.pieupaparenkorean=12819;e.pieupcieuckorean=12662;e.pieupcirclekorean=12901;e.pieupkiyeokkorean=12658;e.pieupkorean=12610;e.pieupparenkorean=12805;e.pieupsioskiyeokkorean=12660;e.pieupsioskorean=12612;e.pieupsiostikeutkorean=12661;e.pieupthieuthkorean=12663;e.pieuptikeutkorean=12659;e.pihiragana=12404;e.pikatakana=12500;e.pisymbolgreek=982;e.piwrarmenian=1411;e.plus=43;e.plusbelowcmb=799;e.pluscircle=8853;e.plusminus=177;e.plusmod=726;e.plusmonospace=65291;e.plussmall=65122;e.plussuperior=8314;e.pmonospace=65360;e.pmsquare=13272;e.pohiragana=12413;e.pointingindexdownwhite=9759;e.pointingindexleftwhite=9756;e.pointingindexrightwhite=9758;e.pointingindexupwhite=9757;e.pokatakana=12509;e.poplathai=3611;e.postalmark=12306;e.postalmarkface=12320;e.pparen=9387;e.precedes=8826;e.prescription=8478;e.primemod=697;e.primereversed=8245;e.product=8719;e.projective=8965;e.prolongedkana=12540;e.propellor=8984;e.propersubset=8834;e.propersuperset=8835;e.proportion=8759;e.proportional=8733;e.psi=968;e.psicyrillic=1137;e.psilipneumatacyrilliccmb=1158;e.pssquare=13232;e.puhiragana=12407;e.pukatakana=12503;e.pvsquare=13236;e.pwsquare=13242;e.q=113;e.qadeva=2392;e.qadmahebrew=1448;e.qafarabic=1602;e.qaffinalarabic=65238;e.qafinitialarabic=65239;e.qafmedialarabic=65240;e.qamats=1464;e.qamats10=1464;e.qamats1a=1464;e.qamats1c=1464;e.qamats27=1464;e.qamats29=1464;e.qamats33=1464;e.qamatsde=1464;e.qamatshebrew=1464;e.qamatsnarrowhebrew=1464;e.qamatsqatanhebrew=1464;e.qamatsqatannarrowhebrew=1464;e.qamatsqatanquarterhebrew=1464;e.qamatsqatanwidehebrew=1464;e.qamatsquarterhebrew=1464;e.qamatswidehebrew=1464;e.qarneyparahebrew=1439;e.qbopomofo=12561;e.qcircle=9440;e.qhook=672;e.qmonospace=65361;e.qof=1511;e.qofdagesh=64327;e.qofdageshhebrew=64327;e.qofhebrew=1511;e.qparen=9388;e.quarternote=9833;e.qubuts=1467;e.qubuts18=1467;e.qubuts25=1467;e.qubuts31=1467;e.qubutshebrew=1467;e.qubutsnarrowhebrew=1467;e.qubutsquarterhebrew=1467;e.qubutswidehebrew=1467;e.question=63;e.questionarabic=1567;e.questionarmenian=1374;e.questiondown=191;e.questiondownsmall=63423;e.questiongreek=894;e.questionmonospace=65311;e.questionsmall=63295;e.quotedbl=34;e.quotedblbase=8222;e.quotedblleft=8220;e.quotedblmonospace=65282;e.quotedblprime=12318;e.quotedblprimereversed=12317;e.quotedblright=8221;e.quoteleft=8216;e.quoteleftreversed=8219;e.quotereversed=8219;e.quoteright=8217;e.quoterightn=329;e.quotesinglbase=8218;e.quotesingle=39;e.quotesinglemonospace=65287;e.r=114;e.raarmenian=1404;e.rabengali=2480;e.racute=341;e.radeva=2352;e.radical=8730;e.radicalex=63717;e.radoverssquare=13230;e.radoverssquaredsquare=13231;e.radsquare=13229;e.rafe=1471;e.rafehebrew=1471;e.ragujarati=2736;e.ragurmukhi=2608;e.rahiragana=12425;e.rakatakana=12521;e.rakatakanahalfwidth=65431;e.ralowerdiagonalbengali=2545;e.ramiddlediagonalbengali=2544;e.ramshorn=612;e.ratio=8758;e.rbopomofo=12566;e.rcaron=345;e.rcedilla=343;e.rcircle=9441;e.rcommaaccent=343;e.rdblgrave=529;e.rdotaccent=7769;e.rdotbelow=7771;e.rdotbelowmacron=7773;e.referencemark=8251;e.reflexsubset=8838;e.reflexsuperset=8839;e.registered=174;e.registersans=63720;e.registerserif=63194;e.reharabic=1585;e.reharmenian=1408;e.rehfinalarabic=65198;e.rehiragana=12428;e.rekatakana=12524;e.rekatakanahalfwidth=65434;e.resh=1512;e.reshdageshhebrew=64328;e.reshhebrew=1512;e.reversedtilde=8765;e.reviahebrew=1431;e.reviamugrashhebrew=1431;e.revlogicalnot=8976;e.rfishhook=638;e.rfishhookreversed=639;e.rhabengali=2525;e.rhadeva=2397;e.rho=961;e.rhook=637;e.rhookturned=635;e.rhookturnedsuperior=693;e.rhosymbolgreek=1009;e.rhotichookmod=734;e.rieulacirclekorean=12913;e.rieulaparenkorean=12817;e.rieulcirclekorean=12899;e.rieulhieuhkorean=12608;e.rieulkiyeokkorean=12602;e.rieulkiyeoksioskorean=12649;e.rieulkorean=12601;e.rieulmieumkorean=12603;e.rieulpansioskorean=12652;e.rieulparenkorean=12803;e.rieulphieuphkorean=12607;e.rieulpieupkorean=12604;e.rieulpieupsioskorean=12651;e.rieulsioskorean=12605;e.rieulthieuthkorean=12606;e.rieultikeutkorean=12650;e.rieulyeorinhieuhkorean=12653;e.rightangle=8735;e.righttackbelowcmb=793;e.righttriangle=8895;e.rihiragana=12426;e.rikatakana=12522;e.rikatakanahalfwidth=65432;e.ring=730;e.ringbelowcmb=805;e.ringcmb=778;e.ringhalfleft=703;e.ringhalfleftarmenian=1369;e.ringhalfleftbelowcmb=796;e.ringhalfleftcentered=723;e.ringhalfright=702;e.ringhalfrightbelowcmb=825;e.ringhalfrightcentered=722;e.rinvertedbreve=531;e.rittorusquare=13137;e.rlinebelow=7775;e.rlongleg=636;e.rlonglegturned=634;e.rmonospace=65362;e.rohiragana=12429;e.rokatakana=12525;e.rokatakanahalfwidth=65435;e.roruathai=3619;e.rparen=9389;e.rrabengali=2524;e.rradeva=2353;e.rragurmukhi=2652;e.rreharabic=1681;e.rrehfinalarabic=64397;e.rrvocalicbengali=2528;e.rrvocalicdeva=2400;e.rrvocalicgujarati=2784;e.rrvocalicvowelsignbengali=2500;e.rrvocalicvowelsigndeva=2372;e.rrvocalicvowelsigngujarati=2756;e.rsuperior=63217;e.rtblock=9616;e.rturned=633;e.rturnedsuperior=692;e.ruhiragana=12427;e.rukatakana=12523;e.rukatakanahalfwidth=65433;e.rupeemarkbengali=2546;e.rupeesignbengali=2547;e.rupiah=63197;e.ruthai=3620;e.rvocalicbengali=2443;e.rvocalicdeva=2315;e.rvocalicgujarati=2699;e.rvocalicvowelsignbengali=2499;e.rvocalicvowelsigndeva=2371;e.rvocalicvowelsigngujarati=2755;e.s=115;e.sabengali=2488;e.sacute=347;e.sacutedotaccent=7781;e.sadarabic=1589;e.sadeva=2360;e.sadfinalarabic=65210;e.sadinitialarabic=65211;e.sadmedialarabic=65212;e.sagujarati=2744;e.sagurmukhi=2616;e.sahiragana=12373;e.sakatakana=12469;e.sakatakanahalfwidth=65403;e.sallallahoualayhewasallamarabic=65018;e.samekh=1505;e.samekhdagesh=64321;e.samekhdageshhebrew=64321;e.samekhhebrew=1505;e.saraaathai=3634;e.saraaethai=3649;e.saraaimaimalaithai=3652;e.saraaimaimuanthai=3651;e.saraamthai=3635;e.saraathai=3632;e.saraethai=3648;e.saraiileftthai=63622;e.saraiithai=3637;e.saraileftthai=63621;e.saraithai=3636;e.saraothai=3650;e.saraueeleftthai=63624;e.saraueethai=3639;e.saraueleftthai=63623;e.sarauethai=3638;e.sarauthai=3640;e.sarauuthai=3641;e.sbopomofo=12569;e.scaron=353;e.scarondotaccent=7783;e.scedilla=351;e.schwa=601;e.schwacyrillic=1241;e.schwadieresiscyrillic=1243;e.schwahook=602;e.scircle=9442;e.scircumflex=349;e.scommaaccent=537;e.sdotaccent=7777;e.sdotbelow=7779;e.sdotbelowdotaccent=7785;e.seagullbelowcmb=828;e.second=8243;e.secondtonechinese=714;e.section=167;e.seenarabic=1587;e.seenfinalarabic=65202;e.seeninitialarabic=65203;e.seenmedialarabic=65204;e.segol=1462;e.segol13=1462;e.segol1f=1462;e.segol2c=1462;e.segolhebrew=1462;e.segolnarrowhebrew=1462;e.segolquarterhebrew=1462;e.segoltahebrew=1426;e.segolwidehebrew=1462;e.seharmenian=1405;e.sehiragana=12379;e.sekatakana=12475;e.sekatakanahalfwidth=65406;e.semicolon=59;e.semicolonarabic=1563;e.semicolonmonospace=65307;e.semicolonsmall=65108;e.semivoicedmarkkana=12444;e.semivoicedmarkkanahalfwidth=65439;e.sentisquare=13090;e.sentosquare=13091;e.seven=55;e.sevenarabic=1639;e.sevenbengali=2541;e.sevencircle=9318;e.sevencircleinversesansserif=10128;e.sevendeva=2413;e.seveneighths=8542;e.sevengujarati=2797;e.sevengurmukhi=2669;e.sevenhackarabic=1639;e.sevenhangzhou=12327;e.sevenideographicparen=12838;e.seveninferior=8327;e.sevenmonospace=65303;e.sevenoldstyle=63287;e.sevenparen=9338;e.sevenperiod=9358;e.sevenpersian=1783;e.sevenroman=8566;e.sevensuperior=8311;e.seventeencircle=9328;e.seventeenparen=9348;e.seventeenperiod=9368;e.seventhai=3671;e.sfthyphen=173;e.shaarmenian=1399;e.shabengali=2486;e.shacyrillic=1096;e.shaddaarabic=1617;e.shaddadammaarabic=64609;e.shaddadammatanarabic=64606;e.shaddafathaarabic=64608;e.shaddakasraarabic=64610;e.shaddakasratanarabic=64607;e.shade=9618;e.shadedark=9619;e.shadelight=9617;e.shademedium=9618;e.shadeva=2358;e.shagujarati=2742;e.shagurmukhi=2614;e.shalshelethebrew=1427;e.shbopomofo=12565;e.shchacyrillic=1097;e.sheenarabic=1588;e.sheenfinalarabic=65206;e.sheeninitialarabic=65207;e.sheenmedialarabic=65208;e.sheicoptic=995;e.sheqel=8362;e.sheqelhebrew=8362;e.sheva=1456;e.sheva115=1456;e.sheva15=1456;e.sheva22=1456;e.sheva2e=1456;e.shevahebrew=1456;e.shevanarrowhebrew=1456;e.shevaquarterhebrew=1456;e.shevawidehebrew=1456;e.shhacyrillic=1211;e.shimacoptic=1005;e.shin=1513;e.shindagesh=64329;e.shindageshhebrew=64329;e.shindageshshindot=64300;e.shindageshshindothebrew=64300;e.shindageshsindot=64301;e.shindageshsindothebrew=64301;e.shindothebrew=1473;e.shinhebrew=1513;e.shinshindot=64298;e.shinshindothebrew=64298;e.shinsindot=64299;e.shinsindothebrew=64299;e.shook=642;e.sigma=963;e.sigma1=962;e.sigmafinal=962;e.sigmalunatesymbolgreek=1010;e.sihiragana=12375;e.sikatakana=12471;e.sikatakanahalfwidth=65404;e.siluqhebrew=1469;e.siluqlefthebrew=1469;e.similar=8764;e.sindothebrew=1474;e.siosacirclekorean=12916;e.siosaparenkorean=12820;e.sioscieuckorean=12670;e.sioscirclekorean=12902;e.sioskiyeokkorean=12666;e.sioskorean=12613;e.siosnieunkorean=12667;e.siosparenkorean=12806;e.siospieupkorean=12669;e.siostikeutkorean=12668;e.six=54;e.sixarabic=1638;e.sixbengali=2540;e.sixcircle=9317;e.sixcircleinversesansserif=10127;e.sixdeva=2412;e.sixgujarati=2796;e.sixgurmukhi=2668;e.sixhackarabic=1638;e.sixhangzhou=12326;e.sixideographicparen=12837;e.sixinferior=8326;e.sixmonospace=65302;e.sixoldstyle=63286;e.sixparen=9337;e.sixperiod=9357;e.sixpersian=1782;e.sixroman=8565;e.sixsuperior=8310;e.sixteencircle=9327;e.sixteencurrencydenominatorbengali=2553;e.sixteenparen=9347;e.sixteenperiod=9367;e.sixthai=3670;e.slash=47;e.slashmonospace=65295;e.slong=383;e.slongdotaccent=7835;e.smileface=9786;e.smonospace=65363;e.sofpasuqhebrew=1475;e.softhyphen=173;e.softsigncyrillic=1100;e.sohiragana=12381;e.sokatakana=12477;e.sokatakanahalfwidth=65407;e.soliduslongoverlaycmb=824;e.solidusshortoverlaycmb=823;e.sorusithai=3625;e.sosalathai=3624;e.sosothai=3595;e.sosuathai=3626;e.space=32;e.spacehackarabic=32;e.spade=9824;e.spadesuitblack=9824;e.spadesuitwhite=9828;e.sparen=9390;e.squarebelowcmb=827;e.squarecc=13252;e.squarecm=13213;e.squarediagonalcrosshatchfill=9641;e.squarehorizontalfill=9636;e.squarekg=13199;e.squarekm=13214;e.squarekmcapital=13262;e.squareln=13265;e.squarelog=13266;e.squaremg=13198;e.squaremil=13269;e.squaremm=13212;e.squaremsquared=13217;e.squareorthogonalcrosshatchfill=9638;e.squareupperlefttolowerrightfill=9639;e.squareupperrighttolowerleftfill=9640;e.squareverticalfill=9637;e.squarewhitewithsmallblack=9635;e.srsquare=13275;e.ssabengali=2487;e.ssadeva=2359;e.ssagujarati=2743;e.ssangcieuckorean=12617;e.ssanghieuhkorean=12677;e.ssangieungkorean=12672;e.ssangkiyeokkorean=12594;e.ssangnieunkorean=12645;e.ssangpieupkorean=12611;e.ssangsioskorean=12614;e.ssangtikeutkorean=12600;e.ssuperior=63218;e.sterling=163;e.sterlingmonospace=65505;e.strokelongoverlaycmb=822;e.strokeshortoverlaycmb=821;e.subset=8834;e.subsetnotequal=8842;e.subsetorequal=8838;e.succeeds=8827;e.suchthat=8715;e.suhiragana=12377;e.sukatakana=12473;e.sukatakanahalfwidth=65405;e.sukunarabic=1618;e.summation=8721;e.sun=9788;e.superset=8835;e.supersetnotequal=8843;e.supersetorequal=8839;e.svsquare=13276;e.syouwaerasquare=13180;e.t=116;e.tabengali=2468;e.tackdown=8868;e.tackleft=8867;e.tadeva=2340;e.tagujarati=2724;e.tagurmukhi=2596;e.taharabic=1591;e.tahfinalarabic=65218;e.tahinitialarabic=65219;e.tahiragana=12383;e.tahmedialarabic=65220;e.taisyouerasquare=13181;e.takatakana=12479;e.takatakanahalfwidth=65408;e.tatweelarabic=1600;e.tau=964;e.tav=1514;e.tavdages=64330;e.tavdagesh=64330;e.tavdageshhebrew=64330;e.tavhebrew=1514;e.tbar=359;e.tbopomofo=12554;e.tcaron=357;e.tccurl=680;e.tcedilla=355;e.tcheharabic=1670;e.tchehfinalarabic=64379;e.tchehinitialarabic=64380;e.tchehmedialarabic=64381;e.tcircle=9443;e.tcircumflexbelow=7793;e.tcommaaccent=355;e.tdieresis=7831;e.tdotaccent=7787;e.tdotbelow=7789;e.tecyrillic=1090;e.tedescendercyrillic=1197;e.teharabic=1578;e.tehfinalarabic=65174;e.tehhahinitialarabic=64674;e.tehhahisolatedarabic=64524;e.tehinitialarabic=65175;e.tehiragana=12390;e.tehjeeminitialarabic=64673;e.tehjeemisolatedarabic=64523;e.tehmarbutaarabic=1577;e.tehmarbutafinalarabic=65172;e.tehmedialarabic=65176;e.tehmeeminitialarabic=64676;e.tehmeemisolatedarabic=64526;e.tehnoonfinalarabic=64627;e.tekatakana=12486;e.tekatakanahalfwidth=65411;e.telephone=8481;e.telephoneblack=9742;e.telishagedolahebrew=1440;e.telishaqetanahebrew=1449;e.tencircle=9321;e.tenideographicparen=12841;e.tenparen=9341;e.tenperiod=9361;e.tenroman=8569;e.tesh=679;e.tet=1496;e.tetdagesh=64312;e.tetdageshhebrew=64312;e.tethebrew=1496;e.tetsecyrillic=1205;e.tevirhebrew=1435;e.tevirlefthebrew=1435;e.thabengali=2469;e.thadeva=2341;e.thagujarati=2725;e.thagurmukhi=2597;e.thalarabic=1584;e.thalfinalarabic=65196;e.thanthakhatlowleftthai=63640;e.thanthakhatlowrightthai=63639;e.thanthakhatthai=3660;e.thanthakhatupperleftthai=63638;e.theharabic=1579;e.thehfinalarabic=65178;e.thehinitialarabic=65179;e.thehmedialarabic=65180;e.thereexists=8707;e.therefore=8756;e.theta=952;e.theta1=977;e.thetasymbolgreek=977;e.thieuthacirclekorean=12921;e.thieuthaparenkorean=12825;e.thieuthcirclekorean=12907;e.thieuthkorean=12620;e.thieuthparenkorean=12811;e.thirteencircle=9324;e.thirteenparen=9344;e.thirteenperiod=9364;e.thonangmonthothai=3601;e.thook=429;e.thophuthaothai=3602;e.thorn=254;e.thothahanthai=3607;e.thothanthai=3600;e.thothongthai=3608;e.thothungthai=3606;e.thousandcyrillic=1154;e.thousandsseparatorarabic=1644;e.thousandsseparatorpersian=1644;e.three=51;e.threearabic=1635;e.threebengali=2537;e.threecircle=9314;e.threecircleinversesansserif=10124;e.threedeva=2409;e.threeeighths=8540;e.threegujarati=2793;e.threegurmukhi=2665;e.threehackarabic=1635;e.threehangzhou=12323;e.threeideographicparen=12834;e.threeinferior=8323;e.threemonospace=65299;e.threenumeratorbengali=2550;e.threeoldstyle=63283;e.threeparen=9334;e.threeperiod=9354;e.threepersian=1779;e.threequarters=190;e.threequartersemdash=63198;e.threeroman=8562;e.threesuperior=179;e.threethai=3667;e.thzsquare=13204;e.tihiragana=12385;e.tikatakana=12481;e.tikatakanahalfwidth=65409;e.tikeutacirclekorean=12912;e.tikeutaparenkorean=12816;e.tikeutcirclekorean=12898;e.tikeutkorean=12599;e.tikeutparenkorean=12802;e.tilde=732;e.tildebelowcmb=816;e.tildecmb=771;e.tildecomb=771;e.tildedoublecmb=864;e.tildeoperator=8764;e.tildeoverlaycmb=820;e.tildeverticalcmb=830;e.timescircle=8855;e.tipehahebrew=1430;e.tipehalefthebrew=1430;e.tippigurmukhi=2672;e.titlocyrilliccmb=1155;e.tiwnarmenian=1407;e.tlinebelow=7791;e.tmonospace=65364;e.toarmenian=1385;e.tohiragana=12392;e.tokatakana=12488;e.tokatakanahalfwidth=65412;e.tonebarextrahighmod=741;e.tonebarextralowmod=745;e.tonebarhighmod=742;e.tonebarlowmod=744;e.tonebarmidmod=743;e.tonefive=445;e.tonesix=389;e.tonetwo=424;e.tonos=900;e.tonsquare=13095;e.topatakthai=3599;e.tortoiseshellbracketleft=12308;e.tortoiseshellbracketleftsmall=65117;e.tortoiseshellbracketleftvertical=65081;e.tortoiseshellbracketright=12309;e.tortoiseshellbracketrightsmall=65118;e.tortoiseshellbracketrightvertical=65082;e.totaothai=3605;e.tpalatalhook=427;e.tparen=9391;e.trademark=8482;e.trademarksans=63722;e.trademarkserif=63195;e.tretroflexhook=648;e.triagdn=9660;e.triaglf=9668;e.triagrt=9658;e.triagup=9650;e.ts=678;e.tsadi=1510;e.tsadidagesh=64326;e.tsadidageshhebrew=64326;e.tsadihebrew=1510;e.tsecyrillic=1094;e.tsere=1461;e.tsere12=1461;e.tsere1e=1461;e.tsere2b=1461;e.tserehebrew=1461;e.tserenarrowhebrew=1461;e.tserequarterhebrew=1461;e.tserewidehebrew=1461;e.tshecyrillic=1115;e.tsuperior=63219;e.ttabengali=2463;e.ttadeva=2335;e.ttagujarati=2719;e.ttagurmukhi=2591;e.tteharabic=1657;e.ttehfinalarabic=64359;e.ttehinitialarabic=64360;e.ttehmedialarabic=64361;e.tthabengali=2464;e.tthadeva=2336;e.tthagujarati=2720;e.tthagurmukhi=2592;e.tturned=647;e.tuhiragana=12388;e.tukatakana=12484;e.tukatakanahalfwidth=65410;e.tusmallhiragana=12387;e.tusmallkatakana=12483;e.tusmallkatakanahalfwidth=65391;e.twelvecircle=9323;e.twelveparen=9343;e.twelveperiod=9363;e.twelveroman=8571;e.twentycircle=9331;e.twentyhangzhou=21316;e.twentyparen=9351;e.twentyperiod=9371;e.two=50;e.twoarabic=1634;e.twobengali=2536;e.twocircle=9313;e.twocircleinversesansserif=10123;e.twodeva=2408;e.twodotenleader=8229;e.twodotleader=8229;e.twodotleadervertical=65072;e.twogujarati=2792;e.twogurmukhi=2664;e.twohackarabic=1634;e.twohangzhou=12322;e.twoideographicparen=12833;e.twoinferior=8322;e.twomonospace=65298;e.twonumeratorbengali=2549;e.twooldstyle=63282;e.twoparen=9333;e.twoperiod=9353;e.twopersian=1778;e.tworoman=8561;e.twostroke=443;e.twosuperior=178;e.twothai=3666;e.twothirds=8532;e.u=117;e.uacute=250;e.ubar=649;e.ubengali=2441;e.ubopomofo=12584;e.ubreve=365;e.ucaron=468;e.ucircle=9444;e.ucircumflex=251;e.ucircumflexbelow=7799;e.ucyrillic=1091;e.udattadeva=2385;e.udblacute=369;e.udblgrave=533;e.udeva=2313;e.udieresis=252;e.udieresisacute=472;e.udieresisbelow=7795;e.udieresiscaron=474;e.udieresiscyrillic=1265;e.udieresisgrave=476;e.udieresismacron=470;e.udotbelow=7909;e.ugrave=249;e.ugujarati=2697;e.ugurmukhi=2569;e.uhiragana=12358;e.uhookabove=7911;e.uhorn=432;e.uhornacute=7913;e.uhorndotbelow=7921;e.uhorngrave=7915;e.uhornhookabove=7917;e.uhorntilde=7919;e.uhungarumlaut=369;e.uhungarumlautcyrillic=1267;e.uinvertedbreve=535;e.ukatakana=12454;e.ukatakanahalfwidth=65395;e.ukcyrillic=1145;e.ukorean=12636;e.umacron=363;e.umacroncyrillic=1263;e.umacrondieresis=7803;e.umatragurmukhi=2625;e.umonospace=65365;e.underscore=95;e.underscoredbl=8215;e.underscoremonospace=65343;e.underscorevertical=65075;e.underscorewavy=65103;e.union=8746;e.universal=8704;e.uogonek=371;e.uparen=9392;e.upblock=9600;e.upperdothebrew=1476;e.upsilon=965;e.upsilondieresis=971;e.upsilondieresistonos=944;e.upsilonlatin=650;e.upsilontonos=973;e.uptackbelowcmb=797;e.uptackmod=724;e.uragurmukhi=2675;e.uring=367;e.ushortcyrillic=1118;e.usmallhiragana=12357;e.usmallkatakana=12453;e.usmallkatakanahalfwidth=65385;e.ustraightcyrillic=1199;e.ustraightstrokecyrillic=1201;e.utilde=361;e.utildeacute=7801;e.utildebelow=7797;e.uubengali=2442;e.uudeva=2314;e.uugujarati=2698;e.uugurmukhi=2570;e.uumatragurmukhi=2626;e.uuvowelsignbengali=2498;e.uuvowelsigndeva=2370;e.uuvowelsigngujarati=2754;e.uvowelsignbengali=2497;e.uvowelsigndeva=2369;e.uvowelsigngujarati=2753;e.v=118;e.vadeva=2357;e.vagujarati=2741;e.vagurmukhi=2613;e.vakatakana=12535;e.vav=1493;e.vavdagesh=64309;e.vavdagesh65=64309;e.vavdageshhebrew=64309;e.vavhebrew=1493;e.vavholam=64331;e.vavholamhebrew=64331;e.vavvavhebrew=1520;e.vavyodhebrew=1521;e.vcircle=9445;e.vdotbelow=7807;e.vecyrillic=1074;e.veharabic=1700;e.vehfinalarabic=64363;e.vehinitialarabic=64364;e.vehmedialarabic=64365;e.vekatakana=12537;e.venus=9792;e.verticalbar=124;e.verticallineabovecmb=781;e.verticallinebelowcmb=809;e.verticallinelowmod=716;e.verticallinemod=712;e.vewarmenian=1406;e.vhook=651;e.vikatakana=12536;e.viramabengali=2509;e.viramadeva=2381;e.viramagujarati=2765;e.visargabengali=2435;e.visargadeva=2307;e.visargagujarati=2691;e.vmonospace=65366;e.voarmenian=1400;e.voicediterationhiragana=12446;e.voicediterationkatakana=12542;e.voicedmarkkana=12443;e.voicedmarkkanahalfwidth=65438;e.vokatakana=12538;e.vparen=9393;e.vtilde=7805;e.vturned=652;e.vuhiragana=12436;e.vukatakana=12532;e.w=119;e.wacute=7811;e.waekorean=12633;e.wahiragana=12431;e.wakatakana=12527;e.wakatakanahalfwidth=65436;e.wakorean=12632;e.wasmallhiragana=12430;e.wasmallkatakana=12526;e.wattosquare=13143;e.wavedash=12316;e.wavyunderscorevertical=65076;e.wawarabic=1608;e.wawfinalarabic=65262;e.wawhamzaabovearabic=1572;e.wawhamzaabovefinalarabic=65158;e.wbsquare=13277;e.wcircle=9446;e.wcircumflex=373;e.wdieresis=7813;e.wdotaccent=7815;e.wdotbelow=7817;e.wehiragana=12433;e.weierstrass=8472;e.wekatakana=12529;e.wekorean=12638;e.weokorean=12637;e.wgrave=7809;e.whitebullet=9702;e.whitecircle=9675;e.whitecircleinverse=9689;e.whitecornerbracketleft=12302;e.whitecornerbracketleftvertical=65091;e.whitecornerbracketright=12303;e.whitecornerbracketrightvertical=65092;e.whitediamond=9671;e.whitediamondcontainingblacksmalldiamond=9672;e.whitedownpointingsmalltriangle=9663;e.whitedownpointingtriangle=9661;e.whiteleftpointingsmalltriangle=9667;e.whiteleftpointingtriangle=9665;e.whitelenticularbracketleft=12310;e.whitelenticularbracketright=12311;e.whiterightpointingsmalltriangle=9657;e.whiterightpointingtriangle=9655;e.whitesmallsquare=9643;e.whitesmilingface=9786;e.whitesquare=9633;e.whitestar=9734;e.whitetelephone=9743;e.whitetortoiseshellbracketleft=12312;e.whitetortoiseshellbracketright=12313;e.whiteuppointingsmalltriangle=9653;e.whiteuppointingtriangle=9651;e.wihiragana=12432;e.wikatakana=12528;e.wikorean=12639;e.wmonospace=65367;e.wohiragana=12434;e.wokatakana=12530;e.wokatakanahalfwidth=65382;e.won=8361;e.wonmonospace=65510;e.wowaenthai=3623;e.wparen=9394;e.wring=7832;e.wsuperior=695;e.wturned=653;e.wynn=447;e.x=120;e.xabovecmb=829;e.xbopomofo=12562;e.xcircle=9447;e.xdieresis=7821;e.xdotaccent=7819;e.xeharmenian=1389;e.xi=958;e.xmonospace=65368;e.xparen=9395;e.xsuperior=739;e.y=121;e.yaadosquare=13134;e.yabengali=2479;e.yacute=253;e.yadeva=2351;e.yaekorean=12626;e.yagujarati=2735;e.yagurmukhi=2607;e.yahiragana=12420;e.yakatakana=12516;e.yakatakanahalfwidth=65428;e.yakorean=12625;e.yamakkanthai=3662;e.yasmallhiragana=12419;e.yasmallkatakana=12515;e.yasmallkatakanahalfwidth=65388;e.yatcyrillic=1123;e.ycircle=9448;e.ycircumflex=375;e.ydieresis=255;e.ydotaccent=7823;e.ydotbelow=7925;e.yeharabic=1610;e.yehbarreearabic=1746;e.yehbarreefinalarabic=64431;e.yehfinalarabic=65266;e.yehhamzaabovearabic=1574;e.yehhamzaabovefinalarabic=65162;e.yehhamzaaboveinitialarabic=65163;e.yehhamzaabovemedialarabic=65164;e.yehinitialarabic=65267;e.yehmedialarabic=65268;e.yehmeeminitialarabic=64733;e.yehmeemisolatedarabic=64600;e.yehnoonfinalarabic=64660;e.yehthreedotsbelowarabic=1745;e.yekorean=12630;e.yen=165;e.yenmonospace=65509;e.yeokorean=12629;e.yeorinhieuhkorean=12678;e.yerahbenyomohebrew=1450;e.yerahbenyomolefthebrew=1450;e.yericyrillic=1099;e.yerudieresiscyrillic=1273;e.yesieungkorean=12673;e.yesieungpansioskorean=12675;e.yesieungsioskorean=12674;e.yetivhebrew=1434;e.ygrave=7923;e.yhook=436;e.yhookabove=7927;e.yiarmenian=1397;e.yicyrillic=1111;e.yikorean=12642;e.yinyang=9775;e.yiwnarmenian=1410;e.ymonospace=65369;e.yod=1497;e.yoddagesh=64313;e.yoddageshhebrew=64313;e.yodhebrew=1497;e.yodyodhebrew=1522;e.yodyodpatahhebrew=64287;e.yohiragana=12424;e.yoikorean=12681;e.yokatakana=12520;e.yokatakanahalfwidth=65430;e.yokorean=12635;e.yosmallhiragana=12423;e.yosmallkatakana=12519;e.yosmallkatakanahalfwidth=65390;e.yotgreek=1011;e.yoyaekorean=12680;e.yoyakorean=12679;e.yoyakthai=3618;e.yoyingthai=3597;e.yparen=9396;e.ypogegrammeni=890;e.ypogegrammenigreekcmb=837;e.yr=422;e.yring=7833;e.ysuperior=696;e.ytilde=7929;e.yturned=654;e.yuhiragana=12422;e.yuikorean=12684;e.yukatakana=12518;e.yukatakanahalfwidth=65429;e.yukorean=12640;e.yusbigcyrillic=1131;e.yusbigiotifiedcyrillic=1133;e.yuslittlecyrillic=1127;e.yuslittleiotifiedcyrillic=1129;e.yusmallhiragana=12421;e.yusmallkatakana=12517;e.yusmallkatakanahalfwidth=65389;e.yuyekorean=12683;e.yuyeokorean=12682;e.yyabengali=2527;e.yyadeva=2399;e.z=122;e.zaarmenian=1382;e.zacute=378;e.zadeva=2395;e.zagurmukhi=2651;e.zaharabic=1592;e.zahfinalarabic=65222;e.zahinitialarabic=65223;e.zahiragana=12374;e.zahmedialarabic=65224;e.zainarabic=1586;e.zainfinalarabic=65200;e.zakatakana=12470;e.zaqefgadolhebrew=1429;e.zaqefqatanhebrew=1428;e.zarqahebrew=1432;e.zayin=1494;e.zayindagesh=64310;e.zayindageshhebrew=64310;e.zayinhebrew=1494;e.zbopomofo=12567;e.zcaron=382;e.zcircle=9449;e.zcircumflex=7825;e.zcurl=657;e.zdot=380;e.zdotaccent=380;e.zdotbelow=7827;e.zecyrillic=1079;e.zedescendercyrillic=1177;e.zedieresiscyrillic=1247;e.zehiragana=12380;e.zekatakana=12476;e.zero=48;e.zeroarabic=1632;e.zerobengali=2534;e.zerodeva=2406;e.zerogujarati=2790;e.zerogurmukhi=2662;e.zerohackarabic=1632;e.zeroinferior=8320;e.zeromonospace=65296;e.zerooldstyle=63280;e.zeropersian=1776;e.zerosuperior=8304;e.zerothai=3664;e.zerowidthjoiner=65279;e.zerowidthnonjoiner=8204;e.zerowidthspace=8203;e.zeta=950;e.zhbopomofo=12563;e.zhearmenian=1386;e.zhebrevecyrillic=1218;e.zhecyrillic=1078;e.zhedescendercyrillic=1175;e.zhedieresiscyrillic=1245;e.zihiragana=12376;e.zikatakana=12472;e.zinorhebrew=1454;e.zlinebelow=7829;e.zmonospace=65370;e.zohiragana=12382;e.zokatakana=12478;e.zparen=9397;e.zretroflexhook=656;e.zstroke=438;e.zuhiragana=12378;e.zukatakana=12474;e[".notdef"]=0;e.angbracketleftbig=9001;e.angbracketleftBig=9001;e.angbracketleftbigg=9001;e.angbracketleftBigg=9001;e.angbracketrightBig=9002;e.angbracketrightbig=9002;e.angbracketrightBigg=9002;e.angbracketrightbigg=9002;e.arrowhookleft=8618;e.arrowhookright=8617;e.arrowlefttophalf=8636;e.arrowleftbothalf=8637;e.arrownortheast=8599;e.arrownorthwest=8598;e.arrowrighttophalf=8640;e.arrowrightbothalf=8641;e.arrowsoutheast=8600;e.arrowsouthwest=8601;e.backslashbig=8726;e.backslashBig=8726;e.backslashBigg=8726;e.backslashbigg=8726;e.bardbl=8214;e.bracehtipdownleft=65079;e.bracehtipdownright=65079;e.bracehtipupleft=65080;e.bracehtipupright=65080;e.braceleftBig=123;e.braceleftbig=123;e.braceleftbigg=123;e.braceleftBigg=123;e.bracerightBig=125;e.bracerightbig=125;e.bracerightbigg=125;e.bracerightBigg=125;e.bracketleftbig=91;e.bracketleftBig=91;e.bracketleftbigg=91;e.bracketleftBigg=91;e.bracketrightBig=93;e.bracketrightbig=93;e.bracketrightbigg=93;e.bracketrightBigg=93;e.ceilingleftbig=8968;e.ceilingleftBig=8968;e.ceilingleftBigg=8968;e.ceilingleftbigg=8968;e.ceilingrightbig=8969;e.ceilingrightBig=8969;e.ceilingrightbigg=8969;e.ceilingrightBigg=8969;e.circledotdisplay=8857;e.circledottext=8857;e.circlemultiplydisplay=8855;e.circlemultiplytext=8855;e.circleplusdisplay=8853;e.circleplustext=8853;e.contintegraldisplay=8750;e.contintegraltext=8750;e.coproductdisplay=8720;e.coproducttext=8720;e.floorleftBig=8970;e.floorleftbig=8970;e.floorleftbigg=8970;e.floorleftBigg=8970;e.floorrightbig=8971;e.floorrightBig=8971;e.floorrightBigg=8971;e.floorrightbigg=8971;e.hatwide=770;e.hatwider=770;e.hatwidest=770;e.intercal=7488;e.integraldisplay=8747;e.integraltext=8747;e.intersectiondisplay=8898;e.intersectiontext=8898;e.logicalanddisplay=8743;e.logicalandtext=8743;e.logicalordisplay=8744;e.logicalortext=8744;e.parenleftBig=40;e.parenleftbig=40;e.parenleftBigg=40;e.parenleftbigg=40;e.parenrightBig=41;e.parenrightbig=41;e.parenrightBigg=41;e.parenrightbigg=41;e.prime=8242;e.productdisplay=8719;e.producttext=8719;e.radicalbig=8730;e.radicalBig=8730;e.radicalBigg=8730;e.radicalbigg=8730;e.radicalbt=8730;e.radicaltp=8730;e.radicalvertex=8730;e.slashbig=47;e.slashBig=47;e.slashBigg=47;e.slashbigg=47;e.summationdisplay=8721;e.summationtext=8721;e.tildewide=732;e.tildewider=732;e.tildewidest=732;e.uniondisplay=8899;e.unionmultidisplay=8846;e.unionmultitext=8846;e.unionsqdisplay=8852;e.unionsqtext=8852;e.uniontext=8899;e.vextenddouble=8741;e.vextendsingle=8739})),n=r((function(e){e.space=32;e.a1=9985;e.a2=9986;e.a202=9987;e.a3=9988;e.a4=9742;e.a5=9990;e.a119=9991;e.a118=9992;e.a117=9993;e.a11=9755;e.a12=9758;e.a13=9996;e.a14=9997;e.a15=9998;e.a16=9999;e.a105=1e4;e.a17=10001;e.a18=10002;e.a19=10003;e.a20=10004;e.a21=10005;e.a22=10006;e.a23=10007;e.a24=10008;e.a25=10009;e.a26=10010;e.a27=10011;e.a28=10012;e.a6=10013;e.a7=10014;e.a8=10015;e.a9=10016;e.a10=10017;e.a29=10018;e.a30=10019;e.a31=10020;e.a32=10021;e.a33=10022;e.a34=10023;e.a35=9733;e.a36=10025;e.a37=10026;e.a38=10027;e.a39=10028;e.a40=10029;e.a41=10030;e.a42=10031;e.a43=10032;e.a44=10033;e.a45=10034;e.a46=10035;e.a47=10036;e.a48=10037;e.a49=10038;e.a50=10039;e.a51=10040;e.a52=10041;e.a53=10042;e.a54=10043;e.a55=10044;e.a56=10045;e.a57=10046;e.a58=10047;e.a59=10048;e.a60=10049;e.a61=10050;e.a62=10051;e.a63=10052;e.a64=10053;e.a65=10054;e.a66=10055;e.a67=10056;e.a68=10057;e.a69=10058;e.a70=10059;e.a71=9679;e.a72=10061;e.a73=9632;e.a74=10063;e.a203=10064;e.a75=10065;e.a204=10066;e.a76=9650;e.a77=9660;e.a78=9670;e.a79=10070;e.a81=9687;e.a82=10072;e.a83=10073;e.a84=10074;e.a97=10075;e.a98=10076;e.a99=10077;e.a100=10078;e.a101=10081;e.a102=10082;e.a103=10083;e.a104=10084;e.a106=10085;e.a107=10086;e.a108=10087;e.a112=9827;e.a111=9830;e.a110=9829;e.a109=9824;e.a120=9312;e.a121=9313;e.a122=9314;e.a123=9315;e.a124=9316;e.a125=9317;e.a126=9318;e.a127=9319;e.a128=9320;e.a129=9321;e.a130=10102;e.a131=10103;e.a132=10104;e.a133=10105;e.a134=10106;e.a135=10107;e.a136=10108;e.a137=10109;e.a138=10110;e.a139=10111;e.a140=10112;e.a141=10113;e.a142=10114;e.a143=10115;e.a144=10116;e.a145=10117;e.a146=10118;e.a147=10119;e.a148=10120;e.a149=10121;e.a150=10122;e.a151=10123;e.a152=10124;e.a153=10125;e.a154=10126;e.a155=10127;e.a156=10128;e.a157=10129;e.a158=10130;e.a159=10131;e.a160=10132;e.a161=8594;e.a163=8596;e.a164=8597;e.a196=10136;e.a165=10137;e.a192=10138;e.a166=10139;e.a167=10140;e.a168=10141;e.a169=10142;e.a170=10143;e.a171=10144;e.a172=10145;e.a173=10146;e.a162=10147;e.a174=10148;e.a175=10149;e.a176=10150;e.a177=10151;e.a178=10152;e.a179=10153;e.a193=10154;e.a180=10155;e.a199=10156;e.a181=10157;e.a200=10158;e.a182=10159;e.a201=10161;e.a183=10162;e.a184=10163;e.a197=10164;e.a185=10165;e.a194=10166;e.a198=10167;e.a186=10168;e.a195=10169;e.a187=10170;e.a188=10171;e.a189=10172;e.a190=10173;e.a191=10174;e.a89=10088;e.a90=10089;e.a93=10090;e.a94=10091;e.a91=10092;e.a92=10093;e.a205=10094;e.a85=10095;e.a206=10096;e.a86=10097;e.a87=10098;e.a88=10099;e.a95=10100;e.a96=10101;e[".notdef"]=0}));t.getGlyphsUnicode=i;t.getDingbatsGlyphsUnicode=n},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getSupplementalGlyphMapForCalibri=t.getSupplementalGlyphMapForArialBlack=t.getGlyphMapForStandardFonts=t.getSymbolsFonts=t.getSerifFonts=t.getNonStdFontMap=t.getStdFontMap=void 0;var r=a(7);const i=(0,r.getLookupTableFactory)((function(e){e.ArialNarrow="Helvetica";e["ArialNarrow-Bold"]="Helvetica-Bold";e["ArialNarrow-BoldItalic"]="Helvetica-BoldOblique";e["ArialNarrow-Italic"]="Helvetica-Oblique";e.ArialBlack="Helvetica";e["ArialBlack-Bold"]="Helvetica-Bold";e["ArialBlack-BoldItalic"]="Helvetica-BoldOblique";e["ArialBlack-Italic"]="Helvetica-Oblique";e["Arial-Black"]="Helvetica";e["Arial-Black-Bold"]="Helvetica-Bold";e["Arial-Black-BoldItalic"]="Helvetica-BoldOblique";e["Arial-Black-Italic"]="Helvetica-Oblique";e.Arial="Helvetica";e["Arial-Bold"]="Helvetica-Bold";e["Arial-BoldItalic"]="Helvetica-BoldOblique";e["Arial-Italic"]="Helvetica-Oblique";e["Arial-BoldItalicMT"]="Helvetica-BoldOblique";e["Arial-BoldMT"]="Helvetica-Bold";e["Arial-ItalicMT"]="Helvetica-Oblique";e.ArialMT="Helvetica";e["Courier-Bold"]="Courier-Bold";e["Courier-BoldItalic"]="Courier-BoldOblique";e["Courier-Italic"]="Courier-Oblique";e.CourierNew="Courier";e["CourierNew-Bold"]="Courier-Bold";e["CourierNew-BoldItalic"]="Courier-BoldOblique";e["CourierNew-Italic"]="Courier-Oblique";e["CourierNewPS-BoldItalicMT"]="Courier-BoldOblique";e["CourierNewPS-BoldMT"]="Courier-Bold";e["CourierNewPS-ItalicMT"]="Courier-Oblique";e.CourierNewPSMT="Courier";e.Helvetica="Helvetica";e["Helvetica-Bold"]="Helvetica-Bold";e["Helvetica-BoldItalic"]="Helvetica-BoldOblique";e["Helvetica-BoldOblique"]="Helvetica-BoldOblique";e["Helvetica-Italic"]="Helvetica-Oblique";e["Helvetica-Oblique"]="Helvetica-Oblique";e["Symbol-Bold"]="Symbol";e["Symbol-BoldItalic"]="Symbol";e["Symbol-Italic"]="Symbol";e.TimesNewRoman="Times-Roman";e["TimesNewRoman-Bold"]="Times-Bold";e["TimesNewRoman-BoldItalic"]="Times-BoldItalic";e["TimesNewRoman-Italic"]="Times-Italic";e.TimesNewRomanPS="Times-Roman";e["TimesNewRomanPS-Bold"]="Times-Bold";e["TimesNewRomanPS-BoldItalic"]="Times-BoldItalic";e["TimesNewRomanPS-BoldItalicMT"]="Times-BoldItalic";e["TimesNewRomanPS-BoldMT"]="Times-Bold";e["TimesNewRomanPS-Italic"]="Times-Italic";e["TimesNewRomanPS-ItalicMT"]="Times-Italic";e.TimesNewRomanPSMT="Times-Roman";e["TimesNewRomanPSMT-Bold"]="Times-Bold";e["TimesNewRomanPSMT-BoldItalic"]="Times-BoldItalic";e["TimesNewRomanPSMT-Italic"]="Times-Italic"}));t.getStdFontMap=i;const n=(0,r.getLookupTableFactory)((function(e){e.Calibri="Helvetica";e["Calibri-Bold"]="Helvetica-Bold";e["Calibri-BoldItalic"]="Helvetica-BoldOblique";e["Calibri-Italic"]="Helvetica-Oblique";e.CenturyGothic="Helvetica";e["CenturyGothic-Bold"]="Helvetica-Bold";e["CenturyGothic-BoldItalic"]="Helvetica-BoldOblique";e["CenturyGothic-Italic"]="Helvetica-Oblique";e.ComicSansMS="Comic Sans MS";e["ComicSansMS-Bold"]="Comic Sans MS-Bold";e["ComicSansMS-BoldItalic"]="Comic Sans MS-BoldItalic";e["ComicSansMS-Italic"]="Comic Sans MS-Italic";e.LucidaConsole="Courier";e["LucidaConsole-Bold"]="Courier-Bold";e["LucidaConsole-BoldItalic"]="Courier-BoldOblique";e["LucidaConsole-Italic"]="Courier-Oblique";e["LucidaSans-Demi"]="Helvetica-Bold";e["MS-Gothic"]="MS Gothic";e["MS-Gothic-Bold"]="MS Gothic-Bold";e["MS-Gothic-BoldItalic"]="MS Gothic-BoldItalic";e["MS-Gothic-Italic"]="MS Gothic-Italic";e["MS-Mincho"]="MS Mincho";e["MS-Mincho-Bold"]="MS Mincho-Bold";e["MS-Mincho-BoldItalic"]="MS Mincho-BoldItalic";e["MS-Mincho-Italic"]="MS Mincho-Italic";e["MS-PGothic"]="MS PGothic";e["MS-PGothic-Bold"]="MS PGothic-Bold";e["MS-PGothic-BoldItalic"]="MS PGothic-BoldItalic";e["MS-PGothic-Italic"]="MS PGothic-Italic";e["MS-PMincho"]="MS PMincho";e["MS-PMincho-Bold"]="MS PMincho-Bold";e["MS-PMincho-BoldItalic"]="MS PMincho-BoldItalic";e["MS-PMincho-Italic"]="MS PMincho-Italic";e.NuptialScript="Times-Italic";e.SegoeUISymbol="Helvetica";e.Wingdings="ZapfDingbats";e["Wingdings-Regular"]="ZapfDingbats"}));t.getNonStdFontMap=n;const s=(0,r.getLookupTableFactory)((function(e){e["Adobe Jenson"]=!0;e["Adobe Text"]=!0;e.Albertus=!0;e.Aldus=!0;e.Alexandria=!0;e.Algerian=!0;e["American Typewriter"]=!0;e.Antiqua=!0;e.Apex=!0;e.Arno=!0;e.Aster=!0;e.Aurora=!0;e.Baskerville=!0;e.Bell=!0;e.Bembo=!0;e["Bembo Schoolbook"]=!0;e.Benguiat=!0;e["Berkeley Old Style"]=!0;e["Bernhard Modern"]=!0;e["Berthold City"]=!0;e.Bodoni=!0;e["Bauer Bodoni"]=!0;e["Book Antiqua"]=!0;e.Bookman=!0;e["Bordeaux Roman"]=!0;e["Californian FB"]=!0;e.Calisto=!0;e.Calvert=!0;e.Capitals=!0;e.Cambria=!0;e.Cartier=!0;e.Caslon=!0;e.Catull=!0;e.Centaur=!0;e["Century Old Style"]=!0;e["Century Schoolbook"]=!0;e.Chaparral=!0;e["Charis SIL"]=!0;e.Cheltenham=!0;e["Cholla Slab"]=!0;e.Clarendon=!0;e.Clearface=!0;e.Cochin=!0;e.Colonna=!0;e["Computer Modern"]=!0;e["Concrete Roman"]=!0;e.Constantia=!0;e["Cooper Black"]=!0;e.Corona=!0;e.Ecotype=!0;e.Egyptienne=!0;e.Elephant=!0;e.Excelsior=!0;e.Fairfield=!0;e["FF Scala"]=!0;e.Folkard=!0;e.Footlight=!0;e.FreeSerif=!0;e["Friz Quadrata"]=!0;e.Garamond=!0;e.Gentium=!0;e.Georgia=!0;e.Gloucester=!0;e["Goudy Old Style"]=!0;e["Goudy Schoolbook"]=!0;e["Goudy Pro Font"]=!0;e.Granjon=!0;e["Guardian Egyptian"]=!0;e.Heather=!0;e.Hercules=!0;e["High Tower Text"]=!0;e.Hiroshige=!0;e["Hoefler Text"]=!0;e["Humana Serif"]=!0;e.Imprint=!0;e["Ionic No. 5"]=!0;e.Janson=!0;e.Joanna=!0;e.Korinna=!0;e.Lexicon=!0;e["Liberation Serif"]=!0;e["Linux Libertine"]=!0;e.Literaturnaya=!0;e.Lucida=!0;e["Lucida Bright"]=!0;e.Melior=!0;e.Memphis=!0;e.Miller=!0;e.Minion=!0;e.Modern=!0;e["Mona Lisa"]=!0;e["Mrs Eaves"]=!0;e["MS Serif"]=!0;e["Museo Slab"]=!0;e["New York"]=!0;e["Nimbus Roman"]=!0;e["NPS Rawlinson Roadway"]=!0;e.NuptialScript=!0;e.Palatino=!0;e.Perpetua=!0;e.Plantin=!0;e["Plantin Schoolbook"]=!0;e.Playbill=!0;e["Poor Richard"]=!0;e["Rawlinson Roadway"]=!0;e.Renault=!0;e.Requiem=!0;e.Rockwell=!0;e.Roman=!0;e["Rotis Serif"]=!0;e.Sabon=!0;e.Scala=!0;e.Seagull=!0;e.Sistina=!0;e.Souvenir=!0;e.STIX=!0;e["Stone Informal"]=!0;e["Stone Serif"]=!0;e.Sylfaen=!0;e.Times=!0;e.Trajan=!0;e["Trinité"]=!0;e["Trump Mediaeval"]=!0;e.Utopia=!0;e["Vale Type"]=!0;e["Bitstream Vera"]=!0;e["Vera Serif"]=!0;e.Versailles=!0;e.Wanted=!0;e.Weiss=!0;e["Wide Latin"]=!0;e.Windsor=!0;e.XITS=!0}));t.getSerifFonts=s;const o=(0,r.getLookupTableFactory)((function(e){e.Dingbats=!0;e.Symbol=!0;e.ZapfDingbats=!0}));t.getSymbolsFonts=o;const c=(0,r.getLookupTableFactory)((function(e){e[2]=10;e[3]=32;e[4]=33;e[5]=34;e[6]=35;e[7]=36;e[8]=37;e[9]=38;e[10]=39;e[11]=40;e[12]=41;e[13]=42;e[14]=43;e[15]=44;e[16]=45;e[17]=46;e[18]=47;e[19]=48;e[20]=49;e[21]=50;e[22]=51;e[23]=52;e[24]=53;e[25]=54;e[26]=55;e[27]=56;e[28]=57;e[29]=58;e[30]=894;e[31]=60;e[32]=61;e[33]=62;e[34]=63;e[35]=64;e[36]=65;e[37]=66;e[38]=67;e[39]=68;e[40]=69;e[41]=70;e[42]=71;e[43]=72;e[44]=73;e[45]=74;e[46]=75;e[47]=76;e[48]=77;e[49]=78;e[50]=79;e[51]=80;e[52]=81;e[53]=82;e[54]=83;e[55]=84;e[56]=85;e[57]=86;e[58]=87;e[59]=88;e[60]=89;e[61]=90;e[62]=91;e[63]=92;e[64]=93;e[65]=94;e[66]=95;e[67]=96;e[68]=97;e[69]=98;e[70]=99;e[71]=100;e[72]=101;e[73]=102;e[74]=103;e[75]=104;e[76]=105;e[77]=106;e[78]=107;e[79]=108;e[80]=109;e[81]=110;e[82]=111;e[83]=112;e[84]=113;e[85]=114;e[86]=115;e[87]=116;e[88]=117;e[89]=118;e[90]=119;e[91]=120;e[92]=121;e[93]=122;e[94]=123;e[95]=124;e[96]=125;e[97]=126;e[98]=196;e[99]=197;e[100]=199;e[101]=201;e[102]=209;e[103]=214;e[104]=220;e[105]=225;e[106]=224;e[107]=226;e[108]=228;e[109]=227;e[110]=229;e[111]=231;e[112]=233;e[113]=232;e[114]=234;e[115]=235;e[116]=237;e[117]=236;e[118]=238;e[119]=239;e[120]=241;e[121]=243;e[122]=242;e[123]=244;e[124]=246;e[125]=245;e[126]=250;e[127]=249;e[128]=251;e[129]=252;e[130]=8224;e[131]=176;e[132]=162;e[133]=163;e[134]=167;e[135]=8226;e[136]=182;e[137]=223;e[138]=174;e[139]=169;e[140]=8482;e[141]=180;e[142]=168;e[143]=8800;e[144]=198;e[145]=216;e[146]=8734;e[147]=177;e[148]=8804;e[149]=8805;e[150]=165;e[151]=181;e[152]=8706;e[153]=8721;e[154]=8719;e[156]=8747;e[157]=170;e[158]=186;e[159]=8486;e[160]=230;e[161]=248;e[162]=191;e[163]=161;e[164]=172;e[165]=8730;e[166]=402;e[167]=8776;e[168]=8710;e[169]=171;e[170]=187;e[171]=8230;e[210]=218;e[223]=711;e[224]=321;e[225]=322;e[227]=353;e[229]=382;e[234]=253;e[252]=263;e[253]=268;e[254]=269;e[258]=258;e[260]=260;e[261]=261;e[265]=280;e[266]=281;e[268]=283;e[269]=313;e[275]=323;e[276]=324;e[278]=328;e[284]=345;e[285]=346;e[286]=347;e[292]=367;e[295]=377;e[296]=378;e[298]=380;e[305]=963;e[306]=964;e[307]=966;e[308]=8215;e[309]=8252;e[310]=8319;e[311]=8359;e[312]=8592;e[313]=8593;e[337]=9552;e[493]=1039;e[494]=1040;e[705]=1524;e[706]=8362;e[710]=64288;e[711]=64298;e[759]=1617;e[761]=1776;e[763]=1778;e[775]=1652;e[777]=1764;e[778]=1780;e[779]=1781;e[780]=1782;e[782]=771;e[783]=64726;e[786]=8363;e[788]=8532;e[790]=768;e[791]=769;e[792]=768;e[795]=803;e[797]=64336;e[798]=64337;e[799]=64342;e[800]=64343;e[801]=64344;e[802]=64345;e[803]=64362;e[804]=64363;e[805]=64364;e[2424]=7821;e[2425]=7822;e[2426]=7823;e[2427]=7824;e[2428]=7825;e[2429]=7826;e[2430]=7827;e[2433]=7682;e[2678]=8045;e[2679]=8046;e[2830]=1552;e[2838]=686;e[2840]=751;e[2842]=753;e[2843]=754;e[2844]=755;e[2846]=757;e[2856]=767;e[2857]=848;e[2858]=849;e[2862]=853;e[2863]=854;e[2864]=855;e[2865]=861;e[2866]=862;e[2906]=7460;e[2908]=7462;e[2909]=7463;e[2910]=7464;e[2912]=7466;e[2913]=7467;e[2914]=7468;e[2916]=7470;e[2917]=7471;e[2918]=7472;e[2920]=7474;e[2921]=7475;e[2922]=7476;e[2924]=7478;e[2925]=7479;e[2926]=7480;e[2928]=7482;e[2929]=7483;e[2930]=7484;e[2932]=7486;e[2933]=7487;e[2934]=7488;e[2936]=7490;e[2937]=7491;e[2938]=7492;e[2940]=7494;e[2941]=7495;e[2942]=7496;e[2944]=7498;e[2946]=7500;e[2948]=7502;e[2950]=7504;e[2951]=7505;e[2952]=7506;e[2954]=7508;e[2955]=7509;e[2956]=7510;e[2958]=7512;e[2959]=7513;e[2960]=7514;e[2962]=7516;e[2963]=7517;e[2964]=7518;e[2966]=7520;e[2967]=7521;e[2968]=7522;e[2970]=7524;e[2971]=7525;e[2972]=7526;e[2974]=7528;e[2975]=7529;e[2976]=7530;e[2978]=1537;e[2979]=1538;e[2980]=1539;e[2982]=1549;e[2983]=1551;e[2984]=1552;e[2986]=1554;e[2987]=1555;e[2988]=1556;e[2990]=1623;e[2991]=1624;e[2995]=1775;e[2999]=1791;e[3002]=64290;e[3003]=64291;e[3004]=64292;e[3006]=64294;e[3007]=64295;e[3008]=64296;e[3011]=1900;e[3014]=8223;e[3015]=8244;e[3017]=7532;e[3018]=7533;e[3019]=7534;e[3075]=7590;e[3076]=7591;e[3079]=7594;e[3080]=7595;e[3083]=7598;e[3084]=7599;e[3087]=7602;e[3088]=7603;e[3091]=7606;e[3092]=7607;e[3095]=7610;e[3096]=7611;e[3099]=7614;e[3100]=7615;e[3103]=7618;e[3104]=7619;e[3107]=8337;e[3108]=8338;e[3116]=1884;e[3119]=1885;e[3120]=1885;e[3123]=1886;e[3124]=1886;e[3127]=1887;e[3128]=1887;e[3131]=1888;e[3132]=1888;e[3135]=1889;e[3136]=1889;e[3139]=1890;e[3140]=1890;e[3143]=1891;e[3144]=1891;e[3147]=1892;e[3148]=1892;e[3153]=580;e[3154]=581;e[3157]=584;e[3158]=585;e[3161]=588;e[3162]=589;e[3165]=891;e[3166]=892;e[3169]=1274;e[3170]=1275;e[3173]=1278;e[3174]=1279;e[3181]=7622;e[3182]=7623;e[3282]=11799;e[3316]=578;e[3379]=42785;e[3393]=1159;e[3416]=8377}));t.getGlyphMapForStandardFonts=c;const l=(0,r.getLookupTableFactory)((function(e){e[227]=322;e[264]=261;e[291]=346}));t.getSupplementalGlyphMapForArialBlack=l;const h=(0,r.getLookupTableFactory)((function(e){e[1]=32;e[4]=65;e[17]=66;e[18]=67;e[24]=68;e[28]=69;e[38]=70;e[39]=71;e[44]=72;e[47]=73;e[58]=74;e[60]=75;e[62]=76;e[68]=77;e[69]=78;e[75]=79;e[87]=80;e[89]=81;e[90]=82;e[94]=83;e[100]=84;e[104]=85;e[115]=86;e[116]=87;e[121]=88;e[122]=89;e[127]=90;e[258]=97;e[268]=261;e[271]=98;e[272]=99;e[273]=263;e[282]=100;e[286]=101;e[295]=281;e[296]=102;e[336]=103;e[346]=104;e[349]=105;e[361]=106;e[364]=107;e[367]=108;e[371]=322;e[373]=109;e[374]=110;e[381]=111;e[383]=243;e[393]=112;e[395]=113;e[396]=114;e[400]=115;e[401]=347;e[410]=116;e[437]=117;e[448]=118;e[449]=119;e[454]=120;e[455]=121;e[460]=122;e[463]=380;e[853]=44;e[855]=58;e[856]=46;e[876]=47;e[878]=45;e[882]=45;e[894]=40;e[895]=41;e[896]=91;e[897]=93;e[923]=64;e[1004]=48;e[1005]=49;e[1006]=50;e[1007]=51;e[1008]=52;e[1009]=53;e[1010]=54;e[1011]=55;e[1012]=56;e[1013]=57;e[1081]=37;e[1085]=43;e[1086]=45}));t.getSupplementalGlyphMapForCalibri=h},function(e,t,a){var r=a(7).getLookupTableFactory,i=r((function(e){e[63721]=169;e[63193]=169;e[63720]=174;e[63194]=174;e[63722]=8482;e[63195]=8482;e[63729]=9127;e[63730]=9128;e[63731]=9129;e[63740]=9131;e[63741]=9132;e[63742]=9133;e[63726]=9121;e[63727]=9122;e[63728]=9123;e[63737]=9124;e[63738]=9125;e[63739]=9126;e[63723]=9115;e[63724]=9116;e[63725]=9117;e[63734]=9118;e[63735]=9119;e[63736]=9120}));var n=[{begin:0,end:127},{begin:128,end:255},{begin:256,end:383},{begin:384,end:591},{begin:592,end:687},{begin:688,end:767},{begin:768,end:879},{begin:880,end:1023},{begin:11392,end:11519},{begin:1024,end:1279},{begin:1328,end:1423},{begin:1424,end:1535},{begin:42240,end:42559},{begin:1536,end:1791},{begin:1984,end:2047},{begin:2304,end:2431},{begin:2432,end:2559},{begin:2560,end:2687},{begin:2688,end:2815},{begin:2816,end:2943},{begin:2944,end:3071},{begin:3072,end:3199},{begin:3200,end:3327},{begin:3328,end:3455},{begin:3584,end:3711},{begin:3712,end:3839},{begin:4256,end:4351},{begin:6912,end:7039},{begin:4352,end:4607},{begin:7680,end:7935},{begin:7936,end:8191},{begin:8192,end:8303},{begin:8304,end:8351},{begin:8352,end:8399},{begin:8400,end:8447},{begin:8448,end:8527},{begin:8528,end:8591},{begin:8592,end:8703},{begin:8704,end:8959},{begin:8960,end:9215},{begin:9216,end:9279},{begin:9280,end:9311},{begin:9312,end:9471},{begin:9472,end:9599},{begin:9600,end:9631},{begin:9632,end:9727},{begin:9728,end:9983},{begin:9984,end:10175},{begin:12288,end:12351},{begin:12352,end:12447},{begin:12448,end:12543},{begin:12544,end:12591},{begin:12592,end:12687},{begin:43072,end:43135},{begin:12800,end:13055},{begin:13056,end:13311},{begin:44032,end:55215},{begin:55296,end:57343},{begin:67840,end:67871},{begin:19968,end:40959},{begin:57344,end:63743},{begin:12736,end:12783},{begin:64256,end:64335},{begin:64336,end:65023},{begin:65056,end:65071},{begin:65040,end:65055},{begin:65104,end:65135},{begin:65136,end:65279},{begin:65280,end:65519},{begin:65520,end:65535},{begin:3840,end:4095},{begin:1792,end:1871},{begin:1920,end:1983},{begin:3456,end:3583},{begin:4096,end:4255},{begin:4608,end:4991},{begin:5024,end:5119},{begin:5120,end:5759},{begin:5760,end:5791},{begin:5792,end:5887},{begin:6016,end:6143},{begin:6144,end:6319},{begin:10240,end:10495},{begin:40960,end:42127},{begin:5888,end:5919},{begin:66304,end:66351},{begin:66352,end:66383},{begin:66560,end:66639},{begin:118784,end:119039},{begin:119808,end:120831},{begin:1044480,end:1048573},{begin:65024,end:65039},{begin:917504,end:917631},{begin:6400,end:6479},{begin:6480,end:6527},{begin:6528,end:6623},{begin:6656,end:6687},{begin:11264,end:11359},{begin:11568,end:11647},{begin:19904,end:19967},{begin:43008,end:43055},{begin:65536,end:65663},{begin:65856,end:65935},{begin:66432,end:66463},{begin:66464,end:66527},{begin:66640,end:66687},{begin:66688,end:66735},{begin:67584,end:67647},{begin:68096,end:68191},{begin:119552,end:119647},{begin:73728,end:74751},{begin:119648,end:119679},{begin:7040,end:7103},{begin:7168,end:7247},{begin:7248,end:7295},{begin:43136,end:43231},{begin:43264,end:43311},{begin:43312,end:43359},{begin:43520,end:43615},{begin:65936,end:65999},{begin:66e3,end:66047},{begin:66208,end:66271},{begin:127024,end:127135}];var s=r((function(e){e["¨"]=" ̈";e["¯"]=" ̄";e["´"]=" ́";e["µ"]="μ";e["¸"]=" ̧";e["IJ"]="IJ";e["ij"]="ij";e["Ŀ"]="L·";e["ŀ"]="l·";e["ʼn"]="ʼn";e["ſ"]="s";e["DŽ"]="DŽ";e["Dž"]="Dž";e["dž"]="dž";e["LJ"]="LJ";e["Lj"]="Lj";e["lj"]="lj";e["NJ"]="NJ";e["Nj"]="Nj";e["nj"]="nj";e["DZ"]="DZ";e["Dz"]="Dz";e["dz"]="dz";e["˘"]=" ̆";e["˙"]=" ̇";e["˚"]=" ̊";e["˛"]=" ̨";e["˜"]=" ̃";e["˝"]=" ̋";e["ͺ"]=" ͅ";e["΄"]=" ́";e["ϐ"]="β";e["ϑ"]="θ";e["ϒ"]="Υ";e["ϕ"]="φ";e["ϖ"]="π";e["ϰ"]="κ";e["ϱ"]="ρ";e["ϲ"]="ς";e["ϴ"]="Θ";e["ϵ"]="ε";e["Ϲ"]="Σ";e["և"]="եւ";e["ٵ"]="اٴ";e["ٶ"]="وٴ";e["ٷ"]="ۇٴ";e["ٸ"]="يٴ";e["ำ"]="ํา";e["ຳ"]="ໍາ";e["ໜ"]="ຫນ";e["ໝ"]="ຫມ";e["ཷ"]="ྲཱྀ";e["ཹ"]="ླཱྀ";e["ẚ"]="aʾ";e["᾽"]=" ̓";e["᾿"]=" ̓";e["῀"]=" ͂";e["῾"]=" ̔";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e["‗"]=" ̳";e["․"]=".";e["‥"]="..";e["…"]="...";e["″"]="′′";e["‴"]="′′′";e["‶"]="‵‵";e["‷"]="‵‵‵";e["‼"]="!!";e["‾"]=" ̅";e["⁇"]="??";e["⁈"]="?!";e["⁉"]="!?";e["⁗"]="′′′′";e[" "]=" ";e["₨"]="Rs";e["℀"]="a/c";e["℁"]="a/s";e["℃"]="°C";e["℅"]="c/o";e["℆"]="c/u";e["ℇ"]="Ɛ";e["℉"]="°F";e["№"]="No";e["℡"]="TEL";e["ℵ"]="א";e["ℶ"]="ב";e["ℷ"]="ג";e["ℸ"]="ד";e["℻"]="FAX";e["Ⅰ"]="I";e["Ⅱ"]="II";e["Ⅲ"]="III";e["Ⅳ"]="IV";e["Ⅴ"]="V";e["Ⅵ"]="VI";e["Ⅶ"]="VII";e["Ⅷ"]="VIII";e["Ⅸ"]="IX";e["Ⅹ"]="X";e["Ⅺ"]="XI";e["Ⅻ"]="XII";e["Ⅼ"]="L";e["Ⅽ"]="C";e["Ⅾ"]="D";e["Ⅿ"]="M";e["ⅰ"]="i";e["ⅱ"]="ii";e["ⅲ"]="iii";e["ⅳ"]="iv";e["ⅴ"]="v";e["ⅵ"]="vi";e["ⅶ"]="vii";e["ⅷ"]="viii";e["ⅸ"]="ix";e["ⅹ"]="x";e["ⅺ"]="xi";e["ⅻ"]="xii";e["ⅼ"]="l";e["ⅽ"]="c";e["ⅾ"]="d";e["ⅿ"]="m";e["∬"]="∫∫";e["∭"]="∫∫∫";e["∯"]="∮∮";e["∰"]="∮∮∮";e["⑴"]="(1)";e["⑵"]="(2)";e["⑶"]="(3)";e["⑷"]="(4)";e["⑸"]="(5)";e["⑹"]="(6)";e["⑺"]="(7)";e["⑻"]="(8)";e["⑼"]="(9)";e["⑽"]="(10)";e["⑾"]="(11)";e["⑿"]="(12)";e["⒀"]="(13)";e["⒁"]="(14)";e["⒂"]="(15)";e["⒃"]="(16)";e["⒄"]="(17)";e["⒅"]="(18)";e["⒆"]="(19)";e["⒇"]="(20)";e["⒈"]="1.";e["⒉"]="2.";e["⒊"]="3.";e["⒋"]="4.";e["⒌"]="5.";e["⒍"]="6.";e["⒎"]="7.";e["⒏"]="8.";e["⒐"]="9.";e["⒑"]="10.";e["⒒"]="11.";e["⒓"]="12.";e["⒔"]="13.";e["⒕"]="14.";e["⒖"]="15.";e["⒗"]="16.";e["⒘"]="17.";e["⒙"]="18.";e["⒚"]="19.";e["⒛"]="20.";e["⒜"]="(a)";e["⒝"]="(b)";e["⒞"]="(c)";e["⒟"]="(d)";e["⒠"]="(e)";e["⒡"]="(f)";e["⒢"]="(g)";e["⒣"]="(h)";e["⒤"]="(i)";e["⒥"]="(j)";e["⒦"]="(k)";e["⒧"]="(l)";e["⒨"]="(m)";e["⒩"]="(n)";e["⒪"]="(o)";e["⒫"]="(p)";e["⒬"]="(q)";e["⒭"]="(r)";e["⒮"]="(s)";e["⒯"]="(t)";e["⒰"]="(u)";e["⒱"]="(v)";e["⒲"]="(w)";e["⒳"]="(x)";e["⒴"]="(y)";e["⒵"]="(z)";e["⨌"]="∫∫∫∫";e["⩴"]="::=";e["⩵"]="==";e["⩶"]="===";e["⺟"]="母";e["⻳"]="龟";e["⼀"]="一";e["⼁"]="丨";e["⼂"]="丶";e["⼃"]="丿";e["⼄"]="乙";e["⼅"]="亅";e["⼆"]="二";e["⼇"]="亠";e["⼈"]="人";e["⼉"]="儿";e["⼊"]="入";e["⼋"]="八";e["⼌"]="冂";e["⼍"]="冖";e["⼎"]="冫";e["⼏"]="几";e["⼐"]="凵";e["⼑"]="刀";e["⼒"]="力";e["⼓"]="勹";e["⼔"]="匕";e["⼕"]="匚";e["⼖"]="匸";e["⼗"]="十";e["⼘"]="卜";e["⼙"]="卩";e["⼚"]="厂";e["⼛"]="厶";e["⼜"]="又";e["⼝"]="口";e["⼞"]="囗";e["⼟"]="土";e["⼠"]="士";e["⼡"]="夂";e["⼢"]="夊";e["⼣"]="夕";e["⼤"]="大";e["⼥"]="女";e["⼦"]="子";e["⼧"]="宀";e["⼨"]="寸";e["⼩"]="小";e["⼪"]="尢";e["⼫"]="尸";e["⼬"]="屮";e["⼭"]="山";e["⼮"]="巛";e["⼯"]="工";e["⼰"]="己";e["⼱"]="巾";e["⼲"]="干";e["⼳"]="幺";e["⼴"]="广";e["⼵"]="廴";e["⼶"]="廾";e["⼷"]="弋";e["⼸"]="弓";e["⼹"]="彐";e["⼺"]="彡";e["⼻"]="彳";e["⼼"]="心";e["⼽"]="戈";e["⼾"]="戶";e["⼿"]="手";e["⽀"]="支";e["⽁"]="攴";e["⽂"]="文";e["⽃"]="斗";e["⽄"]="斤";e["⽅"]="方";e["⽆"]="无";e["⽇"]="日";e["⽈"]="曰";e["⽉"]="月";e["⽊"]="木";e["⽋"]="欠";e["⽌"]="止";e["⽍"]="歹";e["⽎"]="殳";e["⽏"]="毋";e["⽐"]="比";e["⽑"]="毛";e["⽒"]="氏";e["⽓"]="气";e["⽔"]="水";e["⽕"]="火";e["⽖"]="爪";e["⽗"]="父";e["⽘"]="爻";e["⽙"]="爿";e["⽚"]="片";e["⽛"]="牙";e["⽜"]="牛";e["⽝"]="犬";e["⽞"]="玄";e["⽟"]="玉";e["⽠"]="瓜";e["⽡"]="瓦";e["⽢"]="甘";e["⽣"]="生";e["⽤"]="用";e["⽥"]="田";e["⽦"]="疋";e["⽧"]="疒";e["⽨"]="癶";e["⽩"]="白";e["⽪"]="皮";e["⽫"]="皿";e["⽬"]="目";e["⽭"]="矛";e["⽮"]="矢";e["⽯"]="石";e["⽰"]="示";e["⽱"]="禸";e["⽲"]="禾";e["⽳"]="穴";e["⽴"]="立";e["⽵"]="竹";e["⽶"]="米";e["⽷"]="糸";e["⽸"]="缶";e["⽹"]="网";e["⽺"]="羊";e["⽻"]="羽";e["⽼"]="老";e["⽽"]="而";e["⽾"]="耒";e["⽿"]="耳";e["⾀"]="聿";e["⾁"]="肉";e["⾂"]="臣";e["⾃"]="自";e["⾄"]="至";e["⾅"]="臼";e["⾆"]="舌";e["⾇"]="舛";e["⾈"]="舟";e["⾉"]="艮";e["⾊"]="色";e["⾋"]="艸";e["⾌"]="虍";e["⾍"]="虫";e["⾎"]="血";e["⾏"]="行";e["⾐"]="衣";e["⾑"]="襾";e["⾒"]="見";e["⾓"]="角";e["⾔"]="言";e["⾕"]="谷";e["⾖"]="豆";e["⾗"]="豕";e["⾘"]="豸";e["⾙"]="貝";e["⾚"]="赤";e["⾛"]="走";e["⾜"]="足";e["⾝"]="身";e["⾞"]="車";e["⾟"]="辛";e["⾠"]="辰";e["⾡"]="辵";e["⾢"]="邑";e["⾣"]="酉";e["⾤"]="釆";e["⾥"]="里";e["⾦"]="金";e["⾧"]="長";e["⾨"]="門";e["⾩"]="阜";e["⾪"]="隶";e["⾫"]="隹";e["⾬"]="雨";e["⾭"]="靑";e["⾮"]="非";e["⾯"]="面";e["⾰"]="革";e["⾱"]="韋";e["⾲"]="韭";e["⾳"]="音";e["⾴"]="頁";e["⾵"]="風";e["⾶"]="飛";e["⾷"]="食";e["⾸"]="首";e["⾹"]="香";e["⾺"]="馬";e["⾻"]="骨";e["⾼"]="高";e["⾽"]="髟";e["⾾"]="鬥";e["⾿"]="鬯";e["⿀"]="鬲";e["⿁"]="鬼";e["⿂"]="魚";e["⿃"]="鳥";e["⿄"]="鹵";e["⿅"]="鹿";e["⿆"]="麥";e["⿇"]="麻";e["⿈"]="黃";e["⿉"]="黍";e["⿊"]="黑";e["⿋"]="黹";e["⿌"]="黽";e["⿍"]="鼎";e["⿎"]="鼓";e["⿏"]="鼠";e["⿐"]="鼻";e["⿑"]="齊";e["⿒"]="齒";e["⿓"]="龍";e["⿔"]="龜";e["⿕"]="龠";e["〶"]="〒";e["〸"]="十";e["〹"]="卄";e["〺"]="卅";e["゛"]=" ゙";e["゜"]=" ゚";e["ㄱ"]="ᄀ";e["ㄲ"]="ᄁ";e["ㄳ"]="ᆪ";e["ㄴ"]="ᄂ";e["ㄵ"]="ᆬ";e["ㄶ"]="ᆭ";e["ㄷ"]="ᄃ";e["ㄸ"]="ᄄ";e["ㄹ"]="ᄅ";e["ㄺ"]="ᆰ";e["ㄻ"]="ᆱ";e["ㄼ"]="ᆲ";e["ㄽ"]="ᆳ";e["ㄾ"]="ᆴ";e["ㄿ"]="ᆵ";e["ㅀ"]="ᄚ";e["ㅁ"]="ᄆ";e["ㅂ"]="ᄇ";e["ㅃ"]="ᄈ";e["ㅄ"]="ᄡ";e["ㅅ"]="ᄉ";e["ㅆ"]="ᄊ";e["ㅇ"]="ᄋ";e["ㅈ"]="ᄌ";e["ㅉ"]="ᄍ";e["ㅊ"]="ᄎ";e["ㅋ"]="ᄏ";e["ㅌ"]="ᄐ";e["ㅍ"]="ᄑ";e["ㅎ"]="ᄒ";e["ㅏ"]="ᅡ";e["ㅐ"]="ᅢ";e["ㅑ"]="ᅣ";e["ㅒ"]="ᅤ";e["ㅓ"]="ᅥ";e["ㅔ"]="ᅦ";e["ㅕ"]="ᅧ";e["ㅖ"]="ᅨ";e["ㅗ"]="ᅩ";e["ㅘ"]="ᅪ";e["ㅙ"]="ᅫ";e["ㅚ"]="ᅬ";e["ㅛ"]="ᅭ";e["ㅜ"]="ᅮ";e["ㅝ"]="ᅯ";e["ㅞ"]="ᅰ";e["ㅟ"]="ᅱ";e["ㅠ"]="ᅲ";e["ㅡ"]="ᅳ";e["ㅢ"]="ᅴ";e["ㅣ"]="ᅵ";e["ㅤ"]="ᅠ";e["ㅥ"]="ᄔ";e["ㅦ"]="ᄕ";e["ㅧ"]="ᇇ";e["ㅨ"]="ᇈ";e["ㅩ"]="ᇌ";e["ㅪ"]="ᇎ";e["ㅫ"]="ᇓ";e["ㅬ"]="ᇗ";e["ㅭ"]="ᇙ";e["ㅮ"]="ᄜ";e["ㅯ"]="ᇝ";e["ㅰ"]="ᇟ";e["ㅱ"]="ᄝ";e["ㅲ"]="ᄞ";e["ㅳ"]="ᄠ";e["ㅴ"]="ᄢ";e["ㅵ"]="ᄣ";e["ㅶ"]="ᄧ";e["ㅷ"]="ᄩ";e["ㅸ"]="ᄫ";e["ㅹ"]="ᄬ";e["ㅺ"]="ᄭ";e["ㅻ"]="ᄮ";e["ㅼ"]="ᄯ";e["ㅽ"]="ᄲ";e["ㅾ"]="ᄶ";e["ㅿ"]="ᅀ";e["ㆀ"]="ᅇ";e["ㆁ"]="ᅌ";e["ㆂ"]="ᇱ";e["ㆃ"]="ᇲ";e["ㆄ"]="ᅗ";e["ㆅ"]="ᅘ";e["ㆆ"]="ᅙ";e["ㆇ"]="ᆄ";e["ㆈ"]="ᆅ";e["ㆉ"]="ᆈ";e["ㆊ"]="ᆑ";e["ㆋ"]="ᆒ";e["ㆌ"]="ᆔ";e["ㆍ"]="ᆞ";e["ㆎ"]="ᆡ";e["㈀"]="(ᄀ)";e["㈁"]="(ᄂ)";e["㈂"]="(ᄃ)";e["㈃"]="(ᄅ)";e["㈄"]="(ᄆ)";e["㈅"]="(ᄇ)";e["㈆"]="(ᄉ)";e["㈇"]="(ᄋ)";e["㈈"]="(ᄌ)";e["㈉"]="(ᄎ)";e["㈊"]="(ᄏ)";e["㈋"]="(ᄐ)";e["㈌"]="(ᄑ)";e["㈍"]="(ᄒ)";e["㈎"]="(가)";e["㈏"]="(나)";e["㈐"]="(다)";e["㈑"]="(라)";e["㈒"]="(마)";e["㈓"]="(바)";e["㈔"]="(사)";e["㈕"]="(아)";e["㈖"]="(자)";e["㈗"]="(차)";e["㈘"]="(카)";e["㈙"]="(타)";e["㈚"]="(파)";e["㈛"]="(하)";e["㈜"]="(주)";e["㈝"]="(오전)";e["㈞"]="(오후)";e["㈠"]="(一)";e["㈡"]="(二)";e["㈢"]="(三)";e["㈣"]="(四)";e["㈤"]="(五)";e["㈥"]="(六)";e["㈦"]="(七)";e["㈧"]="(八)";e["㈨"]="(九)";e["㈩"]="(十)";e["㈪"]="(月)";e["㈫"]="(火)";e["㈬"]="(水)";e["㈭"]="(木)";e["㈮"]="(金)";e["㈯"]="(土)";e["㈰"]="(日)";e["㈱"]="(株)";e["㈲"]="(有)";e["㈳"]="(社)";e["㈴"]="(名)";e["㈵"]="(特)";e["㈶"]="(財)";e["㈷"]="(祝)";e["㈸"]="(労)";e["㈹"]="(代)";e["㈺"]="(呼)";e["㈻"]="(学)";e["㈼"]="(監)";e["㈽"]="(企)";e["㈾"]="(資)";e["㈿"]="(協)";e["㉀"]="(祭)";e["㉁"]="(休)";e["㉂"]="(自)";e["㉃"]="(至)";e["㋀"]="1月";e["㋁"]="2月";e["㋂"]="3月";e["㋃"]="4月";e["㋄"]="5月";e["㋅"]="6月";e["㋆"]="7月";e["㋇"]="8月";e["㋈"]="9月";e["㋉"]="10月";e["㋊"]="11月";e["㋋"]="12月";e["㍘"]="0点";e["㍙"]="1点";e["㍚"]="2点";e["㍛"]="3点";e["㍜"]="4点";e["㍝"]="5点";e["㍞"]="6点";e["㍟"]="7点";e["㍠"]="8点";e["㍡"]="9点";e["㍢"]="10点";e["㍣"]="11点";e["㍤"]="12点";e["㍥"]="13点";e["㍦"]="14点";e["㍧"]="15点";e["㍨"]="16点";e["㍩"]="17点";e["㍪"]="18点";e["㍫"]="19点";e["㍬"]="20点";e["㍭"]="21点";e["㍮"]="22点";e["㍯"]="23点";e["㍰"]="24点";e["㏠"]="1日";e["㏡"]="2日";e["㏢"]="3日";e["㏣"]="4日";e["㏤"]="5日";e["㏥"]="6日";e["㏦"]="7日";e["㏧"]="8日";e["㏨"]="9日";e["㏩"]="10日";e["㏪"]="11日";e["㏫"]="12日";e["㏬"]="13日";e["㏭"]="14日";e["㏮"]="15日";e["㏯"]="16日";e["㏰"]="17日";e["㏱"]="18日";e["㏲"]="19日";e["㏳"]="20日";e["㏴"]="21日";e["㏵"]="22日";e["㏶"]="23日";e["㏷"]="24日";e["㏸"]="25日";e["㏹"]="26日";e["㏺"]="27日";e["㏻"]="28日";e["㏼"]="29日";e["㏽"]="30日";e["㏾"]="31日";e["ff"]="ff";e["fi"]="fi";e["fl"]="fl";e["ffi"]="ffi";e["ffl"]="ffl";e["ſt"]="ſt";e["st"]="st";e["ﬓ"]="մն";e["ﬔ"]="մե";e["ﬕ"]="մի";e["ﬖ"]="վն";e["ﬗ"]="մխ";e["ﭏ"]="אל";e["ﭐ"]="ٱ";e["ﭑ"]="ٱ";e["ﭒ"]="ٻ";e["ﭓ"]="ٻ";e["ﭔ"]="ٻ";e["ﭕ"]="ٻ";e["ﭖ"]="پ";e["ﭗ"]="پ";e["ﭘ"]="پ";e["ﭙ"]="پ";e["ﭚ"]="ڀ";e["ﭛ"]="ڀ";e["ﭜ"]="ڀ";e["ﭝ"]="ڀ";e["ﭞ"]="ٺ";e["ﭟ"]="ٺ";e["ﭠ"]="ٺ";e["ﭡ"]="ٺ";e["ﭢ"]="ٿ";e["ﭣ"]="ٿ";e["ﭤ"]="ٿ";e["ﭥ"]="ٿ";e["ﭦ"]="ٹ";e["ﭧ"]="ٹ";e["ﭨ"]="ٹ";e["ﭩ"]="ٹ";e["ﭪ"]="ڤ";e["ﭫ"]="ڤ";e["ﭬ"]="ڤ";e["ﭭ"]="ڤ";e["ﭮ"]="ڦ";e["ﭯ"]="ڦ";e["ﭰ"]="ڦ";e["ﭱ"]="ڦ";e["ﭲ"]="ڄ";e["ﭳ"]="ڄ";e["ﭴ"]="ڄ";e["ﭵ"]="ڄ";e["ﭶ"]="ڃ";e["ﭷ"]="ڃ";e["ﭸ"]="ڃ";e["ﭹ"]="ڃ";e["ﭺ"]="چ";e["ﭻ"]="چ";e["ﭼ"]="چ";e["ﭽ"]="چ";e["ﭾ"]="ڇ";e["ﭿ"]="ڇ";e["ﮀ"]="ڇ";e["ﮁ"]="ڇ";e["ﮂ"]="ڍ";e["ﮃ"]="ڍ";e["ﮄ"]="ڌ";e["ﮅ"]="ڌ";e["ﮆ"]="ڎ";e["ﮇ"]="ڎ";e["ﮈ"]="ڈ";e["ﮉ"]="ڈ";e["ﮊ"]="ژ";e["ﮋ"]="ژ";e["ﮌ"]="ڑ";e["ﮍ"]="ڑ";e["ﮎ"]="ک";e["ﮏ"]="ک";e["ﮐ"]="ک";e["ﮑ"]="ک";e["ﮒ"]="گ";e["ﮓ"]="گ";e["ﮔ"]="گ";e["ﮕ"]="گ";e["ﮖ"]="ڳ";e["ﮗ"]="ڳ";e["ﮘ"]="ڳ";e["ﮙ"]="ڳ";e["ﮚ"]="ڱ";e["ﮛ"]="ڱ";e["ﮜ"]="ڱ";e["ﮝ"]="ڱ";e["ﮞ"]="ں";e["ﮟ"]="ں";e["ﮠ"]="ڻ";e["ﮡ"]="ڻ";e["ﮢ"]="ڻ";e["ﮣ"]="ڻ";e["ﮤ"]="ۀ";e["ﮥ"]="ۀ";e["ﮦ"]="ہ";e["ﮧ"]="ہ";e["ﮨ"]="ہ";e["ﮩ"]="ہ";e["ﮪ"]="ھ";e["ﮫ"]="ھ";e["ﮬ"]="ھ";e["ﮭ"]="ھ";e["ﮮ"]="ے";e["ﮯ"]="ے";e["ﮰ"]="ۓ";e["ﮱ"]="ۓ";e["ﯓ"]="ڭ";e["ﯔ"]="ڭ";e["ﯕ"]="ڭ";e["ﯖ"]="ڭ";e["ﯗ"]="ۇ";e["ﯘ"]="ۇ";e["ﯙ"]="ۆ";e["ﯚ"]="ۆ";e["ﯛ"]="ۈ";e["ﯜ"]="ۈ";e["ﯝ"]="ٷ";e["ﯞ"]="ۋ";e["ﯟ"]="ۋ";e["ﯠ"]="ۅ";e["ﯡ"]="ۅ";e["ﯢ"]="ۉ";e["ﯣ"]="ۉ";e["ﯤ"]="ې";e["ﯥ"]="ې";e["ﯦ"]="ې";e["ﯧ"]="ې";e["ﯨ"]="ى";e["ﯩ"]="ى";e["ﯪ"]="ئا";e["ﯫ"]="ئا";e["ﯬ"]="ئە";e["ﯭ"]="ئە";e["ﯮ"]="ئو";e["ﯯ"]="ئو";e["ﯰ"]="ئۇ";e["ﯱ"]="ئۇ";e["ﯲ"]="ئۆ";e["ﯳ"]="ئۆ";e["ﯴ"]="ئۈ";e["ﯵ"]="ئۈ";e["ﯶ"]="ئې";e["ﯷ"]="ئې";e["ﯸ"]="ئې";e["ﯹ"]="ئى";e["ﯺ"]="ئى";e["ﯻ"]="ئى";e["ﯼ"]="ی";e["ﯽ"]="ی";e["ﯾ"]="ی";e["ﯿ"]="ی";e["ﰀ"]="ئج";e["ﰁ"]="ئح";e["ﰂ"]="ئم";e["ﰃ"]="ئى";e["ﰄ"]="ئي";e["ﰅ"]="بج";e["ﰆ"]="بح";e["ﰇ"]="بخ";e["ﰈ"]="بم";e["ﰉ"]="بى";e["ﰊ"]="بي";e["ﰋ"]="تج";e["ﰌ"]="تح";e["ﰍ"]="تخ";e["ﰎ"]="تم";e["ﰏ"]="تى";e["ﰐ"]="تي";e["ﰑ"]="ثج";e["ﰒ"]="ثم";e["ﰓ"]="ثى";e["ﰔ"]="ثي";e["ﰕ"]="جح";e["ﰖ"]="جم";e["ﰗ"]="حج";e["ﰘ"]="حم";e["ﰙ"]="خج";e["ﰚ"]="خح";e["ﰛ"]="خم";e["ﰜ"]="سج";e["ﰝ"]="سح";e["ﰞ"]="سخ";e["ﰟ"]="سم";e["ﰠ"]="صح";e["ﰡ"]="صم";e["ﰢ"]="ضج";e["ﰣ"]="ضح";e["ﰤ"]="ضخ";e["ﰥ"]="ضم";e["ﰦ"]="طح";e["ﰧ"]="طم";e["ﰨ"]="ظم";e["ﰩ"]="عج";e["ﰪ"]="عم";e["ﰫ"]="غج";e["ﰬ"]="غم";e["ﰭ"]="فج";e["ﰮ"]="فح";e["ﰯ"]="فخ";e["ﰰ"]="فم";e["ﰱ"]="فى";e["ﰲ"]="في";e["ﰳ"]="قح";e["ﰴ"]="قم";e["ﰵ"]="قى";e["ﰶ"]="قي";e["ﰷ"]="كا";e["ﰸ"]="كج";e["ﰹ"]="كح";e["ﰺ"]="كخ";e["ﰻ"]="كل";e["ﰼ"]="كم";e["ﰽ"]="كى";e["ﰾ"]="كي";e["ﰿ"]="لج";e["ﱀ"]="لح";e["ﱁ"]="لخ";e["ﱂ"]="لم";e["ﱃ"]="لى";e["ﱄ"]="لي";e["ﱅ"]="مج";e["ﱆ"]="مح";e["ﱇ"]="مخ";e["ﱈ"]="مم";e["ﱉ"]="مى";e["ﱊ"]="مي";e["ﱋ"]="نج";e["ﱌ"]="نح";e["ﱍ"]="نخ";e["ﱎ"]="نم";e["ﱏ"]="نى";e["ﱐ"]="ني";e["ﱑ"]="هج";e["ﱒ"]="هم";e["ﱓ"]="هى";e["ﱔ"]="هي";e["ﱕ"]="يج";e["ﱖ"]="يح";e["ﱗ"]="يخ";e["ﱘ"]="يم";e["ﱙ"]="يى";e["ﱚ"]="يي";e["ﱛ"]="ذٰ";e["ﱜ"]="رٰ";e["ﱝ"]="ىٰ";e["ﱞ"]=" ٌّ";e["ﱟ"]=" ٍّ";e["ﱠ"]=" َّ";e["ﱡ"]=" ُّ";e["ﱢ"]=" ِّ";e["ﱣ"]=" ّٰ";e["ﱤ"]="ئر";e["ﱥ"]="ئز";e["ﱦ"]="ئم";e["ﱧ"]="ئن";e["ﱨ"]="ئى";e["ﱩ"]="ئي";e["ﱪ"]="بر";e["ﱫ"]="بز";e["ﱬ"]="بم";e["ﱭ"]="بن";e["ﱮ"]="بى";e["ﱯ"]="بي";e["ﱰ"]="تر";e["ﱱ"]="تز";e["ﱲ"]="تم";e["ﱳ"]="تن";e["ﱴ"]="تى";e["ﱵ"]="تي";e["ﱶ"]="ثر";e["ﱷ"]="ثز";e["ﱸ"]="ثم";e["ﱹ"]="ثن";e["ﱺ"]="ثى";e["ﱻ"]="ثي";e["ﱼ"]="فى";e["ﱽ"]="في";e["ﱾ"]="قى";e["ﱿ"]="قي";e["ﲀ"]="كا";e["ﲁ"]="كل";e["ﲂ"]="كم";e["ﲃ"]="كى";e["ﲄ"]="كي";e["ﲅ"]="لم";e["ﲆ"]="لى";e["ﲇ"]="لي";e["ﲈ"]="ما";e["ﲉ"]="مم";e["ﲊ"]="نر";e["ﲋ"]="نز";e["ﲌ"]="نم";e["ﲍ"]="نن";e["ﲎ"]="نى";e["ﲏ"]="ني";e["ﲐ"]="ىٰ";e["ﲑ"]="ير";e["ﲒ"]="يز";e["ﲓ"]="يم";e["ﲔ"]="ين";e["ﲕ"]="يى";e["ﲖ"]="يي";e["ﲗ"]="ئج";e["ﲘ"]="ئح";e["ﲙ"]="ئخ";e["ﲚ"]="ئم";e["ﲛ"]="ئه";e["ﲜ"]="بج";e["ﲝ"]="بح";e["ﲞ"]="بخ";e["ﲟ"]="بم";e["ﲠ"]="به";e["ﲡ"]="تج";e["ﲢ"]="تح";e["ﲣ"]="تخ";e["ﲤ"]="تم";e["ﲥ"]="ته";e["ﲦ"]="ثم";e["ﲧ"]="جح";e["ﲨ"]="جم";e["ﲩ"]="حج";e["ﲪ"]="حم";e["ﲫ"]="خج";e["ﲬ"]="خم";e["ﲭ"]="سج";e["ﲮ"]="سح";e["ﲯ"]="سخ";e["ﲰ"]="سم";e["ﲱ"]="صح";e["ﲲ"]="صخ";e["ﲳ"]="صم";e["ﲴ"]="ضج";e["ﲵ"]="ضح";e["ﲶ"]="ضخ";e["ﲷ"]="ضم";e["ﲸ"]="طح";e["ﲹ"]="ظم";e["ﲺ"]="عج";e["ﲻ"]="عم";e["ﲼ"]="غج";e["ﲽ"]="غم";e["ﲾ"]="فج";e["ﲿ"]="فح";e["ﳀ"]="فخ";e["ﳁ"]="فم";e["ﳂ"]="قح";e["ﳃ"]="قم";e["ﳄ"]="كج";e["ﳅ"]="كح";e["ﳆ"]="كخ";e["ﳇ"]="كل";e["ﳈ"]="كم";e["ﳉ"]="لج";e["ﳊ"]="لح";e["ﳋ"]="لخ";e["ﳌ"]="لم";e["ﳍ"]="له";e["ﳎ"]="مج";e["ﳏ"]="مح";e["ﳐ"]="مخ";e["ﳑ"]="مم";e["ﳒ"]="نج";e["ﳓ"]="نح";e["ﳔ"]="نخ";e["ﳕ"]="نم";e["ﳖ"]="نه";e["ﳗ"]="هج";e["ﳘ"]="هم";e["ﳙ"]="هٰ";e["ﳚ"]="يج";e["ﳛ"]="يح";e["ﳜ"]="يخ";e["ﳝ"]="يم";e["ﳞ"]="يه";e["ﳟ"]="ئم";e["ﳠ"]="ئه";e["ﳡ"]="بم";e["ﳢ"]="به";e["ﳣ"]="تم";e["ﳤ"]="ته";e["ﳥ"]="ثم";e["ﳦ"]="ثه";e["ﳧ"]="سم";e["ﳨ"]="سه";e["ﳩ"]="شم";e["ﳪ"]="شه";e["ﳫ"]="كل";e["ﳬ"]="كم";e["ﳭ"]="لم";e["ﳮ"]="نم";e["ﳯ"]="نه";e["ﳰ"]="يم";e["ﳱ"]="يه";e["ﳲ"]="ـَّ";e["ﳳ"]="ـُّ";e["ﳴ"]="ـِّ";e["ﳵ"]="طى";e["ﳶ"]="طي";e["ﳷ"]="عى";e["ﳸ"]="عي";e["ﳹ"]="غى";e["ﳺ"]="غي";e["ﳻ"]="سى";e["ﳼ"]="سي";e["ﳽ"]="شى";e["ﳾ"]="شي";e["ﳿ"]="حى";e["ﴀ"]="حي";e["ﴁ"]="جى";e["ﴂ"]="جي";e["ﴃ"]="خى";e["ﴄ"]="خي";e["ﴅ"]="صى";e["ﴆ"]="صي";e["ﴇ"]="ضى";e["ﴈ"]="ضي";e["ﴉ"]="شج";e["ﴊ"]="شح";e["ﴋ"]="شخ";e["ﴌ"]="شم";e["ﴍ"]="شر";e["ﴎ"]="سر";e["ﴏ"]="صر";e["ﴐ"]="ضر";e["ﴑ"]="طى";e["ﴒ"]="طي";e["ﴓ"]="عى";e["ﴔ"]="عي";e["ﴕ"]="غى";e["ﴖ"]="غي";e["ﴗ"]="سى";e["ﴘ"]="سي";e["ﴙ"]="شى";e["ﴚ"]="شي";e["ﴛ"]="حى";e["ﴜ"]="حي";e["ﴝ"]="جى";e["ﴞ"]="جي";e["ﴟ"]="خى";e["ﴠ"]="خي";e["ﴡ"]="صى";e["ﴢ"]="صي";e["ﴣ"]="ضى";e["ﴤ"]="ضي";e["ﴥ"]="شج";e["ﴦ"]="شح";e["ﴧ"]="شخ";e["ﴨ"]="شم";e["ﴩ"]="شر";e["ﴪ"]="سر";e["ﴫ"]="صر";e["ﴬ"]="ضر";e["ﴭ"]="شج";e["ﴮ"]="شح";e["ﴯ"]="شخ";e["ﴰ"]="شم";e["ﴱ"]="سه";e["ﴲ"]="شه";e["ﴳ"]="طم";e["ﴴ"]="سج";e["ﴵ"]="سح";e["ﴶ"]="سخ";e["ﴷ"]="شج";e["ﴸ"]="شح";e["ﴹ"]="شخ";e["ﴺ"]="طم";e["ﴻ"]="ظم";e["ﴼ"]="اً";e["ﴽ"]="اً";e["ﵐ"]="تجم";e["ﵑ"]="تحج";e["ﵒ"]="تحج";e["ﵓ"]="تحم";e["ﵔ"]="تخم";e["ﵕ"]="تمج";e["ﵖ"]="تمح";e["ﵗ"]="تمخ";e["ﵘ"]="جمح";e["ﵙ"]="جمح";e["ﵚ"]="حمي";e["ﵛ"]="حمى";e["ﵜ"]="سحج";e["ﵝ"]="سجح";e["ﵞ"]="سجى";e["ﵟ"]="سمح";e["ﵠ"]="سمح";e["ﵡ"]="سمج";e["ﵢ"]="سمم";e["ﵣ"]="سمم";e["ﵤ"]="صحح";e["ﵥ"]="صحح";e["ﵦ"]="صمم";e["ﵧ"]="شحم";e["ﵨ"]="شحم";e["ﵩ"]="شجي";e["ﵪ"]="شمخ";e["ﵫ"]="شمخ";e["ﵬ"]="شمم";e["ﵭ"]="شمم";e["ﵮ"]="ضحى";e["ﵯ"]="ضخم";e["ﵰ"]="ضخم";e["ﵱ"]="طمح";e["ﵲ"]="طمح";e["ﵳ"]="طمم";e["ﵴ"]="طمي";e["ﵵ"]="عجم";e["ﵶ"]="عمم";e["ﵷ"]="عمم";e["ﵸ"]="عمى";e["ﵹ"]="غمم";e["ﵺ"]="غمي";e["ﵻ"]="غمى";e["ﵼ"]="فخم";e["ﵽ"]="فخم";e["ﵾ"]="قمح";e["ﵿ"]="قمم";e["ﶀ"]="لحم";e["ﶁ"]="لحي";e["ﶂ"]="لحى";e["ﶃ"]="لجج";e["ﶄ"]="لجج";e["ﶅ"]="لخم";e["ﶆ"]="لخم";e["ﶇ"]="لمح";e["ﶈ"]="لمح";e["ﶉ"]="محج";e["ﶊ"]="محم";e["ﶋ"]="محي";e["ﶌ"]="مجح";e["ﶍ"]="مجم";e["ﶎ"]="مخج";e["ﶏ"]="مخم";e["ﶒ"]="مجخ";e["ﶓ"]="همج";e["ﶔ"]="همم";e["ﶕ"]="نحم";e["ﶖ"]="نحى";e["ﶗ"]="نجم";e["ﶘ"]="نجم";e["ﶙ"]="نجى";e["ﶚ"]="نمي";e["ﶛ"]="نمى";e["ﶜ"]="يمم";e["ﶝ"]="يمم";e["ﶞ"]="بخي";e["ﶟ"]="تجي";e["ﶠ"]="تجى";e["ﶡ"]="تخي";e["ﶢ"]="تخى";e["ﶣ"]="تمي";e["ﶤ"]="تمى";e["ﶥ"]="جمي";e["ﶦ"]="جحى";e["ﶧ"]="جمى";e["ﶨ"]="سخى";e["ﶩ"]="صحي";e["ﶪ"]="شحي";e["ﶫ"]="ضحي";e["ﶬ"]="لجي";e["ﶭ"]="لمي";e["ﶮ"]="يحي";e["ﶯ"]="يجي";e["ﶰ"]="يمي";e["ﶱ"]="ممي";e["ﶲ"]="قمي";e["ﶳ"]="نحي";e["ﶴ"]="قمح";e["ﶵ"]="لحم";e["ﶶ"]="عمي";e["ﶷ"]="كمي";e["ﶸ"]="نجح";e["ﶹ"]="مخي";e["ﶺ"]="لجم";e["ﶻ"]="كمم";e["ﶼ"]="لجم";e["ﶽ"]="نجح";e["ﶾ"]="جحي";e["ﶿ"]="حجي";e["ﷀ"]="مجي";e["ﷁ"]="فمي";e["ﷂ"]="بحي";e["ﷃ"]="كمم";e["ﷄ"]="عجم";e["ﷅ"]="صمم";e["ﷆ"]="سخي";e["ﷇ"]="نجي";e["﹉"]="‾";e["﹊"]="‾";e["﹋"]="‾";e["﹌"]="‾";e["﹍"]="_";e["﹎"]="_";e["﹏"]="_";e["ﺀ"]="ء";e["ﺁ"]="آ";e["ﺂ"]="آ";e["ﺃ"]="أ";e["ﺄ"]="أ";e["ﺅ"]="ؤ";e["ﺆ"]="ؤ";e["ﺇ"]="إ";e["ﺈ"]="إ";e["ﺉ"]="ئ";e["ﺊ"]="ئ";e["ﺋ"]="ئ";e["ﺌ"]="ئ";e["ﺍ"]="ا";e["ﺎ"]="ا";e["ﺏ"]="ب";e["ﺐ"]="ب";e["ﺑ"]="ب";e["ﺒ"]="ب";e["ﺓ"]="ة";e["ﺔ"]="ة";e["ﺕ"]="ت";e["ﺖ"]="ت";e["ﺗ"]="ت";e["ﺘ"]="ت";e["ﺙ"]="ث";e["ﺚ"]="ث";e["ﺛ"]="ث";e["ﺜ"]="ث";e["ﺝ"]="ج";e["ﺞ"]="ج";e["ﺟ"]="ج";e["ﺠ"]="ج";e["ﺡ"]="ح";e["ﺢ"]="ح";e["ﺣ"]="ح";e["ﺤ"]="ح";e["ﺥ"]="خ";e["ﺦ"]="خ";e["ﺧ"]="خ";e["ﺨ"]="خ";e["ﺩ"]="د";e["ﺪ"]="د";e["ﺫ"]="ذ";e["ﺬ"]="ذ";e["ﺭ"]="ر";e["ﺮ"]="ر";e["ﺯ"]="ز";e["ﺰ"]="ز";e["ﺱ"]="س";e["ﺲ"]="س";e["ﺳ"]="س";e["ﺴ"]="س";e["ﺵ"]="ش";e["ﺶ"]="ش";e["ﺷ"]="ش";e["ﺸ"]="ش";e["ﺹ"]="ص";e["ﺺ"]="ص";e["ﺻ"]="ص";e["ﺼ"]="ص";e["ﺽ"]="ض";e["ﺾ"]="ض";e["ﺿ"]="ض";e["ﻀ"]="ض";e["ﻁ"]="ط";e["ﻂ"]="ط";e["ﻃ"]="ط";e["ﻄ"]="ط";e["ﻅ"]="ظ";e["ﻆ"]="ظ";e["ﻇ"]="ظ";e["ﻈ"]="ظ";e["ﻉ"]="ع";e["ﻊ"]="ع";e["ﻋ"]="ع";e["ﻌ"]="ع";e["ﻍ"]="غ";e["ﻎ"]="غ";e["ﻏ"]="غ";e["ﻐ"]="غ";e["ﻑ"]="ف";e["ﻒ"]="ف";e["ﻓ"]="ف";e["ﻔ"]="ف";e["ﻕ"]="ق";e["ﻖ"]="ق";e["ﻗ"]="ق";e["ﻘ"]="ق";e["ﻙ"]="ك";e["ﻚ"]="ك";e["ﻛ"]="ك";e["ﻜ"]="ك";e["ﻝ"]="ل";e["ﻞ"]="ل";e["ﻟ"]="ل";e["ﻠ"]="ل";e["ﻡ"]="م";e["ﻢ"]="م";e["ﻣ"]="م";e["ﻤ"]="م";e["ﻥ"]="ن";e["ﻦ"]="ن";e["ﻧ"]="ن";e["ﻨ"]="ن";e["ﻩ"]="ه";e["ﻪ"]="ه";e["ﻫ"]="ه";e["ﻬ"]="ه";e["ﻭ"]="و";e["ﻮ"]="و";e["ﻯ"]="ى";e["ﻰ"]="ى";e["ﻱ"]="ي";e["ﻲ"]="ي";e["ﻳ"]="ي";e["ﻴ"]="ي";e["ﻵ"]="لآ";e["ﻶ"]="لآ";e["ﻷ"]="لأ";e["ﻸ"]="لأ";e["ﻹ"]="لإ";e["ﻺ"]="لإ";e["ﻻ"]="لا";e["ﻼ"]="لا"}));t.mapSpecialUnicodeValues=function(e){return e>=65520&&e<=65535?0:e>=62976&&e<=63743?i()[e]||e:173===e?45:e};t.reverseIfRtl=function(e){var t,a,r=e.length;if(r<=1||!(t=e.charCodeAt(0),a=n[13],t>=a.begin&&t<a.end||t>=(a=n[11]).begin&&t<a.end))return e;for(var i="",s=r-1;s>=0;s--)i+=e[s];return i};t.getUnicodeRangeFor=function(e){for(var t=0,a=n.length;t<a;t++){var r=n[t];if(e>=r.begin&&e<r.end)return t}return-1};t.getNormalizedUnicodes=s;t.getUnicodeForGlyph=function(e,t){var a=t[e];if(void 0!==a)return a;if(!e)return-1;if("u"===e[0]){var r,i=e.length;if(7===i&&"n"===e[1]&&"i"===e[2])r=e.substring(3);else{if(!(i>=5&&i<=7))return-1;r=e.substring(1)}if(r===r.toUpperCase()&&(a=parseInt(r,16))>=0)return a}return-1}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.FontRendererFactory=void 0;var r=a(2),i=a(28),n=a(31),s=a(30),o=a(11),c=function(){function e(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]}function t(e,t){return e[t]<<8|e[t+1]}function a(e){const t=e.length;let a=32768;t<1240?a=107:t<33900&&(a=1131);return a}function c(a,i,n){var s,o,c,l=1===t(a,i+2)?e(a,i+8):e(a,i+16),h=t(a,i+l);if(4===h){t(a,i+l+2);var u=t(a,i+l+6)>>1;o=i+l+14;s=[];for(c=0;c<u;c++,o+=2)s[c]={end:t(a,o)};o+=2;for(c=0;c<u;c++,o+=2)s[c].start=t(a,o);for(c=0;c<u;c++,o+=2)s[c].idDelta=t(a,o);for(c=0;c<u;c++,o+=2){var d=t(a,o);if(0!==d){s[c].ids=[];for(var f=0,g=s[c].end-s[c].start+1;f<g;f++){s[c].ids[f]=t(a,o+d);d+=2}}}return s}if(12===h){e(a,i+l+4);var m=e(a,i+l+12);o=i+l+16;s=[];for(c=0;c<m;c++){s.push({start:e(a,o),end:e(a,o+4),idDelta:e(a,o+8)-e(a,o)});o+=12}return s}throw new r.FormatError(`unsupported cmap: ${h}`)}function l(e,t,a,r){var n=new i.CFFParser(new o.Stream(e,t,a-t),{},r).parse();return{glyphs:n.charStrings.objects,subrs:n.topDict.privateDict&&n.topDict.privateDict.subrsIndex&&n.topDict.privateDict.subrsIndex.objects,gsubrs:n.globalSubrIndex&&n.globalSubrIndex.objects,isCFFCIDFont:n.isCIDFont,fdSelect:n.fdSelect,fdArray:n.fdArray}}function h(e,t){for(var a=t.codePointAt(0),r=0,i=0,n=e.length-1;i<n;){var s=i+n+1>>1;a<e[s].start?n=s-1:i=s}e[i].start<=a&&a<=e[i].end&&(r=e[i].idDelta+(e[i].ids?e[i].ids[a-e[i].start]:a)&65535);return{charCode:a,glyphId:r}}const u=[];class d{constructor(e){this.constructor===d&&(0,r.unreachable)("Cannot initialize CompiledFont.");this.fontMatrix=e;this.compiledGlyphs=Object.create(null);this.compiledCharCodeToGlyphId=Object.create(null)}getPathJs(e){const t=h(this.cmap,e);let a=this.compiledGlyphs[t.glyphId];if(!a){a=this.compileGlyph(this.glyphs[t.glyphId],t.glyphId);this.compiledGlyphs[t.glyphId]=a}void 0===this.compiledCharCodeToGlyphId[t.charCode]&&(this.compiledCharCodeToGlyphId[t.charCode]=t.glyphId);return a}compileGlyph(e,t){if(!e||0===e.length||14===e[0])return u;let a=this.fontMatrix;if(this.isCFFCIDFont){const e=this.fdSelect.getFDIndex(t);if(e>=0&&e<this.fdArray.length){a=this.fdArray[e].getByName("FontMatrix")||r.FONT_IDENTITY_MATRIX}else(0,r.warn)("Invalid fd index for glyph index.")}const i=[];i.push({cmd:"save"});i.push({cmd:"transform",args:a.slice()});i.push({cmd:"scale",args:["size","-size"]});this.compileGlyphImpl(e,i,t);i.push({cmd:"restore"});return i}compileGlyphImpl(){(0,r.unreachable)("Children classes should implement this.")}hasBuiltPath(e){const t=h(this.cmap,e);return void 0!==this.compiledGlyphs[t.glyphId]&&void 0!==this.compiledCharCodeToGlyphId[t.charCode]}}class f extends d{constructor(e,t,a){super(a||[488e-6,0,0,488e-6,0,0]);this.glyphs=e;this.cmap=t}compileGlyphImpl(e,t){!function e(t,a,r){function i(e,t){a.push({cmd:"moveTo",args:[e,t]})}function n(e,t){a.push({cmd:"lineTo",args:[e,t]})}function s(e,t,r,i){a.push({cmd:"quadraticCurveTo",args:[e,t,r,i]})}var o,c=0,l=(t[c]<<24|t[c+1]<<16)>>16,h=0,u=0;c+=10;if(l<0)do{o=t[c]<<8|t[c+1];var d,f,g=t[c+2]<<8|t[c+3];c+=4;if(1&o){d=(t[c]<<24|t[c+1]<<16)>>16;f=(t[c+2]<<24|t[c+3]<<16)>>16;c+=4}else{d=t[c++];f=t[c++]}if(2&o){h=d;u=f}else{h=0;u=0}var m=1,p=1,b=0,y=0;if(8&o){m=p=(t[c]<<24|t[c+1]<<16)/1073741824;c+=2}else if(64&o){m=(t[c]<<24|t[c+1]<<16)/1073741824;p=(t[c+2]<<24|t[c+3]<<16)/1073741824;c+=4}else if(128&o){m=(t[c]<<24|t[c+1]<<16)/1073741824;b=(t[c+2]<<24|t[c+3]<<16)/1073741824;y=(t[c+4]<<24|t[c+5]<<16)/1073741824;p=(t[c+6]<<24|t[c+7]<<16)/1073741824;c+=8}var v=r.glyphs[g];if(v){a.push({cmd:"save"});a.push({cmd:"transform",args:[m,b,y,p,h,u]});e(v,a,r);a.push({cmd:"restore"})}}while(32&o);else{var w,k,S=[];for(w=0;w<l;w++){S.push(t[c]<<8|t[c+1]);c+=2}c+=2+(t[c]<<8|t[c+1]);for(var C=S[S.length-1]+1,x=[];x.length<C;){var A=1;8&(o=t[c++])&&(A+=t[c++]);for(;A-- >0;)x.push({flags:o})}for(w=0;w<C;w++){switch(18&x[w].flags){case 0:h+=(t[c]<<24|t[c+1]<<16)>>16;c+=2;break;case 2:h-=t[c++];break;case 18:h+=t[c++]}x[w].x=h}for(w=0;w<C;w++){switch(36&x[w].flags){case 0:u+=(t[c]<<24|t[c+1]<<16)>>16;c+=2;break;case 4:u-=t[c++];break;case 36:u+=t[c++]}x[w].y=u}var I=0;for(c=0;c<l;c++){var F=S[c],T=x.slice(I,F+1);if(1&T[0].flags)T.push(T[0]);else if(1&T[T.length-1].flags)T.unshift(T[T.length-1]);else{var E={flags:1,x:(T[0].x+T[T.length-1].x)/2,y:(T[0].y+T[T.length-1].y)/2};T.unshift(E);T.push(E)}i(T[0].x,T[0].y);for(w=1,k=T.length;w<k;w++)if(1&T[w].flags)n(T[w].x,T[w].y);else if(1&T[w+1].flags){s(T[w].x,T[w].y,T[w+1].x,T[w+1].y);w++}else s(T[w].x,T[w].y,(T[w].x+T[w+1].x)/2,(T[w].y+T[w+1].y)/2);I=F+1}}}(e,t,this)}}class g extends d{constructor(e,t,r,i){super(r||[.001,0,0,.001,0,0]);this.glyphs=e.glyphs;this.gsubrs=e.gsubrs||[];this.subrs=e.subrs||[];this.cmap=t;this.glyphNameMap=i||(0,n.getGlyphsUnicode)();this.gsubrsBias=a(this.gsubrs);this.subrsBias=a(this.subrs);this.isCFFCIDFont=e.isCFFCIDFont;this.fdSelect=e.fdSelect;this.fdArray=e.fdArray}compileGlyphImpl(e,t,i){!function e(t,i,n,o){var c=[],l=0,u=0,d=0;function f(e,t){i.push({cmd:"moveTo",args:[e,t]})}function g(e,t){i.push({cmd:"lineTo",args:[e,t]})}function m(e,t,a,r,n,s){i.push({cmd:"bezierCurveTo",args:[e,t,a,r,n,s]})}!function t(p){for(var b=0;b<p.length;){var y,v,w,k,S,C,x,A,I=!1,F=p[b++];switch(F){case 1:case 3:d+=c.length>>1;I=!0;break;case 4:u+=c.pop();f(l,u);I=!0;break;case 5:for(;c.length>0;){l+=c.shift();u+=c.shift();g(l,u)}break;case 6:for(;c.length>0;){g(l+=c.shift(),u);if(0===c.length)break;u+=c.shift();g(l,u)}break;case 7:for(;c.length>0;){u+=c.shift();g(l,u);if(0===c.length)break;g(l+=c.shift(),u)}break;case 8:for(;c.length>0;){y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u)}break;case 10:x=c.pop();A=null;if(n.isCFFCIDFont){const e=n.fdSelect.getFDIndex(o);if(e>=0&&e<n.fdArray.length){const t=n.fdArray[e];let r;t.privateDict&&t.privateDict.subrsIndex&&(r=t.privateDict.subrsIndex.objects);r&&(A=r[x+=a(r)])}else(0,r.warn)("Invalid fd index for glyph index.")}else A=n.subrs[x+n.subrsBias];A&&t(A);break;case 11:return;case 12:switch(F=p[b++]){case 34:v=(y=l+c.shift())+c.shift();S=u+c.shift();l=v+c.shift();m(y,u,v,S,l,S);v=(y=l+c.shift())+c.shift();l=v+c.shift();m(y,S,v,u,l,u);break;case 35:y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u);y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u);c.pop();break;case 36:m(y=l+c.shift(),S=u+c.shift(),v=y+c.shift(),C=S+c.shift(),l=v+c.shift(),C);m(y=l+c.shift(),C,v=y+c.shift(),C+c.shift(),l=v+c.shift(),u);break;case 37:var T=l,E=u;y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u);y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v;u=k;Math.abs(l-T)>Math.abs(u-E)?l+=c.shift():u+=c.shift();m(y,w,v,k,l,u);break;default:throw new r.FormatError(`unknown operator: 12 ${F}`)}break;case 14:if(c.length>=4){var O=c.pop(),P=c.pop();u=c.pop();l=c.pop();i.push({cmd:"save"});i.push({cmd:"translate",args:[l,u]});var B=h(n.cmap,String.fromCharCode(n.glyphNameMap[s.StandardEncoding[O]]));e(n.glyphs[B.glyphId],i,n,B.glyphId);i.push({cmd:"restore"});B=h(n.cmap,String.fromCharCode(n.glyphNameMap[s.StandardEncoding[P]]));e(n.glyphs[B.glyphId],i,n,B.glyphId)}return;case 18:d+=c.length>>1;I=!0;break;case 19:case 20:b+=(d+=c.length>>1)+7>>3;I=!0;break;case 21:u+=c.pop();f(l+=c.pop(),u);I=!0;break;case 22:f(l+=c.pop(),u);I=!0;break;case 23:d+=c.length>>1;I=!0;break;case 24:for(;c.length>2;){y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u)}l+=c.shift();u+=c.shift();g(l,u);break;case 25:for(;c.length>6;){l+=c.shift();u+=c.shift();g(l,u)}y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u);break;case 26:c.length%2&&(l+=c.shift());for(;c.length>0;){y=l;w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v;u=k+c.shift();m(y,w,v,k,l,u)}break;case 27:c.length%2&&(u+=c.shift());for(;c.length>0;)m(y=l+c.shift(),w=u,v=y+c.shift(),k=w+c.shift(),l=v+c.shift(),u=k);break;case 28:c.push((p[b]<<24|p[b+1]<<16)>>16);b+=2;break;case 29:x=c.pop()+n.gsubrsBias;(A=n.gsubrs[x])&&t(A);break;case 30:for(;c.length>0;){y=l;w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+(1===c.length?c.shift():0);m(y,w,v,k,l,u);if(0===c.length)break;y=l+c.shift();w=u;v=y+c.shift();k=w+c.shift();u=k+c.shift();m(y,w,v,k,l=v+(1===c.length?c.shift():0),u)}break;case 31:for(;c.length>0;){y=l+c.shift();w=u;v=y+c.shift();k=w+c.shift();u=k+c.shift();m(y,w,v,k,l=v+(1===c.length?c.shift():0),u);if(0===c.length)break;y=l;w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+(1===c.length?c.shift():0);m(y,w,v,k,l,u)}break;default:if(F<32)throw new r.FormatError(`unknown operator: ${F}`);if(F<247)c.push(F-139);else if(F<251)c.push(256*(F-247)+p[b++]+108);else if(F<255)c.push(256*-(F-251)-p[b++]-108);else{c.push((p[b]<<24|p[b+1]<<16|p[b+2]<<8|p[b+3])/65536);b+=4}}I&&(c.length=0)}}(t)}(e,t,this,i)}}return{create:function(a,i){for(var n,s,o,h,u,d,m=new Uint8Array(a.data),p=t(m,4),b=0,y=12;b<p;b++,y+=16){var v=(0,r.bytesToString)(m.subarray(y,y+4)),w=e(m,y+8),k=e(m,y+12);switch(v){case"cmap":n=c(m,w);break;case"glyf":s=m.subarray(w,w+k);break;case"loca":o=m.subarray(w,w+k);break;case"head":d=t(m,w+18);u=t(m,w+50);break;case"CFF ":h=l(m,w,w+k,i)}}if(s){var S=d?[1/d,0,0,1/d,0,0]:a.fontMatrix;return new f(function(e,t,a){var r,i;if(a){r=4;i=function(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]}}else{r=2;i=function(e,t){return e[t]<<9|e[t+1]<<1}}for(var n=[],s=i(t,0),o=r;o<t.length;o+=r){var c=i(t,o);n.push(e.subarray(s,c));s=c}return n}(s,o,u),n,S)}return new g(h,n,a.fontMatrix,a.glyphNameMap)}}}();t.FontRendererFactory=c},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Type1Parser=void 0;var r=a(30),i=a(7),n=a(11),s=a(2),o=function(){var e=[4],t=[5],a=[6],r=[7],i=[8],n=[12,35],o=[14],c=[21],l=[22],h=[30],u=[31];function d(){this.width=0;this.lsb=0;this.flexing=!1;this.output=[];this.stack=[]}d.prototype={convert:function(d,f,g){for(var m,p,b,y=d.length,v=!1,w=0;w<y;w++){var k=d[w];if(k<32){12===k&&(k=(k<<8)+d[++w]);switch(k){case 1:case 3:this.stack=[];break;case 4:if(this.flexing){if(this.stack.length<1){v=!0;break}var S=this.stack.pop();this.stack.push(0,S);break}v=this.executeCommand(1,e);break;case 5:v=this.executeCommand(2,t);break;case 6:v=this.executeCommand(1,a);break;case 7:v=this.executeCommand(1,r);break;case 8:v=this.executeCommand(6,i);break;case 9:this.stack=[];break;case 10:if(this.stack.length<1){v=!0;break}if(!f[b=this.stack.pop()]){v=!0;break}v=this.convert(f[b],f,g);break;case 11:return v;case 13:if(this.stack.length<2){v=!0;break}m=this.stack.pop();p=this.stack.pop();this.lsb=p;this.width=m;this.stack.push(m,p);v=this.executeCommand(2,l);break;case 14:this.output.push(o[0]);break;case 21:if(this.flexing)break;v=this.executeCommand(2,c);break;case 22:if(this.flexing){this.stack.push(0);break}v=this.executeCommand(1,l);break;case 30:v=this.executeCommand(4,h);break;case 31:v=this.executeCommand(4,u);break;case 3072:case 3073:case 3074:this.stack=[];break;case 3078:if(g){this.seac=this.stack.splice(-4,4);v=this.executeCommand(0,o)}else v=this.executeCommand(4,o);break;case 3079:if(this.stack.length<4){v=!0;break}this.stack.pop();m=this.stack.pop();var C=this.stack.pop();p=this.stack.pop();this.lsb=p;this.width=m;this.stack.push(m,p,C);v=this.executeCommand(3,c);break;case 3084:if(this.stack.length<2){v=!0;break}var x=this.stack.pop(),A=this.stack.pop();this.stack.push(A/x);break;case 3088:if(this.stack.length<2){v=!0;break}b=this.stack.pop();var I=this.stack.pop();if(0===b&&3===I){var F=this.stack.splice(this.stack.length-17,17);this.stack.push(F[2]+F[0],F[3]+F[1],F[4],F[5],F[6],F[7],F[8],F[9],F[10],F[11],F[12],F[13],F[14]);v=this.executeCommand(13,n,!0);this.flexing=!1;this.stack.push(F[15],F[16])}else 1===b&&0===I&&(this.flexing=!0);break;case 3089:break;case 3105:this.stack=[];break;default:(0,s.warn)('Unknown type 1 charstring command of "'+k+'"')}if(v)break}else{k<=246?k-=139:k=k<=250?256*(k-247)+d[++w]+108:k<=254?-256*(k-251)-d[++w]-108:(255&d[++w])<<24|(255&d[++w])<<16|(255&d[++w])<<8|(255&d[++w])<<0;this.stack.push(k)}}return v},executeCommand(e,t,a){var r=this.stack.length;if(e>r)return!0;for(var i=r-e,n=i;n<r;n++){var s=this.stack[n];if(Number.isInteger(s))this.output.push(28,s>>8&255,255&s);else{s=65536*s|0;this.output.push(255,s>>24&255,s>>16&255,s>>8&255,255&s)}}this.output.push.apply(this.output,t);a?this.stack.splice(i,e):this.stack.length=0;return!1}};return d}(),c=function(){function e(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function t(e,t,a){if(a>=e.length)return new Uint8Array(0);var r,i,n=0|t;for(r=0;r<a;r++)n=52845*(e[r]+n)+22719&65535;var s=e.length-a,o=new Uint8Array(s);for(r=a,i=0;i<s;r++,i++){var c=e[r];o[i]=c^n>>8;n=52845*(c+n)+22719&65535}return o}function a(e){return 47===e||91===e||93===e||123===e||125===e||40===e||41===e}function s(a,r,i){if(r){var s=a.getBytes(),o=!(e(s[0])&&e(s[1])&&e(s[2])&&e(s[3]));a=new n.Stream(o?t(s,55665,4):function(t,a,r){var i,n,s=0|a,o=t.length,c=new Uint8Array(o>>>1);for(i=0,n=0;i<o;i++){var l=t[i];if(e(l)){i++;for(var h;i<o&&!e(h=t[i]);)i++;if(i<o){var u=parseInt(String.fromCharCode(l,h),16);c[n++]=u^s>>8;s=52845*(u+s)+22719&65535}}}return Array.prototype.slice.call(c,r,n)}(s,55665,4))}this.seacAnalysisEnabled=!!i;this.stream=a;this.nextChar()}s.prototype={readNumberArray:function(){this.getToken();for(var e=[];;){var t=this.getToken();if(null===t||"]"===t||"}"===t)break;e.push(parseFloat(t||0))}return e},readNumber:function(){var e=this.getToken();return parseFloat(e||0)},readInt:function(){var e=this.getToken();return 0|parseInt(e||0,10)},readBoolean:function(){return"true"===this.getToken()?1:0},nextChar:function(){return this.currentChar=this.stream.getByte()},getToken:function(){for(var e=!1,t=this.currentChar;;){if(-1===t)return null;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(!(0,i.isWhiteSpace)(t))break;t=this.nextChar()}if(a(t)){this.nextChar();return String.fromCharCode(t)}var r="";do{r+=String.fromCharCode(t);t=this.nextChar()}while(t>=0&&!(0,i.isWhiteSpace)(t)&&!a(t));return r},readCharStrings:function(e,a){return-1===a?e:t(e,4330,a)},extractFontProgram:function(e){var t=this.stream,a=[],r=[],i=Object.create(null);i.lenIV=4;for(var n,s,c,l,h,u={subrs:[],charstrings:[],properties:{privateData:i}};null!==(n=this.getToken());)if("/"===n)switch(n=this.getToken()){case"CharStrings":this.getToken();this.getToken();this.getToken();this.getToken();for(;null!==(n=this.getToken())&&"end"!==n;)if("/"===n){var d=this.getToken();s=this.readInt();this.getToken();c=s>0?t.getBytes(s):new Uint8Array(0);l=u.properties.privateData.lenIV;h=this.readCharStrings(c,l);this.nextChar();"noaccess"===(n=this.getToken())&&this.getToken();r.push({glyph:d,encoded:h})}break;case"Subrs":this.readInt();this.getToken();for(;"dup"===this.getToken();){var f=this.readInt();s=this.readInt();this.getToken();c=s>0?t.getBytes(s):new Uint8Array(0);l=u.properties.privateData.lenIV;h=this.readCharStrings(c,l);this.nextChar();"noaccess"===(n=this.getToken())&&this.getToken();a[f]=h}break;case"BlueValues":case"OtherBlues":case"FamilyBlues":case"FamilyOtherBlues":var g=this.readNumberArray();g.length>0&&g.length,0;break;case"StemSnapH":case"StemSnapV":u.properties.privateData[n]=this.readNumberArray();break;case"StdHW":case"StdVW":u.properties.privateData[n]=this.readNumberArray()[0];break;case"BlueShift":case"lenIV":case"BlueFuzz":case"BlueScale":case"LanguageGroup":case"ExpansionFactor":u.properties.privateData[n]=this.readNumber();break;case"ForceBold":u.properties.privateData[n]=this.readBoolean()}for(var m=0;m<r.length;m++){d=r[m].glyph;h=r[m].encoded;var p=new o,b=p.convert(h,a,this.seacAnalysisEnabled),y=p.output;b&&(y=[14]);const t={glyphName:d,charstring:y,width:p.width,lsb:p.lsb,seac:p.seac};".notdef"===d?u.charstrings.unshift(t):u.charstrings.push(t);if(e.builtInEncoding){const t=e.builtInEncoding.indexOf(d);t>-1&&void 0===e.widths[t]&&t>=e.firstChar&&t<=e.lastChar&&(e.widths[t]=p.width)}}return u},extractFontHeader:function(e){for(var t;null!==(t=this.getToken());)if("/"===t)switch(t=this.getToken()){case"FontMatrix":var a=this.readNumberArray();e.fontMatrix=a;break;case"Encoding":var i,n=this.getToken();if(/^\d+$/.test(n)){i=[];var s=0|parseInt(n,10);this.getToken();for(var o=0;o<s;o++){t=this.getToken();for(;"dup"!==t&&"def"!==t;)if(null===(t=this.getToken()))return;if("def"===t)break;var c=this.readInt();this.getToken();var l=this.getToken();i[c]=l;this.getToken()}}else i=(0,r.getEncoding)(n);e.builtInEncoding=i;break;case"FontBBox":var h=this.readNumberArray();e.ascent=Math.max(h[3],h[1]);e.descent=Math.min(h[1],h[3]);e.ascentScaled=!0}}};return s}();t.Type1Parser=c},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getTilingPatternIR=function(e,t,a){const i=t.getArray("Matrix"),n=r.Util.normalizeRect(t.getArray("BBox")),s=t.get("XStep"),o=t.get("YStep"),c=t.get("PaintType"),l=t.get("TilingType");if(n[2]-n[0]==0||n[3]-n[1]==0)throw new r.FormatError(`Invalid getTilingPatternIR /BBox array: [${n}].`);return["TilingPattern",a,e,i,n,s,o,c,l]};t.Pattern=void 0;var r=a(2),i=a(22),n=a(4),s=a(7),o=2,c=3,l=4,h=5,u=6,d=7,f=function(){function e(){(0,r.unreachable)("should not call Pattern constructor")}e.prototype={getPattern:function(e){(0,r.unreachable)(`Should not call Pattern.getStyle: ${e}`)}};e.parseShading=function(e,t,a,i,f,m){var p=(0,n.isStream)(e)?e.dict:e,b=p.get("ShadingType");try{switch(b){case o:case c:return new g.RadialAxial(p,t,a,i,m);case l:case h:case u:case d:return new g.Mesh(e,t,a,i,m);default:throw new r.FormatError("Unsupported ShadingType: "+b)}}catch(e){if(e instanceof s.MissingDataException)throw e;f.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.shadingPattern});(0,r.warn)(e);return new g.Dummy}};return e}();t.Pattern=f;var g={SMALL_NUMBER:1e-6};g.RadialAxial=function(){function e(e,t,a,n,s){this.matrix=t;this.coordsArr=e.getArray("Coords");this.shadingType=e.get("ShadingType");this.type="Pattern";var o=e.get("ColorSpace","CS");o=i.ColorSpace.parse(o,a,n,s);this.cs=o;const l=e.getArray("BBox");Array.isArray(l)&&4===l.length?this.bbox=r.Util.normalizeRect(l):this.bbox=null;var h=0,u=1;if(e.has("Domain")){var d=e.getArray("Domain");h=d[0];u=d[1]}var f=!1,m=!1;if(e.has("Extend")){var p=e.getArray("Extend");f=p[0];m=p[1]}if(!(this.shadingType!==c||f&&m)){var b=this.coordsArr[0],y=this.coordsArr[1],v=this.coordsArr[2],w=this.coordsArr[3],k=this.coordsArr[4],S=this.coordsArr[5],C=Math.sqrt((b-w)*(b-w)+(y-k)*(y-k));v<=S+C&&S<=v+C&&(0,r.warn)("Unsupported radial gradient.")}this.extendStart=f;this.extendEnd=m;var x=e.get("Function"),A=s.createFromArray(x);const I=(u-h)/10;var F=this.colorStops=[];if(h>=u||I<=0)(0,r.info)("Bad shading domain.");else{var T,E=new Float32Array(o.numComps),O=new Float32Array(1);for(let e=0;e<=10;e++){O[0]=h+e*I;A(O,0,E,0);T=o.getRgb(E,0);var P=r.Util.makeCssRgb(T[0],T[1],T[2]);F.push([e/10,P])}var B="transparent";if(e.has("Background")){T=o.getRgb(e.get("Background"),0);B=r.Util.makeCssRgb(T[0],T[1],T[2])}if(!f){F.unshift([0,B]);F[1][0]+=g.SMALL_NUMBER}if(!m){F[F.length-1][0]-=g.SMALL_NUMBER;F.push([1,B])}this.colorStops=F}}e.prototype={getIR:function(){var e,t,a,i,n,s=this.coordsArr,l=this.shadingType;if(l===o){t=[s[0],s[1]];a=[s[2],s[3]];i=null;n=null;e="axial"}else if(l===c){t=[s[0],s[1]];a=[s[3],s[4]];i=s[2];n=s[5];e="radial"}else(0,r.unreachable)(`getPattern type unknown: ${l}`);var h=this.matrix;if(h){t=r.Util.applyTransform(t,h);a=r.Util.applyTransform(a,h);if(l===c){var u=r.Util.singularValueDecompose2dScale(h);i*=u[0];n*=u[1]}}return["RadialAxial",e,this.bbox,this.colorStops,t,a,i,n]}};return e}();g.Mesh=function(){function e(e,t){this.stream=e;this.context=t;this.buffer=0;this.bufferLength=0;var a=t.numComps;this.tmpCompsBuf=new Float32Array(a);var r=t.colorSpace.numComps;this.tmpCsCompsBuf=t.colorFn?new Float32Array(r):this.tmpCompsBuf}e.prototype={get hasData(){if(this.stream.end)return this.stream.pos<this.stream.end;if(this.bufferLength>0)return!0;var e=this.stream.getByte();if(e<0)return!1;this.buffer=e;this.bufferLength=8;return!0},readBits:function(e){var t=this.buffer,a=this.bufferLength;if(32===e){if(0===a)return(this.stream.getByte()<<24|this.stream.getByte()<<16|this.stream.getByte()<<8|this.stream.getByte())>>>0;t=t<<24|this.stream.getByte()<<16|this.stream.getByte()<<8|this.stream.getByte();var r=this.stream.getByte();this.buffer=r&(1<<a)-1;return(t<<8-a|(255&r)>>a)>>>0}if(8===e&&0===a)return this.stream.getByte();for(;a<e;){t=t<<8|this.stream.getByte();a+=8}a-=e;this.bufferLength=a;this.buffer=t&(1<<a)-1;return t>>a},align:function(){this.buffer=0;this.bufferLength=0},readFlag:function(){return this.readBits(this.context.bitsPerFlag)},readCoordinate:function(){var e=this.context.bitsPerCoordinate,t=this.readBits(e),a=this.readBits(e),r=this.context.decode,i=e<32?1/((1<<e)-1):2.3283064365386963e-10;return[t*i*(r[1]-r[0])+r[0],a*i*(r[3]-r[2])+r[2]]},readComponents:function(){for(var e=this.context.numComps,t=this.context.bitsPerComponent,a=t<32?1/((1<<t)-1):2.3283064365386963e-10,r=this.context.decode,i=this.tmpCompsBuf,n=0,s=4;n<e;n++,s+=2){var o=this.readBits(t);i[n]=o*a*(r[s+1]-r[s])+r[s]}var c=this.tmpCsCompsBuf;this.context.colorFn&&this.context.colorFn(i,0,c,0);return this.context.colorSpace.getRgb(c,0)}};var t,a=(t=[],function(e){t[e]||(t[e]=function(e){for(var t=[],a=0;a<=e;a++){var r=a/e,i=1-r;t.push(new Float32Array([i*i*i,3*r*i*i,3*r*r*i,r*r*r]))}return t}(e));return t[e]});function s(e,t){var i=e.figures[t];(0,r.assert)("patch"===i.type,"Unexpected patch mesh figure");var n=e.coords,s=e.colors,o=i.coords,c=i.colors,l=Math.min(n[o[0]][0],n[o[3]][0],n[o[12]][0],n[o[15]][0]),h=Math.min(n[o[0]][1],n[o[3]][1],n[o[12]][1],n[o[15]][1]),u=Math.max(n[o[0]][0],n[o[3]][0],n[o[12]][0],n[o[15]][0]),d=Math.max(n[o[0]][1],n[o[3]][1],n[o[12]][1],n[o[15]][1]),f=Math.ceil(20*(u-l)/(e.bounds[2]-e.bounds[0]));f=Math.max(3,Math.min(20,f));var g=Math.ceil(20*(d-h)/(e.bounds[3]-e.bounds[1]));g=Math.max(3,Math.min(20,g));for(var m=f+1,p=new Int32Array((g+1)*m),b=new Int32Array((g+1)*m),y=0,v=new Uint8Array(3),w=new Uint8Array(3),k=s[c[0]],S=s[c[1]],C=s[c[2]],x=s[c[3]],A=a(g),I=a(f),F=0;F<=g;F++){v[0]=(k[0]*(g-F)+C[0]*F)/g|0;v[1]=(k[1]*(g-F)+C[1]*F)/g|0;v[2]=(k[2]*(g-F)+C[2]*F)/g|0;w[0]=(S[0]*(g-F)+x[0]*F)/g|0;w[1]=(S[1]*(g-F)+x[1]*F)/g|0;w[2]=(S[2]*(g-F)+x[2]*F)/g|0;for(var T=0;T<=f;T++,y++)if(0!==F&&F!==g||0!==T&&T!==f){for(var E=0,O=0,P=0,B=0;B<=3;B++)for(var D=0;D<=3;D++,P++){var N=A[F][B]*I[T][D];E+=n[o[P]][0]*N;O+=n[o[P]][1]*N}p[y]=n.length;n.push([E,O]);b[y]=s.length;var M=new Uint8Array(3);M[0]=(v[0]*(f-T)+w[0]*T)/f|0;M[1]=(v[1]*(f-T)+w[1]*T)/f|0;M[2]=(v[2]*(f-T)+w[2]*T)/f|0;s.push(M)}}p[0]=o[0];b[0]=c[0];p[f]=o[3];b[f]=c[1];p[m*g]=o[12];b[m*g]=c[2];p[m*g+f]=o[15];b[m*g+f]=c[3];e.figures[t]={type:"lattice",coords:p,colors:b,verticesPerRow:m}}function o(e){for(var t=e.coords[0][0],a=e.coords[0][1],r=t,i=a,n=1,s=e.coords.length;n<s;n++){var o=e.coords[n][0],c=e.coords[n][1];t=t>o?o:t;a=a>c?c:a;r=r<o?o:r;i=i<c?c:i}e.bounds=[t,a,r,i]}function c(t,a,c,f,g){if(!(0,n.isStream)(t))throw new r.FormatError("Mesh data is not a stream");var m=t.dict;this.matrix=a;this.shadingType=m.get("ShadingType");this.type="Pattern";const p=m.getArray("BBox");Array.isArray(p)&&4===p.length?this.bbox=r.Util.normalizeRect(p):this.bbox=null;var b=m.get("ColorSpace","CS");b=i.ColorSpace.parse(b,c,f,g);this.cs=b;this.background=m.has("Background")?b.getRgb(m.get("Background"),0):null;var y=m.get("Function"),v=y?g.createFromArray(y):null;this.coords=[];this.colors=[];this.figures=[];var w=new e(t,{bitsPerCoordinate:m.get("BitsPerCoordinate"),bitsPerComponent:m.get("BitsPerComponent"),bitsPerFlag:m.get("BitsPerFlag"),decode:m.getArray("Decode"),colorFn:v,colorSpace:b,numComps:v?1:b.numComps}),k=!1;switch(this.shadingType){case l:!function(e,t){for(var a=e.coords,i=e.colors,n=[],s=[],o=0;t.hasData;){var c=t.readFlag(),l=t.readCoordinate(),h=t.readComponents();if(0===o){if(!(0<=c&&c<=2))throw new r.FormatError("Unknown type4 flag");switch(c){case 0:o=3;break;case 1:s.push(s[s.length-2],s[s.length-1]);o=1;break;case 2:s.push(s[s.length-3],s[s.length-1]);o=1}n.push(c)}s.push(a.length);a.push(l);i.push(h);o--;t.align()}e.figures.push({type:"triangles",coords:new Int32Array(s),colors:new Int32Array(s)})}(this,w);break;case h:var S=0|m.get("VerticesPerRow");if(S<2)throw new r.FormatError("Invalid VerticesPerRow");!function(e,t,a){for(var r=e.coords,i=e.colors,n=[];t.hasData;){var s=t.readCoordinate(),o=t.readComponents();n.push(r.length);r.push(s);i.push(o)}e.figures.push({type:"lattice",coords:new Int32Array(n),colors:new Int32Array(n),verticesPerRow:a})}(this,w,S);break;case u:!function(e,t){for(var a=e.coords,i=e.colors,n=new Int32Array(16),s=new Int32Array(4);t.hasData;){var o,c,l=t.readFlag();if(!(0<=l&&l<=3))throw new r.FormatError("Unknown type6 flag");var h=a.length;for(o=0,c=0!==l?8:12;o<c;o++)a.push(t.readCoordinate());var u,d,f,g,m=i.length;for(o=0,c=0!==l?2:4;o<c;o++)i.push(t.readComponents());switch(l){case 0:n[12]=h+3;n[13]=h+4;n[14]=h+5;n[15]=h+6;n[8]=h+2;n[11]=h+7;n[4]=h+1;n[7]=h+8;n[0]=h;n[1]=h+11;n[2]=h+10;n[3]=h+9;s[2]=m+1;s[3]=m+2;s[0]=m;s[1]=m+3;break;case 1:u=n[12];d=n[13];f=n[14];g=n[15];n[12]=g;n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=f;n[11]=h+3;n[4]=d;n[7]=h+4;n[0]=u;n[1]=h+7;n[2]=h+6;n[3]=h+5;u=s[2];d=s[3];s[2]=d;s[3]=m;s[0]=u;s[1]=m+1;break;case 2:u=n[15];d=n[11];n[12]=n[3];n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=n[7];n[11]=h+3;n[4]=d;n[7]=h+4;n[0]=u;n[1]=h+7;n[2]=h+6;n[3]=h+5;u=s[3];s[2]=s[1];s[3]=m;s[0]=u;s[1]=m+1;break;case 3:n[12]=n[0];n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=n[1];n[11]=h+3;n[4]=n[2];n[7]=h+4;n[0]=n[3];n[1]=h+7;n[2]=h+6;n[3]=h+5;s[2]=s[0];s[3]=m;s[0]=s[1];s[1]=m+1}n[5]=a.length;a.push([(-4*a[n[0]][0]-a[n[15]][0]+6*(a[n[4]][0]+a[n[1]][0])-2*(a[n[12]][0]+a[n[3]][0])+3*(a[n[13]][0]+a[n[7]][0]))/9,(-4*a[n[0]][1]-a[n[15]][1]+6*(a[n[4]][1]+a[n[1]][1])-2*(a[n[12]][1]+a[n[3]][1])+3*(a[n[13]][1]+a[n[7]][1]))/9]);n[6]=a.length;a.push([(-4*a[n[3]][0]-a[n[12]][0]+6*(a[n[2]][0]+a[n[7]][0])-2*(a[n[0]][0]+a[n[15]][0])+3*(a[n[4]][0]+a[n[14]][0]))/9,(-4*a[n[3]][1]-a[n[12]][1]+6*(a[n[2]][1]+a[n[7]][1])-2*(a[n[0]][1]+a[n[15]][1])+3*(a[n[4]][1]+a[n[14]][1]))/9]);n[9]=a.length;a.push([(-4*a[n[12]][0]-a[n[3]][0]+6*(a[n[8]][0]+a[n[13]][0])-2*(a[n[0]][0]+a[n[15]][0])+3*(a[n[11]][0]+a[n[1]][0]))/9,(-4*a[n[12]][1]-a[n[3]][1]+6*(a[n[8]][1]+a[n[13]][1])-2*(a[n[0]][1]+a[n[15]][1])+3*(a[n[11]][1]+a[n[1]][1]))/9]);n[10]=a.length;a.push([(-4*a[n[15]][0]-a[n[0]][0]+6*(a[n[11]][0]+a[n[14]][0])-2*(a[n[12]][0]+a[n[3]][0])+3*(a[n[2]][0]+a[n[8]][0]))/9,(-4*a[n[15]][1]-a[n[0]][1]+6*(a[n[11]][1]+a[n[14]][1])-2*(a[n[12]][1]+a[n[3]][1])+3*(a[n[2]][1]+a[n[8]][1]))/9]);e.figures.push({type:"patch",coords:new Int32Array(n),colors:new Int32Array(s)})}}(this,w);k=!0;break;case d:!function(e,t){for(var a=e.coords,i=e.colors,n=new Int32Array(16),s=new Int32Array(4);t.hasData;){var o,c,l=t.readFlag();if(!(0<=l&&l<=3))throw new r.FormatError("Unknown type7 flag");var h=a.length;for(o=0,c=0!==l?12:16;o<c;o++)a.push(t.readCoordinate());var u,d,f,g,m=i.length;for(o=0,c=0!==l?2:4;o<c;o++)i.push(t.readComponents());switch(l){case 0:n[12]=h+3;n[13]=h+4;n[14]=h+5;n[15]=h+6;n[8]=h+2;n[9]=h+13;n[10]=h+14;n[11]=h+7;n[4]=h+1;n[5]=h+12;n[6]=h+15;n[7]=h+8;n[0]=h;n[1]=h+11;n[2]=h+10;n[3]=h+9;s[2]=m+1;s[3]=m+2;s[0]=m;s[1]=m+3;break;case 1:u=n[12];d=n[13];f=n[14];g=n[15];n[12]=g;n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=f;n[9]=h+9;n[10]=h+10;n[11]=h+3;n[4]=d;n[5]=h+8;n[6]=h+11;n[7]=h+4;n[0]=u;n[1]=h+7;n[2]=h+6;n[3]=h+5;u=s[2];d=s[3];s[2]=d;s[3]=m;s[0]=u;s[1]=m+1;break;case 2:u=n[15];d=n[11];n[12]=n[3];n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=n[7];n[9]=h+9;n[10]=h+10;n[11]=h+3;n[4]=d;n[5]=h+8;n[6]=h+11;n[7]=h+4;n[0]=u;n[1]=h+7;n[2]=h+6;n[3]=h+5;u=s[3];s[2]=s[1];s[3]=m;s[0]=u;s[1]=m+1;break;case 3:n[12]=n[0];n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=n[1];n[9]=h+9;n[10]=h+10;n[11]=h+3;n[4]=n[2];n[5]=h+8;n[6]=h+11;n[7]=h+4;n[0]=n[3];n[1]=h+7;n[2]=h+6;n[3]=h+5;s[2]=s[0];s[3]=m;s[0]=s[1];s[1]=m+1}e.figures.push({type:"patch",coords:new Int32Array(n),colors:new Int32Array(s)})}}(this,w);k=!0;break;default:(0,r.unreachable)("Unsupported mesh type.")}if(k){o(this);for(var C=0,x=this.figures.length;C<x;C++)s(this,C)}o(this);!function(e){var t,a,r,i,n=e.coords,s=new Float32Array(2*n.length);for(t=0,r=0,a=n.length;t<a;t++){var o=n[t];s[r++]=o[0];s[r++]=o[1]}e.coords=s;var c=e.colors,l=new Uint8Array(3*c.length);for(t=0,r=0,a=c.length;t<a;t++){var h=c[t];l[r++]=h[0];l[r++]=h[1];l[r++]=h[2]}e.colors=l;var u=e.figures;for(t=0,a=u.length;t<a;t++){var d=u[t],f=d.coords,g=d.colors;for(r=0,i=f.length;r<i;r++){f[r]*=2;g[r]*=3}}}(this)}c.prototype={getIR:function(){return["Mesh",this.shadingType,this.coords,this.colors,this.figures,this.bounds,this.matrix,this.bbox,this.background]}};return c}();g.Dummy=function(){function e(){this.type="Pattern"}e.prototype={getIR:function(){return["Dummy"]}};return e}()},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.bidi=function(e,t,a){var g=!0,m=e.length;if(0===m||a)return u(e,g,a);d.length=m;f.length=m;var p,b,y=0;for(p=0;p<m;++p){d[p]=e.charAt(p);var v=e.charCodeAt(p),w="L";v<=255?w=i[v]:1424<=v&&v<=1524?w="R":1536<=v&&v<=1791?(w=n[255&v])||(0,r.warn)("Bidi: invalid Unicode character "+v.toString(16)):1792<=v&&v<=2220&&(w="AL");"R"!==w&&"AL"!==w&&"AN"!==w||y++;f[p]=w}if(0===y)return u(e,g=!0);if(-1===t)if(y/m<.3){g=!0;t=0}else{g=!1;t=1}var k=[];for(p=0;p<m;++p)k[p]=t;var S,C=s(t)?"R":"L",x=C,A=x,I=x;for(p=0;p<m;++p)"NSM"===f[p]?f[p]=I:I=f[p];I=x;for(p=0;p<m;++p)"EN"===(S=f[p])?f[p]="AL"===I?"AN":"EN":"R"!==S&&"L"!==S&&"AL"!==S||(I=S);for(p=0;p<m;++p)"AL"===(S=f[p])&&(f[p]="R");for(p=1;p<m-1;++p){"ES"===f[p]&&"EN"===f[p-1]&&"EN"===f[p+1]&&(f[p]="EN");"CS"!==f[p]||"EN"!==f[p-1]&&"AN"!==f[p-1]||f[p+1]!==f[p-1]||(f[p]=f[p-1])}for(p=0;p<m;++p)if("EN"===f[p]){var F;for(F=p-1;F>=0&&"ET"===f[F];--F)f[F]="EN";for(F=p+1;F<m&&"ET"===f[F];++F)f[F]="EN"}for(p=0;p<m;++p)"WS"!==(S=f[p])&&"ES"!==S&&"ET"!==S&&"CS"!==S||(f[p]="ON");I=x;for(p=0;p<m;++p)"EN"===(S=f[p])?f[p]="L"===I?"L":"EN":"R"!==S&&"L"!==S||(I=S);for(p=0;p<m;++p)if("ON"===f[p]){var T=c(f,p+1,"ON"),E=x;p>0&&(E=f[p-1]);var O=A;T+1<m&&(O=f[T+1]);"L"!==E&&(E="R");"L"!==O&&(O="R");E===O&&l(f,p,T,E);p=T-1}for(p=0;p<m;++p)"ON"===f[p]&&(f[p]=C);for(p=0;p<m;++p){S=f[p];o(k[p])?"R"===S?k[p]+=1:"AN"!==S&&"EN"!==S||(k[p]+=2):"L"!==S&&"AN"!==S&&"EN"!==S||(k[p]+=1)}var P,B=-1,D=99;for(p=0,b=k.length;p<b;++p){P=k[p];B<P&&(B=P);D>P&&s(P)&&(D=P)}for(P=B;P>=D;--P){var N=-1;for(p=0,b=k.length;p<b;++p)if(k[p]<P){if(N>=0){h(d,N,p);N=-1}}else N<0&&(N=p);N>=0&&h(d,N,k.length)}for(p=0,b=d.length;p<b;++p){var M=d[p];"<"!==M&&">"!==M||(d[p]="")}return u(d.join(""),g)};var r=a(2),i=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],n=["AN","AN","AN","AN","AN","AN","ON","ON","AL","ET","ET","AL","CS","AL","ON","ON","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","AN","AN","AN","AN","AN","AN","AN","AN","AN","ET","AN","AN","AL","AL","AL","NSM","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","ON","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","NSM","NSM","ON","NSM","NSM","NSM","NSM","AL","AL","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","AL","AL","AL","AL","AL","AL"];function s(e){return 0!=(1&e)}function o(e){return 0==(1&e)}function c(e,t,a){for(var r=t,i=e.length;r<i;++r)if(e[r]!==a)return r;return r}function l(e,t,a,r){for(var i=t;i<a;++i)e[i]=r}function h(e,t,a){for(var r=t,i=a-1;r<i;++r,--i){var n=e[r];e[r]=e[i];e[i]=n}}function u(e,t,a=!1){let r="ltr";a?r="ttb":t||(r="rtl");return{str:e,dir:r}}var d=[],f=[]},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getMetrics=void 0;var r=a(7),i=(0,r.getLookupTableFactory)((function(e){e.Courier=600;e["Courier-Bold"]=600;e["Courier-BoldOblique"]=600;e["Courier-Oblique"]=600;e.Helvetica=(0,r.getLookupTableFactory)((function(e){e.space=278;e.exclam=278;e.quotedbl=355;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=667;e.quoteright=222;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=278;e.semicolon=278;e.less=584;e.equal=584;e.greater=584;e.question=556;e.at=1015;e.A=667;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=500;e.K=667;e.L=556;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=278;e.backslash=278;e.bracketright=278;e.asciicircum=469;e.underscore=556;e.quoteleft=222;e.a=556;e.b=556;e.c=500;e.d=556;e.e=556;e.f=278;e.g=556;e.h=556;e.i=222;e.j=222;e.k=500;e.l=222;e.m=833;e.n=556;e.o=556;e.p=556;e.q=556;e.r=333;e.s=500;e.t=278;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=500;e.braceleft=334;e.bar=260;e.braceright=334;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=191;e.quotedblleft=333;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=537;e.bullet=350;e.quotesinglbase=222;e.quotedblbase=333;e.quotedblright=333;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=556;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=222;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=556;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=667;e.aacute=556;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=500;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=500;e.aring=556;e.Ncommaaccent=722;e.lacute=222;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=500;e.scedilla=500;e.iacute=278;e.lozenge=471;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=556;e.Amacron=667;e.rcaron=333;e.ccedilla=500;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=643;e.Umacron=722;e.uring=556;e.threesuperior=333;e.Ograve=778;e.Agrave=667;e.Abreve=667;e.multiply=584;e.uacute=556;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=500;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=260;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=333;e.omacron=556;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=222;e.tcaron=317;e.eogonek=556;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=556;e.zacute=500;e.iogonek=222;e.Oacute=778;e.oacute=556;e.amacron=556;e.sacute=500;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=333;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=556;e.Eogonek=667;e.dcroat=556;e.threequarters=834;e.Scedilla=667;e.lcaron=299;e.Kcommaaccent=667;e.Lacute=556;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=556;e.onehalf=834;e.lessequal=549;e.ocircumflex=556;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=556;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=556;e.Ccaron=722;e.ugrave=556;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=556;e.Rcommaaccent=722;e.Lcommaaccent=556;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=500;e.minus=584;e.Icircumflex=278;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=584;e.odieresis=556;e.udieresis=556;e.notequal=549;e.gcommaaccent=556;e.eth=556;e.zcaron=500;e.ncommaaccent=556;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-Bold"]=(0,r.getLookupTableFactory)((function(e){e.space=278;e.exclam=333;e.quotedbl=474;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=722;e.quoteright=278;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=333;e.semicolon=333;e.less=584;e.equal=584;e.greater=584;e.question=611;e.at=975;e.A=722;e.B=722;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=556;e.K=722;e.L=611;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=584;e.underscore=556;e.quoteleft=278;e.a=556;e.b=611;e.c=556;e.d=611;e.e=556;e.f=333;e.g=611;e.h=611;e.i=278;e.j=278;e.k=556;e.l=278;e.m=889;e.n=611;e.o=611;e.p=611;e.q=611;e.r=389;e.s=556;e.t=333;e.u=611;e.v=556;e.w=778;e.x=556;e.y=556;e.z=500;e.braceleft=389;e.bar=280;e.braceright=389;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=238;e.quotedblleft=500;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=611;e.fl=611;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=556;e.bullet=350;e.quotesinglbase=278;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=611;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=278;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=611;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=722;e.aacute=556;e.Ucircumflex=722;e.yacute=556;e.scommaaccent=556;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=611;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=556;e.aring=556;e.Ncommaaccent=722;e.lacute=278;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=556;e.scedilla=556;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=611;e.acircumflex=556;e.Amacron=722;e.rcaron=389;e.ccedilla=556;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=743;e.Umacron=722;e.uring=611;e.threesuperior=333;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=584;e.uacute=611;e.Tcaron=611;e.partialdiff=494;e.ydieresis=556;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=556;e.nacute=611;e.umacron=611;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=280;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=611;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=389;e.eogonek=556;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=556;e.zacute=500;e.iogonek=278;e.Oacute=778;e.oacute=611;e.amacron=556;e.sacute=556;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=611;e.twosuperior=333;e.Odieresis=778;e.mu=611;e.igrave=278;e.ohungarumlaut=611;e.Eogonek=667;e.dcroat=611;e.threequarters=834;e.Scedilla=667;e.lcaron=400;e.Kcommaaccent=722;e.Lacute=611;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=611;e.onehalf=834;e.lessequal=549;e.ocircumflex=611;e.ntilde=611;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=611;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=611;e.Ccaron=722;e.ugrave=611;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=611;e.Rcommaaccent=722;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=556;e.minus=584;e.Icircumflex=278;e.ncaron=611;e.tcommaaccent=333;e.logicalnot=584;e.odieresis=611;e.udieresis=611;e.notequal=549;e.gcommaaccent=611;e.eth=611;e.zcaron=500;e.ncommaaccent=611;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-BoldOblique"]=(0,r.getLookupTableFactory)((function(e){e.space=278;e.exclam=333;e.quotedbl=474;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=722;e.quoteright=278;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=333;e.semicolon=333;e.less=584;e.equal=584;e.greater=584;e.question=611;e.at=975;e.A=722;e.B=722;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=556;e.K=722;e.L=611;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=584;e.underscore=556;e.quoteleft=278;e.a=556;e.b=611;e.c=556;e.d=611;e.e=556;e.f=333;e.g=611;e.h=611;e.i=278;e.j=278;e.k=556;e.l=278;e.m=889;e.n=611;e.o=611;e.p=611;e.q=611;e.r=389;e.s=556;e.t=333;e.u=611;e.v=556;e.w=778;e.x=556;e.y=556;e.z=500;e.braceleft=389;e.bar=280;e.braceright=389;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=238;e.quotedblleft=500;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=611;e.fl=611;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=556;e.bullet=350;e.quotesinglbase=278;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=611;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=278;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=611;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=722;e.aacute=556;e.Ucircumflex=722;e.yacute=556;e.scommaaccent=556;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=611;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=556;e.aring=556;e.Ncommaaccent=722;e.lacute=278;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=556;e.scedilla=556;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=611;e.acircumflex=556;e.Amacron=722;e.rcaron=389;e.ccedilla=556;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=743;e.Umacron=722;e.uring=611;e.threesuperior=333;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=584;e.uacute=611;e.Tcaron=611;e.partialdiff=494;e.ydieresis=556;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=556;e.nacute=611;e.umacron=611;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=280;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=611;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=389;e.eogonek=556;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=556;e.zacute=500;e.iogonek=278;e.Oacute=778;e.oacute=611;e.amacron=556;e.sacute=556;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=611;e.twosuperior=333;e.Odieresis=778;e.mu=611;e.igrave=278;e.ohungarumlaut=611;e.Eogonek=667;e.dcroat=611;e.threequarters=834;e.Scedilla=667;e.lcaron=400;e.Kcommaaccent=722;e.Lacute=611;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=611;e.onehalf=834;e.lessequal=549;e.ocircumflex=611;e.ntilde=611;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=611;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=611;e.Ccaron=722;e.ugrave=611;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=611;e.Rcommaaccent=722;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=556;e.minus=584;e.Icircumflex=278;e.ncaron=611;e.tcommaaccent=333;e.logicalnot=584;e.odieresis=611;e.udieresis=611;e.notequal=549;e.gcommaaccent=611;e.eth=611;e.zcaron=500;e.ncommaaccent=611;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-Oblique"]=(0,r.getLookupTableFactory)((function(e){e.space=278;e.exclam=278;e.quotedbl=355;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=667;e.quoteright=222;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=278;e.semicolon=278;e.less=584;e.equal=584;e.greater=584;e.question=556;e.at=1015;e.A=667;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=500;e.K=667;e.L=556;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=278;e.backslash=278;e.bracketright=278;e.asciicircum=469;e.underscore=556;e.quoteleft=222;e.a=556;e.b=556;e.c=500;e.d=556;e.e=556;e.f=278;e.g=556;e.h=556;e.i=222;e.j=222;e.k=500;e.l=222;e.m=833;e.n=556;e.o=556;e.p=556;e.q=556;e.r=333;e.s=500;e.t=278;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=500;e.braceleft=334;e.bar=260;e.braceright=334;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=191;e.quotedblleft=333;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=537;e.bullet=350;e.quotesinglbase=222;e.quotedblbase=333;e.quotedblright=333;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=556;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=222;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=556;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=667;e.aacute=556;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=500;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=500;e.aring=556;e.Ncommaaccent=722;e.lacute=222;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=500;e.scedilla=500;e.iacute=278;e.lozenge=471;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=556;e.Amacron=667;e.rcaron=333;e.ccedilla=500;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=643;e.Umacron=722;e.uring=556;e.threesuperior=333;e.Ograve=778;e.Agrave=667;e.Abreve=667;e.multiply=584;e.uacute=556;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=500;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=260;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=333;e.omacron=556;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=222;e.tcaron=317;e.eogonek=556;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=556;e.zacute=500;e.iogonek=222;e.Oacute=778;e.oacute=556;e.amacron=556;e.sacute=500;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=333;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=556;e.Eogonek=667;e.dcroat=556;e.threequarters=834;e.Scedilla=667;e.lcaron=299;e.Kcommaaccent=667;e.Lacute=556;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=556;e.onehalf=834;e.lessequal=549;e.ocircumflex=556;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=556;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=556;e.Ccaron=722;e.ugrave=556;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=556;e.Rcommaaccent=722;e.Lcommaaccent=556;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=500;e.minus=584;e.Icircumflex=278;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=584;e.odieresis=556;e.udieresis=556;e.notequal=549;e.gcommaaccent=556;e.eth=556;e.zcaron=500;e.ncommaaccent=556;e.onesuperior=333;e.imacron=278;e.Euro=556}));e.Symbol=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=333;e.universal=713;e.numbersign=500;e.existential=549;e.percent=833;e.ampersand=778;e.suchthat=439;e.parenleft=333;e.parenright=333;e.asteriskmath=500;e.plus=549;e.comma=250;e.minus=549;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=278;e.semicolon=278;e.less=549;e.equal=549;e.greater=549;e.question=444;e.congruent=549;e.Alpha=722;e.Beta=667;e.Chi=722;e.Delta=612;e.Epsilon=611;e.Phi=763;e.Gamma=603;e.Eta=722;e.Iota=333;e.theta1=631;e.Kappa=722;e.Lambda=686;e.Mu=889;e.Nu=722;e.Omicron=722;e.Pi=768;e.Theta=741;e.Rho=556;e.Sigma=592;e.Tau=611;e.Upsilon=690;e.sigma1=439;e.Omega=768;e.Xi=645;e.Psi=795;e.Zeta=611;e.bracketleft=333;e.therefore=863;e.bracketright=333;e.perpendicular=658;e.underscore=500;e.radicalex=500;e.alpha=631;e.beta=549;e.chi=549;e.delta=494;e.epsilon=439;e.phi=521;e.gamma=411;e.eta=603;e.iota=329;e.phi1=603;e.kappa=549;e.lambda=549;e.mu=576;e.nu=521;e.omicron=549;e.pi=549;e.theta=521;e.rho=549;e.sigma=603;e.tau=439;e.upsilon=576;e.omega1=713;e.omega=686;e.xi=493;e.psi=686;e.zeta=494;e.braceleft=480;e.bar=200;e.braceright=480;e.similar=549;e.Euro=750;e.Upsilon1=620;e.minute=247;e.lessequal=549;e.fraction=167;e.infinity=713;e.florin=500;e.club=753;e.diamond=753;e.heart=753;e.spade=753;e.arrowboth=1042;e.arrowleft=987;e.arrowup=603;e.arrowright=987;e.arrowdown=603;e.degree=400;e.plusminus=549;e.second=411;e.greaterequal=549;e.multiply=549;e.proportional=713;e.partialdiff=494;e.bullet=460;e.divide=549;e.notequal=549;e.equivalence=549;e.approxequal=549;e.ellipsis=1e3;e.arrowvertex=603;e.arrowhorizex=1e3;e.carriagereturn=658;e.aleph=823;e.Ifraktur=686;e.Rfraktur=795;e.weierstrass=987;e.circlemultiply=768;e.circleplus=768;e.emptyset=823;e.intersection=768;e.union=768;e.propersuperset=713;e.reflexsuperset=713;e.notsubset=713;e.propersubset=713;e.reflexsubset=713;e.element=713;e.notelement=713;e.angle=768;e.gradient=713;e.registerserif=790;e.copyrightserif=790;e.trademarkserif=890;e.product=823;e.radical=549;e.dotmath=250;e.logicalnot=713;e.logicaland=603;e.logicalor=603;e.arrowdblboth=1042;e.arrowdblleft=987;e.arrowdblup=603;e.arrowdblright=987;e.arrowdbldown=603;e.lozenge=494;e.angleleft=329;e.registersans=790;e.copyrightsans=790;e.trademarksans=786;e.summation=713;e.parenlefttp=384;e.parenleftex=384;e.parenleftbt=384;e.bracketlefttp=384;e.bracketleftex=384;e.bracketleftbt=384;e.bracelefttp=494;e.braceleftmid=494;e.braceleftbt=494;e.braceex=494;e.angleright=329;e.integral=274;e.integraltp=686;e.integralex=686;e.integralbt=686;e.parenrighttp=384;e.parenrightex=384;e.parenrightbt=384;e.bracketrighttp=384;e.bracketrightex=384;e.bracketrightbt=384;e.bracerighttp=494;e.bracerightmid=494;e.bracerightbt=494;e.apple=790}));e["Times-Roman"]=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=333;e.quotedbl=408;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=564;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=278;e.semicolon=278;e.less=564;e.equal=564;e.greater=564;e.question=444;e.at=921;e.A=722;e.B=667;e.C=667;e.D=722;e.E=611;e.F=556;e.G=722;e.H=722;e.I=333;e.J=389;e.K=722;e.L=611;e.M=889;e.N=722;e.O=722;e.P=556;e.Q=722;e.R=667;e.S=556;e.T=611;e.U=722;e.V=722;e.W=944;e.X=722;e.Y=722;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=469;e.underscore=500;e.quoteleft=333;e.a=444;e.b=500;e.c=444;e.d=500;e.e=444;e.f=333;e.g=500;e.h=500;e.i=278;e.j=278;e.k=500;e.l=278;e.m=778;e.n=500;e.o=500;e.p=500;e.q=500;e.r=333;e.s=389;e.t=278;e.u=500;e.v=500;e.w=722;e.x=500;e.y=500;e.z=444;e.braceleft=480;e.bar=200;e.braceright=480;e.asciitilde=541;e.exclamdown=333;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=180;e.quotedblleft=444;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=453;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=444;e.quotedblright=444;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=444;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=889;e.ordfeminine=276;e.Lslash=611;e.Oslash=722;e.OE=889;e.ordmasculine=310;e.ae=667;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=500;e.Idieresis=333;e.eacute=444;e.abreve=444;e.uhungarumlaut=500;e.ecaron=444;e.Ydieresis=722;e.divide=564;e.Yacute=722;e.Acircumflex=722;e.aacute=444;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=444;e.Uacute=722;e.uogonek=500;e.Edieresis=611;e.Dcroat=722;e.commaaccent=250;e.copyright=760;e.Emacron=611;e.ccaron=444;e.aring=444;e.Ncommaaccent=722;e.lacute=278;e.agrave=444;e.Tcommaaccent=611;e.Cacute=667;e.atilde=444;e.Edotaccent=611;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=471;e.Rcaron=667;e.Gcommaaccent=722;e.ucircumflex=500;e.acircumflex=444;e.Amacron=722;e.rcaron=333;e.ccedilla=444;e.Zdotaccent=611;e.Thorn=556;e.Omacron=722;e.Racute=667;e.Sacute=556;e.dcaron=588;e.Umacron=722;e.uring=500;e.threesuperior=300;e.Ograve=722;e.Agrave=722;e.Abreve=722;e.multiply=564;e.uacute=500;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=611;e.adieresis=444;e.edieresis=444;e.cacute=444;e.nacute=500;e.umacron=500;e.Ncaron=722;e.Iacute=333;e.plusminus=564;e.brokenbar=200;e.registered=760;e.Gbreve=722;e.Idotaccent=333;e.summation=600;e.Egrave=611;e.racute=333;e.omacron=500;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=326;e.eogonek=444;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=444;e.zacute=444;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=444;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=500;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=611;e.dcroat=500;e.threequarters=750;e.Scedilla=556;e.lcaron=344;e.Kcommaaccent=722;e.Lacute=611;e.trademark=980;e.edotaccent=444;e.Igrave=333;e.Imacron=333;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=500;e.Uhungarumlaut=722;e.Eacute=611;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=500;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=667;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=722;e.zdotaccent=444;e.Ecaron=611;e.Iogonek=333;e.kcommaaccent=500;e.minus=564;e.Icircumflex=333;e.ncaron=500;e.tcommaaccent=278;e.logicalnot=564;e.odieresis=500;e.udieresis=500;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=444;e.ncommaaccent=500;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-Bold"]=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=333;e.quotedbl=555;e.numbersign=500;e.dollar=500;e.percent=1e3;e.ampersand=833;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=570;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=570;e.equal=570;e.greater=570;e.question=500;e.at=930;e.A=722;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=778;e.I=389;e.J=500;e.K=778;e.L=667;e.M=944;e.N=722;e.O=778;e.P=611;e.Q=778;e.R=722;e.S=556;e.T=667;e.U=722;e.V=722;e.W=1e3;e.X=722;e.Y=722;e.Z=667;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=581;e.underscore=500;e.quoteleft=333;e.a=500;e.b=556;e.c=444;e.d=556;e.e=444;e.f=333;e.g=500;e.h=556;e.i=278;e.j=333;e.k=556;e.l=278;e.m=833;e.n=556;e.o=500;e.p=556;e.q=556;e.r=444;e.s=389;e.t=333;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=444;e.braceleft=394;e.bar=220;e.braceright=394;e.asciitilde=520;e.exclamdown=333;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=278;e.quotedblleft=500;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=540;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=300;e.Lslash=667;e.Oslash=778;e.OE=1e3;e.ordmasculine=330;e.ae=722;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=556;e.Idieresis=389;e.eacute=444;e.abreve=500;e.uhungarumlaut=556;e.ecaron=444;e.Ydieresis=722;e.divide=570;e.Yacute=722;e.Acircumflex=722;e.aacute=500;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=747;e.Emacron=667;e.ccaron=444;e.aring=500;e.Ncommaaccent=722;e.lacute=278;e.agrave=500;e.Tcommaaccent=667;e.Cacute=722;e.atilde=500;e.Edotaccent=667;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=500;e.Amacron=722;e.rcaron=444;e.ccedilla=444;e.Zdotaccent=667;e.Thorn=611;e.Omacron=778;e.Racute=722;e.Sacute=556;e.dcaron=672;e.Umacron=722;e.uring=556;e.threesuperior=300;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=570;e.uacute=556;e.Tcaron=667;e.partialdiff=494;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=389;e.plusminus=570;e.brokenbar=220;e.registered=747;e.Gbreve=778;e.Idotaccent=389;e.summation=600;e.Egrave=667;e.racute=444;e.omacron=500;e.Zacute=667;e.Zcaron=667;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=416;e.eogonek=444;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=444;e.zacute=444;e.iogonek=278;e.Oacute=778;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=300;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=667;e.dcroat=556;e.threequarters=750;e.Scedilla=556;e.lcaron=394;e.Kcommaaccent=778;e.Lacute=667;e.trademark=1e3;e.edotaccent=444;e.Igrave=389;e.Imacron=389;e.Lcaron=667;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=778;e.degree=400;e.ograve=500;e.Ccaron=722;e.ugrave=556;e.radical=549;e.Dcaron=722;e.rcommaaccent=444;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=722;e.Lcommaaccent=667;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=444;e.Ecaron=667;e.Iogonek=389;e.kcommaaccent=556;e.minus=570;e.Icircumflex=389;e.ncaron=556;e.tcommaaccent=333;e.logicalnot=570;e.odieresis=500;e.udieresis=556;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=444;e.ncommaaccent=556;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-BoldItalic"]=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=389;e.quotedbl=555;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=570;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=570;e.equal=570;e.greater=570;e.question=500;e.at=832;e.A=667;e.B=667;e.C=667;e.D=722;e.E=667;e.F=667;e.G=722;e.H=778;e.I=389;e.J=500;e.K=667;e.L=611;e.M=889;e.N=722;e.O=722;e.P=611;e.Q=722;e.R=667;e.S=556;e.T=611;e.U=722;e.V=667;e.W=889;e.X=667;e.Y=611;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=570;e.underscore=500;e.quoteleft=333;e.a=500;e.b=500;e.c=444;e.d=500;e.e=444;e.f=333;e.g=500;e.h=556;e.i=278;e.j=278;e.k=500;e.l=278;e.m=778;e.n=556;e.o=500;e.p=500;e.q=500;e.r=389;e.s=389;e.t=278;e.u=556;e.v=444;e.w=667;e.x=500;e.y=444;e.z=389;e.braceleft=348;e.bar=220;e.braceright=348;e.asciitilde=570;e.exclamdown=389;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=278;e.quotedblleft=500;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=500;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=944;e.ordfeminine=266;e.Lslash=611;e.Oslash=722;e.OE=944;e.ordmasculine=300;e.ae=722;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=500;e.Idieresis=389;e.eacute=444;e.abreve=500;e.uhungarumlaut=556;e.ecaron=444;e.Ydieresis=611;e.divide=570;e.Yacute=611;e.Acircumflex=667;e.aacute=500;e.Ucircumflex=722;e.yacute=444;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=747;e.Emacron=667;e.ccaron=444;e.aring=500;e.Ncommaaccent=722;e.lacute=278;e.agrave=500;e.Tcommaaccent=611;e.Cacute=667;e.atilde=500;e.Edotaccent=667;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=494;e.Rcaron=667;e.Gcommaaccent=722;e.ucircumflex=556;e.acircumflex=500;e.Amacron=667;e.rcaron=389;e.ccedilla=444;e.Zdotaccent=611;e.Thorn=611;e.Omacron=722;e.Racute=667;e.Sacute=556;e.dcaron=608;e.Umacron=722;e.uring=556;e.threesuperior=300;e.Ograve=722;e.Agrave=667;e.Abreve=667;e.multiply=570;e.uacute=556;e.Tcaron=611;e.partialdiff=494;e.ydieresis=444;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=389;e.plusminus=570;e.brokenbar=220;e.registered=747;e.Gbreve=722;e.Idotaccent=389;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=500;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=366;e.eogonek=444;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=444;e.zacute=389;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=576;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=667;e.dcroat=500;e.threequarters=750;e.Scedilla=556;e.lcaron=382;e.Kcommaaccent=667;e.Lacute=611;e.trademark=1e3;e.edotaccent=444;e.Igrave=389;e.Imacron=389;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=556;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=667;e.Lcommaaccent=611;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=722;e.zdotaccent=389;e.Ecaron=667;e.Iogonek=389;e.kcommaaccent=500;e.minus=606;e.Icircumflex=389;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=606;e.odieresis=500;e.udieresis=556;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=389;e.ncommaaccent=556;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-Italic"]=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=333;e.quotedbl=420;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=675;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=675;e.equal=675;e.greater=675;e.question=500;e.at=920;e.A=611;e.B=611;e.C=667;e.D=722;e.E=611;e.F=611;e.G=722;e.H=722;e.I=333;e.J=444;e.K=667;e.L=556;e.M=833;e.N=667;e.O=722;e.P=611;e.Q=722;e.R=611;e.S=500;e.T=556;e.U=722;e.V=611;e.W=833;e.X=611;e.Y=556;e.Z=556;e.bracketleft=389;e.backslash=278;e.bracketright=389;e.asciicircum=422;e.underscore=500;e.quoteleft=333;e.a=500;e.b=500;e.c=444;e.d=500;e.e=444;e.f=278;e.g=500;e.h=500;e.i=278;e.j=278;e.k=444;e.l=278;e.m=722;e.n=500;e.o=500;e.p=500;e.q=500;e.r=389;e.s=389;e.t=278;e.u=500;e.v=444;e.w=667;e.x=444;e.y=444;e.z=389;e.braceleft=400;e.bar=275;e.braceright=400;e.asciitilde=541;e.exclamdown=389;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=214;e.quotedblleft=556;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=523;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=556;e.quotedblright=556;e.guillemotright=500;e.ellipsis=889;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=889;e.AE=889;e.ordfeminine=276;e.Lslash=556;e.Oslash=722;e.OE=944;e.ordmasculine=310;e.ae=667;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=667;e.germandbls=500;e.Idieresis=333;e.eacute=444;e.abreve=500;e.uhungarumlaut=500;e.ecaron=444;e.Ydieresis=556;e.divide=675;e.Yacute=556;e.Acircumflex=611;e.aacute=500;e.Ucircumflex=722;e.yacute=444;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=500;e.Edieresis=611;e.Dcroat=722;e.commaaccent=250;e.copyright=760;e.Emacron=611;e.ccaron=444;e.aring=500;e.Ncommaaccent=667;e.lacute=278;e.agrave=500;e.Tcommaaccent=556;e.Cacute=667;e.atilde=500;e.Edotaccent=611;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=471;e.Rcaron=611;e.Gcommaaccent=722;e.ucircumflex=500;e.acircumflex=500;e.Amacron=611;e.rcaron=389;e.ccedilla=444;e.Zdotaccent=556;e.Thorn=611;e.Omacron=722;e.Racute=611;e.Sacute=500;e.dcaron=544;e.Umacron=722;e.uring=500;e.threesuperior=300;e.Ograve=722;e.Agrave=611;e.Abreve=611;e.multiply=675;e.uacute=500;e.Tcaron=556;e.partialdiff=476;e.ydieresis=444;e.Nacute=667;e.icircumflex=278;e.Ecircumflex=611;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=500;e.umacron=500;e.Ncaron=667;e.Iacute=333;e.plusminus=675;e.brokenbar=275;e.registered=760;e.Gbreve=722;e.Idotaccent=333;e.summation=600;e.Egrave=611;e.racute=389;e.omacron=500;e.Zacute=556;e.Zcaron=556;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=300;e.eogonek=444;e.Uogonek=722;e.Aacute=611;e.Adieresis=611;e.egrave=444;e.zacute=389;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=500;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=611;e.dcroat=500;e.threequarters=750;e.Scedilla=500;e.lcaron=300;e.Kcommaaccent=667;e.Lacute=556;e.trademark=980;e.edotaccent=444;e.Igrave=333;e.Imacron=333;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=500;e.Uhungarumlaut=722;e.Eacute=611;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=500;e.Scommaaccent=500;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=500;e.radical=453;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=667;e.otilde=500;e.Rcommaaccent=611;e.Lcommaaccent=556;e.Atilde=611;e.Aogonek=611;e.Aring=611;e.Otilde=722;e.zdotaccent=389;e.Ecaron=611;e.Iogonek=333;e.kcommaaccent=444;e.minus=675;e.Icircumflex=333;e.ncaron=500;e.tcommaaccent=278;e.logicalnot=675;e.odieresis=500;e.udieresis=500;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=389;e.ncommaaccent=500;e.onesuperior=300;e.imacron=278;e.Euro=500}));e.ZapfDingbats=(0,r.getLookupTableFactory)((function(e){e.space=278;e.a1=974;e.a2=961;e.a202=974;e.a3=980;e.a4=719;e.a5=789;e.a119=790;e.a118=791;e.a117=690;e.a11=960;e.a12=939;e.a13=549;e.a14=855;e.a15=911;e.a16=933;e.a105=911;e.a17=945;e.a18=974;e.a19=755;e.a20=846;e.a21=762;e.a22=761;e.a23=571;e.a24=677;e.a25=763;e.a26=760;e.a27=759;e.a28=754;e.a6=494;e.a7=552;e.a8=537;e.a9=577;e.a10=692;e.a29=786;e.a30=788;e.a31=788;e.a32=790;e.a33=793;e.a34=794;e.a35=816;e.a36=823;e.a37=789;e.a38=841;e.a39=823;e.a40=833;e.a41=816;e.a42=831;e.a43=923;e.a44=744;e.a45=723;e.a46=749;e.a47=790;e.a48=792;e.a49=695;e.a50=776;e.a51=768;e.a52=792;e.a53=759;e.a54=707;e.a55=708;e.a56=682;e.a57=701;e.a58=826;e.a59=815;e.a60=789;e.a61=789;e.a62=707;e.a63=687;e.a64=696;e.a65=689;e.a66=786;e.a67=787;e.a68=713;e.a69=791;e.a70=785;e.a71=791;e.a72=873;e.a73=761;e.a74=762;e.a203=762;e.a75=759;e.a204=759;e.a76=892;e.a77=892;e.a78=788;e.a79=784;e.a81=438;e.a82=138;e.a83=277;e.a84=415;e.a97=392;e.a98=392;e.a99=668;e.a100=668;e.a89=390;e.a90=390;e.a93=317;e.a94=317;e.a91=276;e.a92=276;e.a205=509;e.a85=509;e.a206=410;e.a86=410;e.a87=234;e.a88=234;e.a95=334;e.a96=334;e.a101=732;e.a102=544;e.a103=544;e.a104=910;e.a106=667;e.a107=760;e.a108=760;e.a112=776;e.a111=595;e.a110=694;e.a109=626;e.a120=788;e.a121=788;e.a122=788;e.a123=788;e.a124=788;e.a125=788;e.a126=788;e.a127=788;e.a128=788;e.a129=788;e.a130=788;e.a131=788;e.a132=788;e.a133=788;e.a134=788;e.a135=788;e.a136=788;e.a137=788;e.a138=788;e.a139=788;e.a140=788;e.a141=788;e.a142=788;e.a143=788;e.a144=788;e.a145=788;e.a146=788;e.a147=788;e.a148=788;e.a149=788;e.a150=788;e.a151=788;e.a152=788;e.a153=788;e.a154=788;e.a155=788;e.a156=788;e.a157=788;e.a158=788;e.a159=788;e.a160=894;e.a161=838;e.a163=1016;e.a164=458;e.a196=748;e.a165=924;e.a192=748;e.a166=918;e.a167=927;e.a168=928;e.a169=928;e.a170=834;e.a171=873;e.a172=828;e.a173=924;e.a162=924;e.a174=917;e.a175=930;e.a176=931;e.a177=463;e.a178=883;e.a179=836;e.a193=836;e.a180=867;e.a199=867;e.a181=696;e.a200=696;e.a182=874;e.a201=874;e.a183=760;e.a184=946;e.a197=771;e.a185=865;e.a194=771;e.a198=888;e.a186=967;e.a195=888;e.a187=831;e.a188=873;e.a189=927;e.a190=970;e.a191=918}))}));t.getMetrics=i},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.isPDFFunction=function(e){var t;if("object"!=typeof e)return!1;if((0,i.isDict)(e))t=e;else{if(!(0,i.isStream)(e))return!1;t=e.dict}return t.has("FunctionType")};t.PostScriptCompiler=t.PostScriptEvaluator=t.PDFFunctionFactory=void 0;var r=a(2),i=a(4),n=a(40);t.PDFFunctionFactory=class{constructor({xref:e,isEvalSupported:t=!0}){this.xref=e;this.isEvalSupported=!1!==t}create(e){return o.parse({xref:this.xref,isEvalSupported:this.isEvalSupported,fn:e})}createFromArray(e){return o.parseArray({xref:this.xref,isEvalSupported:this.isEvalSupported,fnObj:e})}};function s(e){if(!Array.isArray(e))return null;const t=e.length;for(let a=0;a<t;a++)if("number"!=typeof e[a]){const a=new Array(t);for(let r=0;r<t;r++)a[r]=+e[r];return a}return e}var o={getSampleArray(e,t,a,r){var i,n,s=1;for(i=0,n=e.length;i<n;i++)s*=e[i];s*=t;var o=new Array(s),c=0,l=0,h=1/(2**a-1),u=r.getBytes((s*a+7)/8),d=0;for(i=0;i<s;i++){for(;c<a;){l<<=8;l|=u[d++];c+=8}c-=a;o[i]=(l>>c)*h;l&=(1<<c)-1}return o},getIR({xref:e,isEvalSupported:t,fn:a}){var i=a.dict;i||(i=a);var n=[this.constructSampled,null,this.constructInterpolated,this.constructStiched,this.constructPostScript][i.get("FunctionType")];if(!n)throw new r.FormatError("Unknown type of function");return n.call(this,{xref:e,isEvalSupported:t,fn:a,dict:i})},fromIR({xref:e,isEvalSupported:t,IR:a}){switch(a[0]){case 0:return this.constructSampledFromIR({xref:e,isEvalSupported:t,IR:a});case 2:return this.constructInterpolatedFromIR({xref:e,isEvalSupported:t,IR:a});case 3:return this.constructStichedFromIR({xref:e,isEvalSupported:t,IR:a});default:return this.constructPostScriptFromIR({xref:e,isEvalSupported:t,IR:a})}},parse({xref:e,isEvalSupported:t,fn:a}){const r=this.getIR({xref:e,isEvalSupported:t,fn:a});return this.fromIR({xref:e,isEvalSupported:t,IR:r})},parseArray({xref:e,isEvalSupported:t,fnObj:a}){if(!Array.isArray(a))return this.parse({xref:e,isEvalSupported:t,fn:a});for(var r=[],i=0,n=a.length;i<n;i++)r.push(this.parse({xref:e,isEvalSupported:t,fn:e.fetchIfRef(a[i])}));return function(e,t,a,i){for(var n=0,s=r.length;n<s;n++)r[n](e,t,a,i+n)}},constructSampled({xref:e,isEvalSupported:t,fn:a,dict:i}){function n(e){for(var t=e.length,a=[],r=0,i=0;i<t;i+=2){a[r]=[e[i],e[i+1]];++r}return a}var o=s(i.getArray("Domain")),c=s(i.getArray("Range"));if(!o||!c)throw new r.FormatError("No domain or range");var l=o.length/2,h=c.length/2;o=n(o);c=n(c);var u=s(i.getArray("Size")),d=i.get("BitsPerSample"),f=i.get("Order")||1;1!==f&&(0,r.info)("No support for cubic spline interpolation: "+f);var g=s(i.getArray("Encode"));if(g)g=n(g);else{g=[];for(var m=0;m<l;++m)g.push([0,u[m]-1])}var p=s(i.getArray("Decode"));return[0,l,o,g,p=p?n(p):c,this.getSampleArray(u,h,d,a),u,h,2**d-1,c]},constructSampledFromIR({xref:e,isEvalSupported:t,IR:a}){function r(e,t,a,r,i){return r+(i-r)/(a-t)*(e-t)}return function(e,t,i,n){var s,o,c=a[1],l=a[2],h=a[3],u=a[4],d=a[5],f=a[6],g=a[7],m=a[9],p=1<<c,b=new Float64Array(p),y=new Uint32Array(p);for(o=0;o<p;o++)b[o]=1;var v=g,w=1;for(s=0;s<c;++s){var k=l[s][0],S=l[s][1],C=r(Math.min(Math.max(e[t+s],k),S),k,S,h[s][0],h[s][1]),x=f[s],A=(C=Math.min(Math.max(C,0),x-1))<x-1?Math.floor(C):C-1,I=A+1-C,F=C-A,T=A*v,E=T+v;for(o=0;o<p;o++)if(o&w){b[o]*=F;y[o]+=E}else{b[o]*=I;y[o]+=T}v*=x;w<<=1}for(o=0;o<g;++o){var O=0;for(s=0;s<p;s++)O+=d[y[s]+o]*b[s];O=r(O,0,1,u[o][0],u[o][1]);i[n+o]=Math.min(Math.max(O,m[o][0]),m[o][1])}}},constructInterpolated({xref:e,isEvalSupported:t,fn:a,dict:r}){for(var i=s(r.getArray("C0"))||[0],n=s(r.getArray("C1"))||[1],o=r.get("N"),c=i.length,l=[],h=0;h<c;++h)l.push(n[h]-i[h]);return[2,i,l,o]},constructInterpolatedFromIR({xref:e,isEvalSupported:t,IR:a}){var r=a[1],i=a[2],n=a[3],s=i.length;return function(e,t,a,o){for(var c=1===n?e[t]:e[t]**n,l=0;l<s;++l)a[o+l]=r[l]+c*i[l]}},constructStiched({xref:e,isEvalSupported:t,fn:a,dict:i}){var n=s(i.getArray("Domain"));if(!n)throw new r.FormatError("No domain");if(1!=n.length/2)throw new r.FormatError("Bad domain for stiched function");for(var o=i.get("Functions"),c=[],l=0,h=o.length;l<h;++l)c.push(this.parse({xref:e,isEvalSupported:t,fn:e.fetchIfRef(o[l])}));return[3,n,s(i.getArray("Bounds")),s(i.getArray("Encode")),c]},constructStichedFromIR({xref:e,isEvalSupported:t,IR:a}){var r=a[1],i=a[2],n=a[3],s=a[4],o=new Float32Array(1);return function(e,t,a,c){for(var l=function(e,t,a){e>a?e=a:e<t&&(e=t);return e}(e[t],r[0],r[1]),h=0,u=i.length;h<u&&!(l<i[h]);++h);var d=r[0];h>0&&(d=i[h-1]);var f=r[1];h<i.length&&(f=i[h]);var g=n[2*h],m=n[2*h+1];o[0]=d===f?g:g+(l-d)*(m-g)/(f-d);s[h](o,0,a,c)}},constructPostScript({xref:e,isEvalSupported:t,fn:a,dict:i}){var o=s(i.getArray("Domain")),c=s(i.getArray("Range"));if(!o)throw new r.FormatError("No domain.");if(!c)throw new r.FormatError("No range.");var l=new n.PostScriptLexer(a);return[4,o,c,new n.PostScriptParser(l).parse()]},constructPostScriptFromIR({xref:e,isEvalSupported:t,IR:a}){var i=a[1],n=a[2],s=a[3];if(t&&r.IsEvalSupportedCached.value){const e=(new h).compile(s,i,n);if(e)return new Function("src","srcOffset","dest","destOffset",e)}(0,r.info)("Unable to compile PS function");var o=n.length>>1,c=i.length>>1,u=new l(s),d=Object.create(null),f=8192,g=new Float32Array(c);return function(e,t,a,r){var i,s,l="",h=g;for(i=0;i<c;i++){s=e[t+i];h[i]=s;l+=s+"_"}var m=d[l];if(void 0===m){var p=new Float32Array(o),b=u.execute(h),y=b.length-o;for(i=0;i<o;i++){s=b[y+i];var v=n[2*i];(s<v||s>(v=n[2*i+1]))&&(s=v);p[i]=s}if(f>0){f--;d[l]=p}a.set(p,r)}else a.set(m,r)}}};var c=function(){function e(e){this.stack=e?Array.prototype.slice.call(e,0):[]}e.prototype={push:function(e){if(this.stack.length>=100)throw new Error("PostScript function stack overflow.");this.stack.push(e)},pop:function(){if(this.stack.length<=0)throw new Error("PostScript function stack underflow.");return this.stack.pop()},copy:function(e){if(this.stack.length+e>=100)throw new Error("PostScript function stack overflow.");for(var t=this.stack,a=t.length-e,r=e-1;r>=0;r--,a++)t.push(t[a])},index:function(e){this.push(this.stack[this.stack.length-e-1])},roll:function(e,t){var a,r,i,n=this.stack,s=n.length-e,o=n.length-1,c=s+(t-Math.floor(t/e)*e);for(a=s,r=o;a<r;a++,r--){i=n[a];n[a]=n[r];n[r]=i}for(a=s,r=c-1;a<r;a++,r--){i=n[a];n[a]=n[r];n[r]=i}for(a=c,r=o;a<r;a++,r--){i=n[a];n[a]=n[r];n[r]=i}}};return e}(),l=function(){function e(e){this.operators=e}e.prototype={execute:function(e){for(var t,a,i,n=new c(e),s=0,o=this.operators,l=o.length;s<l;)if("number"!=typeof(t=o[s++]))switch(t){case"jz":i=n.pop();(a=n.pop())||(s=i);break;case"j":s=a=n.pop();break;case"abs":a=n.pop();n.push(Math.abs(a));break;case"add":i=n.pop();a=n.pop();n.push(a+i);break;case"and":i=n.pop();a=n.pop();(0,r.isBool)(a)&&(0,r.isBool)(i)?n.push(a&&i):n.push(a&i);break;case"atan":a=n.pop();n.push(Math.atan(a));break;case"bitshift":i=n.pop();(a=n.pop())>0?n.push(a<<i):n.push(a>>i);break;case"ceiling":a=n.pop();n.push(Math.ceil(a));break;case"copy":a=n.pop();n.copy(a);break;case"cos":a=n.pop();n.push(Math.cos(a));break;case"cvi":a=0|n.pop();n.push(a);break;case"cvr":break;case"div":i=n.pop();a=n.pop();n.push(a/i);break;case"dup":n.copy(1);break;case"eq":i=n.pop();a=n.pop();n.push(a===i);break;case"exch":n.roll(2,1);break;case"exp":i=n.pop();a=n.pop();n.push(a**i);break;case"false":n.push(!1);break;case"floor":a=n.pop();n.push(Math.floor(a));break;case"ge":i=n.pop();a=n.pop();n.push(a>=i);break;case"gt":i=n.pop();a=n.pop();n.push(a>i);break;case"idiv":i=n.pop();a=n.pop();n.push(a/i|0);break;case"index":a=n.pop();n.index(a);break;case"le":i=n.pop();a=n.pop();n.push(a<=i);break;case"ln":a=n.pop();n.push(Math.log(a));break;case"log":a=n.pop();n.push(Math.log(a)/Math.LN10);break;case"lt":i=n.pop();a=n.pop();n.push(a<i);break;case"mod":i=n.pop();a=n.pop();n.push(a%i);break;case"mul":i=n.pop();a=n.pop();n.push(a*i);break;case"ne":i=n.pop();a=n.pop();n.push(a!==i);break;case"neg":a=n.pop();n.push(-a);break;case"not":a=n.pop();(0,r.isBool)(a)?n.push(!a):n.push(~a);break;case"or":i=n.pop();a=n.pop();(0,r.isBool)(a)&&(0,r.isBool)(i)?n.push(a||i):n.push(a|i);break;case"pop":n.pop();break;case"roll":i=n.pop();a=n.pop();n.roll(a,i);break;case"round":a=n.pop();n.push(Math.round(a));break;case"sin":a=n.pop();n.push(Math.sin(a));break;case"sqrt":a=n.pop();n.push(Math.sqrt(a));break;case"sub":i=n.pop();a=n.pop();n.push(a-i);break;case"true":n.push(!0);break;case"truncate":a=(a=n.pop())<0?Math.ceil(a):Math.floor(a);n.push(a);break;case"xor":i=n.pop();a=n.pop();(0,r.isBool)(a)&&(0,r.isBool)(i)?n.push(a!==i):n.push(a^i);break;default:throw new r.FormatError(`Unknown operator ${t}`)}else n.push(t);return n.stack}};return e}();t.PostScriptEvaluator=l;var h=function(){function e(e){this.type=e}e.prototype.visit=function(e){(0,r.unreachable)("abstract method")};function t(t,a,r){e.call(this,"args");this.index=t;this.min=a;this.max=r}t.prototype=Object.create(e.prototype);t.prototype.visit=function(e){e.visitArgument(this)};function a(t){e.call(this,"literal");this.number=t;this.min=t;this.max=t}a.prototype=Object.create(e.prototype);a.prototype.visit=function(e){e.visitLiteral(this)};function i(t,a,r,i,n){e.call(this,"binary");this.op=t;this.arg1=a;this.arg2=r;this.min=i;this.max=n}i.prototype=Object.create(e.prototype);i.prototype.visit=function(e){e.visitBinaryOperation(this)};function n(t,a){e.call(this,"max");this.arg=t;this.min=t.min;this.max=a}n.prototype=Object.create(e.prototype);n.prototype.visit=function(e){e.visitMin(this)};function s(t,a,r){e.call(this,"var");this.index=t;this.min=a;this.max=r}s.prototype=Object.create(e.prototype);s.prototype.visit=function(e){e.visitVariable(this)};function o(t,a){e.call(this,"definition");this.variable=t;this.arg=a}o.prototype=Object.create(e.prototype);o.prototype.visit=function(e){e.visitVariableDefinition(this)};function c(){this.parts=[]}c.prototype={visitArgument(e){this.parts.push("Math.max(",e.min,", Math.min(",e.max,", src[srcOffset + ",e.index,"]))")},visitVariable(e){this.parts.push("v",e.index)},visitLiteral(e){this.parts.push(e.number)},visitBinaryOperation(e){this.parts.push("(");e.arg1.visit(this);this.parts.push(" ",e.op," ");e.arg2.visit(this);this.parts.push(")")},visitVariableDefinition(e){this.parts.push("var ");e.variable.visit(this);this.parts.push(" = ");e.arg.visit(this);this.parts.push(";")},visitMin(e){this.parts.push("Math.min(");e.arg.visit(this);this.parts.push(", ",e.max,")")},toString(){return this.parts.join("")}};function l(e,t){return"literal"===t.type&&0===t.number?e:"literal"===e.type&&0===e.number?t:"literal"===t.type&&"literal"===e.type?new a(e.number+t.number):new i("+",e,t,e.min+t.min,e.max+t.max)}function h(e,t){if("literal"===t.type){if(0===t.number)return new a(0);if(1===t.number)return e;if("literal"===e.type)return new a(e.number*t.number)}if("literal"===e.type){if(0===e.number)return new a(0);if(1===e.number)return t}return new i("*",e,t,Math.min(e.min*t.min,e.min*t.max,e.max*t.min,e.max*t.max),Math.max(e.min*t.min,e.min*t.max,e.max*t.min,e.max*t.max))}function u(e,t){if("literal"===t.type){if(0===t.number)return e;if("literal"===e.type)return new a(e.number-t.number)}return"binary"===t.type&&"-"===t.op&&"literal"===e.type&&1===e.number&&"literal"===t.arg1.type&&1===t.arg1.number?t.arg2:new i("-",e,t,e.min-t.max,e.max-t.min)}function d(e,t){return e.min>=t?new a(t):e.max<=t?e:new n(e,t)}function f(){}f.prototype={compile:function(e,r,i){var n,f,g,m,p,b,y,v,w,k,S=[],C=[],x=r.length>>1,A=i.length>>1,I=0;for(n=0;n<x;n++)S.push(new t(n,r[2*n],r[2*n+1]));for(n=0,f=e.length;n<f;n++)if("number"!=typeof(k=e[n]))switch(k){case"add":if(S.length<2)return null;b=S.pop();p=S.pop();S.push(l(p,b));break;case"cvr":if(S.length<1)return null;break;case"mul":if(S.length<2)return null;b=S.pop();p=S.pop();S.push(h(p,b));break;case"sub":if(S.length<2)return null;b=S.pop();p=S.pop();S.push(u(p,b));break;case"exch":if(S.length<2)return null;y=S.pop();v=S.pop();S.push(y,v);break;case"pop":if(S.length<1)return null;S.pop();break;case"index":if(S.length<1)return null;if("literal"!==(p=S.pop()).type)return null;if((g=p.number)<0||!Number.isInteger(g)||S.length<g)return null;if("literal"===(y=S[S.length-g-1]).type||"var"===y.type){S.push(y);break}w=new s(I++,y.min,y.max);S[S.length-g-1]=w;S.push(w);C.push(new o(w,y));break;case"dup":if(S.length<1)return null;if("number"==typeof e[n+1]&&"gt"===e[n+2]&&e[n+3]===n+7&&"jz"===e[n+4]&&"pop"===e[n+5]&&e[n+6]===e[n+1]){p=S.pop();S.push(d(p,e[n+1]));n+=6;break}if("literal"===(y=S[S.length-1]).type||"var"===y.type){S.push(y);break}w=new s(I++,y.min,y.max);S[S.length-1]=w;S.push(w);C.push(new o(w,y));break;case"roll":if(S.length<2)return null;b=S.pop();p=S.pop();if("literal"!==b.type||"literal"!==p.type)return null;m=b.number;if((g=p.number)<=0||!Number.isInteger(g)||!Number.isInteger(m)||S.length<g)return null;if(0===(m=(m%g+g)%g))break;Array.prototype.push.apply(S,S.splice(S.length-g,g-m));break;default:return null}else S.push(new a(k));if(S.length!==A)return null;var F=[];C.forEach((function(e){var t=new c;e.visit(t);F.push(t.toString())}));S.forEach((function(e,t){var a=new c;e.visit(a);var r=i[2*t],n=i[2*t+1],s=[a.toString()];if(r>e.min){s.unshift("Math.max(",r,", ");s.push(")")}if(n<e.max){s.unshift("Math.min(",n,", ");s.push(")")}s.unshift("dest[destOffset + ",t,"] = ");s.push(";");F.push(s.join(""))}));return F.join("\n")}};return f}();t.PostScriptCompiler=h},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PostScriptParser=t.PostScriptLexer=void 0;var r=a(2),i=a(4),n=a(7);t.PostScriptParser=class{constructor(e){this.lexer=e;this.operators=[];this.token=null;this.prev=null}nextToken(){this.prev=this.token;this.token=this.lexer.getToken()}accept(e){if(this.token.type===e){this.nextToken();return!0}return!1}expect(e){if(this.accept(e))return!0;throw new r.FormatError(`Unexpected symbol: found ${this.token.type} expected ${e}.`)}parse(){this.nextToken();this.expect(s.LBRACE);this.parseBlock();this.expect(s.RBRACE);return this.operators}parseBlock(){for(;;)if(this.accept(s.NUMBER))this.operators.push(this.prev.value);else if(this.accept(s.OPERATOR))this.operators.push(this.prev.value);else{if(!this.accept(s.LBRACE))return;this.parseCondition()}}parseCondition(){const e=this.operators.length;this.operators.push(null,null);this.parseBlock();this.expect(s.RBRACE);if(this.accept(s.IF)){this.operators[e]=this.operators.length;this.operators[e+1]="jz"}else{if(!this.accept(s.LBRACE))throw new r.FormatError("PS Function: error parsing conditional.");{const t=this.operators.length;this.operators.push(null,null);const a=this.operators.length;this.parseBlock();this.expect(s.RBRACE);this.expect(s.IFELSE);this.operators[t]=this.operators.length;this.operators[t+1]="j";this.operators[e]=a;this.operators[e+1]="jz"}}}};const s={LBRACE:0,RBRACE:1,NUMBER:2,OPERATOR:3,IF:4,IFELSE:5},o=function(){const e=Object.create(null);class t{constructor(e,t){this.type=e;this.value=t}static getOperator(a){const r=e[a];return r||(e[a]=new t(s.OPERATOR,a))}static get LBRACE(){return(0,r.shadow)(this,"LBRACE",new t(s.LBRACE,"{"))}static get RBRACE(){return(0,r.shadow)(this,"RBRACE",new t(s.RBRACE,"}"))}static get IF(){return(0,r.shadow)(this,"IF",new t(s.IF,"IF"))}static get IFELSE(){return(0,r.shadow)(this,"IFELSE",new t(s.IFELSE,"IFELSE"))}}return t}();t.PostScriptLexer=class{constructor(e){this.stream=e;this.nextChar();this.strBuf=[]}nextChar(){return this.currentChar=this.stream.getByte()}getToken(){let e=!1,t=this.currentChar;for(;;){if(t<0)return i.EOF;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(!(0,n.isWhiteSpace)(t))break;t=this.nextChar()}switch(0|t){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return new o(s.NUMBER,this.getNumber());case 123:this.nextChar();return o.LBRACE;case 125:this.nextChar();return o.RBRACE}const a=this.strBuf;a.length=0;a[0]=String.fromCharCode(t);for(;(t=this.nextChar())>=0&&(t>=65&&t<=90||t>=97&&t<=122);)a.push(String.fromCharCode(t));const r=a.join("");switch(r.toLowerCase()){case"if":return o.IF;case"ifelse":return o.IFELSE;default:return o.getOperator(r)}}getNumber(){let e=this.currentChar;const t=this.strBuf;t.length=0;t[0]=String.fromCharCode(e);for(;(e=this.nextChar())>=0&&(e>=48&&e<=57||45===e||46===e);)t.push(String.fromCharCode(e));const a=parseFloat(t.join(""));if(isNaN(a))throw new r.FormatError(`Invalid floating point number: ${a}`);return a}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.MurmurHash3_64=void 0;var r=a(2);t.MurmurHash3_64=class{constructor(e){this.h1=e?4294967295&e:3285377520;this.h2=e?4294967295&e:3285377520}update(e){let t,a;if((0,r.isString)(e)){t=new Uint8Array(2*e.length);a=0;for(let r=0,i=e.length;r<i;r++){const i=e.charCodeAt(r);if(i<=255)t[a++]=i;else{t[a++]=i>>>8;t[a++]=255&i}}}else{if(!(0,r.isArrayBuffer)(e))throw new Error("Wrong data format in MurmurHash3_64_update. Input must be a string or array.");t=e;a=t.byteLength}const i=a>>2,n=a-4*i,s=new Uint32Array(t.buffer,0,i);let o=0,c=0,l=this.h1,h=this.h2;const u=3432918353,d=461845907;for(let e=0;e<i;e++)if(1&e){o=s[e];o=o*u&4294901760|11601*o&65535;o=o<<15|o>>>17;o=o*d&4294901760|13715*o&65535;l^=o;l=l<<13|l>>>19;l=5*l+3864292196}else{c=s[e];c=c*u&4294901760|11601*c&65535;c=c<<15|c>>>17;c=c*d&4294901760|13715*c&65535;h^=c;h=h<<13|h>>>19;h=5*h+3864292196}o=0;switch(n){case 3:o^=t[4*i+2]<<16;case 2:o^=t[4*i+1]<<8;case 1:o^=t[4*i];o=o*u&4294901760|11601*o&65535;o=o<<15|o>>>17;o=o*d&4294901760|13715*o&65535;1&i?l^=o:h^=o}this.h1=l;this.h2=h}hexdigest(){let e=this.h1,t=this.h2;e^=t>>>1;e=3981806797*e&4294901760|36045*e&65535;t=4283543511*t&4294901760|(2950163797*(t<<16|e>>>16)&4294901760)>>>16;e^=t>>>1;e=444984403*e&4294901760|60499*e&65535;t=3301882366*t&4294901760|(3120437893*(t<<16|e>>>16)&4294901760)>>>16;e^=t>>>1;const a=(e>>>0).toString(16),r=(t>>>0).toString(16);return a.padStart(8,"0")+r.padStart(8,"0")}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.NativeImageDecoder=void 0;var r=a(22),i=a(17),n=a(11);class s{constructor({xref:e,resources:t,handler:a,forceDataSchema:r=!1,pdfFunctionFactory:i}){this.xref=e;this.resources=t;this.handler=a;this.forceDataSchema=r;this.pdfFunctionFactory=i}canDecode(e){return e instanceof i.JpegStream&&s.isDecodable(e,this.xref,this.resources,this.pdfFunctionFactory)&&e.maybeValidDimensions}decode(e){const t=e.dict;let a=t.get("ColorSpace","CS");a=r.ColorSpace.parse(a,this.xref,this.resources,this.pdfFunctionFactory);return this.handler.sendWithPromise("JpegDecode",[e.getIR(this.forceDataSchema),a.numComps]).then((function({data:e,width:a,height:r}){return new n.Stream(e,0,e.length,t)}))}static isSupported(e,t,a,i){const n=e.dict;if(n.has("DecodeParms")||n.has("DP"))return!1;const s=r.ColorSpace.parse(n.get("ColorSpace","CS"),t,a,i);return("DeviceGray"===s.name||"DeviceRGB"===s.name)&&s.isDefaultDecode(n.getArray("Decode","D"))}static isDecodable(e,t,a,i){const n=e.dict;if(n.has("DecodeParms")||n.has("DP"))return!1;const s=r.ColorSpace.parse(n.get("ColorSpace","CS"),t,a,i),o=n.get("BitsPerComponent","BPC")||1;return(1===s.numComps||3===s.numComps)&&s.isDefaultDecode(n.getArray("Decode","D"),o)}}t.NativeImageDecoder=s},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PDFImage=void 0;var r=a(2),i=a(4),n=a(22),s=a(11),o=a(17),c=a(20),l=function(){function e(e,t){return t&&t.canDecode(e)?t.decode(e).catch(t=>{(0,r.warn)("Native image decoding failed -- trying to recover: "+(t&&t.message));return e}):Promise.resolve(e)}function t(e,t,a,r){(e=t+e*a)<0?e=0:e>r&&(e=r);return e}function a(e,t,a,r,i,n){var s=i*n;let o;o=t<=8?new Uint8Array(s):t<=16?new Uint16Array(s):new Uint32Array(s);var c,l,h,u,d=a/i,f=r/n,g=0,m=new Uint16Array(i),p=a;for(c=0;c<i;c++)m[c]=Math.floor(c*d);for(c=0;c<n;c++){h=Math.floor(c*f)*p;for(l=0;l<i;l++){u=h+m[l];o[g++]=e[u]}}return o}function l({xref:e,res:t,image:a,isInline:s=!1,smask:o=null,mask:h=null,isMask:u=!1,pdfFunctionFactory:d}){this.image=a;var f=a.dict;const g=f.get("Filter");if((0,i.isName)(g))switch(g.name){case"JPXDecode":var m=new c.JpxImage;m.parseImageProperties(a.stream);a.stream.reset();a.width=m.width;a.height=m.height;a.bitsPerComponent=m.bitsPerComponent;a.numComps=m.componentsCount;break;case"JBIG2Decode":a.bitsPerComponent=1;a.numComps=1}let p=f.get("Width","W"),b=f.get("Height","H");if(Number.isInteger(a.width)&&a.width>0&&Number.isInteger(a.height)&&a.height>0&&(a.width!==p||a.height!==b)){(0,r.warn)("PDFImage - using the Width/Height of the image data, rather than the image dictionary.");p=a.width;b=a.height}if(p<1||b<1)throw new r.FormatError(`Invalid image width: ${p} or height: ${b}`);this.width=p;this.height=b;this.interpolate=f.get("Interpolate","I")||!1;this.imageMask=f.get("ImageMask","IM")||!1;this.matte=f.get("Matte")||!1;var y=a.bitsPerComponent;if(!y&&!(y=f.get("BitsPerComponent","BPC"))){if(!this.imageMask)throw new r.FormatError(`Bits per component missing in image: ${this.imageMask}`);y=1}this.bpc=y;if(!this.imageMask){var v=f.get("ColorSpace","CS");if(!v){(0,r.info)("JPX images (which do not require color spaces)");switch(a.numComps){case 1:v=i.Name.get("DeviceGray");break;case 3:v=i.Name.get("DeviceRGB");break;case 4:v=i.Name.get("DeviceCMYK");break;default:throw new Error(`JPX images with ${a.numComps} `+"color components not supported.")}}const o=s?t:null;this.colorSpace=n.ColorSpace.parse(v,e,o,d);this.numComps=this.colorSpace.numComps}this.decode=f.getArray("Decode","D");this.needsDecode=!1;if(this.decode&&(this.colorSpace&&!this.colorSpace.isDefaultDecode(this.decode,y)||u&&!n.ColorSpace.isDefaultDecode(this.decode,1))){this.needsDecode=!0;var w=(1<<y)-1;this.decodeCoefficients=[];this.decodeAddends=[];const e=this.colorSpace&&"Indexed"===this.colorSpace.name;for(var k=0,S=0;k<this.decode.length;k+=2,++S){var C=this.decode[k],x=this.decode[k+1];this.decodeCoefficients[S]=e?(x-C)/w:x-C;this.decodeAddends[S]=e?C:w*C}}if(o)this.smask=new l({xref:e,res:t,image:o,isInline:s,pdfFunctionFactory:d});else if(h)if((0,i.isStream)(h)){h.dict.get("ImageMask","IM")?this.mask=new l({xref:e,res:t,image:h,isInline:s,isMask:!0,pdfFunctionFactory:d}):(0,r.warn)("Ignoring /Mask in image without /ImageMask.")}else this.mask=h}l.buildImage=function({handler:t,xref:a,res:n,image:s,isInline:o=!1,nativeDecoder:c=null,pdfFunctionFactory:h}){var u,d,f=e(s,c),g=s.dict.get("SMask"),m=s.dict.get("Mask");if(g){u=e(g,c);d=Promise.resolve(null)}else{u=Promise.resolve(null);if(m)if((0,i.isStream)(m))d=e(m,c);else if(Array.isArray(m))d=Promise.resolve(m);else{(0,r.warn)("Unsupported mask format.");d=Promise.resolve(null)}else d=Promise.resolve(null)}return Promise.all([f,u,d]).then((function([e,t,r]){return new l({xref:a,res:n,image:e,isInline:o,smask:t,mask:r,pdfFunctionFactory:h})}))};l.createMask=function({imgArray:e,width:t,height:a,imageIsFromDecodeStream:r,inverseDecode:i}){var n,s,o=(t+7>>3)*a,c=e.byteLength;if(!r||i&&!(o===c))if(i){(n=new Uint8ClampedArray(o)).set(e);for(s=c;s<o;s++)n[s]=255}else(n=new Uint8ClampedArray(c)).set(e);else n=e;if(i)for(s=0;s<c;s++)n[s]^=255;return{data:n,width:t,height:a}};l.prototype={get drawWidth(){return Math.max(this.width,this.smask&&this.smask.width||0,this.mask&&this.mask.width||0)},get drawHeight(){return Math.max(this.height,this.smask&&this.smask.height||0,this.mask&&this.mask.height||0)},decodeBuffer(e){var a,r,i=this.bpc,n=this.numComps,s=this.decodeAddends,o=this.decodeCoefficients,c=(1<<i)-1;if(1!==i){var l=0;for(a=0,r=this.width*this.height;a<r;a++)for(var h=0;h<n;h++){e[l]=t(e[l],s[h],o[h],c);l++}}else for(a=0,r=e.length;a<r;a++)e[a]=+!e[a]},getComponents(e){var t=this.bpc;if(8===t)return e;var a=this.width,r=this.height,i=this.numComps,n=a*r*i,s=0;let o;o=t<=8?new Uint8Array(n):t<=16?new Uint16Array(n):new Uint32Array(n);var c,l,h=a*i,u=(1<<t)-1,d=0;if(1===t)for(var f,g,m,p=0;p<r;p++){g=d+(-8&h);m=d+h;for(;d<g;){l=e[s++];o[d]=l>>7&1;o[d+1]=l>>6&1;o[d+2]=l>>5&1;o[d+3]=l>>4&1;o[d+4]=l>>3&1;o[d+5]=l>>2&1;o[d+6]=l>>1&1;o[d+7]=1&l;d+=8}if(d<m){l=e[s++];f=128;for(;d<m;){o[d++]=+!!(l&f);f>>=1}}}else{var b=0;l=0;for(d=0,c=n;d<c;++d){if(d%h==0){l=0;b=0}for(;b<t;){l=l<<8|e[s++];b+=8}var y=b-t;let a=l>>y;a<0?a=0:a>u&&(a=u);o[d]=a;l&=(1<<y)-1;b=y}}return o},fillOpacity(e,t,i,n,s){var o,c,h,u,d,f,g=this.smask,m=this.mask;if(g){c=g.width;h=g.height;o=new Uint8ClampedArray(c*h);g.fillGrayBuffer(o);c===t&&h===i||(o=a(o,g.bpc,c,h,t,i))}else if(m)if(m instanceof l){c=m.width;h=m.height;o=new Uint8ClampedArray(c*h);m.numComps=1;m.fillGrayBuffer(o);for(u=0,d=c*h;u<d;++u)o[u]=255-o[u];c===t&&h===i||(o=a(o,m.bpc,c,h,t,i))}else{if(!Array.isArray(m))throw new r.FormatError("Unknown mask format.");o=new Uint8ClampedArray(t*i);var p=this.numComps;for(u=0,d=t*i;u<d;++u){var b=0,y=u*p;for(f=0;f<p;++f){var v=s[y+f],w=2*f;if(v<m[w]||v>m[w+1]){b=255;break}}o[u]=b}}if(o)for(u=0,f=3,d=t*n;u<d;++u,f+=4)e[f]=o[u];else for(u=0,f=3,d=t*n;u<d;++u,f+=4)e[f]=255},undoPreblend(e,t,a){var r=this.smask&&this.smask.matte;if(r)for(var i=this.colorSpace.getRgb(r,0),n=i[0],s=i[1],o=i[2],c=t*a*4,l=0;l<c;l+=4){var h=e[l+3];if(0!==h){var u=255/h;e[l]=(e[l]-n)*u+n;e[l+1]=(e[l+1]-s)*u+s;e[l+2]=(e[l+2]-o)*u+o}else{e[l]=255;e[l+1]=255;e[l+2]=255}}},createImageData(e=!1){var t,a=this.drawWidth,i=this.drawHeight,n={width:a,height:i,kind:0,data:null},c=this.numComps,l=this.width,h=this.height,u=this.bpc,d=l*c*u+7>>3;if(!e){var f;"DeviceGray"===this.colorSpace.name&&1===u?f=r.ImageKind.GRAYSCALE_1BPP:"DeviceRGB"!==this.colorSpace.name||8!==u||this.needsDecode||(f=r.ImageKind.RGB_24BPP);if(f&&!this.smask&&!this.mask&&a===l&&i===h){n.kind=f;t=this.getImageBytes(h*d);if(this.image instanceof s.DecodeStream)n.data=t;else{var g=new Uint8ClampedArray(t.length);g.set(t);n.data=g}if(this.needsDecode){(0,r.assert)(f===r.ImageKind.GRAYSCALE_1BPP,"PDFImage.createImageData: The image must be grayscale.");for(var m=n.data,p=0,b=m.length;p<b;p++)m[p]^=255}return n}if(this.image instanceof o.JpegStream&&!this.smask&&!this.mask){let e=h*d;switch(this.colorSpace.name){case"DeviceGray":e*=3;case"DeviceRGB":case"DeviceCMYK":n.kind=r.ImageKind.RGB_24BPP;n.data=this.getImageBytes(e,a,i,!0);return n}}}var y,v,w=0|(t=this.getImageBytes(h*d)).length/d*i/h,k=this.getComponents(t);if(e||this.smask||this.mask){n.kind=r.ImageKind.RGBA_32BPP;n.data=new Uint8ClampedArray(a*i*4);y=1;v=!0;this.fillOpacity(n.data,a,i,w,k)}else{n.kind=r.ImageKind.RGB_24BPP;n.data=new Uint8ClampedArray(a*i*3);y=0;v=!1}this.needsDecode&&this.decodeBuffer(k);this.colorSpace.fillRgb(n.data,l,h,a,i,w,u,k,y);v&&this.undoPreblend(n.data,a,w);return n},fillGrayBuffer(e){var t=this.numComps;if(1!==t)throw new r.FormatError(`Reading gray scale from a color image: ${t}`);var a,i,n=this.width,s=this.height,o=this.bpc,c=n*t*o+7>>3,l=this.getImageBytes(s*c),h=this.getComponents(l);if(1!==o){this.needsDecode&&this.decodeBuffer(h);i=n*s;var u=255/((1<<o)-1);for(a=0;a<i;++a)e[a]=u*h[a]}else{i=n*s;if(this.needsDecode)for(a=0;a<i;++a)e[a]=h[a]-1&255;else for(a=0;a<i;++a)e[a]=255&-h[a]}},getImageBytes(e,t,a,r=!1){this.image.reset();this.image.drawWidth=t||this.width;this.image.drawHeight=a||this.height;this.image.forceRGB=!!r;return this.image.getBytes(e,!0)}};return l}();t.PDFImage=l},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.isNodeJS=void 0;const r="object"==typeof process&&process+""=="[object process]"&&!process.versions.nw&&!process.versions.electron;t.isNodeJS=r},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.MessageHandler=void 0;var r=a(2);const i=1,n=2,s=1,o=2,c=3,l=4,h=5,u=6,d=7,f=8;function g(e){if("object"!=typeof e||null===e)return e;switch(e.name){case"AbortException":return new r.AbortException(e.message);case"MissingPDFException":return new r.MissingPDFException(e.message);case"UnexpectedResponseException":return new r.UnexpectedResponseException(e.message,e.status);case"UnknownErrorException":return new r.UnknownErrorException(e.message,e.details);default:return new r.UnknownErrorException(e.message,e.toString())}}t.MessageHandler=class{constructor(e,t,a){this.sourceName=e;this.targetName=t;this.comObj=a;this.callbackId=1;this.streamId=1;this.postMessageTransfers=!0;this.streamSinks=Object.create(null);this.streamControllers=Object.create(null);this.callbackCapabilities=Object.create(null);this.actionHandler=Object.create(null);this._onComObjOnMessage=e=>{const t=e.data;if(t.targetName!==this.sourceName)return;if(t.stream){this._processStreamMessage(t);return}if(t.callback){const e=t.callbackId,a=this.callbackCapabilities[e];if(!a)throw new Error(`Cannot resolve callback ${e}`);delete this.callbackCapabilities[e];if(t.callback===i)a.resolve(t.data);else{if(t.callback!==n)throw new Error("Unexpected callback case");a.reject(g(t.reason))}return}const r=this.actionHandler[t.action];if(!r)throw new Error(`Unknown action from worker: ${t.action}`);if(t.callbackId){const e=this.sourceName,s=t.sourceName;new Promise((function(e){e(r(t.data))})).then((function(r){a.postMessage({sourceName:e,targetName:s,callback:i,callbackId:t.callbackId,data:r})}),(function(r){a.postMessage({sourceName:e,targetName:s,callback:n,callbackId:t.callbackId,reason:g(r)})}))}else t.streamId?this._createStreamSink(t):r(t.data)};a.addEventListener("message",this._onComObjOnMessage)}on(e,t){const a=this.actionHandler;if(a[e])throw new Error(`There is already an actionName called "${e}"`);a[e]=t}send(e,t,a){this._postMessage({sourceName:this.sourceName,targetName:this.targetName,action:e,data:t},a)}sendWithPromise(e,t,a){const i=this.callbackId++,n=(0,r.createPromiseCapability)();this.callbackCapabilities[i]=n;try{this._postMessage({sourceName:this.sourceName,targetName:this.targetName,action:e,callbackId:i,data:t},a)}catch(e){n.reject(e)}return n.promise}sendWithStream(e,t,a,i){const n=this.streamId++,o=this.sourceName,c=this.targetName,l=this.comObj;return new ReadableStream({start:a=>{const s=(0,r.createPromiseCapability)();this.streamControllers[n]={controller:a,startCall:s,pullCall:null,cancelCall:null,isClosed:!1};this._postMessage({sourceName:o,targetName:c,action:e,streamId:n,data:t,desiredSize:a.desiredSize},i);return s.promise},pull:e=>{const t=(0,r.createPromiseCapability)();this.streamControllers[n].pullCall=t;l.postMessage({sourceName:o,targetName:c,stream:u,streamId:n,desiredSize:e.desiredSize});return t.promise},cancel:e=>{(0,r.assert)(e instanceof Error,"cancel must have a valid reason");const t=(0,r.createPromiseCapability)();this.streamControllers[n].cancelCall=t;this.streamControllers[n].isClosed=!0;l.postMessage({sourceName:o,targetName:c,stream:s,streamId:n,reason:g(e)});return t.promise}},a)}_createStreamSink(e){const t=this,a=this.actionHandler[e.action],i=e.streamId,n=this.sourceName,s=e.sourceName,o=this.comObj,u={enqueue(e,a=1,o){if(this.isCancelled)return;const c=this.desiredSize;this.desiredSize-=a;if(c>0&&this.desiredSize<=0){this.sinkCapability=(0,r.createPromiseCapability)();this.ready=this.sinkCapability.promise}t._postMessage({sourceName:n,targetName:s,stream:l,streamId:i,chunk:e},o)},close(){if(!this.isCancelled){this.isCancelled=!0;o.postMessage({sourceName:n,targetName:s,stream:c,streamId:i});delete t.streamSinks[i]}},error(e){(0,r.assert)(e instanceof Error,"error must have a valid reason");if(!this.isCancelled){this.isCancelled=!0;o.postMessage({sourceName:n,targetName:s,stream:h,streamId:i,reason:g(e)})}},sinkCapability:(0,r.createPromiseCapability)(),onPull:null,onCancel:null,isCancelled:!1,desiredSize:e.desiredSize,ready:null};u.sinkCapability.resolve();u.ready=u.sinkCapability.promise;this.streamSinks[i]=u;new Promise((function(t){t(a(e.data,u))})).then((function(){o.postMessage({sourceName:n,targetName:s,stream:f,streamId:i,success:!0})}),(function(e){o.postMessage({sourceName:n,targetName:s,stream:f,streamId:i,reason:g(e)})}))}_processStreamMessage(e){const t=e.streamId,a=this.sourceName,i=e.sourceName,n=this.comObj;switch(e.stream){case f:e.success?this.streamControllers[t].startCall.resolve():this.streamControllers[t].startCall.reject(g(e.reason));break;case d:e.success?this.streamControllers[t].pullCall.resolve():this.streamControllers[t].pullCall.reject(g(e.reason));break;case u:if(!this.streamSinks[t]){n.postMessage({sourceName:a,targetName:i,stream:d,streamId:t,success:!0});break}this.streamSinks[t].desiredSize<=0&&e.desiredSize>0&&this.streamSinks[t].sinkCapability.resolve();this.streamSinks[t].desiredSize=e.desiredSize;const{onPull:m}=this.streamSinks[e.streamId];new Promise((function(e){e(m&&m())})).then((function(){n.postMessage({sourceName:a,targetName:i,stream:d,streamId:t,success:!0})}),(function(e){n.postMessage({sourceName:a,targetName:i,stream:d,streamId:t,reason:g(e)})}));break;case l:(0,r.assert)(this.streamControllers[t],"enqueue should have stream controller");if(this.streamControllers[t].isClosed)break;this.streamControllers[t].controller.enqueue(e.chunk);break;case c:(0,r.assert)(this.streamControllers[t],"close should have stream controller");if(this.streamControllers[t].isClosed)break;this.streamControllers[t].isClosed=!0;this.streamControllers[t].controller.close();this._deleteStreamController(t);break;case h:(0,r.assert)(this.streamControllers[t],"error should have stream controller");this.streamControllers[t].controller.error(g(e.reason));this._deleteStreamController(t);break;case o:e.success?this.streamControllers[t].cancelCall.resolve():this.streamControllers[t].cancelCall.reject(g(e.reason));this._deleteStreamController(t);break;case s:if(!this.streamSinks[t])break;const{onCancel:p}=this.streamSinks[e.streamId];new Promise((function(t){t(p&&p(g(e.reason)))})).then((function(){n.postMessage({sourceName:a,targetName:i,stream:o,streamId:t,success:!0})}),(function(e){n.postMessage({sourceName:a,targetName:i,stream:o,streamId:t,reason:g(e)})}));this.streamSinks[t].sinkCapability.reject(g(e.reason));this.streamSinks[t].isCancelled=!0;delete this.streamSinks[t];break;default:throw new Error("Unexpected stream case")}}async _deleteStreamController(e){await Promise.allSettled([this.streamControllers[e].startCall,this.streamControllers[e].pullCall,this.streamControllers[e].cancelCall].map((function(e){return e&&e.promise})));delete this.streamControllers[e]}_postMessage(e,t){t&&this.postMessageTransfers?this.comObj.postMessage(e,t):this.comObj.postMessage(e)}destroy(){this.comObj.removeEventListener("message",this._onComObjOnMessage)}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PDFWorkerStream=void 0;var r=a(2);t.PDFWorkerStream=class{constructor(e){this._msgHandler=e;this._contentLength=null;this._fullRequestReader=null;this._rangeRequestReaders=[]}getFullReader(){(0,r.assert)(!this._fullRequestReader);this._fullRequestReader=new i(this._msgHandler);return this._fullRequestReader}getRangeReader(e,t){const a=new n(e,t,this._msgHandler);this._rangeRequestReaders.push(a);return a}cancelAllRequests(e){this._fullRequestReader&&this._fullRequestReader.cancel(e);this._rangeRequestReaders.slice(0).forEach((function(t){t.cancel(e)}))}};class i{constructor(e){this._msgHandler=e;this.onProgress=null;this._contentLength=null;this._isRangeSupported=!1;this._isStreamingSupported=!1;const t=this._msgHandler.sendWithStream("GetReader");this._reader=t.getReader();this._headersReady=this._msgHandler.sendWithPromise("ReaderHeadersReady").then(e=>{this._isStreamingSupported=e.isStreamingSupported;this._isRangeSupported=e.isRangeSupported;this._contentLength=e.contentLength})}get headersReady(){return this._headersReady}get contentLength(){return this._contentLength}get isStreamingSupported(){return this._isStreamingSupported}get isRangeSupported(){return this._isRangeSupported}async read(){const{value:e,done:t}=await this._reader.read();return t?{value:void 0,done:!0}:{value:e.buffer,done:!1}}cancel(e){this._reader.cancel(e)}}class n{constructor(e,t,a){this._msgHandler=a;this.onProgress=null;const r=this._msgHandler.sendWithStream("GetRangeReader",{begin:e,end:t});this._reader=r.getReader()}get isStreamingSupported(){return!1}async read(){const{value:e,done:t}=await this._reader.read();return t?{value:void 0,done:!0}:{value:e.buffer,done:!1}}cancel(e){this._reader.cancel(e)}}}])})); \ No newline at end of file
diff --git a/deploy/loader.js b/deploy/loader.js
index 0be421e14..b3508c5c6 100644
--- a/deploy/loader.js
+++ b/deploy/loader.js
@@ -1,8 +1,8 @@
function getCookie(cname) {
- var name = cname + "=";
- var ca = document.cookie.split(';');
- for (var i = 0; i < ca.length; i++) {
- var c = ca[i];
+ let name = cname + '=';
+ let ca = document.cookie.split(';');
+ for (let i = 0; i < ca.length; i++) {
+ let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
@@ -11,4 +11,4 @@ function getCookie(cname) {
}
}
return 3000;
-} \ No newline at end of file
+}
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 000000000..b35601abd
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,6 @@
+import pluginJs from '@eslint/js';
+import pluginReactConfig from 'eslint-plugin-react/configs/recommended.js';
+import globals from 'globals';
+import tseslint from 'typescript-eslint';
+
+export default [{ languageOptions: { globals: { ...globals.browser, ...globals.node } } }, pluginJs.configs.recommended, ...tseslint.configs.recommended, pluginReactConfig];
diff --git a/package-lock.json b/package-lock.json
index f372d011c..c918759e6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,8 +28,9 @@
"@internationalized/date": "^3.5.0",
"@mui/icons-material": "^5.14.19",
"@mui/material": "^5.14.19",
- "@octokit/core": "^5.0.2",
+ "@octokit/core": "^6.0.1",
"@react-google-maps/api": "^2.19.2",
+ "@react-spring/web": "^9.7.3",
"@turf/turf": "^6.5.0",
"@types/bezier-js": "^4.1.3",
"@types/brotli": "^1.3.4",
@@ -42,20 +43,24 @@
"@types/find-in-files": "^0.5.3",
"@types/fluent-ffmpeg": "^2.1.24",
"@types/formidable": "3.4.5",
+ "@types/geojson": "^7946.0.14",
"@types/google-maps": "^3.2.6",
- "@types/mapbox-gl": "^2.7.19",
+ "@types/mapbox-gl": "^3.1.0",
"@types/pdf-parse": "^1.1.4",
"@types/reveal": "^4.2.0",
"@types/supercluster": "^7.1.3",
- "@types/web": "^0.0.138",
+ "@types/web": "^0.0.143",
+ "@types/webpack-hot-middleware": "^2.25.9",
+ "@typescript-eslint/parser": "^7.8.0",
"@webscopeio/react-textarea-autocomplete": "^4.9.2",
"adm-zip": "^0.5.10",
- "archiver": "^6.0.1",
+ "archiver": "^7.0.1",
"async": "^3.2.5",
"axios": "^1.6.2",
"babel": "^6.23.0",
"babel-loader": "^9.1.3",
"bcrypt-nodejs": "0.0.3",
+ "better-react-mathjax": "^2.0.3",
"bezier-curve": "^1.0.0",
"bezier-js": "^6.1.4",
"bingmaps-react": "^1.2.10",
@@ -78,18 +83,23 @@
"cookie-session": "^2.0.0",
"core-js": "^3.33.3",
"cors": "^2.8.5",
- "css-loader": "^6.8.1",
+ "css-loader": "^7.0.0",
+ "csstype": "^3.1.3",
"csv-parser": "^3.0.0",
"csv-stringify": "^6.4.4",
+ "csvtojson": "^2.0.10",
"D": "^1.0.0",
"d3": "^7.8.5",
"depcheck": "^1.4.7",
+ "dotenv": "^16.3.1",
+ "eslint-webpack-plugin": "^4.1.0",
"exif": "^0.6.0",
"exifr": "^7.1.3",
"express": "^4.18.2",
"express-flash": "0.0.2",
"express-session": "^1.17.3",
"express-validator": "^7.0.1",
+ "extract-colors": "^4.0.2",
"ffmpeg": "0.0.4",
"file-loader": "^6.2.0",
"file-saver": "^2.0.5",
@@ -99,6 +109,7 @@
"fluent-ffmpeg": "^2.1.2",
"forever-agent": "^0.6.1",
"fork-ts-checker-webpack-plugin": "^9.0.2",
+ "form-data": "^4.0.0",
"formidable": "3.5.1",
"function-plot": "^1.23.3",
"golden-layout": "^2.6.0",
@@ -125,9 +136,11 @@
"jszip": "^3.10.1",
"lodash": "^4.17.21",
"mapbox-gl": "^3.0.1",
+ "markdown-it": "^14.1.0",
"mathquill": "^0.10.1-a",
"md5-file": "^5.0.0",
"memorystream": "^0.3.1",
+ "mermaid": "^10.9.0",
"mobile-detect": "^1.4.5",
"mobx": "^6.12.0",
"mobx-react": "^9.1.0",
@@ -137,9 +150,8 @@
"node-stream-zip": "^1.15.0",
"nodemailer": "^6.9.7",
"nodemon": "^3.0.2",
- "normalize.css": "^8.0.1",
"npm": "^10.2.5",
- "openai": "^4.20.1",
+ "openai": "^4.26.0",
"p-limit": "^5.0.0",
"passport": "^0.7.0",
"passport-google-oauth20": "^2.0.0",
@@ -175,23 +187,28 @@
"react-grid-layout": "^1.4.4",
"react-icons": "^5.0.1",
"react-jsx-parser": "^1.29.0",
+ "react-latex-next": "^3.0.0",
"react-loading": "^2.0.3",
"react-map-gl": "^7.1.6",
"react-markdown": "^9.0.1",
"react-measure": "^2.5.2",
"react-resizable": "^3.0.5",
"react-select": "^5.8.0",
+ "react-textarea-autosize": "^8.5.3",
+ "react-type-animation": "^3.2.0",
"react-xarrows": "^2.0.2",
"readline": "^1.3.0",
"recharts": "^2.10.3",
+ "rehype-katex": "^7.0.0",
"rehype-raw": "^7.0.0",
"remark-gfm": "^4.0.0",
+ "remark-math": "^6.0.0",
"request": "^2.88.2",
"request-promise": "^4.2.6",
"reveal.js": "^5.0.2",
"rimraf": "^5.0.5",
"sass": "^1.69.5",
- "sass-loader": "^13.3.2",
+ "sass-loader": "^14.2.0",
"serializr": "^3.0.2",
"shelljs": "^0.8.5",
"socket.io": "^4.7.2",
@@ -204,6 +221,7 @@
"tough-cookie": "^4.1.3",
"tslint": "^6.1.3",
"tslint-loader": "^3.5.4",
+ "typescript": "^5.3.3",
"typescript-collections": "^1.3.3",
"typescript-language-server": "^4.1.3",
"uninstall": "^0.0.0",
@@ -216,13 +234,14 @@
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-middleware": "^7.0.0",
- "webrtc-adapter": "^8.2.3",
+ "webpack-hot-middleware": "^2.25.4",
"wikijs": "^6.4.1",
"words-to-numbers": "^1.5.1",
"xoauth2": "^1.2.0",
"xregexp": "^5.1.1"
},
"devDependencies": {
+ "@eslint/js": "^9.1.1",
"@types/adm-zip": "^0.5.5",
"@types/animejs": "^3.1.12",
"@types/archiver": "^6.0.2",
@@ -254,7 +273,7 @@
"@types/react": "^18.2.41",
"@types/react-autosuggest": "^10.1.10",
"@types/react-color": "^3.0.10",
- "@types/react-datepicker": "^4.19.3",
+ "@types/react-datepicker": "^6.2.0",
"@types/react-dom": "^18.2.17",
"@types/react-grid-layout": "^1.3.5",
"@types/react-measure": "^2.0.12",
@@ -265,40 +284,40 @@
"@types/uuid": "^9.0.7",
"@types/valid-url": "^1.0.7",
"@types/webpack": "^5.28.5",
- "@types/webpack-hot-middleware": "^2.25.9",
"@types/youtube": "0.0.50",
"chai": "^5.0.0",
"cross-env": "^7.0.3",
- "dotenv": "^16.3.1",
- "eslint": "^8.55.0",
+ "eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-node": "^4.1.0",
"eslint-config-prettier": "^9.1.0",
- "eslint-plugin-import": "^2.29.0",
+ "eslint-import-resolver-typescript": "^3.6.1",
+ "eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.0.1",
- "eslint-plugin-react": "^7.33.2",
+ "eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "globals": "^15.1.0",
"jsdom": "^24.0.0",
"mocha": "^10.2.0",
"prettier": "^3.1.0",
- "react-type-animation": "^3.2.0",
"scss-loader": "0.0.1",
- "style-loader": "^3.3.3",
+ "style-loader": "^4.0.0",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.1",
"ts-node-dev": "^2.0.0",
- "typescript": "^5.3.3",
- "webpack-dev-server": "^4.15.1",
- "webpack-hot-middleware": "^2.25.4"
+ "typescript-eslint": "^7.8.0",
+ "webpack-dev-server": "^5.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
"integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -390,13 +409,13 @@
}
},
"node_modules/@ampproject/remapping": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"peer": true,
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
@@ -414,24 +433,24 @@
}
},
"node_modules/@azure/core-auth": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.6.0.tgz",
- "integrity": "sha512-3X9wzaaGgRaBCwhLQZDtFp5uLIXCPrGbwJNWPPugvL4xbIGgScv77YzzxToKGLAKvG9amDoofMoP+9hsH1vs1w==",
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.7.2.tgz",
+ "integrity": "sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==",
"dependencies": {
"@azure/abort-controller": "^2.0.0",
"@azure/core-util": "^1.1.0",
- "tslib": "^2.2.0"
+ "tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@azure/core-auth/node_modules/@azure/abort-controller": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz",
- "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
"dependencies": {
- "tslib": "^2.2.0"
+ "tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
@@ -470,39 +489,39 @@
}
},
"node_modules/@azure/core-lro": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.6.0.tgz",
- "integrity": "sha512-PyRNcaIOfMgoUC01/24NoG+k8O81VrKxYARnDlo+Q2xji0/0/j2nIt8BwQh294pb1c5QnXTDPbNR4KzoDKXEoQ==",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz",
+ "integrity": "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw==",
"dependencies": {
"@azure/abort-controller": "^2.0.0",
"@azure/core-util": "^1.2.0",
"@azure/logger": "^1.0.0",
- "tslib": "^2.2.0"
+ "tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@azure/core-lro/node_modules/@azure/abort-controller": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz",
- "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
"dependencies": {
- "tslib": "^2.2.0"
+ "tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@azure/core-paging": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.5.0.tgz",
- "integrity": "sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==",
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz",
+ "integrity": "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA==",
"dependencies": {
- "tslib": "^2.2.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@azure/core-tracing": {
@@ -518,37 +537,37 @@
}
},
"node_modules/@azure/core-util": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.7.0.tgz",
- "integrity": "sha512-Zq2i3QO6k9DA8vnm29mYM4G8IE9u1mhF1GUabVEqPNX8Lj833gdxQ2NAFxt2BZsfAL+e9cT8SyVN7dFVJ/Hf0g==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.0.tgz",
+ "integrity": "sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==",
"dependencies": {
"@azure/abort-controller": "^2.0.0",
- "tslib": "^2.2.0"
+ "tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@azure/core-util/node_modules/@azure/abort-controller": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz",
- "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
"dependencies": {
- "tslib": "^2.2.0"
+ "tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@azure/logger": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz",
- "integrity": "sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.2.tgz",
+ "integrity": "sha512-l170uE7bsKpIU6B/giRc9i4NI0Mj+tANMMMxf7Zi/5cKzEqPayP7+X1WPrG7e+91JgY8N+7K7nF2WOi7iVhXvg==",
"dependencies": {
- "tslib": "^2.2.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@azure/storage-blob": {
@@ -570,41 +589,41 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
- "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "version": "7.24.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+ "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
"dependencies": {
- "@babel/highlight": "^7.23.4",
- "chalk": "^2.4.2"
+ "@babel/highlight": "^7.24.2",
+ "picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/compat-data": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
- "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz",
+ "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
- "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz",
+ "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==",
"peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.23.5",
- "@babel/generator": "^7.23.6",
+ "@babel/code-frame": "^7.24.2",
+ "@babel/generator": "^7.24.4",
"@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-module-transforms": "^7.23.3",
- "@babel/helpers": "^7.23.9",
- "@babel/parser": "^7.23.9",
- "@babel/template": "^7.23.9",
- "@babel/traverse": "^7.23.9",
- "@babel/types": "^7.23.9",
+ "@babel/helpers": "^7.24.4",
+ "@babel/parser": "^7.24.4",
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.1",
+ "@babel/types": "^7.24.0",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -620,13 +639,13 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
- "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz",
+ "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==",
"dependencies": {
- "@babel/types": "^7.23.6",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
+ "@babel/types": "^7.24.0",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
},
"engines": {
@@ -671,16 +690,16 @@
}
},
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.23.10",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz",
- "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz",
+ "integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-function-name": "^7.23.0",
"@babel/helper-member-expression-to-functions": "^7.23.0",
"@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.20",
+ "@babel/helper-replace-supers": "^7.24.1",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
"semver": "^6.3.1"
@@ -709,9 +728,9 @@
}
},
"node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz",
- "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==",
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz",
+ "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==",
"dependencies": {
"@babel/helper-compilation-targets": "^7.22.6",
"@babel/helper-plugin-utils": "^7.22.5",
@@ -766,11 +785,11 @@
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
- "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "version": "7.24.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz",
+ "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==",
"dependencies": {
- "@babel/types": "^7.22.15"
+ "@babel/types": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -806,9 +825,9 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
- "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
+ "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
"engines": {
"node": ">=6.9.0"
}
@@ -830,12 +849,12 @@
}
},
"node_modules/@babel/helper-replace-supers": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz",
- "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz",
+ "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==",
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-member-expression-to-functions": "^7.22.15",
+ "@babel/helper-member-expression-to-functions": "^7.23.0",
"@babel/helper-optimise-call-expression": "^7.22.5"
},
"engines": {
@@ -879,9 +898,9 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
- "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
+ "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
"engines": {
"node": ">=6.9.0"
}
@@ -916,36 +935,37 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
- "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz",
+ "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==",
"peer": true,
"dependencies": {
- "@babel/template": "^7.23.9",
- "@babel/traverse": "^7.23.9",
- "@babel/types": "^7.23.9"
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.1",
+ "@babel/types": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
- "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+ "version": "7.24.2",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
+ "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
"dependencies": {
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
- "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
+ "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -953,12 +973,27 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz",
+ "integrity": "sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==",
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.23.3",
- "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.23.3.tgz",
- "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==",
+ "version": "7.24.1",
+ "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.1.tgz",
+ "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -968,13 +1003,13 @@
}
},
"node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz",
- "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz",
+ "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/plugin-transform-optional-chaining": "^7.23.3"
+ "@babel/plugin-transform-optional-chaining": "^7.24.1"
},
"engines": {
"node": ">=6.9.0"
@@ -984,12 +1019,12 @@
}
},
"node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
- "version": "7.23.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz",
- "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz",
+ "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==",
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1068,11 +1103,11 @@
}
},
"node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz",
- "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz",
+ "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1082,11 +1117,11 @@
}
},
"node_modules/@babel/plugin-syntax-import-attributes": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz",
- "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz",
+ "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1118,11 +1153,11 @@
}
},
"node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz",
- "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz",
+ "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1241,11 +1276,11 @@
}
},
"node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz",
- "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz",
+ "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1255,12 +1290,12 @@
}
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz",
- "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==",
+ "version": "7.24.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz",
+ "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==",
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-remap-async-to-generator": "^7.22.20",
"@babel/plugin-syntax-async-generators": "^7.8.4"
},
@@ -1272,12 +1307,12 @@
}
},
"node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz",
- "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz",
+ "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==",
"dependencies": {
- "@babel/helper-module-imports": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-module-imports": "^7.24.1",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-remap-async-to-generator": "^7.22.20"
},
"engines": {
@@ -1288,11 +1323,11 @@
}
},
"node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz",
- "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz",
+ "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1302,11 +1337,11 @@
}
},
"node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz",
- "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz",
+ "integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1316,12 +1351,12 @@
}
},
"node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz",
- "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz",
+ "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-class-features-plugin": "^7.24.1",
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1331,12 +1366,12 @@
}
},
"node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz",
- "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz",
+ "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-create-class-features-plugin": "^7.24.4",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-class-static-block": "^7.14.5"
},
"engines": {
@@ -1347,16 +1382,16 @@
}
},
"node_modules/@babel/plugin-transform-classes": {
- "version": "7.23.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz",
- "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz",
+ "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-function-name": "^7.23.0",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.20",
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-replace-supers": "^7.24.1",
"@babel/helper-split-export-declaration": "^7.22.6",
"globals": "^11.1.0"
},
@@ -1367,13 +1402,21 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-classes/node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz",
- "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz",
+ "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/template": "^7.22.15"
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/template": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1383,11 +1426,11 @@
}
},
"node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz",
- "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz",
+ "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1397,12 +1440,12 @@
}
},
"node_modules/@babel/plugin-transform-dotall-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz",
- "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz",
+ "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1412,11 +1455,11 @@
}
},
"node_modules/@babel/plugin-transform-duplicate-keys": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz",
- "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz",
+ "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1426,11 +1469,11 @@
}
},
"node_modules/@babel/plugin-transform-dynamic-import": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz",
- "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz",
+ "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.3"
},
"engines": {
@@ -1441,12 +1484,12 @@
}
},
"node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz",
- "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz",
+ "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==",
"dependencies": {
"@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1456,11 +1499,11 @@
}
},
"node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz",
- "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz",
+ "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-export-namespace-from": "^7.8.3"
},
"engines": {
@@ -1471,11 +1514,11 @@
}
},
"node_modules/@babel/plugin-transform-for-of": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz",
- "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz",
+ "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
},
"engines": {
@@ -1486,13 +1529,13 @@
}
},
"node_modules/@babel/plugin-transform-function-name": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz",
- "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz",
+ "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.22.15",
+ "@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-function-name": "^7.23.0",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1502,11 +1545,11 @@
}
},
"node_modules/@babel/plugin-transform-json-strings": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz",
- "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz",
+ "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-json-strings": "^7.8.3"
},
"engines": {
@@ -1517,11 +1560,11 @@
}
},
"node_modules/@babel/plugin-transform-literals": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz",
- "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz",
+ "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1531,11 +1574,11 @@
}
},
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz",
- "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz",
+ "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
},
"engines": {
@@ -1546,11 +1589,11 @@
}
},
"node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz",
- "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz",
+ "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1560,12 +1603,12 @@
}
},
"node_modules/@babel/plugin-transform-modules-amd": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz",
- "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz",
+ "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==",
"dependencies": {
"@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1575,12 +1618,12 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz",
- "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz",
+ "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==",
"dependencies": {
"@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-simple-access": "^7.22.5"
},
"engines": {
@@ -1591,13 +1634,13 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz",
- "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz",
+ "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==",
"dependencies": {
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-validator-identifier": "^7.22.20"
},
"engines": {
@@ -1608,12 +1651,12 @@
}
},
"node_modules/@babel/plugin-transform-modules-umd": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz",
- "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz",
+ "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==",
"dependencies": {
"@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1638,11 +1681,11 @@
}
},
"node_modules/@babel/plugin-transform-new-target": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz",
- "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz",
+ "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1652,11 +1695,11 @@
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz",
- "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz",
+ "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
},
"engines": {
@@ -1667,11 +1710,11 @@
}
},
"node_modules/@babel/plugin-transform-numeric-separator": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz",
- "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz",
+ "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-numeric-separator": "^7.10.4"
},
"engines": {
@@ -1682,15 +1725,14 @@
}
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz",
- "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz",
+ "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==",
"dependencies": {
- "@babel/compat-data": "^7.23.3",
- "@babel/helper-compilation-targets": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.23.3"
+ "@babel/plugin-transform-parameters": "^7.24.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1700,12 +1742,12 @@
}
},
"node_modules/@babel/plugin-transform-object-super": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz",
- "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz",
+ "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.20"
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-replace-supers": "^7.24.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1715,11 +1757,11 @@
}
},
"node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz",
- "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz",
+ "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
},
"engines": {
@@ -1730,11 +1772,11 @@
}
},
"node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz",
- "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz",
+ "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
"@babel/plugin-syntax-optional-chaining": "^7.8.3"
},
@@ -1746,11 +1788,11 @@
}
},
"node_modules/@babel/plugin-transform-parameters": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz",
- "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz",
+ "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1760,12 +1802,12 @@
}
},
"node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz",
- "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz",
+ "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-class-features-plugin": "^7.24.1",
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1775,13 +1817,13 @@
}
},
"node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz",
- "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz",
+ "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-create-class-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-create-class-features-plugin": "^7.24.1",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-private-property-in-object": "^7.14.5"
},
"engines": {
@@ -1792,11 +1834,11 @@
}
},
"node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz",
- "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz",
+ "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1806,11 +1848,11 @@
}
},
"node_modules/@babel/plugin-transform-react-display-name": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz",
- "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz",
+ "integrity": "sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1852,12 +1894,12 @@
}
},
"node_modules/@babel/plugin-transform-react-pure-annotations": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz",
- "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz",
+ "integrity": "sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1867,11 +1909,11 @@
}
},
"node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz",
- "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz",
+ "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"regenerator-transform": "^0.15.2"
},
"engines": {
@@ -1882,11 +1924,11 @@
}
},
"node_modules/@babel/plugin-transform-reserved-words": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz",
- "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz",
+ "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1896,11 +1938,11 @@
}
},
"node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz",
- "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz",
+ "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1910,11 +1952,11 @@
}
},
"node_modules/@babel/plugin-transform-spread": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz",
- "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz",
+ "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
},
"engines": {
@@ -1925,11 +1967,11 @@
}
},
"node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz",
- "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz",
+ "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1939,11 +1981,11 @@
}
},
"node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz",
- "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz",
+ "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1953,11 +1995,11 @@
}
},
"node_modules/@babel/plugin-transform-typeof-symbol": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz",
- "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz",
+ "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1967,11 +2009,11 @@
}
},
"node_modules/@babel/plugin-transform-unicode-escapes": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz",
- "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz",
+ "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1981,12 +2023,12 @@
}
},
"node_modules/@babel/plugin-transform-unicode-property-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz",
- "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz",
+ "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1996,12 +2038,12 @@
}
},
"node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz",
- "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz",
+ "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -2011,12 +2053,12 @@
}
},
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz",
- "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz",
+ "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -2026,25 +2068,26 @@
}
},
"node_modules/@babel/preset-env": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz",
- "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.4.tgz",
+ "integrity": "sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A==",
"dependencies": {
- "@babel/compat-data": "^7.23.5",
+ "@babel/compat-data": "^7.24.4",
"@babel/helper-compilation-targets": "^7.23.6",
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-validator-option": "^7.23.5",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3",
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.4",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1",
"@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",
"@babel/plugin-syntax-class-static-block": "^7.14.5",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-export-namespace-from": "^7.8.3",
- "@babel/plugin-syntax-import-assertions": "^7.23.3",
- "@babel/plugin-syntax-import-attributes": "^7.23.3",
+ "@babel/plugin-syntax-import-assertions": "^7.24.1",
+ "@babel/plugin-syntax-import-attributes": "^7.24.1",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-syntax-json-strings": "^7.8.3",
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
@@ -2056,58 +2099,58 @@
"@babel/plugin-syntax-private-property-in-object": "^7.14.5",
"@babel/plugin-syntax-top-level-await": "^7.14.5",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
- "@babel/plugin-transform-arrow-functions": "^7.23.3",
- "@babel/plugin-transform-async-generator-functions": "^7.23.9",
- "@babel/plugin-transform-async-to-generator": "^7.23.3",
- "@babel/plugin-transform-block-scoped-functions": "^7.23.3",
- "@babel/plugin-transform-block-scoping": "^7.23.4",
- "@babel/plugin-transform-class-properties": "^7.23.3",
- "@babel/plugin-transform-class-static-block": "^7.23.4",
- "@babel/plugin-transform-classes": "^7.23.8",
- "@babel/plugin-transform-computed-properties": "^7.23.3",
- "@babel/plugin-transform-destructuring": "^7.23.3",
- "@babel/plugin-transform-dotall-regex": "^7.23.3",
- "@babel/plugin-transform-duplicate-keys": "^7.23.3",
- "@babel/plugin-transform-dynamic-import": "^7.23.4",
- "@babel/plugin-transform-exponentiation-operator": "^7.23.3",
- "@babel/plugin-transform-export-namespace-from": "^7.23.4",
- "@babel/plugin-transform-for-of": "^7.23.6",
- "@babel/plugin-transform-function-name": "^7.23.3",
- "@babel/plugin-transform-json-strings": "^7.23.4",
- "@babel/plugin-transform-literals": "^7.23.3",
- "@babel/plugin-transform-logical-assignment-operators": "^7.23.4",
- "@babel/plugin-transform-member-expression-literals": "^7.23.3",
- "@babel/plugin-transform-modules-amd": "^7.23.3",
- "@babel/plugin-transform-modules-commonjs": "^7.23.3",
- "@babel/plugin-transform-modules-systemjs": "^7.23.9",
- "@babel/plugin-transform-modules-umd": "^7.23.3",
+ "@babel/plugin-transform-arrow-functions": "^7.24.1",
+ "@babel/plugin-transform-async-generator-functions": "^7.24.3",
+ "@babel/plugin-transform-async-to-generator": "^7.24.1",
+ "@babel/plugin-transform-block-scoped-functions": "^7.24.1",
+ "@babel/plugin-transform-block-scoping": "^7.24.4",
+ "@babel/plugin-transform-class-properties": "^7.24.1",
+ "@babel/plugin-transform-class-static-block": "^7.24.4",
+ "@babel/plugin-transform-classes": "^7.24.1",
+ "@babel/plugin-transform-computed-properties": "^7.24.1",
+ "@babel/plugin-transform-destructuring": "^7.24.1",
+ "@babel/plugin-transform-dotall-regex": "^7.24.1",
+ "@babel/plugin-transform-duplicate-keys": "^7.24.1",
+ "@babel/plugin-transform-dynamic-import": "^7.24.1",
+ "@babel/plugin-transform-exponentiation-operator": "^7.24.1",
+ "@babel/plugin-transform-export-namespace-from": "^7.24.1",
+ "@babel/plugin-transform-for-of": "^7.24.1",
+ "@babel/plugin-transform-function-name": "^7.24.1",
+ "@babel/plugin-transform-json-strings": "^7.24.1",
+ "@babel/plugin-transform-literals": "^7.24.1",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.24.1",
+ "@babel/plugin-transform-member-expression-literals": "^7.24.1",
+ "@babel/plugin-transform-modules-amd": "^7.24.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.24.1",
+ "@babel/plugin-transform-modules-systemjs": "^7.24.1",
+ "@babel/plugin-transform-modules-umd": "^7.24.1",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
- "@babel/plugin-transform-new-target": "^7.23.3",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4",
- "@babel/plugin-transform-numeric-separator": "^7.23.4",
- "@babel/plugin-transform-object-rest-spread": "^7.23.4",
- "@babel/plugin-transform-object-super": "^7.23.3",
- "@babel/plugin-transform-optional-catch-binding": "^7.23.4",
- "@babel/plugin-transform-optional-chaining": "^7.23.4",
- "@babel/plugin-transform-parameters": "^7.23.3",
- "@babel/plugin-transform-private-methods": "^7.23.3",
- "@babel/plugin-transform-private-property-in-object": "^7.23.4",
- "@babel/plugin-transform-property-literals": "^7.23.3",
- "@babel/plugin-transform-regenerator": "^7.23.3",
- "@babel/plugin-transform-reserved-words": "^7.23.3",
- "@babel/plugin-transform-shorthand-properties": "^7.23.3",
- "@babel/plugin-transform-spread": "^7.23.3",
- "@babel/plugin-transform-sticky-regex": "^7.23.3",
- "@babel/plugin-transform-template-literals": "^7.23.3",
- "@babel/plugin-transform-typeof-symbol": "^7.23.3",
- "@babel/plugin-transform-unicode-escapes": "^7.23.3",
- "@babel/plugin-transform-unicode-property-regex": "^7.23.3",
- "@babel/plugin-transform-unicode-regex": "^7.23.3",
- "@babel/plugin-transform-unicode-sets-regex": "^7.23.3",
+ "@babel/plugin-transform-new-target": "^7.24.1",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1",
+ "@babel/plugin-transform-numeric-separator": "^7.24.1",
+ "@babel/plugin-transform-object-rest-spread": "^7.24.1",
+ "@babel/plugin-transform-object-super": "^7.24.1",
+ "@babel/plugin-transform-optional-catch-binding": "^7.24.1",
+ "@babel/plugin-transform-optional-chaining": "^7.24.1",
+ "@babel/plugin-transform-parameters": "^7.24.1",
+ "@babel/plugin-transform-private-methods": "^7.24.1",
+ "@babel/plugin-transform-private-property-in-object": "^7.24.1",
+ "@babel/plugin-transform-property-literals": "^7.24.1",
+ "@babel/plugin-transform-regenerator": "^7.24.1",
+ "@babel/plugin-transform-reserved-words": "^7.24.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.24.1",
+ "@babel/plugin-transform-spread": "^7.24.1",
+ "@babel/plugin-transform-sticky-regex": "^7.24.1",
+ "@babel/plugin-transform-template-literals": "^7.24.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.24.1",
+ "@babel/plugin-transform-unicode-escapes": "^7.24.1",
+ "@babel/plugin-transform-unicode-property-regex": "^7.24.1",
+ "@babel/plugin-transform-unicode-regex": "^7.24.1",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.24.1",
"@babel/preset-modules": "0.1.6-no-external-plugins",
- "babel-plugin-polyfill-corejs2": "^0.4.8",
- "babel-plugin-polyfill-corejs3": "^0.9.0",
- "babel-plugin-polyfill-regenerator": "^0.5.5",
+ "babel-plugin-polyfill-corejs2": "^0.4.10",
+ "babel-plugin-polyfill-corejs3": "^0.10.4",
+ "babel-plugin-polyfill-regenerator": "^0.6.1",
"core-js-compat": "^3.31.0",
"semver": "^6.3.1"
},
@@ -2132,16 +2175,16 @@
}
},
"node_modules/@babel/preset-react": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz",
- "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.1.tgz",
+ "integrity": "sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-validator-option": "^7.22.15",
- "@babel/plugin-transform-react-display-name": "^7.23.3",
- "@babel/plugin-transform-react-jsx": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-validator-option": "^7.23.5",
+ "@babel/plugin-transform-react-display-name": "^7.24.1",
+ "@babel/plugin-transform-react-jsx": "^7.23.4",
"@babel/plugin-transform-react-jsx-development": "^7.22.5",
- "@babel/plugin-transform-react-pure-annotations": "^7.23.3"
+ "@babel/plugin-transform-react-pure-annotations": "^7.24.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2156,9 +2199,9 @@
"integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
},
"node_modules/@babel/runtime": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
- "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz",
+ "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -2167,9 +2210,9 @@
}
},
"node_modules/@babel/runtime-corejs3": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.9.tgz",
- "integrity": "sha512-oeOFTrYWdWXCvXGB5orvMTJ6gCZ9I6FBjR+M38iKNXCsPxr4xT0RTdg5uz1H7QP8pp74IzPtwritEr+JscqHXQ==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.4.tgz",
+ "integrity": "sha512-VOQOexSilscN24VEY810G/PqtpFvx/z6UqDIjIWbDe2368HhDLkYN5TYwaEz/+eRCUkhJ2WaNLLmQAlxzfWj4w==",
"dependencies": {
"core-js-pure": "^3.30.2",
"regenerator-runtime": "^0.14.0"
@@ -2179,31 +2222,31 @@
}
},
"node_modules/@babel/template": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
- "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+ "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
"dependencies": {
"@babel/code-frame": "^7.23.5",
- "@babel/parser": "^7.23.9",
- "@babel/types": "^7.23.9"
+ "@babel/parser": "^7.24.0",
+ "@babel/types": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz",
- "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz",
+ "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==",
"dependencies": {
- "@babel/code-frame": "^7.23.5",
- "@babel/generator": "^7.23.6",
+ "@babel/code-frame": "^7.24.1",
+ "@babel/generator": "^7.24.1",
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.9",
- "@babel/types": "^7.23.9",
+ "@babel/parser": "^7.24.1",
+ "@babel/types": "^7.24.0",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -2211,10 +2254,18 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/traverse/node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/@babel/types": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
- "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
+ "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
"dependencies": {
"@babel/helper-string-parser": "^7.23.4",
"@babel/helper-validator-identifier": "^7.22.20",
@@ -2224,6 +2275,11 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@braintree/sanitize-url": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz",
+ "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A=="
+ },
"node_modules/@bundled-es-modules/pdfjs-dist": {
"version": "3.6.172-alpha.1",
"resolved": "https://registry.npmjs.org/@bundled-es-modules/pdfjs-dist/-/pdfjs-dist-3.6.172-alpha.1.tgz",
@@ -2300,9 +2356,9 @@
"integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
},
"node_modules/@emotion/is-prop-valid": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
- "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
+ "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
"dependencies": {
"@emotion/memoize": "^0.8.1"
}
@@ -2313,9 +2369,9 @@
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
},
"node_modules/@emotion/react": {
- "version": "11.11.3",
- "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.3.tgz",
- "integrity": "sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==",
+ "version": "11.11.4",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz",
+ "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==",
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.11.0",
@@ -2336,9 +2392,9 @@
}
},
"node_modules/@emotion/serialize": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz",
- "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz",
+ "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==",
"dependencies": {
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
@@ -2353,14 +2409,14 @@
"integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA=="
},
"node_modules/@emotion/styled": {
- "version": "11.11.0",
- "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz",
- "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==",
+ "version": "11.11.5",
+ "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz",
+ "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==",
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.11.0",
- "@emotion/is-prop-valid": "^1.2.1",
- "@emotion/serialize": "^1.1.2",
+ "@emotion/is-prop-valid": "^1.2.2",
+ "@emotion/serialize": "^1.1.4",
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
"@emotion/utils": "^1.2.1"
},
@@ -2401,7 +2457,6 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
- "dev": true,
"dependencies": {
"eslint-visitor-keys": "^3.3.0"
},
@@ -2416,7 +2471,6 @@
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
"integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
- "dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
@@ -2425,7 +2479,6 @@
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
- "dev": true,
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
@@ -2447,14 +2500,12 @@
"node_modules/@eslint/eslintrc/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2464,7 +2515,6 @@
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
- "dev": true,
"dependencies": {
"type-fest": "^0.20.2"
},
@@ -2479,7 +2529,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
"dependencies": {
"argparse": "^2.0.1"
},
@@ -2491,7 +2540,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -2500,12 +2548,12 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
- "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.2.0.tgz",
+ "integrity": "sha512-ESiIudvhoYni+MdsI8oD7skpprZ89qKocwRM2KEvhhBJ9nl5MRh7BXU5GTod7Mdygq+AUl+QzId6iWJKR/wABA==",
"dev": true,
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@ffmpeg/core": {
@@ -2553,13 +2601,13 @@
}
},
"node_modules/@floating-ui/react": {
- "version": "0.26.9",
- "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.9.tgz",
- "integrity": "sha512-p86wynZJVEkEq2BBjY/8p2g3biQ6TlgT4o/3KgFKyTWoJLU1GZ8wpctwRqtkEl2tseYA+kw7dBAIDFcednfI5w==",
+ "version": "0.26.12",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.12.tgz",
+ "integrity": "sha512-D09o62HrWdIkstF2kGekIKAC0/N/Dl6wo3CQsnLcOmO3LkW6Ik8uIb3kw8JYkwxNCcg+uJ2bpWUiIijTBep05w==",
"dependencies": {
- "@floating-ui/react-dom": "^2.0.8",
- "@floating-ui/utils": "^0.2.1",
- "tabbable": "^6.0.1"
+ "@floating-ui/react-dom": "^2.0.0",
+ "@floating-ui/utils": "^0.2.0",
+ "tabbable": "^6.0.0"
},
"peerDependencies": {
"react": ">=16.8.0",
@@ -2628,57 +2676,57 @@
}
},
"node_modules/@fortawesome/fontawesome-common-types": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz",
- "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==",
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz",
+ "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==",
"hasInstallScript": true,
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/fontawesome-svg-core": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz",
- "integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==",
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz",
+ "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==",
"hasInstallScript": true,
"dependencies": {
- "@fortawesome/fontawesome-common-types": "6.5.1"
+ "@fortawesome/fontawesome-common-types": "6.5.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-brands-svg-icons": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.1.tgz",
- "integrity": "sha512-093l7DAkx0aEtBq66Sf19MgoZewv1zeY9/4C7vSKPO4qMwEsW/2VYTUTpBtLwfb9T2R73tXaRDPmE4UqLCYHfg==",
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.2.tgz",
+ "integrity": "sha512-zi5FNYdmKLnEc0jc0uuHH17kz/hfYTg4Uei0wMGzcoCL/4d3WM3u1VMc0iGGa31HuhV5i7ZK8ZlTCQrHqRHSGQ==",
"hasInstallScript": true,
"dependencies": {
- "@fortawesome/fontawesome-common-types": "6.5.1"
+ "@fortawesome/fontawesome-common-types": "6.5.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-regular-svg-icons": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz",
- "integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==",
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz",
+ "integrity": "sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw==",
"hasInstallScript": true,
"dependencies": {
- "@fortawesome/fontawesome-common-types": "6.5.1"
+ "@fortawesome/fontawesome-common-types": "6.5.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-solid-svg-icons": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz",
- "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==",
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz",
+ "integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==",
"hasInstallScript": true,
"dependencies": {
- "@fortawesome/fontawesome-common-types": "6.5.1"
+ "@fortawesome/fontawesome-common-types": "6.5.2"
},
"engines": {
"node": ">=6"
@@ -2744,7 +2792,6 @@
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
- "dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^2.0.2",
"debug": "^4.3.1",
@@ -2758,7 +2805,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2768,7 +2814,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -2780,7 +2825,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
"engines": {
"node": ">=12.22"
},
@@ -2790,10 +2834,9 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
- "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
- "dev": true
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA=="
},
"node_modules/@icons/material": {
"version": "0.2.4",
@@ -2863,69 +2906,117 @@
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
- "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
- "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
"engines": {
"node": ">=12"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
- "node_modules/@isaacs/cliui/node_modules/string-width": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
- "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
"dependencies": {
- "eastasianwidth": "^0.2.0",
- "emoji-regex": "^9.2.2",
- "strip-ansi": "^7.0.1"
+ "@sinclair/typebox": "^0.27.8"
},
"engines": {
- "node": ">=12"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "node_modules/@jest/types/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
- "ansi-regex": "^6.0.1"
+ "color-convert": "^2.0.1"
},
"engines": {
- "node": ">=12"
+ "node": ">=8"
},
"funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
- "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "node_modules/@jest/types/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
- "ansi-styles": "^6.1.0",
- "string-width": "^5.0.1",
- "strip-ansi": "^7.0.1"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=10"
},
"funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@jest/types/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@jest/types/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/@jest/types/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/types/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/@jimp/bmp": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.10.tgz",
- "integrity": "sha512-1UXRl1Nw1KptZ1r0ANqtXOst9vGH51dq7keVKQzyyTO2lz4dOaezS9StuSTNh+RmiHg/SVPaFRpPfB0S/ln4Kg==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.12.tgz",
+ "integrity": "sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g==",
"dependencies": {
- "@jimp/utils": "^0.22.10",
+ "@jimp/utils": "^0.22.12",
"bmp-js": "^0.1.0"
},
"peerDependencies": {
@@ -2933,11 +3024,11 @@
}
},
"node_modules/@jimp/core": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.10.tgz",
- "integrity": "sha512-ZKyrehVy6wu1PnBXIUpn/fXmyMRQiVSbvHDubgXz4bfTOao3GiOurKHjByutQIgozuAN6ZHWiSge1dKA+dex3w==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.12.tgz",
+ "integrity": "sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA==",
"dependencies": {
- "@jimp/utils": "^0.22.10",
+ "@jimp/utils": "^0.22.12",
"any-base": "^1.1.0",
"buffer": "^5.2.0",
"exif-parser": "^0.1.12",
@@ -2948,19 +3039,19 @@
}
},
"node_modules/@jimp/custom": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.10.tgz",
- "integrity": "sha512-sPZkUYe1hu0iIgNisjizxPJqq2vaaKvkCkPoXq2U6UV3ZA1si/WVdrg25da3IcGIEV+83AoHgM8TvqlLgrCJsg==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz",
+ "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==",
"dependencies": {
- "@jimp/core": "^0.22.10"
+ "@jimp/core": "^0.22.12"
}
},
"node_modules/@jimp/gif": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.10.tgz",
- "integrity": "sha512-yEX2dSpamvkSx1PPDWGnKeWDrBz0vrCKjVG/cn4Zr68MRRT75tbZIeOrBa+RiUpY3ho5ix7d36LkYvt3qfUIhQ==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.12.tgz",
+ "integrity": "sha512-y6BFTJgch9mbor2H234VSjd9iwAhaNf/t3US5qpYIs0TSbAvM02Fbc28IaDETj9+4YB4676sz4RcN/zwhfu1pg==",
"dependencies": {
- "@jimp/utils": "^0.22.10",
+ "@jimp/utils": "^0.22.12",
"gifwrap": "^0.10.1",
"omggif": "^1.0.9"
},
@@ -2969,11 +3060,11 @@
}
},
"node_modules/@jimp/jpeg": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.10.tgz",
- "integrity": "sha512-6bu98pAcVN4DY2oiDLC4TOgieX/lZrLd1tombWZOFCN5PBmqaHQxm7IUmT+Wj4faEvh8QSHgVLSA+2JQQRJWVA==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.12.tgz",
+ "integrity": "sha512-Rq26XC/uQWaQKyb/5lksCTCxXhtY01NJeBN+dQv5yNYedN0i7iYu+fXEoRsfaJ8xZzjoANH8sns7rVP4GE7d/Q==",
"dependencies": {
- "@jimp/utils": "^0.22.10",
+ "@jimp/utils": "^0.22.12",
"jpeg-js": "^0.4.4"
},
"peerDependencies": {
@@ -2981,44 +3072,44 @@
}
},
"node_modules/@jimp/plugin-blit": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.10.tgz",
- "integrity": "sha512-6EI8Sl+mxYHEIy6Yteh6eknD+EZguKpNdr3sCKxNezmLR0+vK99vHcllo6uGSjXXiwtwS67Xqxn8SsoatL+UJQ==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.12.tgz",
+ "integrity": "sha512-xslz2ZoFZOPLY8EZ4dC29m168BtDx95D6K80TzgUi8gqT7LY6CsajWO0FAxDwHz6h0eomHMfyGX0stspBrTKnQ==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-blur": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.10.tgz",
- "integrity": "sha512-4XRTWuPVdMXJeclJMisXPGizeHtTryVaVV5HnuQXpKqIZtzXReCCpNGH8q/i0kBQOQMXhGWS3mpqOEwtpPePKw==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.12.tgz",
+ "integrity": "sha512-S0vJADTuh1Q9F+cXAwFPlrKWzDj2F9t/9JAbUvaaDuivpyWuImEKXVz5PUZw2NbpuSHjwssbTpOZ8F13iJX4uw==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-circle": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.10.tgz",
- "integrity": "sha512-mhcwTO1ywRxiCgtLGge6tDDIDPlX6qkI3CY+BjgGG/XhVHccCddXgOGLdlf+5OuKIEF2Nqs0V01LQEQIJFTmEw==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.12.tgz",
+ "integrity": "sha512-SWVXx1yiuj5jZtMijqUfvVOJBwOifFn0918ou4ftoHgegc5aHWW5dZbYPjvC9fLpvz7oSlptNl2Sxr1zwofjTg==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-color": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.10.tgz",
- "integrity": "sha512-e4t3L7Kedd96E0x1XjsTM6NcgulKUU66HdFTao7Tc9FYJRFSlttARZ/C6LEryGDm/i69R6bJEpo7BkNz0YL55Q==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.12.tgz",
+ "integrity": "sha512-xImhTE5BpS8xa+mAN6j4sMRWaUgUDLoaGHhJhpC+r7SKKErYDR0WQV4yCE4gP+N0gozD0F3Ka1LUSaMXrn7ZIA==",
"dependencies": {
- "@jimp/utils": "^0.22.10",
+ "@jimp/utils": "^0.22.12",
"tinycolor2": "^1.6.0"
},
"peerDependencies": {
@@ -3026,11 +3117,11 @@
}
},
"node_modules/@jimp/plugin-contain": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.10.tgz",
- "integrity": "sha512-eP8KrzctuEoqibQAxi9WhbnoRosydhiwg+IYya3dKuKDBTrD9UHt+ERlPQ/lTNWHzV/l4S1ntV3r9s9saJgsXA==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.12.tgz",
+ "integrity": "sha512-Eo3DmfixJw3N79lWk8q/0SDYbqmKt1xSTJ69yy8XLYQj9svoBbyRpSnHR+n9hOw5pKXytHwUW6nU4u1wegHNoQ==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5",
@@ -3040,11 +3131,11 @@
}
},
"node_modules/@jimp/plugin-cover": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.10.tgz",
- "integrity": "sha512-kJCwL5T1igfa0InCfkE7bBeqg26m46aoRt10ug+rvm11P6RrvRMGrgINFyIKB+mnB7CiyBN/MOula1CvLhSInQ==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.12.tgz",
+ "integrity": "sha512-z0w/1xH/v/knZkpTNx+E8a7fnasQ2wHG5ze6y5oL2dhH1UufNua8gLQXlv8/W56+4nJ1brhSd233HBJCo01BXA==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5",
@@ -3054,55 +3145,55 @@
}
},
"node_modules/@jimp/plugin-crop": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.10.tgz",
- "integrity": "sha512-BOZ+YGaZlhU7c5ye65RxikicXH0Ki0It6/XHISvipR5WZrfjLjL2Ke20G+AGnwBQc76gKenVcMXVUCnEjtZV+Q==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.12.tgz",
+ "integrity": "sha512-FNuUN0OVzRCozx8XSgP9MyLGMxNHHJMFt+LJuFjn1mu3k0VQxrzqbN06yIl46TVejhyAhcq5gLzqmSCHvlcBVw==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-displace": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.10.tgz",
- "integrity": "sha512-llNiWWMTKISDXt5+cXI0GaFmZWAjlT+4fFLYf4eXquuL/9wZoQsEBhv2GdGd48mkiS8jZq1Nnb2Q4ehEPTvrzw==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.12.tgz",
+ "integrity": "sha512-qpRM8JRicxfK6aPPqKZA6+GzBwUIitiHaZw0QrJ64Ygd3+AsTc7BXr+37k2x7QcyCvmKXY4haUrSIsBug4S3CA==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-dither": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.10.tgz",
- "integrity": "sha512-05WLmeV5M+P/0FS+bWf13hMew2X0oa8w9AtmevL2UyA/5GqiyvP2Xm5WfGQ8oFiiMvpnL6RFomJQOZtWca0C2w==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.12.tgz",
+ "integrity": "sha512-jYgGdSdSKl1UUEanX8A85v4+QUm+PE8vHFwlamaKk89s+PXQe7eVE3eNeSZX4inCq63EHL7cX580dMqkoC3ZLw==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-fisheye": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.10.tgz",
- "integrity": "sha512-InjiXvc7Gkzrx8VWtU97kDqV7ENnhHGPULymJWeZaF2aicud9Fpk4iCtd/DcZIrk7Cbe60A8RwNXN00HXIbSCg==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.12.tgz",
+ "integrity": "sha512-LGuUTsFg+fOp6KBKrmLkX4LfyCy8IIsROwoUvsUPKzutSqMJnsm3JGDW2eOmWIS/jJpPaeaishjlxvczjgII+Q==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-flip": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.10.tgz",
- "integrity": "sha512-42GkGtTHWnhnwTMPVK/kXObZbkYIpQWfuIfy5EMEMk6zRj05zpv4vsjkKWfuemweZINwfvD7wDJF7FVFNNcZZg==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.12.tgz",
+ "integrity": "sha512-m251Rop7GN8W0Yo/rF9LWk6kNclngyjIJs/VXHToGQ6EGveOSTSQaX2Isi9f9lCDLxt+inBIb7nlaLLxnvHX8Q==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5",
@@ -3110,55 +3201,55 @@
}
},
"node_modules/@jimp/plugin-gaussian": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.10.tgz",
- "integrity": "sha512-ykrG/6lTp9Q5YA8jS5XzwMHtRxb9HOFMgtmnrUZ8kU+BK8REecfy9Ic5BUEOjCYvS1a/xLsnrZQU07iiYxBxFg==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.12.tgz",
+ "integrity": "sha512-sBfbzoOmJ6FczfG2PquiK84NtVGeScw97JsCC3rpQv1PHVWyW+uqWFF53+n3c8Y0P2HWlUjflEla2h/vWShvhg==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-invert": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.10.tgz",
- "integrity": "sha512-d8j9BlUJYs/c994t4azUWSWmQq4LLPG4ecm8m6SSNqap+S/HlVQGqjYhJEBbY9EXkOTYB9vBL9bqwSM1Rr6paA==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.12.tgz",
+ "integrity": "sha512-N+6rwxdB+7OCR6PYijaA/iizXXodpxOGvT/smd/lxeXsZ/empHmFFFJ/FaXcYh19Tm04dGDaXcNF/dN5nm6+xQ==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-mask": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.10.tgz",
- "integrity": "sha512-yRBs1230XZkz24uFTdTcSlZ0HXZpIWzM3iFQN56MzZ7USgdVZjPPDCQ8I9RpqfZ36nDflQkUO0wV7ucsi4ogow==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.12.tgz",
+ "integrity": "sha512-4AWZg+DomtpUA099jRV8IEZUfn1wLv6+nem4NRJC7L/82vxzLCgXKTxvNvBcNmJjT9yS1LAAmiJGdWKXG63/NA==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-normalize": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.10.tgz",
- "integrity": "sha512-Wk9GX6eJMchX/ZAazVa70Fagu+OXMvHiPY+HrcEwcclL+p1wo8xAHEsf9iKno7Ja4EU9lLhbBRY5hYJyiKMEkg==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.12.tgz",
+ "integrity": "sha512-0So0rexQivnWgnhacX4cfkM2223YdExnJTTy6d06WbkfZk5alHUx8MM3yEzwoCN0ErO7oyqEWRnEkGC+As1FtA==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-print": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.10.tgz",
- "integrity": "sha512-1U3VloIR+beE1kWPdGEJMiE2h1Do29iv3w8sBbvPyRP4qXxRFcDpmCGtctsrKmb1krlBFlj8ubyAY90xL+5n9w==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.12.tgz",
+ "integrity": "sha512-c7TnhHlxm87DJeSnwr/XOLjJU/whoiKYY7r21SbuJ5nuH+7a78EW1teOaj5gEr2wYEd7QtkFqGlmyGXY/YclyQ==",
"dependencies": {
- "@jimp/utils": "^0.22.10",
+ "@jimp/utils": "^0.22.12",
"load-bmfont": "^1.4.1"
},
"peerDependencies": {
@@ -3167,22 +3258,22 @@
}
},
"node_modules/@jimp/plugin-resize": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.10.tgz",
- "integrity": "sha512-ixomxVcnAONXDgaq0opvAx4UAOiEhOA/tipuhFFOvPKFd4yf1BAnEviB5maB0SBHHkJXPUSzDp/73xVTMGSe7g==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.12.tgz",
+ "integrity": "sha512-3NyTPlPbTnGKDIbaBgQ3HbE6wXbAlFfxHVERmrbqAi8R3r6fQPxpCauA8UVDnieg5eo04D0T8nnnNIX//i/sXg==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
}
},
"node_modules/@jimp/plugin-rotate": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.10.tgz",
- "integrity": "sha512-eeFX8dnRyf3LAdsdXWKWuN18hLRg8zy1cP0cP9rHzQVWRK7ck/QsLxK1vHq7MADGwQalNaNTJ9SQxH6c8mz6jw==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.12.tgz",
+ "integrity": "sha512-9YNEt7BPAFfTls2FGfKBVgwwLUuKqy+E8bDGGEsOqHtbuhbshVGxN2WMZaD4gh5IDWvR+emmmPPWGgaYNYt1gA==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5",
@@ -3192,11 +3283,11 @@
}
},
"node_modules/@jimp/plugin-scale": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.10.tgz",
- "integrity": "sha512-TG/H0oUN69C9ArBCZg4PmuoixFVKIiru8282KzSB/Tp1I0xwX0XLTv3dJ5pobPlIgPcB+TmD4xAIdkCT4rtWxg==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.12.tgz",
+ "integrity": "sha512-dghs92qM6MhHj0HrV2qAwKPMklQtjNpoYgAB94ysYpsXslhRTiPisueSIELRwZGEr0J0VUxpUY7HgJwlSIgGZw==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5",
@@ -3204,11 +3295,11 @@
}
},
"node_modules/@jimp/plugin-shadow": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.10.tgz",
- "integrity": "sha512-TN9xm6fI7XfxbMUQqFPZjv59Xdpf0tSiAQdINB4g6pJMWiVANR/74OtDONoy3KKpenu5Y38s+FkrtID/KcQAhw==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.12.tgz",
+ "integrity": "sha512-FX8mTJuCt7/3zXVoeD/qHlm4YH2bVqBuWQHXSuBK054e7wFRnRnbSLPUqAwSeYP3lWqpuQzJtgiiBxV3+WWwTg==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5",
@@ -3217,11 +3308,11 @@
}
},
"node_modules/@jimp/plugin-threshold": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.10.tgz",
- "integrity": "sha512-DA2lSnU0TgIRbAgmXaxroYw3Ad6J2DOFEoJp0NleSm2h3GWbZEE5yW9U2B6hD3iqn4AenG4E2b2WzHXZyzSutw==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.12.tgz",
+ "integrity": "sha512-4x5GrQr1a/9L0paBC/MZZJjjgjxLYrqSmWd+e+QfAEPvmRxdRoQ5uKEuNgXnm9/weHQBTnQBQsOY2iFja+XGAw==",
"dependencies": {
- "@jimp/utils": "^0.22.10"
+ "@jimp/utils": "^0.22.12"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5",
@@ -3230,31 +3321,31 @@
}
},
"node_modules/@jimp/plugins": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.10.tgz",
- "integrity": "sha512-KDMZyM6pmvS8freB+UBLko1TO/k4D7URS/nphCozuH+P7i3UMe7NdckXKJ8u+WD6sqN0YFYvBehpkpnUiw/91w==",
- "dependencies": {
- "@jimp/plugin-blit": "^0.22.10",
- "@jimp/plugin-blur": "^0.22.10",
- "@jimp/plugin-circle": "^0.22.10",
- "@jimp/plugin-color": "^0.22.10",
- "@jimp/plugin-contain": "^0.22.10",
- "@jimp/plugin-cover": "^0.22.10",
- "@jimp/plugin-crop": "^0.22.10",
- "@jimp/plugin-displace": "^0.22.10",
- "@jimp/plugin-dither": "^0.22.10",
- "@jimp/plugin-fisheye": "^0.22.10",
- "@jimp/plugin-flip": "^0.22.10",
- "@jimp/plugin-gaussian": "^0.22.10",
- "@jimp/plugin-invert": "^0.22.10",
- "@jimp/plugin-mask": "^0.22.10",
- "@jimp/plugin-normalize": "^0.22.10",
- "@jimp/plugin-print": "^0.22.10",
- "@jimp/plugin-resize": "^0.22.10",
- "@jimp/plugin-rotate": "^0.22.10",
- "@jimp/plugin-scale": "^0.22.10",
- "@jimp/plugin-shadow": "^0.22.10",
- "@jimp/plugin-threshold": "^0.22.10",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.12.tgz",
+ "integrity": "sha512-yBJ8vQrDkBbTgQZLty9k4+KtUQdRjsIDJSPjuI21YdVeqZxYywifHl4/XWILoTZsjTUASQcGoH0TuC0N7xm3ww==",
+ "dependencies": {
+ "@jimp/plugin-blit": "^0.22.12",
+ "@jimp/plugin-blur": "^0.22.12",
+ "@jimp/plugin-circle": "^0.22.12",
+ "@jimp/plugin-color": "^0.22.12",
+ "@jimp/plugin-contain": "^0.22.12",
+ "@jimp/plugin-cover": "^0.22.12",
+ "@jimp/plugin-crop": "^0.22.12",
+ "@jimp/plugin-displace": "^0.22.12",
+ "@jimp/plugin-dither": "^0.22.12",
+ "@jimp/plugin-fisheye": "^0.22.12",
+ "@jimp/plugin-flip": "^0.22.12",
+ "@jimp/plugin-gaussian": "^0.22.12",
+ "@jimp/plugin-invert": "^0.22.12",
+ "@jimp/plugin-mask": "^0.22.12",
+ "@jimp/plugin-normalize": "^0.22.12",
+ "@jimp/plugin-print": "^0.22.12",
+ "@jimp/plugin-resize": "^0.22.12",
+ "@jimp/plugin-rotate": "^0.22.12",
+ "@jimp/plugin-scale": "^0.22.12",
+ "@jimp/plugin-shadow": "^0.22.12",
+ "@jimp/plugin-threshold": "^0.22.12",
"timm": "^1.6.1"
},
"peerDependencies": {
@@ -3262,11 +3353,11 @@
}
},
"node_modules/@jimp/png": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.10.tgz",
- "integrity": "sha512-RYinU7tZToeeR2g2qAMn42AU+8OUHjXPKZZ9RkmoL4bguA1xyZWaSdr22/FBkmnHhOERRlr02KPDN1OTOYHLDQ==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.12.tgz",
+ "integrity": "sha512-Mrp6dr3UTn+aLK8ty/dSKELz+Otdz1v4aAXzV5q53UDD2rbB5joKVJ/ChY310B+eRzNxIovbUF1KVrUsYdE8Hg==",
"dependencies": {
- "@jimp/utils": "^0.22.10",
+ "@jimp/utils": "^0.22.12",
"pngjs": "^6.0.0"
},
"peerDependencies": {
@@ -3274,9 +3365,9 @@
}
},
"node_modules/@jimp/tiff": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.10.tgz",
- "integrity": "sha512-OaivlSYzpNTHyH/h7pEtl3A7F7TbsgytZs52GLX/xITW92ffgDgT6PkldIrMrET6ERh/hdijNQiew7IoEEr2og==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.12.tgz",
+ "integrity": "sha512-E1LtMh4RyJsoCAfAkBRVSYyZDTtLq9p9LUiiYP0vPtXyxX4BiYBUYihTLSBlCQg5nF2e4OpQg7SPrLdJ66u7jg==",
"dependencies": {
"utif2": "^4.0.1"
},
@@ -3285,15 +3376,15 @@
}
},
"node_modules/@jimp/types": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.10.tgz",
- "integrity": "sha512-u/r+XYzbCx4zZukDmxx8S0er3Yq3iDPI6+31WKX0N18i2qPPJYcn8qwIFurfupRumGvJ8SlGLCgt/T+Y8zzUIw==",
- "dependencies": {
- "@jimp/bmp": "^0.22.10",
- "@jimp/gif": "^0.22.10",
- "@jimp/jpeg": "^0.22.10",
- "@jimp/png": "^0.22.10",
- "@jimp/tiff": "^0.22.10",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.12.tgz",
+ "integrity": "sha512-wwKYzRdElE1MBXFREvCto5s699izFHNVvALUv79GXNbsOVqlwlOxlWJ8DuyOGIXoLP4JW/m30YyuTtfUJgMRMA==",
+ "dependencies": {
+ "@jimp/bmp": "^0.22.12",
+ "@jimp/gif": "^0.22.12",
+ "@jimp/jpeg": "^0.22.12",
+ "@jimp/png": "^0.22.12",
+ "@jimp/tiff": "^0.22.12",
"timm": "^1.6.1"
},
"peerDependencies": {
@@ -3301,9 +3392,9 @@
}
},
"node_modules/@jimp/utils": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.10.tgz",
- "integrity": "sha512-ztlOK9Mm2iLG2AMoabzM4i3WZ/FtshcgsJCbZCRUs/DKoeS2tySRJTnQZ1b7Roq0M4Ce+FUAxnCAcBV0q7PH9w==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz",
+ "integrity": "sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==",
"dependencies": {
"regenerator-runtime": "^0.13.3"
}
@@ -3314,13 +3405,13 @@
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
@@ -3335,20 +3426,20 @@
}
},
"node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
- "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
@@ -3357,9 +3448,9 @@
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.22",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
- "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@@ -3371,9 +3462,9 @@
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
},
"node_modules/@leichtgewicht/ip-codec": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
- "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
+ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
"dev": true
},
"node_modules/@mapbox/geojson-rewind": {
@@ -3408,9 +3499,9 @@
}
},
"node_modules/@mapbox/mapbox-gl-supported": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz",
- "integrity": "sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ=="
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-3.0.0.tgz",
+ "integrity": "sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg=="
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.11",
@@ -3564,22 +3655,22 @@
}
},
"node_modules/@mongodb-js/saslprep": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz",
- "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz",
+ "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==",
"dependencies": {
"sparse-bitfield": "^3.0.3"
}
},
"node_modules/@mui/base": {
- "version": "5.0.0-beta.36",
- "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.36.tgz",
- "integrity": "sha512-6A8fYiXgjqTO6pgj31Hc8wm1M3rFYCxDRh09dBVk0L0W4cb2lnurRJa3cAyic6hHY+we1S58OdGYRbKmOsDpGQ==",
+ "version": "5.0.0-beta.40",
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz",
+ "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==",
"dependencies": {
"@babel/runtime": "^7.23.9",
"@floating-ui/react-dom": "^2.0.8",
- "@mui/types": "^7.2.13",
- "@mui/utils": "^5.15.9",
+ "@mui/types": "^7.2.14",
+ "@mui/utils": "^5.15.14",
"@popperjs/core": "^2.11.8",
"clsx": "^2.1.0",
"prop-types": "^15.8.1"
@@ -3603,18 +3694,18 @@
}
},
"node_modules/@mui/core-downloads-tracker": {
- "version": "5.15.11",
- "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.11.tgz",
- "integrity": "sha512-JVrJ9Jo4gyU707ujnRzmE8ABBWpXd6FwL9GYULmwZRtfPg89ggXs/S3MStQkpJ1JRWfdLL6S5syXmgQGq5EDAw==",
+ "version": "5.15.15",
+ "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.15.tgz",
+ "integrity": "sha512-aXnw29OWQ6I5A47iuWEI6qSSUfH6G/aCsW9KmW3LiFqr7uXZBK4Ks+z8G+qeIub8k0T5CMqlT2q0L+ZJTMrqpg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui-org"
}
},
"node_modules/@mui/icons-material": {
- "version": "5.15.10",
- "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.10.tgz",
- "integrity": "sha512-9cF8oUHZKo9oQ7EQ3pxPELaZuZVmphskU4OI6NiJNDVN7zcuvrEsuWjYo1Zh4fLiC39Nrvm30h/B51rcUjvSGA==",
+ "version": "5.15.15",
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.15.tgz",
+ "integrity": "sha512-kkeU/pe+hABcYDH6Uqy8RmIsr2S/y5bP2rp+Gat4CcRjCcVne6KudS1NrZQhUCRysrTDCAhcbcf9gt+/+pGO2g==",
"dependencies": {
"@babel/runtime": "^7.23.9"
},
@@ -3637,16 +3728,16 @@
}
},
"node_modules/@mui/material": {
- "version": "5.15.10",
- "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.10.tgz",
- "integrity": "sha512-YJJGHjwDOucecjDEV5l9ISTCo+l9YeWrho623UajzoHRYxuKUmwrGVYOW4PKwGvCx9SU9oklZnbbi2Clc5XZHw==",
+ "version": "5.15.15",
+ "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.15.tgz",
+ "integrity": "sha512-3zvWayJ+E1kzoIsvwyEvkTUKVKt1AjchFFns+JtluHCuvxgKcLSRJTADw37k0doaRtVAsyh8bz9Afqzv+KYrIA==",
"dependencies": {
"@babel/runtime": "^7.23.9",
- "@mui/base": "5.0.0-beta.36",
- "@mui/core-downloads-tracker": "^5.15.10",
- "@mui/system": "^5.15.9",
- "@mui/types": "^7.2.13",
- "@mui/utils": "^5.15.9",
+ "@mui/base": "5.0.0-beta.40",
+ "@mui/core-downloads-tracker": "^5.15.15",
+ "@mui/system": "^5.15.15",
+ "@mui/types": "^7.2.14",
+ "@mui/utils": "^5.15.14",
"@types/react-transition-group": "^4.4.10",
"clsx": "^2.1.0",
"csstype": "^3.1.3",
@@ -3681,12 +3772,12 @@
}
},
"node_modules/@mui/private-theming": {
- "version": "5.15.11",
- "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.11.tgz",
- "integrity": "sha512-jY/696SnSxSzO1u86Thym7ky5T9CgfidU3NFJjguldqK4f3Z5S97amZ6nffg8gTD0HBjY9scB+4ekqDEUmxZOA==",
+ "version": "5.15.14",
+ "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.14.tgz",
+ "integrity": "sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==",
"dependencies": {
"@babel/runtime": "^7.23.9",
- "@mui/utils": "^5.15.11",
+ "@mui/utils": "^5.15.14",
"prop-types": "^15.8.1"
},
"engines": {
@@ -3707,9 +3798,9 @@
}
},
"node_modules/@mui/styled-engine": {
- "version": "5.15.11",
- "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.11.tgz",
- "integrity": "sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==",
+ "version": "5.15.14",
+ "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz",
+ "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==",
"dependencies": {
"@babel/runtime": "^7.23.9",
"@emotion/cache": "^11.11.0",
@@ -3764,15 +3855,15 @@
}
},
"node_modules/@mui/system": {
- "version": "5.15.9",
- "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.9.tgz",
- "integrity": "sha512-SxkaaZ8jsnIJ77bBXttfG//LUf6nTfOcaOuIgItqfHv60ZCQy/Hu7moaob35kBb+guxVJnoSZ+7vQJrA/E7pKg==",
+ "version": "5.15.15",
+ "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.15.tgz",
+ "integrity": "sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ==",
"dependencies": {
"@babel/runtime": "^7.23.9",
- "@mui/private-theming": "^5.15.9",
- "@mui/styled-engine": "^5.15.9",
- "@mui/types": "^7.2.13",
- "@mui/utils": "^5.15.9",
+ "@mui/private-theming": "^5.15.14",
+ "@mui/styled-engine": "^5.15.14",
+ "@mui/types": "^7.2.14",
+ "@mui/utils": "^5.15.14",
"clsx": "^2.1.0",
"csstype": "^3.1.3",
"prop-types": "^15.8.1"
@@ -3803,9 +3894,9 @@
}
},
"node_modules/@mui/types": {
- "version": "7.2.13",
- "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz",
- "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==",
+ "version": "7.2.14",
+ "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz",
+ "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==",
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0"
},
@@ -3816,9 +3907,9 @@
}
},
"node_modules/@mui/utils": {
- "version": "5.15.11",
- "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.11.tgz",
- "integrity": "sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==",
+ "version": "5.15.14",
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.14.tgz",
+ "integrity": "sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==",
"dependencies": {
"@babel/runtime": "^7.23.9",
"@types/prop-types": "^15.7.11",
@@ -3846,7 +3937,6 @@
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
@@ -3859,7 +3949,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
"engines": {
"node": ">= 8"
}
@@ -3868,7 +3957,6 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
@@ -3878,99 +3966,97 @@
}
},
"node_modules/@octokit/auth-token": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
- "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.0.tgz",
+ "integrity": "sha512-JH+5PhVMjpbBuKlykiseCHa2uZdEd8Qm/N9Kpqncx4o/wkGF38gqVjIP2gZqfaP3nxFZPpg0FwGClKzBi6nS2g==",
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/core": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.1.0.tgz",
- "integrity": "sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==",
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz",
+ "integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==",
"dependencies": {
- "@octokit/auth-token": "^4.0.0",
- "@octokit/graphql": "^7.0.0",
- "@octokit/request": "^8.0.2",
- "@octokit/request-error": "^5.0.0",
- "@octokit/types": "^12.0.0",
- "before-after-hook": "^2.2.0",
- "universal-user-agent": "^6.0.0"
+ "@octokit/auth-token": "^5.0.0",
+ "@octokit/graphql": "^8.0.0",
+ "@octokit/request": "^9.0.0",
+ "@octokit/request-error": "^6.0.1",
+ "@octokit/types": "^13.0.0",
+ "before-after-hook": "^3.0.2",
+ "universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/endpoint": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz",
- "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.0.tgz",
+ "integrity": "sha512-ogZ5uLMeGBZUzS32fNt9j+dNw3kkEn5CSw4CVkN1EvCNdFYWrQ5diQR6Hh52VrPR0oayIoYTqQFL/l8RqkV0qw==",
"dependencies": {
- "@octokit/types": "^12.0.0",
- "universal-user-agent": "^6.0.0"
+ "@octokit/types": "^13.0.0",
+ "universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/graphql": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz",
- "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.1.0.tgz",
+ "integrity": "sha512-XDvj6GcUnQYgbCLXElt3vZDzNIPGvGiwxQO2XzsvfVUjebGh0E5eCD/1My9zUGSNKaGVZitVuO8LMziGmoFryg==",
"dependencies": {
- "@octokit/request": "^8.0.1",
- "@octokit/types": "^12.0.0",
- "universal-user-agent": "^6.0.0"
+ "@octokit/request": "^9.0.0",
+ "@octokit/types": "^13.0.0",
+ "universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/openapi-types": {
- "version": "19.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz",
- "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw=="
+ "version": "22.0.1",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.0.1.tgz",
+ "integrity": "sha512-1yN5m1IMNXthoBDUXFF97N1gHop04B3H8ws7wtOr8GgRyDO1gKALjwMHARNBoMBiB/2vEe/vxstrApcJZzQbnQ=="
},
"node_modules/@octokit/request": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.2.0.tgz",
- "integrity": "sha512-exPif6x5uwLqv1N1irkLG1zZNJkOtj8bZxuVHd71U5Ftuxf2wGNvAJyNBcPbPC+EBzwYEbBDdSFb8EPcjpYxPQ==",
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.0.tgz",
+ "integrity": "sha512-1mDzqKSiryRKZM++MhO6WQBukWbikes6AN6UTxB5vpRnNUbPDkVfUhpSvZ3aXYEFnbcV8DZkikOnCr3pdgMD3Q==",
"dependencies": {
- "@octokit/endpoint": "^9.0.0",
- "@octokit/request-error": "^5.0.0",
- "@octokit/types": "^12.0.0",
- "universal-user-agent": "^6.0.0"
+ "@octokit/endpoint": "^10.0.0",
+ "@octokit/request-error": "^6.0.1",
+ "@octokit/types": "^13.1.0",
+ "universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/request-error": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz",
- "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.0.tgz",
+ "integrity": "sha512-xcLJv4IgfWIOEEVZwfhUN3yHNWJL0AMw1J1Ba8BofM9RdDTbapg6MO4zNxlPS4XXX9aAIsbDRa47K57EhgeVAw==",
"dependencies": {
- "@octokit/types": "^12.0.0",
- "deprecation": "^2.0.0",
- "once": "^1.4.0"
+ "@octokit/types": "^13.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/types": {
- "version": "12.5.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.5.0.tgz",
- "integrity": "sha512-YJEKcb0KkJlIUNU/zjnZwHEP8AoVh/OoIcP/1IyR4UHxExz7fzpe/a8IG4wBtQi7QDEqiomVLX88S6FpxxAJtg==",
+ "version": "13.4.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.4.0.tgz",
+ "integrity": "sha512-WlMegy3lPXYWASe3k9Jslc5a0anrYAYMWtsFrxBTdQjS70hvLH6C+PGvHbOsgy3RA3LouGJoU/vAt4KarecQLQ==",
"dependencies": {
- "@octokit/openapi-types": "^19.1.0"
+ "@octokit/openapi-types": "^22.0.1"
}
},
"node_modules/@opentelemetry/api": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz",
- "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz",
+ "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==",
"engines": {
"node": ">=8.0.0"
}
@@ -5882,6 +5968,66 @@
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
}
},
+ "node_modules/@react-spring/animated": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz",
+ "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==",
+ "dependencies": {
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-spring/core": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz",
+ "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==",
+ "dependencies": {
+ "@react-spring/animated": "~9.7.3",
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-spring/donate"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-spring/shared": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz",
+ "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==",
+ "dependencies": {
+ "@react-spring/types": "~9.7.3"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-spring/types": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz",
+ "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw=="
+ },
+ "node_modules/@react-spring/web": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz",
+ "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==",
+ "dependencies": {
+ "@react-spring/animated": "~9.7.3",
+ "@react-spring/core": "~9.7.3",
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/@react-stately/calendar": {
"version": "3.4.4",
"resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.4.4.tgz",
@@ -6764,10 +6910,15 @@
"url": "https://ko-fi.com/killymxi"
}
},
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.8",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="
+ },
"node_modules/@sindresorhus/is": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.1.0.tgz",
- "integrity": "sha512-BuvU07zq3tQ/2SIgBsEuxKYDyDjC0n7Zir52bpHy2xnBbW81+po43aLFPLbeV3HRAheFbGud1qgcqSYfhtHMAg==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.2.0.tgz",
+ "integrity": "sha512-yM/IGPkVnYGblhDosFBwq0ZGdnVSBkNV4onUtipGMOjZd4kB6GAu3ys91aftSbyMHh6A2GPdt+KDI5NoWP63MQ==",
"engines": {
"node": ">=16"
},
@@ -6776,9 +6927,9 @@
}
},
"node_modules/@socket.io/component-emitter": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
- "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.1.tgz",
+ "integrity": "sha512-dzJtaDAAoXx4GCOJpbB2eG/Qj8VDpdwkLsWGzGm+0L7E8/434RyMbAHmk9ubXWVAb9nXmc44jUf8GKqVDiKezg=="
},
"node_modules/@spectrum-icons/ui": {
"version": "3.6.5",
@@ -6809,9 +6960,9 @@
}
},
"node_modules/@swc/helpers": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.6.tgz",
- "integrity": "sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==",
+ "version": "0.5.9",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.9.tgz",
+ "integrity": "sha512-XI76sLwMJoLjJTOK5RblBZkouOJG3X3hjxLCzLnyN1ifAiKQc6Hck3uvnU4Z/dV/Dyk36Ffj8FLvDLV2oWvKTw==",
"dependencies": {
"tslib": "^2.4.0"
}
@@ -6833,9 +6984,9 @@
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
},
"node_modules/@tsconfig/node10": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
- "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
+ "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
"dev": true
},
"node_modules/@tsconfig/node12": {
@@ -8501,9 +8652,9 @@
"dev": true
},
"node_modules/@types/chai": {
- "version": "4.3.11",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz",
- "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==",
+ "version": "4.3.14",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz",
+ "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==",
"dev": true
},
"node_modules/@types/color": {
@@ -8525,16 +8676,15 @@
}
},
"node_modules/@types/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-87W6MJCKZYDhLAx/J1ikW8niMvmGRyY+rpUxWpL1cO7F8Uu5CHuQoFv+R0/L5pgNdW4jTyda42kv60uwVIPjLw==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-hulKeREDdLFesGQjl96+4aoJSHY5b2GRjagzzcqCfIrWhe5vkCqIvrLbqzBaI1q94Vg8DNJZZqTR5ocdWmWclg==",
"dev": true
},
"node_modules/@types/connect": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
- "dev": true,
"dependencies": {
"@types/node": "*"
}
@@ -8555,9 +8705,9 @@
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
},
"node_modules/@types/cookie-parser": {
- "version": "1.4.6",
- "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.6.tgz",
- "integrity": "sha512-KoooCrD56qlLskXPLGUiJxOMnv5l/8m7cQD2OxJ73NPMhuSz9PmvwRD6EpjDyKBVrdJDdQ4bQK7JFNHnNmax0w==",
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.7.tgz",
+ "integrity": "sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==",
"dev": true,
"dependencies": {
"@types/express": "*"
@@ -8725,9 +8875,9 @@
}
},
"node_modules/@types/d3-hierarchy": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.6.tgz",
- "integrity": "sha512-qlmD/8aMk5xGorUvTUWHCiumvgaUXYldYjNVOWtYoTYY/L+WwIEAmJxUmTgr9LoGNG0PPAOmqMDJVDPc7DOpPw==",
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz",
+ "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==",
"dev": true
},
"node_modules/@types/d3-interpolate": {
@@ -8772,8 +8922,7 @@
"node_modules/@types/d3-scale-chromatic": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz",
- "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==",
- "dev": true
+ "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw=="
},
"node_modules/@types/d3-selection": {
"version": "3.0.10",
@@ -8837,9 +8986,9 @@
"integrity": "sha512-zf2GwV/G6TdaLwpLDcGTIkHnXf8JEf/viMux+khqKQKDa8/8BAUtXXZS563GnvJ4Fg0PBLGAaFf2GekEVSZ6GQ=="
},
"node_modules/@types/eslint": {
- "version": "8.56.2",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz",
- "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==",
+ "version": "8.56.9",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.9.tgz",
+ "integrity": "sha512-W4W3KcqzjJ0sHg2vAq9vfml6OhsJ53TcUjUqfzzZf/EChUtwspszj/S0pzMxnfRcO55/iGq47dscXw71Fxc4Zg==",
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -8860,9 +9009,9 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
},
"node_modules/@types/estree-jsx": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.4.tgz",
- "integrity": "sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz",
+ "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
"dependencies": {
"@types/estree": "*"
}
@@ -8889,9 +9038,9 @@
}
},
"node_modules/@types/express-serve-static-core": {
- "version": "4.17.43",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz",
- "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz",
+ "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==",
"dev": true,
"dependencies": {
"@types/node": "*",
@@ -8901,9 +9050,9 @@
}
},
"node_modules/@types/express-session": {
- "version": "1.17.10",
- "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.10.tgz",
- "integrity": "sha512-U32bC/s0ejXijw5MAzyaV4tuZopCh/K7fPoUDyNbsRXHvPSeymygYD1RFL99YOLhF5PNOkzswvOTRaVHdL1zMw==",
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.18.0.tgz",
+ "integrity": "sha512-27JdDRgor6PoYlURY+Y5kCakqp5ulC0kmf7y+QwaY+hv9jEFuQOThgkjyA53RP3jmKuBsH5GR6qEfFmvb8mwOA==",
"dev": true,
"dependencies": {
"@types/express": "*"
@@ -9009,6 +9158,27 @@
"@types/node": "*"
}
},
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w=="
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
"node_modules/@types/jquery": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.29.tgz",
@@ -9039,6 +9209,11 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
+ "node_modules/@types/katex": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
+ "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ=="
+ },
"node_modules/@types/keygrip": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz",
@@ -9055,15 +9230,15 @@
}
},
"node_modules/@types/lodash": {
- "version": "4.14.202",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz",
- "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==",
+ "version": "4.17.0",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz",
+ "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==",
"dev": true
},
"node_modules/@types/mapbox-gl": {
- "version": "2.7.21",
- "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-2.7.21.tgz",
- "integrity": "sha512-Dx9MuF2kKgT/N22LsMUB4b3acFZh9clVqz9zv1fomoiPoBrJolwYxpWA/9LPO/2N0xWbKi4V+pkjTaFkkx/4wA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.1.0.tgz",
+ "integrity": "sha512-hI6cQDjw1bkJw7MC/eHMqq5TWUamLwsujnUUeiIX2KDRjxRNSYMjnHz07+LATz9I9XIsKumOtUz4gRYnZOJ/FA==",
"dependencies": {
"@types/geojson": "*"
}
@@ -9100,9 +9275,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "20.11.20",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz",
- "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==",
+ "version": "20.12.7",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
+ "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -9211,14 +9386,14 @@
"integrity": "sha512-+gbBHbNCVGGYw1S9lAIIvrHW47UYOhMIFUsJcMkMrzy1Jf0vulBN3XQIjPgnoOXveMuHnF3b57fXROnY/Or7eg=="
},
"node_modules/@types/prop-types": {
- "version": "15.7.11",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
- "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
+ "version": "15.7.12",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
+ "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
},
"node_modules/@types/qs": {
- "version": "6.9.11",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz",
- "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==",
+ "version": "6.9.14",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz",
+ "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==",
"dev": true
},
"node_modules/@types/range-parser": {
@@ -9237,12 +9412,11 @@
}
},
"node_modules/@types/react": {
- "version": "18.2.57",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.57.tgz",
- "integrity": "sha512-ZvQsktJgSYrQiMirAN60y4O/LRevIV8hUzSOSNB6gfR3/o3wCBFQx3sPwIYtuDMeiVgsSS3UzCV26tEzgnfvQw==",
+ "version": "18.2.78",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.78.tgz",
+ "integrity": "sha512-qOwdPnnitQY4xKlKayt42q5W5UQrSHjgoXNVEtxeqdITJ99k4VXJOP3vt8Rkm9HmgJpH50UNU+rlqfkfWOqp0A==",
"dependencies": {
"@types/prop-types": "*",
- "@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
@@ -9256,9 +9430,9 @@
}
},
"node_modules/@types/react-color": {
- "version": "3.0.11",
- "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.11.tgz",
- "integrity": "sha512-20m5GpzmdqwmSdnPeMs4UPPUuvkS4ESwakL6u2YN1hbo+ajWiiTwGYIMGhdcJFGeoLyAsr7TVonbZrMhU3+pdw==",
+ "version": "3.0.12",
+ "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.12.tgz",
+ "integrity": "sha512-pr3uKE3lSvf7GFo1Rn2K3QktiZQFFrSgSGJ/3iMvSOYWt2pPAJ97rVdVfhWxYJZ8prAEXzoP2XX//3qGSQgu7Q==",
"dev": true,
"dependencies": {
"@types/react": "*",
@@ -9266,21 +9440,20 @@
}
},
"node_modules/@types/react-datepicker": {
- "version": "4.19.6",
- "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-4.19.6.tgz",
- "integrity": "sha512-uH5fzxt9eXxnc+hDCy/iRSFqU2+9lR/q2lAmaG4WILMai1o3IOdpcV+VSypzBFJLTEC2jrfeDXcdol0CJVMq4g==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-6.2.0.tgz",
+ "integrity": "sha512-+JtO4Fm97WLkJTH8j8/v3Ldh7JCNRwjMYjRaKh4KHH0M3jJoXtwiD3JBCsdlg3tsFIw9eQSqyAPeVDN2H2oM9Q==",
"dev": true,
"dependencies": {
- "@popperjs/core": "^2.9.2",
+ "@floating-ui/react": "^0.26.2",
"@types/react": "*",
- "date-fns": "^2.0.1",
- "react-popper": "^2.2.5"
+ "date-fns": "^3.3.1"
}
},
"node_modules/@types/react-dom": {
- "version": "18.2.19",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.19.tgz",
- "integrity": "sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==",
+ "version": "18.2.25",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz",
+ "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==",
"dev": true,
"dependencies": {
"@types/react": "*"
@@ -9322,9 +9495,9 @@
}
},
"node_modules/@types/reactcss": {
- "version": "1.2.11",
- "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.11.tgz",
- "integrity": "sha512-0fFy0ubuPlhksId8r9V8nsLcxBAPQnn15g/ERAElgE9L6rOquMj2CapsxqfyBuHlkp0/ndEUVnkYI7MkTtkGpw==",
+ "version": "1.2.12",
+ "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.12.tgz",
+ "integrity": "sha512-BrXUQ86/wbbFiZv8h/Q1/Q1XOsaHneYmCb/tHe9+M8XBAAUc2EHfdY0DY22ZZjVSaXr5ix7j+zsqO2eGZub8lQ==",
"dev": true,
"dependencies": {
"@types/react": "*"
@@ -9376,9 +9549,9 @@
}
},
"node_modules/@types/retry": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
- "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz",
+ "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==",
"dev": true
},
"node_modules/@types/reveal": {
@@ -9389,7 +9562,8 @@
"node_modules/@types/scheduler": {
"version": "0.16.8",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
- "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A=="
+ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
+ "optional": true
},
"node_modules/@types/send": {
"version": "0.17.4",
@@ -9411,14 +9585,14 @@
}
},
"node_modules/@types/serve-static": {
- "version": "1.15.5",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
- "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
+ "version": "1.15.7",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
+ "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
"dev": true,
"dependencies": {
"@types/http-errors": "*",
- "@types/mime": "*",
- "@types/node": "*"
+ "@types/node": "*",
+ "@types/send": "*"
}
},
"node_modules/@types/shelljs": {
@@ -9502,9 +9676,9 @@
"dev": true
},
"node_modules/@types/web": {
- "version": "0.0.138",
- "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.138.tgz",
- "integrity": "sha512-oQD74hl+cNCZdSWIupJCXZ2azTuB3MJ/mrWlgYt+v4pD7/Dr78gl5hKAdieZNf9NrAqwUez79bHtnFVSNSscWA=="
+ "version": "0.0.143",
+ "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.143.tgz",
+ "integrity": "sha512-TazK16/OqeeqfQRB/Tv/NwzJagHbLi/w5g26FLbiFte/8LpPq6BuTyXHO/cpgwJpE6KGgFSNYb6Ap05Tz9XvCA=="
},
"node_modules/@types/webidl-conversions": {
"version": "7.0.3",
@@ -9526,7 +9700,6 @@
"version": "2.25.9",
"resolved": "https://registry.npmjs.org/@types/webpack-hot-middleware/-/webpack-hot-middleware-2.25.9.tgz",
"integrity": "sha512-fad4T9VfocBjS2fZxlqkGoXoVUAjVp0EEnKBRqPwnhEEDN/FqJoFkSP5t9O1gPH75qsyG2kkT/GSUqSNTn1ZPg==",
- "dev": true,
"dependencies": {
"@types/connect": "*",
"tapable": "^2.2.0",
@@ -9550,72 +9723,290 @@
"@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==",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="
+ },
"node_modules/@types/youtube": {
"version": "0.0.50",
"resolved": "https://registry.npmjs.org/@types/youtube/-/youtube-0.0.50.tgz",
"integrity": "sha512-d4GpH4uPYp9W07kc487tiq6V/EUHl18vZWFMbQoe4Sk9LXEWzFi/BMf9x7TI4m7/j7gU3KeX8H6M8aPBgykeLw==",
"dev": true
},
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz",
+ "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "7.9.0",
+ "@typescript-eslint/type-utils": "7.9.0",
+ "@typescript-eslint/utils": "7.9.0",
+ "@typescript-eslint/visitor-keys": "7.9.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.3.1",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^7.0.0",
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz",
+ "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "7.9.0",
+ "@typescript-eslint/types": "7.9.0",
+ "@typescript-eslint/typescript-estree": "7.9.0",
+ "@typescript-eslint/visitor-keys": "7.9.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz",
+ "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==",
+ "dependencies": {
+ "@typescript-eslint/types": "7.9.0",
+ "@typescript-eslint/visitor-keys": "7.9.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz",
+ "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "7.9.0",
+ "@typescript-eslint/utils": "7.9.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz",
+ "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==",
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz",
+ "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==",
+ "dependencies": {
+ "@typescript-eslint/types": "7.9.0",
+ "@typescript-eslint/visitor-keys": "7.9.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz",
+ "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "7.9.0",
+ "@typescript-eslint/types": "7.9.0",
+ "@typescript-eslint/typescript-estree": "7.9.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz",
+ "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==",
+ "dependencies": {
+ "@typescript-eslint/types": "7.9.0",
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
},
"node_modules/@vue/compiler-core": {
- "version": "3.4.19",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz",
- "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==",
+ "version": "3.4.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
+ "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
"dependencies": {
"@babel/parser": "^7.23.9",
- "@vue/shared": "3.4.19",
+ "@vue/shared": "3.4.21",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-dom": {
- "version": "3.4.19",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz",
- "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==",
+ "version": "3.4.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
+ "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
"dependencies": {
- "@vue/compiler-core": "3.4.19",
- "@vue/shared": "3.4.19"
+ "@vue/compiler-core": "3.4.21",
+ "@vue/shared": "3.4.21"
}
},
"node_modules/@vue/compiler-sfc": {
- "version": "3.4.19",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz",
- "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==",
+ "version": "3.4.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
+ "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
"dependencies": {
"@babel/parser": "^7.23.9",
- "@vue/compiler-core": "3.4.19",
- "@vue/compiler-dom": "3.4.19",
- "@vue/compiler-ssr": "3.4.19",
- "@vue/shared": "3.4.19",
+ "@vue/compiler-core": "3.4.21",
+ "@vue/compiler-dom": "3.4.21",
+ "@vue/compiler-ssr": "3.4.21",
+ "@vue/shared": "3.4.21",
"estree-walker": "^2.0.2",
- "magic-string": "^0.30.6",
- "postcss": "^8.4.33",
+ "magic-string": "^0.30.7",
+ "postcss": "^8.4.35",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-ssr": {
- "version": "3.4.19",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz",
- "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==",
+ "version": "3.4.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
+ "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
"dependencies": {
- "@vue/compiler-dom": "3.4.19",
- "@vue/shared": "3.4.19"
+ "@vue/compiler-dom": "3.4.21",
+ "@vue/shared": "3.4.21"
}
},
"node_modules/@vue/shared": {
- "version": "3.4.19",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz",
- "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw=="
+ "version": "3.4.21",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
+ "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g=="
},
"node_modules/@webassemblyjs/ast": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
- "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
+ "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
"dependencies": {
"@webassemblyjs/helper-numbers": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6"
@@ -9632,9 +10023,9 @@
"integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q=="
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
- "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA=="
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
+ "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw=="
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.11.6",
@@ -9652,14 +10043,14 @@
"integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA=="
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
- "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
+ "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6"
+ "@webassemblyjs/wasm-gen": "1.12.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
@@ -9684,26 +10075,26 @@
"integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA=="
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
- "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
+ "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/helper-wasm-section": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-opt": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6",
- "@webassemblyjs/wast-printer": "1.11.6"
+ "@webassemblyjs/helper-wasm-section": "1.12.1",
+ "@webassemblyjs/wasm-gen": "1.12.1",
+ "@webassemblyjs/wasm-opt": "1.12.1",
+ "@webassemblyjs/wasm-parser": "1.12.1",
+ "@webassemblyjs/wast-printer": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
- "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
+ "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
"@webassemblyjs/leb128": "1.11.6",
@@ -9711,22 +10102,22 @@
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
- "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
+ "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6"
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
+ "@webassemblyjs/wasm-gen": "1.12.1",
+ "@webassemblyjs/wasm-parser": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
- "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
+ "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-api-error": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
@@ -9735,11 +10126,11 @@
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
- "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
+ "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@xtuc/long": "4.2.2"
}
},
@@ -9878,9 +10269,9 @@
}
},
"node_modules/adm-zip": {
- "version": "0.5.10",
- "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz",
- "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==",
+ "version": "0.5.12",
+ "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.12.tgz",
+ "integrity": "sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ==",
"engines": {
"node": ">=6.0"
}
@@ -10025,7 +10416,6 @@
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
"integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==",
- "dev": true,
"engines": [
"node >= 0.8.0"
],
@@ -10075,36 +10465,37 @@
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
},
"node_modules/archiver": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz",
- "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz",
+ "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==",
"dependencies": {
- "archiver-utils": "^4.0.1",
+ "archiver-utils": "^5.0.2",
"async": "^3.2.4",
- "buffer-crc32": "^0.2.1",
- "readable-stream": "^3.6.0",
+ "buffer-crc32": "^1.0.0",
+ "readable-stream": "^4.0.0",
"readdir-glob": "^1.1.2",
"tar-stream": "^3.0.0",
- "zip-stream": "^5.0.1"
+ "zip-stream": "^6.0.1"
},
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 14"
}
},
"node_modules/archiver-utils": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz",
- "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz",
+ "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==",
"dependencies": {
- "glob": "^8.0.0",
+ "glob": "^10.0.0",
"graceful-fs": "^4.2.0",
+ "is-stream": "^2.0.1",
"lazystream": "^1.0.0",
"lodash": "^4.17.15",
"normalize-path": "^3.0.0",
- "readable-stream": "^3.6.0"
+ "readable-stream": "^4.0.0"
},
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 14"
}
},
"node_modules/are-we-there-yet": {
@@ -10119,6 +10510,19 @@
"node": ">=10"
}
},
+ "node_modules/are-we-there-yet/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@@ -10191,15 +10595,16 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"node_modules/array-includes": {
- "version": "3.1.7",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz",
- "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==",
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
"is-string": "^1.0.7"
},
"engines": {
@@ -10217,17 +10622,18 @@
"node": ">=8"
}
},
- "node_modules/array.prototype.filter": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz",
- "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==",
+ "node_modules/array.prototype.findlast": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "es-array-method-boxes-properly": "^1.0.0",
- "is-string": "^1.0.7"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -10237,15 +10643,16 @@
}
},
"node_modules/array.prototype.findlastindex": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz",
- "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
+ "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.5",
+ "call-bind": "^1.0.7",
"define-properties": "^1.2.1",
- "es-abstract": "^1.22.3",
+ "es-abstract": "^1.23.2",
"es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
"es-shim-unscopables": "^1.0.2"
},
"engines": {
@@ -10291,6 +10698,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/array.prototype.toreversed": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz",
+ "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ }
+ },
"node_modules/array.prototype.tosorted": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz",
@@ -10408,15 +10827,6 @@
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
},
- "node_modules/asynciterator.prototype": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz",
- "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==",
- "dev": true,
- "dependencies": {
- "has-symbols": "^1.0.3"
- }
- },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -10459,11 +10869,11 @@
}
},
"node_modules/axios": {
- "version": "1.6.7",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
- "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
+ "version": "1.6.8",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
+ "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
"dependencies": {
- "follow-redirects": "^1.15.4",
+ "follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
@@ -10554,12 +10964,12 @@
}
},
"node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.8",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz",
- "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==",
+ "version": "0.4.10",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz",
+ "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==",
"dependencies": {
"@babel/compat-data": "^7.22.6",
- "@babel/helper-define-polyfill-provider": "^0.5.0",
+ "@babel/helper-define-polyfill-provider": "^0.6.1",
"semver": "^6.3.1"
},
"peerDependencies": {
@@ -10567,23 +10977,23 @@
}
},
"node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz",
- "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==",
+ "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==",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.5.0",
- "core-js-compat": "^3.34.0"
+ "@babel/helper-define-polyfill-provider": "^0.6.1",
+ "core-js-compat": "^3.36.1"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
"node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz",
- "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==",
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz",
+ "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.5.0"
+ "@babel/helper-define-polyfill-provider": "^0.6.1"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -10636,16 +11046,11 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/bare-events": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.0.tgz",
- "integrity": "sha512-Yyyqff4PIFfSuthCZqLlPISTWHmnQxoPuAvkmgzsJEmG3CesdIv6Xweayl0JkCZJSB2yYIdJyEz97tpxNhgjbg==",
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz",
+ "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==",
"optional": true
},
- "node_modules/base-64": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
- "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
- },
"node_modules/Base64": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/Base64/-/Base64-0.2.1.tgz",
@@ -10707,9 +11112,20 @@
}
},
"node_modules/before-after-hook": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
- "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
+ "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="
+ },
+ "node_modules/better-react-mathjax": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/better-react-mathjax/-/better-react-mathjax-2.0.3.tgz",
+ "integrity": "sha512-wfifT8GFOKb1TWm2+E50I6DJpLZ5kLbch283Lu043EJtwSv0XvZDjr4YfR4d2MjAhqP6SH4VjjrKgbX8R00oCQ==",
+ "dependencies": {
+ "mathjax-full": "^3.2.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
},
"node_modules/bezier-curve": {
"version": "1.0.0",
@@ -10742,11 +11158,14 @@
}
},
"node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"engines": {
"node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/bingmaps-react": {
@@ -10886,9 +11305,9 @@
}
},
"node_modules/browndash-components/node_modules/npm": {
- "version": "9.9.2",
- "resolved": "https://registry.npmjs.org/npm/-/npm-9.9.2.tgz",
- "integrity": "sha512-D3tV+W0PzJOlwo8YmO6fNzaB1CrMVYd1V+2TURF6lbCbmZKqMsYgeQfPVvqiM3zbNSJPhFEnmlEXIogH2Vq7PQ==",
+ "version": "9.9.3",
+ "resolved": "https://registry.npmjs.org/npm/-/npm-9.9.3.tgz",
+ "integrity": "sha512-Z1l+rcQ5kYb17F3hHtO601arEpvdRYnCLtg8xo3AGtyj3IthwaraEOexI9903uANkifFbqHC8hT53KIrozWg8A==",
"bundleDependencies": [
"@isaacs/string-locale-compare",
"@npmcli/arborist",
@@ -10972,21 +11391,21 @@
"@npmcli/run-script": "^6.0.2",
"abbrev": "^2.0.0",
"archy": "~1.0.0",
- "cacache": "^17.1.3",
+ "cacache": "^17.1.4",
"chalk": "^5.3.0",
- "ci-info": "^3.8.0",
+ "ci-info": "^4.0.0",
"cli-columns": "^4.0.0",
"cli-table3": "^0.6.3",
"columnify": "^1.6.0",
"fastest-levenshtein": "^1.0.16",
- "fs-minipass": "^3.0.2",
- "glob": "^10.2.7",
+ "fs-minipass": "^3.0.3",
+ "glob": "^10.3.10",
"graceful-fs": "^4.2.11",
"hosted-git-info": "^6.1.1",
"ini": "^4.1.1",
"init-package-json": "^5.0.0",
"is-cidr": "^4.0.2",
- "json-parse-even-better-errors": "^3.0.0",
+ "json-parse-even-better-errors": "^3.0.1",
"libnpmaccess": "^7.0.2",
"libnpmdiff": "^5.0.20",
"libnpmexec": "^6.0.4",
@@ -11000,14 +11419,14 @@
"libnpmversion": "^4.0.2",
"make-fetch-happen": "^11.1.1",
"minimatch": "^9.0.3",
- "minipass": "^5.0.0",
+ "minipass": "^7.0.4",
"minipass-pipeline": "^1.2.4",
"ms": "^2.1.2",
- "node-gyp": "^9.4.0",
+ "node-gyp": "^9.4.1",
"nopt": "^7.2.0",
"normalize-package-data": "^5.0.0",
"npm-audit-report": "^5.0.0",
- "npm-install-checks": "^6.2.0",
+ "npm-install-checks": "^6.3.0",
"npm-package-arg": "^10.1.0",
"npm-pick-manifest": "^8.0.2",
"npm-profile": "^7.0.1",
@@ -11020,12 +11439,12 @@
"proc-log": "^3.0.0",
"qrcode-terminal": "^0.12.0",
"read": "^2.1.0",
- "semver": "^7.5.4",
+ "semver": "^7.6.0",
"sigstore": "^1.9.0",
"spdx-expression-parse": "^3.0.1",
- "ssri": "^10.0.4",
+ "ssri": "^10.0.5",
"supports-color": "^9.4.0",
- "tar": "^6.1.15",
+ "tar": "^6.2.0",
"text-table": "~0.2.0",
"tiny-relative-date": "^1.3.0",
"treeverse": "^3.0.0",
@@ -11050,6 +11469,11 @@
"node": ">=0.1.90"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/@gar/promisify": {
+ "version": "1.1.3",
+ "inBundle": true,
+ "license": "MIT"
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/@isaacs/cliui": {
"version": "8.0.2",
"inBundle": true,
@@ -11118,7 +11542,7 @@
"license": "ISC"
},
"node_modules/browndash-components/node_modules/npm/node_modules/@npmcli/arborist": {
- "version": "6.5.0",
+ "version": "6.5.1",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -11130,7 +11554,7 @@
"@npmcli/name-from-folder": "^2.0.0",
"@npmcli/node-gyp": "^3.0.0",
"@npmcli/package-json": "^4.0.0",
- "@npmcli/query": "^3.0.0",
+ "@npmcli/query": "^3.1.0",
"@npmcli/run-script": "^6.0.0",
"bin-links": "^4.0.1",
"cacache": "^17.0.4",
@@ -11164,12 +11588,12 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/@npmcli/config": {
- "version": "6.4.0",
+ "version": "6.4.1",
"inBundle": true,
"license": "ISC",
"dependencies": {
"@npmcli/map-workspaces": "^3.0.2",
- "ci-info": "^3.8.0",
+ "ci-info": "^4.0.0",
"ini": "^4.1.0",
"nopt": "^7.0.0",
"proc-log": "^3.0.0",
@@ -11264,6 +11688,18 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/@npmcli/move-file": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "mkdirp": "^1.0.4",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/@npmcli/name-from-folder": {
"version": "2.0.0",
"inBundle": true,
@@ -11309,7 +11745,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/@npmcli/query": {
- "version": "3.0.0",
+ "version": "3.1.0",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -11423,17 +11859,6 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "node_modules/browndash-components/node_modules/npm/node_modules/abort-controller": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "event-target-shim": "^5.0.0"
- },
- "engines": {
- "node": ">=6.5"
- }
- },
"node_modules/browndash-components/node_modules/npm/node_modules/agent-base": {
"version": "6.0.2",
"inBundle": true,
@@ -11446,12 +11871,10 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/agentkeepalive": {
- "version": "4.3.0",
+ "version": "4.5.0",
"inBundle": true,
"license": "MIT",
"dependencies": {
- "debug": "^4.1.0",
- "depd": "^2.0.0",
"humanize-ms": "^1.2.1"
},
"engines": {
@@ -11503,13 +11926,9 @@
"license": "MIT"
},
"node_modules/browndash-components/node_modules/npm/node_modules/are-we-there-yet": {
- "version": "4.0.0",
+ "version": "4.0.2",
"inBundle": true,
"license": "ISC",
- "dependencies": {
- "delegates": "^1.0.0",
- "readable-stream": "^4.1.0"
- },
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
@@ -11519,27 +11938,8 @@
"inBundle": true,
"license": "MIT"
},
- "node_modules/browndash-components/node_modules/npm/node_modules/base64-js": {
- "version": "1.5.1",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "inBundle": true,
- "license": "MIT"
- },
"node_modules/browndash-components/node_modules/npm/node_modules/bin-links": {
- "version": "4.0.2",
+ "version": "4.0.3",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -11568,29 +11968,6 @@
"balanced-match": "^1.0.0"
}
},
- "node_modules/browndash-components/node_modules/npm/node_modules/buffer": {
- "version": "6.0.3",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.2.1"
- }
- },
"node_modules/browndash-components/node_modules/npm/node_modules/builtins": {
"version": "5.0.1",
"inBundle": true,
@@ -11600,7 +11977,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/cacache": {
- "version": "17.1.3",
+ "version": "17.1.4",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -11608,7 +11985,7 @@
"fs-minipass": "^3.0.0",
"glob": "^10.2.2",
"lru-cache": "^7.7.1",
- "minipass": "^5.0.0",
+ "minipass": "^7.0.3",
"minipass-collect": "^1.0.2",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.4",
@@ -11641,7 +12018,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/ci-info": {
- "version": "3.8.0",
+ "version": "4.0.0",
"funding": [
{
"type": "github",
@@ -11708,7 +12085,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/cmd-shim": {
- "version": "6.0.1",
+ "version": "6.0.2",
"inBundle": true,
"license": "ISC",
"engines": {
@@ -11841,16 +12218,8 @@
"inBundle": true,
"license": "MIT"
},
- "node_modules/browndash-components/node_modules/npm/node_modules/depd": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/browndash-components/node_modules/npm/node_modules/diff": {
- "version": "5.1.0",
+ "version": "5.2.0",
"inBundle": true,
"license": "BSD-3-Clause",
"engines": {
@@ -11889,22 +12258,6 @@
"inBundle": true,
"license": "MIT"
},
- "node_modules/browndash-components/node_modules/npm/node_modules/event-target-shim": {
- "version": "5.0.1",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/browndash-components/node_modules/npm/node_modules/events": {
- "version": "3.3.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.x"
- }
- },
"node_modules/browndash-components/node_modules/npm/node_modules/exponential-backoff": {
"version": "3.1.1",
"inBundle": true,
@@ -11934,11 +12287,11 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/fs-minipass": {
- "version": "3.0.2",
+ "version": "3.0.3",
"inBundle": true,
"license": "ISC",
"dependencies": {
- "minipass": "^5.0.0"
+ "minipass": "^7.0.3"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
@@ -11950,9 +12303,12 @@
"license": "ISC"
},
"node_modules/browndash-components/node_modules/npm/node_modules/function-bind": {
- "version": "1.1.1",
+ "version": "1.1.2",
"inBundle": true,
- "license": "MIT"
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/browndash-components/node_modules/npm/node_modules/gauge": {
"version": "5.0.1",
@@ -11973,18 +12329,18 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/glob": {
- "version": "10.2.7",
+ "version": "10.3.10",
"inBundle": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
- "jackspeak": "^2.0.3",
+ "jackspeak": "^2.3.5",
"minimatch": "^9.0.1",
- "minipass": "^5.0.0 || ^6.0.2",
- "path-scurry": "^1.7.0"
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+ "path-scurry": "^1.10.1"
},
"bin": {
- "glob": "dist/cjs/src/bin.js"
+ "glob": "dist/esm/bin.mjs"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -11998,22 +12354,22 @@
"inBundle": true,
"license": "ISC"
},
- "node_modules/browndash-components/node_modules/npm/node_modules/has": {
- "version": "1.0.3",
+ "node_modules/browndash-components/node_modules/npm/node_modules/has-unicode": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/hasown": {
+ "version": "2.0.1",
"inBundle": true,
"license": "MIT",
"dependencies": {
- "function-bind": "^1.1.1"
+ "function-bind": "^1.1.2"
},
"engines": {
- "node": ">= 0.4.0"
+ "node": ">= 0.4"
}
},
- "node_modules/browndash-components/node_modules/npm/node_modules/has-unicode": {
- "version": "2.0.1",
- "inBundle": true,
- "license": "ISC"
- },
"node_modules/browndash-components/node_modules/npm/node_modules/hosted-git-info": {
"version": "6.1.1",
"inBundle": true,
@@ -12075,27 +12431,8 @@
"node": ">=0.10.0"
}
},
- "node_modules/browndash-components/node_modules/npm/node_modules/ieee754": {
- "version": "1.2.1",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "inBundle": true,
- "license": "BSD-3-Clause"
- },
"node_modules/browndash-components/node_modules/npm/node_modules/ignore-walk": {
- "version": "6.0.3",
+ "version": "6.0.4",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12121,6 +12458,11 @@
"node": ">=8"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/infer-owner": {
+ "version": "1.0.4",
+ "inBundle": true,
+ "license": "ISC"
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/inflight": {
"version": "1.0.6",
"inBundle": true,
@@ -12160,10 +12502,22 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "node_modules/browndash-components/node_modules/npm/node_modules/ip": {
- "version": "2.0.0",
+ "node_modules/browndash-components/node_modules/npm/node_modules/ip-address": {
+ "version": "9.0.5",
"inBundle": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/ip-address/node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "inBundle": true,
+ "license": "BSD-3-Clause"
},
"node_modules/browndash-components/node_modules/npm/node_modules/ip-regex": {
"version": "4.3.0",
@@ -12185,11 +12539,11 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/is-core-module": {
- "version": "2.13.0",
+ "version": "2.13.1",
"inBundle": true,
"license": "MIT",
"dependencies": {
- "has": "^1.0.3"
+ "hasown": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -12214,7 +12568,7 @@
"license": "ISC"
},
"node_modules/browndash-components/node_modules/npm/node_modules/jackspeak": {
- "version": "2.2.1",
+ "version": "2.3.6",
"inBundle": true,
"license": "BlueOak-1.0.0",
"dependencies": {
@@ -12230,8 +12584,13 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/jsbn": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/json-parse-even-better-errors": {
- "version": "3.0.0",
+ "version": "3.0.1",
"inBundle": true,
"license": "MIT",
"engines": {
@@ -12265,7 +12624,7 @@
"license": "MIT"
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmaccess": {
- "version": "7.0.2",
+ "version": "7.0.3",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12277,7 +12636,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmdiff": {
- "version": "5.0.20",
+ "version": "5.0.21",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12296,13 +12655,13 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmexec": {
- "version": "6.0.4",
+ "version": "6.0.5",
"inBundle": true,
"license": "ISC",
"dependencies": {
"@npmcli/arborist": "^6.5.0",
"@npmcli/run-script": "^6.0.0",
- "ci-info": "^3.7.1",
+ "ci-info": "^4.0.0",
"npm-package-arg": "^10.1.0",
"npmlog": "^7.0.1",
"pacote": "^15.0.8",
@@ -12317,7 +12676,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmfund": {
- "version": "4.2.1",
+ "version": "4.2.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12328,7 +12687,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmhook": {
- "version": "9.0.3",
+ "version": "9.0.4",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12340,7 +12699,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmorg": {
- "version": "5.0.4",
+ "version": "5.0.5",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12352,7 +12711,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmpack": {
- "version": "5.0.20",
+ "version": "5.0.21",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12366,11 +12725,11 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmpublish": {
- "version": "7.5.1",
+ "version": "7.5.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
- "ci-info": "^3.6.1",
+ "ci-info": "^4.0.0",
"normalize-package-data": "^5.0.0",
"npm-package-arg": "^10.1.0",
"npm-registry-fetch": "^14.0.3",
@@ -12384,7 +12743,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmsearch": {
- "version": "6.0.2",
+ "version": "6.0.3",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12395,7 +12754,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmteam": {
- "version": "5.0.3",
+ "version": "5.0.4",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12407,7 +12766,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/libnpmversion": {
- "version": "4.0.2",
+ "version": "4.0.3",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -12454,6 +12813,14 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/make-fetch-happen/node_modules/minipass": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/minimatch": {
"version": "9.0.3",
"inBundle": true,
@@ -12469,11 +12836,11 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/minipass": {
- "version": "5.0.0",
+ "version": "7.0.4",
"inBundle": true,
"license": "ISC",
"engines": {
- "node": ">=8"
+ "node": ">=16 || 14 >=14.17"
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/minipass-collect": {
@@ -12499,11 +12866,11 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/minipass-fetch": {
- "version": "3.0.3",
+ "version": "3.0.4",
"inBundle": true,
"license": "MIT",
"dependencies": {
- "minipass": "^5.0.0",
+ "minipass": "^7.0.3",
"minipass-sized": "^1.0.3",
"minizlib": "^2.1.2"
},
@@ -12656,7 +13023,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/node-gyp": {
- "version": "9.4.0",
+ "version": "9.4.1",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -12664,7 +13031,7 @@
"exponential-backoff": "^3.1.1",
"glob": "^7.1.4",
"graceful-fs": "^4.2.6",
- "make-fetch-happen": "^11.0.3",
+ "make-fetch-happen": "^10.0.3",
"nopt": "^6.0.0",
"npmlog": "^6.0.0",
"rimraf": "^3.0.2",
@@ -12679,6 +13046,18 @@
"node": "^12.13 || ^14.13 || >=16"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/fs": {
+ "version": "2.1.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@gar/promisify": "^1.1.3",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/abbrev": {
"version": "1.1.1",
"inBundle": true,
@@ -12705,6 +13084,82 @@
"concat-map": "0.0.1"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/cacache": {
+ "version": "16.1.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/fs": "^2.1.0",
+ "@npmcli/move-file": "^2.0.0",
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.1.0",
+ "glob": "^8.0.1",
+ "infer-owner": "^1.0.4",
+ "lru-cache": "^7.7.1",
+ "minipass": "^3.1.6",
+ "minipass-collect": "^1.0.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "mkdirp": "^1.0.4",
+ "p-map": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^3.0.2",
+ "ssri": "^9.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^2.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/cacache/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/cacache/node_modules/glob": {
+ "version": "8.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch": {
+ "version": "5.1.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/gauge": {
"version": "4.0.4",
"inBundle": true,
@@ -12742,6 +13197,32 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/make-fetch-happen": {
+ "version": "10.2.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "agentkeepalive": "^4.2.1",
+ "cacache": "^16.1.0",
+ "http-cache-semantics": "^4.1.0",
+ "http-proxy-agent": "^5.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "is-lambda": "^1.0.1",
+ "lru-cache": "^7.7.1",
+ "minipass": "^3.1.6",
+ "minipass-collect": "^1.0.2",
+ "minipass-fetch": "^2.0.3",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "promise-retry": "^2.0.1",
+ "socks-proxy-agent": "^7.0.0",
+ "ssri": "^9.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/minimatch": {
"version": "3.1.2",
"inBundle": true,
@@ -12753,6 +13234,33 @@
"node": "*"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/minipass-fetch": {
+ "version": "2.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^3.1.6",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/nopt": {
"version": "6.0.0",
"inBundle": true,
@@ -12781,23 +13289,43 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
- "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/readable-stream": {
- "version": "3.6.2",
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/signal-exit": {
+ "version": "3.0.7",
"inBundle": true,
- "license": "MIT",
+ "license": "ISC"
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/ssri": {
+ "version": "9.0.1",
+ "inBundle": true,
+ "license": "ISC",
"dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
+ "minipass": "^3.1.1"
},
"engines": {
- "node": ">= 6"
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
- "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/signal-exit": {
- "version": "3.0.7",
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/unique-filename": {
+ "version": "2.0.1",
"inBundle": true,
- "license": "ISC"
+ "license": "ISC",
+ "dependencies": {
+ "unique-slug": "^3.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/unique-slug": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
},
"node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/which": {
"version": "2.0.2",
@@ -12861,7 +13389,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/npm-install-checks": {
- "version": "6.2.0",
+ "version": "6.3.0",
"inBundle": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -12947,6 +13475,14 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/npm-registry-fetch/node_modules/minipass": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/npm-user-validate": {
"version": "2.0.0",
"inBundle": true,
@@ -13022,6 +13558,14 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/pacote/node_modules/minipass": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/parse-conflict-json": {
"version": "3.0.1",
"inBundle": true,
@@ -13052,12 +13596,12 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/path-scurry": {
- "version": "1.9.2",
+ "version": "1.10.1",
"inBundle": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "lru-cache": "^9.1.1",
- "minipass": "^5.0.0 || ^6.0.2"
+ "lru-cache": "^9.1.1 || ^10.0.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -13067,7 +13611,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/path-scurry/node_modules/lru-cache": {
- "version": "9.1.1",
+ "version": "10.2.0",
"inBundle": true,
"license": "ISC",
"engines": {
@@ -13075,7 +13619,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/postcss-selector-parser": {
- "version": "6.0.13",
+ "version": "6.0.15",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -13094,14 +13638,6 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "node_modules/browndash-components/node_modules/npm/node_modules/process": {
- "version": "0.11.10",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6.0"
- }
- },
"node_modules/browndash-components/node_modules/npm/node_modules/promise-all-reject-late": {
"version": "1.0.1",
"inBundle": true,
@@ -13199,17 +13735,16 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/readable-stream": {
- "version": "4.4.0",
+ "version": "3.6.2",
"inBundle": true,
"license": "MIT",
"dependencies": {
- "abort-controller": "^3.0.0",
- "buffer": "^6.0.3",
- "events": "^3.3.0",
- "process": "^0.11.10"
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": ">= 6"
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/retry": {
@@ -13299,7 +13834,7 @@
"optional": true
},
"node_modules/browndash-components/node_modules/npm/node_modules/semver": {
- "version": "7.5.4",
+ "version": "7.6.0",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -13348,7 +13883,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/signal-exit": {
- "version": "4.0.2",
+ "version": "4.1.0",
"inBundle": true,
"license": "ISC",
"engines": {
@@ -13386,15 +13921,15 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/socks": {
- "version": "2.7.1",
+ "version": "2.8.1",
"inBundle": true,
"license": "MIT",
"dependencies": {
- "ip": "^2.0.0",
+ "ip-address": "^9.0.5",
"smart-buffer": "^4.2.0"
},
"engines": {
- "node": ">= 10.13.0",
+ "node": ">= 10.0.0",
"npm": ">= 3.0.0"
}
},
@@ -13421,7 +13956,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/spdx-exceptions": {
- "version": "2.3.0",
+ "version": "2.5.0",
"inBundle": true,
"license": "CC-BY-3.0"
},
@@ -13435,16 +13970,16 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/spdx-license-ids": {
- "version": "3.0.13",
+ "version": "3.0.17",
"inBundle": true,
"license": "CC0-1.0"
},
"node_modules/browndash-components/node_modules/npm/node_modules/ssri": {
- "version": "10.0.4",
+ "version": "10.0.5",
"inBundle": true,
"license": "ISC",
"dependencies": {
- "minipass": "^5.0.0"
+ "minipass": "^7.0.3"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
@@ -13520,7 +14055,7 @@
}
},
"node_modules/browndash-components/node_modules/npm/node_modules/tar": {
- "version": "6.1.15",
+ "version": "6.2.0",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -13557,6 +14092,14 @@
"node": ">=8"
}
},
+ "node_modules/browndash-components/node_modules/npm/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/browndash-components/node_modules/npm/node_modules/text-table": {
"version": "0.2.0",
"inBundle": true,
@@ -13833,9 +14376,9 @@
}
},
"node_modules/bson": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz",
- "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==",
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.6.0.tgz",
+ "integrity": "sha512-BVINv2SgcMjL4oYbBuCQTpE3/VKOSxrOA8Cj/wQP7izSzlBGVomdm+TcUd0Pzy0ytLSSDweCKQ6X3f5veM5LQA==",
"engines": {
"node": ">=16.20.1"
}
@@ -13864,11 +14407,11 @@
}
},
"node_modules/buffer-crc32": {
- "version": "0.2.13",
- "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz",
+ "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==",
"engines": {
- "node": "*"
+ "node": ">=8.0.0"
}
},
"node_modules/buffer-equal": {
@@ -13905,6 +14448,21 @@
"node": ">=0.10.0"
}
},
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -14029,9 +14587,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001589",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz",
- "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==",
+ "version": "1.0.30001610",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz",
+ "integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==",
"funding": [
{
"type": "opencollective",
@@ -14162,23 +14720,15 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
- "node_modules/charenc": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
- "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
- "engines": {
- "node": "*"
- }
- },
"node_modules/chart.js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz",
- "integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==",
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
+ "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
"dependencies": {
"@kurkle/color": "^0.3.0"
},
"engines": {
- "pnpm": ">=7"
+ "pnpm": ">=8"
}
},
"node_modules/cheap-ruler": {
@@ -14250,6 +14800,20 @@
"node": ">=6.0"
}
},
+ "node_modules/ci-info": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/class-transformer": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
@@ -14373,6 +14937,70 @@
"wrap-ansi": "^7.0.0"
}
},
+ "node_modules/cliui/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/cliui/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/cliui/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
"node_modules/clj-fuzzy": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/clj-fuzzy/-/clj-fuzzy-0.3.3.tgz",
@@ -14519,17 +15147,18 @@
"integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w=="
},
"node_modules/compress-commons": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz",
- "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz",
+ "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==",
"dependencies": {
"crc-32": "^1.2.0",
- "crc32-stream": "^5.0.0",
+ "crc32-stream": "^6.0.0",
+ "is-stream": "^2.0.1",
"normalize-path": "^3.0.0",
- "readable-stream": "^3.6.0"
+ "readable-stream": "^4.0.0"
},
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 14"
}
},
"node_modules/compressible": {
@@ -14754,9 +15383,9 @@
}
},
"node_modules/core-js": {
- "version": "3.36.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz",
- "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==",
+ "version": "3.36.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz",
+ "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
@@ -14764,11 +15393,11 @@
}
},
"node_modules/core-js-compat": {
- "version": "3.36.0",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz",
- "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==",
+ "version": "3.36.1",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz",
+ "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==",
"dependencies": {
- "browserslist": "^4.22.3"
+ "browserslist": "^4.23.0"
},
"funding": {
"type": "opencollective",
@@ -14776,9 +15405,9 @@
}
},
"node_modules/core-js-pure": {
- "version": "3.36.0",
- "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.0.tgz",
- "integrity": "sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==",
+ "version": "3.36.1",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.1.tgz",
+ "integrity": "sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
@@ -14802,6 +15431,14 @@
"node": ">= 0.10"
}
},
+ "node_modules/cose-base": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz",
+ "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==",
+ "dependencies": {
+ "layout-base": "^1.0.0"
+ }
+ },
"node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
@@ -14829,15 +15466,15 @@
}
},
"node_modules/crc32-stream": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz",
- "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz",
+ "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==",
"dependencies": {
"crc-32": "^1.2.0",
- "readable-stream": "^3.4.0"
+ "readable-stream": "^4.0.0"
},
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 14"
}
},
"node_modules/create-require": {
@@ -14885,14 +15522,6 @@
"node": ">= 8"
}
},
- "node_modules/crypt": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
- "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
- "engines": {
- "node": "*"
- }
- },
"node_modules/css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
@@ -14902,21 +15531,21 @@
}
},
"node_modules/css-loader": {
- "version": "6.10.0",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz",
- "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.1.tgz",
+ "integrity": "sha512-OxIR5P2mjO1PSXk44bWuQ8XtMK4dpEqpIyERCx3ewOo3I8EmbcxMPUc5ScLtQfgXtOojoMv57So4V/C02HQLsw==",
"dependencies": {
"icss-utils": "^5.1.0",
"postcss": "^8.4.33",
- "postcss-modules-extract-imports": "^3.0.0",
- "postcss-modules-local-by-default": "^4.0.4",
- "postcss-modules-scope": "^3.1.1",
+ "postcss-modules-extract-imports": "^3.1.0",
+ "postcss-modules-local-by-default": "^4.0.5",
+ "postcss-modules-scope": "^3.2.0",
"postcss-modules-values": "^4.0.0",
"postcss-value-parser": "^4.2.0",
"semver": "^7.5.4"
},
"engines": {
- "node": ">= 12.13.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
@@ -14924,7 +15553,7 @@
},
"peerDependencies": {
"@rspack/core": "0.x || 1.x",
- "webpack": "^5.0.0"
+ "webpack": "^5.27.0"
},
"peerDependenciesMeta": {
"@rspack/core": {
@@ -15097,15 +15726,65 @@
}
},
"node_modules/csv-stringify": {
- "version": "6.4.5",
- "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.4.5.tgz",
- "integrity": "sha512-SPu1Vnh8U5EnzpNOi1NDBL5jU5Rx7DVHr15DNg9LXDTAbQlAVAmEbVt16wZvEW9Fu9Qt4Ji8kmeCJ2B1+4rFTQ=="
+ "version": "6.4.6",
+ "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.4.6.tgz",
+ "integrity": "sha512-h2V2XZ3uOTLilF5dPIptgUfN/o2ia/80Ie0Lly18LAnw5s8Eb7kt8rfxSUy24AztJZas9f6DPZpVlzDUtFt/ag=="
+ },
+ "node_modules/csvtojson": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/csvtojson/-/csvtojson-2.0.10.tgz",
+ "integrity": "sha512-lUWFxGKyhraKCW8Qghz6Z0f2l/PqB1W3AO0HKJzGIQ5JRSlR651ekJDiGJbBT4sRNNv5ddnSGVEnsxP9XRCVpQ==",
+ "dependencies": {
+ "bluebird": "^3.5.1",
+ "lodash": "^4.17.3",
+ "strip-bom": "^2.0.0"
+ },
+ "bin": {
+ "csvtojson": "bin/csvtojson"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/csvtojson/node_modules/strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==",
+ "dependencies": {
+ "is-utf8": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
"node_modules/custom-event": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
"integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg=="
},
+ "node_modules/cytoscape": {
+ "version": "3.28.1",
+ "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.28.1.tgz",
+ "integrity": "sha512-xyItz4O/4zp9/239wCcH8ZcFuuZooEeF8KHRmzjDfGdXsj3OG9MFSMA0pJE0uX3uCN/ygof6hHf4L7lst+JaDg==",
+ "dependencies": {
+ "heap": "^0.2.6",
+ "lodash": "^4.17.21"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/cytoscape-cose-bilkent": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz",
+ "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==",
+ "dependencies": {
+ "cose-base": "^1.0.0"
+ },
+ "peerDependencies": {
+ "cytoscape": "^3.2.0"
+ }
+ },
"node_modules/D": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/D/-/D-1.0.0.tgz",
@@ -15113,9 +15792,9 @@
"deprecated": "Package no longer supported. Contact support@npmjs.com for more info."
},
"node_modules/d3": {
- "version": "7.8.5",
- "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
- "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz",
+ "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==",
"dependencies": {
"d3-array": "3",
"d3-axis": "3",
@@ -15386,6 +16065,41 @@
"node": ">=12"
}
},
+ "node_modules/d3-sankey": {
+ "version": "0.12.3",
+ "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz",
+ "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==",
+ "dependencies": {
+ "d3-array": "1 - 2",
+ "d3-shape": "^1.2.0"
+ }
+ },
+ "node_modules/d3-sankey/node_modules/d3-array": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+ "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+ "dependencies": {
+ "internmap": "^1.0.0"
+ }
+ },
+ "node_modules/d3-sankey/node_modules/d3-path": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
+ "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
+ },
+ "node_modules/d3-sankey/node_modules/d3-shape": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+ "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+ "dependencies": {
+ "d3-path": "1"
+ }
+ },
+ "node_modules/d3-sankey/node_modules/internmap": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
+ "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
+ },
"node_modules/d3-scale": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
@@ -15402,9 +16116,9 @@
}
},
"node_modules/d3-scale-chromatic": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
- "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
+ "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==",
"dependencies": {
"d3-color": "1 - 3",
"d3-interpolate": "1 - 3"
@@ -15501,9 +16215,9 @@
}
},
"node_modules/d3/node_modules/d3-geo": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz",
- "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz",
+ "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==",
"dependencies": {
"d3-array": "2.5.0 - 3"
},
@@ -15511,6 +16225,15 @@
"node": ">=12"
}
},
+ "node_modules/dagre-d3-es": {
+ "version": "7.0.10",
+ "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz",
+ "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==",
+ "dependencies": {
+ "d3": "^7.8.2",
+ "lodash-es": "^4.17.21"
+ }
+ },
"node_modules/damerau-levenshtein": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -15549,22 +16272,71 @@
"node": ">=18"
}
},
- "node_modules/date-fns": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
- "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+ "node_modules/data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
"dev": true,
"dependencies": {
- "@babel/runtime": "^7.21.0"
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
},
"engines": {
- "node": ">=0.11"
+ "node": ">= 0.4"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/date-fns"
+ "url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/date-fns": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
+ "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/kossnocorp"
+ }
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
+ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -15688,8 +16460,7 @@
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
},
"node_modules/deepmerge": {
"version": "4.3.1",
@@ -15699,6 +16470,34 @@
"node": ">=0.10.0"
}
},
+ "node_modules/default-browser": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
+ "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
+ "dev": true,
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
+ "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/default-gateway": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
@@ -15736,12 +16535,15 @@
}
},
"node_modules/define-lazy-prop": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
- "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
"dev": true,
"engines": {
- "node": ">=8"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/define-properties": {
@@ -15865,11 +16667,6 @@
"node": ">= 0.8"
}
},
- "node_modules/deprecation": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
- "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
- },
"node_modules/deps-regex": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.2.0.tgz",
@@ -15901,9 +16698,9 @@
}
},
"node_modules/detect-libc": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
- "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"engines": {
"node": ">=8"
}
@@ -15939,18 +16736,19 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
- "dev": true,
"engines": {
"node": ">=0.3.1"
}
},
- "node_modules/digest-fetch": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz",
- "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==",
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dependencies": {
- "base-64": "^0.1.0",
- "md5": "^2.3.0"
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/dns-packet": {
@@ -15969,7 +16767,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
"dependencies": {
"esutils": "^2.0.2"
},
@@ -16042,6 +16839,11 @@
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
+ "node_modules/dompurify": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.9.tgz",
+ "integrity": "sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ=="
+ },
"node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
@@ -16068,7 +16870,6 @@
"version": "16.4.5",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
- "dev": true,
"engines": {
"node": ">=12"
},
@@ -16123,9 +16924,14 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"node_modules/electron-to-chromium": {
- "version": "1.4.680",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.680.tgz",
- "integrity": "sha512-4nToZ5jlPO14W82NkF32wyjhYqQByVaDmLy4J2/tYcAbJfgO2TKJC780Az1V13gzq4l73CJ0yuyalpXvxXXD9A=="
+ "version": "1.4.736",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz",
+ "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q=="
+ },
+ "node_modules/elkjs": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.2.tgz",
+ "integrity": "sha512-2Y/RaA1pdgSHpY0YG4TYuYCD2wh97CRvu22eLG3Kz0pgQ/6KbIFTxsTnDc4MH/6hFlg2L/9qXrDMG0nMjP63iw=="
},
"node_modules/emoji-regex": {
"version": "9.2.2",
@@ -16229,9 +17035,9 @@
}
},
"node_modules/enhanced-resolve": {
- "version": "5.15.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
- "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+ "version": "5.16.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz",
+ "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@@ -16252,9 +17058,9 @@
}
},
"node_modules/envinfo": {
- "version": "7.11.1",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz",
- "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==",
+ "version": "7.12.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz",
+ "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==",
"bin": {
"envinfo": "dist/cli.js"
},
@@ -16271,18 +17077,22 @@
}
},
"node_modules/es-abstract": {
- "version": "1.22.4",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz",
- "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==",
+ "version": "1.23.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
+ "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
"dev": true,
"dependencies": {
"array-buffer-byte-length": "^1.0.1",
"arraybuffer.prototype.slice": "^1.0.3",
- "available-typed-arrays": "^1.0.6",
+ "available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
- "es-set-tostringtag": "^2.0.2",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
"es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.6",
"get-intrinsic": "^1.2.4",
@@ -16290,15 +17100,16 @@
"globalthis": "^1.0.3",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2",
- "has-proto": "^1.0.1",
+ "has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
- "hasown": "^2.0.1",
+ "hasown": "^2.0.2",
"internal-slot": "^1.0.7",
"is-array-buffer": "^3.0.4",
"is-callable": "^1.2.7",
- "is-negative-zero": "^2.0.2",
+ "is-data-view": "^1.0.1",
+ "is-negative-zero": "^2.0.3",
"is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
+ "is-shared-array-buffer": "^1.0.3",
"is-string": "^1.0.7",
"is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2",
@@ -16306,17 +17117,17 @@
"object-keys": "^1.1.1",
"object.assign": "^4.1.5",
"regexp.prototype.flags": "^1.5.2",
- "safe-array-concat": "^1.1.0",
+ "safe-array-concat": "^1.1.2",
"safe-regex-test": "^1.0.3",
- "string.prototype.trim": "^1.2.8",
- "string.prototype.trimend": "^1.0.7",
- "string.prototype.trimstart": "^1.0.7",
- "typed-array-buffer": "^1.0.1",
- "typed-array-byte-length": "^1.0.0",
- "typed-array-byte-offset": "^1.0.0",
- "typed-array-length": "^1.0.4",
+ "string.prototype.trim": "^1.2.9",
+ "string.prototype.trimend": "^1.0.8",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.2",
+ "typed-array-length": "^1.0.6",
"unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.14"
+ "which-typed-array": "^1.1.15"
},
"engines": {
"node": ">= 0.4"
@@ -16325,12 +17136,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/es-array-method-boxes-properly": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
- "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==",
- "dev": true
- },
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
@@ -16351,35 +17156,46 @@
}
},
"node_modules/es-iterator-helpers": {
- "version": "1.0.17",
- "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz",
- "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==",
+ "version": "1.0.18",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz",
+ "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==",
"dev": true,
"dependencies": {
- "asynciterator.prototype": "^1.0.0",
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
- "es-abstract": "^1.22.4",
+ "es-abstract": "^1.23.0",
"es-errors": "^1.3.0",
- "es-set-tostringtag": "^2.0.2",
+ "es-set-tostringtag": "^2.0.3",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"globalthis": "^1.0.3",
"has-property-descriptors": "^1.0.2",
- "has-proto": "^1.0.1",
+ "has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
"internal-slot": "^1.0.7",
"iterator.prototype": "^1.1.2",
- "safe-array-concat": "^1.1.0"
+ "safe-array-concat": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-module-lexer": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
- "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w=="
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz",
+ "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw=="
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
},
"node_modules/es-set-tostringtag": {
"version": "2.0.3",
@@ -16451,16 +17267,15 @@
}
},
"node_modules/eslint": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
- "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
- "dev": true,
+ "version": "8.57.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+ "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.56.0",
- "@humanwhocodes/config-array": "^0.11.13",
+ "@eslint/js": "8.57.0",
+ "@humanwhocodes/config-array": "^0.11.14",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
@@ -17433,10 +18248,35 @@
"ms": "^2.1.1"
}
},
+ "node_modules/eslint-import-resolver-typescript": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz",
+ "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4",
+ "enhanced-resolve": "^5.12.0",
+ "eslint-module-utils": "^2.7.4",
+ "fast-glob": "^3.3.1",
+ "get-tsconfig": "^4.5.0",
+ "is-core-module": "^2.11.0",
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*"
+ }
+ },
"node_modules/eslint-module-utils": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz",
- "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==",
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz",
+ "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==",
"dev": true,
"dependencies": {
"debug": "^3.2.7"
@@ -17692,27 +18532,29 @@
}
},
"node_modules/eslint-plugin-react": {
- "version": "7.33.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz",
- "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==",
+ "version": "7.34.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz",
+ "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==",
"dev": true,
"dependencies": {
- "array-includes": "^3.1.6",
- "array.prototype.flatmap": "^1.3.1",
- "array.prototype.tosorted": "^1.1.1",
+ "array-includes": "^3.1.7",
+ "array.prototype.findlast": "^1.2.4",
+ "array.prototype.flatmap": "^1.3.2",
+ "array.prototype.toreversed": "^1.1.2",
+ "array.prototype.tosorted": "^1.1.3",
"doctrine": "^2.1.0",
- "es-iterator-helpers": "^1.0.12",
+ "es-iterator-helpers": "^1.0.17",
"estraverse": "^5.3.0",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.1.2",
- "object.entries": "^1.1.6",
- "object.fromentries": "^2.0.6",
- "object.hasown": "^1.1.2",
- "object.values": "^1.1.6",
+ "object.entries": "^1.1.7",
+ "object.fromentries": "^2.0.7",
+ "object.hasown": "^1.1.3",
+ "object.values": "^1.1.7",
"prop-types": "^15.8.1",
- "resolve": "^2.0.0-next.4",
+ "resolve": "^2.0.0-next.5",
"semver": "^6.3.1",
- "string.prototype.matchall": "^4.0.8"
+ "string.prototype.matchall": "^4.0.10"
},
"engines": {
"node": ">=4"
@@ -17797,7 +18639,6 @@
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
- "dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
@@ -17837,7 +18678,6 @@
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -17845,11 +18685,77 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/eslint-webpack-plugin": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-4.1.0.tgz",
+ "integrity": "sha512-C3wAG2jyockIhN0YRLuKieKj2nx/gnE/VHmoHemD5ifnAtY6ZU+jNPfzPoX4Zd6RIbUyWTiZUh/ofUlBhoAX7w==",
+ "dependencies": {
+ "@types/eslint": "^8.56.5",
+ "jest-worker": "^29.7.0",
+ "micromatch": "^4.0.5",
+ "normalize-path": "^3.0.0",
+ "schema-utils": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "eslint": "^8.0.0",
+ "webpack": "^5.0.0"
+ }
+ },
+ "node_modules/eslint-webpack-plugin/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-webpack-plugin/node_modules/jest-worker": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
+ "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.7.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/eslint-webpack-plugin/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/@eslint/js": {
+ "version": "8.57.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+ "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
"node_modules/eslint/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
@@ -17863,14 +18769,12 @@
"node_modules/eslint/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/eslint/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -17880,7 +18784,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -17896,7 +18799,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
@@ -17907,14 +18809,12 @@
"node_modules/eslint/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/eslint/node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
- "dev": true,
"dependencies": {
"type-fest": "^0.20.2"
},
@@ -17929,7 +18829,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -17938,7 +18837,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
"dependencies": {
"argparse": "^2.0.1"
},
@@ -17950,7 +18848,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -17962,7 +18859,6 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -17970,11 +18866,18 @@
"node": ">=8"
}
},
+ "node_modules/esm": {
+ "version": "3.2.25",
+ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/espree": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
- "dev": true,
"dependencies": {
"acorn": "^8.9.0",
"acorn-jsx": "^5.3.2",
@@ -18003,7 +18906,6 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
"integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
- "dev": true,
"dependencies": {
"estraverse": "^5.1.0"
},
@@ -18116,6 +19018,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/execa/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
"node_modules/exif": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/exif/-/exif-0.6.0.tgz",
@@ -18159,16 +19067,16 @@
}
},
"node_modules/express": {
- "version": "4.18.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
- "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
+ "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
- "body-parser": "1.20.1",
+ "body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.5.0",
+ "cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -18266,33 +19174,10 @@
"node": ">= 8.0.0"
}
},
- "node_modules/express/node_modules/body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
- "dependencies": {
- "bytes": "3.1.2",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.11.0",
- "raw-body": "2.5.1",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
"node_modules/express/node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"engines": {
"node": ">= 0.6"
}
@@ -18310,20 +19195,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/express/node_modules/raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -18354,6 +19225,11 @@
"node": ">=4"
}
},
+ "node_modules/extract-colors": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/extract-colors/-/extract-colors-4.0.6.tgz",
+ "integrity": "sha512-U+pYyQKXCSHOmtZPIEJBGLJjLDiqS+oOub2ILA3a7UGt9+IvZvwAN3hOPFjUgT+gX/apSBwP5vBgnKMlV0fy8Q=="
+ },
"node_modules/extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -18383,6 +19259,32 @@
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="
},
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -18391,8 +19293,7 @@
"node_modules/fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
},
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
@@ -18406,7 +19307,6 @@
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
- "dev": true,
"dependencies": {
"reusify": "^1.0.4"
}
@@ -18436,6 +19336,11 @@
}
}
},
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="
+ },
"node_modules/ffmpeg": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/ffmpeg/-/ffmpeg-0.0.4.tgz",
@@ -18472,7 +19377,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
- "dev": true,
"dependencies": {
"flat-cache": "^3.0.4"
},
@@ -18627,7 +19531,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
"dependencies": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
@@ -18670,7 +19573,6 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
- "dev": true,
"dependencies": {
"flatted": "^3.2.9",
"keyv": "^4.5.3",
@@ -18684,7 +19586,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -18694,7 +19595,6 @@
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -18714,7 +19614,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -18726,7 +19625,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
"dependencies": {
"glob": "^7.1.3"
},
@@ -18740,8 +19638,7 @@
"node_modules/flatted": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
- "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
- "dev": true
+ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw=="
},
"node_modules/flexlayout-react": {
"version": "0.7.15",
@@ -18776,9 +19673,9 @@
}
},
"node_modules/follow-redirects": {
- "version": "1.15.5",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
- "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
@@ -18833,17 +19730,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/foreground-child/node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@@ -19261,24 +20147,48 @@
"node": ">=10"
}
},
+ "node_modules/gauge/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/gauge/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ },
+ "node_modules/gauge/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/gaxios": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.3.0.tgz",
- "integrity": "sha512-p+ggrQw3fBwH2F5N/PAI4k/G/y1art5OxKpb2J2chwNNHM4hHuAOtivjPuirMF4KNKwTTUal/lPfL2+7h2mEcg==",
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.4.0.tgz",
+ "integrity": "sha512-apAloYrY4dlBGlhauDAYSZveafb5U6+L9titing1wox6BvWM0TSXBp603zTrLpyLMGkrcFgohnUN150dFN/zOA==",
"dependencies": {
"extend": "^3.0.2",
"https-proxy-agent": "^7.0.1",
"is-stream": "^2.0.0",
- "node-fetch": "^2.6.9"
+ "node-fetch": "^2.6.9",
+ "uuid": "^9.0.1"
},
"engines": {
"node": ">=14"
}
},
"node_modules/gaxios/node_modules/agent-base": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
- "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+ "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
"dependencies": {
"debug": "^4.3.4"
},
@@ -19459,6 +20369,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-tsconfig": {
+ "version": "4.7.5",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz",
+ "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==",
+ "dev": true,
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
"node_modules/get-value": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -19490,18 +20412,21 @@
"integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
},
"node_modules/glob": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
- "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "version": "10.3.12",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz",
+ "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==",
"dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^5.0.1",
- "once": "^1.3.0"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.6",
+ "minimatch": "^9.0.1",
+ "minipass": "^7.0.4",
+ "path-scurry": "^1.10.2"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
},
"engines": {
- "node": ">=12"
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -19511,7 +20436,6 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
"dependencies": {
"is-glob": "^4.0.3"
},
@@ -19525,14 +20449,17 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
},
"node_modules/glob/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/global": {
@@ -19584,11 +20511,15 @@
}
},
"node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "version": "15.2.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.2.0.tgz",
+ "integrity": "sha512-FQ5YwCHZM3nCmtb5FzEWwdUc9K5d3V/w9mzcz8iGD1gC/aOTHc6PouYu0kkKipNJqHAT7m51sqzQjEjIP+cK0A==",
+ "dev": true,
"engines": {
- "node": ">=4"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globalthis": {
@@ -19606,15 +20537,34 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/golden-layout": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/golden-layout/-/golden-layout-2.6.0.tgz",
"integrity": "sha512-sIVQCiRWOymHbVD1Aw/T9/ijbPYAVGBlgGYd1N9MRKfcyBNSpjr87Vg9nSHm+RCT8ELrvK8IJYJV0QRJuVUkCQ=="
},
"node_modules/google-auth-library": {
- "version": "9.6.3",
- "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.6.3.tgz",
- "integrity": "sha512-4CacM29MLC2eT9Cey5GDVK4Q8t+MMp8+OEdOaqD9MG6b0dOyLORaaeJMPQ7EESVgm/+z5EKYyFLxgzBJlJgyHQ==",
+ "version": "9.7.0",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.7.0.tgz",
+ "integrity": "sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==",
"dependencies": {
"base64-js": "^1.3.0",
"ecdsa-sig-formatter": "^1.0.11",
@@ -19652,13 +20602,13 @@
}
},
"node_modules/googleapis-common": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.0.1.tgz",
- "integrity": "sha512-mgt5zsd7zj5t5QXvDanjWguMdHAcJmmDrF9RkInCecNsyV7S7YtGqm5v2IWONNID88osb7zmx5FtrAP12JfD0w==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.1.0.tgz",
+ "integrity": "sha512-p3KHiWDBBWJEXk6SYauBEvxw5+UmRy7k2scxGtsNv9eHsTbpopJ3/7If4OrNnzJ9XMLg3IlyQXpVp8YPQsStiw==",
"dependencies": {
"extend": "^3.0.2",
"gaxios": "^6.0.3",
- "google-auth-library": "^9.0.0",
+ "google-auth-library": "^9.7.0",
"qs": "^6.7.0",
"url-template": "^2.0.8",
"uuid": "^9.0.0"
@@ -19692,9 +20642,9 @@
}
},
"node_modules/got": {
- "version": "14.2.0",
- "resolved": "https://registry.npmjs.org/got/-/got-14.2.0.tgz",
- "integrity": "sha512-dBq2KkHcQl3AwPoIWsLsQScCPpUgRulz1qZVthjPYKYOPmYfBnekR3vxecjZbm91Vc3JUGnV9mqFX7B+Fe2quw==",
+ "version": "14.2.1",
+ "resolved": "https://registry.npmjs.org/got/-/got-14.2.1.tgz",
+ "integrity": "sha512-KOaPMremmsvx6l9BLC04LYE6ZFW4x7e4HkTe3LwBmtuYYQwpeS4XKqzhubTIkaQ1Nr+eXxeori0zuwupXMovBQ==",
"dependencies": {
"@sindresorhus/is": "^6.1.0",
"@szmarczak/http-timer": "^5.0.1",
@@ -19723,8 +20673,7 @@
"node_modules/graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
- "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "dev": true
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
},
"node_modules/grid-index": {
"version": "1.1.0",
@@ -19840,9 +20789,9 @@
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
"node_modules/hasown": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
- "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -19850,6 +20799,52 @@
"node": ">= 0.4"
}
},
+ "node_modules/hast-util-from-dom": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz",
+ "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "hastscript": "^8.0.0",
+ "web-namespaces": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-from-html": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz",
+ "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "devlop": "^1.1.0",
+ "hast-util-from-parse5": "^8.0.0",
+ "parse5": "^7.0.0",
+ "vfile": "^6.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-from-html-isomorphic": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz",
+ "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "hast-util-from-dom": "^5.0.0",
+ "hast-util-from-html": "^2.0.0",
+ "unist-util-remove-position": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hast-util-from-parse5": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz",
@@ -19869,6 +20864,18 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/hast-util-is-element": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz",
+ "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hast-util-parse-selector": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz",
@@ -19949,6 +20956,21 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/hast-util-to-text": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz",
+ "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "hast-util-is-element": "^3.0.0",
+ "unist-util-find-after": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hast-util-whitespace": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
@@ -19985,6 +21007,11 @@
"he": "bin/he"
}
},
+ "node_modules/heap": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz",
+ "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg=="
+ },
"node_modules/hexoid": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
@@ -20083,10 +21110,9 @@
}
},
"node_modules/html-entities": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz",
- "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==",
- "dev": true,
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz",
+ "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
"funding": [
{
"type": "github",
@@ -20282,9 +21308,9 @@
}
},
"node_modules/http-proxy-agent/node_modules/agent-base": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
- "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+ "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
"dev": true,
"dependencies": {
"debug": "^4.3.4"
@@ -20733,7 +21759,6 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
"engines": {
"node": ">=0.8.19"
}
@@ -20778,9 +21803,9 @@
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"node_modules/inline-style-parser": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz",
- "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ=="
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz",
+ "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g=="
},
"node_modules/inquirer": {
"version": "7.3.3",
@@ -20855,6 +21880,12 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
+ "node_modules/inquirer/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
"node_modules/inquirer/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -20864,6 +21895,20 @@
"node": ">=8"
}
},
+ "node_modules/inquirer/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/inquirer/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -21189,11 +22234,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
- },
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
@@ -21216,6 +22256,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-data-view": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
+ "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+ "dev": true,
+ "dependencies": {
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
@@ -21240,15 +22295,15 @@
}
},
"node_modules/is-docker": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
"dev": true,
"bin": {
"is-docker": "cli.js"
},
"engines": {
- "node": ">=8"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -21349,11 +22404,32 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-map": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
- "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -21370,6 +22446,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-network-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz",
+ "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -21397,7 +22485,6 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -21451,10 +22538,13 @@
}
},
"node_modules/is-set": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
- "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -21546,11 +22636,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q=="
+ },
"node_modules/is-weakmap": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
- "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -21568,13 +22666,16 @@
}
},
"node_modules/is-weakset": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
- "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
+ "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -21589,15 +22690,18 @@
}
},
"node_modules/is-wsl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
+ "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
"dev": true,
"dependencies": {
- "is-docker": "^2.0.0"
+ "is-inside-container": "^1.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/isarray": {
@@ -21672,6 +22776,86 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/jest-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
+ "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-util/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-util/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-util/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/jest-util/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/jest-util/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-util/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/jest-worker": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
@@ -21708,13 +22892,13 @@
}
},
"node_modules/jimp": {
- "version": "0.22.10",
- "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.10.tgz",
- "integrity": "sha512-lCaHIJAgTOsplyJzC1w/laxSxrbSsEBw4byKwXgUdMmh+ayPsnidTblenQm+IvhIs44Gcuvlb6pd2LQ0wcKaKg==",
+ "version": "0.22.12",
+ "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.12.tgz",
+ "integrity": "sha512-R5jZaYDnfkxKJy1dwLpj/7cvyjxiclxU3F4TrI/J4j2rS0niq6YDUMoPn5hs8GDpO+OZGo7Ky057CRtWesyhfg==",
"dependencies": {
- "@jimp/custom": "^0.22.10",
- "@jimp/plugins": "^0.22.10",
- "@jimp/types": "^0.22.10",
+ "@jimp/custom": "^0.22.12",
+ "@jimp/plugins": "^0.22.12",
+ "@jimp/types": "^0.22.12",
"regenerator-runtime": "^0.13.3"
}
},
@@ -21862,9 +23046,9 @@
}
},
"node_modules/jsdom/node_modules/agent-base": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
- "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+ "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
"dev": true,
"dependencies": {
"debug": "^4.3.4"
@@ -21928,8 +23112,7 @@
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
},
"node_modules/json-stringify-pretty-compact": {
"version": "3.0.0",
@@ -22072,13 +23255,36 @@
}
},
"node_modules/kareem": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz",
- "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==",
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
+ "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
"engines": {
"node": ">=12.0.0"
}
},
+ "node_modules/katex": {
+ "version": "0.16.10",
+ "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz",
+ "integrity": "sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==",
+ "funding": [
+ "https://opencollective.com/katex",
+ "https://github.com/sponsors/katex"
+ ],
+ "dependencies": {
+ "commander": "^8.3.0"
+ },
+ "bin": {
+ "katex": "cli.js"
+ }
+ },
+ "node_modules/katex/node_modules/commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
"node_modules/kdbush": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
@@ -22103,6 +23309,11 @@
"json-buffer": "3.0.1"
}
},
+ "node_modules/khroma": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz",
+ "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="
+ },
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -22119,6 +23330,14 @@
"graceful-fs": "^4.1.9"
}
},
+ "node_modules/kleur": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/kruptein": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/kruptein/-/kruptein-3.0.6.tgz",
@@ -22209,6 +23428,11 @@
"shell-quote": "^1.8.1"
}
},
+ "node_modules/layout-base": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz",
+ "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="
+ },
"node_modules/lazystream": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
@@ -22273,7 +23497,6 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
"dependencies": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
@@ -22295,6 +23518,14 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
+ "node_modules/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "dependencies": {
+ "uc.micro": "^2.0.0"
+ }
+ },
"node_modules/load-bmfont": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz",
@@ -22335,7 +23566,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
"dependencies": {
"p-locate": "^5.0.0"
},
@@ -22361,6 +23591,11 @@
"resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz",
"integrity": "sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w=="
},
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
+ },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -22524,9 +23759,9 @@
}
},
"node_modules/magic-string": {
- "version": "0.30.7",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
- "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+ "version": "0.30.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz",
+ "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
@@ -22627,13 +23862,13 @@
"dev": true
},
"node_modules/mapbox-gl": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.1.2.tgz",
- "integrity": "sha512-+KoLEqZM8GxO/ViPz9tKgGURteKne+Y0pXiVCNsowymiZFH3FiL6dt9oZE95owMg5XqD3Kygz5mfchR1ZgmWlA==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.3.0.tgz",
+ "integrity": "sha512-cVeAu9PxPTx113AnJAzcSKbBtL5F5EpJ6/NuYgNib9zNduNSoDG2oVX6xK0bAP/VwwVwRh9SEhcyM7nh4GThvQ==",
"dependencies": {
"@mapbox/geojson-rewind": "^0.5.2",
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
- "@mapbox/mapbox-gl-supported": "^2.0.1",
+ "@mapbox/mapbox-gl-supported": "^3.0.0",
"@mapbox/point-geometry": "^0.1.0",
"@mapbox/tiny-sdf": "^2.0.6",
"@mapbox/unitbezier": "^0.0.1",
@@ -22642,20 +23877,46 @@
"cheap-ruler": "^3.0.1",
"csscolorparser": "~1.0.3",
"earcut": "^2.2.4",
+ "fflate": "^0.8.1",
"geojson-vt": "^3.2.1",
"gl-matrix": "^3.4.3",
"grid-index": "^1.1.0",
"kdbush": "^4.0.1",
+ "lodash.clonedeep": "^4.5.0",
"murmurhash-js": "^1.0.0",
"pbf": "^3.2.1",
"potpack": "^2.0.0",
"quickselect": "^2.0.0",
"rw": "^1.3.3",
+ "serialize-to-js": "^3.1.2",
"supercluster": "^8.0.0",
+ "tiny-lru": "^11.2.5",
"tinyqueue": "^2.0.3",
+ "tweakpane": "^4.0.3",
"vt-pbf": "^3.1.3"
}
},
+ "node_modules/markdown-it": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
+ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.0",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/markdown-it/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
"node_modules/markdown-table": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
@@ -22679,6 +23940,17 @@
"mr-parser": "^0.2.1"
}
},
+ "node_modules/mathjax-full": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
+ "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
+ "dependencies": {
+ "esm": "^3.2.25",
+ "mhchemparser": "^4.1.0",
+ "mj-context-menu": "^0.6.1",
+ "speech-rule-engine": "^4.0.6"
+ }
+ },
"node_modules/mathquill": {
"version": "0.10.1-a",
"resolved": "https://registry.npmjs.org/mathquill/-/mathquill-0.10.1-a.tgz",
@@ -22692,16 +23964,6 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-1.12.4.tgz",
"integrity": "sha512-UEVp7PPK9xXYSk8xqXCJrkXnKZtlgWkd2GsAQbMRFK6S/ePU2JN5G2Zum8hIVjzR3CpdfSqdqAzId/xd4TJHeg=="
},
- "node_modules/md5": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
- "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
- "dependencies": {
- "charenc": "0.0.2",
- "crypt": "0.0.2",
- "is-buffer": "~1.1.6"
- }
- },
"node_modules/md5-file": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz",
@@ -22857,6 +24119,24 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/mdast-util-math": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz",
+ "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "longest-streak": "^3.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.1.0",
+ "unist-util-remove-position": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/mdast-util-mdx-expression": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz",
@@ -22875,9 +24155,9 @@
}
},
"node_modules/mdast-util-mdx-jsx": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.0.tgz",
- "integrity": "sha512-A8AJHlR7/wPQ3+Jre1+1rq040fX9A4Q1jG8JxmSNp/PLPHg80A6475wxTp3KzHpApFH6yWxFotHrJQA3dXP6/w==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz",
+ "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==",
"dependencies": {
"@types/estree-jsx": "^1.0.0",
"@types/hast": "^3.0.0",
@@ -22979,6 +24259,11 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="
+ },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -23026,6 +24311,522 @@
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
},
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/mermaid": {
+ "version": "10.9.0",
+ "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.0.tgz",
+ "integrity": "sha512-swZju0hFox/B/qoLKK0rOxxgh8Cf7rJSfAUc1u8fezVihYMvrJAS45GzAxTVf4Q+xn9uMgitBcmWk7nWGXOs/g==",
+ "dependencies": {
+ "@braintree/sanitize-url": "^6.0.1",
+ "@types/d3-scale": "^4.0.3",
+ "@types/d3-scale-chromatic": "^3.0.0",
+ "cytoscape": "^3.28.1",
+ "cytoscape-cose-bilkent": "^4.1.0",
+ "d3": "^7.4.0",
+ "d3-sankey": "^0.12.3",
+ "dagre-d3-es": "7.0.10",
+ "dayjs": "^1.11.7",
+ "dompurify": "^3.0.5",
+ "elkjs": "^0.9.0",
+ "katex": "^0.16.9",
+ "khroma": "^2.0.0",
+ "lodash-es": "^4.17.21",
+ "mdast-util-from-markdown": "^1.3.0",
+ "non-layered-tidy-tree-layout": "^2.0.2",
+ "stylis": "^4.1.3",
+ "ts-dedent": "^2.2.0",
+ "uuid": "^9.0.0",
+ "web-worker": "^1.2.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/@types/mdast": {
+ "version": "3.0.15",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz",
+ "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==",
+ "dependencies": {
+ "@types/unist": "^2"
+ }
+ },
+ "node_modules/mermaid/node_modules/@types/unist": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
+ "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
+ },
+ "node_modules/mermaid/node_modules/mdast-util-from-markdown": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz",
+ "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "@types/unist": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "mdast-util-to-string": "^3.1.0",
+ "micromark": "^3.0.0",
+ "micromark-util-decode-numeric-character-reference": "^1.0.0",
+ "micromark-util-decode-string": "^1.0.0",
+ "micromark-util-normalize-identifier": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "unist-util-stringify-position": "^3.0.0",
+ "uvu": "^0.5.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mermaid/node_modules/mdast-util-to-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
+ "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
+ "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "@types/debug": "^4.0.0",
+ "debug": "^4.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "micromark-core-commonmark": "^1.0.1",
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-chunked": "^1.0.0",
+ "micromark-util-combine-extensions": "^1.0.0",
+ "micromark-util-decode-numeric-character-reference": "^1.0.0",
+ "micromark-util-encode": "^1.0.0",
+ "micromark-util-normalize-identifier": "^1.0.0",
+ "micromark-util-resolve-all": "^1.0.0",
+ "micromark-util-sanitize-uri": "^1.0.0",
+ "micromark-util-subtokenize": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.1",
+ "uvu": "^0.5.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-core-commonmark": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz",
+ "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "micromark-factory-destination": "^1.0.0",
+ "micromark-factory-label": "^1.0.0",
+ "micromark-factory-space": "^1.0.0",
+ "micromark-factory-title": "^1.0.0",
+ "micromark-factory-whitespace": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-chunked": "^1.0.0",
+ "micromark-util-classify-character": "^1.0.0",
+ "micromark-util-html-tag-name": "^1.0.0",
+ "micromark-util-normalize-identifier": "^1.0.0",
+ "micromark-util-resolve-all": "^1.0.0",
+ "micromark-util-subtokenize": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.1",
+ "uvu": "^0.5.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-factory-destination": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz",
+ "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-factory-label": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz",
+ "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-factory-space": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz",
+ "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-factory-title": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz",
+ "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-factory-whitespace": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz",
+ "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-character": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz",
+ "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-chunked": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz",
+ "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-classify-character": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz",
+ "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-combine-extensions": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz",
+ "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-chunked": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz",
+ "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-decode-string": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz",
+ "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-decode-numeric-character-reference": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz",
+ "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/mermaid/node_modules/micromark-util-html-tag-name": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz",
+ "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/mermaid/node_modules/micromark-util-normalize-identifier": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz",
+ "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-resolve-all": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz",
+ "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-sanitize-uri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz",
+ "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-encode": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-subtokenize": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz",
+ "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-chunked": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/micromark-util-symbol": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz",
+ "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/mermaid/node_modules/micromark-util-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz",
+ "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/mermaid/node_modules/unist-util-stringify-position": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",
+ "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==",
+ "dependencies": {
+ "@types/unist": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -23034,6 +24835,11 @@
"node": ">= 0.6"
}
},
+ "node_modules/mhchemparser": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
+ "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ=="
+ },
"node_modules/micromark": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz",
@@ -23215,6 +25021,24 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/micromark-extension-math": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.0.0.tgz",
+ "integrity": "sha512-iJ2Q28vBoEovLN5o3GO12CpqorQRYDPT+p4zW50tGwTfJB+iv/VnB6Ini+gqa24K97DwptMBBIvVX6Bjk49oyQ==",
+ "dependencies": {
+ "@types/katex": "^0.16.0",
+ "devlop": "^1.0.0",
+ "katex": "^0.16.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/micromark-factory-destination": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz",
@@ -23667,11 +25491,11 @@
}
},
"node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+ "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
"engines": {
- "node": ">=8"
+ "node": ">=16 || 14 >=14.17"
}
},
"node_modules/minizlib": {
@@ -23702,6 +25526,11 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
+ "node_modules/mj-context-menu": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
+ "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
+ },
"node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@@ -23719,20 +25548,20 @@
"integrity": "sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g=="
},
"node_modules/mobx": {
- "version": "6.12.0",
- "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.12.0.tgz",
- "integrity": "sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ==",
+ "version": "6.12.3",
+ "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.12.3.tgz",
+ "integrity": "sha512-c8NKkO4R2lShkSXZ2Ongj1ycjugjzFFo/UswHBnS62y07DMcTc9Rvo03/3nRyszIvwPNljlkd4S828zIBv/piw==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mobx"
}
},
"node_modules/mobx-react": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.1.0.tgz",
- "integrity": "sha512-DeDRTYw4AlgHw8xEXtiZdKKEnp+c5/jeUgTbTQXEqnAzfkrgYRWP3p3Nv3Whc2CEcM/mDycbDWGjxKokQdlffg==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.1.1.tgz",
+ "integrity": "sha512-gVV7AdSrAAxqXOJ2bAbGa5TkPqvITSzaPiiEkzpW4rRsMhSec7C2NBCJYILADHKp2tzOAIETGRsIY0UaCV5aEw==",
"dependencies": {
- "mobx-react-lite": "^4.0.4"
+ "mobx-react-lite": "^4.0.7"
},
"funding": {
"type": "opencollective",
@@ -23752,9 +25581,9 @@
}
},
"node_modules/mobx-react-lite": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.0.5.tgz",
- "integrity": "sha512-StfB2wxE8imKj1f6T8WWPf4lVMx3cYH9Iy60bbKXEs21+HQ4tvvfIBZfSmMXgQAefi8xYEwQIz4GN9s0d2h7dg==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.0.7.tgz",
+ "integrity": "sha512-RjwdseshK9Mg8On5tyJZHtGD+J78ZnCnRaxeQDSiciKVQDUbfZcXhmld0VMxAwvcTnPEHZySGGewm467Fcpreg==",
"dependencies": {
"use-sync-external-store": "^1.2.0"
},
@@ -23784,9 +25613,9 @@
}
},
"node_modules/mocha": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz",
- "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==",
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz",
+ "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==",
"dev": true,
"dependencies": {
"ansi-colors": "4.1.1",
@@ -23851,6 +25680,25 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/mocha/node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/mocha/node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -23927,12 +25775,12 @@
}
},
"node_modules/mongodb": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz",
- "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz",
+ "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==",
"dependencies": {
- "@mongodb-js/saslprep": "^1.1.0",
- "bson": "^6.2.0",
+ "@mongodb-js/saslprep": "^1.1.5",
+ "bson": "^6.4.0",
"mongodb-connection-string-url": "^3.0.0"
},
"engines": {
@@ -24004,13 +25852,13 @@
}
},
"node_modules/mongoose": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.0.tgz",
- "integrity": "sha512-la93n6zCYRbPS+c5N9oTDAktvREy5OT9OCljp1Tah0y3+p8UPMTAoabWaLZMdzYruOtF9/9GRf6MasaZjiZP1A==",
+ "version": "8.3.1",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.3.1.tgz",
+ "integrity": "sha512-D78C+s7QI4+pJQhs3XbOxzrHFEti4x+BDhaH94QrdV1/cmMA7fHc50LgLSXjzA/5q89TBK8DAXyf3VwDZbQJlA==",
"dependencies": {
- "bson": "^6.2.0",
- "kareem": "2.5.1",
- "mongodb": "6.3.0",
+ "bson": "^6.5.0",
+ "kareem": "2.6.3",
+ "mongodb": "6.5.0",
"mpath": "0.9.0",
"mquery": "5.0.0",
"ms": "2.1.3",
@@ -24053,6 +25901,14 @@
"resolved": "https://registry.npmjs.org/mr-parser/-/mr-parser-0.2.1.tgz",
"integrity": "sha512-hug+mpbSSKnH13rFqy3zm+XiG+QTStiDAgMTHK355TIstQE0qBkBtSJsa5YHP94AuarVX9b/4dcebdTRZ9YiEw=="
},
+ "node_modules/mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -24126,9 +25982,9 @@
"dev": true
},
"node_modules/nan": {
- "version": "2.18.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz",
- "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w=="
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz",
+ "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw=="
},
"node_modules/nanoid": {
"version": "3.3.7",
@@ -24150,8 +26006,7 @@
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
},
"node_modules/needle": {
"version": "2.9.1",
@@ -24306,9 +26161,9 @@
}
},
"node_modules/nodemailer": {
- "version": "6.9.10",
- "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.10.tgz",
- "integrity": "sha512-qtoKfGFhvIFW5kLfrkw2R6Nm6Ur4LNUMykyqu6n9BRKJuyQrqEGwdXXUAbwWEKt33dlWUGXb7rzmJP/p4+O+CA==",
+ "version": "6.9.13",
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.13.tgz",
+ "integrity": "sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA==",
"engines": {
"node": ">=6.0.0"
}
@@ -24390,6 +26245,11 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
+ "node_modules/non-layered-tidy-tree-layout": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz",
+ "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw=="
+ },
"node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
@@ -24413,9 +26273,9 @@
}
},
"node_modules/normalize-url": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz",
- "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz",
+ "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==",
"engines": {
"node": ">=14.16"
},
@@ -24423,15 +26283,10 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/normalize.css": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz",
- "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg=="
- },
"node_modules/npm": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/npm/-/npm-10.4.0.tgz",
- "integrity": "sha512-RS7Mx0OVfXlOcQLRePuDIYdFCVBPCNapWHplDK+mh7GDdP/Tvor4ocuybRRPSvfcRb2vjRJt1fHCqw3cr8qACQ==",
+ "version": "10.5.2",
+ "resolved": "https://registry.npmjs.org/npm/-/npm-10.5.2.tgz",
+ "integrity": "sha512-cHVG7QEJwJdZyOrK0dKX5uf3R5Fd0E8AcmSES1jLtO52UT1enUKZ96Onw/xwq4CbrTZEnDuu2Vf9kCQh/Sd12w==",
"bundleDependencies": [
"@isaacs/string-locale-compare",
"@npmcli/arborist",
@@ -24440,6 +26295,7 @@
"@npmcli/map-workspaces",
"@npmcli/package-json",
"@npmcli/promise-spawn",
+ "@npmcli/redact",
"@npmcli/run-script",
"@sigstore/tuf",
"abbrev",
@@ -24509,27 +26365,28 @@
"@npmcli/arborist": "^7.2.1",
"@npmcli/config": "^8.0.2",
"@npmcli/fs": "^3.1.0",
- "@npmcli/map-workspaces": "^3.0.4",
- "@npmcli/package-json": "^5.0.0",
+ "@npmcli/map-workspaces": "^3.0.6",
+ "@npmcli/package-json": "^5.0.2",
"@npmcli/promise-spawn": "^7.0.1",
+ "@npmcli/redact": "^1.1.0",
"@npmcli/run-script": "^7.0.4",
- "@sigstore/tuf": "^2.3.0",
+ "@sigstore/tuf": "^2.3.2",
"abbrev": "^2.0.0",
"archy": "~1.0.0",
"cacache": "^18.0.2",
"chalk": "^5.3.0",
"ci-info": "^4.0.0",
"cli-columns": "^4.0.0",
- "cli-table3": "^0.6.3",
+ "cli-table3": "^0.6.4",
"columnify": "^1.6.0",
"fastest-levenshtein": "^1.0.16",
"fs-minipass": "^3.0.3",
- "glob": "^10.3.10",
+ "glob": "^10.3.12",
"graceful-fs": "^4.2.11",
"hosted-git-info": "^7.0.1",
- "ini": "^4.1.1",
- "init-package-json": "^6.0.0",
- "is-cidr": "^5.0.3",
+ "ini": "^4.1.2",
+ "init-package-json": "^6.0.2",
+ "is-cidr": "^5.0.5",
"json-parse-even-better-errors": "^3.0.1",
"libnpmaccess": "^8.0.1",
"libnpmdiff": "^6.0.3",
@@ -24543,11 +26400,11 @@
"libnpmteam": "^6.0.0",
"libnpmversion": "^5.0.1",
"make-fetch-happen": "^13.0.0",
- "minimatch": "^9.0.3",
+ "minimatch": "^9.0.4",
"minipass": "^7.0.4",
"minipass-pipeline": "^1.2.4",
"ms": "^2.1.2",
- "node-gyp": "^10.0.1",
+ "node-gyp": "^10.1.0",
"nopt": "^7.2.0",
"normalize-package-data": "^6.0.0",
"npm-audit-report": "^5.0.0",
@@ -24555,7 +26412,7 @@
"npm-package-arg": "^11.0.1",
"npm-pick-manifest": "^9.0.0",
"npm-profile": "^9.0.0",
- "npm-registry-fetch": "^16.1.0",
+ "npm-registry-fetch": "^16.2.0",
"npm-user-validate": "^2.0.0",
"npmlog": "^7.0.1",
"p-map": "^4.0.0",
@@ -24563,12 +26420,12 @@
"parse-conflict-json": "^3.0.1",
"proc-log": "^3.0.0",
"qrcode-terminal": "^0.12.0",
- "read": "^2.1.0",
- "semver": "^7.5.4",
- "spdx-expression-parse": "^3.0.1",
+ "read": "^3.0.1",
+ "semver": "^7.6.0",
+ "spdx-expression-parse": "^4.0.0",
"ssri": "^10.0.5",
"supports-color": "^9.4.0",
- "tar": "^6.2.0",
+ "tar": "^6.2.1",
"text-table": "~0.2.0",
"tiny-relative-date": "^1.3.0",
"treeverse": "^3.0.0",
@@ -24673,7 +26530,7 @@
"license": "ISC"
},
"node_modules/npm/node_modules/@npmcli/agent": {
- "version": "2.2.0",
+ "version": "2.2.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24681,14 +26538,14 @@
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.1",
"lru-cache": "^10.0.1",
- "socks-proxy-agent": "^8.0.1"
+ "socks-proxy-agent": "^8.0.3"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/npm/node_modules/@npmcli/arborist": {
- "version": "7.3.1",
+ "version": "7.4.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24700,7 +26557,8 @@
"@npmcli/name-from-folder": "^2.0.0",
"@npmcli/node-gyp": "^3.0.0",
"@npmcli/package-json": "^5.0.0",
- "@npmcli/query": "^3.0.1",
+ "@npmcli/query": "^3.1.0",
+ "@npmcli/redact": "^1.1.0",
"@npmcli/run-script": "^7.0.2",
"bin-links": "^4.0.1",
"cacache": "^18.0.0",
@@ -24708,12 +26566,12 @@
"hosted-git-info": "^7.0.1",
"json-parse-even-better-errors": "^3.0.0",
"json-stringify-nice": "^1.1.4",
- "minimatch": "^9.0.0",
+ "minimatch": "^9.0.4",
"nopt": "^7.0.0",
"npm-install-checks": "^6.2.0",
"npm-package-arg": "^11.0.1",
"npm-pick-manifest": "^9.0.0",
- "npm-registry-fetch": "^16.0.0",
+ "npm-registry-fetch": "^16.2.0",
"npmlog": "^7.0.1",
"pacote": "^17.0.4",
"parse-conflict-json": "^3.0.0",
@@ -24734,13 +26592,13 @@
}
},
"node_modules/npm/node_modules/@npmcli/config": {
- "version": "8.1.0",
+ "version": "8.2.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
"@npmcli/map-workspaces": "^3.0.2",
"ci-info": "^4.0.0",
- "ini": "^4.1.0",
+ "ini": "^4.1.2",
"nopt": "^7.0.0",
"proc-log": "^3.0.0",
"read-package-json-fast": "^3.0.2",
@@ -24788,7 +26646,7 @@
}
},
"node_modules/npm/node_modules/@npmcli/git": {
- "version": "5.0.4",
+ "version": "5.0.5",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24821,7 +26679,7 @@
}
},
"node_modules/npm/node_modules/@npmcli/map-workspaces": {
- "version": "3.0.4",
+ "version": "3.0.6",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24865,7 +26723,7 @@
}
},
"node_modules/npm/node_modules/@npmcli/package-json": {
- "version": "5.0.0",
+ "version": "5.0.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24893,7 +26751,7 @@
}
},
"node_modules/npm/node_modules/@npmcli/query": {
- "version": "3.0.1",
+ "version": "3.1.0",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24903,6 +26761,14 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/npm/node_modules/@npmcli/redact": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
"node_modules/npm/node_modules/@npmcli/run-script": {
"version": "7.0.4",
"inBundle": true,
@@ -24928,18 +26794,18 @@
}
},
"node_modules/npm/node_modules/@sigstore/bundle": {
- "version": "2.1.1",
+ "version": "2.3.1",
"inBundle": true,
"license": "Apache-2.0",
"dependencies": {
- "@sigstore/protobuf-specs": "^0.2.1"
+ "@sigstore/protobuf-specs": "^0.3.1"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/npm/node_modules/@sigstore/core": {
- "version": "0.2.0",
+ "version": "1.1.0",
"inBundle": true,
"license": "Apache-2.0",
"engines": {
@@ -24947,21 +26813,21 @@
}
},
"node_modules/npm/node_modules/@sigstore/protobuf-specs": {
- "version": "0.2.1",
+ "version": "0.3.1",
"inBundle": true,
"license": "Apache-2.0",
"engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ "node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/npm/node_modules/@sigstore/sign": {
- "version": "2.2.1",
+ "version": "2.3.0",
"inBundle": true,
"license": "Apache-2.0",
"dependencies": {
- "@sigstore/bundle": "^2.1.1",
- "@sigstore/core": "^0.2.0",
- "@sigstore/protobuf-specs": "^0.2.1",
+ "@sigstore/bundle": "^2.3.0",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.1",
"make-fetch-happen": "^13.0.0"
},
"engines": {
@@ -24969,11 +26835,11 @@
}
},
"node_modules/npm/node_modules/@sigstore/tuf": {
- "version": "2.3.0",
+ "version": "2.3.2",
"inBundle": true,
"license": "Apache-2.0",
"dependencies": {
- "@sigstore/protobuf-specs": "^0.2.1",
+ "@sigstore/protobuf-specs": "^0.3.0",
"tuf-js": "^2.2.0"
},
"engines": {
@@ -24981,13 +26847,13 @@
}
},
"node_modules/npm/node_modules/@sigstore/verify": {
- "version": "0.1.0",
+ "version": "1.2.0",
"inBundle": true,
"license": "Apache-2.0",
"dependencies": {
- "@sigstore/bundle": "^2.1.1",
- "@sigstore/core": "^0.2.0",
- "@sigstore/protobuf-specs": "^0.2.1"
+ "@sigstore/bundle": "^2.3.1",
+ "@sigstore/core": "^1.1.0",
+ "@sigstore/protobuf-specs": "^0.3.1"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
@@ -25022,7 +26888,7 @@
}
},
"node_modules/npm/node_modules/agent-base": {
- "version": "7.1.0",
+ "version": "7.1.1",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -25101,11 +26967,14 @@
}
},
"node_modules/npm/node_modules/binary-extensions": {
- "version": "2.2.0",
+ "version": "2.3.0",
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/npm/node_modules/brace-expansion": {
@@ -25117,7 +26986,7 @@
}
},
"node_modules/npm/node_modules/builtins": {
- "version": "5.0.1",
+ "version": "5.1.0",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -25180,7 +27049,7 @@
}
},
"node_modules/npm/node_modules/cidr-regex": {
- "version": "4.0.3",
+ "version": "4.0.5",
"inBundle": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -25211,7 +27080,7 @@
}
},
"node_modules/npm/node_modules/cli-table3": {
- "version": "0.6.3",
+ "version": "0.6.4",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -25357,7 +27226,7 @@
}
},
"node_modules/npm/node_modules/diff": {
- "version": "5.1.0",
+ "version": "5.2.0",
"inBundle": true,
"license": "BSD-3-Clause",
"engines": {
@@ -25462,15 +27331,15 @@
}
},
"node_modules/npm/node_modules/glob": {
- "version": "10.3.10",
+ "version": "10.3.12",
"inBundle": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
- "jackspeak": "^2.3.5",
+ "jackspeak": "^2.3.6",
"minimatch": "^9.0.1",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
- "path-scurry": "^1.10.1"
+ "minipass": "^7.0.4",
+ "path-scurry": "^1.10.2"
},
"bin": {
"glob": "dist/esm/bin.mjs"
@@ -25493,7 +27362,7 @@
"license": "ISC"
},
"node_modules/npm/node_modules/hasown": {
- "version": "2.0.0",
+ "version": "2.0.2",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -25520,7 +27389,7 @@
"license": "BSD-2-Clause"
},
"node_modules/npm/node_modules/http-proxy-agent": {
- "version": "7.0.0",
+ "version": "7.0.2",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -25532,7 +27401,7 @@
}
},
"node_modules/npm/node_modules/https-proxy-agent": {
- "version": "7.0.2",
+ "version": "7.0.4",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -25583,7 +27452,7 @@
}
},
"node_modules/npm/node_modules/ini": {
- "version": "4.1.1",
+ "version": "4.1.2",
"inBundle": true,
"license": "ISC",
"engines": {
@@ -25591,14 +27460,14 @@
}
},
"node_modules/npm/node_modules/init-package-json": {
- "version": "6.0.0",
+ "version": "6.0.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
+ "@npmcli/package-json": "^5.0.0",
"npm-package-arg": "^11.0.0",
"promzard": "^1.0.0",
- "read": "^2.0.0",
- "read-package-json": "^7.0.0",
+ "read": "^3.0.1",
"semver": "^7.3.5",
"validate-npm-package-license": "^3.0.4",
"validate-npm-package-name": "^5.0.0"
@@ -25607,10 +27476,22 @@
"node": "^16.14.0 || >=18.0.0"
}
},
- "node_modules/npm/node_modules/ip": {
- "version": "2.0.0",
+ "node_modules/npm/node_modules/ip-address": {
+ "version": "9.0.5",
"inBundle": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/npm/node_modules/ip-address/node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "inBundle": true,
+ "license": "BSD-3-Clause"
},
"node_modules/npm/node_modules/ip-regex": {
"version": "5.0.0",
@@ -25624,11 +27505,11 @@
}
},
"node_modules/npm/node_modules/is-cidr": {
- "version": "5.0.3",
+ "version": "5.0.5",
"inBundle": true,
"license": "BSD-2-Clause",
"dependencies": {
- "cidr-regex": "4.0.3"
+ "cidr-regex": "^4.0.4"
},
"engines": {
"node": ">=14"
@@ -25680,6 +27561,11 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/npm/node_modules/jsbn": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
"node_modules/npm/node_modules/json-parse-even-better-errors": {
"version": "3.0.1",
"inBundle": true,
@@ -25715,38 +27601,38 @@
"license": "MIT"
},
"node_modules/npm/node_modules/libnpmaccess": {
- "version": "8.0.2",
+ "version": "8.0.3",
"inBundle": true,
"license": "ISC",
"dependencies": {
"npm-package-arg": "^11.0.1",
- "npm-registry-fetch": "^16.0.0"
+ "npm-registry-fetch": "^16.2.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/npm/node_modules/libnpmdiff": {
- "version": "6.0.6",
+ "version": "6.0.9",
"inBundle": true,
"license": "ISC",
"dependencies": {
"@npmcli/arborist": "^7.2.1",
"@npmcli/disparity-colors": "^3.0.0",
"@npmcli/installed-package-contents": "^2.0.2",
- "binary-extensions": "^2.2.0",
+ "binary-extensions": "^2.3.0",
"diff": "^5.1.0",
- "minimatch": "^9.0.0",
+ "minimatch": "^9.0.4",
"npm-package-arg": "^11.0.1",
"pacote": "^17.0.4",
- "tar": "^6.2.0"
+ "tar": "^6.2.1"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/npm/node_modules/libnpmexec": {
- "version": "7.0.7",
+ "version": "7.0.10",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -25757,7 +27643,7 @@
"npmlog": "^7.0.1",
"pacote": "^17.0.4",
"proc-log": "^3.0.0",
- "read": "^2.0.0",
+ "read": "^3.0.1",
"read-package-json-fast": "^3.0.2",
"semver": "^7.3.7",
"walk-up-path": "^3.0.1"
@@ -25767,7 +27653,7 @@
}
},
"node_modules/npm/node_modules/libnpmfund": {
- "version": "5.0.4",
+ "version": "5.0.7",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -25778,31 +27664,31 @@
}
},
"node_modules/npm/node_modules/libnpmhook": {
- "version": "10.0.1",
+ "version": "10.0.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
"aproba": "^2.0.0",
- "npm-registry-fetch": "^16.0.0"
+ "npm-registry-fetch": "^16.2.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/npm/node_modules/libnpmorg": {
- "version": "6.0.2",
+ "version": "6.0.3",
"inBundle": true,
"license": "ISC",
"dependencies": {
"aproba": "^2.0.0",
- "npm-registry-fetch": "^16.0.0"
+ "npm-registry-fetch": "^16.2.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/npm/node_modules/libnpmpack": {
- "version": "6.0.6",
+ "version": "6.0.9",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -25816,14 +27702,14 @@
}
},
"node_modules/npm/node_modules/libnpmpublish": {
- "version": "9.0.4",
+ "version": "9.0.5",
"inBundle": true,
"license": "ISC",
"dependencies": {
"ci-info": "^4.0.0",
"normalize-package-data": "^6.0.0",
"npm-package-arg": "^11.0.1",
- "npm-registry-fetch": "^16.0.0",
+ "npm-registry-fetch": "^16.2.0",
"proc-log": "^3.0.0",
"semver": "^7.3.7",
"sigstore": "^2.2.0",
@@ -25834,23 +27720,23 @@
}
},
"node_modules/npm/node_modules/libnpmsearch": {
- "version": "7.0.1",
+ "version": "7.0.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
- "npm-registry-fetch": "^16.0.0"
+ "npm-registry-fetch": "^16.2.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/npm/node_modules/libnpmteam": {
- "version": "6.0.1",
+ "version": "6.0.2",
"inBundle": true,
"license": "ISC",
"dependencies": {
"aproba": "^2.0.0",
- "npm-registry-fetch": "^16.0.0"
+ "npm-registry-fetch": "^16.2.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
@@ -25872,7 +27758,7 @@
}
},
"node_modules/npm/node_modules/lru-cache": {
- "version": "10.1.0",
+ "version": "10.2.0",
"inBundle": true,
"license": "ISC",
"engines": {
@@ -25901,7 +27787,7 @@
}
},
"node_modules/npm/node_modules/minimatch": {
- "version": "9.0.3",
+ "version": "9.0.4",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -26091,7 +27977,7 @@
}
},
"node_modules/npm/node_modules/node-gyp": {
- "version": "10.0.1",
+ "version": "10.1.0",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -26231,10 +28117,11 @@
}
},
"node_modules/npm/node_modules/npm-registry-fetch": {
- "version": "16.1.0",
+ "version": "16.2.0",
"inBundle": true,
"license": "ISC",
"dependencies": {
+ "@npmcli/redact": "^1.1.0",
"make-fetch-happen": "^13.0.0",
"minipass": "^7.0.2",
"minipass-fetch": "^3.0.0",
@@ -26336,11 +28223,11 @@
}
},
"node_modules/npm/node_modules/path-scurry": {
- "version": "1.10.1",
+ "version": "1.10.2",
"inBundle": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "lru-cache": "^9.1.1 || ^10.0.0",
+ "lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
@@ -26351,7 +28238,7 @@
}
},
"node_modules/npm/node_modules/postcss-selector-parser": {
- "version": "6.0.15",
+ "version": "6.0.16",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -26404,11 +28291,11 @@
}
},
"node_modules/npm/node_modules/promzard": {
- "version": "1.0.0",
+ "version": "1.0.1",
"inBundle": true,
"license": "ISC",
"dependencies": {
- "read": "^2.0.0"
+ "read": "^3.0.1"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
@@ -26422,11 +28309,11 @@
}
},
"node_modules/npm/node_modules/read": {
- "version": "2.1.0",
+ "version": "3.0.1",
"inBundle": true,
"license": "ISC",
"dependencies": {
- "mute-stream": "~1.0.0"
+ "mute-stream": "^1.0.0"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
@@ -26481,7 +28368,7 @@
"optional": true
},
"node_modules/npm/node_modules/semver": {
- "version": "7.5.4",
+ "version": "7.6.0",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -26541,16 +28428,16 @@
}
},
"node_modules/npm/node_modules/sigstore": {
- "version": "2.2.0",
+ "version": "2.3.0",
"inBundle": true,
"license": "Apache-2.0",
"dependencies": {
- "@sigstore/bundle": "^2.1.1",
- "@sigstore/core": "^0.2.0",
- "@sigstore/protobuf-specs": "^0.2.1",
- "@sigstore/sign": "^2.2.1",
- "@sigstore/tuf": "^2.3.0",
- "@sigstore/verify": "^0.1.0"
+ "@sigstore/bundle": "^2.3.1",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.1",
+ "@sigstore/sign": "^2.3.0",
+ "@sigstore/tuf": "^2.3.1",
+ "@sigstore/verify": "^1.2.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
@@ -26566,24 +28453,24 @@
}
},
"node_modules/npm/node_modules/socks": {
- "version": "2.7.1",
+ "version": "2.8.3",
"inBundle": true,
"license": "MIT",
"dependencies": {
- "ip": "^2.0.0",
+ "ip-address": "^9.0.5",
"smart-buffer": "^4.2.0"
},
"engines": {
- "node": ">= 10.13.0",
+ "node": ">= 10.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/npm/node_modules/socks-proxy-agent": {
- "version": "8.0.2",
+ "version": "8.0.3",
"inBundle": true,
"license": "MIT",
"dependencies": {
- "agent-base": "^7.0.2",
+ "agent-base": "^7.1.1",
"debug": "^4.3.4",
"socks": "^2.7.1"
},
@@ -26600,13 +28487,22 @@
"spdx-license-ids": "^3.0.0"
}
},
+ "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
"node_modules/npm/node_modules/spdx-exceptions": {
- "version": "2.3.0",
+ "version": "2.5.0",
"inBundle": true,
"license": "CC-BY-3.0"
},
"node_modules/npm/node_modules/spdx-expression-parse": {
- "version": "3.0.1",
+ "version": "4.0.0",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -26615,7 +28511,7 @@
}
},
"node_modules/npm/node_modules/spdx-license-ids": {
- "version": "3.0.16",
+ "version": "3.0.17",
"inBundle": true,
"license": "CC0-1.0"
},
@@ -26692,7 +28588,7 @@
}
},
"node_modules/npm/node_modules/tar": {
- "version": "6.2.0",
+ "version": "6.2.1",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -26804,6 +28700,15 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
"node_modules/npm/node_modules/validate-npm-package-name": {
"version": "5.0.0",
"inBundle": true,
@@ -27026,12 +28931,12 @@
}
},
"node_modules/object-is": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
- "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
+ "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
@@ -27126,28 +29031,29 @@
}
},
"node_modules/object.entries": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz",
- "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==",
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz",
+ "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.fromentries": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz",
- "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -27157,40 +29063,45 @@
}
},
"node_modules/object.groupby": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz",
- "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
"dev": true,
"dependencies": {
- "array.prototype.filter": "^1.0.3",
- "call-bind": "^1.0.5",
+ "call-bind": "^1.0.7",
"define-properties": "^1.2.1",
- "es-abstract": "^1.22.3",
- "es-errors": "^1.0.0"
+ "es-abstract": "^1.23.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
"node_modules/object.hasown": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz",
- "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz",
+ "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==",
"dev": true,
"dependencies": {
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object.values": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz",
- "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
+ "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -27253,32 +29164,32 @@
}
},
"node_modules/open": {
- "version": "8.4.2",
- "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
- "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz",
+ "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==",
"dev": true,
"dependencies": {
- "define-lazy-prop": "^2.0.0",
- "is-docker": "^2.1.1",
- "is-wsl": "^2.2.0"
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "is-wsl": "^3.1.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/openai": {
- "version": "4.28.0",
- "resolved": "https://registry.npmjs.org/openai/-/openai-4.28.0.tgz",
- "integrity": "sha512-JM8fhcpmpGN0vrUwGquYIzdcEQHtFuom6sRCbbCM6CfzZXNuRk33G7KfeRAIfnaCxSpzrP5iHtwJzIm6biUZ2Q==",
+ "version": "4.33.1",
+ "resolved": "https://registry.npmjs.org/openai/-/openai-4.33.1.tgz",
+ "integrity": "sha512-0DH572aSxGTT1JPOXgJQ9mjiuSPg/7scPot8hLc5I1mfQxPxLXTZWJpWerKaIWOuPkR2nrB0SamGDEehH8RuWA==",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
- "digest-fetch": "^1.3.0",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7",
@@ -27289,9 +29200,9 @@
}
},
"node_modules/openai/node_modules/@types/node": {
- "version": "18.19.18",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.18.tgz",
- "integrity": "sha512-80CP7B8y4PzZF0GWx15/gVWRrB5y/bIjNI84NK3cmQJu0WZwvmj2WMA5LcofQFVfLqqCSp545+U2LsrVzX36Zg==",
+ "version": "18.19.31",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.31.tgz",
+ "integrity": "sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -27320,7 +29231,6 @@
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
"integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
- "dev": true,
"dependencies": {
"@aashutoshrathi/word-wrap": "^1.2.3",
"deep-is": "^0.1.3",
@@ -27373,7 +29283,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
"dependencies": {
"p-limit": "^3.0.2"
},
@@ -27388,7 +29297,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
"dependencies": {
"yocto-queue": "^0.1.0"
},
@@ -27403,7 +29311,6 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
"engines": {
"node": ">=10"
},
@@ -27412,16 +29319,20 @@
}
},
"node_modules/p-retry": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
- "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz",
+ "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==",
"dev": true,
"dependencies": {
- "@types/retry": "0.12.0",
+ "@types/retry": "0.12.2",
+ "is-network-error": "^1.0.0",
"retry": "^0.13.1"
},
"engines": {
- "node": ">=8"
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-try": {
@@ -27671,11 +29582,11 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"node_modules/path-scurry": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
- "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
+ "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
"dependencies": {
- "lru-cache": "^9.1.1 || ^10.0.0",
+ "lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
@@ -27706,13 +29617,13 @@
"node": ">=8"
}
},
- "node_modules/path2d-polyfill": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz",
- "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==",
+ "node_modules/path2d": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.1.2.tgz",
+ "integrity": "sha512-LW++2uxgHNL/FANhgGTPo/yDDQcgsVbKotwIVbpTgTBgRlKUpjOpjp3s3+KjG4OWCQ/r6z+WLDljH1/fC03PWw==",
"optional": true,
"engines": {
- "node": ">=8"
+ "node": ">=6"
}
},
"node_modules/pathval": {
@@ -27778,15 +29689,15 @@
}
},
"node_modules/pdfjs-dist": {
- "version": "4.0.379",
- "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.0.379.tgz",
- "integrity": "sha512-6H0Gv1nna+wmrr3CakaKlZ4rbrL8hvGIFAgg4YcoFuGC0HC4B2DVjXEGTFjJEjLlf8nYi3C3/MYRcM5bNx0elA==",
+ "version": "4.1.392",
+ "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.1.392.tgz",
+ "integrity": "sha512-fUV14+CG81uDLjgZ2Nmy35GvJsLIekotJb2VhXAoUfMCrWHhQtPJbqryUuevAdSHyEiAdr675ULikoD087+lMg==",
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"canvas": "^2.11.2",
- "path2d-polyfill": "^2.0.1"
+ "path2d": "^0.1.2"
}
},
"node_modules/pdfjs/node_modules/pako": {
@@ -27794,6 +29705,19 @@
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
},
+ "node_modules/pdfjs/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/pdfjs/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
@@ -28001,9 +29925,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.35",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
- "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
+ "version": "8.4.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+ "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
"funding": [
{
"type": "opencollective",
@@ -28021,16 +29945,16 @@
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-modules-extract-imports": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
- "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz",
+ "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==",
"engines": {
"node": "^10 || ^12 || >= 14"
},
@@ -28039,9 +29963,9 @@
}
},
"node_modules/postcss-modules-local-by-default": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz",
- "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==",
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz",
+ "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==",
"dependencies": {
"icss-utils": "^5.0.0",
"postcss-selector-parser": "^6.0.2",
@@ -28055,9 +29979,9 @@
}
},
"node_modules/postcss-modules-scope": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz",
- "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz",
+ "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==",
"dependencies": {
"postcss-selector-parser": "^6.0.4"
},
@@ -28083,9 +30007,9 @@
}
},
"node_modules/postcss-selector-parser": {
- "version": "6.0.15",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
- "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
+ "version": "6.0.16",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
+ "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -28117,7 +30041,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
"engines": {
"node": ">= 0.8.0"
}
@@ -28214,9 +30137,9 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/property-information": {
- "version": "6.4.1",
- "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz",
- "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
+ "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -28248,9 +30171,9 @@
}
},
"node_modules/prosemirror-history": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.3.2.tgz",
- "integrity": "sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.0.tgz",
+ "integrity": "sha512-UUiGzDVcqo1lovOPdi9YxxUps3oBFWAIYkXLu3Ot+JPv1qzVogRbcizxK3LhHmtaUxclohgiOVesRw5QSlMnbQ==",
"dependencies": {
"prosemirror-state": "^1.2.2",
"prosemirror-transform": "^1.0.0",
@@ -28277,9 +30200,9 @@
}
},
"node_modules/prosemirror-model": {
- "version": "1.19.4",
- "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.19.4.tgz",
- "integrity": "sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ==",
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.20.0.tgz",
+ "integrity": "sha512-q7AY7vMjKYqDCeoedgUiAgrLabliXxndJuuFmcmc2+YU1SblvnOiG2WEACF2lwAZsMlfLpiAilA3L+TWlDqIsQ==",
"dependencies": {
"orderedmap": "^2.0.0"
}
@@ -28313,11 +30236,11 @@
}
},
"node_modules/prosemirror-view": {
- "version": "1.33.1",
- "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.1.tgz",
- "integrity": "sha512-62qkYgSJIkwIMMCpuGuPzc52DiK1Iod6TWoIMxP4ja6BTD4yO8kCUL64PZ/WhH/dJ9fW0CDO39FhH1EMyhUFEg==",
+ "version": "1.33.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.4.tgz",
+ "integrity": "sha512-xQqAhH8/HGleVpKDhQsrd+oqdyeKMxFtdCWDxWMmP+n0k27fBpyUqa8pA+RB5cFY8rqDDc1hll69aRZQa7UaAw==",
"dependencies": {
- "prosemirror-model": "^1.16.0",
+ "prosemirror-model": "^1.20.0",
"prosemirror-state": "^1.0.0",
"prosemirror-transform": "^1.1.0"
}
@@ -28474,6 +30397,14 @@
"node": ">=6"
}
},
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@@ -28539,7 +30470,6 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -28678,9 +30608,9 @@
}
},
"node_modules/rc-util": {
- "version": "5.38.2",
- "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.38.2.tgz",
- "integrity": "sha512-yRGRPKyi84H7NkRSP6FzEIYBdUt4ufdsmXUZ7qM2H5qoByPax70NnGPkfo36N+UKUnUBj2f2Q2eUbwYMuAsIOQ==",
+ "version": "5.39.1",
+ "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.39.1.tgz",
+ "integrity": "sha512-OW/ERynNDgNr4y0oiFmtes3rbEamXw7GHGbkbNd9iRr7kgT03T6fT0b9WpJ3mbxKhyOcAHnGcIoh5u/cjrC2OQ==",
"dependencies": {
"@babel/runtime": "^7.18.3",
"react-is": "^18.2.0"
@@ -28783,12 +30713,12 @@
"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
},
"node_modules/react-datepicker": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.1.0.tgz",
- "integrity": "sha512-8uz+hAOpvHqZGvD4Ky1hJ0/tLI4S9B0Gu9LV7LtLxRKXODs/xrxEay0aMVp7AW9iizTeImZh/6aA00fFaRZpJw==",
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.7.1.tgz",
+ "integrity": "sha512-W6mBZR+3aLTblFs5AFQ5Yp+OltipEtmLnNl0bnsPTuTDanufyz+5ndN7jwhD7EXEQGX4PUnEztWu0CpY+jyNwQ==",
"dependencies": {
"@floating-ui/react": "^0.26.2",
- "classnames": "^2.2.6",
+ "clsx": "^2.1.0",
"date-fns": "^3.3.1",
"prop-types": "^15.7.2",
"react-onclickoutside": "^6.13.0"
@@ -28798,15 +30728,6 @@
"react-dom": "^16.9.0 || ^17 || ^18"
}
},
- "node_modules/react-datepicker/node_modules/date-fns": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz",
- "integrity": "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/kossnocorp"
- }
- },
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@@ -28840,12 +30761,6 @@
"node": ">=6"
}
},
- "node_modules/react-fast-compare": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
- "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
- "dev": true
- },
"node_modules/react-grid-layout": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-1.4.4.tgz",
@@ -28864,17 +30779,17 @@
}
},
"node_modules/react-icons": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz",
- "integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.1.0.tgz",
+ "integrity": "sha512-D3zug1270S4hbSlIRJ0CUS97QE1yNNKDjzQe3HqY0aefp2CBn9VgzgES27sRR2gOvFK+0CNx/BW0ggOESp6fqQ==",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-intersection-observer": {
- "version": "9.8.1",
- "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.8.1.tgz",
- "integrity": "sha512-QzOFdROX8D8MH3wE3OVKH0f3mLjKTtEN1VX/rkNuECCff+aKky0pIjulDhr3Ewqj5el/L+MhBkM3ef0Tbt+qUQ==",
+ "version": "9.8.2",
+ "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.8.2.tgz",
+ "integrity": "sha512-901naEiiZmse3p+AmtbQ3NL9xx+gQ8TXLiGDc+8GiE3JKJkNV3vP737aGuWTAXBA+1QqxPrDDE+fIEgYpGDlrQ==",
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
@@ -28912,13 +30827,13 @@
}
},
"node_modules/react-jsx-parser/node_modules/@types/react": {
- "version": "17.0.75",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.75.tgz",
- "integrity": "sha512-MSA+NzEzXnQKrqpO63CYqNstFjsESgvJAdAyyJ1n6ZQq/GLgf6nOfIKwk+Twuz0L1N6xPe+qz5xRCJrbhMaLsw==",
+ "version": "17.0.80",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.80.tgz",
+ "integrity": "sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA==",
"optional": true,
"dependencies": {
"@types/prop-types": "*",
- "@types/scheduler": "*",
+ "@types/scheduler": "^0.16",
"csstype": "^3.0.2"
}
},
@@ -28931,6 +30846,22 @@
"@types/react": "^17"
}
},
+ "node_modules/react-latex-next": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/react-latex-next/-/react-latex-next-3.0.0.tgz",
+ "integrity": "sha512-x70f1b1G7TronVigsRgKHKYYVUNfZk/3bciFyYX1lYLQH2y3/TXku3+5Vap8MDbJhtopePSYBsYWS6jhzIdz+g==",
+ "dependencies": {
+ "katex": "^0.16.0"
+ },
+ "engines": {
+ "node": ">=12",
+ "npm": ">=5"
+ },
+ "peerDependencies": {
+ "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-loading": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/react-loading/-/react-loading-2.0.3.tgz",
@@ -29016,21 +30947,6 @@
"react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x"
}
},
- "node_modules/react-popper": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
- "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
- "dev": true,
- "dependencies": {
- "react-fast-compare": "^3.0.1",
- "warning": "^4.0.2"
- },
- "peerDependencies": {
- "@popperjs/core": "^2.0.0",
- "react": "^16.8.0 || ^17 || ^18",
- "react-dom": "^16.8.0 || ^17 || ^18"
- }
- },
"node_modules/react-resizable": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-3.0.5.tgz",
@@ -29064,9 +30980,9 @@
}
},
"node_modules/react-smooth": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.0.tgz",
- "integrity": "sha512-2NMXOBY1uVUQx1jBeENGA497HK20y6CPGYL1ZnJLeoQ8rrc3UfmOM82sRxtzpcoCkUMy4CS0RGylfuVhuFjBgg==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz",
+ "integrity": "sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==",
"dependencies": {
"fast-equals": "^5.0.1",
"prop-types": "^15.8.1",
@@ -29085,6 +31001,22 @@
"node": ">=6.0.0"
}
},
+ "node_modules/react-textarea-autosize": {
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz",
+ "integrity": "sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "use-composed-ref": "^1.3.0",
+ "use-latest": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-themeable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/react-themeable/-/react-themeable-1.1.0.tgz",
@@ -29120,7 +31052,6 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/react-type-animation/-/react-type-animation-3.2.0.tgz",
"integrity": "sha512-WXTe0i3rRNKjmggPvT5ntye1QBt0ATGbijeW6V3cQe2W0jaMABXXlPPEdtofnS9tM7wSRHchEvI9SUw+0kUohw==",
- "dev": true,
"peerDependencies": {
"prop-types": "^15.5.4",
"react": ">= 15.0.0",
@@ -29153,16 +31084,41 @@
}
},
"node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
+ "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
"dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
+ "abort-controller": "^3.0.0",
+ "buffer": "^6.0.3",
+ "events": "^3.3.0",
+ "process": "^0.11.10",
+ "string_decoder": "^1.3.0"
},
"engines": {
- "node": ">= 6"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/readable-stream/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
}
},
"node_modules/readable-web-to-node-stream": {
@@ -29180,6 +31136,19 @@
"url": "https://github.com/sponsors/Borewit"
}
},
+ "node_modules/readable-web-to-node-stream/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/readdir-glob": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
@@ -29216,9 +31185,9 @@
"integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg=="
},
"node_modules/recharts": {
- "version": "2.12.1",
- "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.1.tgz",
- "integrity": "sha512-35vUCEBPf+pM+iVgSgVTn86faKya5pc4JO6cYJL63qOK2zDEyzDn20Tdj+CDI/3z+VcpKyQ8ZBQ9OiQ+vuAbjg==",
+ "version": "2.12.5",
+ "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.5.tgz",
+ "integrity": "sha512-Cy+BkqrFIYTHJCyKHJEPvbHE2kVQEP6PKbOHJ8ztRGTAhvHuUnCwDaKVb13OwRFZ0QNUk1QvGTDdgWSMbuMtKw==",
"dependencies": {
"clsx": "^2.0.0",
"eventemitter3": "^4.0.1",
@@ -29270,16 +31239,16 @@
}
},
"node_modules/reflect.getprototypeof": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz",
- "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz",
+ "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.5",
+ "call-bind": "^1.0.7",
"define-properties": "^1.2.1",
- "es-abstract": "^1.22.3",
- "es-errors": "^1.0.0",
- "get-intrinsic": "^1.2.3",
+ "es-abstract": "^1.23.1",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
"globalthis": "^1.0.3",
"which-builtin-type": "^1.1.3"
},
@@ -29383,6 +31352,24 @@
"jsesc": "bin/jsesc"
}
},
+ "node_modules/rehype-katex": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz",
+ "integrity": "sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/katex": "^0.16.0",
+ "hast-util-from-html-isomorphic": "^2.0.0",
+ "hast-util-to-text": "^4.0.0",
+ "katex": "^0.16.0",
+ "unist-util-visit-parents": "^6.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/rehype-raw": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz",
@@ -29422,6 +31409,21 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/remark-math": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz",
+ "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-math": "^3.0.0",
+ "micromark-extension-math": "^3.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/remark-parse": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
@@ -29745,6 +31747,15 @@
"node": ">=8"
}
},
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
"node_modules/resolve-protobuf-schema": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
@@ -29780,6 +31791,12 @@
"node": ">=8"
}
},
+ "node_modules/restore-cursor/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
"node_modules/retry": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
@@ -29793,16 +31810,15 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
"engines": {
"iojs": ">=1.0.0",
"node": ">=0.10.0"
}
},
"node_modules/reveal.js": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-5.0.4.tgz",
- "integrity": "sha512-480pVhre9SXWuE4QbDwG0nPrip3TkifflqaKQWF8Ynf4iYIUBfgu5leeMso0srubQsZQ+G2OzktAfAkrvBY0Ww==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-5.1.0.tgz",
+ "integrity": "sha512-KDt7m0+xwKV6nAZt4CNPVFBf42sTKRQapg0bGGKB5PKO5XvChnMfwlZkybydHiQJ7p5+6LbHKRGrhXODdoNIaA==",
"engines": {
"node": ">=18.0.0"
}
@@ -29824,41 +31840,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/rimraf/node_modules/glob": {
- "version": "10.3.10",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
- "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^2.3.5",
- "minimatch": "^9.0.1",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
- "path-scurry": "^1.10.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/rimraf/node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/robust-predicates": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz",
@@ -29875,6 +31856,18 @@
"integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==",
"dev": true
},
+ "node_modules/run-applescript": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
+ "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/run-async": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
@@ -29888,7 +31881,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -29930,14 +31922,25 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
+ "node_modules/sade": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+ "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+ "dependencies": {
+ "mri": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/safe-array-concat": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz",
- "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+ "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.5",
- "get-intrinsic": "^1.2.2",
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4",
"has-symbols": "^1.0.3",
"isarray": "^2.0.5"
},
@@ -29990,9 +31993,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/sass": {
- "version": "1.71.1",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz",
- "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==",
+ "version": "1.75.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz",
+ "integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==",
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
@@ -30006,28 +32009,28 @@
}
},
"node_modules/sass-loader": {
- "version": "13.3.3",
- "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz",
- "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==",
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.2.0.tgz",
+ "integrity": "sha512-jxmjDXD9OYNDb2bp9JvopdE6QjecQY9beTWik/6sEHrsMxyo90Gyc471A4NUz60NLs4WsAh6yVtIvhLwEZcXeg==",
"dependencies": {
"neo-async": "^2.6.2"
},
"engines": {
- "node": ">= 14.15.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "fibers": ">= 3.1.0",
+ "@rspack/core": "0.x || 1.x",
"node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
"sass": "^1.3.0",
"sass-embedded": "*",
"webpack": "^5.0.0"
},
"peerDependenciesMeta": {
- "fibers": {
+ "@rspack/core": {
"optional": true
},
"node-sass": {
@@ -30038,6 +32041,9 @@
},
"sass-embedded": {
"optional": true
+ },
+ "webpack": {
+ "optional": true
}
}
},
@@ -30121,11 +32127,6 @@
"integrity": "sha512-SbT/smRJjkvvdHSEdAYAplosVkrtaSwwgUlnQCOuDS5sOKNjrS/eYCMvKeV6+YxK5cCOCsOJZd3vltrXatFp+g==",
"dev": true
},
- "node_modules/sdp": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz",
- "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="
- },
"node_modules/section-iterator": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/section-iterator/-/section-iterator-2.0.0.tgz",
@@ -30224,6 +32225,14 @@
"randombytes": "^2.1.0"
}
},
+ "node_modules/serialize-to-js": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.1.2.tgz",
+ "integrity": "sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
"node_modules/serializr": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/serializr/-/serializr-3.0.2.tgz",
@@ -30327,16 +32336,16 @@
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
},
"node_modules/set-function-length": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
- "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dependencies": {
- "define-data-property": "^1.1.2",
+ "define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.3",
+ "get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.1"
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -30485,11 +32494,11 @@
}
},
"node_modules/side-channel": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
- "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+ "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
@@ -30507,9 +32516,15 @@
"integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ=="
},
"node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
},
"node_modules/simple-concat": {
"version": "1.0.1",
@@ -30621,6 +32636,14 @@
"resolved": "https://registry.npmjs.org/skmeans/-/skmeans-0.9.7.tgz",
"integrity": "sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg=="
},
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/slice-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
@@ -30645,9 +32668,9 @@
}
},
"node_modules/socket.io": {
- "version": "4.7.4",
- "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz",
- "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==",
+ "version": "4.7.5",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
+ "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==",
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
@@ -30691,9 +32714,9 @@
}
},
"node_modules/socket.io-client": {
- "version": "4.7.4",
- "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.4.tgz",
- "integrity": "sha512-wh+OkeF0rAVCrABWQBaEjLfb7DVPotMbu0cgWgyR0v6eA4EoVnAwcIeIbcdTE3GT/H3kbdLl7OoH2+asoDRIIg==",
+ "version": "4.7.5",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz",
+ "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
@@ -30777,9 +32800,9 @@
}
},
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"engines": {
"node": ">=0.10.0"
}
@@ -30848,6 +32871,41 @@
"wbuf": "^1.7.3"
}
},
+ "node_modules/spdy-transport/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/speech-rule-engine": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
+ "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
+ "dependencies": {
+ "commander": "9.2.0",
+ "wicked-good-xpath": "1.3.0",
+ "xmldom-sre": "0.1.31"
+ },
+ "bin": {
+ "sre": "bin/sre"
+ }
+ },
+ "node_modules/speech-rule-engine/node_modules/commander": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
+ "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
+ "engines": {
+ "node": "^12.20.0 || >=14"
+ }
+ },
"node_modules/splaytree": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/splaytree/-/splaytree-3.1.2.tgz",
@@ -30967,6 +33025,19 @@
"readable-stream": "^3.5.0"
}
},
+ "node_modules/stream-browserify/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/stream-parser": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz",
@@ -31017,16 +33088,19 @@
}
},
"node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
},
"engines": {
- "node": ">=8"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/string-width-cjs": {
@@ -31048,10 +33122,30 @@
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
- "node_modules/string-width/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ "node_modules/string-width/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
},
"node_modules/string.prototype.codepointat": {
"version": "0.2.1",
@@ -31059,34 +33153,41 @@
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
},
"node_modules/string.prototype.matchall": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
- "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==",
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz",
+ "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
"has-symbols": "^1.0.3",
- "internal-slot": "^1.0.5",
- "regexp.prototype.flags": "^1.5.0",
- "set-function-name": "^2.0.0",
- "side-channel": "^1.0.4"
+ "internal-slot": "^1.0.7",
+ "regexp.prototype.flags": "^1.5.2",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trim": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz",
- "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==",
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+ "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.0",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -31096,37 +33197,40 @@
}
},
"node_modules/string.prototype.trimend": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz",
- "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+ "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz",
- "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/stringify-entities": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz",
- "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
"dependencies": {
"character-entities-html4": "^2.0.0",
"character-entities-legacy": "^3.0.0"
@@ -31223,7 +33327,6 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true,
"engines": {
"node": ">=8"
},
@@ -31248,27 +33351,27 @@
}
},
"node_modules/style-loader": {
- "version": "3.3.4",
- "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz",
- "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz",
+ "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==",
"dev": true,
"engines": {
- "node": ">= 12.13.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "^5.0.0"
+ "webpack": "^5.27.0"
}
},
"node_modules/style-to-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz",
- "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz",
+ "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==",
"dependencies": {
- "inline-style-parser": "0.2.2"
+ "inline-style-parser": "0.2.3"
}
},
"node_modules/styled-components": {
@@ -31298,6 +33401,14 @@
"react-dom": ">= 16.8.0"
}
},
+ "node_modules/styled-components/node_modules/@emotion/is-prop-valid": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
+ "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.1"
+ }
+ },
"node_modules/styled-components/node_modules/@emotion/unitless": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
@@ -31496,9 +33607,9 @@
}
},
"node_modules/tar": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
- "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@@ -31521,15 +33632,23 @@
"streamx": "^2.15.0"
}
},
+ "node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/tar/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/terser": {
- "version": "5.27.2",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.2.tgz",
- "integrity": "sha512-sHXmLSkImesJ4p5apTeT63DsV4Obe1s37qT8qvwHRmVxKTBH7Rv9Wr26VcAMmLbmk9UliiwK8z+657NyJHHy/w==",
+ "version": "5.30.3",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz",
+ "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@@ -31640,9 +33759,17 @@
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
},
"node_modules/tiny-invariant": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
- "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
+ },
+ "node_modules/tiny-lru": {
+ "version": "11.2.5",
+ "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.2.5.tgz",
+ "integrity": "sha512-JpqM0K33lG6iQGKiigcwuURAKZlq6rHXfrgeL4/I8/REoyJTGU+tEMszvT/oTRVHG2OiylhGDjqPp1jWMlr3bw==",
+ "engines": {
+ "node": ">=12"
+ }
},
"node_modules/tinycolor2": {
"version": "1.6.0",
@@ -31844,6 +33971,25 @@
"resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
"integrity": "sha512-6C5h3CE+0qjGp+YKYTs74xR0k/Nw/ePtl/Lp6CCf44hqBQ66qnH1sDFR5mV/Gc48EsrHLB53lCFSffQCkka3kg=="
},
+ "node_modules/ts-api-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/ts-dedent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
+ "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==",
+ "engines": {
+ "node": ">=6.10"
+ }
+ },
"node_modules/ts-loader": {
"version": "9.5.1",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz",
@@ -32428,6 +34574,14 @@
"resolved": "https://registry.npmjs.org/turf-jsts/-/turf-jsts-1.2.3.tgz",
"integrity": "sha512-Ja03QIJlPuHt4IQ2FfGex4F4JAr8m3jpaHbFbQrgwr7s7L6U8ocrHiF3J1+wf9jzhGKxvDeaCAnGDot8OjGFyA=="
},
+ "node_modules/tweakpane": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/tweakpane/-/tweakpane-4.0.3.tgz",
+ "integrity": "sha512-BlcWOAe8oe4c+k9pmLBARGdWB6MVZMszayekkixQXTgkxTaYoTUpHpwVEp+3HkoamZkomodpbBf0CkguIHTgLg==",
+ "funding": {
+ "url": "https://github.com/sponsors/cocopon"
+ }
+ },
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
@@ -32437,7 +34591,6 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
"dependencies": {
"prelude-ls": "^1.2.1"
},
@@ -32449,7 +34602,6 @@
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
- "dev": true,
"engines": {
"node": ">=10"
},
@@ -32523,9 +34675,9 @@
}
},
"node_modules/typed-array-length": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz",
- "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
+ "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
@@ -32543,9 +34695,9 @@
}
},
"node_modules/typescript": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
- "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "version": "5.4.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+ "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -32559,6 +34711,32 @@
"resolved": "https://registry.npmjs.org/typescript-collections/-/typescript-collections-1.3.3.tgz",
"integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ=="
},
+ "node_modules/typescript-eslint": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.9.0.tgz",
+ "integrity": "sha512-7iTn9c10teHHCys5Ud/yaJntXZrjt3h2mrx3feJGBOLgQkF3TB1X89Xs3aVQ/GgdXRAXpk2bPTdpRwHP4YkUow==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "7.9.0",
+ "@typescript-eslint/parser": "7.9.0",
+ "@typescript-eslint/utils": "7.9.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/typescript-language-server": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/typescript-language-server/-/typescript-language-server-4.3.3.tgz",
@@ -32588,6 +34766,11 @@
"resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
"integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg=="
},
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
+ },
"node_modules/uid-safe": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
@@ -32716,6 +34899,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/unist-util-find-after": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz",
+ "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/unist-util-is": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
@@ -32793,9 +34989,9 @@
}
},
"node_modules/universal-user-agent": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
- "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ=="
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
+ "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
},
"node_modules/universalify": {
"version": "2.0.1",
@@ -32935,11 +35131,11 @@
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
},
"node_modules/url/node_modules/qs": {
- "version": "6.11.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
- "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
+ "version": "6.12.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz",
+ "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==",
"dependencies": {
- "side-channel": "^1.0.4"
+ "side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
@@ -32948,6 +35144,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/use-composed-ref": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz",
+ "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/use-isomorphic-layout-effect": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
@@ -32961,6 +35165,22 @@
}
}
},
+ "node_modules/use-latest": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz",
+ "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==",
+ "dependencies": {
+ "use-isomorphic-layout-effect": "^1.1.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
@@ -33019,6 +35239,23 @@
"uuid": "dist/bin/uuid"
}
},
+ "node_modules/uvu": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
+ "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
+ "dependencies": {
+ "dequal": "^2.0.0",
+ "diff": "^5.0.0",
+ "kleur": "^4.0.3",
+ "sade": "^1.7.3"
+ },
+ "bin": {
+ "uvu": "bin.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/v8-compile-cache": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz",
@@ -33106,9 +35343,9 @@
}
},
"node_modules/victory-vendor": {
- "version": "36.9.1",
- "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.1.tgz",
- "integrity": "sha512-+pZIP+U3pEJdDCeFmsXwHzV7vNHQC/eIbHklfe2ZCZqayYRH7lQbHcVgsJ0XOOv27hWs4jH4MONgXxHMObTMSA==",
+ "version": "36.9.2",
+ "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",
+ "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==",
"dependencies": {
"@types/d3-array": "^3.0.3",
"@types/d3-ease": "^3.0.0",
@@ -33170,9 +35407,9 @@
}
},
"node_modules/watchpack": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
- "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz",
+ "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==",
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -33215,6 +35452,11 @@
"node": ">= 8"
}
},
+ "node_modules/web-worker": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz",
+ "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA=="
+ },
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
@@ -33224,25 +35466,25 @@
}
},
"node_modules/webpack": {
- "version": "5.90.3",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz",
- "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==",
+ "version": "5.91.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz",
+ "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==",
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.5",
- "@webassemblyjs/ast": "^1.11.5",
- "@webassemblyjs/wasm-edit": "^1.11.5",
- "@webassemblyjs/wasm-parser": "^1.11.5",
+ "@webassemblyjs/ast": "^1.12.1",
+ "@webassemblyjs/wasm-edit": "^1.12.1",
+ "@webassemblyjs/wasm-parser": "^1.12.1",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.9.0",
"browserslist": "^4.21.10",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.15.0",
+ "enhanced-resolve": "^5.16.0",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
- "graceful-fs": "^4.2.9",
+ "graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
@@ -33250,7 +35492,7 @@
"schema-utils": "^3.2.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.3.10",
- "watchpack": "^2.4.0",
+ "watchpack": "^2.4.1",
"webpack-sources": "^3.2.3"
},
"bin": {
@@ -33341,13 +35583,14 @@
}
},
"node_modules/webpack-dev-middleware": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.0.0.tgz",
- "integrity": "sha512-tZ5hqsWwww/8DislmrzXE3x+4f+v10H1z57mA2dWFrILb4i3xX+dPhTkcdR0DLyQztrhF2AUmO5nN085UYjd/Q==",
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.2.1.tgz",
+ "integrity": "sha512-hRLz+jPQXo999Nx9fXVdKlg/aehsw1ajA9skAneGmT03xwmyuhvF93p6HUKKbWhXdcERtGTzUCtIQr+2IQegrA==",
"dependencies": {
"colorette": "^2.0.10",
"memfs": "^4.6.0",
"mime-types": "^2.1.31",
+ "on-finished": "^2.4.1",
"range-parser": "^1.2.1",
"schema-utils": "^4.0.0"
},
@@ -33368,9 +35611,9 @@
}
},
"node_modules/webpack-dev-middleware/node_modules/memfs": {
- "version": "4.7.7",
- "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.7.7.tgz",
- "integrity": "sha512-x9qc6k88J/VVwnfTkJV8pRRswJ2156Rc4w5rciRqKceFDZ0y1MqsNL9pkg5sE0GOcDzZYbonreALhaHzg1siFw==",
+ "version": "4.8.2",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.8.2.tgz",
+ "integrity": "sha512-j4WKth315edViMBGkHW6NTF0QBjsTrcRDmYNcGsPq+ozMEyCCCIlX2d2mJ5wuh6iHvJ3FevUrr48v58YRqVdYg==",
"dependencies": {
"tslib": "^2.0.0"
},
@@ -33383,54 +35626,54 @@
}
},
"node_modules/webpack-dev-server": {
- "version": "4.15.1",
- "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz",
- "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==",
- "dev": true,
- "dependencies": {
- "@types/bonjour": "^3.5.9",
- "@types/connect-history-api-fallback": "^1.3.5",
- "@types/express": "^4.17.13",
- "@types/serve-index": "^1.9.1",
- "@types/serve-static": "^1.13.10",
- "@types/sockjs": "^0.3.33",
- "@types/ws": "^8.5.5",
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz",
+ "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==",
+ "dev": true,
+ "dependencies": {
+ "@types/bonjour": "^3.5.13",
+ "@types/connect-history-api-fallback": "^1.5.4",
+ "@types/express": "^4.17.21",
+ "@types/serve-index": "^1.9.4",
+ "@types/serve-static": "^1.15.5",
+ "@types/sockjs": "^0.3.36",
+ "@types/ws": "^8.5.10",
"ansi-html-community": "^0.0.8",
- "bonjour-service": "^1.0.11",
- "chokidar": "^3.5.3",
+ "bonjour-service": "^1.2.1",
+ "chokidar": "^3.6.0",
"colorette": "^2.0.10",
"compression": "^1.7.4",
"connect-history-api-fallback": "^2.0.0",
"default-gateway": "^6.0.3",
"express": "^4.17.3",
"graceful-fs": "^4.2.6",
- "html-entities": "^2.3.2",
+ "html-entities": "^2.4.0",
"http-proxy-middleware": "^2.0.3",
- "ipaddr.js": "^2.0.1",
- "launch-editor": "^2.6.0",
- "open": "^8.0.9",
- "p-retry": "^4.5.0",
- "rimraf": "^3.0.2",
- "schema-utils": "^4.0.0",
- "selfsigned": "^2.1.1",
+ "ipaddr.js": "^2.1.0",
+ "launch-editor": "^2.6.1",
+ "open": "^10.0.3",
+ "p-retry": "^6.2.0",
+ "rimraf": "^5.0.5",
+ "schema-utils": "^4.2.0",
+ "selfsigned": "^2.4.1",
"serve-index": "^1.9.1",
"sockjs": "^0.3.24",
"spdy": "^4.0.2",
- "webpack-dev-middleware": "^5.3.1",
- "ws": "^8.13.0"
+ "webpack-dev-middleware": "^7.1.0",
+ "ws": "^8.16.0"
},
"bin": {
"webpack-dev-server": "bin/webpack-dev-server.js"
},
"engines": {
- "node": ">= 12.13.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "^4.37.0 || ^5.0.0"
+ "webpack": "^5.0.0"
},
"peerDependenciesMeta": {
"webpack": {
@@ -33441,36 +35684,6 @@
}
}
},
- "node_modules/webpack-dev-server/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/webpack-dev-server/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/webpack-dev-server/node_modules/ipaddr.js": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz",
@@ -33480,61 +35693,10 @@
"node": ">= 10"
}
},
- "node_modules/webpack-dev-server/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/webpack-dev-server/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz",
- "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==",
- "dev": true,
- "dependencies": {
- "colorette": "^2.0.10",
- "memfs": "^3.4.3",
- "mime-types": "^2.1.31",
- "range-parser": "^1.2.1",
- "schema-utils": "^4.0.0"
- },
- "engines": {
- "node": ">= 12.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- },
- "peerDependencies": {
- "webpack": "^4.0.0 || ^5.0.0"
- }
- },
"node_modules/webpack-hot-middleware": {
"version": "2.26.1",
"resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz",
"integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==",
- "dev": true,
"dependencies": {
"ansi-html-community": "0.0.8",
"html-entities": "^2.1.0",
@@ -33599,18 +35761,6 @@
"url": "https://opencollective.com/webpack"
}
},
- "node_modules/webrtc-adapter": {
- "version": "8.2.3",
- "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-8.2.3.tgz",
- "integrity": "sha512-gnmRz++suzmvxtp3ehQts6s2JtAGPuDPjA1F3a9ckNpG1kYdYuHWYpazoAnL9FS5/B21tKlhkorbdCXat0+4xQ==",
- "dependencies": {
- "sdp": "^3.2.0"
- },
- "engines": {
- "node": ">=6.0.0",
- "npm": ">=3.10.0"
- }
- },
"node_modules/websocket-driver": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
@@ -33747,30 +35897,33 @@
}
},
"node_modules/which-collection": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
- "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
"dependencies": {
- "is-map": "^2.0.1",
- "is-set": "^2.0.1",
- "is-weakmap": "^2.0.1",
- "is-weakset": "^2.0.1"
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-typed-array": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz",
- "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
+ "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
"dependencies": {
- "available-typed-arrays": "^1.0.6",
- "call-bind": "^1.0.5",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
- "has-tostringtag": "^1.0.1"
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -33779,6 +35932,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/wicked-good-xpath": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
+ "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
+ },
"node_modules/wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
@@ -33787,6 +35945,24 @@
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
+ "node_modules/wide-align/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/wide-align/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/wikijs": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/wikijs/-/wikijs-6.4.1.tgz",
@@ -33861,16 +36037,16 @@
"dev": true
},
"node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
@@ -33923,36 +36099,60 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": {
- "color-convert": "^2.0.1"
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "engines": {
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dependencies": {
- "color-name": "~1.1.4"
+ "ansi-regex": "^6.0.1"
},
"engines": {
- "node": ">=7.0.0"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -34054,6 +36254,14 @@
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"dev": true
},
+ "node_modules/xmldom-sre": {
+ "version": "0.1.31",
+ "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
+ "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
+ "engines": {
+ "node": ">=0.1"
+ }
+ },
"node_modules/xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
@@ -34153,6 +36361,24 @@
"node": ">=8"
}
},
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
@@ -34174,16 +36400,16 @@
}
},
"node_modules/zip-stream": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz",
- "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz",
+ "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==",
"dependencies": {
- "archiver-utils": "^4.0.1",
- "compress-commons": "^5.0.1",
- "readable-stream": "^3.6.0"
+ "archiver-utils": "^5.0.0",
+ "compress-commons": "^6.0.2",
+ "readable-stream": "^4.0.0"
},
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 14"
}
},
"node_modules/zwitch": {
diff --git a/package.json b/package.json
index b27d50d54..af3e8275d 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,9 @@
"version": "1.0.0",
"description": "",
"main": "index.js",
+ "engines": {
+ "node": ">=12.0.0"
+ },
"browser": {
"child_process": false
},
@@ -10,8 +13,8 @@
"child_process": "empty"
},
"scripts": {
- "start-release": "cross-env RELEASE=true USE_AZURE=false NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts",
- "start-release-debug": "cross-env RELEASE=true USE_AZURE=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --inspect -- src/server/index.ts",
+ "start-release": "cross-env RELEASE=true USE_AZURE=false NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug -- src/server/index.ts",
+ "start-release-debug": "cross-env RELEASE=true USE_AZURE=false NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --inspect -- src/server/index.ts",
"start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only -- src/server/index.ts",
"debug": "cross-env NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --transpile-only --inspect -- src/server/index.ts",
"monitor": "cross-env MONITORED=true NODE_OPTIONS=--max_old_space_size=4096 ts-node src/server/index.ts",
@@ -20,6 +23,7 @@
"tsc": "tsc -t es5"
},
"devDependencies": {
+ "@eslint/js": "^9.1.1",
"@types/adm-zip": "^0.5.5",
"@types/animejs": "^3.1.12",
"@types/archiver": "^6.0.2",
@@ -51,7 +55,7 @@
"@types/react": "^18.2.41",
"@types/react-autosuggest": "^10.1.10",
"@types/react-color": "^3.0.10",
- "@types/react-datepicker": "^4.19.3",
+ "@types/react-datepicker": "^6.2.0",
"@types/react-dom": "^18.2.17",
"@types/react-grid-layout": "^1.3.5",
"@types/react-measure": "^2.0.12",
@@ -62,33 +66,31 @@
"@types/uuid": "^9.0.7",
"@types/valid-url": "^1.0.7",
"@types/webpack": "^5.28.5",
- "@types/webpack-hot-middleware": "^2.25.9",
"@types/youtube": "0.0.50",
"chai": "^5.0.0",
"cross-env": "^7.0.3",
- "dotenv": "^16.3.1",
- "eslint": "^8.55.0",
+ "eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-node": "^4.1.0",
"eslint-config-prettier": "^9.1.0",
- "eslint-plugin-import": "^2.29.0",
+ "eslint-import-resolver-typescript": "^3.6.1",
+ "eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.0.1",
- "eslint-plugin-react": "^7.33.2",
+ "eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "globals": "^15.1.0",
"jsdom": "^24.0.0",
"mocha": "^10.2.0",
"prettier": "^3.1.0",
- "react-type-animation": "^3.2.0",
"scss-loader": "0.0.1",
- "style-loader": "^3.3.3",
+ "style-loader": "^4.0.0",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.1",
"ts-node-dev": "^2.0.0",
- "typescript": "^5.3.3",
- "webpack-dev-server": "^4.15.1",
- "webpack-hot-middleware": "^2.25.4"
+ "typescript-eslint": "^7.8.0",
+ "webpack-dev-server": "^5.0.4"
},
"dependencies": {
"@adobe/react-spectrum": "^3.32.2",
@@ -111,8 +113,9 @@
"@internationalized/date": "^3.5.0",
"@mui/icons-material": "^5.14.19",
"@mui/material": "^5.14.19",
- "@octokit/core": "^5.0.2",
+ "@octokit/core": "^6.0.1",
"@react-google-maps/api": "^2.19.2",
+ "@react-spring/web": "^9.7.3",
"@turf/turf": "^6.5.0",
"@types/bezier-js": "^4.1.3",
"@types/brotli": "^1.3.4",
@@ -125,20 +128,24 @@
"@types/find-in-files": "^0.5.3",
"@types/fluent-ffmpeg": "^2.1.24",
"@types/formidable": "3.4.5",
+ "@types/geojson": "^7946.0.14",
"@types/google-maps": "^3.2.6",
- "@types/mapbox-gl": "^2.7.19",
+ "@types/mapbox-gl": "^3.1.0",
"@types/pdf-parse": "^1.1.4",
"@types/reveal": "^4.2.0",
"@types/supercluster": "^7.1.3",
- "@types/web": "^0.0.138",
+ "@types/web": "^0.0.143",
+ "@types/webpack-hot-middleware": "^2.25.9",
+ "@typescript-eslint/parser": "^7.8.0",
"@webscopeio/react-textarea-autocomplete": "^4.9.2",
"adm-zip": "^0.5.10",
- "archiver": "^6.0.1",
+ "archiver": "^7.0.1",
"async": "^3.2.5",
"axios": "^1.6.2",
"babel": "^6.23.0",
"babel-loader": "^9.1.3",
"bcrypt-nodejs": "0.0.3",
+ "better-react-mathjax": "^2.0.3",
"bezier-curve": "^1.0.0",
"bezier-js": "^6.1.4",
"bingmaps-react": "^1.2.10",
@@ -161,18 +168,23 @@
"cookie-session": "^2.0.0",
"core-js": "^3.33.3",
"cors": "^2.8.5",
- "css-loader": "^6.8.1",
+ "css-loader": "^7.0.0",
+ "csstype": "^3.1.3",
"csv-parser": "^3.0.0",
"csv-stringify": "^6.4.4",
+ "csvtojson": "^2.0.10",
"D": "^1.0.0",
"d3": "^7.8.5",
"depcheck": "^1.4.7",
+ "dotenv": "^16.3.1",
+ "eslint-webpack-plugin": "^4.1.0",
"exif": "^0.6.0",
"exifr": "^7.1.3",
"express": "^4.18.2",
"express-flash": "0.0.2",
"express-session": "^1.17.3",
"express-validator": "^7.0.1",
+ "extract-colors": "^4.0.2",
"ffmpeg": "0.0.4",
"file-loader": "^6.2.0",
"file-saver": "^2.0.5",
@@ -182,6 +194,7 @@
"fluent-ffmpeg": "^2.1.2",
"forever-agent": "^0.6.1",
"fork-ts-checker-webpack-plugin": "^9.0.2",
+ "form-data": "^4.0.0",
"formidable": "3.5.1",
"function-plot": "^1.23.3",
"golden-layout": "^2.6.0",
@@ -208,9 +221,11 @@
"jszip": "^3.10.1",
"lodash": "^4.17.21",
"mapbox-gl": "^3.0.1",
+ "markdown-it": "^14.1.0",
"mathquill": "^0.10.1-a",
"md5-file": "^5.0.0",
"memorystream": "^0.3.1",
+ "mermaid": "^10.9.0",
"mobile-detect": "^1.4.5",
"mobx": "^6.12.0",
"mobx-react": "^9.1.0",
@@ -220,9 +235,8 @@
"node-stream-zip": "^1.15.0",
"nodemailer": "^6.9.7",
"nodemon": "^3.0.2",
- "normalize.css": "^8.0.1",
"npm": "^10.2.5",
- "openai": "^4.20.1",
+ "openai": "^4.26.0",
"p-limit": "^5.0.0",
"passport": "^0.7.0",
"passport-google-oauth20": "^2.0.0",
@@ -258,23 +272,28 @@
"react-grid-layout": "^1.4.4",
"react-icons": "^5.0.1",
"react-jsx-parser": "^1.29.0",
+ "react-latex-next": "^3.0.0",
"react-loading": "^2.0.3",
"react-map-gl": "^7.1.6",
"react-markdown": "^9.0.1",
"react-measure": "^2.5.2",
"react-resizable": "^3.0.5",
"react-select": "^5.8.0",
+ "react-textarea-autosize": "^8.5.3",
+ "react-type-animation": "^3.2.0",
"react-xarrows": "^2.0.2",
"readline": "^1.3.0",
"recharts": "^2.10.3",
+ "rehype-katex": "^7.0.0",
"rehype-raw": "^7.0.0",
"remark-gfm": "^4.0.0",
+ "remark-math": "^6.0.0",
"request": "^2.88.2",
"request-promise": "^4.2.6",
"reveal.js": "^5.0.2",
"rimraf": "^5.0.5",
"sass": "^1.69.5",
- "sass-loader": "^13.3.2",
+ "sass-loader": "^14.2.0",
"serializr": "^3.0.2",
"shelljs": "^0.8.5",
"socket.io": "^4.7.2",
@@ -287,6 +306,7 @@
"tough-cookie": "^4.1.3",
"tslint": "^6.1.3",
"tslint-loader": "^3.5.4",
+ "typescript": "^5.3.3",
"typescript-collections": "^1.3.3",
"typescript-language-server": "^4.1.3",
"uninstall": "^0.0.0",
@@ -299,7 +319,7 @@
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-middleware": "^7.0.0",
- "webrtc-adapter": "^8.2.3",
+ "webpack-hot-middleware": "^2.25.4",
"wikijs": "^6.4.1",
"words-to-numbers": "^1.5.1",
"xoauth2": "^1.2.0",
diff --git a/report.20231129.000028.55430.0.001.json b/report.20231129.000028.55430.0.001.json
deleted file mode 100644
index a29d550ae..000000000
--- a/report.20231129.000028.55430.0.001.json
+++ /dev/null
@@ -1,1343 +0,0 @@
-
-{
- "header": {
- "reportVersion": 1,
- "event": "Allocation failed - JavaScript heap out of memory",
- "trigger": "FatalError",
- "filename": "report.20231129.000028.55430.0.001.json",
- "dumpEventTime": "2023-11-29T00:00:28Z",
- "dumpEventTimeStamp": "1701234028056",
- "processId": 55430,
- "cwd": "/Users/sarah/Desktop/dash/Dash-Web",
- "commandLine": [
- "/Users/sarah/.nvm/versions/node/v12.16.0/bin/node",
- "--max-old-space-size=2048",
- "/Users/sarah/Desktop/dash/Dash-Web/node_modules/ts-node-dev/lib/wrap.js",
- "/Users/sarah/Desktop/dash/Dash-Web/node_modules/fork-ts-checker-webpack-plugin/lib/service.js"
- ],
- "nodejsVersion": "v12.16.0",
- "wordSize": 64,
- "arch": "x64",
- "platform": "darwin",
- "componentVersions": {
- "node": "12.16.0",
- "v8": "7.8.279.23-node.31",
- "uv": "1.34.0",
- "zlib": "1.2.11",
- "brotli": "1.0.7",
- "ares": "1.15.0",
- "modules": "72",
- "nghttp2": "1.40.0",
- "napi": "5",
- "llhttp": "2.0.4",
- "http_parser": "2.9.3",
- "openssl": "1.1.1d",
- "cldr": "35.1",
- "icu": "64.2",
- "tz": "2019c",
- "unicode": "12.1"
- },
- "release": {
- "name": "node",
- "lts": "Erbium",
- "headersUrl": "https://nodejs.org/download/release/v12.16.0/node-v12.16.0-headers.tar.gz",
- "sourceUrl": "https://nodejs.org/download/release/v12.16.0/node-v12.16.0.tar.gz"
- },
- "osName": "Darwin",
- "osRelease": "22.6.0",
- "osVersion": "Darwin Kernel Version 22.6.0: Wed Jul 5 22:21:56 PDT 2023; root:xnu-8796.141.3~6/RELEASE_X86_64",
- "osMachine": "x86_64",
- "cpus": [
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 19491620,
- "nice": 0,
- "sys": 10530730,
- "idle": 128029940,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 1041080,
- "nice": 0,
- "sys": 832510,
- "idle": 156711500,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 17230140,
- "nice": 0,
- "sys": 7308720,
- "idle": 133550270,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 1101080,
- "nice": 0,
- "sys": 813690,
- "idle": 156678120,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 14246350,
- "nice": 0,
- "sys": 5654800,
- "idle": 138314740,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 1142930,
- "nice": 0,
- "sys": 790770,
- "idle": 156668310,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 12228700,
- "nice": 0,
- "sys": 4533960,
- "idle": 141551990,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 1165420,
- "nice": 0,
- "sys": 773220,
- "idle": 156669740,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 9805920,
- "nice": 0,
- "sys": 3386750,
- "idle": 145216650,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 1177080,
- "nice": 0,
- "sys": 759980,
- "idle": 156674610,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 8806950,
- "nice": 0,
- "sys": 2889820,
- "idle": 146774530,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 1166250,
- "nice": 0,
- "sys": 737790,
- "idle": 156711830,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 7865920,
- "nice": 0,
- "sys": 2438950,
- "idle": 148205800,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 1155370,
- "nice": 0,
- "sys": 719580,
- "idle": 156743860,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 7478040,
- "nice": 0,
- "sys": 2248690,
- "idle": 148810130,
- "irq": 0
- },
- {
- "model": "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
- "speed": 2300,
- "user": 1131070,
- "nice": 0,
- "sys": 695000,
- "idle": 156797450,
- "irq": 0
- }
- ],
- "networkInterfaces": [
- {
- "name": "lo0",
- "internal": true,
- "mac": "00:00:00:00:00:00",
- "address": "127.0.0.1",
- "netmask": "255.0.0.0",
- "family": "IPv4"
- },
- {
- "name": "lo0",
- "internal": true,
- "mac": "00:00:00:00:00:00",
- "address": "::1",
- "netmask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
- "family": "IPv6",
- "scopeid": 0
- },
- {
- "name": "lo0",
- "internal": true,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::1",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 1
- },
- {
- "name": "en5",
- "internal": false,
- "mac": "ac:de:48:00:11:22",
- "address": "fe80::aede:48ff:fe00:1122",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 4
- },
- {
- "name": "en0",
- "internal": false,
- "mac": "88:66:5a:29:28:77",
- "address": "fe80::1467:9dad:c3d1:73a7",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 6
- },
- {
- "name": "en0",
- "internal": false,
- "mac": "88:66:5a:29:28:77",
- "address": "10.38.21.14",
- "netmask": "255.255.192.0",
- "family": "IPv4"
- },
- {
- "name": "en0",
- "internal": false,
- "mac": "88:66:5a:29:28:77",
- "address": "fde6:e673:d766:4b72:1481:e813:77a2:da34",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 0
- },
- {
- "name": "en0",
- "internal": false,
- "mac": "88:66:5a:29:28:77",
- "address": "2620:6e:6000:3100:148e:201a:1a33:145d",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 0
- },
- {
- "name": "en0",
- "internal": false,
- "mac": "88:66:5a:29:28:77",
- "address": "2620:6e:6000:3100:5c7f:8d3f:76ba:694b",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 0
- },
- {
- "name": "awdl0",
- "internal": false,
- "mac": "12:df:77:23:4c:4e",
- "address": "fe80::10df:77ff:fe23:4c4e",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 9
- },
- {
- "name": "llw0",
- "internal": false,
- "mac": "12:df:77:23:4c:4e",
- "address": "fe80::10df:77ff:fe23:4c4e",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 12
- },
- {
- "name": "utun0",
- "internal": false,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::6616:29f1:d83d:2f8d",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 14
- },
- {
- "name": "utun1",
- "internal": false,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::b4dc:ec9a:5d3d:18ab",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 15
- },
- {
- "name": "utun2",
- "internal": false,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::ce81:b1c:bd2c:69e",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 16
- },
- {
- "name": "utun3",
- "internal": false,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::bd9f:d9d8:700d:2011",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 17
- },
- {
- "name": "utun4",
- "internal": false,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::9a49:1de7:e220:2bb",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 18
- },
- {
- "name": "utun5",
- "internal": false,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::93fe:38cf:1393:3191",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 19
- },
- {
- "name": "utun6",
- "internal": false,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::781d:651c:69a7:3d42",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 20
- },
- {
- "name": "utun7",
- "internal": false,
- "mac": "00:00:00:00:00:00",
- "address": "fe80::b39:d094:2a6d:e0c5",
- "netmask": "ffff:ffff:ffff:ffff::",
- "family": "IPv6",
- "scopeid": 21
- }
- ],
- "host": "sarahs-mbp-2.devices.brown.edu"
- },
- "javascriptStack": {
- "message": "No stack.",
- "stack": [
- "Unavailable."
- ]
- },
- "nativeStack": [
- {
- "pc": "0x000000010015c8ca",
- "symbol": "report::TriggerNodeReport(v8::Isolate*, node::Environment*, char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, v8::Local<v8::String>) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x0000000100080f3e",
- "symbol": "node::OnFatalError(char const*, char const*) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x0000000100185467",
- "symbol": "v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x0000000100185403",
- "symbol": "v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x000000010030b5f5",
- "symbol": "v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x000000010030ccc4",
- "symbol": "v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x0000000100309b37",
- "symbol": "v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x0000000100307afd",
- "symbol": "v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x00000001003132ba",
- "symbol": "v8::internal::Heap::AllocateRawWithLightRetry(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x0000000100313341",
- "symbol": "v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x00000001002e065b",
- "symbol": "v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x0000000100618a18",
- "symbol": "v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- },
- {
- "pc": "0x0000000100950c19",
- "symbol": "Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit [/Users/sarah/.nvm/versions/node/v12.16.0/bin/node]"
- }
- ],
- "javascriptHeap": {
- "totalMemory": 2154991616,
- "totalCommittedMemory": 2153815368,
- "usedMemory": 2136222480,
- "availableMemory": 51343040,
- "memoryLimit": 2197815296,
- "heapSpaces": {
- "read_only_space": {
- "memorySize": 262144,
- "committedMemory": 33088,
- "capacity": 32808,
- "used": 32808,
- "available": 0
- },
- "new_space": {
- "memorySize": 8388608,
- "committedMemory": 8388528,
- "capacity": 4189824,
- "used": 69544,
- "available": 4120280
- },
- "old_space": {
- "memorySize": 1946566656,
- "committedMemory": 1946346224,
- "capacity": 1939183704,
- "used": 1938974448,
- "available": 209256
- },
- "code_space": {
- "memorySize": 14323712,
- "committedMemory": 13779552,
- "capacity": 12481792,
- "used": 12481792,
- "available": 0
- },
- "map_space": {
- "memorySize": 1576960,
- "committedMemory": 1394440,
- "capacity": 1280720,
- "used": 1280720,
- "available": 0
- },
- "large_object_space": {
- "memorySize": 183824384,
- "committedMemory": 183824384,
- "capacity": 183380384,
- "used": 183380384,
- "available": 0
- },
- "code_large_object_space": {
- "memorySize": 49152,
- "committedMemory": 49152,
- "capacity": 2784,
- "used": 2784,
- "available": 0
- },
- "new_large_object_space": {
- "memorySize": 0,
- "committedMemory": 0,
- "capacity": 4189824,
- "used": 0,
- "available": 4189824
- }
- }
- },
- "resourceUsage": {
- "userCpuSeconds": 306.691,
- "kernelCpuSeconds": 15.3869,
- "cpuConsumptionPercent": 11.2772,
- "maxRss": 2231285841920,
- "pageFaults": {
- "IORequired": 110,
- "IONotRequired": 2487718
- },
- "fsActivity": {
- "reads": 0,
- "writes": 0
- }
- },
- "libuv": [
- ],
- "environmentVariables": {
- "npm_config_save_dev": "",
- "npm_config_legacy_bundling": "",
- "npm_config_dry_run": "",
- "npm_package_dependencies_request": "^2.88.2",
- "npm_package_dependencies_express_flash": "0.0.2",
- "npm_package_dependencies__fortawesome_fontawesome_svg_core": "^6.3.0",
- "NVM_INC": "/Users/sarah/.nvm/versions/node/v12.16.0/include/node",
- "npm_config_viewer": "man",
- "npm_config_only": "",
- "npm_config_commit_hooks": "true",
- "npm_config_browser": "",
- "npm_package_gitHead": "5754c1c056ec62e17b5d7badddc4a8fc3637e09f",
- "npm_package_dependencies_webpack_dev_middleware": "^5.3.1",
- "npm_package_dependencies_webpack_cli": "^4.10.0",
- "npm_package_devDependencies_prettier": "^2.7.1",
- "npm_package_devDependencies_awesome_typescript_loader": "^5.2.1",
- "npm_package_devDependencies__types_archiver": "^3.1.1",
- "npm_config_also": "",
- "npm_package_dependencies_react_jsx_parser": "^1.29.0",
- "npm_package_dependencies_mongoose": "^5.13.14",
- "npm_package_dependencies_connect_flash": "^0.1.1",
- "npm_package_browser_child_process": "false",
- "npm_config_sign_git_commit": "",
- "npm_config_rollback": "true",
- "npm_package_dependencies_material_ui": "^0.20.2",
- "npm_package_devDependencies__types_sharp": "^0.23.1",
- "npm_package_devDependencies__types_passport_local": "^1.0.34",
- "npm_package_devDependencies__types_dotenv": "^6.1.1",
- "npm_package_devDependencies__types_cookie_parser": "^1.4.2",
- "TERM_PROGRAM": "Apple_Terminal",
- "NODE": "/Users/sarah/.nvm/versions/node/v12.16.0/bin/node",
- "npm_config_usage": "",
- "npm_config_audit": "true",
- "npm_package_dependencies_reveal_js": "^4.3.0",
- "npm_package_dependencies_process": "^0.11.10",
- "npm_package_dependencies_pdfjs": "^2.4.7",
- "npm_package_dependencies_html_to_image": "^0.1.3",
- "npm_package_devDependencies_file_loader": "^3.0.1",
- "npm_package_devDependencies__types_express_flash": "0.0.0",
- "npm_package_scripts_monitor": "cross-env MONITORED=true NODE_OPTIONS=--max_old_space_size=4096 ts-node src/server/index.ts",
- "INIT_CWD": "/Users/sarah/Desktop/dash/Dash-Web",
- "npm_package_dependencies_rehype_raw": "^6.1.1",
- "npm_package_dependencies_react_audio_waveform": "0.0.5",
- "npm_package_dependencies_path_browserify": "^1.0.1",
- "npm_package_dependencies_nodemailer": "^5.1.1",
- "npm_package_dependencies_axios": "^0.19.2",
- "npm_package_devDependencies_typescript": "^4.7.4",
- "NVM_CD_FLAGS": "-q",
- "npm_config_globalignorefile": "/Users/sarah/.nvm/versions/node/v12.16.0/etc/npmignore",
- "npm_package_dependencies_react_grid_layout": "^1.3.4",
- "npm_package_dependencies_prosemirror_find_replace": "^0.9.0",
- "npm_package_dependencies_normalize_css": "^8.0.1",
- "npm_package_devDependencies_mocha": "^5.2.0",
- "npm_package_devDependencies__types_express_session": "^1.17.5",
- "SHELL": "/bin/zsh",
- "TERM": "xterm-256color",
- "npm_config_shell": "/bin/zsh",
- "npm_config_maxsockets": "50",
- "npm_config_init_author_url": "",
- "npm_package_dependencies_prosemirror_dev_tools": "^3.1.0",
- "npm_package_dependencies_p_limit": "^2.2.0",
- "npm_package_dependencies_bson": "^4.6.1",
- "npm_package_dependencies__types_dom_speech_recognition": "0.0.1",
- "npm_package_dependencies__emotion_styled": "^11.11.0",
- "npm_package_devDependencies_style_loader": "^0.23.1",
- "npm_package_devDependencies__types_react_datepicker": "^3.1.8",
- "npm_config_shrinkwrap": "true",
- "npm_config_parseable": "",
- "npm_config_metrics_registry": "https://registry.npmjs.org/",
- "npm_package_dependencies_xregexp": "^4.4.1",
- "npm_package_dependencies_shelljs": "^0.8.5",
- "npm_package_dependencies_bezier_curve": "^1.0.0",
- "npm_package_dependencies__mui_icons_material": "^5.11.16",
- "npm_package_devDependencies_tslint": "^5.20.1",
- "npm_package_devDependencies__types_react_transition_group": "^4.4.5",
- "npm_package_scripts_tsc": "tsc",
- "TMPDIR": "/var/folders/yk/p_39q8jn673c5p8_66mcxm7r0000gn/T/",
- "npm_config_timing": "",
- "npm_config_init_license": "ISC",
- "npm_package_dependencies_socket_io": "^2.5.0",
- "npm_package_dependencies_probe_image_size": "^4.0.0",
- "npm_package_dependencies_canvas": "^2.9.3",
- "npm_package_dependencies__hig_theme_data": "^2.23.1",
- "npm_package_devDependencies__types_react_select": "^3.1.2",
- "npm_package_devDependencies__types_prosemirror_model": "^1.16.1",
- "CONDA_SHLVL": "1",
- "npm_config_if_present": "",
- "npm_package_dependencies_typescript_collections": "^1.3.3",
- "npm_package_dependencies_rimraf": "^3.0.0",
- "npm_package_dependencies_react_autosuggest": "^9.4.3",
- "npm_package_dependencies_flexlayout_react": "^0.3.11",
- "npm_package_dependencies_find_in_files": "^0.5.0",
- "npm_package_devDependencies__types_chai": "^4.3.0",
- "CONDA_PROMPT_MODIFIER": "(base) ",
- "TERM_PROGRAM_VERSION": "447",
- "npm_package_dependencies_prosemirror_inputrules": "^1.1.3",
- "npm_package_dependencies_bcrypt_nodejs": "0.0.3",
- "npm_package_dependencies_async": "^2.6.2",
- "npm_config_sign_git_tag": "",
- "npm_config_init_author_email": "",
- "npm_config_cache_max": "Infinity",
- "npm_package_dependencies_uuid": "^3.4.0",
- "npm_package_dependencies_supercluster": "^7.1.4",
- "npm_package_dependencies_remark_gfm": "^3.0.1",
- "npm_package_dependencies_connect_mongo": "^2.0.3",
- "npm_package_dependencies_browser_assert": "^1.2.1",
- "npm_package_devDependencies_sass_loader": "^7.3.1",
- "npm_package_scripts_start_release_debug": "cross-env RELEASE=true USE_AZURE=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --inspect -- src/server/index.ts",
- "npm_config_preid": "",
- "npm_config_long": "",
- "npm_config_local_address": "",
- "npm_config_git_tag_version": "true",
- "npm_config_cert": "",
- "npm_package_dependencies_js_datepicker": "^4.6.6",
- "npm_package_devDependencies__types_webpack_hot_middleware": "^2.25.6",
- "npm_package_devDependencies__types_mongodb": "^3.6.20",
- "npm_package_devDependencies__types_mocha": "^5.2.6",
- "TERM_SESSION_ID": "4AACD142-8780-44F4-A4FA-BB53E1BF6081",
- "npm_config_registry": "https://registry.npmjs.org/",
- "npm_config_noproxy": "",
- "npm_config_fetch_retries": "2",
- "npm_package_dependencies_react_compound_slider": "^2.5.0",
- "npm_package_dependencies_prosemirror_history": "^1.2.0",
- "npm_package_devDependencies__types_react_color": "^2.17.6",
- "npm_package_devDependencies__types_google_maps_react": "^2.0.5",
- "npm_package_devDependencies__types_color": "^3.0.3",
- "npm_package_dependencies_react_dom": "^18.2.0",
- "npm_package_dependencies_passport_local": "^1.0.0",
- "npm_package_dependencies__octokit_core": "^4.0.4",
- "npm_package_devDependencies__types_async": "^2.4.1",
- "npm_package_scripts_debug": "cross-env NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --transpile-only --inspect -- src/server/index.ts",
- "npm_package_scripts_oldstart": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug -- src/server/index.ts",
- "npm_config_versions": "",
- "npm_config_message": "%s",
- "npm_config_key": "",
- "npm_package_readmeFilename": "README.md",
- "npm_package_dependencies_react_refresh_typescript": "^2.0.7",
- "npm_package_dependencies_react_dropzone": "^14.2.3",
- "npm_package_dependencies_image_size": "^0.7.5",
- "npm_package_dependencies_html_to_text": "^5.1.1",
- "npm_package_dependencies_express_validator": "^5.3.1",
- "npm_package_devDependencies_eslint_plugin_jsx_a11y": "^6.6.0",
- "npm_package_node_child_process": "empty",
- "npm_package_dependencies_react_resizable_rotatable_draggable": "^0.2.0",
- "npm_package_dependencies_got": "^12.0.1",
- "npm_package_dependencies__types_d3_color": "^2.0.3",
- "npm_package_devDependencies_webpack": "^5.69.1",
- "npm_package_devDependencies__types_nodemailer": "^4.6.6",
- "npm_package_description": "Install Node.js, then, from the project directory, run",
- "NVM_DIR": "/Users/sarah/.nvm",
- "USER": "sarah",
- "npm_package_dependencies__types_d3_scale": "^3.3.2",
- "npm_package_devDependencies_dotenv": "^8.6.0",
- "npm_package_devDependencies__types_react": "^18.0.15",
- "npm_package_devDependencies__types_prosemirror_transform": "^1.1.5",
- "npm_package_devDependencies__types_prosemirror_history": "^1.0.3",
- "npm_package_dependencies_readline": "^1.3.0",
- "npm_package_dependencies__types_supercluster": "^7.1.0",
- "npm_package_dependencies__azure_storage_blob": "^12.14.0",
- "npm_config_globalconfig": "/Users/sarah/.nvm/versions/node/v12.16.0/etc/npmrc",
- "npm_package_dependencies_depcheck": "^0.9.2",
- "npm_package_dependencies__types_web": "0.0.53",
- "CONDA_EXE": "/Users/sarah/miniconda3/bin/conda",
- "npm_config_prefer_online": "",
- "npm_config_logs_max": "10",
- "npm_config_always_auth": "",
- "npm_package_dependencies_react_icons": "^4.3.1",
- "npm_package_dependencies_passport_google_oauth20": "^2.0.0",
- "npm_package_devDependencies_webpack_dev_server": "^3.11.3",
- "npm_package_devDependencies__types_brotli": "^1.3.1",
- "npm_package_dependencies_url_loader": "^1.1.2",
- "npm_package_dependencies_stream_browserify": "^3.0.0",
- "npm_package_dependencies_prosemirror_transform": "^1.3.4",
- "npm_package_dependencies_lodash": "^4.17.21",
- "npm_package_dependencies_i": "^0.3.7",
- "npm_package_devDependencies_tslint_loader": "^3.6.0",
- "SSH_AUTH_SOCK": "/private/tmp/com.apple.launchd.dBaRxB6a53/Listeners",
- "npm_package_dependencies_words_to_numbers": "^1.5.1",
- "npm_package_dependencies_valid_url": "^1.0.9",
- "npm_package_dependencies_styled_components": "^4.4.1",
- "npm_package_dependencies_csv_parser": "^3.0.0",
- "npm_package_dependencies_class_transformer": "^0.2.0",
- "npm_package_devDependencies_eslint": "^8.36.0",
- "npm_package_devDependencies__types_prosemirror_inputrules": "^1.0.4",
- "npm_package_devDependencies__types_express": "^4.17.13",
- "__CF_USER_TEXT_ENCODING": "0x1F5:0x0:0x0",
- "npm_execpath": "/Users/sarah/.nvm/versions/node/v12.16.0/lib/node_modules/npm/bin/npm-cli.js",
- "npm_config_global_style": "",
- "npm_config_cache_lock_retries": "10",
- "npm_package_dependencies_wikijs": "^6.3.3",
- "npm_package_dependencies_bluebird": "^3.7.2",
- "npm_package_devDependencies__types_react_typist": "^2.0.3",
- "npm_config_update_notifier": "true",
- "npm_config_cafile": "",
- "npm_package_dependencies_util": "^0.12.4",
- "npm_package_dependencies_raw_loader": "^1.0.0",
- "npm_package_dependencies_https_browserify": "^1.0.0",
- "npm_package_dependencies_brotli": "^1.3.3",
- "npm_package_dependencies__mui_material": "^5.13.1",
- "npm_package_dependencies__fortawesome_react_fontawesome": "^0.2.0",
- "npm_package_devDependencies__types_passport_google_oauth20": "^2.0.11",
- "npm_package_dependencies_cors": "^2.8.5",
- "npm_package_dependencies_bezier_js": "^4.1.1",
- "npm_package_dependencies__fortawesome_free_brands_svg_icons": "^6.3.0",
- "npm_config_heading": "npm",
- "npm_config_audit_level": "low",
- "npm_package_dependencies_chrome": "^0.1.0",
- "npm_package_dependencies__react_three_fiber": "^6.2.3",
- "npm_package_devDependencies_eslint_plugin_prettier": "^4.2.1",
- "npm_package_devDependencies_copy_webpack_plugin": "^4.6.0",
- "npm_package_devDependencies__types_react_measure": "^2.0.8",
- "npm_package_devDependencies__types_react_dom": "^18.0.6",
- "npm_package_devDependencies__types_mobile_detect": "^1.3.4",
- "_CE_CONDA": "",
- "npm_config_searchlimit": "20",
- "npm_config_read_only": "",
- "npm_config_offline": "",
- "npm_config_fetch_retry_mintimeout": "10000",
- "npm_package_dependencies_react_typist": "^2.0.5",
- "npm_package_dependencies_mobx_react_devtools": "^6.1.1",
- "npm_package_dependencies_md5_file": "^5.0.0",
- "npm_package_dependencies_forever_agent": "^0.6.1",
- "npm_package_devDependencies__types_xregexp": "^4.4.0",
- "npm_package_devDependencies__types_typescript": "^2.0.0",
- "npm_package_devDependencies__types_request": "^2.48.8",
- "npm_package_devDependencies__types_prosemirror_commands": "^1.0.4",
- "npm_config_json": "",
- "npm_config_access": "",
- "npm_config_argv": "{\"remain\":[],\"cooked\":[\"start\"],\"original\":[\"start\"]}",
- "npm_package_dependencies__fortawesome_free_solid_svg_icons": "^6.3.0",
- "npm_package_devDependencies__types_socket_io": "^2.1.13",
- "PATH": "/Users/sarah/.nvm/versions/node/v12.16.0/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/sarah/Desktop/dash/Dash-Web/node_modules/.bin:/Users/sarah/.nvm/versions/node/v12.16.0/bin:/Users/sarah/miniconda3/bin:/Users/sarah/miniconda3/condabin:/Users/sarah/.elan/bin:/Library/Frameworks/Python.framework/Versions/3.9/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin",
- "npm_config_allow_same_version": "",
- "npm_package_dependencies_webrtc_adapter": "^7.7.1",
- "npm_package_dependencies_react_reveal": "^1.2.2",
- "npm_package_dependencies_prosemirror_schema_list": "^1.1.6",
- "npm_package_dependencies__material_ui_core": "^4.12.3",
- "npm_package_devDependencies__types_rimraf": "^2.0.5",
- "npm_package_devDependencies__types_connect_flash": "0.0.34",
- "npm_config_https_proxy": "",
- "npm_config_engine_strict": "",
- "npm_config_description": "true",
- "npm_package_dependencies_pug": "^2.0.4",
- "npm_package_dependencies_prosemirror_keymap": "^1.1.5",
- "npm_package_dependencies_pdfjs_dist": "^2.14.305",
- "npm_package_dependencies_mobile_detect": "^1.4.5",
- "npm_package_dependencies_image_size_stream": "^1.1.0",
- "npm_package_dependencies_golden_layout": "^1.5.9",
- "npm_package_dependencies_child_process": "^1.0.2",
- "npm_package_dependencies__types_d3_axis": "^2.1.3",
- "_": "/Users/sarah/Desktop/dash/Dash-Web/node_modules/.bin/cross-env",
- "LaunchInstanceID": "16109DB5-CDB2-454A-9613-8F6F534702AC",
- "npm_config_userconfig": "/Users/sarah/.npmrc",
- "npm_config_init_module": "/Users/sarah/.npm-init.js",
- "npm_package_dependencies__react_google_maps_api": "^2.7.0",
- "CONDA_PREFIX": "/Users/sarah/miniconda3",
- "__CFBundleIdentifier": "com.apple.Terminal",
- "npm_config_cidr": "",
- "npm_package_dependencies_puppeteer": "^3.3.0",
- "npm_package_dependencies_prosemirror_view": "^1.26.5",
- "npm_package_dependencies_mongodb": "^3.7.3",
- "npm_package_dependencies_google_auth_library": "^4.2.4",
- "npm_package_dependencies_bootstrap": "^4.6.1",
- "npm_package_devDependencies_eslint_config_airbnb": "^19.0.4",
- "PWD": "/Users/sarah/desktop/dash/dash-web",
- "npm_config_user": "501",
- "npm_config_node_version": "12.16.0",
- "npm_package_dependencies_node_sass": "^4.14.1",
- "npm_package_dependencies_howler": "^2.2.3",
- "npm_package_dependencies_expressjs": "^1.0.1",
- "npm_package_dependencies_core_js": "^3.28.0",
- "npm_package_dependencies_browndash_components": "^0.1.36",
- "npm_package_devDependencies_eslint_plugin_react_hooks": "^4.6.0",
- "npm_package_devDependencies__types_lodash": "^4.14.179",
- "JAVA_HOME": "/Library/Java/JavaVirtualMachines/jdk1.8.0_341.jdk/Contents/Home",
- "npm_lifecycle_event": "start",
- "npm_package_dependencies_react_table": "^6.11.5",
- "npm_package_dependencies_react_loading": "^2.0.3",
- "npm_package_dependencies_mobx": "^5.15.7",
- "npm_package_dependencies_babel": "^6.23.0",
- "npm_package_devDependencies_jsdom": "^15.2.1",
- "npm_package_devDependencies_chai": "^4.3.6",
- "npm_config_save": "true",
- "npm_config_ignore_prepublish": "",
- "npm_config_editor": "vi",
- "npm_config_auth_type": "legacy",
- "npm_package_dependencies_npm": "^6.14.18",
- "npm_package_dependencies_node_stream_zip": "^1.15.0",
- "npm_package_dependencies_image_data_uri": "^2.0.1",
- "npm_package_scripts_start_release": "cross-env RELEASE=true USE_AZURE=false NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts",
- "npm_package_name": "dash",
- "LANG": "en_US.UTF-8",
- "npm_config_tag": "latest",
- "npm_config_script_shell": "",
- "npm_package_dependencies_query_string": "^6.14.1",
- "npm_package_dependencies_mobx_utils": "^5.6.2",
- "npm_package_dependencies_file_saver": "^2.0.5",
- "npm_package_dependencies_body_parser": "^1.19.2",
- "npm_package_dependencies__types_reveal": "^3.3.33",
- "npm_package_devDependencies_eslint_plugin_import": "^2.26.0",
- "npm_package_devDependencies__types_prosemirror_view": "^1.23.1",
- "npm_config_progress": "true",
- "npm_config_global": "",
- "npm_config_before": "",
- "npm_package_dependencies_xoauth2": "^1.2.0",
- "npm_package_dependencies_standard_http_error": "^2.0.1",
- "npm_package_dependencies_react_loader_spinner": "^5.3.4",
- "npm_package_dependencies_http_browserify": "^1.7.0",
- "npm_package_dependencies__types_d3_selection": "^2.0.1",
- "npm_package_dependencies__hig_flyout": "^1.3.1",
- "npm_package_devDependencies_fork_ts_checker_webpack_plugin": "^1.6.0",
- "npm_package_scripts_build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 webpack --env production",
- "npm_package_scripts_start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only -- src/server/index.ts",
- "npm_config_searchstaleness": "900",
- "npm_config_optional": "true",
- "npm_config_ham_it_up": "",
- "npm_package_dependencies_sharp": "^0.23.4",
- "npm_package_dependencies_rc_switch": "^1.9.2",
- "npm_package_dependencies_googlephotos": "^0.2.5",
- "npm_package_dependencies_exifr": "^7.1.3",
- "npm_package_dependencies__types_google_maps": "^3.2.3",
- "npm_package_dependencies__types_bezier_js": "^4.1.0",
- "npm_package_dependencies__ffmpeg_core": "0.10.0",
- "npm_package_devDependencies_ts_loader": "^5.3.3",
- "npm_package_devDependencies__types_bcrypt_nodejs": "0.0.30",
- "XPC_FLAGS": "0x0",
- "npm_config_save_prod": "",
- "npm_config_force": "",
- "npm_config_bin_links": "true",
- "npm_package_devDependencies__types_youtube": "0.0.39",
- "npm_config_searchopts": "",
- "npm_package_dependencies_react_beautiful_dnd": "^13.1.0",
- "npm_package_dependencies_jszip": "^3.7.1",
- "npm_package_dependencies_csv_stringify": "^6.3.0",
- "npm_package_devDependencies__types_react_icons": "^3.0.0",
- "npm_config_node_gyp": "/Users/sarah/.nvm/versions/node/v12.16.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js",
- "npm_config_depth": "Infinity",
- "npm_package_dependencies_google_maps_react": "^2.0.6",
- "npm_package_dependencies_express_session": "^1.17.2",
- "npm_package_devDependencies_eslint_plugin_node": "^11.1.0",
- "npm_package_devDependencies_eslint_config_prettier": "^8.5.0",
- "npm_package_main": "index.js",
- "npm_config_sso_poll_frequency": "500",
- "npm_config_rebuild_bundle": "true",
- "npm_package_dependencies_chart_js": "^3.8.0",
- "npm_package_dependencies__emotion_react": "^11.11.0",
- "npm_package_devDependencies__types_prosemirror_menu": "^1.0.6",
- "npm_package_devDependencies__types_prosemirror_keymap": "^1.0.4",
- "npm_package_devDependencies__types_pdfjs_dist": "^2.10.378",
- "npm_package_devDependencies__types_exif": "^0.6.3",
- "npm_package_version": "1.0.0",
- "_CE_M": "",
- "XPC_SERVICE_NAME": "0",
- "npm_config_unicode": "true",
- "npm_package_dependencies_typescript_language_server": "^0.4.0",
- "npm_package_dependencies_prosemirror_model": "^1.18.1",
- "npm_package_dependencies__ffmpeg_ffmpeg": "0.10.0",
- "SHLVL": "2",
- "HOME": "/Users/sarah",
- "npm_config_fetch_retry_maxtimeout": "60000",
- "npm_package_dependencies_request_promise": "^4.2.6",
- "npm_package_dependencies_react_markdown": "^8.0.3",
- "npm_package_dependencies__hig_theme_context": "^2.1.3",
- "npm_package_devDependencies__types_react_autosuggest": "^9.3.14",
- "npm_package_devDependencies__types_mongoose": "^5.11.97",
- "npm_package_devDependencies__types_d3": "^7.4.0",
- "npm_package_devDependencies__types_animejs": "^2.0.2",
- "npm_package_scripts_test": "mocha -r ts-node/register test/**/*.ts",
- "npm_config_tag_version_prefix": "v",
- "npm_config_strict_ssl": "true",
- "npm_config_sso_type": "oauth",
- "npm_config_scripts_prepend_node_path": "warn-only",
- "npm_config_save_prefix": "^",
- "npm_config_loglevel": "notice",
- "npm_config_ca": "",
- "npm_package_dependencies_three": "^0.127.0",
- "npm_package_dependencies_openai": "^3.2.1",
- "npm_package_dependencies_mobx_react": "^5.4.4",
- "npm_package_dependencies_google_translate_api_browser": "^3.0.1",
- "npm_package_dependencies_cookie_parser": "^1.4.6",
- "npm_package_dependencies_adm_zip": "^0.4.16",
- "npm_package_devDependencies_eslint_config_node": "^4.1.0",
- "npm_config_save_exact": "",
- "npm_config_group": "20",
- "npm_config_fetch_retry_factor": "10",
- "npm_config_dev": "",
- "npm_package_devDependencies_webpack_hot_middleware": "^2.25.1",
- "npm_package_devDependencies_cross_env": "^5.2.1",
- "npm_config_version": "",
- "npm_config_prefer_offline": "",
- "npm_config_cache_lock_stale": "60000",
- "npm_package_devDependencies__types_prosemirror_state": "^1.2.8",
- "npm_package_devDependencies__types_body_parser": "^1.19.2",
- "npm_config_otp": "",
- "npm_config_cache_min": "10",
- "npm_package_dependencies_react_color": "^2.19.3",
- "npm_package_dependencies_d3": "^7.6.1",
- "npm_package_devDependencies_ts_node": "^10.9.1",
- "npm_package_devDependencies__types_react_grid_layout": "^1.3.2",
- "npm_config_searchexclude": "",
- "npm_config_cache": "/Users/sarah/.npm",
- "npm_package_dependencies_tough_cookie": "^4.0.0",
- "npm_package_dependencies_googleapis": "^40.0.0",
- "npm_package_devDependencies__types_valid_url": "^1.0.3",
- "npm_package_devDependencies__types_passport": "^1.0.9",
- "npm_package_devDependencies__types_adm_zip": "^0.4.34",
- "CONDA_PYTHON_EXE": "/Users/sarah/miniconda3/bin/python",
- "LOGNAME": "sarah",
- "npm_lifecycle_script": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only -- src/server/index.ts",
- "npm_config_color": "true",
- "npm_package_dependencies_solr_node": "^1.2.1",
- "npm_package_dependencies_react_transition_group": "^4.4.2",
- "npm_package_dependencies_iink_js": "^1.5.4",
- "npm_package_dependencies_html_webpack_plugin": "^5.5.0",
- "npm_config_proxy": "",
- "npm_config_package_lock": "true",
- "npm_package_dependencies_prosemirror_state": "^1.4.1",
- "npm_package_dependencies_nodemon": "^1.19.4",
- "npm_package_dependencies_function_plot": "^1.22.8",
- "npm_package_dependencies_equation_editor_react": "github:bobzel/equation-editor-react#useLocally",
- "npm_package_devDependencies__types_socket_io_parser": "^3.0.0",
- "CLASSPATH": "/Users/sarah/Downloads/cs15/*:.",
- "npm_config_package_lock_only": "",
- "npm_config_fund": "true",
- "npm_package_dependencies_react": "^18.2.0",
- "npm_package_dependencies_bingmaps_react": "^1.2.10",
- "npm_package_devDependencies_scss_loader": "0.0.1",
- "npm_package_devDependencies__types_cookie_session": "^2.0.44",
- "npm_config_save_optional": "",
- "npm_package_dependencies_textarea_caret": "^3.1.0",
- "npm_package_dependencies_react_measure": "^2.5.2",
- "npm_package_dependencies_exif": "^0.6.0",
- "NVM_BIN": "/Users/sarah/.nvm/versions/node/v12.16.0/bin",
- "CONDA_DEFAULT_ENV": "base",
- "npm_config_ignore_scripts": "",
- "npm_config_user_agent": "npm/6.14.7 node/v12.16.0 darwin x64",
- "npm_package_dependencies_react_resizable": "^1.11.1",
- "npm_package_dependencies_prosemirror_commands": "^1.2.1",
- "npm_package_dependencies_memorystream": "^0.3.1",
- "npm_package_dependencies_formidable": "1.2.1",
- "npm_package_devDependencies__types_uuid": "^3.4.10",
- "npm_config_cache_lock_wait": "10000",
- "npm_package_dependencies_socket_io_client": "^2.5.0",
- "npm_package_dependencies_recharts": "^2.1.12",
- "npm_package_dependencies_react_chartjs_2": "^4.3.0",
- "npm_package_dependencies_fluent_ffmpeg": "^2.1.2",
- "npm_package_dependencies__types_cors": "^2.8.12",
- "npm_package_devDependencies__types_node": "^10.17.60",
- "npm_package_devDependencies__types_file_saver": "^2.0.5",
- "npm_config_production": "",
- "npm_package_dependencies_jsonschema": "^1.4.0",
- "npm_package_dependencies_ffmpeg": "0.0.4",
- "npm_package_dependencies_cookie_session": "^2.0.0",
- "npm_package_dependencies_color": "^3.2.1",
- "npm_package_devDependencies__types_webpack": "^4.41.32",
- "npm_package_devDependencies__types_request_promise": "^4.1.48",
- "npm_package_devDependencies__types_prosemirror_schema_list": "^1.0.3",
- "npm_config_send_metrics": "",
- "npm_config_save_bundle": "",
- "npm_package_dependencies_web_request": "^1.0.7",
- "npm_package_dependencies_react_datepicker": "^3.8.0",
- "npm_package_dependencies_express": "^4.17.3",
- "npm_package_dependencies_D": "^1.0.0",
- "npm_package_dependencies__types_formidable": "1.0.31",
- "npm_package_devDependencies__types_rc_switch": "^1.9.2",
- "npm_package_devDependencies__types_prosemirror_dev_tools": "^2.1.0",
- "npm_package_devDependencies__types_jquery": "^3.5.14",
- "npm_config_umask": "0022",
- "npm_config_node_options": "",
- "npm_config_init_version": "1.0.0",
- "npm_package_dependencies_https": "^1.0.0",
- "npm_package_dependencies_array_batcher": "^1.2.3",
- "npm_package_dependencies__fortawesome_free_regular_svg_icons": "^6.3.0",
- "npm_package_devDependencies__types_shelljs": "^0.8.11",
- "npm_package_devDependencies__types_libxmljs": "^0.18.7",
- "npm_package_devDependencies__types_express_validator": "^3.0.0",
- "npm_package_devDependencies__types_bluebird": "^3.5.36",
- "npm_config_init_author_name": "",
- "npm_config_git": "git",
- "npm_config_scope": "",
- "npm_package_dependencies_react_select": "^3.2.0",
- "npm_package_dependencies_pdf_parse": "^1.1.1",
- "npm_package_dependencies_colors": "^1.4.0",
- "npm_package_dependencies_archiver": "^3.1.1",
- "npm_package_devDependencies_css_loader": "^2.1.1",
- "npm_package_devDependencies__types_socket_io_client": "^1.4.36",
- "SECURITYSESSIONID": "186a6",
- "npm_config_unsafe_perm": "true",
- "npm_config_tmp": "/var/folders/yk/p_39q8jn673c5p8_66mcxm7r0000gn/T",
- "npm_config_onload_script": "",
- "npm_package_dependencies_serializr": "^1.5.4",
- "npm_package_dependencies_fit_curve": "^0.1.7",
- "npm_package_dependencies__webscopeio_react_textarea_autocomplete": "^4.9.1",
- "npm_package_dependencies__types_three": "^0.126.2",
- "npm_package_devDependencies_ts_node_dev": "^2.0.0",
- "npm_node_execpath": "/Users/sarah/.nvm/versions/node/v12.16.0/bin/node",
- "npm_config_prefix": "/Users/sarah/.nvm/versions/node/v12.16.0",
- "npm_config_link": "",
- "npm_config_format_package_lock": "true",
- "npm_package_dependencies_passport": "^0.4.0",
- "npm_package_devDependencies_eslint_plugin_react": "^7.30.1",
- "npm_package_devDependencies__types_react_table": "^6.8.9",
- "npm_package_devDependencies__types_react_reconciler": "^0.26.4",
- "NODE_OPTIONS": "--max_old_space_size=4096",
- "TS_NODE_DEV": "true",
- "_CLIENT_OPENAI_KEY": "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",
- "VIPSHOME": "/usr/local/Cellar/vips/8.8.1",
- "TYPESCRIPT_PATH": "/Users/sarah/Desktop/dash/Dash-Web/node_modules/typescript/lib/typescript.js",
- "TSCONFIG": "/Users/sarah/Desktop/dash/Dash-Web/tsconfig.json",
- "COMPILER_OPTIONS": "{}",
- "TSLINT": "true",
- "CONTEXT": "/Users/sarah/Desktop/dash/Dash-Web",
- "TSLINTAUTOFIX": "false",
- "ESLINT": "false",
- "ESLINT_OPTIONS": "{}",
- "WATCH": "",
- "WORK_DIVISION": "1",
- "MEMORY_LIMIT": "2048",
- "CHECK_SYNTACTIC_ERRORS": "false",
- "USE_INCREMENTAL_API": "true",
- "VUE": "false"
- },
- "userLimits": {
- "core_file_size_blocks": {
- "soft": 0,
- "hard": "unlimited"
- },
- "data_seg_size_kbytes": {
- "soft": "unlimited",
- "hard": "unlimited"
- },
- "file_size_blocks": {
- "soft": "unlimited",
- "hard": "unlimited"
- },
- "max_locked_memory_bytes": {
- "soft": "unlimited",
- "hard": "unlimited"
- },
- "max_memory_size_kbytes": {
- "soft": "unlimited",
- "hard": "unlimited"
- },
- "open_files": {
- "soft": 1048575,
- "hard": "unlimited"
- },
- "stack_size_bytes": {
- "soft": 8388608,
- "hard": 67104768
- },
- "cpu_time_seconds": {
- "soft": "unlimited",
- "hard": "unlimited"
- },
- "max_user_processes": {
- "soft": 2784,
- "hard": 4176
- },
- "virtual_memory_kbytes": {
- "soft": "unlimited",
- "hard": "unlimited"
- }
- },
- "sharedObjects": [
- "/Users/sarah/.nvm/versions/node/v12.16.0/bin/node",
- "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation",
- "/usr/lib/libobjc.A.dylib",
- "/System/Library/PrivateFrameworks/CoreServicesInternal.framework/Versions/A/CoreServicesInternal",
- "/usr/lib/liboah.dylib",
- "/usr/lib/libfakelink.dylib",
- "/usr/lib/libicucore.A.dylib",
- "/usr/lib/libSystem.B.dylib",
- "/System/Library/PrivateFrameworks/SoftLinking.framework/Versions/A/SoftLinking",
- "/usr/lib/libc++abi.dylib",
- "/usr/lib/libc++.1.dylib",
- "/usr/lib/system/libcache.dylib",
- "/usr/lib/system/libcommonCrypto.dylib",
- "/usr/lib/system/libcompiler_rt.dylib",
- "/usr/lib/system/libcopyfile.dylib",
- "/usr/lib/system/libcorecrypto.dylib",
- "/usr/lib/system/libdispatch.dylib",
- "/usr/lib/system/libdyld.dylib",
- "/usr/lib/system/libkeymgr.dylib",
- "/usr/lib/system/libmacho.dylib",
- "/usr/lib/system/libquarantine.dylib",
- "/usr/lib/system/libremovefile.dylib",
- "/usr/lib/system/libsystem_asl.dylib",
- "/usr/lib/system/libsystem_blocks.dylib",
- "/usr/lib/system/libsystem_c.dylib",
- "/usr/lib/system/libsystem_collections.dylib",
- "/usr/lib/system/libsystem_configuration.dylib",
- "/usr/lib/system/libsystem_containermanager.dylib",
- "/usr/lib/system/libsystem_coreservices.dylib",
- "/usr/lib/system/libsystem_darwin.dylib",
- "/usr/lib/system/libsystem_dnssd.dylib",
- "/usr/lib/system/libsystem_featureflags.dylib",
- "/usr/lib/system/libsystem_info.dylib",
- "/usr/lib/system/libsystem_m.dylib",
- "/usr/lib/system/libsystem_malloc.dylib",
- "/usr/lib/system/libsystem_networkextension.dylib",
- "/usr/lib/system/libsystem_notify.dylib",
- "/usr/lib/system/libsystem_sandbox.dylib",
- "/usr/lib/system/libsystem_secinit.dylib",
- "/usr/lib/system/libsystem_kernel.dylib",
- "/usr/lib/system/libsystem_platform.dylib",
- "/usr/lib/system/libsystem_pthread.dylib",
- "/usr/lib/system/libsystem_symptoms.dylib",
- "/usr/lib/system/libsystem_trace.dylib",
- "/usr/lib/system/libunwind.dylib",
- "/usr/lib/system/libxpc.dylib",
- "/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices",
- "/usr/lib/libDiagnosticMessagesClient.dylib",
- "/usr/lib/libenergytrace.dylib",
- "/usr/lib/libbsm.0.dylib",
- "/usr/lib/libz.1.dylib",
- "/usr/lib/system/libkxld.dylib",
- "/System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/FSEvents",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices",
- "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SharedFileList.framework/Versions/A/SharedFileList",
- "/System/Library/Frameworks/Security.framework/Versions/A/Security",
- "/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration",
- "/usr/lib/libapple_nghttp2.dylib",
- "/usr/lib/libcompression.dylib",
- "/usr/lib/libnetwork.dylib",
- "/usr/lib/libsqlite3.dylib",
- "/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation",
- "/System/Library/Frameworks/Network.framework/Versions/A/Network",
- "/usr/lib/libCoreEntitlements.dylib",
- "/System/Library/PrivateFrameworks/MessageSecurity.framework/Versions/A/MessageSecurity",
- "/System/Library/PrivateFrameworks/ProtocolBuffer.framework/Versions/A/ProtocolBuffer",
- "/usr/lib/libMobileGestalt.dylib",
- "/System/Library/PrivateFrameworks/AppleFSCompression.framework/Versions/A/AppleFSCompression",
- "/usr/lib/libcoretls.dylib",
- "/usr/lib/libcoretls_cfhelpers.dylib",
- "/usr/lib/libpam.2.dylib",
- "/usr/lib/libxar.1.dylib",
- "/System/Library/PrivateFrameworks/CoreAutoLayout.framework/Versions/A/CoreAutoLayout",
- "/System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration",
- "/usr/lib/libarchive.2.dylib",
- "/usr/lib/libxml2.2.dylib",
- "/usr/lib/liblangid.dylib",
- "/System/Library/Frameworks/Combine.framework/Versions/A/Combine",
- "/usr/lib/swift/libswiftCore.dylib",
- "/usr/lib/swift/libswiftCoreFoundation.dylib",
- "/usr/lib/swift/libswiftDarwin.dylib",
- "/usr/lib/swift/libswiftDispatch.dylib",
- "/usr/lib/swift/libswiftIOKit.dylib",
- "/usr/lib/swift/libswiftObjectiveC.dylib",
- "/usr/lib/swift/libswiftXPC.dylib",
- "/usr/lib/swift/libswift_Concurrency.dylib",
- "/usr/lib/swift/libswift_StringProcessing.dylib",
- "/usr/lib/swift/libswiftos.dylib",
- "/System/Library/PrivateFrameworks/AppleSystemInfo.framework/Versions/A/AppleSystemInfo",
- "/System/Library/PrivateFrameworks/IOMobileFramebuffer.framework/Versions/A/IOMobileFramebuffer",
- "/System/Library/Frameworks/IOSurface.framework/Versions/A/IOSurface",
- "/usr/lib/libpcap.A.dylib",
- "/usr/lib/libdns_services.dylib",
- "/usr/lib/liblzma.5.dylib",
- "/usr/lib/libbz2.1.0.dylib",
- "/usr/lib/libiconv.2.dylib",
- "/usr/lib/libcharset.1.dylib",
- "/usr/lib/swift/libswift_RegexParser.dylib",
- "/usr/lib/libheimdal-asn1.dylib",
- "/usr/lib/libCheckFix.dylib",
- "/System/Library/PrivateFrameworks/TCC.framework/Versions/A/TCC",
- "/System/Library/PrivateFrameworks/CoreNLP.framework/Versions/A/CoreNLP",
- "/System/Library/PrivateFrameworks/MetadataUtilities.framework/Versions/A/MetadataUtilities",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate",
- "/usr/lib/libmecab.dylib",
- "/usr/lib/libCRFSuite.dylib",
- "/usr/lib/libgermantok.dylib",
- "/usr/lib/libThaiTokenizer.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vImage.framework/Versions/A/vImage",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/vecLib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvMisc.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLinearAlgebra.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libSparseBLAS.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libQuadrature.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBNNS.dylib",
- "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libSparse.dylib",
- "/System/Library/PrivateFrameworks/MIL.framework/Versions/A/MIL",
- "/System/Library/Frameworks/OpenDirectory.framework/Versions/A/Frameworks/CFOpenDirectory.framework/Versions/A/CFOpenDirectory",
- "/System/Library/Frameworks/OpenDirectory.framework/Versions/A/OpenDirectory",
- "/System/Library/PrivateFrameworks/APFS.framework/Versions/A/APFS",
- "/System/Library/Frameworks/SecurityFoundation.framework/Versions/A/SecurityFoundation",
- "/usr/lib/libutil.dylib",
- "/System/Library/PrivateFrameworks/InstalledContentLibrary.framework/Versions/A/InstalledContentLibrary",
- "/System/Library/PrivateFrameworks/CoreServicesStore.framework/Versions/A/CoreServicesStore",
- "/usr/lib/libapp_launch_measurement.dylib",
- "/System/Library/PrivateFrameworks/AppleMobileFileIntegrity.framework/Versions/A/AppleMobileFileIntegrity",
- "/usr/lib/libmis.dylib",
- "/System/Library/PrivateFrameworks/MobileSystemServices.framework/Versions/A/MobileSystemServices",
- "/System/Library/PrivateFrameworks/ConfigProfileHelper.framework/Versions/A/ConfigProfileHelper",
- "/System/Library/PrivateFrameworks/CoreAnalytics.framework/Versions/A/CoreAnalytics",
- "/System/Library/PrivateFrameworks/AppleSauce.framework/Versions/A/AppleSauce",
- "/System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling",
- "/usr/lib/libxslt.1.dylib",
- "/usr/lib/libcmph.dylib",
- "/System/Library/PrivateFrameworks/CoreEmoji.framework/Versions/A/CoreEmoji",
- "/System/Library/PrivateFrameworks/LinguisticData.framework/Versions/A/LinguisticData",
- "/System/Library/PrivateFrameworks/Lexicon.framework/Versions/A/Lexicon",
- "/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/BackgroundTaskManagement",
- "/usr/lib/libTLE.dylib",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices",
- "/System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics",
- "/System/Library/Frameworks/CoreText.framework/Versions/A/CoreText",
- "/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO",
- "/System/Library/Frameworks/ColorSync.framework/Versions/A/ColorSync",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/QD.framework/Versions/A/QD",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ColorSyncLegacy.framework/Versions/A/ColorSyncLegacy",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis",
- "/System/Library/PrivateFrameworks/SkyLight.framework/Versions/A/SkyLight",
- "/System/Library/PrivateFrameworks/FontServices.framework/libFontParser.dylib",
- "/System/Library/PrivateFrameworks/RunningBoardServices.framework/Versions/A/RunningBoardServices",
- "/System/Library/PrivateFrameworks/IOSurfaceAccelerator.framework/Versions/A/IOSurfaceAccelerator",
- "/System/Library/PrivateFrameworks/WatchdogClient.framework/Versions/A/WatchdogClient",
- "/System/Library/Frameworks/CoreDisplay.framework/Versions/A/CoreDisplay",
- "/System/Library/Frameworks/CoreMedia.framework/Versions/A/CoreMedia",
- "/System/Library/PrivateFrameworks/IOAccelerator.framework/Versions/A/IOAccelerator",
- "/System/Library/Frameworks/Metal.framework/Versions/A/Metal",
- "/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo",
- "/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/MetalPerformanceShaders",
- "/System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/A/MultitouchSupport",
- "/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore",
- "/System/Library/Frameworks/VideoToolbox.framework/Versions/A/VideoToolbox",
- "/System/Library/PrivateFrameworks/BaseBoard.framework/Versions/A/BaseBoard",
- "/System/Library/PrivateFrameworks/AppleJPEG.framework/Versions/A/AppleJPEG",
- "/usr/lib/libexpat.1.dylib",
- "/System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libPng.dylib",
- "/System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib",
- "/System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libGIF.dylib",
- "/System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJP2.dylib",
- "/usr/lib/libate.dylib",
- "/System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib",
- "/System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libRadiance.dylib",
- "/System/Library/PrivateFrameworks/GPUWrangler.framework/Versions/A/GPUWrangler",
- "/System/Library/PrivateFrameworks/IOPresentment.framework/Versions/A/IOPresentment",
- "/System/Library/PrivateFrameworks/DSExternalDisplay.framework/Versions/A/DSExternalDisplay",
- "/System/Library/PrivateFrameworks/GPUCompiler.framework/Versions/31001/Libraries/libllvm-flatbuffers.dylib",
- "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCoreFSCache.dylib",
- "/System/Library/PrivateFrameworks/GPUCompiler.framework/Versions/31001/Libraries/libGPUCompilerUtils.dylib",
- "/System/Library/PrivateFrameworks/CMCaptureCore.framework/Versions/A/CMCaptureCore",
- "/usr/lib/libspindump.dylib",
- "/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio",
- "/System/Library/Frameworks/ExtensionFoundation.framework/Versions/A/ExtensionFoundation",
- "/System/Library/PrivateFrameworks/CoreTime.framework/Versions/A/CoreTime",
- "/System/Library/PrivateFrameworks/AppServerSupport.framework/Versions/A/AppServerSupport",
- "/System/Library/PrivateFrameworks/perfdata.framework/Versions/A/perfdata",
- "/System/Library/PrivateFrameworks/AudioToolboxCore.framework/Versions/A/AudioToolboxCore",
- "/System/Library/PrivateFrameworks/caulk.framework/Versions/A/caulk",
- "/usr/lib/libAudioStatistics.dylib",
- "/System/Library/PrivateFrameworks/SystemPolicy.framework/Versions/A/SystemPolicy",
- "/usr/lib/libSMC.dylib",
- "/System/Library/Frameworks/CoreMIDI.framework/Versions/A/CoreMIDI",
- "/usr/lib/libAudioToolboxUtility.dylib",
- "/System/Library/PrivateFrameworks/OSAServicesClient.framework/Versions/A/OSAServicesClient",
- "/usr/lib/libperfcheck.dylib",
- "/System/Library/PrivateFrameworks/PlugInKit.framework/Versions/A/PlugInKit",
- "/System/Library/PrivateFrameworks/AssertionServices.framework/Versions/A/AssertionServices",
- "/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL",
- "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib",
- "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGFXShared.dylib",
- "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
- "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLImage.dylib",
- "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCVMSPluginSupport.dylib",
- "/usr/lib/libRosetta.dylib",
- "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCoreVMClient.dylib",
- "/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/Frameworks/MPSCore.framework/Versions/A/MPSCore",
- "/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/Frameworks/MPSImage.framework/Versions/A/MPSImage",
- "/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/Frameworks/MPSNeuralNetwork.framework/Versions/A/MPSNeuralNetwork",
- "/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/Frameworks/MPSMatrix.framework/Versions/A/MPSMatrix",
- "/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/Frameworks/MPSRayIntersector.framework/Versions/A/MPSRayIntersector",
- "/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/Frameworks/MPSNDArray.framework/Versions/A/MPSNDArray",
- "/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/Frameworks/MPSFunctions.framework/Versions/A/MPSFunctions",
- "/System/Library/PrivateFrameworks/MetalTools.framework/Versions/A/MetalTools",
- "/System/Library/PrivateFrameworks/AggregateDictionary.framework/Versions/A/AggregateDictionary",
- "/usr/lib/libIOReport.dylib",
- "/System/Library/Frameworks/CoreImage.framework/Versions/A/CoreImage",
- "/System/Library/PrivateFrameworks/PhotosensitivityProcessing.framework/Versions/A/PhotosensitivityProcessing",
- "/System/Library/Frameworks/OpenCL.framework/Versions/A/OpenCL",
- "/System/Library/PrivateFrameworks/GraphVisualizer.framework/Versions/A/GraphVisualizer",
- "/System/Library/PrivateFrameworks/FontServices.framework/Versions/A/FontServices",
- "/System/Library/Frameworks/UniformTypeIdentifiers.framework/Versions/A/UniformTypeIdentifiers",
- "/System/Library/PrivateFrameworks/OTSVG.framework/Versions/A/OTSVG",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontRegistry.dylib",
- "/System/Library/PrivateFrameworks/FontServices.framework/libhvf.dylib",
- "/System/Library/PrivateFrameworks/FontServices.framework/libXTFontStaticRegistryData.dylib",
- "/usr/lib/swift/libswiftMetal.dylib",
- "/usr/lib/swift/libswiftsimd.dylib",
- "/System/Library/PrivateFrameworks/VideoToolboxParavirtualizationSupport.framework/Versions/A/VideoToolboxParavirtualizationSupport",
- "/System/Library/PrivateFrameworks/AppleVA.framework/Versions/A/AppleVA",
- "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATSUI.framework/Versions/A/ATSUI",
- "/usr/lib/libcups.2.dylib",
- "/System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos",
- "/System/Library/Frameworks/GSS.framework/Versions/A/GSS",
- "/usr/lib/libresolv.9.dylib",
- "/System/Library/PrivateFrameworks/Heimdal.framework/Versions/A/Heimdal",
- "/System/Library/Frameworks/Kerberos.framework/Versions/A/Libraries/libHeimdalProxy.dylib",
- "/System/Library/PrivateFrameworks/CommonAuth.framework/Versions/A/CommonAuth",
- "/System/Library/Frameworks/AVFAudio.framework/Versions/A/AVFAudio",
- "/System/Library/PrivateFrameworks/AXCoreUtilities.framework/Versions/A/AXCoreUtilities",
- "/System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox",
- "/System/Library/PrivateFrameworks/AudioSession.framework/Versions/A/AudioSession",
- "/System/Library/Frameworks/IOBluetooth.framework/Versions/A/IOBluetooth",
- "/System/Library/PrivateFrameworks/MediaExperience.framework/Versions/A/MediaExperience",
- "/System/Library/PrivateFrameworks/AudioSession.framework/libSessionUtility.dylib",
- "/System/Library/PrivateFrameworks/AudioResourceArbitration.framework/Versions/A/AudioResourceArbitration",
- "/System/Library/PrivateFrameworks/PowerLog.framework/Versions/A/PowerLog",
- "/System/Library/Frameworks/CoreData.framework/Versions/A/CoreData",
- "/System/Library/Frameworks/CoreBluetooth.framework/Versions/A/CoreBluetooth",
- "/System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit",
- "/System/Library/PrivateFrameworks/CoreUtils.framework/Versions/A/CoreUtils",
- "/System/Library/PrivateFrameworks/CoreUtilsExtras.framework/Versions/A/CoreUtilsExtras",
- "/System/Library/PrivateFrameworks/IO80211.framework/Versions/A/IO80211",
- "/System/Library/PrivateFrameworks/MobileKeyBag.framework/Versions/A/MobileKeyBag",
- "/Users/sarah/Desktop/dash/Dash-Web/node_modules/fsevents/build/Release/fse.node"
- ]
-} \ No newline at end of file
diff --git a/src/.DS_Store b/src/.DS_Store
index f1f08fbb5..75cff7b55 100644
--- a/src/.DS_Store
+++ b/src/.DS_Store
Binary files differ
diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts
new file mode 100644
index 000000000..d03ae1486
--- /dev/null
+++ b/src/ClientUtils.ts
@@ -0,0 +1,721 @@
+import * as Color from 'color';
+import * as React from 'react';
+import { ColorResult } from 'react-color';
+import * as rp from 'request-promise';
+import { numberRange, decimalToHexString } from './Utils';
+import { CollectionViewType, DocumentType } from './client/documents/DocumentTypes';
+import { Colors } from './client/views/global/globalEnums';
+import { CreateImage } from './client/views/nodes/WebBoxRenderer';
+
+export function DashColor(color: string) {
+ try {
+ return color ? Color(color.toLowerCase()) : Color('transparent');
+ } catch (e) {
+ if (color.includes('gradient')) console.log("using color 'white' in place of :" + color);
+ else console.log('COLOR error:', e);
+ return Color('white');
+ }
+}
+
+export function lightOrDark(color: any) {
+ if (color === 'transparent' || !color) return Colors.BLACK;
+ if (color.startsWith?.('linear')) return Colors.BLACK;
+ if (DashColor(color).isLight()) return Colors.BLACK;
+ return Colors.WHITE;
+}
+
+export function returnTransparent() {
+ return 'transparent';
+}
+
+export function returnTrue() {
+ return true;
+}
+
+export function returnIgnore(): 'ignore' {
+ return 'ignore';
+}
+export function returnAlways(): 'always' {
+ return 'always';
+}
+export function returnNever(): 'never' {
+ return 'never';
+}
+
+export function returnDefault(): 'default' {
+ return 'default';
+}
+
+export function return18() {
+ return 18;
+}
+
+export function returnFalse() {
+ return false;
+}
+
+export function returnAll(): 'all' {
+ return 'all';
+}
+
+export function returnNone(): 'none' {
+ return 'none';
+}
+
+export function returnVal(val1?: number, val2?: number) {
+ return val1 || (val2 !== undefined ? val2 : 0);
+}
+
+export function returnOne() {
+ return 1;
+}
+
+export function returnZero() {
+ return 0;
+}
+
+export function returnEmptyString() {
+ return '';
+}
+
+export function returnEmptyFilter() {
+ return [] as string[];
+}
+
+export function returnEmptyDoclist() {
+ return [] as any[];
+}
+
+export namespace ClientUtils {
+ export const CLICK_TIME = 300;
+ export const DRAG_THRESHOLD = 4;
+ export const SNAP_THRESHOLD = 10;
+ let _currentUserEmail: string = '';
+ export function CurrentUserEmail() {
+ return _currentUserEmail;
+ }
+ export function SetCurrentUserEmail(email: string) {
+ _currentUserEmail = email;
+ }
+ export function isClick(x: number, y: number, downX: number, downY: number, downTime: number) {
+ return Date.now() - downTime < ClientUtils.CLICK_TIME && Math.abs(x - downX) < ClientUtils.DRAG_THRESHOLD && Math.abs(y - downY) < ClientUtils.DRAG_THRESHOLD;
+ }
+
+ export function cleanDocumentTypeExt(type: DocumentType) {
+ switch (type) {
+ case DocumentType.PDF: return 'PDF';
+ case DocumentType.IMG: return 'Img';
+ case DocumentType.AUDIO: return 'Aud';
+ case DocumentType.COL: return 'Col';
+ case DocumentType.RTF: return 'Rtf';
+ default: return type.charAt(0).toUpperCase() + type.substring(1,3);
+ } // prettier-ignore
+ }
+ export function cleanDocumentType(type: DocumentType, colType: CollectionViewType) {
+ switch (type) {
+ case DocumentType.PDF: return 'PDF';
+ case DocumentType.IMG: return 'Image';
+ case DocumentType.AUDIO: return 'Audio';
+ case DocumentType.COL: return 'Collection:'+colType;
+ case DocumentType.RTF: return 'Text';
+ default: return type.charAt(0).toUpperCase() + type.slice(1);
+ } // prettier-ignore
+ }
+
+ export function readUploadedFileAsText(inputFile: File) {
+ // eslint-disable-next-line no-undef
+ const temporaryFileReader = new FileReader();
+
+ return new Promise((resolve, reject) => {
+ temporaryFileReader.onerror = () => {
+ temporaryFileReader.abort();
+ reject(new DOMException('Problem parsing input file.'));
+ };
+
+ temporaryFileReader.onload = () => {
+ resolve(temporaryFileReader.result);
+ };
+ temporaryFileReader.readAsText(inputFile);
+ });
+ }
+
+ /**
+ * Uploads an image buffer to the server and stores with specified filename. by default the image
+ * is stored at multiple resolutions each retrieved by using the filename appended with _o, _s, _m, _l (indicating original, small, medium, or large)
+ * @param imageUri the bytes of the image
+ * @param returnedFilename the base filename to store the image on the server
+ * @param nosuffix optionally suppress creating multiple resolution images
+ */
+ export async function convertDataUri(imageUri: string, returnedFilename: string, nosuffix = false, replaceRootFilename: string | undefined = undefined) {
+ try {
+ const posting = ClientUtils.prepend('/uploadURI');
+ const returnedUri = await rp.post(posting, {
+ body: {
+ uri: imageUri,
+ name: returnedFilename,
+ nosuffix,
+ replaceRootFilename,
+ },
+ json: true,
+ });
+ return returnedUri;
+ } catch (e) {
+ console.log('ConvertDataURI :' + e);
+ }
+ return undefined;
+ }
+
+ export function GetScreenTransform(ele?: HTMLElement | null): { scale: number; translateX: number; translateY: number } {
+ if (!ele) {
+ return { scale: 1, translateX: 1, translateY: 1 };
+ }
+ const rect = ele.getBoundingClientRect();
+ const scale = ele.offsetWidth === 0 && rect.width === 0 ? 1 : rect.width / ele.offsetWidth;
+ const translateX = rect.left;
+ const translateY = rect.top;
+
+ return { scale, translateX, translateY };
+ }
+
+ /**
+ * A convenience method. Prepends the full path (i.e. http://localhost:<port>) to the
+ * requested extension
+ * @param extension the specified sub-path to append to the window origin
+ */
+ export function prepend(extension: string): string {
+ return window.location.origin + extension;
+ }
+ export function fileUrl(filename: string): string {
+ return prepend(`/files/${filename}`);
+ }
+
+ export function shareUrl(documentId: string): string {
+ return prepend(`/doc/${documentId}?sharing=true`);
+ }
+
+ export function CorsProxy(url: string): string {
+ return prepend('/corsProxy/') + encodeURIComponent(url);
+ }
+
+ export function CopyText(text: string) {
+ navigator.clipboard.writeText(text);
+ }
+
+ export function colorString(color: ColorResult) {
+ return color.hex.startsWith('#') && color.hex.length < 8 ? color.hex + (color.rgb.a ? decimalToHexString(Math.round(color.rgb.a * 255)) : 'ff') : color.hex;
+ }
+
+ export function fromRGBAstr(rgba: string) {
+ const rm = rgba.match(/rgb[a]?\(([ 0-9]+)/);
+ const r = rm ? Number(rm[1]) : 0;
+ const gm = rgba.match(/rgb[a]?\([ 0-9]+,([ 0-9]+)/);
+ const g = gm ? Number(gm[1]) : 0;
+ const bm = rgba.match(/rgb[a]?\([ 0-9]+,[ 0-9]+,([ 0-9]+)/);
+ const b = bm ? Number(bm[1]) : 0;
+ const am = rgba.match(/rgba?\([ 0-9]+,[ 0-9]+,[ 0-9]+,([ .0-9]+)/);
+ const a = am ? Number(am[1]) : 1;
+ return { r: r, g: g, b: b, a: a };
+ }
+
+ const isTransparentFunctionHack = 'isTransparent(__value__)';
+ export const noRecursionHack = '__noRecursion';
+
+ // special case filters
+ export const noDragDocsFilter = 'noDragDocs::any::check';
+ export const TransparentBackgroundFilter = `backgroundColor::${isTransparentFunctionHack},${noRecursionHack}::check`; // bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
+ export const OpaqueBackgroundFilter = `backgroundColor::${isTransparentFunctionHack},${noRecursionHack}::x`; // bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
+
+ export function IsRecursiveFilter(val: string) {
+ return !val.includes(noRecursionHack);
+ }
+ export function HasFunctionFilter(val: string) {
+ if (val.includes(isTransparentFunctionHack)) return (color: string) => color !== '' && DashColor(color).alpha() !== 1;
+ // add other function filters here...
+ return undefined;
+ }
+
+ export function toRGBAstr(col: { r: number; g: number; b: number; a?: number }) {
+ return 'rgba(' + col.r + ',' + col.g + ',' + col.b + (col.a !== undefined ? ',' + col.a : '') + ')';
+ }
+
+ export function HSLtoRGB(h: number, s: number, l: number) {
+ // Must be fractions of 1
+ // s /= 100;
+ // l /= 100;
+
+ const c = (1 - Math.abs(2 * l - 1)) * s;
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
+ const m = l - c / 2;
+ let r = 0;
+ let g = 0;
+ let b = 0;
+ if (h >= 0 && h < 60) {
+ r = c;
+ g = x;
+ b = 0;
+ } else if (h >= 60 && h < 120) {
+ r = x;
+ g = c;
+ b = 0;
+ } else if (h >= 120 && h < 180) {
+ r = 0;
+ g = c;
+ b = x;
+ } else if (h >= 180 && h < 240) {
+ r = 0;
+ g = x;
+ b = c;
+ } else if (h >= 240 && h < 300) {
+ r = x;
+ g = 0;
+ b = c;
+ } else if (h >= 300 && h < 360) {
+ r = c;
+ g = 0;
+ b = x;
+ }
+ r = Math.round((r + m) * 255);
+ g = Math.round((g + m) * 255);
+ b = Math.round((b + m) * 255);
+ return { r: r, g: g, b: b };
+ }
+
+ export function RGBToHSL(red: number, green: number, blue: number) {
+ // Make r, g, and b fractions of 1
+ const r = red / 255;
+ const g = green / 255;
+ const b = blue / 255;
+
+ // Find greatest and smallest channel values
+ const cmin = Math.min(r, g, b);
+ const cmax = Math.max(r, g, b);
+ const delta = cmax - cmin;
+ let h = 0;
+ let s = 0;
+ let l = 0;
+ // Calculate hue
+
+ // No difference
+ if (delta === 0) h = 0;
+ // Red is max
+ else if (cmax === r) h = ((g - b) / delta) % 6;
+ // Green is max
+ else if (cmax === g) h = (b - r) / delta + 2;
+ // Blue is max
+ else h = (r - g) / delta + 4;
+
+ h = Math.round(h * 60);
+
+ // Make negative hues positive behind 360°
+ if (h < 0) h += 360; // Calculate lightness
+
+ l = (cmax + cmin) / 2;
+
+ // Calculate saturation
+ s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
+
+ // Multiply l and s by 100
+ // s = +(s * 100).toFixed(1);
+ // l = +(l * 100).toFixed(1);
+
+ return { h: h, s: s, l: l };
+ }
+
+ export function scrollIntoView(targetY: number, targetHgt: number, scrollTop: number, contextHgt: number, minSpacing: number, scrollHeight: number) {
+ if (!targetHgt) return targetY; // if there's no height, then assume that
+ if (scrollTop + contextHgt < Math.min(scrollHeight, targetY + minSpacing + targetHgt)) {
+ return Math.ceil(targetY + minSpacing + targetHgt - contextHgt);
+ }
+ if (scrollTop >= Math.max(0, targetY - minSpacing)) {
+ return Math.max(0, Math.floor(targetY - minSpacing));
+ }
+ return undefined;
+ }
+
+ export function GetClipboardText(): string {
+ const textArea = document.createElement('textarea');
+ document.body.appendChild(textArea);
+ textArea.focus();
+ textArea.select();
+
+ try {
+ document.execCommand('paste');
+ } catch (err) {
+ /* empty */
+ }
+
+ const val = textArea.value;
+ document.body.removeChild(textArea);
+ return val;
+ }
+}
+
+export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any; extract: any } {
+ const omit: any = { ...obj };
+ const extract: any = {};
+ keys.forEach(key => {
+ extract[key] = omit[key];
+ delete omit[key];
+ });
+ pattern &&
+ Array.from(Object.keys(omit))
+ .filter(key => key.match(pattern))
+ .forEach(key => {
+ extract[key] = omit[key];
+ delete omit[key];
+ });
+ addKeyFunc?.(omit);
+ return { omit, extract };
+}
+
+export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
+ const dup: any = {};
+ keys.forEach(key => {
+ dup[key] = obj[key];
+ });
+ addKeyFunc && addKeyFunc(dup);
+ return dup;
+}
+
+export function incrementTitleCopy(title: string) {
+ const numstr = title.match(/.*(\{([0-9]*)\})+/);
+ const copyNumStr = `{${1 + (numstr ? +numstr[2] : 0)}}`;
+ return (numstr ? title.replace(numstr[1], '') : title) + copyNumStr;
+}
+
+const easeFunc = (transition: 'ease' | 'linear' | undefined, currentTime: number, start: number, change: number, duration: number) => {
+ if (transition === 'linear') {
+ const newCurrentTime = currentTime / duration; // currentTime / (duration / 2);
+ return start + newCurrentTime * change;
+ }
+
+ let newCurrentTime = currentTime / (duration / 2);
+ if (newCurrentTime < 1) {
+ return (change / 2) * newCurrentTime * newCurrentTime + start;
+ }
+
+ newCurrentTime -= 1;
+ return (-change / 2) * (newCurrentTime * (newCurrentTime - 2) - 1) + start;
+};
+
+export function smoothScroll(duration: number, element: HTMLElement | HTMLElement[], to: number, transition: 'ease' | 'linear' | undefined, stopper?: () => void) {
+ stopper?.();
+ const elements = element instanceof HTMLElement ? [element] : element;
+ const starts = elements.map(ele => ele.scrollTop);
+ const startDate = new Date().getTime();
+ let _stop = false;
+ const stop = () => {
+ _stop = true;
+ };
+ const animateScroll = () => {
+ const currentDate = new Date().getTime();
+ const currentTime = currentDate - startDate;
+ const setScrollTop = (ele: HTMLElement, value: number) => {
+ ele.scrollTop = value;
+ };
+ if (!_stop) {
+ if (currentTime < duration) {
+ elements.forEach((ele, i) => currentTime && setScrollTop(ele, easeFunc(transition, Math.min(currentTime, duration), starts[i], to - starts[i], duration)));
+ requestAnimationFrame(animateScroll);
+ } else {
+ elements.forEach(ele => setScrollTop(ele, to));
+ }
+ }
+ };
+ animateScroll();
+ return stop;
+}
+
+export function smoothScrollHorizontal(duration: number, element: HTMLElement | HTMLElement[], to: number) {
+ const elements = element instanceof HTMLElement ? [element] : element;
+ const starts = elements.map(ele => ele.scrollLeft);
+ const startDate = new Date().getTime();
+
+ const animateScroll = () => {
+ const currentDate = new Date().getTime();
+ const currentTime = currentDate - startDate;
+ elements.forEach((ele, i) => {
+ ele.scrollLeft = easeFunc('ease', currentTime, starts[i], to - starts[i], duration);
+ });
+
+ if (currentTime < duration) {
+ requestAnimationFrame(animateScroll);
+ } else {
+ elements.forEach(ele => {
+ ele.scrollLeft = to;
+ });
+ }
+ };
+ animateScroll();
+}
+
+export function addStyleSheet(styleType: string = 'text/css') {
+ const style = document.createElement('style');
+ style.type = styleType;
+ const sheets = document.head.appendChild(style);
+ return (sheets as any).sheet;
+}
+export function addStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') {
+ const propText =
+ typeof css === 'string'
+ ? css
+ : Object.keys(css)
+ .map(p => p + ':' + (p === 'content' ? "'" + css[p] + "'" : css[p]))
+ .join(';');
+ return sheet.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length);
+}
+export function removeStyleSheetRule(sheet: any, rule: number) {
+ if (sheet.rules.length) {
+ sheet.removeRule(rule);
+ return true;
+ }
+ return false;
+}
+export function clearStyleSheetRules(sheet: any) {
+ if (sheet.rules.length) {
+ numberRange(sheet.rules.length).map(() => sheet.removeRule(0));
+ return true;
+ }
+ return false;
+}
+
+export function simulateMouseClick(element: Element | null | undefined, x: number, y: number, sx: number, sy: number, rightClick = true) {
+ if (!element) return;
+ ['pointerdown', 'pointerup'].forEach(event => {
+ const me = new PointerEvent(event, {
+ view: window,
+ bubbles: true,
+ cancelable: true,
+ button: 2,
+ pointerType: 'mouse',
+ clientX: x,
+ clientY: y,
+ screenX: sx,
+ screenY: sy,
+ });
+ (me as any).dash = true;
+ element.dispatchEvent(me);
+ });
+
+ if (rightClick) {
+ const me = new MouseEvent('contextmenu', {
+ view: window,
+ bubbles: true,
+ cancelable: true,
+ button: 2,
+ clientX: x,
+ clientY: y,
+ movementX: 0,
+ movementY: 0,
+ screenX: sx,
+ screenY: sy,
+ });
+ (me as any).dash = true;
+ element.dispatchEvent(me);
+ }
+}
+
+export function getWordAtPoint(elem: any, 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) {
+ const range = elem.ownerDocument.createRange();
+ range.selectNodeContents(elem);
+ let currentPos = 0;
+ const endPos = range.endOffset;
+ while (currentPos + 1 <= endPos) {
+ range.setStart(elem, currentPos);
+ 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
+ const ret = range.toString();
+ range.detach();
+ return ret;
+ }
+ 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();
+ }
+ return undefined;
+ });
+ }
+ return undefined;
+}
+
+export function isTargetChildOf(ele: HTMLDivElement | null, target: Element | null) {
+ let entered = false;
+ for (let child = target; !entered && child; child = child.parentElement) {
+ entered = child === ele;
+ }
+ return entered;
+}
+
+export function StopEvent(e: React.PointerEvent | React.MouseEvent | React.KeyboardEvent) {
+ e.stopPropagation();
+ e.preventDefault();
+}
+
+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,
+ // 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;
+ const doubleTapTimeout = 300;
+ targetAny._doubleTap = Date.now() - (target as any)._lastTap < doubleTapTimeout;
+ targetAny._lastTap = Date.now();
+ targetAny._downX = targetAny._lastX = e.clientX;
+ targetAny._downY = targetAny._lastY = e.clientY;
+ targetAny._noClick = false;
+ 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) {
+ moving = true;
+ if ((target as any)._doubleTime) {
+ clearTimeout((target as any)._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])) {
+ document.removeEventListener('pointermove', _moveEvent);
+ // eslint-disable-next-line no-use-before-define
+ document.removeEventListener('pointerup', _upEvent);
+ }
+ }
+ targetAny._lastX = moveEv.clientX;
+ targetAny._lastY = moveEv.clientY;
+ stopMovePropagation && moveEv.stopPropagation();
+ };
+ const _upEvent = (upEv: PointerEvent): void => {
+ const isClick = Math.abs(upEv.clientX - targetAny._downX) < 4 && Math.abs(upEv.clientY - targetAny._downY) < 4;
+ upEvent(upEv, [upEv.clientX - targetAny._downX, upEv.clientY - targetAny._downY], isClick);
+ if (isClick) {
+ if (!targetAny._doubleTime && noDoubleTapTimeout) {
+ targetAny._doubleTime = setTimeout(() => {
+ noDoubleTapTimeout?.();
+ targetAny._doubleTime = undefined;
+ }, doubleTapTimeout);
+ }
+ if (targetAny._doubleTime && targetAny._doubleTap) {
+ clearTimeout(targetAny._doubleTime);
+ targetAny._doubleTime = undefined;
+ }
+ targetAny._noClick = clickEvent(upEv, targetAny._doubleTap);
+ }
+ document.removeEventListener('pointermove', _moveEvent);
+ document.removeEventListener('pointerup', _upEvent, true);
+ };
+ const _clickEvent = (clickev: MouseEvent): void => {
+ if ((target as any)._noClick) clickev.stopPropagation();
+ document.removeEventListener('click', _clickEvent, true);
+ };
+ if (stopPropagation) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ document.addEventListener('pointermove', _moveEvent);
+ document.addEventListener('pointerup', _upEvent, true);
+ document.addEventListener('click', _clickEvent, true);
+}
+
+export function DivHeight(ele: HTMLElement): number {
+ return Number(getComputedStyle(ele).height.replace('px', ''));
+}
+export function DivWidth(ele: HTMLElement): number {
+ return Number(getComputedStyle(ele).width.replace('px', ''));
+}
+
+export function dateRangeStrToDates(dateStr: string) {
+ // dateStr in yyyy-mm-dd format
+ const dateRangeParts = dateStr.split('|'); // splits into from and to date
+ const fromParts = dateRangeParts[0].split('-');
+ const toParts = dateRangeParts[1].split('-');
+
+ const fromYear = parseInt(fromParts[0]);
+ const fromMonth = parseInt(fromParts[1]) - 1;
+ const fromDay = parseInt(fromParts[2]);
+
+ const toYear = parseInt(toParts[0]);
+ const toMonth = parseInt(toParts[1]) - 1;
+ const toDay = parseInt(toParts[2]);
+
+ return [new Date(fromYear, fromMonth, fromDay), new Date(toYear, toMonth, toDay)];
+}
+
+function replaceCanvases(oldDiv: HTMLElement, newDiv: HTMLElement) {
+ if (oldDiv.childNodes && newDiv) {
+ for (let i = 0; i < oldDiv.childNodes.length; i++) {
+ replaceCanvases(oldDiv.childNodes[i] as HTMLElement, newDiv.childNodes[i] as HTMLElement);
+ }
+ }
+ if (oldDiv instanceof HTMLCanvasElement) {
+ if (oldDiv.className === 'collectionFreeFormView-grid') {
+ const newCan = newDiv as HTMLCanvasElement;
+ const parEle = newCan.parentElement as HTMLElement;
+ parEle.removeChild(newCan);
+ parEle.appendChild(document.createElement('div'));
+ } else {
+ const canvas = oldDiv;
+ const img = document.createElement('img'); // create a Image Element
+ try {
+ img.src = canvas.toDataURL(); // image source
+ } catch (e) {
+ console.log(e);
+ }
+ img.style.width = canvas.style.width;
+ img.style.height = canvas.style.height;
+ const newCan = newDiv as HTMLCanvasElement;
+ if (newCan) {
+ const parEle = newCan.parentElement as HTMLElement;
+ parEle.removeChild(newCan);
+ parEle.appendChild(img);
+ }
+ }
+ }
+}
+
+export function UpdateIcon(
+ filename: string,
+ docViewContent: HTMLElement,
+ width: number,
+ height: number,
+ panelWidth: number,
+ panelHeight: number,
+ scrollTop: number,
+ realNativeHeight: number,
+ noSuffix: boolean,
+ replaceRootFilename: string | undefined,
+ cb: (iconFile: string, nativeWidth: number, nativeHeight: number) => any
+) {
+ const newDiv = docViewContent.cloneNode(true) as HTMLDivElement;
+ newDiv.style.width = width.toString();
+ newDiv.style.height = height.toString();
+ replaceCanvases(docViewContent, newDiv);
+ const htmlString = new XMLSerializer().serializeToString(newDiv);
+ const nativeWidth = width;
+ const nativeHeight = height;
+ return CreateImage(ClientUtils.prepend(''), document.styleSheets, htmlString, nativeWidth, (nativeWidth * panelHeight) / panelWidth, (scrollTop * panelHeight) / realNativeHeight)
+ .then(async (dataUrl: any) => {
+ 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));
+}
diff --git a/src/ServerUtils.ts b/src/ServerUtils.ts
new file mode 100644
index 000000000..ade4ca35d
--- /dev/null
+++ b/src/ServerUtils.ts
@@ -0,0 +1,27 @@
+import { Socket } from 'socket.io';
+import { Message } from './server/Message';
+import { Utils } from './Utils';
+
+export namespace ServerUtils {
+ export function Emit<T>(socket: Socket, message: Message<T>, args: T) {
+ Utils.log('Emit', message.Name, args, false);
+ socket.emit(message.Message, args);
+ }
+
+ export function AddServerHandler<T>(socket: Socket, message: Message<T>, handler: (args: T) => any) {
+ socket.on(message.Message, Utils.loggingCallback('Incoming', handler, message.Name));
+ }
+
+ export function AddServerHandlerCallback<T>(socket: Socket, message: Message<T>, handler: (args: [T, (res: any) => any]) => any) {
+ socket.on(message.Message, (arg: T, fn: (res: any) => any) => {
+ 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 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));
+ }
+}
diff --git a/src/Utils.ts b/src/Utils.ts
index 38325a463..3af057d82 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -1,53 +1,12 @@
-import { ColorResult } from 'react-color';
import * as uuid from 'uuid';
-//import { Socket } from '../node_modules/socket.io-client';
-import * as Color from 'color';
-import * as rp from 'request-promise';
-import { Socket } from '../node_modules/socket.io/dist/index';
-import { DocumentType } from './client/documents/DocumentTypes';
-import { Colors } from './client/views/global/globalEnums';
-import { Message } from './server/Message';
-import { DocumentView } from './client/views/nodes/DocumentView';
+export function clamp(n: number, lower: number, upper: number) {
+ return Math.max(lower, Math.min(upper, n));
+}
export namespace Utils {
- export let CLICK_TIME = 300;
- export let DRAG_THRESHOLD = 4;
- export let SNAP_THRESHOLD = 10;
- export function isClick(x: number, y: number, downX: number, downY: number, downTime: number) {
- return Date.now() - downTime < Utils.CLICK_TIME && Math.abs(x - downX) < Utils.DRAG_THRESHOLD && Math.abs(y - downY) < Utils.DRAG_THRESHOLD;
- }
-
- export function cleanDocumentType(type: DocumentType) {
- switch (type) {
- case DocumentType.IMG:
- return 'Image';
- case DocumentType.AUDIO:
- return 'Audio';
- case DocumentType.COL:
- return 'Collection';
- case DocumentType.RTF:
- return 'Text';
- default:
- return type.charAt(0).toUpperCase() + type.slice(1);
- }
- }
-
- export function readUploadedFileAsText(inputFile: File) {
- const temporaryFileReader = new FileReader();
-
- return new Promise((resolve, reject) => {
- temporaryFileReader.onerror = () => {
- temporaryFileReader.abort();
- reject(new DOMException('Problem parsing input file.'));
- };
-
- temporaryFileReader.onload = () => {
- resolve(temporaryFileReader.result);
- };
- temporaryFileReader.readAsText(inputFile);
- });
+ export function GuestID() {
+ return '__guest__';
}
-
export function GenerateGuid(): string {
return uuid.v4();
}
@@ -56,410 +15,138 @@ export namespace Utils {
return uuid.v5(seed, uuid.v5.URL);
}
- export function GuestID() {
- return '__guest__';
- }
+ export const loggingEnabled = false;
+ export const logFilter: number | undefined = undefined;
- /**
- * Uploads an image buffer to the server and stores with specified filename. by default the image
- * is stored at multiple resolutions each retrieved by using the filename appended with _o, _s, _m, _l (indicating original, small, medium, or large)
- * @param imageUri the bytes of the image
- * @param returnedFilename the base filename to store the image on the server
- * @param nosuffix optionally suppress creating multiple resolution images
- */
- export async function convertDataUri(imageUri: string, returnedFilename: string, nosuffix = false, replaceRootFilename?: string) {
- try {
- const posting = Utils.prepend('/uploadURI');
- const returnedUri = await rp.post(posting, {
- body: {
- uri: imageUri,
- name: returnedFilename,
- nosuffix,
- replaceRootFilename,
- },
- json: true,
- });
- return returnedUri;
- } catch (e) {
- console.log('ConvertDataURI :' + e);
+ export function log(prefixIn: string, messageName: string, messageIn: any, receiving: boolean) {
+ let prefix = prefixIn;
+ let message = messageIn;
+ if (!loggingEnabled) {
+ return;
}
- }
-
- export function GetScreenTransform(ele?: HTMLElement | null): { scale: number; translateX: number; translateY: number } {
- if (!ele) {
- return { scale: 1, translateX: 1, translateY: 1 };
+ message = message || {};
+ if (logFilter !== undefined && logFilter !== message.type) {
+ return;
}
- const rect = ele.getBoundingClientRect();
- const scale = ele.offsetWidth === 0 && rect.width === 0 ? 1 : rect.width / ele.offsetWidth;
- const translateX = rect.left;
- const translateY = rect.top;
+ const idString = (message.id || '').padStart(36, ' ');
+ prefix = prefix.padEnd(16, ' ');
+ console.log(`${prefix}: ${idString}, ${receiving ? 'receiving' : 'sending'} ${messageName} with data ${JSON.stringify(message)} `);
+ }
- return { scale, translateX, translateY };
+ export function loggingCallback(prefix: string, func: (args: any) => any, messageName: string) {
+ return (args: any) => {
+ log(prefix, messageName, args, true);
+ func(args);
+ };
}
export function TraceConsoleLog() {
- ['log', 'warn'].forEach(function (method) {
+ ['log', 'warn'].forEach(method => {
const old = (console as any)[method];
- (console as any)[method] = function () {
+ (console as any)[method] = function (...args: any[]) {
let stack = new Error('').stack?.split(/\n/);
// Chrome includes a single "Error" line, FF doesn't.
if (stack && stack[0].indexOf('Error') === 0) {
stack = stack.slice(1);
}
const message = (stack?.[1] || 'Stack undefined!').trim();
- const args = ([] as any[]).slice.apply(arguments).concat([message]);
- return old.apply(console, args);
+ const newArgs = args.slice().concat([message]);
+ return old.apply(console, newArgs);
};
});
}
- /**
- * A convenience method. Prepends the full path (i.e. http://localhost:<port>) to the
- * requested extension
- * @param extension the specified sub-path to append to the window origin
- */
- export function prepend(extension: string): string {
- return window.location.origin + extension;
- }
- export function fileUrl(filename: string): string {
- return prepend(`/files/${filename}`);
- }
-
- export function shareUrl(documentId: string): string {
- return prepend(`/doc/${documentId}?sharing=true`);
- }
-
- export function CorsProxy(url: string): string {
- return prepend('/corsProxy/') + encodeURIComponent(url);
- }
-
- export function CopyText(text: string) {
- navigator.clipboard.writeText(text);
- }
-
- export function decimalToHexString(number: number) {
- if (number < 0) {
- number = 0xffffffff + number + 1;
- }
- return (number < 16 ? '0' : '') + number.toString(16).toUpperCase();
- }
-
- export function colorString(color: ColorResult) {
- return color.hex.startsWith('#') && color.hex.length < 8 ? color.hex + (color.rgb.a ? decimalToHexString(Math.round(color.rgb.a * 255)) : 'ff') : color.hex;
- }
-
- export function fromRGBAstr(rgba: string) {
- const rm = rgba.match(/rgb[a]?\(([ 0-9]+)/);
- const r = rm ? Number(rm[1]) : 0;
- const gm = rgba.match(/rgb[a]?\([ 0-9]+,([ 0-9]+)/);
- const g = gm ? Number(gm[1]) : 0;
- const bm = rgba.match(/rgb[a]?\([ 0-9]+,[ 0-9]+,([ 0-9]+)/);
- const b = bm ? Number(bm[1]) : 0;
- const am = rgba.match(/rgba?\([ 0-9]+,[ 0-9]+,[ 0-9]+,([ .0-9]+)/);
- const a = am ? Number(am[1]) : 1;
- return { r: r, g: g, b: b, a: a };
- }
-
- const isTransparentFunctionHack = 'isTransparent(__value__)';
- export const noRecursionHack = '__noRecursion';
-
- // special case filters
- export const noDragDocsFilter = 'noDragDocs::any::check';
- export const TransparentBackgroundFilter = `backgroundColor::${isTransparentFunctionHack},${noRecursionHack}::check`; // bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
- export const OpaqueBackgroundFilter = `backgroundColor::${isTransparentFunctionHack},${noRecursionHack}::x`; // bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
-
- export function IsRecursiveFilter(val: string) {
- return !val.includes(noRecursionHack);
- }
- export function HasFunctionFilter(val: string) {
- if (val.includes(isTransparentFunctionHack)) return (color: string) => color !== '' && DashColor(color).alpha() !== 1;
- // add other function filters here...
- return undefined;
- }
-
- export function toRGBAstr(col: { r: number; g: number; b: number; a?: number }) {
- return 'rgba(' + col.r + ',' + col.g + ',' + col.b + (col.a !== undefined ? ',' + col.a : '') + ')';
- }
-
- export function HSLtoRGB(h: number, s: number, l: number) {
- // Must be fractions of 1
- // s /= 100;
- // l /= 100;
-
- const c = (1 - Math.abs(2 * l - 1)) * s,
- x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
- m = l - c / 2;
- let r = 0,
- g = 0,
- b = 0;
- if (0 <= h && h < 60) {
- r = c;
- g = x;
- b = 0;
- } else if (60 <= h && h < 120) {
- r = x;
- g = c;
- b = 0;
- } else if (120 <= h && h < 180) {
- r = 0;
- g = c;
- b = x;
- } else if (180 <= h && h < 240) {
- r = 0;
- g = x;
- b = c;
- } else if (240 <= h && h < 300) {
- r = x;
- g = 0;
- b = c;
- } else if (300 <= h && h < 360) {
- r = c;
- g = 0;
- b = x;
- }
- r = Math.round((r + m) * 255);
- g = Math.round((g + m) * 255);
- b = Math.round((b + m) * 255);
- return { r: r, g: g, b: b };
- }
-
- export function RGBToHSL(r: number, g: number, b: number) {
- // Make r, g, and b fractions of 1
- r /= 255;
- g /= 255;
- b /= 255;
-
- // Find greatest and smallest channel values
- const cmin = Math.min(r, g, b),
- cmax = Math.max(r, g, b),
- delta = cmax - cmin;
- let h = 0,
- s = 0,
- l = 0;
- // Calculate hue
-
- // No difference
- if (delta === 0) h = 0;
- // Red is max
- else if (cmax === r) h = ((g - b) / delta) % 6;
- // Green is max
- else if (cmax === g) h = (b - r) / delta + 2;
- // Blue is max
- else h = (r - g) / delta + 4;
-
- h = Math.round(h * 60);
-
- // Make negative hues positive behind 360°
- if (h < 0) h += 360; // Calculate lightness
-
- l = (cmax + cmin) / 2;
-
- // Calculate saturation
- s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
-
- // Multiply l and s by 100
- // s = +(s * 100).toFixed(1);
- // l = +(l * 100).toFixed(1);
-
- return { h: h, s: s, l: l };
- }
-
- export function scrollIntoView(targetY: number, targetHgt: number, scrollTop: number, contextHgt: number, minSpacing: number, scrollHeight: number) {
- if (!targetHgt) return targetY; // if there's no height, then assume that
- if (scrollTop + contextHgt < Math.min(scrollHeight, targetY + minSpacing + targetHgt)) {
- return Math.ceil(targetY + minSpacing + targetHgt - contextHgt);
- }
- if (scrollTop >= Math.max(0, targetY - minSpacing)) {
- return Math.max(0, Math.floor(targetY - minSpacing));
- }
- }
-
- export function clamp(n: number, lower: number, upper: number) {
- return Math.max(lower, Math.min(upper, n));
- }
-
- export function distanceBetweenHorizontalLines(xs: number, xe: number, y: number, xs2: number, xe2: number, y2: number): [number, number[]] {
- if ((xs2 <= xs && xe2 >= xs) || (xs2 <= xe && xe2 >= xe) || (xs2 >= xs && xe2 <= xe)) return [Math.abs(y - y2), [Math.max(xs, xs2), y, Math.min(xe, xe2), y]];
- if (xe2 <= xs) return [Math.sqrt((xe2 - xs) * (xe2 - xs) + (y2 - y) * (y2 - y)), [xs, y, xs, y]];
- //if (xs2 > xe)
- return [Math.sqrt((xs2 - xe) * (xs2 - xe) + (y2 - y) * (y2 - y)), [xe, y, xe, y]];
- }
- export function distanceBetweenVerticalLines(x: number, ys: number, ye: number, x2: number, ys2: number, ye2: number): [number, number[]] {
- if ((ys2 <= ys && ye2 >= ys) || (ys2 <= ye && ye2 >= ye) || (ys2 >= ys && ye2 <= ye)) return [Math.abs(x - x2), [x, Math.max(ys, ys2), x, Math.min(ye, ye2)]];
- if (ye2 <= ys) return [Math.sqrt((ye2 - ys) * (ye2 - ys) + (x2 - x) * (x2 - x)), [x, ys, x, ys]];
- //if (ys2 > ye)
- return [Math.sqrt((ys2 - ye) * (ys2 - ye) + (x2 - x) * (x2 - x)), [x, ye, x, ye]];
- }
-
export function rotPt(x: number, y: number, radAng: number) {
return { x: x * Math.cos(radAng) - y * Math.sin(radAng), y: x * Math.sin(radAng) + y * Math.cos(radAng) };
}
- function project(px: number, py: number, ax: number, ay: number, bx: number, by: number) {
- if (ax === bx && ay === by) return { point: { x: ax, y: ay }, left: false, dot: 0, t: 0 };
- const atob = { x: bx - ax, y: by - ay };
- const atop = { x: px - ax, y: py - ay };
- const len = atob.x * atob.x + atob.y * atob.y;
- var dot = atop.x * atob.x + atop.y * atob.y;
- const t = Math.min(1, Math.max(0, dot / len));
-
- dot = (bx - ax) * (py - ay) - (by - ay) * (px - ax);
-
- return {
- point: {
- x: ax + atob.x * t,
- y: ay + atob.y * t,
- },
- left: dot < 1,
- dot: dot,
- t: t,
- };
- }
+ export function getNearestPointInPerimeter(l: number, t: number, w: number, h: number, xIn: number, yIn: number) {
+ const r = l + w;
+ const b = t + h;
- export function closestPtBetweenRectangles(l: number, t: number, w: number, h: number, l1: number, t1: number, w1: number, h1: number, x: number, y: number) {
- const r = l + w,
- b = t + h;
- const r1 = l1 + w1,
- b1 = t1 + h1;
- const hsegs = [
- [l, r, t, l1, r1, t1],
- [l, r, b, l1, r1, t1],
- [l, r, t, l1, r1, b1],
- [l, r, b, l1, r1, b1],
- ];
- const vsegs = [
- [l, t, b, l1, t1, b1],
- [r, t, b, l1, t1, b1],
- [l, t, b, r1, t1, b1],
- [r, t, b, r1, t1, b1],
- ];
- const res = hsegs.reduce(
- (closest, seg) => {
- const res = distanceBetweenHorizontalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
- return res[0] < closest[0] ? res : closest;
- },
- [Number.MAX_VALUE, []] as [number, number[]]
- );
- const fres = vsegs.reduce((closest, seg) => {
- const res = distanceBetweenVerticalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
- return res[0] < closest[0] ? res : closest;
- }, res);
+ const x = clamp(xIn, l, r);
+ const y = clamp(yIn, t, b);
- const near = project(x, y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
- return project(near.point.x, near.point.y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
- }
-
- export function getNearestPointInPerimeter(l: number, t: number, w: number, h: number, x: number, y: number) {
- const r = l + w,
- b = t + h;
-
- (x = clamp(x, l, r)), (y = clamp(y, t, b));
-
- const dl = Math.abs(x - l),
- dr = Math.abs(x - r),
- dt = Math.abs(y - t),
- db = Math.abs(y - b);
+ const dl = Math.abs(x - l);
+ const dr = Math.abs(x - r);
+ const dt = Math.abs(y - t);
+ const db = Math.abs(y - b);
const m = Math.min(dl, dr, dt, db);
return m === dt ? [x, t] : m === db ? [x, b] : m === dl ? [l, y] : [r, y];
}
+}
+export function decimalToHexString(numberIn: number) {
+ const number = numberIn < 0 ? 0xffffffff + numberIn + 1 : numberIn;
+ return (number < 16 ? '0' : '') + number.toString(16).toUpperCase();
+}
- export function GetClipboardText(): string {
- const textArea = document.createElement('textarea');
- document.body.appendChild(textArea);
- textArea.focus();
- textArea.select();
-
- try {
- document.execCommand('paste');
- } catch (err) {}
-
- const val = textArea.value;
- document.body.removeChild(textArea);
- return val;
- }
-
- export const loggingEnabled: Boolean = false;
- export const logFilter: number | undefined = undefined;
-
- function log(prefix: string, messageName: string, message: any, receiving: boolean) {
- if (!loggingEnabled) {
- return;
- }
- message = message || {};
- if (logFilter !== undefined && logFilter !== message.type) {
- return;
- }
- const idString = (message.id || '').padStart(36, ' ');
- prefix = prefix.padEnd(16, ' ');
- console.log(`${prefix}: ${idString}, ${receiving ? 'receiving' : 'sending'} ${messageName} with data ${JSON.stringify(message)} `);
- }
-
- function loggingCallback(prefix: string, func: (args: any) => any, messageName: string) {
- return (args: any) => {
- log(prefix, messageName, args, true);
- func(args);
- };
- }
-
- export function Emit<T>(socket: Socket, message: Message<T>, args: T) {
- log('Emit', message.Name, args, false);
- socket.emit(message.Message, args);
- }
-
- export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T): Promise<any>;
- export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T, fn: (args: any) => any): void;
- export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T, fn?: (args: any) => any): void | Promise<any> {
- log('Emit', message.Name, args, false);
- if (fn) {
- socket.emit(message.Message, args, loggingCallback('Receiving', fn, message.Name));
- } else {
- return new Promise<any>(res => socket.emit(message.Message, args, loggingCallback('Receiving', res, message.Name)));
- }
- }
+export function distanceBetweenHorizontalLines(xs: number, xe: number, y: number, xs2: number, xe2: number, y2: number): [number, number[]] {
+ if ((xs2 <= xs && xe2 >= xs) || (xs2 <= xe && xe2 >= xe) || (xs2 >= xs && xe2 <= xe)) return [Math.abs(y - y2), [Math.max(xs, xs2), y, Math.min(xe, xe2), y]];
+ if (xe2 <= xs) return [Math.sqrt((xe2 - xs) * (xe2 - xs) + (y2 - y) * (y2 - y)), [xs, y, xs, y]];
+ // if (xs2 > xe)
+ return [Math.sqrt((xs2 - xe) * (xs2 - xe) + (y2 - y) * (y2 - y)), [xe, y, xe, y]];
+}
+export function distanceBetweenVerticalLines(x: number, ys: number, ye: number, x2: number, ys2: number, ye2: number): [number, number[]] {
+ if ((ys2 <= ys && ye2 >= ys) || (ys2 <= ye && ye2 >= ye) || (ys2 >= ys && ye2 <= ye)) return [Math.abs(x - x2), [x, Math.max(ys, ys2), x, Math.min(ye, ye2)]];
+ if (ye2 <= ys) return [Math.sqrt((ye2 - ys) * (ye2 - ys) + (x2 - x) * (x2 - x)), [x, ys, x, ys]];
+ // if (ys2 > ye)
+ return [Math.sqrt((ys2 - ye) * (ys2 - ye) + (x2 - x) * (x2 - x)), [x, ye, x, ye]];
+}
- export function AddServerHandler<T>(socket: Socket, message: Message<T>, handler: (args: T) => any) {
- socket.on(message.Message, loggingCallback('Incoming', handler, message.Name));
- }
+function project(px: number, py: number, ax: number, ay: number, bx: number, by: number) {
+ if (ax === bx && ay === by) return { point: { x: ax, y: ay }, left: false, dot: 0, t: 0 };
+ const atob = { x: bx - ax, y: by - ay };
+ const atop = { x: px - ax, y: py - ay };
+ const len = atob.x * atob.x + atob.y * atob.y;
+ let dot = atop.x * atob.x + atop.y * atob.y;
+ const t = Math.min(1, Math.max(0, dot / len));
- export function AddServerHandlerCallback<T>(socket: Socket, message: Message<T>, handler: (args: [T, (res: any) => any]) => any) {
- socket.on(message.Message, (arg: T, fn: (res: any) => any) => {
- log('S receiving', message.Name, arg, true);
- handler([arg, loggingCallback('S sending', fn, message.Name)]);
- });
- }
- export type RoomHandler = (socket: Socket, room: string) => any;
- 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));
- }
-}
+ dot = (bx - ax) * (py - ay) - (by - ay) * (px - ax);
-export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any; extract: any } {
- const omit: any = { ...obj };
- const extract: any = {};
- keys.forEach(key => {
- extract[key] = omit[key];
- delete omit[key];
- });
- pattern &&
- Array.from(Object.keys(omit))
- .filter(key => key.match(pattern))
- .forEach(key => {
- extract[key] = omit[key];
- delete omit[key];
- });
- addKeyFunc?.(omit);
- return { omit, extract };
+ return {
+ point: {
+ x: ax + atob.x * t,
+ y: ay + atob.y * t,
+ },
+ left: dot < 1,
+ dot: dot,
+ t: t,
+ };
}
-export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
- const dup: any = {};
- keys.forEach(key => (dup[key] = obj[key]));
- addKeyFunc && addKeyFunc(dup);
- return dup;
+export function closestPtBetweenRectangles(l: number, t: number, w: number, h: number, l1: number, t1: number, w1: number, h1: number, x: number, y: number) {
+ const r = l + w;
+ const b = t + h;
+ const r1 = l1 + w1;
+ const b1 = t1 + h1;
+ const hsegs = [
+ [l, r, t, l1, r1, t1],
+ [l, r, b, l1, r1, t1],
+ [l, r, t, l1, r1, b1],
+ [l, r, b, l1, r1, b1],
+ ];
+ const vsegs = [
+ [l, t, b, l1, t1, b1],
+ [r, t, b, l1, t1, b1],
+ [l, t, b, r1, t1, b1],
+ [r, t, b, r1, t1, b1],
+ ];
+ const res = hsegs.reduce(
+ (closest, seg) => {
+ const dist = distanceBetweenHorizontalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
+ return dist[0] < closest[0] ? dist : closest;
+ },
+ [Number.MAX_VALUE, []] as [number, number[]]
+ );
+ const fres = vsegs.reduce((closest, seg) => {
+ const dist = distanceBetweenVerticalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
+ return dist[0] < closest[0] ? dist : closest;
+ }, res);
+
+ const near = project(x, y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
+ return project(near.point.x, near.point.y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
}
export function timenow() {
@@ -467,7 +154,6 @@ export function timenow() {
let ampm = 'am';
let h = now.getHours();
let m: any = now.getMinutes();
- const s: any = now.getSeconds();
if (h >= 12) {
if (h > 12) h -= 12;
ampm = 'pm';
@@ -476,14 +162,8 @@ export function timenow() {
return now.toLocaleDateString() + ' ' + h + ':' + m + ' ' + ampm;
}
-export function incrementTitleCopy(title: string) {
- const numstr = title.match(/.*(\{([0-9]*)\})+/);
- const copyNumStr = `{${1 + (numstr ? +numstr[2] : 0)}}`;
- return (numstr ? title.replace(numstr[1], '') : title) + copyNumStr;
-}
-
-export function formatTime(time: number) {
- time = Math.round(time);
+export function formatTime(timeIn: number) {
+ const time = Math.round(timeIn);
const hours = Math.floor(time / 60 / 60);
const minutes = Math.floor(time / 60) - hours * 60;
const seconds = time % 60;
@@ -495,11 +175,11 @@ export function aggregateBounds(boundsList: { x: number; y: number; width?: numb
const bounds = boundsList
.map(b => ({ x: b.x, y: b.y, r: b.x + (b.width || 0), b: b.y + (b.height || 0) }))
.reduce(
- (bounds, b) => ({
- x: Math.min(b.x, bounds.x),
- y: Math.min(b.y, bounds.y),
- r: Math.max(b.r, bounds.r),
- b: Math.max(b.b, bounds.b),
+ (prevBounds, b) => ({
+ x: Math.min(b.x, prevBounds.x),
+ y: Math.min(b.y, prevBounds.y),
+ r: Math.max(b.r, prevBounds.r),
+ b: Math.max(b.b, prevBounds.b),
}),
{ x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE }
);
@@ -515,93 +195,31 @@ export function intersectRect(r1: { left: number; top: number; width: number; he
}
export function stringHash(s?: string) {
- return !s ? undefined : Math.abs(s.split('').reduce((a: any, b: any) => (a => a & a)((a << 5) - a + b.charCodeAt(0)), 0));
+ // 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));
}
export function percent2frac(percent: string) {
return Number(percent.substr(0, percent.length - 1)) / 100;
}
+export type Without<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
+
+export type Predicate<K, V> = (entry: [K, V]) => boolean;
export function numberRange(num: number) {
return num > 0 && num < 1000 ? Array.from(Array(num)).map((v, i) => i) : [];
}
-export function returnTransparent() {
- return 'transparent';
-}
-
-export function returnTrue() {
- return true;
-}
-
-export function returnIgnore(): 'ignore' {
- return 'ignore';
-}
-export function returnAlways(): 'always' {
- return 'always';
-}
-export function returnNever(): 'never' {
- return 'never';
-}
-
-export function returnDefault(): 'default' {
- return 'default';
-}
-
-export function return18() {
- return 18;
-}
-
-export function returnFalse() {
- return false;
-}
-
-export function returnAll(): 'all' {
- return 'all';
-}
-
-export function returnNone(): 'none' {
- return 'none';
-}
-
-export function returnVal(val1?: number, val2?: number) {
- return val1 ? val1 : val2 !== undefined ? val2 : 0;
-}
-
-export function returnOne() {
- return 1;
-}
-
-export function returnZero() {
- return 0;
-}
-
-export function returnEmptyString() {
- return '';
-}
-
-export function returnEmptyFilter() {
- return [] as string[];
-}
-
-export function returnEmptyDoclist() {
- return [] as any[];
-}
-
-export let emptyPath: DocumentView[] = [];
-
export function emptyFunction() {
return undefined;
}
+export const emptyPath: any[] = [];
+
export function unimplementedFunction() {
throw new Error('This function is not implemented, but should be.');
}
-export type Without<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
-
-export type Predicate<K, V> = (entry: [K, V]) => boolean;
-
export function DeepCopy<K, V>(source: Map<K, V>, predicate?: Predicate<K, V>) {
const deepCopy = new Map<K, V>();
const entries = source.entries();
@@ -628,197 +246,6 @@ export namespace JSONUtils {
}
}
-const easeFunc = (transition: 'ease' | 'linear' | undefined, currentTime: number, start: number, change: number, duration: number) => {
- if (transition === 'linear') {
- let newCurrentTime = currentTime / duration; // currentTime / (duration / 2);
- return start + newCurrentTime * change;
- }
-
- let newCurrentTime = currentTime / (duration / 2);
- if (newCurrentTime < 1) {
- return (change / 2) * newCurrentTime * newCurrentTime + start;
- }
-
- newCurrentTime -= 1;
- return (-change / 2) * (newCurrentTime * (newCurrentTime - 2) - 1) + start;
-};
-
-export function smoothScroll(duration: number, element: HTMLElement | HTMLElement[], to: number, transition: 'ease' | 'linear' | undefined, stopper?: () => void) {
- stopper?.();
- const elements = element instanceof HTMLElement ? [element] : element;
- const starts = elements.map(element => element.scrollTop);
- const startDate = new Date().getTime();
- let _stop = false;
- const stop = () => (_stop = true);
- const animateScroll = () => {
- const currentDate = new Date().getTime();
- const currentTime = currentDate - startDate;
- elements.map((element, i) => (element.scrollTop = easeFunc(transition, currentTime, starts[i], to - starts[i], duration)));
-
- if (!_stop) {
- if (currentTime < duration) {
- requestAnimationFrame(animateScroll);
- } else {
- elements.forEach(element => (element.scrollTop = to));
- }
- }
- };
- animateScroll();
- return stop;
-}
-
-export function smoothScrollHorizontal(duration: number, element: HTMLElement | HTMLElement[], to: number) {
- const elements = element instanceof HTMLElement ? [element] : element;
- const starts = elements.map(element => element.scrollLeft);
- const startDate = new Date().getTime();
-
- const animateScroll = () => {
- const currentDate = new Date().getTime();
- const currentTime = currentDate - startDate;
- elements.map((element, i) => (element.scrollLeft = easeFunc('ease', currentTime, starts[i], to - starts[i], duration)));
-
- if (currentTime < duration) {
- requestAnimationFrame(animateScroll);
- } else {
- elements.forEach(element => (element.scrollLeft = to));
- }
- };
- animateScroll();
-}
-
-export function addStyleSheet(styleType: string = 'text/css') {
- const style = document.createElement('style');
- style.type = styleType;
- const sheets = document.head.appendChild(style);
- return (sheets as any).sheet;
-}
-export function addStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') {
- const propText =
- typeof css === 'string'
- ? css
- : Object.keys(css)
- .map(p => p + ':' + (p === 'content' ? "'" + css[p] + "'" : css[p]))
- .join(';');
- return sheet.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length);
-}
-export function removeStyleSheetRule(sheet: any, rule: number) {
- if (sheet.rules.length) {
- sheet.removeRule(rule);
- return true;
- }
- return false;
-}
-export function clearStyleSheetRules(sheet: any) {
- if (sheet.rules.length) {
- numberRange(sheet.rules.length).map(n => sheet.removeRule(0));
- return true;
- }
- return false;
-}
-
-export function simulateMouseClick(element: Element | null | undefined, x: number, y: number, sx: number, sy: number, rightClick = true) {
- if (!element) return;
- ['pointerdown', 'pointerup'].map(event => {
- const me = new PointerEvent(event, {
- view: window,
- bubbles: true,
- cancelable: true,
- button: 2,
- pointerType: 'mouse',
- clientX: x,
- clientY: y,
- screenX: sx,
- screenY: sy,
- });
- (me as any).dash = true;
- element.dispatchEvent(me);
- });
-
- if (rightClick) {
- const me = new MouseEvent('contextmenu', {
- view: window,
- bubbles: true,
- cancelable: true,
- button: 2,
- clientX: x,
- clientY: y,
- movementX: 0,
- movementY: 0,
- screenX: sx,
- screenY: sy,
- });
- (me as any).dash = true;
- element.dispatchEvent(me);
- }
-}
-
-export function DashColor(color: string) {
- try {
- return color ? Color(color.toLowerCase()) : Color('transparent');
- } catch (e) {
- if (color.includes('gradient')) console.log("using color 'white' in place of :" + color);
- else console.log('COLOR error:', e);
- return Color('white');
- }
-}
-
-export function lightOrDark(color: any) {
- if (color === 'transparent' || !color) return Colors.BLACK;
- if (color.startsWith?.('linear')) return Colors.BLACK;
- if (DashColor(color).isLight()) return Colors.BLACK;
- return Colors.WHITE;
-}
-
-export function getWordAtPoint(elem: any, x: number, y: number): string | undefined {
- if (elem.tagName === 'INPUT') return 'input';
- if (elem.tagName === 'TEXTAREA') return 'textarea';
- if (elem.nodeType === elem.TEXT_NODE) {
- const range = elem.ownerDocument.createRange();
- range.selectNodeContents(elem);
- var currentPos = 0;
- const endPos = range.endOffset;
- while (currentPos + 1 <= endPos) {
- range.setStart(elem, currentPos);
- 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
- const ret = range.toString();
- range.detach();
- return ret;
- }
- currentPos += 1;
- }
- } else {
- for (const childNode of elem.childNodes) {
- 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();
- }
- }
- }
- return undefined;
-}
-
-export function isTargetChildOf(ele: HTMLDivElement | null, target: Element | null) {
- let entered = false;
- for (let child = target; !entered && child; child = child.parentElement) {
- entered = child === ele;
- }
- return entered;
-}
-
-export function StopEvent(e: React.PointerEvent | React.MouseEvent) {
- e.stopPropagation();
- e.preventDefault();
-}
-
/**
* Helper method for converting pixel string eg. '32px' into number eg. 32
* @param value: string with 'px' ending
@@ -828,100 +255,10 @@ export function StopEvent(e: React.PointerEvent | React.MouseEvent) {
* '32px' -> 32
*/
export function numberValue(value: string | undefined): number {
- if (value == undefined) return 0;
+ if (value === undefined) return 0;
return parseInt(value);
}
export function numbersAlmostEqual(num1: number, num2: number) {
return Math.abs(num1 - num2) < 0.2;
}
-
-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,
- stopPropagation: boolean = true,
- stopMovePropagation: boolean = true,
- noDoubleTapTimeout?: () => void
-) {
- const doubleTapTimeout = 300;
- (target as any)._doubleTap = Date.now() - (target as any)._lastTap < doubleTapTimeout;
- (target as any)._lastTap = Date.now();
- (target as any)._downX = (target as any)._lastX = e.clientX;
- (target as any)._downY = (target as any)._lastY = e.clientY;
- (target as any)._noClick = false;
- var moving = false;
-
- const _moveEvent = (e: PointerEvent): void => {
- if (moving || Math.abs(e.clientX - (target as any)._downX) > Utils.DRAG_THRESHOLD || Math.abs(e.clientY - (target as any)._downY) > Utils.DRAG_THRESHOLD) {
- moving = true;
- if ((target as any)._doubleTime) {
- clearTimeout((target as any)._doubleTime);
- (target as any)._doubleTime = undefined;
- }
- if (moveEvent(e, [(target as any)._downX, (target as any)._downY], [e.clientX - (target as any)._lastX, e.clientY - (target as any)._lastY])) {
- document.removeEventListener('pointermove', _moveEvent);
- document.removeEventListener('pointerup', _upEvent);
- }
- }
- (target as any)._lastX = e.clientX;
- (target as any)._lastY = e.clientY;
- stopMovePropagation && e.stopPropagation();
- };
- const _upEvent = (e: PointerEvent): void => {
- const isClick = Math.abs(e.clientX - (target as any)._downX) < 4 && Math.abs(e.clientY - (target as any)._downY) < 4;
- upEvent(e, [e.clientX - (target as any)._downX, e.clientY - (target as any)._downY], isClick);
- if (isClick) {
- if (!(target as any)._doubleTime && noDoubleTapTimeout) {
- (target as any)._doubleTime = setTimeout(() => {
- noDoubleTapTimeout?.();
- (target as any)._doubleTime = undefined;
- }, doubleTapTimeout);
- }
- if ((target as any)._doubleTime && (target as any)._doubleTap) {
- clearTimeout((target as any)._doubleTime);
- (target as any)._doubleTime = undefined;
- }
- (target as any)._noClick = clickEvent(e, (target as any)._doubleTap);
- }
- document.removeEventListener('pointermove', _moveEvent);
- document.removeEventListener('pointerup', _upEvent, true);
- };
- const _clickEvent = (e: MouseEvent): void => {
- if ((target as any)._noClick) e.stopPropagation();
- document.removeEventListener('click', _clickEvent, true);
- };
- if (stopPropagation) {
- e.stopPropagation();
- e.preventDefault();
- }
- document.addEventListener('pointermove', _moveEvent);
- document.addEventListener('pointerup', _upEvent, true);
- document.addEventListener('click', _clickEvent, true);
-}
-
-export function DivHeight(ele: HTMLElement): number {
- return Number(getComputedStyle(ele).height.replace('px', ''));
-}
-export function DivWidth(ele: HTMLElement): number {
- return Number(getComputedStyle(ele).width.replace('px', ''));
-}
-
-export function dateRangeStrToDates(dateStr: string) {
- // dateStr in yyyy-mm-dd format
- const dateRangeParts = dateStr.split('|'); // splits into from and to date
- const fromParts = dateRangeParts[0].split('-');
- const toParts = dateRangeParts[1].split('-');
-
- const fromYear = parseInt(fromParts[0]);
- const fromMonth = parseInt(fromParts[1]) - 1;
- const fromDay = parseInt(fromParts[2]);
-
- const toYear = parseInt(toParts[0]);
- const toMonth = parseInt(toParts[1]) - 1;
- const toDay = parseInt(toParts[2]);
-
- return [new Date(fromYear, fromMonth, fromDay), new Date(toYear, toMonth, toDay)];
-}
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 6217cf04b..ac865382d 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,20 +1,15 @@
import { runInAction } from 'mobx';
-import * as rp from 'request-promise';
-import { Doc, DocListCast, Opt } from '../fields/Doc';
+import { Socket, io } from 'socket.io-client';
+import { ClientUtils } from '../ClientUtils';
+import { Utils, emptyFunction } from '../Utils';
+import { Doc, Opt } from '../fields/Doc';
import { UpdatingFromServer } from '../fields/DocSymbols';
import { FieldLoader } from '../fields/FieldLoader';
import { HandleUpdate, Id, Parent } from '../fields/FieldSymbols';
-import { ObjectField } from '../fields/ObjectField';
+import { ObjectField, SetObjGetRefField, SetObjGetRefFields } from '../fields/ObjectField';
import { RefField } from '../fields/RefField';
-import { DocCast, StrCast } from '../fields/Types';
-import { Socket } from '../../node_modules/socket.io/dist/index';
-//import MobileInkOverlay from '../mobile/MobileInkOverlay';
-import { emptyFunction, Utils } from '../Utils';
-import { GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, YoutubeQueryTypes } from './../server/Message';
-import { DocumentType } from './documents/DocumentTypes';
-import { LinkManager } from './util/LinkManager';
+import { GestureContent, Message, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, YoutubeQueryTypes } from '../server/Message';
import { SerializationHelper } from './util/SerializationHelper';
-//import { GestureOverlay } from './views/GestureOverlay';
/**
* This class encapsulates the transfer and cross-client synchronization of
@@ -30,68 +25,53 @@ 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<Opt<RefField>> } = {};
+ export function Cache() {
+ return _cache;
+ }
- export function FindDocByTitle(title: string) {
- const foundDocId =
- title &&
- Array.from(Object.keys(_cache))
- .filter(key => _cache[key] instanceof Doc)
- .find(key => (_cache[key] as Doc).title === title);
-
- return foundDocId ? (_cache[foundDocId] as Doc) : undefined;
- }
- let cacheDocumentIds = ''; // ; separate string of all documents ids in the user's working set (cached on the server)
- export let CacheNeedsUpdate = false;
- export function UPDATE_SERVER_CACHE() {
- const prototypes = Object.values(DocumentType)
- .filter(type => type !== DocumentType.NONE)
- .map(type => _cache[type + 'Proto'])
- .filter(doc => doc instanceof Doc)
- .map(doc => doc as Doc);
- const references = new Set<Doc>(prototypes);
- Doc.FindReferences(Doc.UserDoc(), references, undefined);
- DocListCast(DocCast(Doc.UserDoc().myLinkDatabase).data).forEach(link => {
- if (!references.has(DocCast(link.link_anchor_1)) && !references.has(DocCast(link.link_anchor_2))) {
- Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myLinkDatabase), 'data', link);
- Doc.AddDocToList(Doc.MyRecentlyClosed, undefined, link);
- }
- });
- LinkManager.Instance.userLinkDBs.forEach(linkDb => Doc.FindReferences(linkDb, references, undefined));
- const filtered = Array.from(references);
-
- const newCacheUpdate = filtered.map(doc => doc[Id]).join(';');
- if (newCacheUpdate === cacheDocumentIds) return;
- cacheDocumentIds = newCacheUpdate;
-
- // print out cached docs
- console.log('Set cached docs = ');
- const is_filtered = filtered.filter(doc => !Doc.IsSystem(doc));
- const strings = is_filtered.map(doc => StrCast(doc.title) + ' ' + (Doc.IsDataProto(doc) ? '(data)' : '(embedding)'));
- strings.sort().forEach((str, i) => console.log(i.toString() + ' ' + str));
-
- rp.post(Utils.prepend('/setCacheDocumentIds'), {
- body: {
- cacheDocumentIds,
- },
- json: true,
- });
+ 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;
+
+ export function AddServerHandler<T>(socket: Socket, message: Message<T>, handler: (args: T) => any) {
+ socket.on(message.Message, Utils.loggingCallback('Incoming', handler, message.Name));
+ }
+ export function Emit<T>(socket: Socket, message: Message<T>, args: T) {
+ // log('Emit', message.Name, args, false);
+ socket.emit(message.Message, args);
+ }
+ export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T): Promise<any>;
+ export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T, fn: (args: any) => any): void;
+ export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T, fn?: (args: any) => any): void | Promise<any> {
+ // log('Emit', message.Name, args, false);
+ if (fn) {
+ socket.emit(message.Message, args, Utils.loggingCallback('Receiving', fn, message.Name));
+ } else {
+ return new Promise<any>(res => {
+ socket.emit(message.Message, args, Utils.loggingCallback('Receiving', res, message.Name));
+ });
+ }
}
- export let _socket: Socket;
+
+ let _socket: Socket;
// this client's distinct GUID created at initialization
let USER_ID: string;
// indicates whether or not a document is currently being udpated, and, if so, its id
export enum WriteMode {
- Default = 0, //Anything goes
- Playground = 1, //Playground (write own/no read other updates)
- LiveReadonly = 2, //Live Readonly (no write/read others)
- LivePlayground = 3, //Live Playground (write own/read others)
+ Default = 0, // Anything goes
+ Playground = 1, // Playground (write own/no read other updates)
+ LiveReadonly = 2, // Live Readonly (no write/read others)
+ LivePlayground = 3, // Live Playground (write own/read others)
}
const fieldWriteModes: { [field: string]: WriteMode } = {};
const docsWithUpdates: { [field: string]: Set<Doc> } = {};
- export var PlaygroundFields: string[] = [];
+ export const PlaygroundFields: string[] = [];
export function setLivePlaygroundFields(livePlaygroundFields: string[]) {
DocServer.PlaygroundFields.push(...livePlaygroundFields);
livePlaygroundFields.forEach(f => DocServer.setFieldWriteMode(f, DocServer.WriteMode.LivePlayground));
@@ -116,7 +96,7 @@ export namespace DocServer {
}
export function getFieldWriteMode(field: string) {
- return Doc.CurrentUserEmail === 'guest' ? WriteMode.LivePlayground : fieldWriteModes[field] || WriteMode.Default;
+ return ClientUtils.CurrentUserEmail() === 'guest' ? WriteMode.LivePlayground : fieldWriteModes[field] || WriteMode.Default;
}
export function registerDocWithCachedUpdate(doc: Doc, field: string, oldValue: any) {
@@ -132,20 +112,20 @@ export namespace DocServer {
export namespace Mobile {
export function dispatchGesturePoints(content: GestureContent) {
- Utils.Emit(_socket, MessageStore.GesturePoints, content);
+ DocServer.Emit(_socket, MessageStore.GesturePoints, content);
}
export function dispatchOverlayTrigger(content: MobileInkOverlayContent) {
// _socket.emit("dispatchBoxTrigger");
- Utils.Emit(_socket, MessageStore.MobileInkOverlayTrigger, content);
+ DocServer.Emit(_socket, MessageStore.MobileInkOverlayTrigger, content);
}
export function dispatchOverlayPositionUpdate(content: UpdateMobileInkOverlayPositionContent) {
- Utils.Emit(_socket, MessageStore.UpdateMobileInkOverlayPosition, content);
+ DocServer.Emit(_socket, MessageStore.UpdateMobileInkOverlayPosition, content);
}
export function dispatchMobileDocumentUpload(content: MobileDocumentUploadContent) {
- Utils.Emit(_socket, MessageStore.MobileDocumentUpload, content);
+ DocServer.Emit(_socket, MessageStore.MobileDocumentUpload, content);
}
}
@@ -167,55 +147,14 @@ export namespace DocServer {
window.location.reload();
}
- export function init(protocol: string, hostname: string, port: number, identifier: string) {
- _cache = {};
- USER_ID = identifier;
- protocol = protocol.startsWith('https') ? 'wss' : 'ws';
- _socket = require('socket.io-client')(`${protocol}://${hostname}:${port}`, { transports: ['websocket'], rejectUnauthorized: false });
- // io.connect(`https://7f079dda.ngrok.io`);// if using ngrok, create a special address for the websocket
-
- _GetCachedRefField = _GetCachedRefFieldImpl;
- _GetRefField = _GetRefFieldImpl;
- _GetRefFields = _GetRefFieldsImpl;
- _CreateField = _CreateFieldImpl;
- _UpdateField = _UpdateFieldImpl;
-
- /**
- * Whenever the server sends us its handshake message on our
- * websocket, we use the above function to return the handshake.
- */
- Utils.AddServerHandler(_socket, MessageStore.Foo, onConnection);
- Utils.AddServerHandler(_socket, MessageStore.UpdateField, respondToUpdate);
- Utils.AddServerHandler(_socket, MessageStore.DeleteField, respondToDelete);
- Utils.AddServerHandler(_socket, MessageStore.DeleteFields, respondToDelete);
- Utils.AddServerHandler(_socket, MessageStore.ConnectionTerminated, alertUser);
-
- // // mobile ink overlay socket events to communicate between mobile view and desktop view
- // _socket.addEventListener('receiveGesturePoints', (content: GestureContent) => {
- // // MobileInkOverlay.Instance.drawStroke(content);
- // });
- // _socket.addEventListener('receiveOverlayTrigger', (content: MobileInkOverlayContent) => {
- // //GestureOverlay.Instance.enableMobileInkOverlay(content);
- // // MobileInkOverlay.Instance.initMobileInkOverlay(content);
- // });
- // _socket.addEventListener('receiveUpdateOverlayPosition', (content: UpdateMobileInkOverlayPositionContent) => {
- // // MobileInkOverlay.Instance.updatePosition(content);
- // });
- // _socket.addEventListener('receiveMobileDocumentUpload', (content: MobileDocumentUploadContent) => {
- // // MobileInkOverlay.Instance.uploadDocument(content);
- // });
- }
-
- function errorFunc(): never {
- throw new Error("Can't use DocServer without calling init first");
- }
-
export namespace Control {
let _isReadOnly = false;
export function makeReadOnly() {
if (!_isReadOnly) {
_isReadOnly = true;
- _CreateField = field => (_cache[field[Id]] = field);
+ _CreateField = field => {
+ _cache[field[Id]] = field;
+ };
_UpdateField = emptyFunction;
// _RespondToUpdate = emptyFunction; // bcz: option: don't clear RespondToUpdate to continue to receive updates as others change the DB
}
@@ -252,7 +191,7 @@ export namespace DocServer {
* all documents in the database.
*/
export function deleteDatabase() {
- Utils.Emit(_socket, MessageStore.DeleteAll, {});
+ DocServer.Emit(_socket, MessageStore.DeleteAll, {});
}
}
@@ -275,7 +214,7 @@ export namespace DocServer {
// synchronously, we emit a single callback to the server requesting the serialized (i.e. represented by a string)
// field for the given ids. This returns a promise, which, when resolved, indicates the the JSON serialized version of
// the field has been returned from the server
- const getSerializedField = Utils.EmitCallback(_socket, MessageStore.GetRefField, id);
+ const getSerializedField = DocServer.EmitCallback(_socket, MessageStore.GetRefField, id);
// when the serialized RefField has been received, go head and begin deserializing it into an object.
// Here, once deserialized, we also invoke .proto to 'load' the document's prototype, which ensures that all
@@ -283,7 +222,7 @@ export namespace DocServer {
const deserializeField = getSerializedField.then(async fieldJson => {
// deserialize
const field = await SerializationHelper.Deserialize(fieldJson);
- if (force && field instanceof Doc && cached instanceof Doc) {
+ if (force && field && cached instanceof Doc) {
cached[UpdatingFromServer] = true;
Array.from(Object.keys(field)).forEach(key => {
const fieldval = field[key];
@@ -294,7 +233,8 @@ export namespace DocServer {
});
cached[UpdatingFromServer] = false;
return cached;
- } else if (field !== undefined) {
+ }
+ if (field !== undefined) {
_cache[id] = field;
} else {
delete _cache[id];
@@ -308,24 +248,25 @@ export namespace DocServer {
// being retrieved and cached
!force && (_cache[id] = deserializeField);
return force ? (cached as any) : deserializeField;
- } else if (cached instanceof Promise) {
+ }
+ if (cached instanceof Promise) {
// BEING RETRIEVED AND CACHED => some other caller previously (likely recently) called GetRefField(s),
// and requested the document I'm looking for. Shouldn't fetch again, just
// return this promise which will resolve to the field itself (see 7)
return cached;
- } else {
- // CACHED => great, let's just return the cached field we have
- return Promise.resolve(cached).then(field => {
- //(field instanceof Doc) && fetchProto(field);
- return field;
- });
}
+ // CACHED => great, let's just return the cached field we have
+ return Promise.resolve(cached).then(
+ field => field
+ // (field instanceof Doc) && fetchProto(field);
+ );
};
const _GetCachedRefFieldImpl = (id: string): Opt<RefField> => {
const cached = _cache[id];
if (cached !== undefined && !(cached instanceof Promise)) {
return cached;
}
+ return undefined;
};
let _GetRefField: (id: string, force: boolean) => Promise<Opt<RefField>> = errorFunc;
@@ -339,15 +280,15 @@ export namespace DocServer {
}
export async function getYoutubeChannels() {
- return await Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.Channels });
+ return DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.Channels });
}
export function getYoutubeVideos(videoTitle: string, callBack: (videos: any[]) => void) {
- Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.SearchVideo, userInput: videoTitle }, callBack);
+ DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.SearchVideo, userInput: videoTitle }, callBack);
}
export function getYoutubeVideoDetails(videoIds: string, callBack: (videoDetails: any[]) => void) {
- Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.VideoDetails, videoIds: videoIds }, callBack);
+ DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.VideoDetails, videoIds: videoIds }, callBack);
}
/**
@@ -360,21 +301,24 @@ export namespace DocServer {
const requestedIds: string[] = [];
const promises: Promise<any>[] = [];
- let defaultRes: any = undefined;
- const defaultPromise = new Promise<any>(res => (defaultRes = res));
- let defaultPromises: { p: Promise<any>; id: string }[] = [];
+ let defaultRes: any;
+ const defaultPromise = new Promise<any>(res => {
+ defaultRes = res;
+ });
+ const defaultPromises: { p: Promise<any>; 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
- for (const id of ids.filter(id => id)) {
+ // 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,
- p: (_cache[id] = new Promise<any>(async res => {
- await defaultPromise;
- res(_cache[id]);
+ // eslint-disable-next-line no-loop-func
+ p: (_cache[id] = new Promise<any>(res => {
+ defaultPromise.then(() => res(_cache[id]));
})),
});
// NOT CACHED => we'll have to send a request to the server
@@ -396,27 +340,39 @@ export namespace DocServer {
// 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 Utils.EmitCallback(_socket, MessageStore.GetRefFields, requestedIds);
+ 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.
let processed = 0;
console.log('deserializing ' + serializedFields.length + ' fields');
+ // eslint-disable-next-line no-restricted-syntax
for (const field of serializedFields) {
processed++;
if (processed % 150 === 0) {
- runInAction(() => (FieldLoader.ServerLoadStatus.retrieved = processed));
- await new Promise(res => setTimeout(res)); // force loading to yield to splash screen rendering to update progress
+ // eslint-disable-next-line no-loop-func
+ runInAction(() => {
+ FieldLoader.ServerLoadStatus.retrieved = processed;
+ });
+ // 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
+ // 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) {
@@ -436,7 +392,7 @@ export namespace DocServer {
// get the resolved field
} else if (cached instanceof Promise) {
console.log('.');
- //promises.push(cached);
+ // promises.push(cached);
} else if (field) {
// console.log('-');
}
@@ -453,7 +409,7 @@ export namespace DocServer {
// 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));
+ // 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)
@@ -462,7 +418,7 @@ export namespace DocServer {
//
// 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);
+ // 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]));
@@ -487,6 +443,10 @@ export namespace DocServer {
}
// WRITE A NEW DOCUMENT TO THE SERVER
+ let _cacheNeedsUpdate = false;
+ export function CacheNeedsUpdate() {
+ return _cacheNeedsUpdate;
+ }
/**
* A wrapper around the function local variable _createField.
@@ -495,18 +455,16 @@ export namespace DocServer {
* @param field the [RefField] to be serialized and sent to the server to be stored in the database
*/
export function CreateField(field: RefField) {
- CacheNeedsUpdate = true;
+ _cacheNeedsUpdate = true;
_CreateField(field);
}
function _CreateFieldImpl(field: RefField) {
_cache[field[Id]] = field;
const initialState = SerializationHelper.Serialize(field);
- Doc.CurrentUserEmail !== 'guest' && Utils.Emit(_socket, MessageStore.CreateField, initialState);
+ ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.CreateField, initialState);
}
- let _CreateField: (field: RefField) => void = errorFunc;
-
// NOTIFY THE SERVER OF AN UPDATE TO A DOC'S STATE
/**
@@ -522,13 +480,11 @@ export namespace DocServer {
}
function _UpdateFieldImpl(id: string, diff: any) {
- !DocServer.Control.isReadOnly() && Doc.CurrentUserEmail !== 'guest' && Utils.Emit(_socket, MessageStore.UpdateField, { id, diff });
+ !DocServer.Control.isReadOnly() && ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.UpdateField, { id, diff });
}
- let _UpdateField: (id: string, diff: any) => void = errorFunc;
-
function _respondToUpdateImpl(diff: any) {
- const id = diff.id;
+ const { id } = diff;
// to be valid, the Diff object must reference
// a document's id
if (id === undefined) {
@@ -559,11 +515,11 @@ export namespace DocServer {
}
export function DeleteDocument(id: string) {
- Doc.CurrentUserEmail !== 'guest' && Utils.Emit(_socket, MessageStore.DeleteField, id);
+ ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.DeleteField, id);
}
export function DeleteDocuments(ids: string[]) {
- Doc.CurrentUserEmail !== 'guest' && Utils.Emit(_socket, MessageStore.DeleteFields, ids);
+ ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.DeleteFields, ids);
}
function _respondToDeleteImpl(ids: string | string[]) {
@@ -577,7 +533,7 @@ export namespace DocServer {
}
}
- let _RespondToUpdate = _respondToUpdateImpl;
+ const _RespondToUpdate = _respondToUpdateImpl;
const _respondToDelete = _respondToDeleteImpl;
function respondToUpdate(diff: any) {
@@ -587,4 +543,28 @@ export namespace DocServer {
function respondToDelete(ids: string | string[]) {
_respondToDelete(ids);
}
+
+ export function init(protocol: string, hostname: string, port: number, identifier: string) {
+ _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));
+ // io.connect(`https://7f079dda.ngrok.io`);// if using ngrok, create a special address for the websocket
+
+ _GetCachedRefField = _GetCachedRefFieldImpl;
+ SetObjGetRefField((_GetRefField = _GetRefFieldImpl));
+ SetObjGetRefFields((_GetRefFields = _GetRefFieldsImpl));
+ _CreateField = _CreateFieldImpl;
+ _UpdateField = _UpdateFieldImpl;
+
+ /**
+ * Whenever the server sends us its handshake message on our
+ * websocket, we use the above function to return the handshake.
+ */
+ DocServer.AddServerHandler(_socket, MessageStore.Foo, onConnection);
+ DocServer.AddServerHandler(_socket, MessageStore.UpdateField, respondToUpdate);
+ DocServer.AddServerHandler(_socket, MessageStore.DeleteField, respondToDelete);
+ DocServer.AddServerHandler(_socket, MessageStore.DeleteFields, respondToDelete);
+ DocServer.AddServerHandler(_socket, MessageStore.ConnectionTerminated, alertUser);
+ }
}
diff --git a/src/client/Network.ts b/src/client/Network.ts
index cdcd5225a..968c407b2 100644
--- a/src/client/Network.ts
+++ b/src/client/Network.ts
@@ -1,5 +1,6 @@
-import { Utils } from '../Utils';
import * as requestPromise from 'request-promise';
+import { ClientUtils } from '../ClientUtils';
+import { Utils } from '../Utils';
import { Upload } from '../server/SharedMediaTypes';
/**
@@ -14,7 +15,7 @@ export namespace Networking {
export async function PostToServer(relativeRoute: string, body?: any) {
const options = {
- uri: Utils.prepend(relativeRoute),
+ uri: ClientUtils.prepend(relativeRoute),
method: 'POST',
body,
json: true,
@@ -49,14 +50,14 @@ export namespace Networking {
}
const maxFileSize = 50000000;
if (fileguidpairs.some(f => f.file.size > maxFileSize)) {
- return new Promise<any>(res =>
+ return new Promise<any>(res => {
res([
{
source: { name: '', type: '', size: 0, toJson: () => ({ name: '', type: '' }) },
result: { name: '', message: `max file size (${maxFileSize / 1000000}MB) exceeded` },
},
- ])
- );
+ ]);
+ });
}
formData.set('fileguids', fileguidpairs.map(pair => pair.guid).join(';'));
formData.set('filesize', fileguidpairs.reduce((sum, pair) => sum + pair.file.size, 0).toString());
diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx
index 855f48f7e..5269f763b 100644
--- a/src/client/apis/GoogleAuthenticationManager.tsx
+++ b/src/client/apis/GoogleAuthenticationManager.tsx
@@ -1,14 +1,14 @@
-import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx";
-import { observer } from "mobx-react";
-import * as React from "react";
-import { Opt } from "../../fields/Doc";
-import { Networking } from "../Network";
-import { ScriptingGlobals } from "../util/ScriptingGlobals";
-import { MainViewModal } from "../views/MainViewModal";
-import "./GoogleAuthenticationManager.scss";
+import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Opt } from '../../fields/Doc';
+import { Networking } from '../Network';
+import { ScriptingGlobals } from '../util/ScriptingGlobals';
+import { MainViewModal } from '../views/MainViewModal';
+import './GoogleAuthenticationManager.scss';
-const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth";
-const prompt = "Paste authorization code here...";
+const AuthenticationUrl = 'https://accounts.google.com/o/oauth2/v2/auth';
+const prompt = 'Paste authorization code here...';
@observer
export class GoogleAuthenticationManager extends React.Component<{}> {
@@ -23,11 +23,11 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
private disposer: Opt<IReactionDisposer>;
private set isOpen(value: boolean) {
- runInAction(() => this.openState = value);
+ runInAction(() => (this.openState = value));
}
private set shouldShowPasteTarget(value: boolean) {
- runInAction(() => this.showPasteTargetState = value);
+ runInAction(() => (this.showPasteTargetState = value));
}
public cancel() {
@@ -35,7 +35,7 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
}
public fetchOrGenerateAccessToken = async (displayIfFound = false) => {
- let response: any = await Networking.FetchFromServer("/readGoogleAccessToken");
+ let response: any = await Networking.FetchFromServer('/readGoogleAccessToken');
// if this is an authentication url, activate the UI to register the new access token
if (new RegExp(AuthenticationUrl).test(response)) {
this.isOpen = true;
@@ -47,7 +47,7 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
async authenticationCode => {
if (authenticationCode && /\d{1}\/[\w-]{55}/.test(authenticationCode)) {
this.disposer?.();
- const response = await Networking.PostToServer("/writeGoogleAccessToken", { authenticationCode });
+ const response = await Networking.PostToServer('/writeGoogleAccessToken', { authenticationCode });
runInAction(() => {
this.success = true;
this.credentials = response;
@@ -71,7 +71,7 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
this.isOpen = true;
}
return response.access_token;
- }
+ };
resetState = action((visibleForMS: number = 3000, fadesOutInMS: number = 500) => {
if (!visibleForMS && !fadesOutInMS) {
@@ -89,14 +89,20 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
this.displayLauncher = false;
this.shouldShowPasteTarget = false;
if (visibleForMS > 0 && fadesOutInMS > 0) {
- setTimeout(action(() => {
- this.isOpen = false;
- setTimeout(action(() => {
- this.success = undefined;
- this.displayLauncher = true;
- this.credentials = undefined;
- }), fadesOutInMS);
- }), visibleForMS);
+ setTimeout(
+ action(() => {
+ this.isOpen = false;
+ setTimeout(
+ action(() => {
+ this.success = undefined;
+ this.displayLauncher = true;
+ this.credentials = undefined;
+ }),
+ fadesOutInMS
+ );
+ }),
+ visibleForMS
+ );
}
});
@@ -108,61 +114,44 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
private get renderPrompt() {
return (
<div className={'authorize-container'}>
-
- {this.displayLauncher ? <button
- className={"dispatch"}
- onClick={() => {
- window.open(this.authenticationLink);
- setTimeout(() => this.shouldShowPasteTarget = true, 500);
- }}
- style={{ marginBottom: this.showPasteTargetState ? 15 : 0 }}
- >Authorize a Google account...</button> : (null)}
- {this.showPasteTargetState ? <input
- className={'paste-target'}
- onChange={action(e => this.authenticationCode = e.currentTarget.value)}
- placeholder={prompt}
- /> : (null)}
- {this.credentials ?
+ {this.displayLauncher ? (
+ <button
+ className={'dispatch'}
+ onClick={() => {
+ window.open(this.authenticationLink);
+ setTimeout(() => (this.shouldShowPasteTarget = true), 500);
+ }}
+ style={{ marginBottom: this.showPasteTargetState ? 15 : 0 }}>
+ Authorize a Google account...
+ </button>
+ ) : null}
+ {this.showPasteTargetState ? <input className={'paste-target'} onChange={action(e => (this.authenticationCode = e.currentTarget.value))} placeholder={prompt} /> : null}
+ {this.credentials ? (
<>
- <img
- className={'avatar'}
- src={this.credentials.userInfo.picture}
- />
- <span
- className={'welcome'}
- >Welcome to Dash, {this.credentials.userInfo.name}
- </span>
+ <img className={'avatar'} src={this.credentials.userInfo.picture} />
+ <span className={'welcome'}>Welcome to Dash, {this.credentials.userInfo.name}</span>
<div
className={'disconnect'}
onClick={async () => {
- await Networking.FetchFromServer("/revokeGoogleAccessToken");
+ await Networking.FetchFromServer('/revokeGoogleAccessToken');
this.resetState(0, 0);
- }}
- >Disconnect Account</div>
- </> : (null)}
+ }}>
+ Disconnect Account
+ </div>
+ </>
+ ) : null}
</div>
);
}
private get dialogueBoxStyle() {
- const borderColor = this.success === undefined ? "black" : this.success ? "green" : "red";
- return { borderColor, transition: "0.2s borderColor ease", zIndex: 1002 };
+ const borderColor = this.success === undefined ? 'black' : this.success ? 'green' : 'red';
+ return { borderColor, transition: '0.2s borderColor ease', zIndex: 1002 };
}
render() {
- return (
- <MainViewModal
- isDisplayed={this.openState}
- interactive={true}
- contents={this.renderPrompt}
- // overlayDisplayedOpacity={0.9}
- dialogueBoxStyle={this.dialogueBoxStyle}
- overlayStyle={{ zIndex: 1001 }}
- closeOnExternalClick={action(() => this.isOpen = false)}
- />
- );
+ return <MainViewModal isDisplayed={this.openState} interactive={true} contents={this.renderPrompt} dialogueBoxStyle={this.dialogueBoxStyle} overlayStyle={{ zIndex: 1001 }} closeOnExternalClick={action(() => (this.isOpen = false))} />;
}
-
}
-ScriptingGlobals.add("GoogleAuthenticationManager", GoogleAuthenticationManager); \ No newline at end of file
+ScriptingGlobals.add('GoogleAuthenticationManager', GoogleAuthenticationManager);
diff --git a/src/client/apis/google_docs/GoogleApiClientUtils.ts b/src/client/apis/google_docs/GoogleApiClientUtils.ts
index c8f381cc0..0b303eacf 100644
--- a/src/client/apis/google_docs/GoogleApiClientUtils.ts
+++ b/src/client/apis/google_docs/GoogleApiClientUtils.ts
@@ -1,45 +1,46 @@
-import { docs_v1 } from "googleapis";
-import { Opt } from "../../../fields/Doc";
-import { isArray } from "util";
-import { EditorState } from "prosemirror-state";
-import { Networking } from "../../Network";
+/* eslint-disable no-restricted-syntax */
+/* eslint-disable no-use-before-define */
+import { docs_v1 as docsV1 } from 'googleapis';
+// eslint-disable-next-line node/no-deprecated-api
+import { isArray } from 'util';
+import { EditorState } from 'prosemirror-state';
+import { Opt } from '../../../fields/Doc';
+import { Networking } from '../../Network';
-export const Pulls = "googleDocsPullCount";
-export const Pushes = "googleDocsPushCount";
+export const Pulls = 'googleDocsPullCount';
+export const Pushes = 'googleDocsPushCount';
export namespace GoogleApiClientUtils {
-
export enum Actions {
- Create = "create",
- Retrieve = "retrieve",
- Update = "update"
+ Create = 'create',
+ Retrieve = 'retrieve',
+ Update = 'update',
}
export namespace Docs {
-
- export type RetrievalResult = Opt<docs_v1.Schema$Document>;
- export type UpdateResult = Opt<docs_v1.Schema$BatchUpdateDocumentResponse>;
+ export type RetrievalResult = Opt<docsV1.Schema$Document>;
+ export type UpdateResult = Opt<docsV1.Schema$BatchUpdateDocumentResponse>;
export interface UpdateOptions {
documentId: DocumentId;
- requests: docs_v1.Schema$Request[];
+ requests: docsV1.Schema$Request[];
}
export enum WriteMode {
Insert,
- Replace
+ Replace,
}
export type DocumentId = string;
export type Reference = DocumentId | CreateOptions;
export interface Content {
text: string | string[];
- requests: docs_v1.Schema$Request[];
+ requests: docsV1.Schema$Request[];
}
export type IdHandler = (id: DocumentId) => any;
export type CreationResult = Opt<DocumentId>;
- export type ReadLinesResult = Opt<{ title?: string, bodyLines?: string[] }>;
- export type ReadResult = { title: string, body: string };
+ export type ReadLinesResult = Opt<{ title?: string; bodyLines?: string[] }>;
+ export type ReadResult = { title: string; body: string };
export interface ImportResult {
title: string;
text: string;
@@ -67,23 +68,23 @@ export namespace GoogleApiClientUtils {
}
/**
- * After following the authentication routine, which connects this API call to the current signed in account
- * and grants the appropriate permissions, this function programmatically creates an arbitrary Google Doc which
- * should appear in the user's Google Doc library instantaneously.
- *
- * @param options the title to assign to the new document, and the information necessary
- * to store the new documentId returned from the creation process
- * @returns the documentId of the newly generated document, or undefined if the creation process fails.
- */
+ * After following the authentication routine, which connects this API call to the current signed in account
+ * and grants the appropriate permissions, this function programmatically creates an arbitrary Google Doc which
+ * should appear in the user's Google Doc library instantaneously.
+ *
+ * @param options the title to assign to the new document, and the information necessary
+ * to store the new documentId returned from the creation process
+ * @returns the documentId of the newly generated document, or undefined if the creation process fails.
+ */
export const create = async (options: CreateOptions): Promise<CreationResult> => {
const path = `/googleDocs/Documents/${Actions.Create}`;
const parameters = {
requestBody: {
- title: options.title || `Dash Export (${new Date().toDateString()})`
- }
+ title: options.title || `Dash Export (${new Date().toDateString()})`,
+ },
};
try {
- const schema: docs_v1.Schema$Document = await Networking.PostToServer(path, parameters);
+ const schema: docsV1.Schema$Document = await Networking.PostToServer(path, parameters);
return schema.documentId === null ? undefined : schema.documentId;
} catch {
return undefined;
@@ -91,19 +92,25 @@ export namespace GoogleApiClientUtils {
};
export namespace Utils {
-
- export type ExtractResult = { text: string, paragraphs: DeconstructedParagraph[] };
- export const extractText = (document: docs_v1.Schema$Document, removeNewlines = false): ExtractResult => {
+ export type ExtractResult = { text: string; paragraphs: DeconstructedParagraph[] };
+ export const extractText = (document: docsV1.Schema$Document, removeNewlines = false): ExtractResult => {
const paragraphs = extractParagraphs(document);
- let text = paragraphs.map(paragraph => paragraph.contents.filter(content => !("inlineObjectId" in content)).map(run => (run as docs_v1.Schema$TextRun).content).join("")).join("");
+ let text = paragraphs
+ .map(paragraph =>
+ paragraph.contents
+ .filter(content => !('inlineObjectId' in content))
+ .map(run => (run as docsV1.Schema$TextRun).content)
+ .join('')
+ )
+ .join('');
text = text.substring(0, text.length - 1);
- removeNewlines && text.replace(/\n/g, "");
+ removeNewlines && text.replace(/\n/g, '');
return { text, paragraphs };
};
- export type ContentArray = (docs_v1.Schema$TextRun | docs_v1.Schema$InlineObjectElement)[];
- export type DeconstructedParagraph = { contents: ContentArray, bullet: Opt<number> };
- const extractParagraphs = (document: docs_v1.Schema$Document, filterEmpty = true): DeconstructedParagraph[] => {
+ export type ContentArray = (docsV1.Schema$TextRun | docsV1.Schema$InlineObjectElement)[];
+ export type DeconstructedParagraph = { contents: ContentArray; bullet: Opt<number> };
+ const extractParagraphs = (document: docsV1.Schema$Document, filterEmpty = true): DeconstructedParagraph[] => {
const fragments: DeconstructedParagraph[] = [];
if (document.body && document.body.content) {
for (const element of document.body.content) {
@@ -132,7 +139,7 @@ export namespace GoogleApiClientUtils {
return fragments;
};
- export const endOf = (schema: docs_v1.Schema$Document): number | undefined => {
+ export const endOf = (schema: docsV1.Schema$Document): number | undefined => {
if (schema.body && schema.body.content) {
const paragraphs = schema.body.content.filter(el => el.paragraph);
if (paragraphs.length) {
@@ -146,10 +153,10 @@ export namespace GoogleApiClientUtils {
}
}
}
+ return undefined;
};
- export const initialize = async (reference: Reference) => typeof reference === "string" ? reference : create(reference);
-
+ export const initialize = async (reference: Reference) => (typeof reference === 'string' ? reference : create(reference));
}
export const retrieve = async (options: RetrieveOptions): Promise<RetrievalResult> => {
@@ -168,8 +175,8 @@ export namespace GoogleApiClientUtils {
const parameters = {
documentId: options.documentId,
requestBody: {
- requests: options.requests
- }
+ requests: options.requests,
+ },
};
try {
const replies: UpdateResult = await Networking.PostToServer(path, parameters);
@@ -179,83 +186,84 @@ export namespace GoogleApiClientUtils {
}
};
- export const read = async (options: ReadOptions): Promise<Opt<ReadResult>> => {
- return retrieve({ documentId: options.documentId }).then(document => {
+ export const read = async (options: ReadOptions): Promise<Opt<ReadResult>> =>
+ retrieve({ documentId: options.documentId }).then(document => {
if (document) {
const title = document.title!;
const body = Utils.extractText(document, options.removeNewlines).text;
return { title, body };
}
+ return undefined;
});
- };
- export const readLines = async (options: ReadOptions): Promise<Opt<ReadLinesResult>> => {
- return retrieve({ documentId: options.documentId }).then(document => {
+ export const readLines = async (options: ReadOptions): Promise<Opt<ReadLinesResult>> =>
+ retrieve({ documentId: options.documentId }).then(document => {
if (document) {
- const title = document.title;
- let bodyLines = Utils.extractText(document).text.split("\n");
+ const { title } = document;
+ let bodyLines = Utils.extractText(document).text.split('\n');
options.removeNewlines && (bodyLines = bodyLines.filter(line => line.length));
- return { title: title ?? "", bodyLines };
+ return { title: title ?? '', bodyLines };
}
+ return undefined;
});
- };
export const setStyle = async (options: UpdateOptions) => {
const replies: any = await update({
documentId: options.documentId,
- requests: options.requests
+ requests: options.requests,
});
- if ("errors" in replies) {
- console.log("Write operation failed:");
+ if ('errors' in replies) {
+ console.log('Write operation failed:');
console.log(replies.errors.map((error: any) => error.message));
}
return replies;
};
export const write = async (options: WriteOptions): Promise<UpdateResult> => {
- const requests: docs_v1.Schema$Request[] = [];
+ const requests: docsV1.Schema$Request[] = [];
const documentId = await Utils.initialize(options.reference);
if (!documentId) {
return undefined;
}
- let index = options.index;
- const mode = options.mode;
+ let { index } = options;
+ const { mode } = options;
if (!(index && mode === WriteMode.Insert)) {
const schema = await retrieve({ documentId });
+ // eslint-disable-next-line no-cond-assign
if (!schema || !(index = Utils.endOf(schema))) {
return undefined;
}
}
if (mode === WriteMode.Replace) {
- index > 1 && requests.push({
- deleteContentRange: {
- range: {
- startIndex: 1,
- endIndex: index
- }
- }
- });
+ index > 1 &&
+ requests.push({
+ deleteContentRange: {
+ range: {
+ startIndex: 1,
+ endIndex: index,
+ },
+ },
+ });
index = 1;
}
- const text = options.content.text;
- text.length && requests.push({
- insertText: {
- text: isArray(text) ? text.join("\n") : text,
- location: { index }
- }
- });
+ const { text } = options.content;
+ text.length &&
+ requests.push({
+ insertText: {
+ text: isArray(text) ? text.join('\n') : text,
+ location: { index },
+ },
+ });
if (!requests.length) {
return undefined;
}
requests.push(...options.content.requests);
const replies: any = await update({ documentId, requests });
- if ("errors" in replies) {
- console.log("Write operation failed:");
+ if ('errors' in replies) {
+ console.log('Write operation failed:');
console.log(replies.errors.map((error: any) => error.message));
}
return replies;
};
-
}
-
-} \ No newline at end of file
+}
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index e8fd8fb8a..b238f07e9 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -1,18 +1,19 @@
+/* eslint-disable no-use-before-define */
+import Photos = require('googlephotos');
import { AssertionError } from 'assert';
import { EditorState } from 'prosemirror-state';
+import { ClientUtils } from '../../../ClientUtils';
import { Doc, DocListCastAsync, Opt } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { RichTextField } from '../../../fields/RichTextField';
import { RichTextUtils } from '../../../fields/RichTextUtils';
-import { Cast, StrCast } from '../../../fields/Types';
-import { ImageField } from '../../../fields/URLField';
+import { Cast, ImageCast, StrCast } from '../../../fields/Types';
import { MediaItem, NewMediaItemResult } from '../../../server/apis/google/SharedTypes';
-import { Utils } from '../../../Utils';
-import { Docs, DocumentOptions, DocUtils } from '../../documents/Documents';
import { Networking } from '../../Network';
+import { Docs, DocumentOptions } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
import { FormattedTextBox } from '../../views/nodes/formattedText/FormattedTextBox';
import { GoogleAuthenticationManager } from '../GoogleAuthenticationManager';
-import Photos = require('googlephotos');
export namespace GooglePhotos {
const endpoint = async () => new Photos(await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken());
@@ -76,17 +77,16 @@ export namespace GooglePhotos {
export const CollectionToAlbum = async (options: AlbumCreationOptions): Promise<Opt<AlbumCreationResult>> => {
const { collection, title, descriptionKey, tag } = options;
const dataDocument = Doc.GetProto(collection);
- const images = ((await DocListCastAsync(dataDocument.data)) || []).filter(doc => Cast(doc.data, ImageField));
+ const images = ((await DocListCastAsync(dataDocument.data)) || []).filter(doc => ImageCast(doc.data));
if (!images || !images.length) {
return undefined;
}
- const resolved = title ? title : StrCast(collection.title) || `Dash Collection (${collection[Id]}`;
+ const resolved = title || StrCast(collection.title) || `Dash Collection (${collection[Id]}`;
const { id, productUrl } = await Create.Album(resolved);
const response = await Transactions.UploadImages(images, { id }, descriptionKey);
if (response) {
const { results, failed } = response;
- let index: Opt<number>;
- while ((index = failed.pop()) !== undefined) {
+ for (let index = failed.pop(); index !== undefined; index = failed.pop()) {
Doc.RemoveDocFromList(dataDocument, 'data', images.splice(index, 1)[0]);
}
const mediaItems: MediaItem[] = results.map(item => item.mediaItem);
@@ -97,13 +97,12 @@ export namespace GooglePhotos {
for (let i = 0; i < images.length; i++) {
const image = Doc.GetProto(images[i]);
const mediaItem = mediaItems[i];
- if (!mediaItem) {
- continue;
+ if (mediaItem) {
+ image.googlePhotosId = mediaItem.id;
+ image.googlePhotosAlbumUrl = productUrl;
+ image.googlePhotosUrl = mediaItem.productUrl || mediaItem.baseUrl;
+ idMapping[mediaItem.id] = image;
}
- image.googlePhotosId = mediaItem.id;
- image.googlePhotosAlbumUrl = productUrl;
- image.googlePhotosUrl = mediaItem.productUrl || mediaItem.baseUrl;
- idMapping[mediaItem.id] = image;
}
collection.googlePhotosAlbumUrl = productUrl;
collection.googlePhotosIdMapping = idMapping;
@@ -111,9 +110,10 @@ export namespace GooglePhotos {
await Query.TagChildImages(collection);
}
collection.albumId = id;
- Transactions.AddTextEnrichment(collection, `Find me at ${Utils.prepend(`/doc/${collection[Id]}?sharing=true`)}`);
+ Transactions.AddTextEnrichment(collection, `Find me at ${ClientUtils.prepend(`/doc/${collection[Id]}?sharing=true`)}`);
return { albumId: id, mediaItems };
}
+ return undefined;
};
}
@@ -124,7 +124,7 @@ export namespace GooglePhotos {
await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
const response = await Query.ContentSearch(requested);
const uploads = await Transactions.WriteMediaItemsToServer(response);
- const children = uploads.map((upload: Transactions.UploadInformation) => Docs.Create.ImageDocument(Utils.fileUrl(upload.fileNames.clean) /*, {"data_contentSize":upload.contentSize}*/));
+ const children = uploads.map((upload: Transactions.UploadInformation) => Docs.Create.ImageDocument(ClientUtils.fileUrl(upload.fileNames.clean) /* , {"data_contentSize":upload.contentSize} */));
const options = { _width: 500, _height: 500 };
return constructor(children, options);
};
@@ -144,7 +144,7 @@ export namespace GooglePhotos {
const images = (await DocListCastAsync(collection.data))!.map(Doc.GetProto);
images?.forEach(image => tagMapping.set(image[Id], ContentCategories.NONE));
const values = Object.values(ContentCategories).filter(value => value !== ContentCategories.NONE);
- for (const value of values) {
+ values.forEach(async value => {
const searched = (await ContentSearch({ included: [value] }))?.mediaItems?.map(({ id }) => id);
searched?.forEach(async id => {
const image = await Cast(idMapping[id], Doc);
@@ -154,7 +154,7 @@ export namespace GooglePhotos {
!tags?.includes(value) && tagMapping.set(key, tags + delimiter + value);
}
});
- }
+ });
images?.forEach(image => {
const concatenated = tagMapping.get(image[Id])!;
const tags = concatenated.split(delimiter);
@@ -200,9 +200,10 @@ export namespace GooglePhotos {
export const AlbumSearch = async (albumId: string, pageSize = 100): Promise<MediaItem[]> => {
const photos = await endpoint();
const mediaItems: MediaItem[] = [];
- let nextPageTokenStored: Opt<string> = undefined;
+ let nextPageTokenStored: Opt<string>;
const found = 0;
do {
+ // eslint-disable-next-line no-await-in-loop
const response: any = await photos.mediaItems.search(albumId, pageSize, nextPageTokenStored);
mediaItems.push(...response.mediaItems);
nextPageTokenStored = response.nextPageToken;
@@ -222,7 +223,7 @@ export namespace GooglePhotos {
excluded.length && excluded.forEach(category => contentFilter.addExcludedContentCategories(category));
filters.setContentFilter(contentFilter);
- const date = options.date;
+ const { date } = options;
if (date) {
const dateFilter = new photos.DateFilter();
if (date instanceof Date) {
@@ -240,15 +241,11 @@ export namespace GooglePhotos {
});
};
- export const GetImage = async (mediaItemId: string): Promise<Transactions.MediaItem> => {
- return (await endpoint()).mediaItems.get(mediaItemId);
- };
+ export const GetImage = async (mediaItemId: string): Promise<Transactions.MediaItem> => (await endpoint()).mediaItems.get(mediaItemId);
}
namespace Create {
- export const Album = async (title: string) => {
- return (await endpoint()).albums.create(title);
- };
+ export const Album = async (title: string) => (await endpoint()).albums.create(title);
}
export namespace Transactions {
@@ -278,6 +275,7 @@ export namespace GooglePhotos {
return enrichmentItem.id;
}
}
+ return undefined;
};
export const WriteMediaItemsToServer = async (body: { mediaItems: any[] }): Promise<UploadInformation[]> => {
@@ -291,9 +289,12 @@ export namespace GooglePhotos {
return undefined;
}
const baseUrls: string[] = await Promise.all(
- response.results.map(item => {
- return new Promise<string>(resolve => Query.GetImage(item.mediaItem.id).then(item => resolve(item.baseUrl)));
- })
+ response.results.map(
+ item =>
+ new Promise<string>(resolve => {
+ Query.GetImage(item.mediaItem.id).then(itm => resolve(itm.baseUrl));
+ })
+ )
);
return baseUrls;
};
@@ -303,36 +304,34 @@ export namespace GooglePhotos {
failed: number[];
}
- export const UploadImages = async (sources: Doc[], album?: AlbumReference, descriptionKey = 'caption'): Promise<Opt<ImageUploadResults>> => {
+ export const UploadImages = async (sources: Doc[], albumIn?: AlbumReference, descriptionKey = 'caption'): Promise<Opt<ImageUploadResults>> => {
await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
- if (album && 'title' in album) {
- album = await Create.Album(album.title);
- }
+ const album = albumIn && 'title' in albumIn ? await Create.Album(albumIn.title) : albumIn;
const media: MediaInput[] = [];
- for (const source of sources) {
- const data = Cast(Doc.GetProto(source).data, ImageField);
- if (!data) {
- return;
- }
- const url = data.url.href;
- const target = Doc.MakeEmbedding(source);
- const description = parseDescription(target, descriptionKey);
- await DocUtils.makeCustomViewClicked(target, Docs.Create.FreeformDocument);
- media.push({ url, description });
- }
+ sources
+ .filter(source => ImageCast(Doc.GetProto(source).data))
+ .forEach(async source => {
+ const data = ImageCast(Doc.GetProto(source).data);
+ const url = data.url.href;
+ const target = Doc.MakeEmbedding(source);
+ const description = parseDescription(target, descriptionKey);
+ await DocUtils.makeCustomViewClicked(target, Docs.Create.FreeformDocument);
+ media.push({ url, description });
+ });
if (media.length) {
const results = await Networking.PostToServer('/googlePhotosMediaPost', { media, album });
return results;
}
+ return undefined;
};
const parseDescription = (document: Doc, descriptionKey: string) => {
- let description: string = Utils.prepend(`/doc/${document[Id]}?sharing=true`);
+ let description: string = ClientUtils.prepend(`/doc/${document[Id]}?sharing=true`);
const target = document[descriptionKey];
if (typeof target === 'string') {
description = target;
} else if (target instanceof RichTextField) {
- description = RichTextUtils.ToPlainText(EditorState.fromJSON(FormattedTextBox.Instance.config, JSON.parse(target.Data)));
+ description = RichTextUtils.ToPlainText(EditorState.fromJSON(new FormattedTextBox({} as any).config, JSON.parse(target.Data)));
}
return description;
};
diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts
index 6600ddab2..2fa92373f 100644
--- a/src/client/apis/gpt/GPT.ts
+++ b/src/client/apis/gpt/GPT.ts
@@ -8,6 +8,10 @@ enum GPTCallType {
CHATCARD = 'chatcard',
FLASHCARD = 'flashcard',
QUIZ = 'quiz',
+ SORT = 'sort',
+ DESCRIBE = 'describe',
+ MERMAID = 'mermaid',
+ DATA = 'data',
}
type GPTCallOpts = {
@@ -18,10 +22,30 @@ type GPTCallOpts = {
};
const callTypeMap: { [type: string]: GPTCallOpts } = {
- summary: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: 'Summarize this text in simpler terms: ' },
- edit: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: 'Reword this: ' },
+ // newest model: gpt-4
+ summary: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: 'Summarize the text given in simpler terms.' },
+ edit: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: 'Reword the text.' },
flashcard: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'Make flashcards out of this text with each question and answer labeled. Do not label each flashcard and do not include asterisks: ' },
- completion: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: '' },
+ completion: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: "You are a helpful assistant. Answer the user's prompt." },
+ mermaid: {
+ model: 'gpt-4-turbo',
+ maxTokens: 2048,
+ temp: 0,
+ prompt: "(Heres an example of changing color of a pie chart to help you pie title Example \"Red\": 20 \"Blue\": 50 \"Green\": 30 %%{init: {'theme': 'base', 'themeVariables': {'pie1': '#0000FF', 'pie2': '#00FF00', 'pie3': '#FF0000'}}}%% keep in mind that pie1 is the highest since its sorted in descending order. Heres an example of a mindmap: mindmap root((mindmap)) Origins Long history ::icon(fa fa-book) Popularisation British popular psychology author Tony Buzan Research On effectivness<br/>and features On Automatic creation Uses Creative techniques Strategic planning Argument mapping Tools Pen and paper Mermaid. ",
+ },
+ data: {
+ model: 'gpt-3.5-turbo',
+ maxTokens: 256,
+ temp: 0.5,
+ prompt: "You are a helpful resarch assistant. Analyze the user's data to find meaningful patterns and/or correlation. Please only return a JSON with a correlation column 1 propert, a correlation column 2 property, and an analysis property. ",
+ },
+ sort: {
+ model: 'gpt-4o',
+ maxTokens: 2048,
+ temp: 0.5,
+ prompt: "I'm going to give you a list of descriptions. Each one is seperated by ====== on either side. They will vary in length, so make sure to only seperate when you see ======. Sort them into lists by shared content. MAKE SURE EACH DESCRIPTOR IS IN ONLY ONE LIST. Generate only the list with each list seperated by ====== with the elements seperated by ~~~~~~. Try to do around 4 groups, but a little more or less is ok.",
+ },
+ describe: { model: 'gpt-4-vision-preview', maxTokens: 2048, temp: 0, prompt: 'Describe these images in 3-5 words' },
chatcard: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'Answer the following question as a short flashcard response. Do not include a label.' },
quiz: {
model: 'gpt-4-turbo',
@@ -31,25 +55,29 @@ const callTypeMap: { [type: string]: GPTCallOpts } = {
},
};
+let lastCall = '';
+let lastResp = '';
/**
* Calls the OpenAI API.
*
* @param inputText Text to process
* @returns AI Output
*/
-const gptAPICall = async (inputText: string, callType: GPTCallType) => {
- if (!inputText) return 'Please provide a response.';
- if (callType === GPTCallType.SUMMARY || callType == GPTCallType.FLASHCARD || GPTCallType.QUIZ) inputText += '.';
+const gptAPICall = async (inputTextIn: string, callType: GPTCallType, prompt?: any) => {
+ const inputText = callType === GPTCallType.SUMMARY || callType == GPTCallType.FLASHCARD || GPTCallType.QUIZ ? inputTextIn + '.' : inputTextIn;
const opts: GPTCallOpts = callTypeMap[callType];
+ if (lastCall === inputText) return lastResp;
try {
const configuration: ClientOptions = {
apiKey: process.env.OPENAI_KEY,
dangerouslyAllowBrowser: true,
};
+ lastCall = inputText;
const openai = new OpenAI(configuration);
- let messages: ChatCompletionMessageParam[] = [
- { role: 'system', content: opts.prompt },
+ const usePrompt = prompt ? opts.prompt + prompt : opts.prompt;
+ const messages: ChatCompletionMessageParam[] = [
+ { role: 'system', content: usePrompt },
{ role: 'user', content: inputText },
];
@@ -59,14 +87,50 @@ const gptAPICall = async (inputText: string, callType: GPTCallType) => {
temperature: opts.temp,
max_tokens: opts.maxTokens,
});
-
- return response.choices[0].message.content;
+ lastResp = response.choices[0].message.content ?? '';
+ return lastResp;
} catch (err) {
console.log(err);
return 'Error connecting with API.';
}
};
+const gptImageLabel = async (imgUrl: string): Promise<string> => {
+ try {
+ const configuration: ClientOptions = {
+ apiKey: process.env.OPENAI_KEY,
+ dangerouslyAllowBrowser: true,
+ };
+
+ const openai = new OpenAI(configuration);
+ const response = await openai.chat.completions.create({
+ model: 'gpt-4o',
+ messages: [
+ {
+ role: 'user',
+ content: [
+ { type: 'text', text: 'Describe this image in 3-5 words' },
+ {
+ type: 'image_url',
+ image_url: {
+ url: `${imgUrl}`,
+ },
+ },
+ ],
+ },
+ ],
+ });
+ if (response.choices[0].message.content) {
+ return response.choices[0].message.content;
+ } else {
+ return ':(';
+ }
+ } catch (err) {
+ console.log(err);
+ return 'Error connecting with API';
+ }
+};
+
const gptImageCall = async (prompt: string, n?: number) => {
try {
const configuration: ClientOptions = {
@@ -84,8 +148,8 @@ const gptImageCall = async (prompt: string, n?: number) => {
// return response.data.data[0].url;
} catch (err) {
console.error(err);
- return;
}
+ return undefined;
};
-export { gptAPICall, gptImageCall, GPTCallType };
+export { gptAPICall, gptImageCall, gptImageLabel, GPTCallType };
diff --git a/src/client/apis/gpt/customization.ts b/src/client/apis/gpt/customization.ts
new file mode 100644
index 000000000..2262886a2
--- /dev/null
+++ b/src/client/apis/gpt/customization.ts
@@ -0,0 +1,133 @@
+import { openai } from './setup';
+
+export enum CustomizationType {
+ PRES_TRAIL_SLIDE = 'trails',
+}
+
+interface PromptInfo {
+ description: string;
+ features: { name: string; description: string; values?: string[] }[];
+}
+const prompts: { [key: string]: PromptInfo } = {
+ trails: {
+ description:
+ 'We are customizing the properties and transition of a slide in a presentation. You are given the current properties of the slide in a json with the fields [title, presentation_transition, presentation_effect, config_zoom, presentation_effectDirection], as well as the prompt for how the user wants to change it. Return a json with the required fields: [title, presentation_transition, presentation_effect, config_zoom, presentation_effectDirection] by applying the changes in the prompt to the current state of the slide.',
+ features: [],
+ },
+};
+
+// Allows you to register properties that are customizable
+export const addCustomizationProperty = (type: CustomizationType, name: string, description: string, values?: string[]) => {
+ values ? prompts[type].features.push({ name, description, values }) : prompts[type].features.push({ name, description });
+};
+
+// All the registered fields, make sure to update during registration, this
+// includes most fields but is not yet fully comprehensive
+export const gptSlideProperties = [
+ 'title',
+ 'config_zoom',
+ 'presentation_transition',
+ 'presentation_easeFunc',
+ 'presentation_effect',
+ 'presentation_effectDirection',
+ 'presentation_effectTiming',
+ 'presentation_playAudio',
+ 'presentation_zoomText',
+ 'presentation_hideBefore',
+ 'presentation_hide',
+ 'presentation_hideAfter',
+ 'presentation_openInLightbox',
+];
+
+// Registers slide properties
+const setupPresSlideCustomization = () => {
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'title', 'is the title/name of the slide.');
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_transition', 'is a number in milliseconds for how long it should take to transition/move to a slide.');
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_easeFunc', 'is the easing function for the movement to the slide.', ['Ease', 'Ease In', 'Ease Out', 'Ease Out', 'Ease In Out', 'Linear']);
+
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_effect', 'is an effect applied to the slide when we transition to it.', ['None', 'Expand', 'Fade in', 'Bounce', 'Flip', 'Rotate', 'Roll']);
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_effectDirection', 'is what direction the effect is applied.', ['Enter from left', 'Enter from right', 'Enter from bottom', 'Enter from Top', 'Enter from center']);
+ addCustomizationProperty(
+ CustomizationType.PRES_TRAIL_SLIDE,
+ 'presentation_effectTiming',
+ "is a json object of the format: {type: string, stiffness: number, damping: number, mass: number}. Type is always “custom”. Controls the spring-based timing of the presentation effect animation. Stiffness, damping, and mass control the physics-based properties of spring animations. This is used to create a more natural looking timing, bouncy effects, etc. Use spring physics to adjust these parameters to match the user's description of how they want to animate the effect."
+ );
+
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'config_zoom', 'is a number from 0 to 1.0 indicating the percentage we should zoom into the slide.');
+
+ // boolean values
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_playAudio', 'is a boolean value indicating if we should play audio when we go to the slide.');
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_zoomText', 'is a boolean value indicating if we should zoom into text selections when we go to the slide.');
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hideBefore', 'is a boolean value indicating if we should hide the slide before going to it.');
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hide', 'is a boolean value indicating if we should hide the slide during the presentation.');
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hideAfter', 'is a boolean value indicating if we should hide the slide after going to it.');
+ addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_openInLightbox', 'is a boolean value indicating if we should open the slide in an overlay or lightbox view during the presentation.');
+};
+
+setupPresSlideCustomization();
+
+export const getSlideTransitionSuggestions = async (inputText: string) => {
+ /**
+ * Prompt: Generate an entrance animations from slower and gentler
+ * to bouncier and more high energy
+ *
+ * Format:
+ * {
+ * name: Slow Fade, Quick Flip, Springy
+ * effect: BOUNCE
+ * effectDirection: LEFT
+ * timingConfig: {
+ * }
+ * }
+ */
+
+ const prompt =
+ "I want to generate four distinct types of slide effect animations. Return a json of the form {effect: string, direction: string, stiffness: number, damping: number, mass: number}[] with four elements. Effect is the type of animation; its only possible values are ['Expand', 'Fade in', 'Bounce', 'Flip', 'Rotate', 'Roll']. Direction is the direction that the animation starts from; its only possible values are ['Enter from left', 'Enter from right', 'Enter from bottom', 'Enter from Top', 'Enter from center']. Stiffness, damping, and mass control the physics-based properties of spring animations. This is used to create a more natural-looking timing, bouncy effects, etc. Use spring physics to adjust these parameters to animate the effect.";
+
+ const customInput = inputText ?? 'Make them as contrasting as possible with different effects and timings ranging from gentle to energetic.';
+
+ try {
+ const response = await openai.chat.completions.create({
+ model: 'gpt-4',
+ messages: [
+ { role: 'system', content: prompt },
+ { role: 'user', content: `${customInput}` },
+ ],
+ temperature: 0,
+ max_tokens: 1000,
+ });
+ return response.choices[0].message?.content;
+ } catch (err) {
+ console.log(err);
+ return 'Error connecting with API.';
+ }
+};
+
+export const gptTrailSlideCustomization = async (inputText: string, properties: any | any[]) => {
+ let prompt = prompts.trails.description;
+
+ prompts.trails.features.forEach(feature => {
+ prompt += feature.name + ' ' + feature.description;
+ if (feature.values) {
+ prompt += `Its only possible values are [${feature.values.join(', ')}].`;
+ }
+ });
+
+ prompt += 'Set unchanged values to null and make sure you include new properties if they are specified in the prompt even if they do not exist in current properties. Please only return the json with the keys described and their values.';
+
+ try {
+ const response = await openai.chat.completions.create({
+ model: 'gpt-4',
+ messages: [
+ { role: 'system', content: prompt },
+ { role: 'user', content: `Prompt: ${inputText}, Current properties: ${JSON.stringify(properties)}` },
+ ],
+ temperature: 0,
+ max_tokens: 1000,
+ });
+ return response.choices[0].message?.content;
+ } catch (err) {
+ console.log(err);
+ return 'Error connecting with API.';
+ }
+};
diff --git a/src/client/apis/gpt/setup.ts b/src/client/apis/gpt/setup.ts
new file mode 100644
index 000000000..831c97eaa
--- /dev/null
+++ b/src/client/apis/gpt/setup.ts
@@ -0,0 +1,30 @@
+// import { Configuration, OpenAIApi } from 'openai';
+import { ClientOptions, OpenAI } from 'openai';
+
+export enum GPTCallType {
+ SUMMARY = 'summary',
+ COMPLETION = 'completion',
+ EDIT = 'edit',
+}
+
+export type GPTCallOpts = {
+ model: string;
+ maxTokens: number;
+ temp: number;
+ prompt: string;
+};
+
+export const callTypeMap: { [type: string]: GPTCallOpts } = {
+ summary: { model: 'text-davinci-003', maxTokens: 256, temp: 0.5, prompt: 'Summarize this text in simpler terms: ' },
+ edit: { model: 'text-davinci-003', maxTokens: 256, temp: 0.5, prompt: 'Reword this: ' },
+ completion: { model: 'text-davinci-003', maxTokens: 256, temp: 0.5, prompt: '' },
+};
+
+const configuration: ClientOptions = {
+ apiKey: process.env.OPENAI_KEY,
+ dangerouslyAllowBrowser: true,
+};
+
+export const openai = new OpenAI(configuration);
+
+// export const openai = new OpenAIApi(configuration);
diff --git a/src/client/apis/youtube/YoutubeBox.scss b/src/client/apis/youtube/YoutubeBox.scss
deleted file mode 100644
index eabdbb1ac..000000000
--- a/src/client/apis/youtube/YoutubeBox.scss
+++ /dev/null
@@ -1,126 +0,0 @@
-.youtubeBox-cont {
- ul {
- list-style-type: none;
- padding-inline-start: 10px;
- }
-
-
- li {
- margin: 4px;
- display: inline-flex;
- }
-
- li:hover {
- cursor: pointer;
- opacity: 0.8;
- }
-
- .search_wrapper {
- width: 100%;
- display: inline-flex;
- height: 175px;
-
- .video_duration {
- // margin: 0;
- // padding: 0;
- border: 0;
- background: transparent;
- display: inline-block;
- position: relative;
- bottom: 25px;
- left: 85%;
- margin: 4px;
- color: #FFFFFF;
- background-color: rgba(0, 0, 0, 0.80);
- padding: 2px 4px;
- border-radius: 2px;
- letter-spacing: .5px;
- font-size: 1.2rem;
- font-weight: 500;
- line-height: 1.2rem;
-
- }
-
- .textual_info {
- font-family: Arial, Helvetica, sans-serif;
-
- .videoTitle {
- margin-left: 4px;
- // display: inline-block;
- color: #0D0D0D;
- -webkit-line-clamp: 2;
- display: block;
- max-height: 4.8rem;
- overflow: hidden;
- font-size: 1.8rem;
- font-weight: 400;
- line-height: 2.4rem;
- -webkit-box-orient: vertical;
- text-overflow: ellipsis;
- white-space: normal;
- display: -webkit-box;
- }
-
- .channelName {
- color: #606060;
- margin-left: 4px;
- font-size: 1.3rem;
- font-weight: 400;
- line-height: 1.8rem;
- text-transform: none;
- margin-top: 0px;
- display: inline-block;
- }
-
- .video_description {
- margin-left: 4px;
- // font-size: 12px;
- color: #606060;
- padding-top: 8px;
- margin-bottom: 8px;
- display: block;
- line-height: 1.8rem;
- max-height: 4.2rem;
- overflow: hidden;
- font-size: 1.3rem;
- font-weight: 400;
- text-transform: none;
- }
-
- .publish_time {
- //display: inline-block;
- margin-left: 8px;
- padding: 0;
- border: 0;
- background: transparent;
- color: #606060;
- max-width: 100%;
- line-height: 1.8rem;
- max-height: 3.6rem;
- overflow: hidden;
- font-size: 1.3rem;
- font-weight: 400;
- text-transform: none;
- }
-
- .viewCount {
-
- margin-left: 8px;
- padding: 0;
- border: 0;
- background: transparent;
- color: #606060;
- max-width: 100%;
- line-height: 1.8rem;
- max-height: 3.6rem;
- overflow: hidden;
- font-size: 1.3rem;
- font-weight: 400;
- text-transform: none;
- }
-
-
-
- }
- }
-} \ No newline at end of file
diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx
deleted file mode 100644
index d3a15cd84..000000000
--- a/src/client/apis/youtube/YoutubeBox.tsx
+++ /dev/null
@@ -1,369 +0,0 @@
-import { action, observable, runInAction } from 'mobx';
-import { observer } from 'mobx-react';
-import { Doc, DocListCastAsync } from '../../../fields/Doc';
-import { InkTool } from '../../../fields/InkField';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { Utils } from '../../../Utils';
-import { DocServer } from '../../DocServer';
-import { Docs } from '../../documents/Documents';
-import { DocumentView } from '../../views/nodes/DocumentView';
-import { FieldView, FieldViewProps } from '../../views/nodes/FieldView';
-import '../../views/nodes/WebBox.scss';
-import './YoutubeBox.scss';
-import * as React from 'react';
-import { SnappingManager } from '../../util/SnappingManager';
-
-interface VideoTemplate {
- thumbnailUrl: string;
- videoTitle: string;
- videoId: string;
- duration: string;
- channelTitle: string;
- viewCount: string;
- publishDate: string;
- videoDescription: string;
-}
-
-/**
- * This class models the youtube search document that can be dropped on to canvas.
- */
-@observer
-export class YoutubeBox extends React.Component<FieldViewProps> {
- @observable YoutubeSearchElement: HTMLInputElement | undefined;
- @observable searchResultsFound: boolean = false;
- @observable searchResults: any[] = [];
- @observable videoClicked: boolean = false;
- @observable selectedVideoUrl: string = '';
- @observable lisOfBackUp: JSX.Element[] = [];
- @observable videoIds: string | undefined;
- @observable videoDetails: any[] = [];
- @observable curVideoTemplates: VideoTemplate[] = [];
-
- public static LayoutString(fieldKey: string) {
- return FieldView.LayoutString(YoutubeBox, fieldKey);
- }
-
- /**
- * When component mounts, last search's results are laoded in based on the back up stored
- * in the document of the props.
- */
- async componentDidMount() {
- //DocServer.getYoutubeChannels();
- const castedSearchBackUp = Cast(this.props.Document.cachedSearchResults, Doc);
- const awaitedBackUp = await castedSearchBackUp;
- const castedDetailBackUp = Cast(this.props.Document.cachedDetails, Doc);
- const awaitedDetails = await castedDetailBackUp;
-
- if (awaitedBackUp) {
- const jsonList = await DocListCastAsync(awaitedBackUp.json);
- const jsonDetailList = await DocListCastAsync(awaitedDetails!.json);
-
- if (jsonList!.length !== 0) {
- runInAction(() => (this.searchResultsFound = true));
- let index = 0;
- //getting the necessary information from backUps and building templates that will be used to map in render
- for (const video of jsonList!) {
- const videoId = await Cast(video.id, Doc);
- const id = StrCast(videoId!.videoId);
- const snippet = await Cast(video.snippet, Doc);
- const videoTitle = this.filterYoutubeTitleResult(StrCast(snippet!.title));
- const thumbnail = await Cast(snippet!.thumbnails, Doc);
- const thumbnailMedium = await Cast(thumbnail!.medium, Doc);
- const thumbnailUrl = StrCast(thumbnailMedium!.url);
- const videoDescription = StrCast(snippet!.description);
- const pusblishDate = this.roundPublishTime(StrCast(snippet!.publishedAt))!;
- const channelTitle = StrCast(snippet!.channelTitle);
- let duration: string = '';
- let viewCount: string = '';
- if (jsonDetailList!.length !== 0) {
- const contentDetails = await Cast(jsonDetailList![index].contentDetails, Doc);
- const statistics = await Cast(jsonDetailList![index].statistics, Doc);
- duration = this.convertIsoTimeToDuration(StrCast(contentDetails!.duration));
- viewCount = this.abbreviateViewCount(parseInt(StrCast(statistics!.viewCount)))!;
- }
- index = index + 1;
- const newTemplate: VideoTemplate = {
- videoId: id,
- videoTitle: videoTitle,
- thumbnailUrl: thumbnailUrl,
- publishDate: pusblishDate,
- channelTitle: channelTitle,
- videoDescription: videoDescription,
- duration: duration,
- viewCount: viewCount,
- };
- runInAction(() => this.curVideoTemplates.push(newTemplate));
- }
- }
- }
- }
-
- _ignore = 0;
- onPreWheel = (e: React.WheelEvent) => {
- this._ignore = e.timeStamp;
- };
- onPrePointer = (e: React.PointerEvent) => {
- this._ignore = e.timeStamp;
- };
- onPostPointer = (e: React.PointerEvent) => {
- if (this._ignore !== e.timeStamp) {
- e.stopPropagation();
- }
- };
- onPostWheel = (e: React.WheelEvent) => {
- if (this._ignore !== e.timeStamp) {
- e.stopPropagation();
- }
- };
-
- /**
- * Function that submits the title entered by user on enter press.
- */
- onEnterKeyDown = (e: React.KeyboardEvent) => {
- if (e.keyCode === 13) {
- const submittedTitle = this.YoutubeSearchElement!.value;
- this.YoutubeSearchElement!.value = '';
- this.YoutubeSearchElement!.blur();
- DocServer.getYoutubeVideos(submittedTitle, this.processesVideoResults);
- }
- };
-
- /**
- * The callback that is passed in to server, which functions as a way to
- * get videos that is returned by search. It also makes a call to server
- * to get details for the videos found.
- */
- @action
- processesVideoResults = (videos: any[]) => {
- this.searchResults = videos;
- if (this.searchResults.length > 0) {
- this.searchResultsFound = true;
- this.videoIds = '';
- videos.forEach(video => {
- if (this.videoIds === '') {
- this.videoIds = video.id.videoId;
- } else {
- this.videoIds = this.videoIds! + ', ' + video.id.videoId;
- }
- });
- //Asking for details that include duration and viewCount from server for videoIds
- DocServer.getYoutubeVideoDetails(this.videoIds, this.processVideoDetails);
- this.backUpSearchResults(videos);
- if (this.videoClicked) {
- this.videoClicked = false;
- }
- }
- };
-
- /**
- * The callback that is given to server to process and receive returned details about the videos.
- */
- @action
- processVideoDetails = (videoDetails: any[]) => {
- this.videoDetails = videoDetails;
- this.props.Document.cachedDetails = Doc.Get.FromJson({ data: videoDetails, title: 'detailBackUp' });
- };
-
- /**
- * The function that stores the search results in the props document.
- */
- backUpSearchResults = (videos: any[]) => {
- this.props.Document.cachedSearchResults = Doc.Get.FromJson({ data: videos, title: 'videosBackUp' });
- };
-
- /**
- * The function that filters out escaped characters returned by the api
- * in the title of the videos.
- */
- filterYoutubeTitleResult = (resultTitle: string) => {
- let processedTitle: string = resultTitle.replace(/&amp;/g, '&'); //.ReplaceAll("&amp;", "&");
- processedTitle = processedTitle.replace(/"&#39;/g, "'");
- processedTitle = processedTitle.replace(/&quot;/g, '"');
- return processedTitle;
- };
-
- /**
- * The function that converts ISO date, which is passed in, to normal date and finds the
- * difference between today's date and that date, in terms of "ago" to imitate youtube.
- */
- roundPublishTime = (publishTime: string) => {
- const date = new Date(publishTime).getTime();
- const curDate = new Date().getTime();
- const timeDif = curDate - date;
- const totalSeconds = timeDif / 1000;
- const totalMin = totalSeconds / 60;
- const totalHours = totalMin / 60;
- const totalDays = totalHours / 24;
- const totalMonths = totalDays / 30.417;
- const totalYears = totalMonths / 12;
-
- const truncYears = Math.trunc(totalYears);
- const truncMonths = Math.trunc(totalMonths);
- const truncDays = Math.trunc(totalDays);
- const truncHours = Math.trunc(totalHours);
- const truncMin = Math.trunc(totalMin);
- const truncSec = Math.trunc(totalSeconds);
-
- let pluralCase = '';
-
- if (truncYears !== 0) {
- truncYears > 1 ? (pluralCase = 's') : (pluralCase = '');
- return truncYears + ' year' + pluralCase + ' ago';
- } else if (truncMonths !== 0) {
- truncMonths > 1 ? (pluralCase = 's') : (pluralCase = '');
- return truncMonths + ' month' + pluralCase + ' ago';
- } else if (truncDays !== 0) {
- truncDays > 1 ? (pluralCase = 's') : (pluralCase = '');
- return truncDays + ' day' + pluralCase + ' ago';
- } else if (truncHours !== 0) {
- truncHours > 1 ? (pluralCase = 's') : (pluralCase = '');
- return truncHours + ' hour' + pluralCase + ' ago';
- } else if (truncMin !== 0) {
- truncMin > 1 ? (pluralCase = 's') : (pluralCase = '');
- return truncMin + ' minute' + pluralCase + ' ago';
- } else if (truncSec !== 0) {
- truncSec > 1 ? (pluralCase = 's') : (pluralCase = '');
- return truncSec + ' second' + pluralCase + ' ago';
- }
- };
-
- /**
- * The function that converts the passed in ISO time to normal duration time.
- */
- convertIsoTimeToDuration = (isoDur: string) => {
- const convertedTime = isoDur.replace(/D|H|M/g, ':').replace(/P|T|S/g, '').split(':');
-
- if (1 === convertedTime.length) {
- 2 !== convertedTime[0].length && (convertedTime[0] = '0' + convertedTime[0]), (convertedTime[0] = '0:' + convertedTime[0]);
- } else {
- for (var r = 1, l = convertedTime.length - 1; l >= r; r++) {
- 2 !== convertedTime[r].length && (convertedTime[r] = '0' + convertedTime[r]);
- }
- }
-
- return convertedTime.join(':');
- };
-
- /**
- * The function that rounds the viewCount to the nearest
- * thousand, million or billion, given a viewCount number.
- */
- abbreviateViewCount = (viewCount: number) => {
- if (viewCount < 1000) {
- return viewCount.toString();
- } else if (viewCount >= 1000 && viewCount < 1000000) {
- return Math.trunc(viewCount / 1000) + 'K';
- } else if (viewCount >= 1000000 && viewCount < 1000000000) {
- return Math.trunc(viewCount / 1000000) + 'M';
- } else if (viewCount >= 1000000000) {
- return Math.trunc(viewCount / 1000000000) + 'B';
- }
- };
-
- /**
- * The function that is called to decide on what'll be rendered by the component.
- * It renders search Results if found. If user didn't do a new search, it renders from the videoTemplates
- * generated by the backUps. If none present, renders nothing.
- */
- renderSearchResultsOrVideo = () => {
- if (this.searchResultsFound) {
- if (this.searchResults.length !== 0) {
- return (
- <ul>
- {this.searchResults.map((video, index) => {
- const filteredTitle = this.filterYoutubeTitleResult(video.snippet.title);
- const channelTitle = video.snippet.channelTitle;
- const videoDescription = video.snippet.description;
- const pusblishDate = this.roundPublishTime(video.snippet.publishedAt);
- let duration;
- let viewCount;
- if (this.videoDetails.length !== 0) {
- duration = this.convertIsoTimeToDuration(this.videoDetails[index].contentDetails.duration);
- viewCount = this.abbreviateViewCount(this.videoDetails[index].statistics.viewCount);
- }
-
- return (
- <li onClick={() => this.embedVideoOnClick(video.id.videoId, filteredTitle)} key={Utils.GenerateGuid()}>
- <div className="search_wrapper">
- <div style={{ backgroundColor: 'yellow' }}>
- <img src={video.snippet.thumbnails.medium.url} />
- <span className="video_duration">{duration}</span>
- </div>
- <div className="textual_info">
- <span className="videoTitle">{filteredTitle}</span>
- <span className="channelName">{channelTitle}</span>
- <span className="viewCount">{viewCount}</span>
- <span className="publish_time">{pusblishDate}</span>
- <p className="video_description">{videoDescription}</p>
- </div>
- </div>
- </li>
- );
- })}
- </ul>
- );
- } else if (this.curVideoTemplates.length !== 0) {
- return (
- <ul>
- {this.curVideoTemplates.map((video: VideoTemplate) => {
- return (
- <li onClick={() => this.embedVideoOnClick(video.videoId, video.videoTitle)} key={Utils.GenerateGuid()}>
- <div className="search_wrapper">
- <div style={{ backgroundColor: 'yellow' }}>
- <img src={video.thumbnailUrl} />
- <span className="video_duration">{video.duration}</span>
- </div>
- <div className="textual_info">
- <span className="videoTitle">{video.videoTitle}</span>
- <span className="channelName">{video.channelTitle}</span>
- <span className="viewCount">{video.viewCount}</span>
- <span className="publish_time">{video.publishDate}</span>
- <p className="video_description">{video.videoDescription}</p>
- </div>
- </div>
- </li>
- );
- })}
- </ul>
- );
- }
- } else {
- return null;
- }
- };
-
- /**
- * Given a videoId and title, creates a new youtube embedded url, and uses that
- * to create a new video document.
- */
- @action
- embedVideoOnClick = (videoId: string, filteredTitle: string) => {
- const embeddedUrl = 'https://www.youtube.com/embed/' + videoId;
- this.selectedVideoUrl = embeddedUrl;
- const addFunction = this.props.addDocument!;
- const newVideoX = NumCast(this.props.Document.x);
- const newVideoY = NumCast(this.props.Document.y) + NumCast(this.props.Document.height);
-
- addFunction(Docs.Create.VideoDocument(embeddedUrl, { title: filteredTitle, _width: 400, _height: 315, x: newVideoX, y: newVideoY }));
- this.videoClicked = true;
- };
-
- render() {
- const content = (
- <div className="youtubeBox-cont" style={{ width: '100%', height: '100%', position: 'absolute' }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
- <input type="text" placeholder="Search for a video" onKeyDown={this.onEnterKeyDown} style={{ height: 40, width: '100%', border: '1px solid black', padding: 5, textAlign: 'center' }} ref={e => (this.YoutubeSearchElement = e!)} />
- {this.renderSearchResultsOrVideo()}
- </div>
- );
-
- const frozen = !this.props.isSelected() || SnappingManager.IsResizing;
-
- const classname = 'webBox-cont' + (this.props.isSelected() && Doc.ActiveTool === InkTool.None && !SnappingManager.IsResizing ? '-interactive' : '');
- return (
- <>
- <div className={classname}>{content}</div>
- {!frozen ? null : <div className="webBox-overlay" onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} />}
- </>
- );
- }
-}
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index 408903324..9808b6a01 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -1,18 +1,21 @@
-import * as request from 'request-promise';
-import { Doc, Field } from '../../fields/Doc';
-import { Cast } from '../../fields/Types';
-import { Utils } from '../../Utils';
+/* eslint-disable @typescript-eslint/no-unused-vars */
+/* eslint-disable camelcase */
+/* eslint-disable no-useless-catch */
+/* eslint-disable no-use-before-define */
+import * as rp from 'request-promise';
+import { Doc, FieldType } from '../../fields/Doc';
import { InkData } from '../../fields/InkField';
-import { UndoManager } from '../util/UndoManager';
-import requestPromise = require('request-promise');
import { List } from '../../fields/List';
+import { Cast } from '../../fields/Types';
+import { UndoManager } from '../util/UndoManager';
+import { ClientUtils } from '../../ClientUtils';
type APIManager<D> = { converter: BodyConverter<D>; requester: RequestExecutor };
type RequestExecutor = (apiKey: string, body: string, service: Service) => Promise<string>;
type AnalysisApplier<D> = (target: Doc, relevantKeys: string[], data: D, ...args: any) => any;
type BodyConverter<D> = (data: D) => string;
-type Converter = (results: any) => Field;
-type TextConverter = (results: any, data: string) => Promise<{ keyterms: Field; external_recommendations: any; kp_string: string[] }>;
+type Converter = (results: any) => FieldType;
+type TextConverter = (results: any, data: string) => Promise<{ keyterms: FieldType; external_recommendations: any; kp_string: string[] }>;
type BingConverter = (results: any) => Promise<{ title_vals: string[]; url_vals: string[] }>;
export type Tag = { name: string; confidence: number };
@@ -42,7 +45,7 @@ export enum Confidence {
*/
export namespace CognitiveServices {
const ExecuteQuery = async <D>(service: Service, manager: APIManager<D>, data: D): Promise<any> => {
- let apiKey = process.env[service.toUpperCase()];
+ const apiKey = process.env[service.toUpperCase()];
if (!apiKey) {
console.log(`No API key found for ${service}: ensure youe root directory has .env file with _CLIENT_${service.toUpperCase()}.`);
return undefined;
@@ -53,7 +56,6 @@ export namespace CognitiveServices {
results = await manager.requester(apiKey, manager.converter(data), service).then(json => JSON.parse(json));
} catch (e) {
throw e;
- results = undefined;
}
return results;
};
@@ -72,7 +74,7 @@ export namespace CognitiveServices {
parameters = {
returnFaceId: 'true',
returnFaceLandmarks: 'false',
- returnFaceAttributes: 'age,gender,headPose,smile,facialHair,glasses,' + 'emotion,hair,makeup,occlusion,accessories,blur,exposure,noise',
+ returnFaceAttributes: 'age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise',
};
break;
case Service.ComputerVision:
@@ -83,6 +85,7 @@ export namespace CognitiveServices {
language: 'en',
};
break;
+ default:
}
const options = {
@@ -95,7 +98,7 @@ export namespace CognitiveServices {
},
};
- return request.post(options);
+ return rp.post(options);
},
};
@@ -111,12 +114,10 @@ export namespace CognitiveServices {
const results = await ExecuteQuery(service, Manager, url);
if (!results) {
toStore = 'Cognitive Services could not process the given image URL.';
+ } else if (!results.length) {
+ toStore = converter(results);
} else {
- if (!results.length) {
- toStore = converter(results);
- } else {
- toStore = results.length > 0 ? converter(results) : 'Empty list returned.';
- }
+ toStore = results.length > 0 ? converter(results) : 'Empty list returned.';
}
target[storageKey] = toStore;
@@ -150,7 +151,7 @@ export namespace CognitiveServices {
const endpoint = serverAddress + '/inkrecognizer/v1.0-preview/recognize';
return new Promise<string>((resolve, reject) => {
- xhttp.onreadystatechange = function () {
+ xhttp.onreadystatechange = function (this: XMLHttpRequest) {
if (this.readyState === 4) {
const result = xhttp.responseText;
switch (this.status) {
@@ -161,6 +162,7 @@ export namespace CognitiveServices {
return reject(result);
}
}
+ return undefined;
};
xhttp.open('PUT', endpoint, true);
@@ -213,15 +215,13 @@ export namespace CognitiveServices {
export namespace BingSearch {
export const Manager: APIManager<string> = {
- converter: (data: string) => {
- return data;
- },
+ converter: (data: string) => data,
requester: async (apiKey: string, query: string) => {
const xhttp = new XMLHttpRequest();
const serverAddress = 'https://api.cognitive.microsoft.com';
const endpoint = serverAddress + '/bing/v5.0/search?q=' + encodeURIComponent(query);
const promisified = (resolve: any, reject: any) => {
- xhttp.onreadystatechange = function () {
+ xhttp.onreadystatechange = function (this: XMLHttpRequest) {
if (this.readyState === 4) {
const result = xhttp.responseText;
switch (this.status) {
@@ -232,6 +232,7 @@ export namespace CognitiveServices {
return reject(result);
}
}
+ return undefined;
};
if (apiKey) {
@@ -259,15 +260,13 @@ export namespace CognitiveServices {
export namespace HathiTrust {
export const Manager: APIManager<string> = {
- converter: (data: string) => {
- return data;
- },
+ converter: (data: string) => data,
requester: async (apiKey: string, query: string) => {
const xhttp = new XMLHttpRequest();
const serverAddress = 'https://babel.hathitrust.org/cgi/htd/​';
const endpoint = serverAddress + '/bing/v5.0/search?q=' + encodeURIComponent(query);
const promisified = (resolve: any, reject: any) => {
- xhttp.onreadystatechange = function () {
+ xhttp.onreadystatechange = function (this: XMLHttpRequest) {
if (this.readyState === 4) {
const result = xhttp.responseText;
switch (this.status) {
@@ -278,6 +277,7 @@ export namespace CognitiveServices {
return reject(result);
}
}
+ return undefined;
};
if (apiKey) {
@@ -305,8 +305,8 @@ export namespace CognitiveServices {
export namespace Text {
export const Manager: APIManager<string> = {
- converter: (data: string) => {
- return JSON.stringify({
+ converter: (data: string) =>
+ JSON.stringify({
documents: [
{
id: 1,
@@ -314,8 +314,7 @@ export namespace CognitiveServices {
text: data,
},
],
- });
- },
+ }),
requester: async (apiKey: string, body: string, service: Service) => {
const serverAddress = 'https://eastus.api.cognitive.microsoft.com';
const endpoint = serverAddress + '/text/analytics/v2.1/keyPhrases';
@@ -344,10 +343,10 @@ export namespace CognitiveServices {
export namespace Appliers {
export async function vectorize(keyterms: any, dataDoc: Doc, mainDoc: boolean = false) {
console.log('vectorizing...');
- //keyterms = ["father", "king"];
+ // keyterms = ["father", "king"];
- const args = { method: 'POST', uri: Utils.prepend('/recommender'), body: { keyphrases: keyterms }, json: true };
- await requestPromise.post(args).then(async wordvecs => {
+ const args = { method: 'POST', uri: ClientUtils.prepend('/recommender'), body: { keyphrases: keyterms }, json: true };
+ await rp.post(args).then(async wordvecs => {
if (wordvecs) {
const indices = Object.keys(wordvecs);
console.log('successful vectorization!');
@@ -355,7 +354,7 @@ export namespace CognitiveServices {
indices.forEach((ind: any) => {
vectorValues.push(wordvecs[ind]);
});
- //ClientRecommender.Instance.processVector(vectorValues, dataDoc, mainDoc);
+ // ClientRecommender.Instance.processVector(vectorValues, dataDoc, mainDoc);
} // adds document to internal doc set
else {
console.log('unsuccessful :( word(s) not in vocabulary');
@@ -369,11 +368,12 @@ export namespace CognitiveServices {
const { keyterms, external_recommendations, kp_string } = await converter(results, data);
target[keys[0]] = keyterms;
if (isInternal) {
- //await vectorize([data], dataDoc, isMainDoc);
+ // await vectorize([data], dataDoc, isMainDoc);
await vectorize(kp_string, dataDoc, isMainDoc);
} else {
return { recs: external_recommendations, keyterms: keyterms };
}
+ return undefined;
};
// export async function countFrequencies()
diff --git a/src/client/documents/DocFromField.ts b/src/client/documents/DocFromField.ts
new file mode 100644
index 000000000..b65bbbdf5
--- /dev/null
+++ b/src/client/documents/DocFromField.ts
@@ -0,0 +1,31 @@
+import { Doc, DocListCast } from '../../fields/Doc';
+import { InkField } from '../../fields/InkField';
+import { List } from '../../fields/List';
+import { StrCast } from '../../fields/Types';
+import { AudioField, ImageField, PdfField, VideoField } from '../../fields/URLField';
+import { Docs, DocumentOptions } from './Documents';
+
+/**
+ * Changes the field key in the doc's layout string to be the specified field
+ */
+export function ResetLayoutFieldKey(doc: Doc, fieldKey: string) {
+ doc.layout = StrCast(doc.layout).replace(/={'.*'}/, `={'${fieldKey}'}`);
+ return doc;
+}
+export function DocumentFromField(target: Doc, fieldKey: string, proto?: Doc, options?: DocumentOptions): Doc | undefined {
+ const field = target[fieldKey];
+ const resolved = options ?? {};
+ const nonDocFieldToDoc = () => {
+ if (field instanceof ImageField) return Docs.Create.ImageDocument(field.url.href, resolved);
+ if (field instanceof VideoField) return Docs.Create.VideoDocument(field.url.href, resolved);
+ if (field instanceof PdfField) return Docs.Create.PdfDocument(field.url.href, resolved);
+ if (field instanceof AudioField) return Docs.Create.AudioDocument(field.url.href, resolved);
+ if (field instanceof InkField) return Docs.Create.InkDocument(field.inkData, resolved);
+ if (field instanceof List && field[0] instanceof Doc) return Docs.Create.StackingDocument(DocListCast(field), resolved);
+ return Docs.Create.TextDocument('', { ...{ _width: 200, _height: 25, _layout_autoHeight: true }, ...resolved });
+ };
+ const created = field instanceof Doc ? field : ResetLayoutFieldKey(nonDocFieldToDoc(), fieldKey);
+ created.title = fieldKey;
+ proto && created.proto && (created.proto = Doc.GetProto(proto));
+ return created;
+}
diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts
new file mode 100644
index 000000000..0c9fe0315
--- /dev/null
+++ b/src/client/documents/DocUtils.ts
@@ -0,0 +1,875 @@
+/* eslint-disable prefer-destructuring */
+/* eslint-disable default-param-last */
+/* eslint-disable no-use-before-define */
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { saveAs } from 'file-saver';
+import * as JSZip from 'jszip';
+import { action, runInAction } from 'mobx';
+import { ClientUtils } from '../../ClientUtils';
+import * as JSZipUtils from '../../JSZipUtils';
+import { decycle } from '../../decycler/decycler';
+import { DateField } from '../../fields/DateField';
+import { Doc, DocListCast, Field, FieldResult, FieldType, LinkedTo, Opt, StrListCast } from '../../fields/Doc';
+import { DocData } from '../../fields/DocSymbols';
+import { Id } from '../../fields/FieldSymbols';
+import { InkDataFieldName, InkField } from '../../fields/InkField';
+import { List, ListFieldName } from '../../fields/List';
+import { ProxyField } from '../../fields/Proxy';
+import { RichTextField } from '../../fields/RichTextField';
+import { ComputedField, ScriptField } from '../../fields/ScriptField';
+import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../fields/Types';
+import { AudioField, CsvField, ImageField, PdfField, VideoField, WebField } from '../../fields/URLField';
+import { SharingPermissions } from '../../fields/util';
+import { Upload } from '../../server/SharedMediaTypes';
+import { DocServer } from '../DocServer';
+import { Networking } from '../Network';
+import { LinkManager } from '../util/LinkManager';
+import { ScriptingGlobals } from '../util/ScriptingGlobals';
+import { SerializationHelper } from '../util/SerializationHelper';
+import { UndoManager, undoable } from '../util/UndoManager';
+import { ContextMenu } from '../views/ContextMenu';
+import { ContextMenuProps } from '../views/ContextMenuItem';
+import { LinkDescriptionPopup } from '../views/nodes/LinkDescriptionPopup';
+import { OpenWhere } from '../views/nodes/OpenWhere';
+import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
+import { DocumentType } from './DocumentTypes';
+import { Docs, DocumentOptions } from './Documents';
+
+const { DFLT_IMAGE_NATIVE_DIM } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore
+
+const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', ''));
+
+export namespace DocUtils {
+ function matchFieldValue(doc: Doc, key: string, valueIn: any): boolean {
+ let value = valueIn;
+ const hasFunctionFilter = ClientUtils.HasFunctionFilter(value);
+ if (hasFunctionFilter) {
+ return hasFunctionFilter(StrCast(doc[key]));
+ }
+ if (key === LinkedTo) {
+ // links are not a field value, so handled here. value is an expression of form ([field=]idToDoc("..."))
+ const allLinks = Doc.Links(doc);
+ const matchLink = (val: string, anchor: Doc) => {
+ const linkedToExp = (val ?? '').split('=');
+ if (linkedToExp.length === 1) return Field.toScriptString(anchor) === val;
+ return Field.toScriptString(DocCast(anchor[linkedToExp[0]])) === linkedToExp[1];
+ };
+ // 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)) ));
+ }
+ if (typeof value === 'string') {
+ value = value.replace(`,${ClientUtils.noRecursionHack}`, '');
+ }
+ const fieldVal = doc[key];
+ // prettier-ignore
+ if ((value === Doc.FilterAny && fieldVal !== undefined) ||
+ (value === Doc.FilterNone && fieldVal === undefined)) {
+ return true;
+ }
+ 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 Field.toString(fieldVal as FieldType).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
+ }
+ /**
+ * @param docs
+ * @param childFilters
+ * @param childFiltersByRanges
+ * @param parentCollection
+ * Given a list of docs and childFilters, @returns the list of Docs that match those filters
+ */
+ export function FilterDocs(childDocs: Doc[], childFilters: string[], childFiltersByRanges: string[], parentCollection?: Doc) {
+ if (!childFilters?.length && !childFiltersByRanges?.length) {
+ return childDocs.filter(d => !d.cookies); // remove documents that need a cookie if there are no filters to provide one
+ }
+
+ const filterFacets: { [key: string]: { [value: string]: string } } = {}; // maps each filter key to an object with value=>modifier fields
+ childFilters.forEach(filter => {
+ const fields = filter.split(Doc.FilterSep);
+ const key = fields[0];
+ const value = fields[1];
+ const modifiers = fields[2];
+ if (!filterFacets[key]) {
+ filterFacets[key] = {};
+ }
+ filterFacets[key][value] = modifiers;
+ });
+
+ const filteredDocs = childFilters.length
+ ? childDocs.filter(d => {
+ if (d.z) return true;
+ // if the document needs a cookie but no filter provides the cookie, then the document does not pass the filter
+ if (d.cookies && (!filterFacets.cookies || !Object.keys(filterFacets.cookies).some(key => d.cookies === key))) {
+ return false;
+ }
+ const facetKeys = Object.keys(filterFacets).filter(fkey => fkey !== 'cookies' && fkey !== ClientUtils.noDragDocsFilter.split(Doc.FilterSep)[0]);
+ // eslint-disable-next-line no-restricted-syntax
+ for (const facetKey of facetKeys) {
+ const facet = filterFacets[facetKey];
+
+ // facets that match some value in the field of the document (e.g. some text field)
+ const matches = Object.keys(facet).filter(value => value !== 'cookies' && facet[value] === 'match');
+
+ // facets that have a check next to them
+ const checks = Object.keys(facet).filter(value => facet[value] === 'check');
+
+ // metadata facets that exist
+ const exists = Object.keys(facet).filter(value => facet[value] === 'exists');
+
+ // facets that unset metadata (a hack for making cookies work)
+ const unsets = Object.keys(facet).filter(value => facet[value] === 'unset');
+
+ // facets that specify that a field must not match a specific value
+ const xs = Object.keys(facet).filter(value => facet[value] === 'x');
+
+ if (!unsets.length && !exists.length && !xs.length && !checks.length && !matches.length) return true;
+ const failsNotEqualFacets = !xs.length ? false : xs.some(value => matchFieldValue(d, facetKey, value));
+ const satisfiesCheckFacets = !checks.length ? true : checks.some(value => matchFieldValue(d, facetKey, value));
+ const satisfiesExistsFacets = !exists.length ? true : facetKey !== LinkedTo ? d[facetKey] !== undefined : Doc.Links(d).length;
+ const satisfiesUnsetsFacets = !unsets.length ? true : d[facetKey] === undefined;
+ const satisfiesMatchFacets = !matches.length
+ ? true
+ : matches.some(value => {
+ if (facetKey.startsWith('*')) {
+ // fields starting with a '*' are used to match families of related fields. ie, *modificationDate will match text_modificationDate, data_modificationDate, etc
+ const allKeys = Array.from(Object.keys(d));
+ allKeys.push(...Object.keys(Doc.GetProto(d)));
+ const keys = allKeys.filter(key => key.includes(facetKey.substring(1)));
+ return keys.some(key => Field.toString(d[key] as FieldType).includes(value));
+ }
+ return Field.toString(d[facetKey] as FieldType).includes(value);
+ });
+ // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria
+ if (parentCollection?.childFilters_boolean === 'OR') {
+ if (satisfiesUnsetsFacets && satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true;
+ }
+ // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria
+ else if (!satisfiesUnsetsFacets || !satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false;
+ }
+ return parentCollection?.childFilters_boolean !== 'OR';
+ })
+ : childDocs;
+ const rangeFilteredDocs = filteredDocs.filter(d => {
+ for (let i = 0; i < childFiltersByRanges.length; i += 3) {
+ const key = childFiltersByRanges[i];
+ const min = Number(childFiltersByRanges[i + 1]);
+ const max = Number(childFiltersByRanges[i + 2]);
+ const val = typeof d[key] === 'string' ? (Number(StrCast(d[key])).toString() === StrCast(d[key]) ? Number(StrCast(d[key])) : undefined) : Cast(d[key], 'number', null);
+ if (val === undefined) {
+ // console.log("Should 'undefined' pass range filter or not?")
+ } else if (val < min || val > max) return false;
+ }
+ return true;
+ });
+ return rangeFilteredDocs;
+ }
+
+ export function MakeLink(source: Doc, target: Doc, linkSettings: { link_relationship?: string; link_description?: string }, id?: string, showPopup?: number[]) {
+ if (!linkSettings.link_relationship) linkSettings.link_relationship = target.type === DocumentType.RTF ? 'Commentary:Comments On' : 'link';
+ if (target.doc === Doc.UserDoc()) return undefined;
+
+ const makeLink = action((linkDoc: Doc, showAt?: number[]) => {
+ if (showAt) {
+ LinkManager.Instance.currentLink = linkDoc;
+
+ TaskCompletionBox.textDisplayed = 'Link Created';
+ TaskCompletionBox.popupX = showAt[0];
+ TaskCompletionBox.popupY = showAt[1] - 33;
+ TaskCompletionBox.taskCompleted = true;
+
+ LinkDescriptionPopup.Instance.popupX = showAt[0];
+ LinkDescriptionPopup.Instance.popupY = showAt[1];
+ LinkDescriptionPopup.Instance.display = true;
+
+ const rect = document.body.getBoundingClientRect();
+ if (LinkDescriptionPopup.Instance.popupX + 200 > rect.width) {
+ LinkDescriptionPopup.Instance.popupX -= 190;
+ TaskCompletionBox.popupX -= 40;
+ }
+ if (LinkDescriptionPopup.Instance.popupY + 100 > rect.height) {
+ LinkDescriptionPopup.Instance.popupY -= 40;
+ TaskCompletionBox.popupY -= 40;
+ }
+
+ setTimeout(
+ action(() => {
+ TaskCompletionBox.taskCompleted = false;
+ }),
+ 2500
+ );
+ }
+ return linkDoc;
+ });
+
+ const a = source.layout_unrendered ? 'link_anchor_1?.annotationOn' : 'link_anchor_1';
+ const b = target.layout_unrendered ? 'link_anchor_2?.annotationOn' : 'link_anchor_2';
+
+ return makeLink(
+ Docs.Create.LinkDocument(
+ source,
+ target,
+ {
+ acl_Guest: SharingPermissions.Augment,
+ _acl_Guest: SharingPermissions.Augment,
+ title: ComputedField.MakeFunction('generateLinkTitle(this)') as any,
+ 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,
+ link_autoMoveAnchors: true,
+ _lockedPosition: true,
+ _layout_showCaption: '', // removed since they conflict with showing a link with a LinkBox (ie, line, not comparison box)
+ _layout_showTitle: '',
+ // _layout_showCaption: 'link_description',
+ // _layout_showTitle: 'link_relationship',
+ },
+ id
+ ),
+ showPopup
+ );
+ }
+
+ export function AssignScripts(doc: Doc, scripts?: { [key: string]: string | undefined }, funcs?: { [key: string]: string }) {
+ scripts &&
+ Object.keys(scripts).forEach(key => {
+ const script = scripts[key];
+ if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && script) {
+ (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = ScriptField.MakeScript(script, {
+ this: Doc.name,
+ dragData: Doc.DocDragDataName,
+ value: 'any',
+ _readOnly_: 'boolean',
+ scriptContext: 'any',
+ documentView: Doc.name,
+ heading: Doc.name,
+ checked: 'boolean',
+ containingTreeView: Doc.name,
+ altKey: 'boolean',
+ ctrlKey: 'boolean',
+ shiftKey: 'boolean',
+ });
+ }
+ });
+ funcs &&
+ Object.keys(funcs)
+ .filter(key => !key.endsWith('-setter'))
+ .forEach(key => {
+ const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+ if (ScriptCast(cfield)?.script.originalScript !== funcs[key]) {
+ 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;
+ }
+ });
+ return doc;
+ }
+ export function AssignOpts(doc: Doc | undefined, reqdOpts: DocumentOptions, items?: Doc[]) {
+ if (doc) {
+ const compareValues = (val1: any, val2: any) => {
+ if (val1 instanceof List && val2 instanceof List && val1.length === val2.length) {
+ return !val1.some(v => !val2.includes(v)) || !val2.some(v => val1.includes(v));
+ }
+ return val1 === val2;
+ };
+ Object.entries(reqdOpts).forEach(pair => {
+ const targetDoc = pair[0].startsWith('_') ? doc : Doc.GetProto(doc as Doc);
+ if (!Object.getOwnPropertyNames(targetDoc).includes(pair[0].replace(/^_/, '')) || !compareValues(pair[1], targetDoc[pair[0]])) {
+ targetDoc[pair[0]] = pair[1];
+ }
+ });
+ items?.forEach(item => !DocListCast(doc.data).includes(item) && Doc.AddDocToList(Doc.GetProto(doc), 'data', item));
+ items && DocListCast(doc.data).forEach(item => Doc.IsSystem(item) && !items.includes(item) && Doc.RemoveDocFromList(Doc.GetProto(doc), 'data', item));
+ }
+ return doc;
+ }
+ export function AssignDocField(doc: Doc, field: string, creator: (reqdOpts: DocumentOptions, items?: Doc[]) => Doc, reqdOpts: DocumentOptions, items?: Doc[], scripts?: { [key: string]: string }, funcs?: { [key: string]: string }) {
+ // eslint-disable-next-line no-return-assign
+ return DocUtils.AssignScripts(DocUtils.AssignOpts(DocCast(doc[field]), reqdOpts, items) ?? (doc[field] = creator(reqdOpts, items)), scripts, funcs);
+ }
+
+ /**
+ *
+ * @param type the type of file.
+ * @param path the path to the file.
+ * @param options the document options.
+ * @param overwriteDoc the placeholder loading doc.
+ * @returns
+ */
+ export async function DocumentFromType(type: string, path: string, options: DocumentOptions, overwriteDoc?: Doc): Promise<Opt<Doc>> {
+ let ctor: ((path: string, options: DocumentOptions, overwriteDoc?: Doc) => Doc | Promise<Doc | undefined>) | undefined;
+ if (type.indexOf('image') !== -1) {
+ ctor = Docs.Create.ImageDocument;
+ if (!options._width) options._width = 300;
+ }
+ if (type.indexOf('video') !== -1) {
+ ctor = Docs.Create.VideoDocument;
+ if (!options._width) options._width = 600;
+ if (!options._height) options._height = ((options._width as number) * 2) / 3;
+ }
+ if (type.indexOf('audio') !== -1) {
+ ctor = Docs.Create.AudioDocument;
+ }
+ if (type.indexOf('pdf') !== -1) {
+ ctor = Docs.Create.PdfDocument;
+ if (!options._width) options._width = 400;
+ if (!options._height) options._height = ((options._width as number) * 1200) / 927;
+ }
+ if (type.indexOf('csv') !== -1) {
+ ctor = Docs.Create.DataVizDocument;
+ if (!options._width) options._width = 400;
+ if (!options._height) options._height = ((options._width as number) * 1200) / 927;
+ }
+ // TODO:al+glr
+ // if (type.indexOf("map") !== -1) {
+ // ctor = Docs.Create.MapDocument;
+ // if (!options._width) options._width = 800;
+ // if (!options._height) options._height = (options._width as number) * 3 / 4;
+ // }
+ if (type.indexOf('html') !== -1) {
+ if (path.includes(window.location.hostname)) {
+ const s = path.split('/');
+ const id = s[s.length - 1];
+ return DocServer.GetRefField(id).then(field => {
+ if (field instanceof Doc) {
+ const embedding = Doc.MakeEmbedding(field);
+ embedding.x = (options.x as number) || 0;
+ embedding.y = (options.y as number) || 0;
+ embedding._width = (options._width as number) || 300;
+ embedding._height = (options._height as number) || (options._width as number) || 300;
+ return embedding;
+ }
+ return undefined;
+ });
+ }
+ ctor = Docs.Create.WebDocument;
+ // eslint-disable-next-line no-param-reassign
+ options = { ...options, _width: 400, _height: 512, title: path };
+ }
+
+ 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 {
+ const documentList: ContextMenuProps[] = DocListCast(DocListCast(Doc.MyTools?.data)[0]?.data)
+ .filter(btnDoc => !btnDoc.hidden)
+ .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null))
+ .filter(doc => doc && doc !== Doc.UserDoc().emptyTrail && doc.title)
+ .map(dragDoc => ({
+ description: ':' + StrCast(dragDoc.title).replace('Untitled ', ''),
+ event: undoable(() => {
+ const newDoc = DocUtils.copyDragFactory(dragDoc);
+ if (newDoc) {
+ newDoc.author = ClientUtils.CurrentUserEmail();
+ newDoc.x = x;
+ newDoc.y = y;
+ Doc.SetSelectOnLoad(newDoc);
+ if (pivotField) {
+ newDoc[pivotField] = pivotValue;
+ }
+ docAdder?.(newDoc);
+ }
+ }, StrCast(dragDoc.title)),
+ icon: Doc.toIcon(dragDoc),
+ })) as ContextMenuProps[];
+ ContextMenu.Instance.addItem({
+ description: 'Create document',
+ subitems: documentList,
+ icon: 'file',
+ });
+ !simpleMenu &&
+ ContextMenu.Instance.addItem({
+ description: 'Styled Notes',
+ subitems: DocListCast((Doc.UserDoc().template_notes as Doc).data).map(note => ({
+ description: ':' + StrCast(note.title),
+ event: undoable(() => {
+ const textDoc = Docs.Create.TextDocument('', {
+ _width: 200,
+ x,
+ y,
+ _layout_autoHeight: note._layout_autoHeight !== false,
+ title: StrCast(note.title) + '#' + (note.embeddingCount = NumCast(note.embeddingCount) + 1),
+ });
+ textDoc.layout_fieldKey = 'layout_' + note.title;
+ textDoc[textDoc.layout_fieldKey] = note;
+ if (pivotField) {
+ textDoc[pivotField] = pivotValue;
+ }
+ docTextAdder(textDoc);
+ }, 'create quick note'),
+ icon: StrCast(note.icon) as IconProp,
+ })) as ContextMenuProps[],
+ icon: 'sticky-note',
+ });
+ const userDocList: ContextMenuProps[] = DocListCast(DocListCast(Doc.MyTools?.data)[1]?.data)
+ .filter(btnDoc => !btnDoc.hidden)
+ .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null))
+ .filter(doc => doc && doc !== Doc.UserDoc().emptyTrail && doc !== Doc.UserDoc().emptyNote && doc.title)
+ .map(dragDoc => ({
+ description: ':' + StrCast(dragDoc.title).replace('Untitled ', ''),
+ event: undoable(() => {
+ const newDoc = DocUtils.delegateDragFactory(dragDoc);
+ if (newDoc) {
+ newDoc.author = ClientUtils.CurrentUserEmail();
+ newDoc.x = x;
+ newDoc.y = y;
+ Doc.SetSelectOnLoad(newDoc);
+ if (pivotField) {
+ newDoc[pivotField] = pivotValue;
+ }
+ docAdder?.(newDoc);
+ }
+ }, StrCast(dragDoc.title)),
+ icon: Doc.toIcon(dragDoc),
+ })) as ContextMenuProps[];
+ ContextMenu.Instance.addItem({
+ description: 'User Templates',
+ subitems: userDocList,
+ icon: 'file',
+ });
+ }
+
+ // applies a custom template to a document. the template is identified by it's short name (e.g, slideView not layout_slideView)
+
+ /**
+ * Applies a template to a Doc and logs the action with the UndoManager
+ * If the template already exists and has been registered, it can be specified by it's signature name (e.g., 'icon' not 'layout_icon').
+ * Alternatively, the signature can be omitted and the template can be provided.
+ * @param doc the Doc to apply the template to.
+ * @param creator a function that will create the template if it doesn't exist
+ * @param templateSignature the signature name for a template that has already been created and registered on the userDoc. (can be "" if template is provide)
+ * @param template the template to use (optional if templateSignature is provided)
+ * @returns doc
+ */
+ export function makeCustomViewClicked(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = 'custom', template?: Doc) {
+ const batch = UndoManager.StartBatch('makeCustomViewClicked');
+ createCustomView(doc, creator, templateSignature || StrCast(template?.title), template);
+ batch.end();
+ return doc;
+ }
+ export function findTemplate(templateName: string, type: string) {
+ let docLayoutTemplate: Opt<Doc>;
+ const iconViews = DocListCast(Cast(Doc.UserDoc().template_icons, Doc, null)?.data);
+ const templBtns = DocListCast(Cast(Doc.UserDoc().template_buttons, Doc, null)?.data);
+ const noteTypes = DocListCast(Cast(Doc.UserDoc().template_notes, Doc, null)?.data);
+ const userTypes = DocListCast(Cast(Doc.UserDoc().template_user, Doc, null)?.data);
+ const clickFuncs = DocListCast(Cast(Doc.UserDoc().template_clickFuncs, Doc, null)?.data);
+ const allTemplates = iconViews
+ .concat(templBtns)
+ .concat(noteTypes)
+ .concat(userTypes)
+ .concat(clickFuncs)
+ .map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc)
+ .filter(doc => doc.isTemplateDoc);
+ // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized
+ // first try to find a template that matches the specific document type (<typeName>_<templateName>). otherwise, fallback to a general match on <templateName>
+ !docLayoutTemplate &&
+ allTemplates.forEach(tempDoc => {
+ StrCast(tempDoc.title) === templateName + '_' + type && (docLayoutTemplate = tempDoc);
+ });
+ !docLayoutTemplate &&
+ allTemplates.forEach(tempDoc => {
+ StrCast(tempDoc.title) === templateName && (docLayoutTemplate = tempDoc);
+ });
+ return docLayoutTemplate;
+ }
+ export function createCustomView(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = 'custom', docLayoutTemplate?: Doc) {
+ 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));
+
+ const customName = 'layout_' + templateSignature;
+ const _width = NumCast(doc._width);
+ const _height = NumCast(doc._height);
+ const options = { title: 'data', backgroundColor: StrCast(doc.backgroundColor), _layout_autoHeight: true, _width, x: -_width / 2, y: -_height / 2, _layout_showSidebar: false };
+
+ if (docLayoutTemplate) {
+ if (docLayoutTemplate !== doc[customName]) {
+ Doc.ApplyTemplateTo(docLayoutTemplate, doc, customName, undefined);
+ }
+ } else {
+ let fieldTemplate: Opt<Doc>;
+ if (doc.data instanceof RichTextField || typeof doc.data === 'string') {
+ fieldTemplate = Docs.Create.TextDocument('', options);
+ } else if (doc.data instanceof PdfField) {
+ fieldTemplate = Docs.Create.PdfDocument('http://www.msn.com', options);
+ } else if (doc.data instanceof VideoField) {
+ fieldTemplate = Docs.Create.VideoDocument('http://www.cs.brown.edu', options);
+ } else if (doc.data instanceof AudioField) {
+ fieldTemplate = Docs.Create.AudioDocument('http://www.cs.brown.edu', options);
+ } else if (doc.data instanceof ImageField) {
+ fieldTemplate = Docs.Create.ImageDocument('http://www.cs.brown.edu', options);
+ }
+ const docTemplate = creator?.(fieldTemplate ? [fieldTemplate] : [], { title: customName + '(' + doc.title + ')', isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
+ fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, docTemplate ? Doc.GetProto(docTemplate) : docTemplate);
+ docTemplate && Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined);
+ }
+ }
+ export function makeCustomView(doc: Doc, custom: boolean, layout: string) {
+ Doc.setNativeView(doc);
+ if (custom) {
+ makeCustomViewClicked(doc, Docs.Create.StackingDocument, layout, undefined);
+ }
+ }
+ export function iconify(doc: Doc) {
+ const layoutFieldKey = Cast(doc.layout_fieldKey, 'string', null);
+ DocUtils.makeCustomViewClicked(doc, Docs.Create.StackingDocument, 'icon', undefined);
+ if (layoutFieldKey && layoutFieldKey !== 'layout' && layoutFieldKey !== 'layout_icon') doc.deiconifyLayout = layoutFieldKey.replace('layout_', '');
+ }
+
+ export function pileup(docList: Doc[], x?: number, y?: number, size: number = 55, create: boolean = true) {
+ runInAction(() => {
+ docList.forEach((doc, i) => {
+ const d = doc;
+ DocUtils.iconify(d);
+ d.x = Math.cos((Math.PI * 2 * i) / docList.length) * size - size;
+ d.y = Math.sin((Math.PI * 2 * i) / docList.length) * size - size;
+ d._timecodeToShow = undefined; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+ });
+ });
+ if (create) {
+ const newCollection = Docs.Create.PileDocument(docList, { title: 'pileup', _freeform_noZoom: true, x: (x || 0) - size, y: (y || 0) - size, _width: size * 2, _height: size * 2, dragWhenActive: true, _layout_fitWidth: false });
+ newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - size;
+ newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - size;
+ newCollection._width = newCollection._height = size * 2;
+ return newCollection;
+ }
+ return undefined;
+ }
+ export function makeIntoPortal(doc: Doc, layoutDoc: Doc, allLinks: Doc[]) {
+ const portalLink = allLinks.find(d => d.link_anchor_1 === doc && d.link_relationship === 'portal to:portal from');
+ if (!portalLink) {
+ DocUtils.MakeLink(
+ doc,
+ Docs.Create.FreeformDocument([], {
+ _width: NumCast(layoutDoc._width) + 10,
+ _height: Math.max(NumCast(layoutDoc._height), NumCast(layoutDoc._width) + 10),
+ _isLightbox: true,
+ _layout_fitWidth: true,
+ title: StrCast(doc.title) + ' [Portal]',
+ }),
+ { link_relationship: 'portal to:portal from' }
+ );
+ }
+ doc.followLinkLocation = OpenWhere.lightbox;
+ doc.onClick = FollowLinkScript();
+ }
+
+ export function LeavePushpin(doc: Doc, annotationField: string) {
+ if (doc.followLinkToggle) return undefined;
+ const context = Cast(doc.embedContainer, Doc, null) ?? Cast(doc.annotationOn, Doc, null);
+ const hasContextAnchor = Doc.Links(doc).some(l => (l.link_anchor_2 === doc && Cast(l.link_anchor_1, Doc, null)?.annotationOn === context) || (l.link_anchor_1 === doc && Cast(l.link_anchor_2, Doc, null)?.annotationOn === context));
+ if (context && !hasContextAnchor && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) {
+ const pushpin = Docs.Create.FontIconDocument({
+ title: '',
+ annotationOn: Cast(doc.annotationOn, Doc, null),
+ followLinkToggle: true,
+ icon: 'map-pin',
+ x: Cast(doc.x, 'number', null),
+ y: Cast(doc.y, 'number', null),
+ backgroundColor: '#ACCEF7',
+ layout_hideAllLinks: true,
+ _width: 15,
+ _height: 15,
+ _xPadding: 0,
+ onClick: FollowLinkScript(),
+ _timecodeToShow: Cast(doc._timecodeToShow, 'number', null),
+ });
+ Doc.AddDocToList(context, annotationField, pushpin);
+ DocUtils.MakeLink(pushpin, doc, { link_relationship: 'pushpin' }, '');
+ doc._timecodeToShow = undefined;
+ return pushpin;
+ }
+ return undefined;
+ }
+
+ // /**
+ // *
+ // * @param dms Degree Minute Second format exif gps data
+ // * @param ref ref that determines negativity of decimal coordinates
+ // * @returns a decimal format of gps latitude / longitude
+ // */
+ // function getDecimalfromDMS(dms?: number[], ref?: string) {
+ // if (dms && ref) {
+ // let degrees = dms[0] / dms[1];
+ // let minutes = dms[2] / dms[3] / 60.0;
+ // let seconds = dms[4] / dms[5] / 3600.0;
+
+ // if (['S', 'W'].includes(ref)) {
+ // degrees = -degrees; minutes = -minutes; seconds = -seconds
+ // }
+ // return (degrees + minutes + seconds).toFixed(5);
+ // }
+ // }
+
+ function ConvertDMSToDD(degrees: number, minutes: number, seconds: number, direction: string) {
+ let dd = degrees + minutes / 60 + seconds / (60 * 60);
+ if (direction === 'S' || direction === 'W') {
+ dd *= -1;
+ } // Don't do anything for N or E
+ return dd;
+ }
+
+ export function assignImageInfo(result: Upload.FileInformation, protoIn: Doc) {
+ 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();
+ 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);
+ if (NumCast(proto.data_nativeOrientation) >= 5) {
+ proto.data_nativeHeight = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim;
+ proto.data_nativeWidth = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight);
+ }
+ proto.data_exif = JSON.stringify(result.exifData?.data);
+ proto.data_contentSize = result.contentSize;
+ // exif gps data coordinates are stored in DMS (Degrees Minutes Seconds), the following operation converts that to decimal coordinates
+ const latitude = result.exifData?.data?.GPSLatitude;
+ const latitudeDirection = result.exifData?.data?.GPSLatitudeRef;
+ const longitude = result.exifData?.data?.GPSLongitude;
+ const longitudeDirection = result.exifData?.data?.GPSLongitudeRef;
+ if (latitude !== undefined && longitude !== undefined && latitudeDirection !== undefined && longitudeDirection !== undefined) {
+ proto.latitude = ConvertDMSToDD(latitude[0], latitude[1], latitude[2], latitudeDirection);
+ proto.longitude = ConvertDMSToDD(longitude[0], longitude[1], longitude[2], longitudeDirection);
+ }
+ }
+ }
+
+ async function processFileupload(generatedDocuments: Doc[], name: string, type: string, result: Error | Upload.FileInformation, options: DocumentOptions, overwriteDoc?: Doc) {
+ if (result instanceof Error) {
+ alert(`Upload failed: ${result.message}`);
+ return;
+ }
+ const full = { ...options, _width: 400, title: name };
+ const pathname = result.accessPaths.agnostic.client;
+ const doc = await DocUtils.DocumentFromType(type, pathname, full, overwriteDoc);
+ if (doc) {
+ const proto = Doc.GetProto(doc);
+ proto.text = result.rawText;
+ !(result instanceof Error) && DocUtils.assignImageInfo(result, proto);
+ if (Upload.isVideoInformation(result)) {
+ proto.data_duration = result.duration;
+ }
+ if (overwriteDoc) {
+ Doc.removeCurrentlyLoading(overwriteDoc);
+ }
+ generatedDocuments.push(doc);
+ }
+ }
+
+ export function GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, annotationOn?: Doc, backgroundColor?: string) {
+ const defaultTextTemplate = DocCast(Doc.UserDoc().defaultTextLayout);
+ const tbox = Docs.Create.TextDocument('', {
+ annotationOn,
+ backgroundColor,
+ x,
+ y,
+ title,
+ ...(defaultTextTemplate
+ ? {} // if the new doc will inherit from a template, don't set any layout fields since that would block the inheritance
+ : {
+ _width: width || 200,
+ _height: 35,
+ _layout_centered: BoolCast(Doc.UserDoc()._layout_centered),
+ _layout_fitWidth: true,
+ _layout_autoHeight: true,
+ }),
+ });
+
+ if (defaultTextTemplate) {
+ tbox.layout_fieldKey = 'layout_' + StrCast(defaultTextTemplate.title);
+ Doc.GetProto(tbox)[StrCast(tbox.layout_fieldKey)] = defaultTextTemplate; // set the text doc's layout to render with the text template
+ tbox[DocData].proto = defaultTextTemplate; // and also set the text doc to inherit from the template (this allows the template to specify default field values)
+ }
+ return tbox;
+ }
+
+ export function uploadYoutubeVideoLoading(videoId: string, options: DocumentOptions, overwriteDoc?: Doc) {
+ const generatedDocuments: Doc[] = [];
+ Networking.UploadYoutubeToServer(videoId, overwriteDoc?.[Id]).then(upfiles => {
+ const {
+ source: { newFilename, mimetype },
+ result,
+ } = upfiles.lastElement();
+ if ((result as any).message) {
+ if (overwriteDoc) {
+ overwriteDoc.isLoading = false;
+ overwriteDoc.loadingError = (result as any).message;
+ Doc.removeCurrentlyLoading(overwriteDoc);
+ }
+ } else newFilename && processFileupload(generatedDocuments, newFilename, mimetype ?? '', result, options, overwriteDoc);
+ });
+ }
+
+ /**
+ * uploadFilesToDocs will take in an array of Files, and creates documents for the
+ * new files.
+ *
+ * @param files an array of files that will be uploaded
+ * @param options options to use while uploading
+ * @returns
+ */
+ export async function uploadFilesToDocs(files: File[], options: DocumentOptions) {
+ const generatedDocuments: Doc[] = [];
+
+ // These files do not have overwriteDocs, so we do not set the guid and let the client generate one.
+ const fileNoGuidPairs: Networking.FileGuidPair[] = files.map(file => ({ file }));
+
+ const upfiles = await Networking.UploadFilesToServer(fileNoGuidPairs);
+ upfiles.forEach(({ source: { newFilename, mimetype }, result }) => {
+ newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options);
+ });
+ return generatedDocuments;
+ }
+
+ export function uploadFileToDoc(file: File, options: DocumentOptions, overwriteDoc: Doc) {
+ const generatedDocuments: Doc[] = [];
+ // Since this file has an overwriteDoc, we can set the client tracking guid to the overwriteDoc's guid.
+ Networking.UploadFilesToServer([{ file, guid: overwriteDoc[Id] }]).then(upfiles => {
+ const {
+ source: { newFilename, mimetype },
+ result,
+ } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: { message: 'upload failed' } };
+ if ((result as any).message) {
+ if (overwriteDoc) {
+ overwriteDoc.loadingError = (result as any).message;
+ Doc.removeCurrentlyLoading(overwriteDoc);
+ }
+ } else newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc);
+ });
+ }
+
+ // copies the specified drag factory document
+ export function copyDragFactory(dragFactory: Doc) {
+ if (!dragFactory) return undefined;
+ const ndoc = dragFactory.isTemplateDoc ? Doc.ApplyTemplate(dragFactory) : Doc.MakeCopy(dragFactory, true);
+ if (ndoc && dragFactory.dragFactory_count !== undefined) {
+ dragFactory.dragFactory_count = NumCast(dragFactory.dragFactory_count) + 1;
+ Doc.SetInPlace(ndoc, 'title', ndoc.title + ' ' + NumCast(dragFactory.dragFactory_count).toString(), true);
+ }
+
+ return ndoc;
+ }
+ export function delegateDragFactory(dragFactory: Doc) {
+ const ndoc = Doc.MakeDelegateWithProto(dragFactory);
+ if (ndoc && dragFactory.dragFactory_count !== undefined) {
+ dragFactory.dragFactory_count = NumCast(dragFactory.dragFactory_count) + 1;
+ Doc.GetProto(ndoc).title = ndoc.title + ' ' + NumCast(dragFactory.dragFactory_count).toString();
+ }
+ return ndoc;
+ }
+
+ export async function Zip(doc: Doc, zipFilename = 'dashExport.zip') {
+ const { clone, map, linkMap } = await Doc.MakeClone(doc);
+ const proms = new Set<string>();
+ function replacer(key: any, value: any) {
+ if (key && ['branchOf', 'cloneOf', 'cursors'].includes(key)) return undefined;
+ if (value?.__type === 'image') {
+ const extension = value.url.replace(/.*\./, '');
+ proms.add(value.url.replace('.' + extension, '_o.' + extension));
+ return SerializationHelper.Serialize(new ImageField(value.url));
+ }
+ if (value?.__type === 'pdf') {
+ proms.add(value.url);
+ return SerializationHelper.Serialize(new PdfField(value.url));
+ }
+ if (value?.__type === 'audio') {
+ proms.add(value.url);
+ return SerializationHelper.Serialize(new AudioField(value.url));
+ }
+ if (value?.__type === 'video') {
+ proms.add(value.url);
+ return SerializationHelper.Serialize(new VideoField(value.url));
+ }
+ if (
+ value instanceof Doc ||
+ value instanceof ScriptField ||
+ value instanceof RichTextField ||
+ value instanceof InkField ||
+ value instanceof CsvField ||
+ value instanceof WebField ||
+ value instanceof DateField ||
+ value instanceof ProxyField ||
+ value instanceof ComputedField
+ ) {
+ return SerializationHelper.Serialize(value);
+ }
+ if (value instanceof Array && key !== ListFieldName && key !== InkDataFieldName) return { fields: value, __type: 'list' };
+ return value;
+ }
+
+ const docs: { [id: string]: any } = {};
+ const links: { [id: string]: any } = {};
+ Array.from(map.entries()).forEach(f => {
+ docs[f[0]] = f[1];
+ });
+ Array.from(linkMap.entries()).forEach(l => {
+ links[l[0]] = l[1];
+ });
+ const jsonDocs = JSON.stringify({ id: clone[Id], docs, links }, decycle(replacer));
+
+ const zip = new JSZip();
+ let count = 0;
+ const promArr = Array.from(proms)
+ .filter(url => url?.startsWith('/files'))
+ .map(url => url.replace('/', '')); // window.location.origin));
+ console.log(promArr.length);
+ if (!promArr.length) {
+ zip.file('docs.json', jsonDocs);
+ zip.generateAsync({ type: 'blob' }).then(content => saveAs(content, zipFilename));
+ } 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) => {
+ 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 });
+ console.log(' => ' + url);
+ if (++count === promArr.length) {
+ zip.file('docs.json', jsonDocs);
+ zip.generateAsync({ type: 'blob' }).then(content => saveAs(content, zipFilename));
+ // const a = document.createElement("a");
+ // const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`);
+ // a.href = url;
+ // a.download = `DocExport-${this.props.Document[Id]}.zip`;
+ // a.click();
+ }
+ });
+ });
+ }
+}
+
+export function FollowLinkScript() {
+ return ScriptField.MakeScript('return followLink(this,altKey)', { altKey: 'boolean' });
+}
+
+export function IsFollowLinkScript(field: FieldResult<FieldType>) {
+ return ScriptCast(field)?.script.originalScript.includes('return followLink(');
+}
+
+ScriptingGlobals.add('Docs', Docs);
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function copyDragFactory(dragFactory: Doc, asDelegate?: boolean) {
+ 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) {
+ const d = Docs.Create.DelegateDocument(proto, { title: 'child of ' + proto.title });
+ return d;
+});
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function generateLinkTitle(link: Doc) {
+ const linkAnchor1title = link.link_anchor_1 && link.link_anchor_1 !== link ? Cast(link.link_anchor_1, Doc, null)?.title : '<?>';
+ const linkAnchor2title = link.link_anchor_2 && link.link_anchor_2 !== link ? Cast(link.link_anchor_2, Doc, null)?.title : '<?>';
+ const relation = link.link_relationship || 'to';
+ return `${linkAnchor1title} (${relation}) ${linkAnchor2title}`;
+});
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 1123bcac9..8f95068db 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -12,6 +12,7 @@ export enum DocumentType {
REC = 'recording',
PDF = 'pdf',
INK = 'ink',
+ DIAGRAM = 'diagram',
SCREENSHOT = 'screenshot',
FONTICON = 'fonticonbox',
SEARCH = 'search', // search query
@@ -20,21 +21,20 @@ export enum DocumentType {
WEBCAM = 'webcam', // webcam
CONFIG = 'config', // configuration document intended to specify a view layout configuration, but not be directly rendered (e.g., for saving the page# of a PDF, or view transform of a collection)
SCRIPTING = 'script', // script editor
+ CHAT = 'chat', // chat with GPT about files
EQUATION = 'equation', // equation editor
FUNCPLOT = 'funcplot', // function plotter
MAP = 'map',
DATAVIZ = 'dataviz',
LOADING = 'loading',
- SIMULATION = 'simulation', //physics simulation
+ SIMULATION = 'simulation', // physics simulation
// special purpose wrappers that either take no data or are compositions of lower level types
LINK = 'link',
IMPORT = 'import',
PRES = 'presentation',
PRESELEMENT = 'preselement',
- YOUTUBE = 'youtube',
COMPARISON = 'comparison',
- GROUP = 'group',
PUSHPIN = 'pushpin',
MAPROUTE = 'maproute',
CALENDAR = 'calendar',
@@ -56,11 +56,11 @@ export enum CollectionViewType {
Carousel = 'carousel',
Carousel3D = '3D Carousel',
Linear = 'linear',
- //Staff = "staff",
Map = 'map',
Grid = 'grid',
Pile = 'pileup',
StackedTimeline = 'stacked timeline',
NoteTaking = 'notetaking',
- Calendar = 'calendar'
+ Calendar = 'calendar',
+ Card = 'card',
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index bf3d14560..1f9d4228f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,68 +1,26 @@
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
-import { action, reaction, runInAction } from 'mobx';
+/* eslint-disable prefer-destructuring */
+/* eslint-disable default-param-last */
+/* eslint-disable no-use-before-define */
+import { reaction } from 'mobx';
import { basename } from 'path';
+import { ClientUtils, OmitKeys } from '../../ClientUtils';
import { DateField } from '../../fields/DateField';
-import { Doc, DocListCast, Field, LinkedTo, Opt, StrListCast, updateCachedAcls } from '../../fields/Doc';
-import { DocData, Initializing } from '../../fields/DocSymbols';
-import { Id } from '../../fields/FieldSymbols';
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, CreateLinkToActiveAudio, Doc, FieldType, Opt, updateCachedAcls } from '../../fields/Doc';
+import { Initializing } from '../../fields/DocSymbols';
import { HtmlField } from '../../fields/HtmlField';
-import { InkField, PointData } from '../../fields/InkField';
+import { InkField } from '../../fields/InkField';
import { List } from '../../fields/List';
import { RichTextField } from '../../fields/RichTextField';
import { SchemaHeaderField } from '../../fields/SchemaHeaderField';
import { ComputedField, ScriptField } from '../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../fields/Types';
-import { AudioField, CsvField, ImageField, PdfField, VideoField, WebField, YoutubeField } from '../../fields/URLField';
-import { inheritParentAcls, SharingPermissions } from '../../fields/util';
-import { Upload } from '../../server/SharedMediaTypes';
-import { OmitKeys, Utils } from '../../Utils';
-import { YoutubeBox } from '../apis/youtube/YoutubeBox';
+import { ScriptCast, StrCast } from '../../fields/Types';
+import { AudioField, CsvField, ImageField, PdfField, VideoField, WebField } from '../../fields/URLField';
+import { SharingPermissions } from '../../fields/util';
+import { PointData } from '../../pen-gestures/GestureTypes';
import { DocServer } from '../DocServer';
-import { Networking } from '../Network';
-import { DragManager, dropActionType } from '../util/DragManager';
-import { FollowLinkScript } from '../util/LinkFollower';
-import { LinkManager } from '../util/LinkManager';
-import { ScriptingGlobals } from '../util/ScriptingGlobals';
-import { undoable, UndoManager } from '../util/UndoManager';
-import { CollectionDockingView } from '../views/collections/CollectionDockingView';
-import { DimUnit } from '../views/collections/collectionMulticolumn/CollectionMulticolumnView';
-import { CollectionView } from '../views/collections/CollectionView';
-import { ContextMenu } from '../views/ContextMenu';
-import { ContextMenuProps } from '../views/ContextMenuItem';
-import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke } from '../views/InkingStroke';
-import { AudioBox, media_state } from '../views/nodes/AudioBox';
-import { ComparisonBox } from '../views/nodes/ComparisonBox';
-import { DataVizBox } from '../views/nodes/DataVizBox/DataVizBox';
-import { EquationBox } from '../views/nodes/EquationBox';
-import { FieldViewProps } from '../views/nodes/FieldView';
-import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
-import { FormattedTextBox } from '../views/nodes/formattedText/FormattedTextBox';
-import { FunctionPlotBox } from '../views/nodes/FunctionPlotBox';
-import { ImageBox } from '../views/nodes/ImageBox';
-import { KeyValueBox } from '../views/nodes/KeyValueBox';
-import { LabelBox } from '../views/nodes/LabelBox';
-import { LinkBox } from '../views/nodes/LinkBox';
-import { LinkDescriptionPopup } from '../views/nodes/LinkDescriptionPopup';
-import { LoadingBox } from '../views/nodes/LoadingBox';
-import { MapBox } from '../views/nodes/MapBox/MapBox';
-import { MapPushpinBox } from '../views/nodes/MapBox/MapPushpinBox';
-import { PDFBox } from '../views/nodes/PDFBox';
-import { PhysicsSimulationBox } from '../views/nodes/PhysicsBox/PhysicsSimulationBox';
-import { RecordingBox } from '../views/nodes/RecordingBox/RecordingBox';
-import { ScreenshotBox } from '../views/nodes/ScreenshotBox';
-import { ScriptingBox } from '../views/nodes/ScriptingBox';
-import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
-import { PresBox } from '../views/nodes/trails/PresBox';
-import { PresElementBox } from '../views/nodes/trails/PresElementBox';
-import { VideoBox } from '../views/nodes/VideoBox';
-import { WebBox } from '../views/nodes/WebBox';
-import { SearchBox } from '../views/search/SearchBox';
+import { dropActionType } from '../util/DropActionTypes';
import { CollectionViewType, DocumentType } from './DocumentTypes';
-import { CalendarBox } from '../views/nodes/calendarBox/CalendarBox';
-import { OpenWhere } from '../views/nodes/DocumentView';
-const { default: { DFLT_IMAGE_NATIVE_DIM } } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore
-const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', ''));
class EmptyBox {
public static LayoutString() {
return '';
@@ -73,6 +31,7 @@ export enum FInfoFieldType {
string = 'string',
boolean = 'boolean',
number = 'number',
+ // eslint-disable-next-line @typescript-eslint/no-shadow
Doc = 'Doc',
enumeration = 'enum',
date = 'date',
@@ -83,7 +42,7 @@ export class FInfo {
description: string = '';
readOnly: boolean = false;
fieldType?: FInfoFieldType;
- values?: Field[];
+ values?: FieldType[];
filterable?: boolean = true; // can be used as a Filter in FilterPanel
// format?: string; // format to display values (e.g, decimal places, $, etc)
@@ -134,7 +93,7 @@ class DocInfo extends FInfo {
}
class DimInfo extends FInfo {
fieldType? = FInfoFieldType.enumeration;
- values? = [DimUnit.Pixel, DimUnit.Ratio];
+ values? = []; // DimUnit.Pixel, DimUnit.Ratio];
readOnly = false;
filterable = false;
override searchable = () => false;
@@ -175,7 +134,7 @@ class DateInfo extends FInfo {
}
class RtfInfo extends FInfo {
constructor(d: string, filterable?: boolean) {
- super(d, true);
+ super(d);
this.filterable = filterable;
}
fieldType? = FInfoFieldType.rtf;
@@ -190,7 +149,7 @@ type STRt = StrInfo | string;
type LISTt = ListInfo | List<any>;
type DOCt = DocInfo | Doc;
type RTFt = RtfInfo | RichTextField;
-type DIMt = DimInfo | typeof DimUnit.Pixel | typeof DimUnit.Ratio;
+type DIMt = DimInfo; // | typeof DimUnit.Pixel | typeof DimUnit.Ratio;
type PEVt = PEInfo | 'none' | 'all';
type COLLt = CTypeInfo | CollectionViewType;
type DROPt = DAInfo | dropActionType;
@@ -204,6 +163,7 @@ export class DocumentOptions {
overlayX?: NUMt = new NumInfo('horizontal coordinate in overlay view', false);
overlayY?: NUMt = new NumInfo('vertical coordinate in overlay view', false);
text?: RTFt = new RtfInfo('plain or rich text', true);
+ text_html?: STRt = new StrInfo('plain text or html', true);
_dimMagnitude?: NUMt = new NumInfo("magnitude of collectionMulti{row,col} element's width or height", false);
_dimUnit?: DIMt = new DimInfo("units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units");
latitude?: NUMt = new NumInfo('latitude coordinate', false);
@@ -220,6 +180,12 @@ export class DocumentOptions {
date_range?: STRt = new StrInfo('date range for calendar', false);
+ chat?: STRt = new StrInfo('fields related to chatBox', false);
+ chat_history?: STRt = new StrInfo('chat history for chatbox', false);
+ chat_thread_id?: STRt = new StrInfo('thread id for chatbox', false);
+ chat_assistant_id?: STRt = new StrInfo('assistant id for chatbox', false);
+ chat_vector_store_id?: STRt = new StrInfo('assistant id for chatbox', false);
+
wikiData?: STRt = new StrInfo('WikiData ID related to map location');
description?: STRt = new StrInfo('description of document');
_timecodeToShow?: NUMt = new NumInfo('media timecode when document should appear (e.g., when an annotation shows up as a video plays)', false);
@@ -232,14 +198,16 @@ export class DocumentOptions {
_nativeWidth?: NUMt = new NumInfo('native width of document contents (e.g., the pixel width of an image)', false);
_nativeHeight?: NUMt = new NumInfo('native height of document contents (e.g., the pixel height of an image)', false);
- 'acl-Guest'?: STRt = new StrInfo("permissions granted to users logged in as 'guest' (either view, or private)"); // public permissions
- '_acl-Guest'?: string; // public permissions
+ acl?: STRt = new StrInfo('unused except as a display category in KeyValueBox');
+ acl_Guest?: STRt = new StrInfo("permissions granted to users logged in as 'guest' (either view, or private)"); // public permissions
+ _acl_Guest?: string; // public permissions
type?: DTYPEt = new DTypeInfo('type of document', true);
type_collection?: COLLt = new CTypeInfo('how collection is rendered'); // sub type of a collection
_type_collection?: COLLt = new CTypeInfo('how collection is rendered'); // sub type of a collection
title?: STRt = new StrInfo('title of document', true);
title_custom?: BOOLt = new BoolInfo('whether title is a default or has been intentionally set');
caption?: RichTextField;
+ systemIcon?: STRt = new StrInfo("name of icon to use to represent document's type");
author?: string; // STRt = new StrInfo('creator of document'); // bcz: don't change this. Otherwise, the userDoc's field Infos will have a FieldInfo assigned to its author field which will render it unreadable
author_date?: DATEt = new DateInfo('date the document was created', true);
annotationOn?: DOCt = new DocInfo('document annotated by this document', false);
@@ -251,14 +219,20 @@ export class DocumentOptions {
opacity?: NUMt = new NumInfo('document opacity', false);
viewTransitionTime?: NUMt = new NumInfo('transition duration for view parameters', false);
dontRegisterView?: BOOLt = new BoolInfo('are views of this document registered so that they can be found when following links, etc', false);
- _undoIgnoreFields?: List<string>; //'fields that should not be added to the undo stack (opacity for Undo/Redo/and sidebar) AND whether modifications to document are undoable (true for linearview menu buttons to prevent open/close from entering undo stack)'
- undoIgnoreFields?: List<string>; //'fields that should not be added to the undo stack (opacity for Undo/Redo/and sidebar) AND whether modifications to document are undoable (true for linearview menu buttons to prevent open/close from entering undo stack)'
- _headerHeight?: NUMt = new NumInfo('height of document header used for displaying title', false);
- _headerFontSize?: NUMt = new NumInfo('font size of header of custom notes', false);
- _headerPointerEvents?: PEVt = new PEInfo('types of events the header of a custom text document can consume');
+ _undoIgnoreFields?: List<string>; // 'fields that should not be added to the undo stack (opacity for Undo/Redo/and sidebar) AND whether modifications to document are undoable (true for linearview menu buttons to prevent open/close from entering undo stack)'
+ undoIgnoreFields?: List<string>; // 'fields that should not be added to the undo stack (opacity for Undo/Redo/and sidebar) AND whether modifications to document are undoable (true for linearview menu buttons to prevent open/close from entering undo stack)'
+ _header_height?: NUMt = new NumInfo('height of document header used for displaying title', false);
+ _header_fontSize?: NUMt = new NumInfo('font size of header of custom notes', false);
+ _header_pointerEvents?: PEVt = new PEInfo('types of events the header of a custom text document can consume');
_lockedPosition?: BOOLt = new BoolInfo("lock the x,y coordinates of the document so that it can't be dragged");
_lockedTransform?: BOOLt = new BoolInfo('lock the freeform_panx,freeform_pany and scale parameters of the document so that it be panned/zoomed');
+ dataViz_title?: string;
+ dataViz_line?: string;
+ dataViz_pie?: string;
+ dataViz_histogram?: string;
+ dataViz?: string;
+
layout?: string | Doc; // default layout string or template document
layout_isSvg?: BOOLt = new BoolInfo('whether document decorations and other selections should handle pointerEvents for svg content or use doc bounding box');
layout_keyValue?: STRt = new StrInfo('layout definition for showing keyValue view of document', false);
@@ -273,8 +247,11 @@ export class DocumentOptions {
layout_hideResizeHandles?: BOOLt = new BoolInfo('whether to hide the resize handles when selected');
layout_hideLinkButton?: BOOLt = new BoolInfo('whether the blue link counter button should be hidden');
layout_hideDecorationTitle?: BOOLt = new BoolInfo('whether to suppress the document decortations title when selected');
+ _layout_hideContextMenu?: BOOLt = new BoolInfo('whether the context menu can be shown');
+ layout_diagramEditor?: STRt = new StrInfo('specify the JSX string for a diagram editor view');
layout_hideContextMenu?: BOOLt = new BoolInfo('whether the context menu can be shown');
layout_borderRounding?: string;
+ _layout_borderRounding?: STRt = new StrInfo('amount of rounding to document view corners');
_layout_modificationDate?: DATEt = new DateInfo('last modification date of doc layout', false);
_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"');
@@ -282,6 +259,7 @@ export class DocumentOptions {
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');
+ _layout_autoHeightMargins?: NUMt = new NumInfo('Margin heights to be added to the computed auto height of a Doc');
_layout_curPage?: NUMt = new NumInfo('current page of a PDF or other? paginated document', false);
_layout_currentTimecode?: NUMt = new NumInfo('the current timecode of a time-based document (e.g., current time of a video) value is in seconds', false);
_layout_centered?: BOOLt = new BoolInfo('whether text should be vertically centered in Doc');
@@ -311,6 +289,7 @@ export class DocumentOptions {
_text_fontSize?: string;
_text_fontFamily?: string;
_text_fontWeight?: string;
+ fontSize?: string;
_pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views
infoWindowOpen?: BOOLt = new BoolInfo('whether info window corresponding to pin is open (on MapDocuments)');
@@ -318,7 +297,8 @@ export class DocumentOptions {
_label_minFontSize?: NUMt = new NumInfo('minimum font size for labelBoxes', false);
_label_maxFontSize?: NUMt = new NumInfo('maximum font size for labelBoxes', false);
stroke_width?: NUMt = new NumInfo('width of an ink stroke', false);
- mediaState?: STRt = new StrInfo(`status of audio/video media document: ${media_state.PendingRecording}, ${media_state.Recording}, ${media_state.Paused}, ${media_state.Playing}`, false);
+ stroke_showLabel?: BOOLt = new BoolInfo('show label inside of stroke');
+ mediaState?: STRt = new StrInfo(`status of audio/video media document:`); // ${mediaState.PendingRecording}, ${mediaState.Recording}, ${mediaState.Paused}, ${mediaState.Playing}`, false);
recording?: BOOLt = new BoolInfo('whether WebCam is recording or not');
slides?: DOCt = new DocInfo('presentation slide associated with video recording (bcz: should be renamed!!)');
autoPlayAnchors?: BOOLt = new BoolInfo('whether to play audio/video when an anchor is clicked in a stackedTimeline.');
@@ -372,6 +352,7 @@ export class DocumentOptions {
config_map?: STRt = new StrInfo('text location of map', false);
config_panX?: NUMt = new NumInfo('panX saved as a view spec', false);
config_panY?: NUMt = new NumInfo('panY saved as a view spec', false);
+ config_zoom?: NUMt = new NumInfo('zoom saved as a view spec', false);
config_viewScale?: NUMt = new NumInfo('viewScale saved as a view Spec', false);
presentation_transition?: NUMt = new NumInfo('the time taken for the transition TO a document', false);
presentation_duration?: NUMt = new NumInfo('the duration of the slide in presentation view', false);
@@ -388,6 +369,7 @@ export class DocumentOptions {
// STOPPING HERE
// freeform properties
+ freeform?: STRt = new StrInfo('');
_freeform_backgroundGrid?: BOOLt = new BoolInfo('whether background grid is shown on freeform collections');
_freeform_scale_min?: NUMt = new NumInfo('how far out a view can zoom (used by image/videoBoxes that are clipped');
_freeform_scale_max?: NUMt = new NumInfo('how far in a view can zoom (used by sidebar freeform views');
@@ -398,7 +380,7 @@ export class DocumentOptions {
_freeform_noZoom?: BOOLt = new BoolInfo('disables zooming (used by Pile docs)');
_freeform_fitContentsToBox?: BOOLt = new BoolInfo('whether a freeformview should zoom/scale to create a shrinkwrapped view of its content');
- //BUTTONS
+ // BUTTONS
buttonText?: string;
btnType?: string;
btnList?: List<string>;
@@ -410,7 +392,7 @@ export class DocumentOptions {
switchToggle?: boolean;
badgeValue?: ScriptField;
- //LINEAR VIEW
+ // LINEAR VIEW
linearView_IsOpen?: BOOLt = new BoolInfo('is linear view open');
linearView_Expandable?: BOOLt = new BoolInfo('can linear view be expanded');
linearView_Dropdown?: BOOLt = new BoolInfo('can linear view be opened as a dropdown');
@@ -418,9 +400,9 @@ export class DocumentOptions {
flexGap?: NUMt = new NumInfo('Linear view flex gap');
flexDirection?: 'unset' | 'row' | 'column' | 'row-reverse' | 'column-reverse';
+ link?: string;
link_description?: string; // added for links
link_relationship?: string; // type of relatinoship a link represents
- link_displayLine?: BOOLt = new BoolInfo('whether a link line should be dipslayed between the two link anchors');
link_displayArrow?: BOOLt = new BoolInfo("whether to display link's directional arrowhead");
link_anchor_1?: DOCt = new DocInfo('start anchor of a link');
link_anchor_2?: DOCt = new DocInfo('end anchor of a link');
@@ -428,7 +410,7 @@ export class DocumentOptions {
link_anchor_1_useSmallAnchor?: BOOLt = new BoolInfo('whether link_anchor_1 of a link should use a miniature anchor dot (as when the anchor is a text selection)');
link_anchor_2_useSmallAnchor?: BOOLt = new BoolInfo('whether link_anchor_1 of a link should use a miniature anchor dot (as when the anchor is a text selection)');
link_relationshipList?: List<string>; // for storing different link relationships (when set by user in the link editor)
- link_relationshipSizes?: List<number>; //stores number of links contained in each relationship
+ link_relationshipSizes?: List<number>; // stores number of links contained in each relationship
link_colorList?: List<string>; // colors of links corresponding to specific link relationships
followLinkZoom?: BOOLt = new BoolInfo('whether to zoom to the target of a link');
followLinkToggle?: BOOLt = new BoolInfo('whether target of link should be toggled on and off when following a link to it');
@@ -460,7 +442,7 @@ export class DocumentOptions {
dragFactory_count?: NUMt = new NumInfo('number of items created from a drag button (used for setting title with incrementing index)', false, true);
dragFactory?: DOCt = new DocInfo('document to create when dragging with a suitable onDragStart script', false);
clickFactory?: DOCt = new DocInfo('document to create when clicking on a button with a suitable onClick script', false);
- onDragStart?: ScriptField; //script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop
+ onDragStart?: ScriptField; // script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop
target?: Doc; // available for use in scripts. used to provide a document parameter to the script (Note, this is a convenience entry since any field could be used for parameterizing a script)
tags?: LISTt = new ListInfo('hashtags added to document, typically using a text view', true);
treeView_HideTitle?: BOOLt = new BoolInfo('whether to hide the top document title of a tree view');
@@ -495,12 +477,14 @@ export class DocumentOptions {
hoverBackgroundColor?: string; // background color of a label when hovered
userBackgroundColor?: STRt = new StrInfo('background color associated with a Dash user (seen in header fields of shared documents)');
userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)');
+
+ cardSort?: STRt = new StrInfo('way cards are sorted in deck view');
+ cardSort_customField?: STRt = new StrInfo('field key used for sorting cards');
+ cardSort_visibleSortGroups?: List<number>; // which sorting values are being filtered (shown)
}
export const DocOptions = new DocumentOptions();
export namespace Docs {
- export let newAccount: boolean = false;
-
export namespace Prototypes {
type LayoutSource = { LayoutString: (key: string) => string };
type PrototypeTemplate = {
@@ -515,117 +499,12 @@ export namespace Docs {
type PrototypeMap = Map<DocumentType, Doc>;
const defaultDataKey = 'data';
- const TemplateMap: TemplateMap = new Map([
- [
- DocumentType.RTF,
- {
- layout: { view: FormattedTextBox, dataField: 'text' },
- options: {
- _height: 35,
- _xMargin: 10,
- _yMargin: 10,
- layout_nativeDimEditable: true,
- layout_reflowVertical: true,
- layout_reflowHorizontal: true,
- defaultDoubleClick: 'ignore',
- systemIcon: 'BsFileEarmarkTextFill',
- },
- },
- ],
- [
- DocumentType.SEARCH,
- {
- layout: { view: SearchBox, dataField: defaultDataKey },
- options: { _width: 400 },
- },
- ],
- [
- DocumentType.IMG,
- {
- layout: { view: ImageBox, dataField: defaultDataKey },
- options: { freeform: '', systemIcon: 'BsFileEarmarkImageFill' },
- },
- ],
- [
- DocumentType.WEB,
- {
- layout: { view: WebBox, dataField: defaultDataKey },
- options: { _height: 300, _layout_fitWidth: true, layout_nativeDimEditable: true, layout_reflowVertical: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' },
- },
- ],
- [
- DocumentType.COL,
- {
- layout: { view: CollectionView, dataField: defaultDataKey },
- options: {
- _layout_fitWidth: true,
- freeform: '',
- _freeform_panX: 0,
- _freeform_panY: 0,
- _freeform_scale: 1,
- layout_nativeDimEditable: true,
- layout_reflowHorizontal: true,
- layout_reflowVertical: true,
- systemIcon: 'BsFillCollectionFill',
- },
- },
- ],
- [
- DocumentType.KVP,
- {
- layout: { view: KeyValueBox, dataField: defaultDataKey },
- options: { _layout_fitWidth: true, _height: 150 },
- },
- ],
- [
- DocumentType.VID,
- {
- layout: { view: VideoBox, dataField: defaultDataKey },
- options: { _layout_currentTimecode: 0, systemIcon: 'BsFileEarmarkPlayFill' },
- },
- ],
- [
- DocumentType.AUDIO,
- {
- layout: { view: AudioBox, dataField: defaultDataKey },
- options: { _height: 100, layout_fitWidth: true, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsFillVolumeUpFill' },
- },
- ],
- [
- DocumentType.REC,
- {
- layout: { view: VideoBox, dataField: defaultDataKey },
- options: { _height: 100, backgroundColor: 'pink', systemIcon: 'BsFillMicFill' },
- },
- ],
- [
- DocumentType.PDF,
- {
- layout: { view: PDFBox, dataField: defaultDataKey },
- options: { _layout_curPage: 1, _layout_fitWidth: true, layout_nativeDimEditable: true, layout_reflowVertical: true, systemIcon: 'BsFileEarmarkPdfFill' },
- },
- ],
+ export const TemplateMap: TemplateMap = new Map([
[
- DocumentType.MAP,
- {
- layout: { view: MapBox, dataField: defaultDataKey },
- options: { map: '', _height: 600, _width: 800, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsFillPinMapFill' },
- },
- ],
- [
- DocumentType.LINK,
+ DocumentType.GROUPDB,
{
- layout: { view: LinkBox, dataField: 'link' },
- options: {
- childDontRegisterViews: true,
- layout_hideLinkAnchors: true,
- _height: 1,
- _width: 1,
- link: '',
- link_description: '',
- color: 'lightBlue', // lightblue is default color for linking dot and link documents text comment area
- _dropPropertiesToRemove: new List(['onClick']),
- },
+ layout: { view: EmptyBox, dataField: defaultDataKey },
+ options: { acl: '', title: 'Global Group Database' },
},
],
[
@@ -633,195 +512,22 @@ export namespace Docs {
{
data: new List<Doc>(),
layout: { view: EmptyBox, dataField: defaultDataKey },
- options: { title: 'Global Script Database' },
- },
- ],
- [
- DocumentType.SCRIPTING,
- {
- layout: { view: ScriptingBox, dataField: defaultDataKey },
- options: { systemIcon: 'BsFileEarmarkCodeFill' },
- },
- ],
- [
- DocumentType.YOUTUBE,
- {
- layout: { view: YoutubeBox, dataField: defaultDataKey },
- },
- ],
- [
- DocumentType.LABEL,
- {
- layout: { view: LabelBox, dataField: 'title' },
- options: { _singleLine: true, layout_nativeDimEditable: true, layout_reflowHorizontal: true, layout_reflowVertical: true },
- },
- ],
- [
- DocumentType.EQUATION,
- {
- layout: { view: EquationBox, dataField: 'text' },
- options: {
- fontSize: '14px',
- layout_reflowHorizontal: true,
- layout_reflowVertical: true,
- layout_nativeDimEditable: true,
- layout_hideDecorationTitle: true,
- systemIcon: 'BsCalculatorFill',
- }, ///systemIcon: 'BsSuperscript' + BsSubscript
- },
- ],
- [
- DocumentType.FUNCPLOT,
- {
- layout: { view: FunctionPlotBox, dataField: defaultDataKey },
- options: {
- layout_reflowHorizontal: true,
- layout_reflowVertical: true,
- layout_nativeDimEditable: true,
- },
- },
- ],
- [
- DocumentType.BUTTON,
- {
- layout: { view: LabelBox, dataField: 'title' },
- options: { layout_nativeDimEditable: true, layout_reflowHorizontal: true, layout_reflowVertical: true },
- },
- ],
- [
- DocumentType.PRES,
- {
- layout: { view: PresBox, dataField: defaultDataKey },
- options: { defaultDoubleClick: 'ignore', hideClickBehaviors: true, layout_hideLinkAnchors: true },
- },
- ],
- [
- DocumentType.FONTICON,
- {
- layout: { view: FontIconBox, dataField: 'icon' },
- options: { defaultDoubleClick: 'ignore', waitForDoubleClickToClick: 'never', layout_hideContextMenu: true, layout_hideLinkButton: true, _width: 40, _height: 40 },
- },
- ],
- [
- DocumentType.WEBCAM,
- {
- layout: { view: RecordingBox, dataField: defaultDataKey },
- options: { systemIcon: 'BsFillCameraVideoFill' },
- },
- ],
- [
- DocumentType.PRESELEMENT,
- {
- layout: { view: PresElementBox, dataField: defaultDataKey },
- options: { title: 'pres element template', _layout_fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: 'data' },
+ options: { acl: '', title: 'Global Script Database' },
},
],
+
[
DocumentType.CONFIG,
{
- layout: { view: CollectionView, dataField: defaultDataKey },
- options: { config: '', layout_hideLinkButton: true, layout_unrendered: true },
- },
- ],
- [
- DocumentType.INK,
- {
- // NOTE: this is unused!! ink fields are filled in directly within the InkDocument() method
- layout: { view: InkingStroke, dataField: 'stroke' },
- options: {
- systemIcon: 'BsFillPencilFill', //
- layout_nativeDimEditable: true,
- layout_reflowVertical: true,
- layout_reflowHorizontal: true,
- layout_hideDecorationTitle: true, // don't show title when selected
- fitWidth: false,
- layout_isSvg: true,
- },
- },
- ],
- [
- DocumentType.SCREENSHOT,
- {
- layout: { view: ScreenshotBox, dataField: defaultDataKey },
- options: { layout_nativeDimEditable: true, systemIcon: 'BsCameraFill' },
- },
- ],
- [
- DocumentType.COMPARISON,
- {
- data: '',
- layout: { view: ComparisonBox, dataField: defaultDataKey },
- options: { backgroundColor: 'gray', dropAction: dropActionType.move, waitForDoubleClickToClick: 'always', layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsLayoutSplit' },
- },
- ],
- [
- DocumentType.GROUPDB,
- {
layout: { view: EmptyBox, dataField: defaultDataKey },
- options: { title: 'Global Group Database' },
- },
- ],
- [
- DocumentType.GROUP,
- {
- layout: { view: EmptyBox, dataField: defaultDataKey },
- options: {},
- },
- ],
- [
- DocumentType.DATAVIZ,
- {
- layout: { view: DataVizBox, dataField: defaultDataKey },
- options: { dataViz_title: '', dataViz_line: '', dataViz_pie: '', dataViz_histogram: '', dataViz: 'table', _layout_fitWidth: true, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true },
- },
- ],
- [
- DocumentType.LOADING,
- {
- layout: { view: LoadingBox, dataField: '' },
- options: { _layout_fitWidth: true, _fitHeight: true, layout_nativeDimEditable: true },
- },
- ],
- [
- DocumentType.SIMULATION,
- {
- data: '',
- layout: { view: PhysicsSimulationBox, dataField: defaultDataKey, _width: 1000, _height: 800 },
- options: {
- _height: 100,
- mass1: '',
- mass2: '',
- layout_nativeDimEditable: true,
- position: '',
- acceleration: '',
- pendulum: '',
- spring: '',
- wedge: '',
- simulation: '',
- review: '',
- systemIcon: 'BsShareFill',
- },
- },
- ],
- [
- DocumentType.PUSHPIN,
- {
- layout: { view: MapPushpinBox, dataField: defaultDataKey },
- options: {},
+ options: { acl: '', config: '', layout_hideLinkButton: true, layout_unrendered: true },
},
],
[
DocumentType.MAPROUTE,
{
- layout: { view: CollectionView, dataField: defaultDataKey },
- options: {},
- },
- ],
- [
- DocumentType.CALENDAR,
- {
- layout: { view: CalendarBox, dataField: defaultDataKey },
- options: {},
+ layout: { view: EmptyBox, dataField: defaultDataKey },
+ options: { acl: '' },
},
],
]);
@@ -847,7 +553,7 @@ export namespace Docs {
// fetch the actual prototype documents from the server
const actualProtos = await DocServer.GetRefFields(prototypeIds);
// update this object to include any default values: DocumentOptions for all prototypes
- prototypeIds.map(id => {
+ prototypeIds.forEach(id => {
const existing = actualProtos[id] as Doc;
const type = id.replace(suffix, '') as DocumentType;
// get or create prototype of the specified type...
@@ -905,7 +611,7 @@ export namespace Docs {
if (!template) {
return undefined;
}
- const layout = template.layout;
+ const { layout } = template;
// create title
const upper = suffix.toUpperCase();
const title = prototypeId.toUpperCase().replace(upper, `_${upper}`);
@@ -917,17 +623,15 @@ export namespace Docs {
title,
type,
isBaseProto: true,
- x: 0,
- y: 0,
_width: 300,
- 'acl-Guest': SharingPermissions.View,
+ 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('@'))
- .map(pair => {
+ .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));
}
@@ -959,15 +663,17 @@ export namespace Docs {
* only when creating a DockDocument from the current user's already existing
* main document.
*/
- function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = 'data', protoId?: string, placeholderDoc?: Doc, noView?: boolean) {
+ // eslint-disable-next-line default-param-last
+ 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, '^_');
- // dataProps['acl-Override'] = SharingPermissions.Unset;
- dataProps['acl-Guest'] = options['acl-Guest'] ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View);
+ // dataProps.acl_Override = SharingPermissions.Unset;
+ dataProps.acl_Guest = options.acl_Guest ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View);
dataProps.isSystem = viewProps.isSystem;
dataProps.isDataDoc = true;
- dataProps.author = Doc.CurrentUserEmail;
+ dataProps.author = ClientUtils.CurrentUserEmail();
dataProps.author_date = new DateField();
if (fieldKey) {
dataProps[`${fieldKey}_modificationDate`] = new DateField();
@@ -987,8 +693,8 @@ export namespace Docs {
}
if (!noView) {
- const viewFirstProps: { [id: string]: any } = { author: Doc.CurrentUserEmail };
- viewFirstProps['acl-Guest'] = options['_acl-Guest'] ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View);
+ const viewFirstProps: { [id: string]: any } = { 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
if (placeholderDoc) {
@@ -996,14 +702,16 @@ export namespace Docs {
placeholderDoc._width = options._width !== undefined ? Number(options._width) : undefined;
viewDoc = Doc.assign(placeholderDoc, viewFirstProps, true, true);
Array.from(Object.keys(placeholderDoc))
- .filter(key => key.startsWith('acl'))
- .forEach(key => (dataDoc[key] = viewDoc[key] = placeholderDoc[key]));
+ .filter(key => key.startsWith('acl_'))
+ .forEach(key => {
+ dataDoc[key] = viewDoc[key] = placeholderDoc[key];
+ });
} else {
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)) {
- DocUtils.MakeLinkToActiveAudio(() => viewDoc);
+ CreateLinkToActiveAudio(() => viewDoc);
}
updateCachedAcls(dataDoc);
updateCachedAcls(viewDoc);
@@ -1016,9 +724,10 @@ export namespace Docs {
return dataDoc;
}
+ // eslint-disable-next-line default-param-last
export function ImageDocument(url: string | ImageField, options: DocumentOptions = {}, overwriteDoc?: Doc) {
- const imgField = url instanceof ImageField ? url : new ImageField(url);
- return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(imgField.url.href), ...options }, undefined, undefined, undefined, overwriteDoc);
+ const imgField = url instanceof ImageField ? url : url ? new ImageField(url) : undefined;
+ return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(imgField?.url.href ?? '-no image-'), ...options }, undefined, undefined, undefined, overwriteDoc);
}
export function PresDocument(options: DocumentOptions = {}) {
@@ -1034,18 +743,19 @@ export namespace Docs {
* @param fieldKey the field that the compiled script is written into.
* @returns the Scripting Doc
*/
+ // eslint-disable-next-line default-param-last
export function ScriptingDocument(script: Opt<ScriptField> | null, options: DocumentOptions = {}, fieldKey?: string) {
- return InstanceFromProto(Prototypes.get(DocumentType.SCRIPTING), script ? script : undefined, { ...options, layout: fieldKey ? ScriptingBox.LayoutString(fieldKey) : undefined });
+ return InstanceFromProto(Prototypes.get(DocumentType.SCRIPTING), script || undefined, { ...options, layout: fieldKey ? `<ScriptingBox {...props} fieldKey={'${fieldKey}'}/>` /* ScriptingBox.LayoutString(fieldKey) */ : undefined });
}
+ export function ChatDocument(options?: DocumentOptions) {
+ return InstanceFromProto(Prototypes.get(DocumentType.CHAT), undefined, { ...(options || {}) });
+ }
+ // eslint-disable-next-line default-param-last
export function VideoDocument(url: string, options: DocumentOptions = {}, overwriteDoc?: Doc) {
return InstanceFromProto(Prototypes.get(DocumentType.VID), new VideoField(url), options, undefined, undefined, undefined, overwriteDoc);
}
- export function YoutubeDocument(url: string, options: DocumentOptions = {}, overwriteDoc?: Doc) {
- return InstanceFromProto(Prototypes.get(DocumentType.YOUTUBE), new YoutubeField(url), options, undefined, undefined, undefined, overwriteDoc);
- }
-
export function WebCamDocument(url: string, options: DocumentOptions = {}) {
return InstanceFromProto(Prototypes.get(DocumentType.WEBCAM), '', options);
}
@@ -1057,7 +767,11 @@ export namespace Docs {
export function ComparisonDocument(text: string, options: DocumentOptions = { title: 'Comparison Box' }) {
return InstanceFromProto(Prototypes.get(DocumentType.COMPARISON), text, options);
}
+ export function DiagramDocument(options: DocumentOptions = { title: 'bruh box' }) {
+ return InstanceFromProto(Prototypes.get(DocumentType.DIAGRAM), undefined, options);
+ }
+ // eslint-disable-next-line default-param-last
export function AudioDocument(url: string, options: DocumentOptions = {}, overwriteDoc?: Doc) {
return InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(url), options, undefined, undefined, undefined, overwriteDoc);
}
@@ -1071,7 +785,7 @@ export namespace Docs {
}
export function LoadingDocument(file: File | string, options: DocumentOptions) {
- return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file == 'string' ? file : file.name, ...options }, undefined, '');
+ return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file === 'string' ? file : file.name, ...options }, undefined, '');
}
export function RTFDocument(field: RichTextField, options: DocumentOptions = {}, fieldKey: string = 'text') {
@@ -1100,6 +814,7 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.RTF), field, options, undefined, fieldKey);
}
+ // eslint-disable-next-line default-param-last
export function LinkDocument(source: Doc, target: Doc, options: DocumentOptions = {}, id?: string) {
const linkDoc = InstanceFromProto(
Prototypes.get(DocumentType.LINK),
@@ -1113,7 +828,7 @@ export namespace Docs {
'link'
);
- LinkManager.Instance.addLink(linkDoc);
+ Doc.AddLink(linkDoc);
return linkDoc;
}
@@ -1123,7 +838,7 @@ export namespace Docs {
options: DocumentOptions = {},
strokeWidth = ActiveInkWidth(),
color = ActiveInkColor(),
- stroke_bezier = ActiveInkBezierApprox(),
+ strokeBezier = ActiveInkBezierApprox(),
fillColor = ActiveFillColor(),
arrowStart = ActiveArrowStart(),
arrowEnd = ActiveArrowEnd(),
@@ -1137,7 +852,7 @@ export namespace Docs {
I.fillColor = fillColor;
I.stroke = new InkField(points);
I.stroke_width = strokeWidth;
- I.stroke_bezier = stroke_bezier;
+ I.stroke_bezier = strokeBezier;
I.stroke_startMarker = arrowStart;
I.stroke_endMarker = arrowEnd;
I.stroke_dash = dash;
@@ -1146,13 +861,14 @@ export namespace Docs {
I.rotation = 0;
I.defaultDoubleClick = 'ignore';
I.author_date = new DateField();
- I['acl-Guest'] = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View;
- //I['acl-Override'] = SharingPermissions.Unset;
+ I.acl_Guest = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View;
+ // I.acl_Override = SharingPermissions.Unset;
I[Initializing] = false;
return ink;
}
+ // eslint-disable-next-line default-param-last
export function PdfDocument(url: string, options: DocumentOptions = {}, overwriteDoc?: Doc) {
const width = options._width || undefined;
const height = options._height || undefined;
@@ -1168,7 +884,7 @@ export namespace Docs {
const nwid = options._nativeWidth || undefined;
const nhght = options._nativeHeight || undefined;
if (!nhght && width && height && nwid) options._nativeHeight = (Number(nwid) * Number(height)) / Number(width);
- return InstanceFromProto(Prototypes.get(DocumentType.WEB), new WebField(url ? url : 'https://www.wikipedia.org/'), options);
+ return InstanceFromProto(Prototypes.get(DocumentType.WEB), new WebField(url || 'https://www.wikipedia.org/'), options);
}
export function HtmlDocument(html: string, options: DocumentOptions = {}) {
@@ -1206,10 +922,6 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id, '', undefined, undefined, true);
}
- export function HTMLMarkerDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
- return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Freeform }, id);
- }
-
export function PileDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
return InstanceFromProto(
Prototypes.get(DocumentType.COL),
@@ -1235,6 +947,10 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Carousel3D });
}
+ export function CardDeckDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
+ return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Card });
+ }
+
export function SchemaDocument(schemaHeaders: SchemaHeaderField[], documents: Array<Doc>, options: DocumentOptions) {
return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaHeaders: new List(schemaHeaders), ...options, _type_collection: CollectionViewType.Schema });
}
@@ -1309,34 +1025,6 @@ export namespace Docs {
return ret;
}
- export type DocConfig = {
- doc: Doc;
- initialWidth?: number;
- path?: Doc[];
- };
-
- export function StandardCollectionDockingDocument(configs: Array<DocConfig>, options: DocumentOptions, id?: string, type: string = 'row') {
- const layoutConfig = {
- content: [
- {
- type: type,
- content: [...configs.map(config => CollectionDockingView.makeDocumentConfig(config.doc, undefined, config.initialWidth))],
- },
- ],
- };
- const doc = DockDocument(
- configs.map(c => c.doc),
- JSON.stringify(layoutConfig),
- Doc.CurrentUserEmail === 'guest' ? options : { 'acl-Guest': SharingPermissions.View, ...options },
- id
- );
- configs.map(c => {
- Doc.SetContainer(c.doc, doc);
- inheritParentAcls(doc, c.doc, false);
- });
- return doc;
- }
-
export function DelegateDocument(proto: Doc, options: DocumentOptions = {}) {
return InstanceFromProto(proto, undefined, options);
}
@@ -1346,760 +1034,3 @@ export namespace Docs {
}
}
}
-
-export namespace DocUtils {
- function matchFieldValue(doc: Doc, key: string, value: any): boolean {
- const hasFunctionFilter = Utils.HasFunctionFilter(value);
- if (hasFunctionFilter) {
- return hasFunctionFilter(StrCast(doc[key]));
- }
- if (key === LinkedTo) {
- // links are not a field value, so handled here. value is an expression of form ([field=]idToDoc("..."))
- const allLinks = LinkManager.Instance.getAllRelatedLinks(doc);
- const matchLink = (value: string, anchor: Doc) => {
- const linkedToExp = (value ?? '').split('=');
- if (linkedToExp.length === 1) return Field.toScriptString(anchor) === value;
- return Field.toScriptString(DocCast(anchor[linkedToExp[0]])) === linkedToExp[1];
- };
- // 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)) ));
- }
- if (typeof value === 'string') {
- value = value.replace(`,${Utils.noRecursionHack}`, '');
- }
- const fieldVal = doc[key];
- // prettier-ignore
- if ((value === Doc.FilterAny && fieldVal !== undefined) ||
- (value === Doc.FilterNone && fieldVal === undefined)) {
- return true;
- }
- 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 Field.toString(fieldVal as Field).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
- }
- /**
- * @param docs
- * @param childFilters
- * @param childFiltersByRanges
- * @param parentCollection
- * Given a list of docs and childFilters, @returns the list of Docs that match those filters
- */
- export function FilterDocs(childDocs: Doc[], childFilters: string[], childFiltersByRanges: string[], parentCollection?: Doc) {
- if (!childFilters?.length && !childFiltersByRanges?.length) {
- return childDocs.filter(d => !d.cookies); // remove documents that need a cookie if there are no filters to provide one
- }
-
- const filterFacets: { [key: string]: { [value: string]: string } } = {}; // maps each filter key to an object with value=>modifier fields
- childFilters.forEach(filter => {
- const fields = filter.split(Doc.FilterSep);
- const key = fields[0];
- const value = fields[1];
- const modifiers = fields[2];
- if (!filterFacets[key]) {
- filterFacets[key] = {};
- }
- filterFacets[key][value] = modifiers;
- });
-
- const filteredDocs = childFilters.length
- ? childDocs.filter(d => {
- if (d.z) return true;
- // if the document needs a cookie but no filter provides the cookie, then the document does not pass the filter
- if (d.cookies && (!filterFacets.cookies || !Object.keys(filterFacets.cookies).some(key => d.cookies === key))) {
- return false;
- }
- for (const facetKey of Object.keys(filterFacets).filter(fkey => fkey !== 'cookies' && fkey !== Utils.noDragDocsFilter.split(Doc.FilterSep)[0])) {
- const facet = filterFacets[facetKey];
-
- // facets that match some value in the field of the document (e.g. some text field)
- const matches = Object.keys(facet).filter(value => value !== 'cookies' && facet[value] === 'match');
-
- // facets that have a check next to them
- const checks = Object.keys(facet).filter(value => facet[value] === 'check');
-
- // metadata facets that exist
- const exists = Object.keys(facet).filter(value => facet[value] === 'exists');
-
- // facets that unset metadata (a hack for making cookies work)
- const unsets = Object.keys(facet).filter(value => facet[value] === 'unset');
-
- // facets that specify that a field must not match a specific value
- const xs = Object.keys(facet).filter(value => facet[value] === 'x');
-
- if (!unsets.length && !exists.length && !xs.length && !checks.length && !matches.length) return true;
- const failsNotEqualFacets = !xs.length ? false : xs.some(value => matchFieldValue(d, facetKey, value));
- const satisfiesCheckFacets = !checks.length ? true : checks.some(value => matchFieldValue(d, facetKey, value));
- const satisfiesExistsFacets = !exists.length ? true : exists.some(value => (facetKey !== LinkedTo ? d[facetKey] !== undefined : LinkManager.Instance.getAllRelatedLinks(d).length));
- const satisfiesUnsetsFacets = !unsets.length ? true : unsets.some(value => d[facetKey] === undefined);
- const satisfiesMatchFacets = !matches.length
- ? true
- : matches.some(value => {
- if (facetKey.startsWith('*')) {
- // fields starting with a '*' are used to match families of related fields. ie, *modificationDate will match text_modificationDate, data_modificationDate, etc
- const allKeys = Array.from(Object.keys(d));
- allKeys.push(...Object.keys(Doc.GetProto(d)));
- const keys = allKeys.filter(key => key.includes(facetKey.substring(1)));
- return keys.some(key => Field.toString(d[key] as Field).includes(value));
- }
- return Field.toString(d[facetKey] as Field).includes(value);
- });
- // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria
- if (parentCollection?.childFilters_boolean === 'OR') {
- if (satisfiesUnsetsFacets && satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true;
- }
- // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria
- else {
- if (!satisfiesUnsetsFacets || !satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false;
- }
- }
- return parentCollection?.childFilters_boolean === 'OR' ? false : true;
- })
- : childDocs;
- const rangeFilteredDocs = filteredDocs.filter(d => {
- for (let i = 0; i < childFiltersByRanges.length; i += 3) {
- const key = childFiltersByRanges[i];
- const min = Number(childFiltersByRanges[i + 1]);
- const max = Number(childFiltersByRanges[i + 2]);
- const val = typeof d[key] === 'string' ? (Number(StrCast(d[key])).toString() === StrCast(d[key]) ? Number(StrCast(d[key])) : undefined) : Cast(d[key], 'number', null);
- if (val === undefined) {
- //console.log("Should 'undefined' pass range filter or not?")
- } else if (val < min || val > max) return false;
- }
- return true;
- });
- return rangeFilteredDocs;
- }
-
- export let ActiveRecordings: { props: FieldViewProps; getAnchor: (addAsAnnotation: boolean) => Doc }[] = [];
-
- export function MakeLinkToActiveAudio(getSourceDoc: () => Doc | undefined, broadcastEvent = true) {
- broadcastEvent && runInAction(() => (Doc.RecordingEvent = Doc.RecordingEvent + 1));
- return DocUtils.ActiveRecordings.map(audio => {
- const sourceDoc = getSourceDoc();
- return sourceDoc && DocUtils.MakeLink(sourceDoc, audio.getAnchor(true) || audio.props.Document, { link_displayLine: false, link_relationship: 'recording annotation:linked recording', link_description: 'recording timeline' });
- });
- }
-
- export function MakeLink(source: Doc, target: Doc, linkSettings: { link_relationship?: string; link_description?: string; link_displayLine?: boolean }, id?: string, showPopup?: number[]) {
- if (!linkSettings.link_relationship) linkSettings.link_relationship = target.type === DocumentType.RTF ? 'Commentary:Comments On' : 'link';
- if (target.doc === Doc.UserDoc()) return undefined;
-
- const makeLink = action((linkDoc: Doc, showPopup?: number[]) => {
- if (showPopup) {
- LinkManager.Instance.currentLink = linkDoc;
-
- TaskCompletionBox.textDisplayed = 'Link Created';
- TaskCompletionBox.popupX = showPopup[0];
- TaskCompletionBox.popupY = showPopup[1] - 33;
- TaskCompletionBox.taskCompleted = true;
-
- LinkDescriptionPopup.Instance.popupX = showPopup[0];
- LinkDescriptionPopup.Instance.popupY = showPopup[1];
- LinkDescriptionPopup.Instance.display = true;
-
- const rect = document.body.getBoundingClientRect();
- if (LinkDescriptionPopup.Instance.popupX + 200 > rect.width) {
- LinkDescriptionPopup.Instance.popupX -= 190;
- TaskCompletionBox.popupX -= 40;
- }
- if (LinkDescriptionPopup.Instance.popupY + 100 > rect.height) {
- LinkDescriptionPopup.Instance.popupY -= 40;
- TaskCompletionBox.popupY -= 40;
- }
-
- setTimeout(
- action(() => (TaskCompletionBox.taskCompleted = false)),
- 2500
- );
- }
- return linkDoc;
- });
-
- return makeLink(
- Docs.Create.LinkDocument(
- source,
- target,
- {
- 'acl-Guest': SharingPermissions.Augment,
- '_acl-Guest': SharingPermissions.Augment,
- title: ComputedField.MakeFunction('generateLinkTitle(this)') as any,
- link_anchor_1_useSmallAnchor: source.useSmallAnchor ? true : undefined,
- link_anchor_2_useSmallAnchor: target.useSmallAnchor ? true : undefined,
- link_displayLine: linkSettings.link_displayLine,
- link_relationship: linkSettings.link_relationship,
- link_description: linkSettings.link_description,
- link_autoMoveAnchors: true,
- _layout_showCaption: '', // removed since they conflict with showing a link with a LinkBox (ie, line, not comparison box)
- _layout_showTitle: '',
- // _layout_showCaption: 'link_description',
- // _layout_showTitle: 'link_relationship',
- },
- id
- ),
- showPopup
- );
- }
-
- export function AssignScripts(doc: Doc, scripts?: { [key: string]: string | undefined }, funcs?: { [key: string]: string }) {
- scripts &&
- Object.keys(scripts).map(key => {
- const script = scripts[key];
- if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && script) {
- (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = ScriptField.MakeScript(script, {
- self: Doc.name,
- this: Doc.name,
- dragData: DragManager.DocumentDragData.name,
- value: 'any',
- _readOnly_: 'boolean',
- scriptContext: 'any',
- documentView: Doc.name,
- heading: Doc.name,
- checked: 'boolean',
- containingTreeView: Doc.name,
- altKey: 'boolean',
- ctrlKey: 'boolean',
- shiftKey: 'boolean',
- });
- }
- });
- funcs &&
- Object.keys(funcs)
- .filter(key => !key.endsWith('-setter'))
- .map(key => {
- const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
- if (ScriptCast(cfield)?.script.originalScript !== funcs[key]) {
- const setFunc = Cast(funcs[key + '-setter'], 'string', null);
- (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = funcs[key] ? ComputedField.MakeFunction(funcs[key], { dragData: DragManager.DocumentDragData.name }, { _readOnly_: true }, setFunc) : undefined;
- }
- });
- return doc;
- }
- export function AssignOpts(doc: Doc | undefined, reqdOpts: DocumentOptions, items?: Doc[]) {
- if (doc) {
- const compareValues = (val1: any, val2: any) => {
- if (val1 instanceof List && val2 instanceof List && val1.length === val2.length) {
- return !val1.some(v => !val2.includes(v)) || !val2.some(v => val1.includes(v));
- }
- return val1 === val2;
- };
- Object.entries(reqdOpts).forEach(pair => {
- const targetDoc = pair[0].startsWith('_') ? doc : Doc.GetProto(doc as Doc);
- if (!Object.getOwnPropertyNames(targetDoc).includes(pair[0].replace(/^_/, '')) || !compareValues(pair[1], targetDoc[pair[0]])) {
- targetDoc[pair[0]] = pair[1];
- }
- });
- items?.forEach(item => !DocListCast(doc.data).includes(item) && Doc.AddDocToList(Doc.GetProto(doc), 'data', item));
- items && DocListCast(doc.data).forEach(item => !items.includes(item) && Doc.RemoveDocFromList(Doc.GetProto(doc), 'data', item));
- }
- return doc;
- }
- export function AssignDocField(doc: Doc, field: string, creator: (reqdOpts: DocumentOptions, items?: Doc[]) => Doc, reqdOpts: DocumentOptions, items?: Doc[], scripts?: { [key: string]: string }, funcs?: { [key: string]: string }) {
- return DocUtils.AssignScripts(DocUtils.AssignOpts(DocCast(doc[field]), reqdOpts, items) ?? (doc[field] = creator(reqdOpts, items)), scripts, funcs);
- }
-
- export function DocumentFromField(target: Doc, fieldKey: string, proto?: Doc, options?: DocumentOptions): Doc | undefined {
- let created: Doc | undefined;
- const field = target[fieldKey];
- const resolved = options ?? {};
- if (field instanceof ImageField) {
- created = Docs.Create.ImageDocument(field.url.href, resolved);
- created.layout = ImageBox.LayoutString(fieldKey);
- } else if (field instanceof Doc) {
- created = field;
- } else if (field instanceof VideoField) {
- created = Docs.Create.VideoDocument(field.url.href, resolved);
- created.layout = VideoBox.LayoutString(fieldKey);
- } else if (field instanceof PdfField) {
- created = Docs.Create.PdfDocument(field.url.href, resolved);
- created.layout = PDFBox.LayoutString(fieldKey);
- } else if (field instanceof AudioField) {
- created = Docs.Create.AudioDocument(field.url.href, resolved);
- created.layout = AudioBox.LayoutString(fieldKey);
- } else if (field instanceof InkField) {
- created = Docs.Create.InkDocument(field.inkData, resolved);
- created.layout = InkingStroke.LayoutString(fieldKey);
- } else if (field instanceof List && field[0] instanceof Doc) {
- created = Docs.Create.StackingDocument(DocListCast(field), resolved);
- created.layout = CollectionView.LayoutString(fieldKey);
- } else {
- created = Docs.Create.TextDocument('', { ...{ _width: 200, _height: 25, _layout_autoHeight: true }, ...resolved });
- created.layout = FormattedTextBox.LayoutString(fieldKey);
- }
- if (created) {
- created.title = fieldKey;
- proto && created.proto && (created.proto = Doc.GetProto(proto));
- }
- return created;
- }
-
- /**
- *
- * @param type the type of file.
- * @param path the path to the file.
- * @param options the document options.
- * @param overwriteDoc the placeholder loading doc.
- * @returns
- */
- export async function DocumentFromType(type: string, path: string, options: DocumentOptions, overwriteDoc?: Doc): Promise<Opt<Doc>> {
- let ctor: ((path: string, options: DocumentOptions, overwriteDoc?: Doc) => Doc | Promise<Doc | undefined>) | undefined = undefined;
- if (type.indexOf('image') !== -1) {
- ctor = Docs.Create.ImageDocument;
- if (!options._width) options._width = 300;
- }
- if (type.indexOf('video') !== -1) {
- ctor = Docs.Create.VideoDocument;
- if (!options._width) options._width = 600;
- if (!options._height) options._height = ((options._width as number) * 2) / 3;
- }
- if (type.indexOf('audio') !== -1) {
- ctor = Docs.Create.AudioDocument;
- }
- if (type.indexOf('pdf') !== -1) {
- ctor = Docs.Create.PdfDocument;
- if (!options._width) options._width = 400;
- if (!options._height) options._height = ((options._width as number) * 1200) / 927;
- }
- if (type.indexOf('csv') !== -1) {
- ctor = Docs.Create.DataVizDocument;
- if (!options._width) options._width = 400;
- if (!options._height) options._height = ((options._width as number) * 1200) / 927;
- }
- //TODO:al+glr
- // if (type.indexOf("map") !== -1) {
- // ctor = Docs.Create.MapDocument;
- // if (!options._width) options._width = 800;
- // if (!options._height) options._height = (options._width as number) * 3 / 4;
- // }
- if (type.indexOf('html') !== -1) {
- if (path.includes(window.location.hostname)) {
- const s = path.split('/');
- const id = s[s.length - 1];
- return DocServer.GetRefField(id).then(field => {
- if (field instanceof Doc) {
- const embedding = Doc.MakeEmbedding(field);
- embedding.x = (options.x as number) || 0;
- embedding.y = (options.y as number) || 0;
- embedding._width = (options._width as number) || 300;
- embedding._height = (options._height as number) || (options._width as number) || 300;
- return embedding;
- }
- return undefined;
- });
- }
- ctor = Docs.Create.WebDocument;
- options = { ...options, _width: 400, _height: 512, title: path };
- }
-
- 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 {
- const documentList: ContextMenuProps[] = DocListCast(DocListCast(Doc.MyTools?.data)[0]?.data)
- .filter(btnDoc => !btnDoc.hidden)
- .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null))
- .filter(doc => doc && doc !== Doc.UserDoc().emptyTrail && doc.title)
- .map((dragDoc, i) => ({
- description: ':' + StrCast(dragDoc.title).replace('Untitled ', ''),
- event: undoable((args: { x: number; y: number }) => {
- const newDoc = DocUtils.copyDragFactory(dragDoc);
- if (newDoc) {
- newDoc.author = Doc.CurrentUserEmail;
- newDoc.x = x;
- newDoc.y = y;
- EquationBox.SelectOnLoad = newDoc[Id];
- if (newDoc.type === DocumentType.RTF) FormattedTextBox.SetSelectOnLoad(newDoc);
- if (pivotField) {
- newDoc[pivotField] = pivotValue;
- }
- docAdder?.(newDoc);
- }
- }, StrCast(dragDoc.title)),
- icon: Doc.toIcon(dragDoc),
- })) as ContextMenuProps[];
- ContextMenu.Instance.addItem({
- description: 'Create document',
- subitems: documentList,
- icon: 'file',
- });
- !simpleMenu &&
- ContextMenu.Instance.addItem({
- description: 'Styled Notes',
- subitems: DocListCast((Doc.UserDoc().template_notes as Doc).data).map((note, i) => ({
- description: ':' + StrCast(note.title),
- event: undoable((args: { x: number; y: number }) => {
- const textDoc = Docs.Create.TextDocument('', {
- _width: 200,
- x,
- y,
- _layout_autoHeight: note._layout_autoHeight !== false,
- title: StrCast(note.title) + '#' + (note.embeddingCount = NumCast(note.embeddingCount) + 1),
- });
- textDoc.layout_fieldKey = 'layout_' + note.title;
- textDoc[textDoc.layout_fieldKey] = note;
- if (pivotField) {
- textDoc[pivotField] = pivotValue;
- }
- docTextAdder(textDoc);
- }, 'create quick note'),
- icon: StrCast(note.icon) as IconProp,
- })) as ContextMenuProps[],
- icon: 'sticky-note',
- });
- const userDocList: ContextMenuProps[] = DocListCast(DocListCast(Doc.MyTools?.data)[1]?.data)
- .filter(btnDoc => !btnDoc.hidden)
- .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null))
- .filter(doc => doc && doc !== Doc.UserDoc().emptyTrail && doc !== Doc.UserDoc().emptyNote && doc.title)
- .map((dragDoc, i) => ({
- description: ':' + StrCast(dragDoc.title).replace('Untitled ', ''),
- event: undoable((args: { x: number; y: number }) => {
- const newDoc = DocUtils.delegateDragFactory(dragDoc);
- if (newDoc) {
- newDoc.author = Doc.CurrentUserEmail;
- newDoc.x = x;
- newDoc.y = y;
- EquationBox.SelectOnLoad = newDoc[Id];
- if (newDoc.type === DocumentType.RTF) FormattedTextBox.SetSelectOnLoad(newDoc);
- if (pivotField) {
- newDoc[pivotField] = pivotValue;
- }
- docAdder?.(newDoc);
- }
- }, StrCast(dragDoc.title)),
- icon: Doc.toIcon(dragDoc),
- })) as ContextMenuProps[];
- ContextMenu.Instance.addItem({
- description: 'User Templates',
- subitems: userDocList,
- icon: 'file',
- });
- } // applies a custom template to a document. the template is identified by it's short name (e.g, slideView not layout_slideView)
- export function makeCustomViewClicked(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = 'custom', docLayoutTemplate?: Doc) {
- const batch = UndoManager.StartBatch('makeCustomViewClicked');
- runInAction(() => {
- doc.layout_fieldKey = 'layout_' + templateSignature;
- createCustomView(doc, creator, templateSignature, docLayoutTemplate);
- });
- batch.end();
- return doc;
- }
- export function findTemplate(templateName: string, type: string, signature: string) {
- let docLayoutTemplate: Opt<Doc>;
- const iconViews = DocListCast(Cast(Doc.UserDoc()['template_icons'], Doc, null)?.data);
- const templBtns = DocListCast(Cast(Doc.UserDoc()['template_buttons'], Doc, null)?.data);
- const noteTypes = DocListCast(Cast(Doc.UserDoc()['template_notes'], Doc, null)?.data);
- const clickFuncs = DocListCast(Cast(Doc.UserDoc()['template_clickFuncs'], Doc, null)?.data);
- const allTemplates = iconViews
- .concat(templBtns)
- .concat(noteTypes)
- .concat(clickFuncs)
- .map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc)
- .filter(doc => doc.isTemplateDoc);
- // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized
- // first try to find a template that matches the specific document type (<typeName>_<templateName>). otherwise, fallback to a general match on <templateName>
- !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName + '_' + type && (docLayoutTemplate = tempDoc));
- !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName && (docLayoutTemplate = tempDoc));
- return docLayoutTemplate;
- }
- export function createCustomView(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = 'custom', docLayoutTemplate?: Doc) {
- const templateName = templateSignature.replace(/\(.*\)/, '');
- docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, StrCast(doc.isGroup && doc.transcription ? 'transcription' : doc.type), templateSignature);
-
- const customName = 'layout_' + templateSignature;
- const _width = NumCast(doc._width);
- const _height = NumCast(doc._height);
- const options = { title: 'data', backgroundColor: StrCast(doc.backgroundColor), _layout_autoHeight: true, _width, x: -_width / 2, y: -_height / 2, _layout_showSidebar: false };
-
- if (docLayoutTemplate) {
- if (docLayoutTemplate !== doc[customName]) {
- Doc.ApplyTemplateTo(docLayoutTemplate, doc, customName, undefined);
- }
- } else {
- let fieldTemplate: Opt<Doc>;
- if (doc.data instanceof RichTextField || typeof doc.data === 'string') {
- fieldTemplate = Docs.Create.TextDocument('', options);
- } else if (doc.data instanceof PdfField) {
- fieldTemplate = Docs.Create.PdfDocument('http://www.msn.com', options);
- } else if (doc.data instanceof VideoField) {
- fieldTemplate = Docs.Create.VideoDocument('http://www.cs.brown.edu', options);
- } else if (doc.data instanceof AudioField) {
- fieldTemplate = Docs.Create.AudioDocument('http://www.cs.brown.edu', options);
- } else if (doc.data instanceof ImageField) {
- fieldTemplate = Docs.Create.ImageDocument('http://www.cs.brown.edu', options);
- }
- const docTemplate = creator?.(fieldTemplate ? [fieldTemplate] : [], { title: customName + '(' + doc.title + ')', isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
- fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, docTemplate ? Doc.GetProto(docTemplate) : docTemplate);
- docTemplate && Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined);
- }
- }
- export function makeCustomView(doc: Doc, custom: boolean, layout: string) {
- Doc.setNativeView(doc);
- if (custom) {
- makeCustomViewClicked(doc, Docs.Create.StackingDocument, layout, undefined);
- }
- }
- export function iconify(doc: Doc) {
- const layout_fieldKey = Cast(doc.layout_fieldKey, 'string', null);
- DocUtils.makeCustomViewClicked(doc, Docs.Create.StackingDocument, 'icon', undefined);
- if (layout_fieldKey && layout_fieldKey !== 'layout' && layout_fieldKey !== 'layout_icon') doc.deiconifyLayout = layout_fieldKey.replace('layout_', '');
- }
-
- export function pileup(docList: Doc[], x?: number, y?: number, size: number = 55, create: boolean = true) {
- runInAction(() => {
- docList.forEach((d, i) => {
- DocUtils.iconify(d);
- d.x = Math.cos((Math.PI * 2 * i) / docList.length) * size - size;
- d.y = Math.sin((Math.PI * 2 * i) / docList.length) * size - size;
- d._timecodeToShow = undefined; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
- });
- });
- if (create) {
- const newCollection = Docs.Create.PileDocument(docList, { title: 'pileup', _freeform_noZoom: true, x: (x || 0) - size, y: (y || 0) - size, _width: size * 2, _height: size * 2, dragWhenActive: true, _layout_fitWidth: false });
- newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - size;
- newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - size;
- newCollection._width = newCollection._height = size * 2;
- return newCollection;
- }
- }
- export function makeIntoPortal(doc: Doc, layoutDoc: Doc, allLinks: Doc[]) {
- const portalLink = allLinks.find(d => d.link_anchor_1 === doc && d.link_relationship === 'portal to:portal from');
- if (!portalLink) {
- DocUtils.MakeLink(
- doc,
- Docs.Create.FreeformDocument([], {
- _width: NumCast(layoutDoc._width) + 10,
- _height: Math.max(NumCast(layoutDoc._height), NumCast(layoutDoc._width) + 10),
- _isLightbox: true,
- _layout_fitWidth: true,
- title: StrCast(doc.title) + ' [Portal]',
- }),
- { link_relationship: 'portal to:portal from' }
- );
- }
- doc.followLinkLocation = OpenWhere.lightbox;
- doc.onClick = FollowLinkScript();
- }
-
- export function LeavePushpin(doc: Doc, annotationField: string) {
- if (doc.followLinkToggle) return undefined;
- const context = Cast(doc.embedContainer, Doc, null) ?? Cast(doc.annotationOn, Doc, null);
- const hasContextAnchor = LinkManager.Links(doc).some(l => (l.link_anchor_2 === doc && Cast(l.link_anchor_1, Doc, null)?.annotationOn === context) || (l.link_anchor_1 === doc && Cast(l.link_anchor_2, Doc, null)?.annotationOn === context));
- if (context && !hasContextAnchor && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) {
- const pushpin = Docs.Create.FontIconDocument({
- title: '',
- annotationOn: Cast(doc.annotationOn, Doc, null),
- followLinkToggle: true,
- icon: 'map-pin',
- x: Cast(doc.x, 'number', null),
- y: Cast(doc.y, 'number', null),
- backgroundColor: '#ACCEF7',
- layout_hideAllLinks: true,
- _width: 15,
- _height: 15,
- _xPadding: 0,
- onClick: FollowLinkScript(),
- _timecodeToShow: Cast(doc._timecodeToShow, 'number', null),
- });
- Doc.AddDocToList(context, annotationField, pushpin);
- const pushpinLink = DocUtils.MakeLink(pushpin, doc, { link_relationship: 'pushpin' }, '');
- doc._timecodeToShow = undefined;
- return pushpin;
- }
- return undefined;
- }
-
- // /**
- // *
- // * @param dms Degree Minute Second format exif gps data
- // * @param ref ref that determines negativity of decimal coordinates
- // * @returns a decimal format of gps latitude / longitude
- // */
- // function getDecimalfromDMS(dms?: number[], ref?: string) {
- // if (dms && ref) {
- // let degrees = dms[0] / dms[1];
- // let minutes = dms[2] / dms[3] / 60.0;
- // let seconds = dms[4] / dms[5] / 3600.0;
-
- // if (['S', 'W'].includes(ref)) {
- // degrees = -degrees; minutes = -minutes; seconds = -seconds
- // }
- // return (degrees + minutes + seconds).toFixed(5);
- // }
- // }
-
- function ConvertDMSToDD(degrees: number, minutes: number, seconds: number, direction: string) {
- var dd = degrees + minutes / 60 + seconds / (60 * 60);
- if (direction === 'S' || direction === 'W') {
- dd = dd * -1;
- } // Don't do anything for N or E
- return dd;
- }
-
- async function processFileupload(generatedDocuments: Doc[], name: string, type: string, result: Error | Upload.FileInformation, options: DocumentOptions, overwriteDoc?: Doc) {
- if (result instanceof Error) {
- alert(`Upload failed: ${result.message}`);
- return;
- }
- const full = { ...options, _width: 400, title: name };
- const pathname = result.accessPaths.agnostic.client;
- const doc = await DocUtils.DocumentFromType(type, pathname, full, overwriteDoc);
- if (doc) {
- const proto = Doc.GetProto(doc);
- proto.text = result.rawText;
- 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();
- 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);
- if (NumCast(proto['data-nativeOrientation']) >= 5) {
- proto['data_nativeHeight'] = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim;
- proto['data_nativeWidth'] = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight);
- }
- proto.data_exif = JSON.stringify(result.exifData?.data);
- proto.data_contentSize = result.contentSize;
- // exif gps data coordinates are stored in DMS (Degrees Minutes Seconds), the following operation converts that to decimal coordinates
- const latitude = result.exifData?.data?.GPSLatitude;
- const latitudeDirection = result.exifData?.data?.GPSLatitudeRef;
- const longitude = result.exifData?.data?.GPSLongitude;
- const longitudeDirection = result.exifData?.data?.GPSLongitudeRef;
- if (latitude !== undefined && longitude !== undefined && latitudeDirection !== undefined && longitudeDirection !== undefined) {
- proto.latitude = ConvertDMSToDD(latitude[0], latitude[1], latitude[2], latitudeDirection);
- proto.longitude = ConvertDMSToDD(longitude[0], longitude[1], longitude[2], longitudeDirection);
- }
- }
- if (Upload.isVideoInformation(result)) {
- proto.data_duration = result.duration;
- }
- if (overwriteDoc) {
- LoadingBox.removeCurrentlyLoading(overwriteDoc);
- }
- generatedDocuments.push(doc);
- }
- }
-
- export function GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, annotationOn?: Doc, backgroundColor?: string) {
- const defaultTextTemplate = DocCast(Doc.UserDoc().defaultTextLayout);
- const tbox = Docs.Create.TextDocument('', {
- annotationOn,
- backgroundColor,
- x,
- y,
- title,
- ...(defaultTextTemplate
- ? {} // if the new doc will inherit from a template, don't set any layout fields since that would block the inheritance
- : {
- _width: width || 200,
- _height: 35,
- _layout_centered: BoolCast(Doc.UserDoc()._layout_centered),
- _layout_fitWidth: true,
- _layout_autoHeight: true,
- _layout_enableAltContentUI: BoolCast(Doc.UserDoc().defaultToFlashcards),
- }),
- });
-
- if (defaultTextTemplate) {
- tbox.layout_fieldKey = 'layout_' + StrCast(defaultTextTemplate.title);
- Doc.GetProto(tbox)[StrCast(tbox.layout_fieldKey)] = defaultTextTemplate; // set the text doc's layout to render with the text template
- tbox[DocData].proto = defaultTextTemplate; // and also set the text doc to inherit from the template (this allows the template to specify default field values)
- }
- return tbox;
- }
-
- export function uploadYoutubeVideoLoading(videoId: string, options: DocumentOptions, overwriteDoc?: Doc) {
- const generatedDocuments: Doc[] = [];
- Networking.UploadYoutubeToServer(videoId, overwriteDoc?.[Id]).then(upfiles => {
- const {
- source: { newFilename, originalFilename, mimetype },
- result,
- } = upfiles.lastElement();
- if ((result as any).message) {
- if (overwriteDoc) {
- overwriteDoc.isLoading = false;
- overwriteDoc.loadingError = (result as any).message;
- LoadingBox.removeCurrentlyLoading(overwriteDoc);
- }
- } else newFilename && processFileupload(generatedDocuments, newFilename, mimetype ?? '', result, options, overwriteDoc);
- });
- }
-
- /**
- * uploadFilesToDocs will take in an array of Files, and creates documents for the
- * new files.
- *
- * @param files an array of files that will be uploaded
- * @param options options to use while uploading
- * @returns
- */
- export async function uploadFilesToDocs(files: File[], options: DocumentOptions) {
- const generatedDocuments: Doc[] = [];
-
- // These files do not have overwriteDocs, so we do not set the guid and let the client generate one.
- const fileNoGuidPairs: Networking.FileGuidPair[] = files.map(file => ({ file }));
-
- const upfiles = await Networking.UploadFilesToServer(fileNoGuidPairs);
- for (const {
- source: { newFilename, mimetype },
- result,
- } of upfiles) {
- newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options);
- }
- return generatedDocuments;
- }
-
- export function uploadFileToDoc(file: File, options: DocumentOptions, overwriteDoc: Doc) {
- const generatedDocuments: Doc[] = [];
- // Since this file has an overwriteDoc, we can set the client tracking guid to the overwriteDoc's guid.
- Networking.UploadFilesToServer([{ file, guid: overwriteDoc[Id] }]).then(upfiles => {
- const {
- source: { newFilename, mimetype },
- result,
- } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: { message: 'upload failed' } };
- if ((result as any).message) {
- if (overwriteDoc) {
- overwriteDoc.loadingError = (result as any).message;
- LoadingBox.removeCurrentlyLoading(overwriteDoc);
- }
- } else newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc);
- });
- }
-
- // copies the specified drag factory document
- export function copyDragFactory(dragFactory: Doc) {
- if (!dragFactory) return undefined;
- const ndoc = dragFactory.isTemplateDoc ? Doc.ApplyTemplate(dragFactory) : Doc.MakeCopy(dragFactory, true);
- if (ndoc && dragFactory['dragFactory_count'] !== undefined) {
- dragFactory['dragFactory_count'] = NumCast(dragFactory['dragFactory_count']) + 1;
- Doc.SetInPlace(ndoc, 'title', ndoc.title + ' ' + NumCast(dragFactory['dragFactory_count']).toString(), true);
- }
-
- return ndoc;
- }
- export function delegateDragFactory(dragFactory: Doc) {
- const ndoc = Doc.MakeDelegateWithProto(dragFactory);
- if (ndoc && dragFactory['dragFactory_count'] !== undefined) {
- dragFactory['dragFactory_count'] = NumCast(dragFactory['dragFactory_count']) + 1;
- Doc.GetProto(ndoc).title = ndoc.title + ' ' + NumCast(dragFactory['dragFactory_count']).toString();
- }
- return ndoc;
- }
-}
-
-ScriptingGlobals.add('Docs', Docs);
-ScriptingGlobals.add(function copyDragFactory(dragFactory: Doc, asDelegate?: boolean) {
- return dragFactory instanceof Doc ? (asDelegate ? DocUtils.delegateDragFactory(dragFactory) : DocUtils.copyDragFactory(dragFactory)) : dragFactory;
-});
-ScriptingGlobals.add(function makeDelegate(proto: any) {
- const d = Docs.Create.DelegateDocument(proto, { title: 'child of ' + proto.title });
- return d;
-});
-ScriptingGlobals.add(function generateLinkTitle(link: Doc) {
- const link_anchor_1title = link.link_anchor_1 && link.link_anchor_1 !== link ? Cast(link.link_anchor_1, Doc, null)?.title : '<?>';
- const link_anchor_2title = link.link_anchor_2 && link.link_anchor_2 !== link ? Cast(link.link_anchor_2, Doc, null)?.title : '<?>';
- const relation = link.link_relationship || 'to';
- return `${link_anchor_1title} (${relation}) ${link_anchor_2title}`;
-});
diff --git a/src/client/goldenLayout.d.ts b/src/client/goldenLayout.d.ts
index b50240563..26e8ba356 100644
--- a/src/client/goldenLayout.d.ts
+++ b/src/client/goldenLayout.d.ts
@@ -1,3 +1,2 @@
-
declare const GoldenLayout: any;
-export = GoldenLayout; \ No newline at end of file
+export = GoldenLayout;
diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx
index 02879e3c4..119d103c5 100644
--- a/src/client/util/BranchingTrailManager.tsx
+++ b/src/client/util/BranchingTrailManager.tsx
@@ -1,18 +1,31 @@
+/* eslint-disable react/no-unused-class-component-methods */
+/* eslint-disable react/no-array-index-key */
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
-import { PresBox } from '../views/nodes/trails';
import { OverlayView } from '../views/OverlayView';
-import { DocumentManager } from './DocumentManager';
-import { Docs } from '../documents/Documents';
-import { nullAudio } from '../../fields/URLField';
+import { DocumentView } from '../views/nodes/DocumentView';
+import { PresBox } from '../views/nodes/trails';
@observer
export class BranchingTrailManager extends React.Component {
+ // eslint-disable-next-line no-use-before-define
public static Instance: BranchingTrailManager;
+ // stack of the history
+ @observable private slideHistoryStack: String[] = [];
+ @observable private containsSet: Set<String> = new Set<String>();
+ // docId to Doc map
+ @observable private docIdToDocMap: Map<String, Doc> = new Map<String, Doc>();
+
+ // prev pres to copmare with
+ @observable private prevPresId: String | null = null;
+ @action setPrevPres = action((newId: String | null) => {
+ this.prevPresId = newId;
+ });
+
constructor(props: any) {
super(props);
makeObservable(this);
@@ -22,7 +35,7 @@ export class BranchingTrailManager extends React.Component {
}
setupUi = () => {
- OverlayView.Instance.addWindow(<BranchingTrailManager></BranchingTrailManager>, { x: 100, y: 150, width: 1000, title: 'Branching Trail' });
+ OverlayView.Instance.addWindow(<BranchingTrailManager />, { x: 100, y: 150, width: 1000, title: 'Branching Trail' });
// OverlayView.Instance.forceUpdate();
console.log(OverlayView.Instance);
// let hi = Docs.Create.TextDocument("beee", {
@@ -33,26 +46,13 @@ export class BranchingTrailManager extends React.Component {
// hi.overlayY = 100;
// Doc.AddToMyOverlay(hi);
- console.log(DocumentManager._overlayViews);
};
- // stack of the history
- @observable private slideHistoryStack: String[] = [];
@action setSlideHistoryStack = action((newArr: String[]) => {
this.slideHistoryStack = newArr;
});
- @observable private containsSet: Set<String> = new Set<String>();
-
- // prev pres to copmare with
- @observable private prevPresId: String | null = null;
- @action setPrevPres = action((newId: String | null) => {
- this.prevPresId = newId;
- });
-
- // docId to Doc map
- @observable private docIdToDocMap: Map<String, Doc> = new Map<String, Doc>();
-
+ // eslint-disable-next-line react/sort-comp
observeDocumentChange = (targetDoc: Doc, pres: PresBox) => {
const presId = pres.Document[Id];
if (this.prevPresId === presId) {
@@ -102,11 +102,11 @@ export class BranchingTrailManager extends React.Component {
this.setSlideHistoryStack(newStack);
removed.forEach(info => this.containsSet.delete(info.toString()));
- DocumentManager.Instance.showDocument(targetDoc, { willZoomCentered: true });
+ DocumentView.showDocument(targetDoc, { willZoomCentered: true });
if (this.slideHistoryStack.length === 0) {
Doc.UserDoc().isBranchingMode = false;
}
- //PresBox.NavigateToTarget(targetDoc, targetDoc);
+ // PresBox.NavigateToTarget(targetDoc, targetDoc);
};
@computed get trailBreadcrumbs() {
@@ -116,11 +116,11 @@ export class BranchingTrailManager extends React.Component {
const [presId, targetDocId] = info.split(',');
const doc = this.docIdToDocMap.get(targetDocId);
if (!doc) {
- return <></>;
+ return null;
}
return (
<span key={targetDocId}>
- <button key={index} onPointerDown={e => this.clickHandler(e, targetDocId, index)}>
+ <button type="button" key={index} onPointerDown={e => this.clickHandler(e, targetDocId, index)}>
{presId.slice(0, 3) + ':' + doc.title}
</button>
-{'>'}
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 6e9094b3a..77cf80151 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -1,4 +1,10 @@
+/* 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';
import { TextField } from '@mui/material';
+import { Button } from 'browndash-components';
import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -6,21 +12,13 @@ import Select from 'react-select';
import { Doc, DocListCast } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { StrCast } from '../../fields/Types';
-import { DictationOverlay } from '../views/DictationOverlay';
+import { Docs } from '../documents/Documents';
import { MainViewModal } from '../views/MainViewModal';
+import { ObservableReactComponent } from '../views/ObservableReactComponent';
import { DocumentView } from '../views/nodes/DocumentView';
import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
import './CalendarManager.scss';
-import { DocumentManager } from './DocumentManager';
-import { SelectionManager } from './SelectionManager';
-import { SettingsManager } from './SettingsManager';
-// import { DateRange, Range, RangeKeyDict } from 'react-date-range';
-import { DateRangePicker, Provider, defaultTheme } from '@adobe/react-spectrum';
-import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button } from 'browndash-components';
-import { Docs } from '../documents/Documents';
-import { ObservableReactComponent } from '../views/ObservableReactComponent';
+import { SnappingManager } from './SnappingManager';
// import 'react-date-range/dist/styles.css';
// import 'react-date-range/dist/theme/default.css';
@@ -47,12 +45,12 @@ const formatCalendarDateToString = (calendarDate: any) => {
@observer
export class CalendarManager extends ObservableReactComponent<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: CalendarManager;
@observable private isOpen = false;
@observable private targetDoc: Doc | undefined = undefined; // the target document
@observable private targetDocView: DocumentView | undefined = undefined; // the DocumentView of the target doc
@observable private dialogueBoxOpacity = 1; // for the modal
- @observable private overlayOpacity = 0.4; // for the modal
@observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used
@@ -83,12 +81,10 @@ export class CalendarManager extends ObservableReactComponent<{}> {
this.creationType = type;
};
- public open = (target?: DocumentView, target_doc?: Doc) => {
- console.log('hi');
+ public open = (target?: DocumentView, targetDoc?: Doc) => {
runInAction(() => {
- this.targetDoc = target_doc || target?.Document;
+ this.targetDoc = targetDoc || target?.Document;
this.targetDocView = target;
- DictationOverlay.Instance.hasActiveModal = true;
this.isOpen = this.targetDoc !== undefined;
});
};
@@ -98,7 +94,6 @@ export class CalendarManager extends ObservableReactComponent<{}> {
TaskCompletionBox.taskCompleted = false;
setTimeout(
action(() => {
- DictationOverlay.Instance.hasActiveModal = false;
this.targetDoc = undefined;
}),
500
@@ -117,7 +112,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
@action
handleSelectChange = (option: any) => {
if (option) {
- let selectOpt = option as CalendarSelectOptions;
+ const selectOpt = option as CalendarSelectOptions;
this.selectedExistingCalendarOption = selectOpt;
this.calendarName = selectOpt.value; // or label
}
@@ -136,7 +131,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
// TODO: Make undoable
private addToCalendar = () => {
- let docs = SelectionManager.Views.length < 2 ? [this.targetDoc] : SelectionManager.Views.map(docView => docView.Document);
+ const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document);
const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // doc to add to calendar
console.log(targetDoc);
@@ -159,7 +154,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
}
} else {
// find existing calendar based on selected name (should technically always find one)
- const existingCalendar = this.existingCalendars.find(calendar => StrCast(calendar.title) === this.calendarName);
+ const existingCalendar = this.existingCalendars.find(findCal => StrCast(findCal.title) === this.calendarName);
if (existingCalendar) calendar = existingCalendar;
else {
this.errorMessage = 'Must select an existing calendar';
@@ -189,28 +184,26 @@ export class CalendarManager extends ObservableReactComponent<{}> {
private focusOn = (contents: string) => {
const title = this.targetDoc ? StrCast(this.targetDoc.title) : '';
- const docs = SelectionManager.Views.length > 1 ? SelectionManager.Views.map(docView => docView.Document) : [this.targetDoc];
+ const docs = DocumentView.Selected().length > 1 ? DocumentView.Selected().map(docView => docView.Document) : [this.targetDoc];
return (
<span
className="focus-span"
title={title}
onClick={() => {
if (this.targetDoc && this.targetDocView && docs.length === 1) {
- DocumentManager.Instance.showDocument(this.targetDoc, { willZoomCentered: true });
+ DocumentView.showDocument(this.targetDoc, { willZoomCentered: true });
}
}}
onPointerEnter={action(() => {
if (docs.length) {
docs.forEach(doc => doc && Doc.BrushDoc(doc));
this.dialogueBoxOpacity = 0.1;
- this.overlayOpacity = 0.1;
}
})}
onPointerLeave={action(() => {
if (docs.length) {
docs.forEach(doc => doc && Doc.UnBrushDoc(doc));
this.dialogueBoxOpacity = 1;
- this.overlayOpacity = 0.4;
}
})}>
{contents}
@@ -252,26 +245,24 @@ export class CalendarManager extends ObservableReactComponent<{}> {
@computed
get calendarInterface() {
- let docs = SelectionManager.Views.length < 2 ? [this.targetDoc] : SelectionManager.Views.map(docView => docView.Document);
+ const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document);
const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData];
- const currentDate = new Date();
-
return (
<div
className="calendar-interface"
style={{
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
color: StrCast(Doc.UserDoc().userColor),
}}>
- <p className="selected-doc-title" style={{ color: SettingsManager.userColor }}>
+ <p className="selected-doc-title" style={{ color: SnappingManager.userColor }}>
<b>{this.focusOn(docs.length < 2 ? StrCast(targetDoc?.title, 'this document') : '-multiple-')}</b>
</p>
<div className="creation-type-container">
- <div className={`calendar-creation ${this.creationType === 'new-calendar' ? 'calendar-creation-selected' : ''}`} onClick={e => this.setInterationType('new-calendar')}>
+ <div className={`calendar-creation ${this.creationType === 'new-calendar' ? 'calendar-creation-selected' : ''}`} onClick={() => this.setInterationType('new-calendar')}>
Add to New Calendar
</div>
- <div className={`calendar-creation ${this.creationType === 'existing-calendar' ? 'calendar-creation-selected' : ''}`} onClick={e => this.setInterationType('existing-calendar')}>
+ <div className={`calendar-creation ${this.creationType === 'existing-calendar' ? 'calendar-creation-selected' : ''}`} onClick={() => this.setInterationType('existing-calendar')}>
Add to Existing calendar
</div>
</div>
@@ -317,7 +308,8 @@ export class CalendarManager extends ObservableReactComponent<{}> {
color: StrCast(Doc.UserDoc().userColor),
width: '100%',
}),
- }}></Select>
+ }}
+ />
)}
</div>
<div className="description-container">
@@ -351,6 +343,6 @@ export class CalendarManager extends ObservableReactComponent<{}> {
}
render() {
- return <MainViewModal contents={this.calendarInterface} isDisplayed={this.isOpen} interactive={true} dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.close} />;
+ return <MainViewModal contents={this.calendarInterface} isDisplayed={this.isOpen} interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} closeOnExternalClick={this.close} />;
}
}
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index 2e13aff2f..253cdd8b5 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -1,30 +1,34 @@
+/* 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 { DocCast, StrCast } from '../../fields/Types';
-import { addStyleSheet } from '../../Utils';
-import { LightboxView } from '../views/LightboxView';
import { MainViewModal } from '../views/MainViewModal';
+import { DocumentView } from '../views/nodes/DocumentView';
import './CaptureManager.scss';
-import { LinkManager } from './LinkManager';
-import { SelectionManager } from './SelectionManager';
@observer
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 isOpen: boolean = false; // whether the CaptureManager is to be displayed or not.
+ // eslint-disable-next-line react/sort-comp
constructor(props: {}) {
super(props);
makeObservable(this);
CaptureManager.Instance = this;
}
- public close = action(() => (this.isOpen = false));
+ public close = action(() => {
+ this.isOpen = false;
+ });
public open = action((doc: Doc) => {
this.isOpen = true;
this._document = doc;
@@ -50,7 +54,7 @@ export class CaptureManager extends React.Component<{}> {
const doc = this._document;
const order: JSX.Element[] = [];
if (doc) {
- LinkManager.Links(doc).forEach((l, i) =>
+ Doc.Links(doc).forEach((l, i) =>
order.push(
<div className="list-item">
<div className="number">{i}</div>
@@ -74,7 +78,7 @@ export class CaptureManager extends React.Component<{}> {
<div
className="save"
onClick={() => {
- LightboxView.Instance.SetLightboxDoc(this._document);
+ DocumentView.SetLightboxDoc(this._document);
this.close();
}}>
Save
@@ -82,8 +86,8 @@ export class CaptureManager extends React.Component<{}> {
<div
className="cancel"
onClick={() => {
- const selected = SelectionManager.Views.slice();
- SelectionManager.DeselectAll();
+ const selected = DocumentView.Selected();
+ DocumentView.DeselectAll();
selected.map(dv => dv.props.removeDocument?.(dv.Document));
this.close();
}}>
@@ -99,15 +103,15 @@ export class CaptureManager extends React.Component<{}> {
<div className="capture-interface">
<div className="capture-t1">
<div className="recordButtonOutline" style={{}}>
- <div className="recordButtonInner" style={{}}></div>
+ <div className="recordButtonInner" style={{}} />
</div>
Conversation Capture
</div>
- <div className="capture-t2"></div>
+ <div className="capture-t2" />
{this.visibilityContent}
{this.linksContent}
<div className="close-button" onClick={this.close}>
- <FontAwesomeIcon icon={'times'} color="black" size={'lg'} />
+ <FontAwesomeIcon icon="times" color="black" size="lg" />
</div>
{this.closeButtons}
</div>
@@ -119,11 +123,10 @@ export class CaptureManager extends React.Component<{}> {
<MainViewModal
contents={this.captureInterface}
isDisplayed={this.isOpen}
- interactive={true}
+ interactive
closeOnExternalClick={this.close}
dialogueBoxStyle={{ width: '500px', height: '350px', border: 'none', background: 'whitesmoke' }}
overlayStyle={{ background: 'black' }}
- overlayDisplayedOpacity={0.6}
/>
);
}
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index b6ba3f187..f32f33c51 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1,6 +1,6 @@
-import { observable, reaction, runInAction } from "mobx";
+import { reaction, runInAction } from "mobx";
import * as rp from 'request-promise';
-import { OmitKeys, Utils } from "../../Utils";
+import { ClientUtils, OmitKeys } from "../../ClientUtils";
import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
import { DocData } from "../../fields/DocSymbols";
import { InkTool } from "../../fields/InkField";
@@ -12,28 +12,32 @@ import { ScriptField } from "../../fields/ScriptField";
import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types";
import { WebField, nullAudio } from "../../fields/URLField";
import { SetCachedGroups, SharingPermissions } from "../../fields/util";
-import { GestureUtils } from "../../pen-gestures/GestureUtils";
+import { Gestures } from "../../pen-gestures/GestureTypes";
import { DocServer } from "../DocServer";
+import { DocUtils, FollowLinkScript } from '../documents/DocUtils';
import { CollectionViewType, DocumentType } from "../documents/DocumentTypes";
-import { DocUtils, Docs, DocumentOptions, FInfo, FInfoFieldType } from "../documents/Documents";
+import { Docs, DocumentOptions, FInfo, FInfoFieldType } from "../documents/Documents";
import { DashboardView } from "../views/DashboardView";
import { OverlayView } from "../views/OverlayView";
-import { CollectionTreeView, TreeViewType } from "../views/collections/CollectionTreeView";
+import { CollectionTreeView } from "../views/collections/CollectionTreeView";
+import { TreeViewType } from "../views/collections/CollectionTreeViewType";
+import { CollectionView } from "../views/collections/CollectionView";
import { Colors } from "../views/global/globalEnums";
-import { media_state } from "../views/nodes/AudioBox";
-import { OpenWhere } from "../views/nodes/DocumentView";
+import { mediaState } from "../views/nodes/AudioBox";
import { ButtonType, FontIconBox } from "../views/nodes/FontIconBox/FontIconBox";
+import { ImageBox } from "../views/nodes/ImageBox";
+import { LabelBox } from "../views/nodes/LabelBox";
+import { OpenWhere } from "../views/nodes/OpenWhere";
import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox";
-import { DragManager, dropActionType } from "./DragManager";
+import { DragManager } from "./DragManager";
+import { dropActionType } from "./DropActionTypes";
import { MakeTemplate } from "./DropConverter";
-import { FollowLinkScript } from "./LinkFollower";
-import { LinkManager } from "./LinkManager";
+import { UPDATE_SERVER_CACHE } from "./LinkManager";
import { ScriptingGlobals } from "./ScriptingGlobals";
+import { SelectionManager } from "./SelectionManager";
import { ColorScheme } from "./SettingsManager";
import { SnappingManager } from "./SnappingManager";
import { UndoManager } from "./UndoManager";
-import { LabelBox } from "../views/nodes/LabelBox";
-import { ImageBox } from "../views/nodes/ImageBox";
interface Button {
// DocumentOptions fields a button can set
@@ -60,12 +64,13 @@ interface Button {
subMenu?: Button[];
}
+// eslint-disable-next-line import/no-mutable-exports
export let resolvedPorts: { server: number, socket: number };
export class CurrentUserUtils {
// initializes experimental advanced template views - slideView, headerView
static setupUserDocumentCreatorButtons(doc: Doc, userDocTemplates: Opt<Doc>) {
- const userTemplates = DocListCast(userDocTemplates?.data).filter(doc => !Doc.IsSystem(doc));
+ const userTemplates = DocListCast(userDocTemplates?.data).filter(fdoc => !Doc.IsSystem(fdoc));
const reqdOpts:DocumentOptions = {
title: "User Tools", _xMargin: 0, _layout_showTitle: "title", _chromeHidden: true, hidden: false,
_dragOnlyWithinContainer: true, layout_hideContextMenu: true, isSystem: true, _forceActive: true,
@@ -73,7 +78,7 @@ export class CurrentUserUtils {
};
const reqdScripts = { dropConverter : "convertToButtons(dragData)" };
const reqdFuncs = { /* hidden: "IsNoviceMode()" */ };
- return DocUtils.AssignScripts(DocUtils.AssignOpts(userDocTemplates, reqdOpts, userTemplates) ?? Docs.Create.MasonryDocument(userTemplates, reqdOpts), reqdScripts, reqdFuncs);
+ return DocUtils.AssignScripts(userDocTemplates ?? Docs.Create.MasonryDocument(userTemplates, reqdOpts), reqdScripts, reqdFuncs);
}
/// Initializes templates for editing click funcs of a document
@@ -85,11 +90,12 @@ export class CurrentUserUtils {
{ opts: { title: "Open Detail On Right", targetScriptKey: "onChildDoubleClick"}, script: `openDoc(this.doubleClickView.${OpenWhere.addRight})`}];
const reqdClickList = reqdTempOpts.map(opts => {
const allOpts = {...reqdClickOpts, ...opts.opts};
- const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(doc => doc.title === opts.opts.title): undefined;
+ const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(fdoc => fdoc.title === opts.opts.title): undefined;
return DocUtils.AssignOpts(clickDoc, allOpts) ?? Docs.Create.ScriptingDocument(ScriptField.MakeScript(opts.script, allOpts),allOpts);
});
const reqdOpts:DocumentOptions = { title: "child click editors", _height:75, isSystem: true};
+ // eslint-disable-next-line no-return-assign
return DocUtils.AssignOpts(tempClicks, reqdOpts, reqdClickList) ?? (doc[field] = Docs.Create.TreeDocument(reqdClickList, reqdOpts));
}
@@ -107,13 +113,14 @@ export class CurrentUserUtils {
const reqdClickList = reqdTempOpts.map(opts => {
const title = opts.opts.title?.toString();
const allOpts = {...reqdClickOpts, ...opts.opts};
- const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(doc => doc.title === title): undefined;
+ const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(fdoc => fdoc.title === title): undefined;
const script = ScriptField.MakeScript(opts.script, {heading:Doc.name, checked:"boolean", containingTreeView:Doc.name});
const scriptDoc = Docs.Create.ScriptingDocument(script, allOpts, title)
return DocUtils.AssignOpts(clickDoc, allOpts) ?? MakeTemplate(scriptDoc);
});
const reqdOpts:DocumentOptions = {title: "click editor templates", _height:75, isSystem: true};
+ // eslint-disable-next-line no-return-assign
return DocUtils.AssignOpts(tempClicks, reqdOpts, reqdClickList) ?? (doc[field] = Docs.Create.TreeDocument(reqdClickList, reqdOpts));
}
@@ -121,23 +128,33 @@ export class CurrentUserUtils {
static setupNoteTemplates(doc: Doc, field="template_notes") {
const tempNotes = DocCast(doc[field]);
const reqdTempOpts:DocumentOptions[] = [
- { title: "Postit", backgroundColor: "yellow", icon: "sticky-note"},
- { title: "Idea", backgroundColor: "pink", icon: "lightbulb" },
- { title: "Topic", backgroundColor: "lightblue", icon: "book-open" }];
+ { title: "Postit", backgroundColor: "yellow", icon: "sticky-note", _layout_showTitle: "title", layout_borderRounding: "5px"},
+ { title: "Idea", backgroundColor: "pink", icon: "lightbulb" , _layout_showTitle: "title"},
+ { title: "Topic", backgroundColor: "lightblue", icon: "book-open" , _layout_showTitle: "title"}];
const reqdNoteList = [...reqdTempOpts.map(opts => {
const reqdOpts = {...opts, isSystem:true, width:200, layout_autoHeight: true, layout_fitWidth: true};
- const noteTemp = tempNotes ? DocListCast(tempNotes.data).find(doc => doc.title === opts.title): undefined;
+ const noteTemp = tempNotes ? DocListCast(tempNotes.data).find(fdoc => fdoc.title === opts.title): undefined;
return DocUtils.AssignOpts(noteTemp, reqdOpts) ?? MakeTemplate(Docs.Create.TextDocument("",reqdOpts));
}), ... DocListCast(tempNotes?.data).filter(note => !reqdTempOpts.find(reqd => reqd.title === note.title))];
const reqdOpts:DocumentOptions = { title: "Note Layouts", _height: 75, isSystem: true };
+ // eslint-disable-next-line no-return-assign
return DocUtils.AssignOpts(tempNotes, reqdOpts, reqdNoteList) ?? (doc[field] = Docs.Create.TreeDocument(reqdNoteList, reqdOpts));
}
+ static setupUserTemplates(doc: Doc, field="template_user") {
+ const tempUsers = DocCast(doc[field]);
+ const reqdUserList = DocListCast(tempUsers?.data);
+
+ const reqdOpts:DocumentOptions = { title: "User Layouts", _height: 75, isSystem: true };
+ // eslint-disable-next-line no-return-assign
+ return DocUtils.AssignOpts(tempUsers, reqdOpts, reqdUserList) ?? (doc[field] = Docs.Create.TreeDocument(reqdUserList, reqdOpts));
+ }
/// Initializes collection of templates for notes and click functions
static setupDocTemplates(doc: Doc, field="myTemplates") {
const templates = [
CurrentUserUtils.setupNoteTemplates(doc),
+ CurrentUserUtils.setupUserTemplates(doc),
CurrentUserUtils.setupClickEditorTemplates(doc)
];
CurrentUserUtils.setupChildClickEditors(doc)
@@ -151,24 +168,26 @@ export class CurrentUserUtils {
const reqdOpts = { title: "icon templates", _height: 75, isSystem: true };
const templateIconsDoc = DocUtils.AssignOpts(DocCast(doc[field]), reqdOpts) ?? (doc[field] = Docs.Create.TreeDocument([], reqdOpts));
+ const labelBox = (opts: DocumentOptions, fieldKey:string) => Docs.Create.LabelDocument({
+ layout: LabelBox.LayoutString(fieldKey), textTransform: "unset", letterSpacing: "unset", _singleLine: false, _label_minFontSize: 14, _label_maxFontSize: 14, layout_borderRounding: "5px", _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, ...opts
+ });
+ 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 curIcon = DocCast(templateIconsDoc[title]);
- let creator = labelBox;
- switch (opts.iconTemplate) {
- case DocumentType.IMG : creator = imageBox; break;
- case DocumentType.FONTICON: creator = fontBox; break;
- }
+ const creator = (() => { switch (opts.iconTemplate) {
+ case DocumentType.IMG : return imageBox;
+ case DocumentType.FONTICON: return fontBox;
+ default: return labelBox;
+ }})();
const allopts = {isSystem: true, onClickScriptDisable: "never", ...opts, title};
+ // eslint-disable-next-line no-return-assign
return DocUtils.AssignScripts( (curIcon?.iconTemplate === opts.iconTemplate ?
DocUtils.AssignOpts(curIcon, allopts):undefined) ?? ((templateIconsDoc[title] = MakeTemplate(creator(allopts, templateField)))),
{onClick:"deiconifyView(documentView)", onDoubleClick: "deiconifyViewToLightbox(documentView)", });
};
- const labelBox = (opts: DocumentOptions, fieldKey:string) => Docs.Create.LabelDocument({
- layout: LabelBox.LayoutString(fieldKey), textTransform: "unset", letterSpacing: "unset", _singleLine: false, _label_minFontSize: 14, _label_maxFontSize: 14, layout_borderRounding: "5px", _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, ...opts
- });
- 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 iconTemplates = [
makeIconTemplate(undefined, "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "dimgray"}),
makeIconTemplate(DocumentType.AUDIO, "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "lightgreen"}),
@@ -180,9 +199,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
+ // 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))
+ // makeIconTemplate(DocumentType.PDF, "icon", {iconTemplate:DocumentType.IMG}, (opts) => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", opts))
].filter(d => d).map(d => d!);
DocUtils.AssignOpts(DocCast(doc[field]), {}, iconTemplates);
}
@@ -212,43 +231,36 @@ export class CurrentUserUtils {
selection: { type: "text", anchor: 1, head: 1 },
storedMarks: []
};
- const headerBtnHgt = 10;
- const headerTemplate = (opts:DocumentOptions) => {
- const header = Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), { ...opts, title: "Untitled Header",
- layout:
- "<HTMLdiv transformOrigin='top left' width='{100/scale}%' height='{100/scale}%' transform='scale({scale})'>" +
- ` <FormattedTextBox {...props} dontScale='true' fieldKey={'text'} height='calc(100% - ${headerBtnHgt}px - {this._headerHeight||0}px)'/>` +
- " <FormattedTextBox {...props} dontScale='true' fieldKey={'header'} dontSelectOnLoad='true' ignoreAutoHeight='true' fontSize='{this._headerFontSize||9}px' height='{(this._headerHeight||0)}px' backgroundColor='{this._headerColor || MySharedDocs().userColor||`lightGray`}' />" +
- ` <HTMLdiv fontSize='${headerBtnHgt - 1}px' height='${headerBtnHgt}px' backgroundColor='yellow' onClick={‘(this._headerHeight=scale*Math.min(Math.max(0,this._height-30),this._headerHeight===0?50:0)) + (this._layout_autoHeightMargins=this._headerHeight ? this._headerHeight+${headerBtnHgt}:0)’} >Metadata</HTMLdiv>` +
- "</HTMLdiv>"
- }, "header");
// "<div style={'height:100%'}>" +
- // " <FormattedTextBox {...props} fieldKey={'header'} dontSelectOnLoad={'true'} ignoreAutoHeight={'true'} pointerEvents='{this._headerPointerEvents||`none`}' fontSize='{this._headerFontSize}px' height='{this._headerHeight}px' background='{this._headerColor||this.target.mySharedDocs.userColor}' />" +
- // " <FormattedTextBox {...props} fieldKey={'text'} position='absolute' top='{(this._headerHeight)*scale}px' height='calc({100/scale}% - {this._headerHeight}px)'/>" +
+ // " <FormattedTextBox {...props} fieldKey={'header'} dontSelectOnLoad={'true'} ignoreAutoHeight={'true'} pointerEvents='{this._header_pointerEvents||`none`}' fontSize='{this._header_fontSize}px' height='{this._header_height}px' background='{this._header_color}' />" +
+ // " <FormattedTextBox {...props} fieldKey={'text'} position='absolute' top='{(this._header_height)*scale}px' height='calc({100/scale}% - {this._header_height}px)'/>" +
// "</div>";
- MakeTemplate(Doc.GetProto(header));
- return header;
- }
- const slideView = (opts:DocumentOptions) => {
- const slide = Docs.Create.MultirowDocument(
+ const headerBtnHgt = 10;
+ const headerTemplate = (opts:DocumentOptions) =>
+ MakeTemplate(Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), { ...opts, title: "Header Template",
+ layout:`<HTMLdiv transformOrigin='top left' width='{100/scale}%' height='{100/scale}%' transform='scale({scale})'>
+ <FormattedTextBox {...props} dontScale='true' fieldKey={'text'} height='calc(100% - ${headerBtnHgt}px - {this._header_height||0}px)' />
+ <FormattedTextBox {...props} dontScale='true' fieldKey={'header'} dontSelectOnLoad='true' ignoreAutoHeight='true' fontSize='{this._header_fontSize||9}px' height='{(this._header_height||0)}px' backgroundColor='{this._header_color || "lightGray"}' />
+ <HTMLdiv fontSize='${headerBtnHgt - 1}px' height='${headerBtnHgt}px' backgroundColor='yellow' onClick={‘(this._header_height=Math.min(Math.max(0,this._height-30),this._header_height===0?50:0)) + (this._layout_autoHeightMargins=this._header_height ? this._header_height+${headerBtnHgt}:0)’} > Metadata</HTMLdiv>
+ </HTMLdiv>`
+ }, "header"));
+ const slideView = (opts:DocumentOptions) =>
+ MakeTemplate(Docs.Create.MultirowDocument(
[
Docs.Create.MulticolumnDocument([], { title: "hero", _height: 200, isSystem: true }),
Docs.Create.TextDocument("", { title: "text", _layout_fitWidth:true, _height: 100, isSystem: true, _text_fontFamily: StrCast(Doc.UserDoc().fontFamily), _text_fontSize: StrCast(Doc.UserDoc().fontSize) })
- ], {...opts, title: "Untitled Slide View"});
-
- MakeTemplate(Doc.GetProto(slide));
- return slide;
- }
+ ], {...opts, title: "Slide View Template"}));
const plotlyApi = () => {
- var plotly = Doc.MyPublishedDocs.find(doc => doc.title === "@plotly");
+ let plotly = Doc.MyPublishedDocs.find(fdoc => fdoc.title === "@plotly");
if (!plotly) {
- const plotly = Docs.Create.TextDocument(
+ plotly = Docs.Create.TextDocument(
`await import("https://cdn.plot.ly/plotly-2.27.0.min.js");
Plotly.newPlot(dashDiv.id, [ --DOCDATA-- ])`
, {title: "@plotly", title_custom: true, _layout_showTitle:"title", _width:300,_height:400});
Doc.AddToMyPublished(plotly);
}
+ return plotly;
}
const plotlyView = (opts:DocumentOptions) => {
const rtfield = new RichTextField(JSON.stringify(
@@ -280,10 +292,10 @@ export class CurrentUserUtils {
return slide;
}
const mermaidsApi = () => {
- var mermaids = Doc.MyPublishedDocs.find(doc => doc.title === "@mermaids");
+ let mermaids = Doc.MyPublishedDocs.find(fdoc => fdoc.title === "@mermaids");
if (!mermaids) {
- const mermaids = Docs.Create.TextDocument(
- `const mdef = (await import("https://cdn.jsdelivr.net/npm/mermaid\@10.8.0/dist/mermaid.esm.min.mjs")).default;
+ mermaids = Docs.Create.TextDocument(
+ `const mdef = (await import("https://cdn.jsdelivr.net/npm/mermaid@10.8.0/dist/mermaid.esm.min.mjs")).default;
window["callb"] = (x) => {
alert(x);
}
@@ -301,6 +313,7 @@ export class CurrentUserUtils {
, {title: "@mermaids", title_custom: true, _layout_showTitle:"title", _width:300,_height:400});
Doc.AddToMyPublished(mermaids);
}
+ return mermaids;
}
const mermaidsView = (opts:DocumentOptions) => {
const rtfield = new RichTextField(JSON.stringify(
@@ -313,9 +326,9 @@ export class CurrentUserUtils {
{type:"text",text:" "},
{type:"text",text:"Minerals in my tap water"},
{type:"text",text:"\n \"Calcium\" : "},
- {type:"dashField",attrs:{fieldKey:"calcium",docId:"","hideKey":false,editable:true}},
+ {type:"dashField",attrs:{fieldKey:"calcium",docId:"",hideKey:true,hideValue:false,editable:true}},
{type:"text",text:"\n \"Potassium\" : "},
- {type:"dashField",attrs:{fieldKey:"pot",docId:"",hideKey:false,editable:true}},
+ {type:"dashField",attrs:{fieldKey:"pot",docId:"",hideKey:true,hideValue:false,editable:true}},
{type:"text",text:"\n \"Magnesium\" : 10.01"}
]}
]},
@@ -333,7 +346,7 @@ pie title Minerals in my tap water
slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"});
return slide;
}
- const apis = [plotlyApi(), mermaidsApi()]
+ 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
@@ -341,21 +354,26 @@ pie title Minerals in my tap water
creator:(opts:DocumentOptions)=> any // 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}},
+ {key: "Flashcard", creator: opts => Docs.Create.ComparisonDocument("", opts), opts: { _layout_isFlashcard: true, _width: 300, _height: 300}},
+ // {key: "Flashcard", creator: opts => Docs.Create.TextDocument("", opts), opts: { _width: 200, _layout_autoHeight: true, _layout_enableAltContentUI: true}},
+ {key: "Image", creator: opts => Docs.Create.ImageDocument("", opts), opts: { _width: 400, _height:400 }},
{key: "Equation", creator: opts => Docs.Create.EquationDocument("",opts), opts: { _width: 300, _height: 35, }},
{key: "Noteboard", creator: opts => Docs.Create.NoteTakingDocument([], opts), opts: { _width: 250, _height: 200, _layout_fitWidth: true}},
{key: "Simulation", creator: opts => Docs.Create.SimulationDocument(opts), opts: { _width: 300, _height: 300, }},
{key: "Collection", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 150, _height: 100, _layout_fitWidth: true }},
{key: "Webpage", creator: opts => Docs.Create.WebDocument("",opts), opts: { _width: 400, _height: 512, _nativeWidth: 850, data_useCors: true, }},
- {key: "Comparison", creator: opts => Docs.Create.ComparisonDocument("",opts), opts: { _width: 300, _height: 300 }},
+ {key: "Comparison", creator: opts => Docs.Create.ComparisonDocument("",opts), opts: { _width: 300, _height: 300 }},
+ {key: "Diagram", creator: Docs.Create.DiagramDocument, opts: { _width: 300, _height: 300, _type_collection: CollectionViewType.Freeform, layout_diagramEditor: CollectionView.LayoutString("data") }, scripts: { onPaint: `toggleDetail(documentView, "diagramEditor","")`}},
{key: "Audio", creator: opts => Docs.Create.AudioDocument(nullAudio, opts),opts: { _width: 200, _height: 100, }},
+ {key: "Audio", creator: opts => Docs.Create.AudioDocument(nullAudio, opts),opts: { _width: 200, _height: 100, _layout_fitWidth: true, }},
{key: "Map", creator: opts => Docs.Create.MapDocument([], opts), opts: { _width: 800, _height: 600, _layout_fitWidth: true, }},
{key: "Screengrab", creator: Docs.Create.ScreenshotDocument, opts: { _width: 400, _height: 200 }},
{key: "WebCam", creator: opts => Docs.Create.WebCamDocument("", opts), opts: { _width: 400, _height: 200, recording:true, isSystem: true, cloneFieldFilter: new List<string>(["isSystem"]) }},
{key: "Button", creator: Docs.Create.ButtonDocument, opts: { _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, title_custom: true, waitForDoubleClickToClick: 'never'}, scripts: {onClick: FollowLinkScript()?.script.originalScript ?? ""}},
{key: "Script", creator: opts => Docs.Create.ScriptingDocument(null, opts), opts: { _width: 200, _height: 250, }},
{key: "DataViz", creator: opts => Docs.Create.DataVizDocument("/users/rz/Downloads/addresses.csv", opts), opts: { _width: 300, _height: 300 }},
- {key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 70, _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _layout_autoHeight: true, treeView_HideUnrendered: true}},
+ {key: "Chat", creator: Docs.Create.ChatDocument, opts: { _width: 300, _height: 300, }},
+ {key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 120, _header_pointerEvents: "all", _header_height: 50, _header_fontSize: 9,_layout_autoHeightMargins: 50, _layout_autoHeight: true, treeView_HideUnrendered: true}},
{key: "ViewSlide", creator: slideView, opts: { _width: 400, _height: 300, _xMargin: 3, _yMargin: 3,}},
{key: "Trail", creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 30, _type_collection: CollectionViewType.Stacking, dropAction: dropActionType.embed, treeView_HideTitle: true, _layout_fitWidth:true, layout_boxShadow: "0 0" }},
{key: "Tab", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 500, _height: 800, _layout_fitWidth: true, _freeform_backgroundGrid: true, }},
@@ -368,27 +386,33 @@ pie title Minerals in my tap water
{key: "Plotly", creator: plotlyView, opts: { _width: 300, _height: 300, }},
];
- emptyThings.forEach(thing => DocUtils.AssignDocField(doc, "empty"+thing.key, (opts) => thing.creator(opts), {...standardOps(thing.key), ...thing.opts}, undefined, thing.scripts, thing.funcs));
+ emptyThings.forEach(
+ thing =>{ DocUtils.AssignDocField(doc, "empty"+thing.key, (opts) => thing.creator(opts), {...standardOps(thing.key), ...thing.opts}, undefined, thing.scripts, thing.funcs);
+ console.log(thing.key)
+ });
return [
{ toolTip: "Tap or drag to create a note", title: "Note", icon: "sticky-note", dragFactory: doc.emptyNote as Doc, clickFactory: DocCast(doc.emptyNote)},
{ toolTip: "Tap or drag to create a flashcard", title: "Flashcard", icon: "id-card", dragFactory: doc.emptyFlashcard as Doc, clickFactory: DocCast(doc.emptyFlashcard)},
{ toolTip: "Tap or drag to create an equation", title: "Math", icon: "calculator", dragFactory: doc.emptyEquation as Doc, clickFactory: DocCast(doc.emptyEquation)},
{ toolTip: "Tap or drag to create a mermaid node", title: "Mermaids", icon: "rocket", dragFactory: doc.emptyMermaids as Doc, clickFactory: DocCast(doc.emptyMermaids)},
- { toolTip: "Tap or drag to create a plotly node", title: "Plotly", icon: "rocket", dragFactory: doc.emptyPlotly as Doc, clickFactory: DocCast(doc.emptyMermaids)},
+ { toolTip: "Tap or drag to create a plotly node", title: "Plotly", icon: "rocket", dragFactory: doc.emptyPlotly as Doc, clickFactory: DocCast(doc.emptyMermaids)},
{ toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation), funcs: { hidden: "IsNoviceMode()"}},
- { toolTip: "Tap or drag to create a note board", title: "Notes", icon: "book", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)},
+ { toolTip: "Tap or drag to create a note board", title: "Notes", icon: "book", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)},
+ { toolTip: "Tap or drag to create an iamge", title: "Image", icon: "image", dragFactory: doc.emptyImage as Doc, clickFactory: DocCast(doc.emptyImage)},
{ 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 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)},
{ toolTip: "Tap or drag to create a screen grabber", title: "Grab", icon: "photo-video", dragFactory: doc.emptyScreengrab as Doc, clickFactory: DocCast(doc.emptyScreengrab), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a WebCam recorder", title: "WebCam", icon: "photo-video", dragFactory: doc.emptyWebCam as Doc, clickFactory: DocCast(doc.emptyWebCam), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
- { 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 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 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: '<ScriptingRepl />' as any, openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script
@@ -404,7 +428,7 @@ pie title Minerals in my tap water
/// Initalizes the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools
static setupCreatorButtons(doc: Doc, dragCreatorDoc?:Doc):Doc {
const creatorBtns = CurrentUserUtils.creatorBtnDescriptors(doc).map((reqdOpts) => {
- const btn = dragCreatorDoc ? DocListCast(dragCreatorDoc.data).find(doc => doc.title === reqdOpts.title): undefined;
+ const btn = dragCreatorDoc ? DocListCast(dragCreatorDoc.data).find(fdoc => fdoc.title === reqdOpts.title): undefined;
const opts:DocumentOptions = {...OmitKeys(reqdOpts, ["funcs", "scripts", "backgroundColor"]).omit,
_width: 60, _height: 60, _dragOnlyWithinContainer: true,
btnType: ButtonType.ToolButton, backgroundColor: reqdOpts.backgroundColor ?? Colors.DARK_GRAY, color: Colors.WHITE, isSystem: true,
@@ -448,7 +472,7 @@ pie title Minerals in my tap water
this.setupLeftSidebarPanel(doc);
const myLeftSidebarMenu = DocCast(doc[field]);
const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions(doc).map(({ title, target, icon, toolTip, hidden, scripts, funcs }) => {
- const btnDoc = myLeftSidebarMenu ? DocListCast(myLeftSidebarMenu.data).find(doc => doc.title === title) : undefined;
+ const btnDoc = myLeftSidebarMenu ? DocListCast(myLeftSidebarMenu.data).find(fdoc => fdoc.title === title) : undefined;
const reqdBtnOpts:DocumentOptions = {
title, icon, target, toolTip, hidden, btnType: ButtonType.MenuButton, isSystem: true, undoIgnoreFields: new List<string>(['height', 'data_columnHeaders']), dontRegisterView: true,
_width: 60, _height: 60, _dragOnlyWithinContainer: true,
@@ -463,83 +487,9 @@ pie title Minerals in my tap water
return DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(items??[], opts), reqdStackOpts, menuBtns, { dropConverter: "convertToButtons(dragData)" });
}
- // Sets up mobile menu if it is undefined creates a new one, otherwise returns existing menu
- static setupActiveMobileMenu(doc: Doc, field="activeMobileMenu") {
- const reqdOpts = { _width: 980, ignoreClick: true, _lockedPosition: false, title: "home", _yMargin: 100, isSystem: true, _chromeHidden: true,};
- DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(this.setupMobileButtons(), opts), reqdOpts);
- }
-
- // Sets up mobile buttons for inside mobile menu
- static setupMobileButtons(doc?: Doc, buttons?: string[]) {
- return [];
- const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
- { title: "DASHBOARDS", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Dashboards from your mobile, and navigate through all of your documents. " },
- { title: "UPLOAD", icon: "upload", click: 'openMobileUploads()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." },
- { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploadCollection()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." },
- { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey", info: "Use your phone to record, dictate and then upload audio onto Dash Web." },
- { title: "PRESENTATION", icon: "desktop", click: 'switchToMobilePresentation()', backgroundColor: "lightgrey", info: "Use your phone as a remote for you presentation." },
- { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey", info: "Change your password, log out, or manage your account security." }
- ];
- // returns a list of mobile buttons
- return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data =>
- this.mobileButton({
- title: data.title,
- _lockedPosition: true,
- onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
- backgroundColor: data.backgroundColor, isSystem: true
- },
- [this.createToolButton({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", isSystem: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
- );
- }
-
- // sets up the main document for the mobile button
- static mobileButton = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MulticolumnDocument(docs, {
- ...opts,
- _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15,
- layout_borderRounding: "5px", layout_boxShadow: "0 0", isSystem: true
- }) as any as Doc
-
- // sets up the text container for the information contained within the mobile button
- static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MultirowDocument(docs, {
- ...opts,
- _nativeWidth: 450, _nativeHeight: 250, _width: 450, _height: 250, _yMargin: 25,
- backgroundColor: "rgba(0,0,0,0)", layout_borderRounding: "0", layout_boxShadow: "0 0", ignoreClick: true, isSystem: true
- }) as any as Doc
-
- // Sets up the title of the button
- static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => Docs.Create.TextDocument(buttonTitle, {
- ...opts,
- title: buttonTitle, _text_fontSize: "37px", _xMargin: 0, _yMargin: 0, ignoreClick: true, backgroundColor: "rgba(0,0,0,0)", isSystem: true
- }) as any as Doc
-
- // Sets up the description of the button
- static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => Docs.Create.TextDocument(buttonInfo, {
- ...opts,
- title: "info", _text_fontSize: "25px", _xMargin: 0, _yMargin: 0, ignoreClick: true, backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2, isSystem: true
- }) as any as Doc
-
-
-
- static setupMobileInkingDoc(userDoc: Doc) {
- return Docs.Create.FreeformDocument([], { title: "Mobile Inking", backgroundColor: "white", isSystem: true });
- }
-
- static setupMobileUploadDoc(userDoc: Doc) {
- // const addButton = Docs.Create.FontIconDocument({ onDragStart: ScriptField.MakeScript('addWebToMobileUpload()'), title: "Add Web Doc to Upload Collection", icon: "plus", backgroundColor: "black" })
- const webDoc = Docs.Create.WebDocument("https://www.britannica.com/biography/Miles-Davis", {
- title: "Upload Images From the Web", _lockedPosition: true, isSystem: true
- });
- const uploadDoc = Docs.Create.StackingDocument([], {
- title: "Mobile Upload Collection", backgroundColor: "white", _lockedPosition: true, isSystem: true, _chromeHidden: true,
- });
- return Docs.Create.StackingDocument([webDoc, uploadDoc], {
- _width: screen.width, _lockedPosition: true, title: "Upload", _layout_autoHeight: true, _yMargin: 80, backgroundColor: "lightgray", isSystem: true, _chromeHidden: true,
- });
- }
-
/// Search option on the left side button panel
static setupSearcher(doc: Doc, field:string) {
- return DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.SearchDocument(opts), {
+ return DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.SearchDocument(opts), {
dontRegisterView: true, backgroundColor: "dimgray", ignoreClick: true, title: "Search Panel", isSystem: true, childDragAction: dropActionType.embed,
_lockedPosition: true, _type_collection: CollectionViewType.Schema });
}
@@ -550,7 +500,7 @@ pie title Minerals in my tap water
const creatorBtns = CurrentUserUtils.setupCreatorButtons(doc, allTools?.length ? allTools[0]:undefined);
const userTools = allTools && allTools?.length > 1 ? allTools[1]:undefined;
const userBtns = CurrentUserUtils.setupUserDocumentCreatorButtons(doc, userTools);
- //doc.myUserBtns = new PrefetchProxy(userBtns);
+ // doc.myUserBtns = new PrefetchProxy(userBtns);
const reqdToolOps:DocumentOptions = {
title: "My Tools", isSystem: true, ignoreClick: true, layout_boxShadow: "0 0",
layout_explainer: "This is a palette of documents that can be created.",
@@ -561,7 +511,7 @@ pie title Minerals in my tap water
/// initializes the left sidebar dashboard pane
static setupDashboards(doc: Doc, field:string) {
- var myDashboards = DocCast(doc[field]);
+ let myDashboards = DocCast(doc[field]);
const newDashboard = `createNewDashboard()`;
@@ -570,9 +520,9 @@ pie title Minerals in my tap water
const reqdBtnScript = {onClick: newDashboard,}
const newDashboardButton = DocUtils.AssignScripts(DocUtils.AssignOpts(DocCast(myDashboards?.layout_headerButton), reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript);
- const contextMenuScripts = [/*newDashboard*/] as string[];
- const contextMenuLabels = [/*"Create New Dashboard"*/] as string[];
- const contextMenuIcons = [/*"plus"*/] as string[];
+ const contextMenuScripts = [/* newDashboard */] as string[];
+ 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 childContextMenuLabels = ["Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters
@@ -603,7 +553,7 @@ pie title Minerals in my tap water
/// initializes the left sidebar File system pane
static setupFilesystem(doc: Doc, field:string) {
- var myFilesystem = DocCast(doc[field]);
+ const myFilesystem = DocCast(doc[field]);
const newFolderOpts: DocumentOptions = {
_forceActive: true, _dragOnlyWithinContainer: true, _embedContainer: Doc.MyFilesystem, _width: 30, _height: 30, undoIgnoreFields:new List<string>(['treeView_SortCriterion']),
@@ -648,7 +598,7 @@ pie title Minerals in my tap water
/// initializes the left sidebar panel view of the UserDoc
static setupUserDocView(doc: Doc, field:string) {
const reqdOpts:DocumentOptions = {
- _lockedPosition: true, _gridGap: 5, _forceActive: true, title: Doc.CurrentUserEmail +"-view",
+ _lockedPosition: true, _gridGap: 5, _forceActive: true, title: ClientUtils.CurrentUserEmail() +"-view",
layout_boxShadow: "0 0", childDontRegisterViews: true, dropAction: dropActionType.same, ignoreClick: true, isSystem: true,
treeView_HideTitle: true, treeView_TruncateTitleWidth: 350
};
@@ -669,14 +619,14 @@ pie title Minerals in my tap water
static createToolButton = (opts: DocumentOptions) => Docs.Create.FontIconDocument({
btnType: ButtonType.ToolButton, _dropPropertiesToRemove: new List<string>([ "layout_hideContextMenu"]),
- /*_nativeWidth: 40, _nativeHeight: 40, */ _width: 40, _height: 40, isSystem: true, ...opts,
+ /* _nativeWidth: 40, _nativeHeight: 40, */ _width: 40, _height: 40, isSystem: true, ...opts,
})
/// initializes the required buttons in the expanding button menu at the bottom of the Dash window
static setupDockedButtons(doc: Doc, field="myDockedBtns") {
const dockedBtns = DocCast(doc[field]);
const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:string}) =>
- DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === opts.title), opts) ??
+ 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
@@ -692,8 +642,8 @@ pie title Minerals in my tap water
title: "docked buttons", _height: 40, flexGap: 0, layout_boxShadow: "standard", childDragAction: dropActionType.move,
childDontRegisterViews: true, linearView_IsOpen: true, linearView_Expandable: true, ignoreClick: true
};
- reaction(() => UndoManager.redoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "Redo")!).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true });
- reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "Undo")!).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true });
+ reaction(() => UndoManager.redoStack.slice(), () => { Doc.GetProto(btns.find(btn => btn.title === "Redo")!).opacity = UndoManager.CanRedo() ? 1 : 0.4; }, { fireImmediately: true });
+ reaction(() => UndoManager.undoStack.slice(), () => { Doc.GetProto(btns.find(btn => btn.title === "Undo")!).opacity = UndoManager.CanUndo() ? 1 : 0.4; }, { fireImmediately: true });
return DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), dockBtnsReqdOpts, btns);
}
@@ -709,6 +659,36 @@ pie title Minerals in my tap water
{ title: "Center", icon: "align-center", toolTip: "Center Align Stack", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"center", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
]
}
+ static cardTools(): Button[] {
+ return [
+ { title: "Time", icon:"hourglass-half", toolTip:"Sort by most recent document creation", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"time", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Type", icon:"eye", toolTip:"Sort by document type", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"docType",funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Color", icon:"palette", toolTip:"Sort by document color", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"color", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ ]
+ }
+ static labelTools(): Button[] {
+ return [
+ { title: "AI", icon:"robot", toolTip:"Add AI labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"chat", funcs: {hidden:`showFreeform ("chat", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "AIs", icon:"AI Sort", toolTip:"Filter AI labels", subMenu: this.cardGroupTools("chat"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("chat", true)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} },
+ { title: "Like", icon:"heart", toolTip:"Add Like labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"like", funcs: {hidden:`showFreeform ("like", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Likes", icon:"Likes", toolTip:"Filter likes", width: 10, subMenu: this.cardGroupTools("heart"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("like", true)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} },
+ { title: "Star", icon:"star", toolTip:"Add Star labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {hidden:`showFreeform ("star", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Stars", icon:"Stars", toolTip:"Filter stars", width: 80, subMenu: this.cardGroupTools("star"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("star", true)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} },
+ { title: "Idea", icon:"satellite", toolTip:"Add Idea labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"idea", funcs: {hidden:`showFreeform ("idea", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Ideas", icon:"Ideas", toolTip:"Filter ideas", width: 80, subMenu: this.cardGroupTools("satellite"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("idea", true)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} },
+ ]
+ }
+ static cardGroupTools(icon: string): Button[] {
+ return [
+ { title: "1", icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"1", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "2", icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"2", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "3", icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"3", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "4", icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"4", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "5", icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"5", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "6", icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"6", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "7", icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"7", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ ]
+ }
static viewTools(): Button[] {
return [
{ title: "Snap", icon: "th", toolTip: "Show Snap Lines", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"snaplines", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
@@ -717,6 +697,7 @@ pie title Minerals in my tap water
{ title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"clusters", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
{ title: "Cards", icon: "brain", toolTip: "Flashcards", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"flashcards", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
{ title: "Arrange", icon:"arrow-down-short-wide",toolTip:"Toggle Auto Arrange", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"arrange", funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+
]
}
static textTools():Button[] {
@@ -725,7 +706,7 @@ pie title Minerals in my tap water
btnList: new List<string>(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]) },
{ title: "Font Size",toolTip: "Font size (%size)", btnType: ButtonType.NumberDropdownButton, toolType:"fontSize", ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'}, numBtnMax: 200, numBtnMin: 6 },
{ title: "Color", toolTip: "Font color (%color)", btnType: ButtonType.ColorButton, icon: "font", toolType:"fontColor",ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'}},
- { title: "Highlight",toolTip: "Font highlight", btnType: ButtonType.ColorButton, icon: "highlighter", toolType:"highlight",ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'},funcs: {hidden: "IsNoviceMode()"} },
+ { title: "Highlight",toolTip: "Font highlight", btnType: ButtonType.ColorButton, icon: "highlighter", toolType:"highlight",ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'}},
{ title: "Bold", toolTip: "Bold (Ctrl+B)", btnType: ButtonType.ToggleButton, icon: "bold", toolType:"bold", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
{ title: "Italic", toolTip: "Italic (Ctrl+I)", btnType: ButtonType.ToggleButton, icon: "italic", toolType:"italics", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
{ title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", toolType:"underline",ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
@@ -738,6 +719,7 @@ pie title Minerals in my tap water
{ title: "Center", toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center",ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
{ title: "Right", toolTip: "Right align (Cmd-])", btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
]},
+ { title: "Elide", toolTip: "Elide selection", btnType: ButtonType.ToggleButton, icon: "eye", toolType:"elide", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'}},
{ title: "Dictate", toolTip: "Dictate", btnType: ButtonType.ToggleButton, icon: "microphone", toolType:"dictation", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'}},
{ title: "NoLink", toolTip: "Auto Link", btnType: ButtonType.ToggleButton, icon: "link", toolType:"noAutoLink", expertMode:true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'}, funcs: {hidden: 'IsNoviceMode()'}},
// { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", scripts: {onClick:: 'toggleStrikethrough()'}},
@@ -751,10 +733,11 @@ pie title Minerals in my tap water
{ title: "Pen", toolTip: "Pen (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen-nib", toolType: "pen", scripts: {onClick:'{ return setActiveTool(this.toolType, false, _readOnly_);}' }},
{ title: "Write", toolTip: "Write (Ctrl+Shift+P)", btnType: ButtonType.ToggleButton, icon: "pen", toolType: "write", scripts: {onClick:'{ return setActiveTool(this.toolType, false, _readOnly_);}' }, funcs: {hidden:"IsNoviceMode()" }},
{ title: "Eraser", toolTip: "Eraser (Ctrl+E)", btnType: ButtonType.ToggleButton, icon: "eraser", toolType: "eraser", scripts: {onClick:'{ return setActiveTool(this.toolType, false, _readOnly_);}' }, funcs: {hidden:"IsNoviceMode()" }},
- { title: "Circle", toolTip: "Circle (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "circle", toolType:GestureUtils.Gestures.Circle, scripts: {onClick:`{ return setActiveTool(this.toolType, false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool(this.toolType, true, _readOnly_);}`} },
- { title: "Square", toolTip: "Square (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "square", toolType:GestureUtils.Gestures.Rectangle, scripts: {onClick:`{ return setActiveTool(this.toolType, false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool(this.toolType, true, _readOnly_);}`} },
- { title: "Line", toolTip: "Line (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "minus", toolType:GestureUtils.Gestures.Line, scripts: {onClick:`{ return setActiveTool(this.toolType, false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool(this.toolType, true, _readOnly_);}`} },
+ { title: "Circle", toolTip: "Circle (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "circle", toolType: Gestures.Circle, scripts: {onClick:`{ return setActiveTool(this.toolType, false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool(this.toolType, true, _readOnly_);}`} },
+ { title: "Square", toolTip: "Square (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "square", toolType: Gestures.Rectangle, scripts: {onClick:`{ return setActiveTool(this.toolType, false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool(this.toolType, true, _readOnly_);}`} },
+ { title: "Line", toolTip: "Line (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "minus", toolType: Gestures.Line, scripts: {onClick:`{ return setActiveTool(this.toolType, false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool(this.toolType, true, _readOnly_);}`} },
{ title: "Mask", toolTip: "Mask", btnType: ButtonType.ToggleButton, icon: "user-circle",toolType: "inkMask", scripts: {onClick:'{ return setInkProperty(this.toolType, value, _readOnly_);}'}, funcs: {hidden:"IsNoviceMode()" } },
+ { title: "Labels", toolTip: "Lab els", btnType: ButtonType.ToggleButton, icon: "text-width", toolType: "labels", scripts: {onClick:'{ return setInkProperty(this.toolType, value, _readOnly_);}'}, },
{ title: "Width", toolTip: "Stroke width", btnType: ButtonType.NumberSliderButton, toolType: "strokeWidth", ignoreClick: true, scripts: {script: '{ return setInkProperty(this.toolType, value, _readOnly_);}'}, numBtnMin: 1},
{ title: "Ink", toolTip: "Stroke color", btnType: ButtonType.ColorButton, icon: "pen", toolType: "strokeColor", ignoreClick: true, scripts: {script: '{ return setInkProperty(this.toolType, value, _readOnly_);}'} },
];
@@ -763,7 +746,7 @@ pie title Minerals in my tap water
static schemaTools():Button[] {
return [
{title: "Preview", toolTip: "Show selection preview", btnType: ButtonType.ToggleButton, icon: "portrait", scripts:{ onClick: '{ return toggleSchemaPreview(_readOnly_); }'} },
- {title: "1 Line", toolTip: "Single Line Rows", btnType: ButtonType.ToggleButton, icon: "eye", scripts:{ onClick: '{ return toggleSingleLineSchema(_readOnly_); }'} },
+ {title: "1 Line", toolTip: "Single Line Rows", btnType: ButtonType.ToggleButton, icon: "eye", scripts:{ onClick: '{ return toggleSingleLineSchema(_readOnly_); }'} },
{title: "DataViz", toolTip: "Turn Schema Table into Data Visualization Doc", btnType: ButtonType.ClickButton, icon: "chart-bar", scripts:{ onClick: '{ datavizFromSchema()'} }, ];
}
@@ -771,12 +754,18 @@ pie title Minerals in my tap water
return [
{ title: "Back", toolTip: "Go back", btnType: ButtonType.ClickButton, icon: "arrow-left", scripts: { onClick: '{ return webBack(); }' }},
{ title: "Forward", toolTip: "Go forward", btnType: ButtonType.ClickButton, icon: "arrow-right", scripts: { onClick: '{ return webForward(); }'}},
- { title: "URL", toolTip: "URL", width: 250, btnType: ButtonType.EditableText, icon: "lock", ignoreClick: true, scripts: { script: '{ return webSetURL(value, _readOnly_); }'} },
+ { title: "URL", toolTip: "URL", width: 250, btnType: ButtonType.EditText, icon: "lock", ignoreClick: true, scripts: { script: '{ return webSetURL(value, _readOnly_); }'} },
];
}
static videoTools() {
return [
- { title: "Snapshot",toolTip: "Take snapshot of current frame", btnType: ButtonType.ClickButton, icon: "camera", scripts: { onClick: '{ return videoSnapshot(); }' }},
+ { title: "Snapshot",toolTip: "Take snapshot of current frame", btnType: ButtonType.ClickButton, icon: "camera", scripts: { onClick: '{ return videoSnapshot(); }' }},
+ ];
+ }
+ static imageTools() {
+ return [
+ { title: "Pixels",toolTip: "Set Native Pixel Sizze", btnType: ButtonType.ClickButton, icon: "portrait", scripts: { onClick: 'imageSetPixelSize();' }},
+ { title: "Rotate",toolTip: "Rotate 90", btnType: ButtonType.ClickButton, icon: "redo-alt", scripts: { onClick: 'imageRotate90();' }},
];
}
static contextMenuTools():Button[] {
@@ -784,30 +773,33 @@ pie title Minerals in my tap water
{ btnList: new List<string>([CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Tree,
CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Multicolumn,
CollectionViewType.Multirow, CollectionViewType.Time, CollectionViewType.Carousel,
- CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map,
- CollectionViewType.Grid, CollectionViewType.NoteTaking]),
- title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}},
+ CollectionViewType.Carousel3D, CollectionViewType.Card, CollectionViewType.Linear, CollectionViewType.Map,
+ CollectionViewType.Grid, CollectionViewType.NoteTaking, ]),
+ title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: '{ return setView(value, _readOnly_); }'}},
{ title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}, funcs: {hidden: "IsNoneSelected()"}},
{ title: "Header", icon: "heading", toolTip: "Doc Titlebar Color", btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'} },
{ title: "Template",icon: "scroll", toolTip: "Default Note Template",btnType: ButtonType.ToggleButton, expertMode: false, toolType:DocumentType.RTF, scripts: { onClick: '{ return setDefaultTemplate(_readOnly_); }'} },
{ title: "Fill", icon: "fill-drip", toolTip: "Fill/Background Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 30, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, // Only when a document is selected
- { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(this.toolType, this.expertMode, true)'}, scripts: { onClick: '{ return toggleOverlay(_readOnly_); }'}}, // Only when floating document is selected in freeform
- { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(this.toolType, this.expertMode)'}, width: 30, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}},
- { title: "Num", icon:"", toolTip: "Frame # (click to toggle edit mode)",btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(this.toolType, this.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}},
- { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(this.toolType, this.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}},
- { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
- { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: {hidden: `IsExploreMode()`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
- { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode, true)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
- { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
- { title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
- { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected
- { title: "Video", icon: "Video", toolTip: "Video functions", subMenu: CurrentUserUtils.videoTools(), expertMode: false, toolType:DocumentType.VID, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected
- { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(),expertMode: false,toolType:CollectionViewType.Schema,funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when Schema is selected
+ { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode, true)'}, scripts: { onClick: '{ return toggleOverlay(_readOnly_); }'}}, // Only when floating document is selected in freeform
+ { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'}, width: 30, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}},
+ { title: "Num", icon:"", toolTip: "Frame # (click to toggle edit mode)",btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}},
+ { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}},
+ { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: {hidden: `IsExploreMode()`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
+ { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode, true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Card", icon: "Sort", toolTip: "Card sort", subMenu: CurrentUserUtils.cardTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Label", icon: "Label", toolTip: "Assign card labels", subMenu: CurrentUserUtils.labelTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected
+ { title: "Video", icon: "Video", toolTip: "Video functions", subMenu: CurrentUserUtils.videoTools(), expertMode: false, toolType:DocumentType.VID, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when video is selected
+ { title: "Image", icon: "Image", toolTip: "Image functions", subMenu: CurrentUserUtils.imageTools(), expertMode: false, toolType:DocumentType.IMG, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when image is selected
+ { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(),expertMode: false,toolType:CollectionViewType.Schema,funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when Schema is selected
];
}
/// initializes a context menu button for the top bar context menu
- static setupContextMenuButton(params:Button, btnDoc?:Doc) {
+ static setupContextMenuButton(params:Button, btnDoc?:Doc, btnContainer?:Doc) {
const reqdOpts:DocumentOptions = {
...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit,
color: Colors.WHITE, isSystem: true,
@@ -815,6 +807,7 @@ pie title Minerals in my tap water
_height: 30, _nativeHeight: 30, linearBtnWidth: params.linearBtnWidth,
toolType: params.toolType, expertMode: params.expertMode,
_dragOnlyWithinContainer: true, _lockedPosition: true,
+ _embedContainer: btnContainer
};
const reqdFuncs:{[key:string]:any} = {
...params.funcs,
@@ -824,17 +817,17 @@ pie title Minerals in my tap water
static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc {
- const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title);
- const subMenu = params.subMenu;
+ const menuBtnDoc = DocListCast(menuDoc?.data).find( doc => doc.title === params.title);
+ const {subMenu} = params;
if (!subMenu) { // button does not have a sub menu
- return this.setupContextMenuButton(params, menuBtnDoc);
+ return this.setupContextMenuButton(params, menuBtnDoc, menuDoc);
}
// linear view
const reqdSubMenuOpts = { ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, undoIgnoreFields: new List<string>(['width', "linearView_IsOpen"]),
- childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: params.scripts?.onClick ? false : true,
- linearView_SubMenu: true, linearView_Expandable: true};
+ childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: !params.scripts?.onClick,
+ linearView_SubMenu: true, linearView_Expandable: true, embedContainer: menuDoc};
- const items = (menuBtnDoc?:Doc) => !menuBtnDoc ? [] : subMenu.map(sub => this.setupContextMenuBtn(sub, menuBtnDoc) );
+ const items = (menutBtn?:Doc) => !menutBtn ? [] : subMenu.map(sub => this.setupContextMenuBtn(sub, menutBtn) );
const creator = params.btnType === ButtonType.MultiToggleButton ? this.multiToggleList : this.linearButtonList;
const btnDoc = DocUtils.AssignScripts( DocUtils.AssignDocField(menuDoc, StrCast(params.title),
(opts) => creator(opts, items(menuBtnDoc)), reqdSubMenuOpts, items(menuBtnDoc)), params.scripts, params.funcs);
@@ -856,17 +849,17 @@ pie title Minerals in my tap water
Doc.UserDoc().workspaceReplayingState = undefined;
const dockedBtns = DocCast(doc[field]);
const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:any}) =>
- DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === opts.title), opts) ??
+ 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: "Play", icon: "play", toolTip: "Play recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Paused}"`}, scripts: { onClick: `resumeWorkspaceReplaying(getCurrentRecording())`}},
- { opts: { title: "Pause", icon: "pause",toolTip: "Pause playback", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Playing}"`}, scripts: { onClick: `pauseWorkspaceReplaying(getCurrentRecording())`}},
- { opts: { title: "Stop", icon: "stop", toolTip: "Stop playback", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Paused}"`}, scripts: { onClick: `stopWorkspaceReplaying(getCurrentRecording())`}},
- { opts: { title: "Delete", icon: "trash",toolTip: "delete selected rec", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Paused}"`}, scripts: { onClick: `removeWorkspaceReplaying(getCurrentRecording())`}}
+ { 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())`}},
+ { opts: { title: "Delete", icon: "trash",toolTip: "delete selected rec", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${mediaState.Paused}"`}, scripts: { onClick: `removeWorkspaceReplaying(getCurrentRecording())`}}
];
const btns = btnDescs.map(desc => dockBtn({_width: desc.opts.width??30, _height: 30, defaultDoubleClick: 'ignore', undoIgnoreFields: new List<string>(['opacity']), _dragOnlyWithinContainer: true, ...desc.opts}, desc.scripts, desc.funcs));
const dockBtnsReqdOpts:DocumentOptions = {
@@ -880,15 +873,17 @@ pie title Minerals in my tap water
return DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.TreeDocument([], opts), { title: "published docs", backgroundColor: "#aca3a6", isSystem: true });
}
- /// The database of all links on all documents
+ static newAccount: boolean = false;
+
+ // The database of all links on all documents
static setupLinkDocs(doc: Doc, linkDatabaseId: string) {
- if (!(Docs.newAccount ? undefined : DocCast(doc.myLinkDatabase))) {
+ if (!(CurrentUserUtils.newAccount ? undefined : DocCast(doc.myLinkDatabase))) {
const linkDocs = new Doc(linkDatabaseId, true);
- linkDocs.title = "LINK DATABASE: " + Doc.CurrentUserEmail;
- linkDocs.author = Doc.CurrentUserEmail;
+ linkDocs.title = "LINK DATABASE: " + ClientUtils.CurrentUserEmail();
+ linkDocs.author = ClientUtils.CurrentUserEmail();
linkDocs.isSystem = true;
linkDocs.data = new List<Doc>([]);
- linkDocs["acl-Guest"] = SharingPermissions.Augment;
+ linkDocs.acl_Guest = SharingPermissions.Augment;
doc.myLinkDatabase = new PrefetchProxy(linkDocs);
}
}
@@ -909,7 +904,7 @@ pie title Minerals in my tap water
// childContextMenuScripts: new List<ScriptField>([addToDashboards!,]),
// childContextMenuLabels: new List<string>(["Add to Dashboards",]),
// childContextMenuIcons: new List<string>(["user-plus",]),
- "acl-Guest": SharingPermissions.Augment, "_acl-Guest": SharingPermissions.Augment,
+ acl_Guest: SharingPermissions.Augment, _acl_Guest: SharingPermissions.Augment,
childDragAction: dropActionType.embed, isSystem: true, childContentPointerEvents: "none", childLimitHeight: 0, _yMargin: 0, _gridGap: 15, childDontRegisterViews:true,
// NOTE: treeView_HideTitle & _layout_showTitle is for a TreeView's editable title, _layout_showTitle is for DocumentViews title bar
_layout_showTitle: "title", treeView_HideTitle: true, ignoreClick: true, _lockedPosition: true, layout_boxShadow: "0 0", _chromeHidden: true, dontRegisterView: true,
@@ -939,16 +934,17 @@ pie title Minerals in my tap water
/// Updates the UserDoc to have all required fields, docs, etc. No changes should need to be
/// written to the server if the code hasn't changed. However, choices need to be made for each Doc/field
/// whether to revert to "default" values, or to leave them as the user/system last set them.
- static updateUserDocument(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) {
+ static updateUserDocument(docIn: Doc, sharingDocumentId: string, linkDatabaseId: string) {
+ const doc = docIn;
DocUtils.AssignDocField(doc, "globalGroupDatabase", () => Docs.Prototypes.MainGroupDocument(), {});
- reaction(() => DateCast(DocCast(doc.globalGroupDatabase)["data_modificationDate"]),
+ reaction(() => DateCast(DocCast(doc.globalGroupDatabase).data_modificationDate),
async () => {
const groups = await DocListCastAsync(DocCast(doc.globalGroupDatabase).data);
- const mygroups = groups?.filter(group => JSON.parse(StrCast(group.members)).includes(Doc.CurrentUserEmail)) || [];
- SetCachedGroups(["Guest", ...mygroups?.map(g => StrCast(g.title))]);
+ const mygroups = groups?.filter(group => JSON.parse(StrCast(group.members)).includes(ClientUtils.CurrentUserEmail())) || [];
+ SetCachedGroups(["Guest", ...(mygroups?.map(g => StrCast(g.title))??[])]);
}, { fireImmediately: true });
doc.isSystem ?? (doc.isSystem = true);
- doc.title ?? (doc.title = Doc.CurrentUserEmail);
+ doc.title ?? (doc.title = ClientUtils.CurrentUserEmail());
Doc.noviceMode ?? (Doc.noviceMode = true);
doc._showLabel ?? (doc._showLabel = true);
doc.textAlign ?? (doc.textAlign = "left");
@@ -961,7 +957,7 @@ pie title Minerals in my tap water
doc.activeFillColor ?? (doc.activeFillColor = "");
doc.activeArrowStart ?? (doc.activeArrowStart = "");
doc.activeArrowEnd ?? (doc.activeArrowEnd = "");
- doc.activeDash ?? (doc.activeDash == "0");
+ doc.activeDash ?? (doc.activeDash === "0");
doc.fontSize ?? (doc.fontSize = "12px");
doc.fontFamily ?? (doc.fontFamily = "Arial");
doc.fontColor ?? (doc.fontColor = "black");
@@ -978,27 +974,26 @@ pie title Minerals in my tap water
this.setupLinkDocs(doc, linkDatabaseId);
this.setupSharedDocs(doc, sharingDocumentId); // sets up the right sidebar collection for mobile upload documents and sharing
this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon
- this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
this.setupPublished(doc); // sets up the list doc of all docs that have been published (meaning that they can be auto-linked by typing their title into another text box)
this.setupContextMenuButtons(doc); // set up the row of buttons at the top of the dashboard that change depending on what is selected
this.setupTopbarButtons(doc);
this.setupDockedButtons(doc); // the bottom bar of font icons
this.setupLeftSidebarMenu(doc); // the left-side column of buttons that open their contents in a flyout panel on the left
this.setupDocTemplates(doc); // sets up the template menu of templates
- //this.setupFieldInfos(doc); // sets up the collection of field info descriptions for each possible DocumentOption
- DocUtils.AssignDocField(doc, "globalScriptDatabase", (opts) => Docs.Prototypes.MainScriptDocument(), {});
+ // sthis.setupFieldInfos(doc); // sets up the collection of field info descriptions for each possible DocumentOption
+ DocUtils.AssignDocField(doc, "globalScriptDatabase", () => Docs.Prototypes.MainScriptDocument(), {});
DocUtils.AssignDocField(doc, "myHeaderBar", (opts) => Docs.Create.MulticolumnDocument([], opts), { title: "My Header Bar", isSystem: true, _chromeHidden:true, layout_maxShown: 10, childLayoutFitWidth:false, childDocumentsActive:false, dropAction: dropActionType.move}); // drop down panel at top of dashboard for stashing documents
- Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyDashboards)
- Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MySharedDocs)
- Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyRecentlyClosed)
-
- Doc.GetProto(DocCast(Doc.UserDoc().emptyWebpage)).data = new WebField("https://www.wikipedia.org")
+ SelectionManager.DeselectAll(); // this forces SelectionManager implementation to copy over to DocumentView's API. This also triggers the LinkManager to be created
+
+ Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyDashboards);
+ Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MySharedDocs);
+ Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyRecentlyClosed);
- new LinkManager();
+ Doc.GetProto(DocCast(Doc.UserDoc().emptyWebpage)).data = new WebField("https://www.wikipedia.org");
- DocServer.CacheNeedsUpdate && setTimeout(DocServer.UPDATE_SERVER_CACHE, 2500);
- setInterval(DocServer.UPDATE_SERVER_CACHE, 120000);
+ DocServer.CacheNeedsUpdate() && setTimeout(UPDATE_SERVER_CACHE, 2500);
+ setInterval(UPDATE_SERVER_CACHE, 120000);
return doc;
}
static setupFieldInfos(doc:Doc, field="fieldInfos") {
@@ -1015,18 +1010,17 @@ pie title Minerals in my tap water
case FInfoFieldType.Doc: opts.fieldValues = new List<Doc>(options.values as any); break;
default: opts.fieldValues = new List<string>(options.values as any); break;// string, pointerEvents, dimUnit, dropActionType
}
- DocUtils.AssignDocField(infos, pair[0], opts => Doc.assign(new Doc(), OmitKeys(opts,["values"]).omit), opts);
+ DocUtils.AssignDocField(infos, pair[0], docOpts => Doc.assign(new Doc(), OmitKeys(docOpts,["values"]).omit), opts);
}
});
}
- @observable public static ServerVersion: string = ';'
public static async loadCurrentUser() {
- return rp.get(Utils.prepend("/getCurrentUser")).then(async response => {
+ 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);
- runInAction(() => CurrentUserUtils.ServerVersion = result.version);
- Doc.CurrentUserEmail = result.email;
+ runInAction(() => { SnappingManager.SetServerVersion(result.version); });
+ ClientUtils.SetCurrentUserEmail(result.email);
resolvedPorts = result.resolvedPorts as any;
DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts?.socket, result.email);
if (result.cacheDocumentIds)
@@ -1034,13 +1028,13 @@ pie title Minerals in my tap water
const ids = result.cacheDocumentIds.split(";");
const batch = 30000;
for (let i = 0; i < ids.length; i += batch) {
+ // eslint-disable-next-line no-await-in-loop
await DocServer.GetRefFields(ids.slice(i, i+batch));
}
}
return result;
- } else {
- throw new Error("There should be a user! Why does Dash think there isn't one?");
- }
+ }
+ throw new Error("There should be a user! Why does Dash think there isn't one?");
});
}
@@ -1050,12 +1044,12 @@ pie title Minerals in my tap water
linkDatabaseId: string;
}) {
return DocServer.GetRefField(info.userDocumentId).then(async field => {
- Docs.newAccount = !(field instanceof Doc);
+ CurrentUserUtils.newAccount = !(field instanceof Doc);
await Docs.Prototypes.initialize();
- const userDoc = Docs.newAccount ? new Doc(info.userDocumentId, true) : field as Doc;
+ const userDoc = CurrentUserUtils.newAccount ? new Doc(info.userDocumentId, true) : field as Doc;
this.updateUserDocument(Doc.SetUserDoc(userDoc), info.sharingDocumentId, info.linkDatabaseId);
- if (Docs.newAccount) {
- if (Doc.CurrentUserEmail === "guest") {
+ if (CurrentUserUtils.newAccount) {
+ if (ClientUtils.CurrentUserEmail() === "guest") {
DashboardView.createNewDashboard(undefined, "guest dashboard");
} else {
userDoc.activePage = "home";
@@ -1072,14 +1066,10 @@ pie title Minerals in my tap water
input.type = "file";
input.multiple = true;
input.accept = ".zip, application/pdf, video/*, image/*, audio/*";
- input.onchange = async _e => {
+ input.onchange = async () => {
const file = input.files?.[0];
if (file?.type === 'application/zip' || file?.type === 'application/x-zip-compressed') {
const doc = await Doc.importDocument(file);
- // NOT USING SOLR, so need to replace this with something else // if (doc instanceof Doc) {
- // setTimeout(() => SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs =>
- // docs.docs.forEach(d => LinkManager.Instance.addLink(d))), 2000); // need to give solr some time to update so that this query will find any link docs we've added.
- // }
const list = Cast(Doc.MyImports.data, listSpec(Doc), null);
doc instanceof Doc && list?.splice(0, 0, doc);
} else if (input.files && input.files.length !== 0) {
@@ -1099,10 +1089,17 @@ pie title Minerals in my tap water
}
}
-ScriptingGlobals.add(function MySharedDocs() { return Doc.MySharedDocs; }, "document containing all shared Docs");
-ScriptingGlobals.add(function IsExploreMode() { return SnappingManager.ExploreMode; }, "is Dash in exploration mode");
-ScriptingGlobals.add(function IsNoviceMode() { return Doc.noviceMode; }, "is Dash in novice mode");
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function MySharedDocs() { return Doc.MySharedDocs; }, "document containing all shared Docs");
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function IsExploreMode() { return SnappingManager.ExploreMode; }, "is Dash in exploration mode");
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function IsNoviceMode() { return Doc.noviceMode; }, "is Dash in novice mode");
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, "switches between comic and normal document rendering");
-ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar");
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar");
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; });
-ScriptingGlobals.add(function getSharingDoc() {return Doc.SharingDoc() }); \ No newline at end of file
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function getSharingDoc() { return Doc.SharingDoc() });
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 82c63695c..bc9fe813f 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -1,18 +1,22 @@
+/* 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';
import { List } from '../../fields/List';
import { RichTextField } from '../../fields/RichTextField';
import { listSpec } from '../../fields/Schema';
-import { Cast, CastCtor, DocCast } from '../../fields/Types';
+import { Cast, CastCtor } from '../../fields/Types';
import { AudioField, ImageField } from '../../fields/URLField';
-import { Utils } from '../../Utils';
-import { Docs } from '../documents/Documents';
+import { AudioAnnoState } from '../../server/SharedMediaTypes';
+import { Networking } from '../Network';
import { DocumentType } from '../documents/DocumentTypes';
+import { Docs } from '../documents/Documents';
import { DictationOverlay } from '../views/DictationOverlay';
-import { DocumentView, OpenWhere } from '../views/nodes/DocumentView';
-import { SelectionManager } from './SelectionManager';
+import { DocumentView } from '../views/nodes/DocumentView';
+import { OpenWhere } from '../views/nodes/OpenWhere';
import { UndoManager } from './UndoManager';
/**
@@ -61,12 +65,13 @@ export namespace DictationManager {
const intraSession = '. ';
const interSession = ' ... ';
- export let isListening = false;
+ let isListening = false;
let isManuallyStopped = false;
- let current: string | undefined = undefined;
+ let current: string | undefined;
let sessionResults: string[] = [];
+ // eslint-disable-next-line new-cap
const recognizer: Opt<SpeechRecognition> = webkitSpeechRecognition ? new webkitSpeechRecognition() : undefined;
export type InterimResultHandler = (results: string) => any;
@@ -87,7 +92,7 @@ export namespace DictationManager {
let pendingListen: Promise<string> | string | undefined;
export const listen = async (options?: Partial<ListeningOptions>) => {
- if (pendingListen instanceof Promise) return pendingListen.then(pl => innerListen(options));
+ if (pendingListen instanceof Promise) return pendingListen.then(() => innerListen(options));
return innerListen(options);
};
const innerListen = async (options?: Partial<ListeningOptions>) => {
@@ -103,7 +108,7 @@ export namespace DictationManager {
results = await (pendingListen = listenImpl(options));
pendingListen = undefined;
if (results) {
- Utils.CopyText(results);
+ ClientUtils.CopyText(results);
if (overlay) {
DictationOverlay.Instance.isListening = false;
const execute = options?.tryExecute;
@@ -150,29 +155,29 @@ export namespace DictationManager {
recognizer.start();
- return new Promise<string>((resolve, reject) => {
+ return new Promise<string>(resolve => {
recognizer.onerror = (e: any) => {
// e is SpeechRecognitionError but where is that defined?
if (!(indefinite && e.error === 'no-speech')) {
recognizer.stop();
resolve(e);
- //reject(e);
}
};
recognizer.onresult = (e: SpeechRecognitionEvent) => {
current = synthesize(e, intra);
- let matchedTerminator: string | undefined;
- if (options?.terminators && (matchedTerminator = options.terminators.find(end => (current ? current.trim().toLowerCase().endsWith(end.toLowerCase()) : false)))) {
+ const matchedTerminator = options?.terminators?.find(end => (current ? current.trim().toLowerCase().endsWith(end.toLowerCase()) : false));
+ if (options?.terminators && matchedTerminator) {
current = matchedTerminator;
recognizer.abort();
return complete();
}
!isManuallyStopped && handler?.(current);
- //isManuallyStopped && complete();
+ // isManuallyStopped && complete()
+ return undefined;
};
- recognizer.onend = (e: Event) => {
+ recognizer.onend = () => {
if (!indefinite || isManuallyStopped) {
return complete();
}
@@ -182,6 +187,7 @@ export namespace DictationManager {
current = undefined;
}
recognizer.start();
+ return undefined;
};
const complete = () => {
@@ -202,7 +208,7 @@ export namespace DictationManager {
});
};
- export const stop = (salvageSession = true) => {
+ export const stop = (/* salvageSession = true */) => {
if (!isListening || !recognizer) {
return;
}
@@ -212,7 +218,7 @@ export namespace DictationManager {
};
const synthesize = (e: SpeechRecognitionEvent, delimiter?: string) => {
- const results = e.results;
+ const { results } = e;
const transcripts: string[] = [];
for (let i = 0; i < results.length; i++) {
transcripts.push(results.item(i).item(0).transcript.trim());
@@ -231,24 +237,30 @@ export namespace DictationManager {
export type DependentEntry = { expression: RegExp; action: DependentAction; restrictTo?: DocumentType[] };
export const RegisterIndependent = (key: string, value: IndependentEntry) => Independent.set(key, value);
- export const RegisterDependent = (entry: DependentEntry) => Dependent.push(entry);
+ export const RegisterDependent = (entry: DependentEntry) => {
+ const { expression, action, restrictTo } = entry;
+ return Dependent.push({ expression, action, restrictTo: restrictTo ?? [] });
+ };
- export const execute = async (phrase: string) => {
- return UndoManager.RunInBatch(async () => {
+ export const execute = async (phrase: string) =>
+ UndoManager.RunInBatch(async () => {
console.log('PHRASE: ' + phrase);
- const targets = SelectionManager.Views;
+ const targets = DocumentView.Selected();
if (!targets || !targets.length) {
- return;
+ return undefined;
}
+ // eslint-disable-next-line no-param-reassign
phrase = phrase.toLowerCase();
const entry = Independent.get(phrase);
if (entry) {
let success = false;
- const restrictTo = entry.restrictTo;
+ const { restrictTo } = entry;
+ // eslint-disable-next-line no-restricted-syntax
for (const target of targets) {
if (!restrictTo || validate(target, restrictTo)) {
+ // eslint-disable-next-line no-await-in-loop
await entry.action(target);
success = true;
}
@@ -256,16 +268,19 @@ export namespace DictationManager {
return success;
}
- for (const entry of Dependent) {
- const regex = entry.expression;
+ // eslint-disable-next-line no-restricted-syntax
+ for (const depEntry of Dependent) {
+ const regex = depEntry.expression;
const matches = regex.exec(phrase);
regex.lastIndex = 0;
if (matches !== null) {
let success = false;
- const restrictTo = entry.restrictTo;
+ const { restrictTo } = depEntry;
+ // eslint-disable-next-line no-restricted-syntax
for (const target of targets) {
if (!restrictTo || validate(target, restrictTo)) {
- await entry.action(target, matches);
+ // eslint-disable-next-line no-await-in-loop
+ await depEntry.action(target, matches);
success = true;
}
}
@@ -275,7 +290,6 @@ export namespace DictationManager {
return false;
}, 'Execute Command');
- };
const ConstructorMap = new Map<DocumentType, CastCtor>([
[DocumentType.COL, listSpec(Doc)],
@@ -294,6 +308,7 @@ export namespace DictationManager {
};
const validate = (target: DocumentView, types: DocumentType[]) => {
+ // eslint-disable-next-line no-restricted-syntax
for (const type of types) {
if (tryCast(target, type)) {
return true;
@@ -318,7 +333,9 @@ export namespace DictationManager {
[
'clear',
{
- action: (target: DocumentView) => (Doc.GetProto(target.Document).data = new List()),
+ action: (target: DocumentView) => {
+ Doc.GetProto(target.Document).data = new List();
+ },
restrictTo: [DocumentType.COL],
},
],
@@ -328,7 +345,7 @@ export namespace DictationManager {
{
action: (target: DocumentView) => {
const newBox = Docs.Create.TextDocument('', { _width: 400, _height: 200, title: 'My Outline', _layout_autoHeight: true });
- const proto = DocCast(newBox.proto);
+ const proto = newBox[DocData];
const prompt = 'Press alt + r to start dictating here...';
const head = 3;
const anchor = head + prompt.length;
@@ -341,7 +358,7 @@ export namespace DictationManager {
],
]);
- const Dependent = new Array<DependentEntry>(
+ const Dependent = [
{
expression: /create (\w+) documents of type (image|nested collection)/g,
action: (target: DocumentView, matches: RegExpExecArray) => {
@@ -361,6 +378,7 @@ export namespace DictationManager {
case 'nested collection':
created = Docs.Create.FreeformDocument([], {});
break;
+ default:
}
created && Doc.AddDocToList(dataDoc, fieldKey, created);
}
@@ -375,7 +393,46 @@ export namespace DictationManager {
mode && (target.Document._type_collection = mode);
},
restrictTo: [DocumentType.COL],
- }
- );
+ },
+ ];
+ }
+ export function recordAudioAnnotation(dataDoc: Doc, field: string, onRecording?: (stop: () => void) => void, onEnd?: () => void) {
+ let gumStream: any;
+ let recorder: any;
+ navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
+ let audioTextAnnos = Cast(dataDoc[field + '_audioAnnotations_text'], listSpec('string'), null);
+ if (audioTextAnnos) audioTextAnnos.push('');
+ else audioTextAnnos = dataDoc[field + '_audioAnnotations_text'] = new List<string>(['']);
+ DictationManager.Controls.listen({
+ interimHandler: value => { audioTextAnnos[audioTextAnnos.length - 1] = value; }, // prettier-ignore
+ continuous: { indefinite: false },
+ }).then(results => {
+ if (results && [DictationManager.Controls.Infringed].includes(results)) {
+ DictationManager.Controls.stop();
+ }
+ onEnd?.();
+ });
+
+ gumStream = stream;
+ recorder = new MediaRecorder(stream);
+ recorder.ondataavailable = async (e: any) => {
+ const [{ result }] = await Networking.UploadFilesToServer({ file: e.data });
+ if (!(result instanceof Error)) {
+ const audioField = new AudioField(result.accessPaths.agnostic.client);
+ const audioAnnos = Cast(dataDoc[field + '_audioAnnotations'], listSpec(AudioField), null);
+ if (audioAnnos) audioAnnos.push(audioField);
+ else dataDoc[field + '_audioAnnotations'] = new List([audioField]);
+ }
+ };
+ recorder.start();
+ const stopFunc = () => {
+ recorder.stop();
+ DictationManager.Controls.stop(/* false */);
+ dataDoc.audioAnnoState = AudioAnnoState.stopped;
+ 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 a38a330da..8ad6ddf47 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,35 +1,30 @@
import { Howl } from 'howler';
import { action, computed, makeObservable, observable, ObservableSet, observe } from 'mobx';
import { Doc, Opt } from '../../fields/Doc';
-import { AclAdmin, AclEdit, Animation, DocData } from '../../fields/DocSymbols';
+import { Animation, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { listSpec } from '../../fields/Schema';
import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { AudioField } from '../../fields/URLField';
-import { GetEffectiveAcl } from '../../fields/util';
import { CollectionViewType } from '../documents/DocumentTypes';
-import { CollectionDockingView } from '../views/collections/CollectionDockingView';
-import { TabDocView } from '../views/collections/TabDocView';
-import { LightboxView } from '../views/LightboxView';
-import { DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from '../views/nodes/DocumentView';
-import { FocusViewOptions } from '../views/nodes/FieldView';
-import { KeyValueBox } from '../views/nodes/KeyValueBox';
-import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox';
+import { DocumentView, DocumentViewInternal } from '../views/nodes/DocumentView';
+import { FocusViewOptions } from '../views/nodes/FocusViewOptions';
+import { OpenWhere } from '../views/nodes/OpenWhere';
import { PresBox } from '../views/nodes/trails';
-import { ScriptingGlobals } from './ScriptingGlobals';
-import { SelectionManager } from './SelectionManager';
+type childIterator = { viewSpec: Opt<Doc>; childDocView: Opt<DocumentView>; focused: boolean; contextPath: Doc[] };
export class DocumentManager {
+ // eslint-disable-next-line no-use-before-define
private static _instance: DocumentManager;
public static get Instance(): DocumentManager {
+ // eslint-disable-next-line no-return-assign
return this._instance || (this._instance = new this());
}
- //global holds all of the nodes (regardless of which collection they're in)
- @observable _documentViews = new Set<DocumentView>();
- @observable.shallow public CurrentlyLoading: Doc[] = [];
+ // global holds all of the nodes (regardless of which collection they're in)
+ @observable private _documentViews = new Set<DocumentView>();
@computed public get DocumentViews() {
- return Array.from(this._documentViews).filter(view => !(view.ComponentView instanceof KeyValueBox) && (!LightboxView.LightboxDoc || LightboxView.Contains(view)));
+ return Array.from(this._documentViews).filter(view => (!view.ComponentView?.dontRegisterView?.() && !DocumentView.LightboxDoc()) || DocumentView.LightboxContains(view));
}
public AddDocumentView(dv: DocumentView) {
this._documentViews.add(dv);
@@ -38,10 +33,22 @@ export class DocumentManager {
this._documentViews.delete(dv);
}
- //private constructor so no other class can create a nodemanager
+ // private constructor so no other class can create a nodemanager
private constructor() {
makeObservable(this);
- observe(this.CurrentlyLoading, change => {
+
+ DocumentView.allViews = () => this.DocumentViews;
+ DocumentView.addView = this.AddView;
+ DocumentView.removeView = this.RemoveView;
+ DocumentView.showDocument = this.showDocument;
+ DocumentView.showDocumentView = this.showDocumentView;
+ DocumentView.linkCommonAncestor = DocumentManager.LinkCommonAncestor;
+ DocumentView.addViewRenderedCb = this.AddViewRenderedCb;
+ DocumentView.getFirstDocumentView = this.getFirstDocumentView;
+ DocumentView.getDocumentView = this.getDocumentView;
+ DocumentView.getContextPath = DocumentManager.GetContextPath;
+ 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) {
case 'update':
@@ -52,6 +59,7 @@ export class DocumentManager {
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())));
break;
+ default:
}
});
}
@@ -59,7 +67,7 @@ export class DocumentManager {
private _viewRenderedCbs: { doc: Doc; func: (dv: DocumentView) => any }[] = [];
public AddViewRenderedCb = (doc: Opt<Doc>, func: (dv: DocumentView) => any) => {
if (doc) {
- const dv = this.getDocumentView(doc);
+ const dv = DocumentView.LightboxDoc() ? this.getLightboxDocumentView(doc) : this.getDocumentView(doc);
this._viewRenderedCbs.push({ doc, func });
if (dv) {
this.callAddViewFuncs(dv);
@@ -88,20 +96,15 @@ export class DocumentManager {
@action
public AddView = (view: DocumentView) => {
- if (!view._props.LayoutTemplateString?.includes(KeyValueBox.name) &&
- !view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- this.AddDocumentView(view);
- this.callAddViewFuncs(view);
- } // prettier-ignore
+ this.AddDocumentView(view);
+ this.callAddViewFuncs(view);
};
public RemoveView = action((view: DocumentView) => {
- if (!view._props.LayoutTemplateString?.includes(KeyValueBox.name) && !view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- this.DeleteDocumentView(view);
- }
- SelectionManager.DeselectView(view);
+ this.DeleteDocumentView(view);
+ DocumentView.DeselectView(view);
});
- //gets all views
+ // gets all views
public getDocumentViewsById(id: string) {
const toReturn: DocumentView[] = [];
DocumentManager.Instance.DocumentViews.forEach(view => {
@@ -135,28 +138,20 @@ export class DocumentManager {
);
}
- public getLightboxDocumentView = (toFind: Doc, originatingDoc: Opt<Doc> = undefined): DocumentView | undefined => {
+ public getLightboxDocumentView = (toFind: Doc): DocumentView | undefined => {
const views: DocumentView[] = [];
- DocumentManager.Instance.DocumentViews.forEach(view => LightboxView.Contains(view) && Doc.AreProtosEqual(view.Document, toFind) && views.push(view));
- return views?.find(view => view.ContentDiv?.getBoundingClientRect().width /*&& view._props.focus !== returnFalse) || views?.find(view => view._props.focus !== returnFalse*/) || (views.length ? views[0] : undefined);
+ DocumentManager.Instance.DocumentViews.forEach(view => DocumentView.LightboxContains(view) && Doc.AreProtosEqual(view.Document, toFind) && views.push(view));
+ return views?.find(view => view.ContentDiv?.getBoundingClientRect().width /* && view._props.focus !== returnFalse) || views?.find(view => view._props.focus !== returnFalse */) || (views.length ? views[0] : undefined);
};
- public getFirstDocumentView = (toFind: Doc, originatingDoc: Opt<Doc> = undefined): DocumentView | undefined => {
- if (LightboxView.LightboxDoc) return DocumentManager.Instance.getLightboxDocumentView(toFind, originatingDoc);
- const views = this.getDocumentViews(toFind); //.filter(view => view.Document !== originatingDoc);
- return views?.find(view => view.ContentDiv?.getBoundingClientRect().width /*&& view._props.focus !== returnFalse) || views?.find(view => view._props.focus !== returnFalse*/) || (views.length ? views[0] : undefined);
+ public getFirstDocumentView = (toFind: Doc): DocumentView | undefined => {
+ if (DocumentView.LightboxDoc()) return DocumentManager.Instance.getLightboxDocumentView(toFind);
+ const views = this.getDocumentViews(toFind); // .filter(view => view.Document !== originatingDoc);
+ return views?.find(view => view.ContentDiv?.getBoundingClientRect().width /* && view._props.focus !== returnFalse) || views?.find(view => view._props.focus !== returnFalse */) || (views.length ? views[0] : undefined);
};
- public getDocumentViews(toFindIn: Doc): DocumentView[] {
- const toFind =
- // Array.from(DocumentManager.Instance.DocumentViews).find(
- // dv =>
- // ((dv.Document.data as any)?.url?.href && (dv.Document.data as any)?.url?.href === (toFindIn.data as any)?.url?.href) ||
- // ((DocCast(dv.Document.annotationOn)?.data as any)?.url?.href && (DocCast(dv.Document.annotationOn)?.data as any)?.url?.href === (DocCast(toFindIn.annotationOn)?.data as any)?.url?.href)
- // )?.Document ??
- toFindIn;
-
+ public getDocumentViews(toFind: Doc): DocumentView[] {
const toReturn: DocumentView[] = [];
- const docViews = DocumentManager.Instance.DocumentViews.filter(view => !LightboxView.Contains(view));
- const lightViews = DocumentManager.Instance.DocumentViews.filter(view => LightboxView.Contains(view));
+ const docViews = DocumentManager.Instance.DocumentViews.filter(view => !DocumentView.LightboxContains(view));
+ const lightViews = DocumentManager.Instance.DocumentViews.filter(view => DocumentView.LightboxContains(view));
// heuristic to return the "best" documents first:
// choose a document in the lightbox first
@@ -172,7 +167,7 @@ export class DocumentManager {
static GetContextPath(doc: Opt<Doc>, includeExistingViews?: boolean) {
if (!doc) return [];
const srcContext = DocCast(doc.annotationOn, DocCast(doc.embedContainer));
- var containerDocContext = srcContext ? [srcContext, doc] : [doc];
+ let containerDocContext = srcContext ? [srcContext, doc] : [doc];
while (
containerDocContext.length &&
DocCast(containerDocContext[0]?.embedContainer) &&
@@ -184,11 +179,13 @@ export class DocumentManager {
return containerDocContext;
}
+ static _howl: Howl;
static playAudioAnno(doc: Doc) {
const anno = Cast(doc[Doc.LayoutFieldKey(doc) + '_audioAnnotations'], listSpec(AudioField), null)?.lastElement();
if (anno) {
+ this._howl?.stop();
if (anno instanceof AudioField) {
- new Howl({
+ this._howl = new Howl({
src: [anno.url.href],
format: ['mp3'],
autoplay: true,
@@ -204,19 +201,20 @@ export class DocumentManager {
DocumentManager._overlayViews?.clear();
}
static _overlayViews = new ObservableSet<DocumentView>();
- static addView = (doc: Doc, finished?: () => void) => {
- CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
- finished?.();
- };
+ /**
+ * Find the nearest common ancestor collection that contains a link's source and target
+ * @param linkDoc
+ * @returns common ancestor DocumentView
+ */
public static LinkCommonAncestor(linkDoc: Doc) {
- const anchor = (which: number) => {
+ const getAnchor = (which: number) => {
const anch = DocCast(linkDoc['link_anchor_' + which]);
const anchor = anch?.layout_unrendered ? DocCast(anch.annotationOn) : anch;
return DocumentManager.Instance.getDocumentView(anchor);
};
- const anchor1 = anchor(1);
- const anchor2 = anchor(2);
+ const anchor1 = getAnchor(1);
+ const anchor2 = getAnchor(2);
return anchor1
?.docViewPath()
.reverse()
@@ -228,8 +226,10 @@ export class DocumentManager {
// focusing on each context
public showDocumentView = async (targetDocView: DocumentView, options: FocusViewOptions) => {
const docViewPath = [...(targetDocView.containerViewPath?.() ?? []), targetDocView];
- let rootContextView = docViewPath.shift();
- await (rootContextView && this.focusViewsInPath(rootContextView, options, async () => ({ childDocView: docViewPath.shift(), viewSpec: undefined, focused: false })));
+ const rootContextView = docViewPath.shift();
+ const iterator = () => ({ childDocView: docViewPath.shift(), viewSpec: undefined, focused: false, contextPath: docViewPath.map(dv => dv.Document) });
+ options.contextPath = docViewPath.map(dv => dv.Document);
+ await (rootContextView && this.focusViewsInPath(rootContextView, options, iterator));
if (options.toggleTarget && (!options.didMove || targetDocView.Document.hidden)) targetDocView.Document.hidden = !targetDocView.Document.hidden;
else if (options.openLocation?.startsWith(OpenWhere.toggle) && !options.didMove && rootContextView) DocumentViewInternal.addDocTabFunc(rootContextView.Document, options.openLocation);
};
@@ -242,85 +242,111 @@ export class DocumentManager {
// and finally restoring the targetDoc to the viewSpec specified by the last document which may either be the targetDoc, or a viewSpec that describes the targetDoc configuration
public showDocument = async (
targetDoc: Doc, // document to display
- options: FocusViewOptions, // options for how to navigate to target
+ optionsIn: FocusViewOptions, // options for how to navigate to target
finished?: (changed: boolean) => void // func called after focusing on target with flag indicating whether anything needed to be done.
) => {
+ const options = optionsIn;
Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, targetDoc);
const docContextPath = DocumentManager.GetContextPath(targetDoc, true);
if (docContextPath.some(doc => doc.hidden)) options.toggleTarget = false;
- const tabView = Array.from(TabDocView._allTabs).find(view => view._document === docContextPath[0]);
- if (!tabView?._activated && tabView?._document) {
- options.toggleTarget = false;
- TabDocView.Activate(tabView?._document);
- }
- let rootContextView =
+ if (DocumentView.activateTabView(docContextPath[0])) options.toggleTarget = false;
+
+ const rootContextView =
docContextPath.length &&
(await new Promise<DocumentView>(res => {
const viewIndex = docContextPath.findIndex(doc => this.getDocumentView(doc));
if (viewIndex !== -1) {
viewIndex && docContextPath.splice(0, viewIndex);
- return res(this.getDocumentView(docContextPath[0])!);
+ res(this.getDocumentView(docContextPath[0])!);
+ return;
}
options.didMove = true;
- docContextPath.some(doc => TabDocView.Activate(doc)) || DocumentViewInternal.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
+ (!DocumentView.LightboxDoc() && docContextPath.some(doc => DocumentView.activateTabView(doc))) || DocumentViewInternal.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
this.AddViewRenderedCb(docContextPath[0], dv => res(dv));
}));
- if (options.openLocation === OpenWhere.lightbox) {
+ if (options.openLocation?.includes(OpenWhere.lightbox)) {
// even if we found the document view, if the target is a lightbox, we try to open it in the lightbox to preserve lightbox semantics (eg, there's only one active doc in the lightbox)
const target = DocCast(targetDoc.annotationOn, targetDoc);
const contextView = this.getDocumentView(DocCast(target.embedContainer));
- if (contextView?.ComponentView?.addDocTab?.(target, OpenWhere.lightbox)) {
- await new Promise<void>(waitres => setTimeout(() => waitres()));
+ if (contextView?.ComponentView?.addDocTab?.(target, options.openLocation)) {
+ await new Promise<void>(waitres => {
+ setTimeout(() => waitres());
+ });
}
}
- docContextPath.shift();
- const childViewIterator = async (docView: DocumentView) => {
- const innerDoc = docContextPath.shift();
- return { focused: false, viewSpec: innerDoc, childDocView: innerDoc && !innerDoc.layout_unrendered ? (await docView.ComponentView?.getView?.(innerDoc, options)) ?? this.getDocumentView(innerDoc) : undefined };
- };
if (rootContextView) {
+ const childViewIterator = async (docView: DocumentView): Promise<childIterator> => {
+ const innerDoc = docContextPath.shift();
+ const childDocView = innerDoc && !innerDoc.layout_unrendered
+ ? (await docView.ComponentView?.getView?.(innerDoc, options)) ?? this.getDocumentView(innerDoc):
+ undefined; // prettier-ignore
+ return { focused: false, viewSpec: innerDoc, childDocView, contextPath: docContextPath };
+ };
+ docContextPath.shift();
+ options.contextPath = docContextPath;
const target = await this.focusViewsInPath(rootContextView, options, childViewIterator);
- this.restoreDocView(target.viewSpec, target.docView, options, target.contextView ?? target.docView, targetDoc);
- finished?.(target.focused);
- } else finished?.(false);
+ if (target) {
+ this.restoreDocView(target.viewSpec, target.docView, options, target.contextView ?? target.docView, targetDoc);
+ finished?.(target.focused);
+ return;
+ }
+ }
+ finished?.(false);
};
focusViewsInPath = async (
- docView: DocumentView, //
- options: FocusViewOptions,
- iterator: (docView: DocumentView) => Promise<{ viewSpec: Opt<Doc>; childDocView: Opt<DocumentView>; focused: boolean }>
+ docViewIn: DocumentView, //
+ optionsIn: FocusViewOptions,
+ iterator: (docView: DocumentView) => childIterator | Promise<childIterator>
) => {
let contextView: DocumentView | undefined; // view containing context that contains target
let focused = false;
- while (true) {
+ let docView = docViewIn;
+ let anchor = docView.Document;
+ const options = optionsIn;
+ const maxFocusLength = 100; // want to keep focusing until we get to target, but avoid an infinite loop
+ for (let i = 0; i < maxFocusLength; i++) {
if (docView.Document.layout_fieldKey === 'layout_icon') {
- await new Promise<void>(res => docView.iconify(res));
+ // eslint-disable-next-line no-loop-func
+ const prom = new Promise<void>(res => {
+ docView.iconify(res);
+ });
+ // eslint-disable-next-line no-await-in-loop
+ await prom;
options.didMove = true;
}
- const nextFocus = docView._props.focus(docView.Document, options); // focus the view within its container
- focused = focused || (nextFocus === undefined ? false : true); // keep track of whether focusing on a view needed to actually change anything
- const { childDocView, viewSpec } = await iterator(docView);
- if (!childDocView) return { viewSpec: options.anchorDoc ?? viewSpec ?? docView.Document, docView, contextView, focused };
- contextView = options.anchorDoc?.layout_unrendered && !childDocView.Document.layout_unrendered ? childDocView : docView;
+ const nextFocus = docView._props.focus(anchor, options); // focus the view within its container
+ focused = focused || nextFocus !== undefined; // keep track of whether focusing on a view needed to actually change anything
+ // eslint-disable-next-line no-await-in-loop
+ const { childDocView, viewSpec, contextPath } = await iterator(docView);
+ if (!childDocView) return { viewSpec: viewSpec ?? docView.Document, docView, contextView, focused };
+ contextView = !childDocView.Document.layout_unrendered ? childDocView : docView;
docView = childDocView;
+ anchor = viewSpec ?? docView.Document;
+ options.contextPath = contextPath;
}
+ options.contextPath = undefined;
+ return undefined;
};
@action
- restoreDocView(viewSpec: Opt<Doc>, docView: DocumentView, options: FocusViewOptions, contextView: Opt<DocumentView>, targetDoc: Doc) {
+ restoreDocView(viewSpec: Opt<Doc>, docViewIn: DocumentView, options: FocusViewOptions, contextView: Opt<DocumentView>, targetDoc: Doc) {
+ const docView = docViewIn;
if (viewSpec && docView) {
- //if (docView.ComponentView instanceof FormattedTextBox)
- //viewSpec !== docView.Document &&
+ // if (docView.ComponentView instanceof FormattedTextBox)
+ // viewSpec !== docView.Document &&
docView.ComponentView?.focus?.(viewSpec, options);
PresBox.restoreTargetDocView(docView, viewSpec, options.zoomTime ?? 500);
- Doc.linkFollowHighlight(viewSpec ? [docView.Document, viewSpec] : docView.Document, undefined, options.effect);
+ // 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), (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;
- if (options.effect) docView.Document[Animation] = options.effect;
- if (options.zoomTextSelections && Doc.UnhighlightTimer && contextView && targetDoc.text_html) {
+ 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);
@@ -332,30 +358,4 @@ export class DocumentManager {
}
}
}
-export function DocFocusOrOpen(doc: Doc, options: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) {
- const func = () => {
- const cv = DocumentManager.Instance.getDocumentView(containingDoc);
- const dv = DocumentManager.Instance.getDocumentView(doc, cv);
- if (dv && (!containingDoc || dv.containerViewPath?.().lastElement()?.Document === containingDoc)) {
- DocumentManager.Instance.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.Document));
- } else {
- const container = DocCast(containingDoc ?? doc.embedContainer ?? Doc.BestEmbedding(doc));
- const showDoc = !Doc.IsSystem(container) && !cv ? container : doc;
- options.toggleTarget = undefined;
- DocumentManager.Instance.showDocument(showDoc, options, () => DocumentManager.Instance.showDocument(doc, { ...options, openLocation: undefined })).then(() => {
- const cv = DocumentManager.Instance.getDocumentView(containingDoc);
- const dv = DocumentManager.Instance.getDocumentView(doc, cv);
- dv && Doc.linkFollowHighlight(dv.Document);
- });
- }
- };
- if (Doc.IsDataProto(doc) && Doc.GetEmbeddings(doc).some(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))) {
- doc = Doc.GetEmbeddings(doc).find(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))!;
- }
- if (doc.hidden) {
- doc.hidden = false;
- options.toggleTarget = false;
- setTimeout(func);
- } else func();
-}
-ScriptingGlobals.add(DocFocusOrOpen);
+setTimeout(() => DocumentManager.Instance);
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index aa0f77c72..fda505420 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,3 +1,5 @@
+/* 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)
*
@@ -13,32 +15,22 @@
*/
import { action, observable, runInAction } from 'mobx';
+import { ClientUtils } from '../../ClientUtils';
+import { emptyFunction } from '../../Utils';
import { DateField } from '../../fields/DateField';
-import { Doc, Field, Opt, StrListCast } from '../../fields/Doc';
+import { CreateLinkToActiveAudio, Doc, FieldType, Opt, StrListCast } from '../../fields/Doc';
+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 { emptyFunction, Utils } from '../../Utils';
-import { Docs, DocUtils } from '../documents/Documents';
-import { CollectionFreeFormDocumentView } from '../views/nodes/CollectionFreeFormDocumentView';
+import { Docs } from '../documents/Documents';
import { DocumentView } from '../views/nodes/DocumentView';
-import { ScriptingGlobals } from './ScriptingGlobals';
-import { SelectionManager } from './SelectionManager';
+import { dropActionType } from './DropActionTypes';
import { SnappingManager } from './SnappingManager';
import { UndoManager } from './UndoManager';
-import { DocData } from '../../fields/DocSymbols';
-const { default : { contextMenuZindex } } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore
-
-export enum dropActionType {
- embed = 'embed', // create a new embedding of the dragged document for the new location
- copy = 'copy', // copy the dragged document
- move = 'move', // move the dragged document to the drop location after removing it from where it was
- add = 'add', // add the dragged document to the drop location without removing it from where it was
- same = 'same', // only allow drop within same collection (or same hierarchical tree collection)
- inPlace = 'inSame', // keep document in place (unless overridden by a drag modifier)
- proto = 'proto',
-} // undefined = move, same = move but doesn't call dropPropertiesToRemove
+
+const { contextMenuZindex } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore
/**
* Initialize drag
@@ -79,10 +71,14 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
}
export namespace DragManager {
+ export const dragClassName = 'collectionFreeFormDocumentView-container';
let dragDiv: HTMLDivElement;
let dragLabel: HTMLDivElement;
export let StartWindowDrag: Opt<(e: { pageX: number; pageY: number }, dragDocs: Doc[], finishDrag?: (aborted: boolean) => void) => boolean>;
export let CompleteWindowDrag: Opt<(aborted: boolean) => void>;
+ export let AbortDrag: () => void = emptyFunction;
+ export const docsBeingDragged: Doc[] = observable([]);
+ export let DocDragData: DocumentDragData | undefined;
export function Root() {
const root = document.getElementById('root');
@@ -91,7 +87,6 @@ export namespace DragManager {
}
return root;
}
- export let AbortDrag: () => void = emptyFunction;
export type MoveFunction = (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean;
export type RemoveFunction = (document: Doc | Doc[]) => boolean;
@@ -106,6 +101,7 @@ export namespace DragManager {
// event called when the drag operation results in a drop action
export class DropEvent {
+ // eslint-disable-next-line no-useless-constructor
constructor(
readonly x: number,
readonly y: number,
@@ -115,7 +111,9 @@ export namespace DragManager {
readonly metaKey: boolean,
readonly ctrlKey: boolean,
readonly embedKey: boolean
- ) {}
+ ) {
+ /* empty */
+ }
}
// event called when the drag operation has completed (aborted or completed a drop) -- this will be after any drop event has been generated
@@ -139,11 +137,11 @@ export namespace DragManager {
constructor(dragDoc: Doc[], dropAction?: dropActionType) {
this.draggedDocuments = dragDoc;
this.droppedDocuments = [];
- this.draggedViews = [];
this.offset = [0, 0];
this.dropAction = dropAction;
}
- draggedViews: DocumentView[];
+ dragEnding?: () => void;
+ dragStarting?: () => void;
draggedDocuments: Doc[];
droppedDocuments: Doc[];
treeViewDoc?: Doc;
@@ -157,6 +155,7 @@ export namespace DragManager {
removeDocument?: RemoveFunction;
isDocDecorationMove?: boolean; // Flags that Document decorations are used to drag document which allows suppression of onDragStart scripts
}
+ Doc.SetDocDragDataName(DocumentDragData.name);
export class LinkDragData {
constructor(dragView: DocumentView, linkSourceGetAnchor: () => Doc) {
this.linkDragView = dragView;
@@ -194,7 +193,7 @@ export namespace DragManager {
userDropAction?: dropActionType;
}
- let defaultPreDropFunc = (e: Event, de: DragManager.DropEvent, targetAction: dropActionType) => {
+ const defaultPreDropFunc = (e: Event, de: DragManager.DropEvent, targetAction: dropActionType) => {
if (de.complete.docDragData) {
targetAction && (de.complete.docDragData.dropAction = targetAction);
e.stopPropagation();
@@ -224,12 +223,12 @@ export namespace DragManager {
export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions, onDropCompleted?: (e?: DragCompleteEvent) => any) {
const addAudioTag = (dropDoc: any) => {
dropDoc && !dropDoc.author_date && (dropDoc.author_date = new DateField());
- dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc);
+ dropDoc instanceof Doc && CreateLinkToActiveAudio(() => dropDoc);
return dropDoc;
};
const finishDrag = async (e: DragCompleteEvent) => {
- const docDragData = e.docDragData;
- setTimeout(() => dragData.draggedViews.forEach(view => view.props.dragEnding?.()));
+ const { docDragData } = e;
+ setTimeout(() => dragData.dragEnding?.());
onDropCompleted?.(e); // glr: optional additional function to be called - in this case with presentation trails
if (docDragData && !docDragData.droppedDocuments.length) {
docDragData.dropAction = dragData.userDropAction || dragData.dropAction;
@@ -256,27 +255,32 @@ export namespace DragManager {
.forEach((drop: Doc, i: number) => {
const dragProps = StrListCast(dragData.draggedDocuments[i].dropPropertiesToRemove);
const remProps = (dragData?.dropPropertiesToRemove || []).concat(Array.from(dragProps));
- [...remProps, 'dropPropertiesToRemove'].map(prop => (drop[prop] = undefined));
+ [...remProps, 'dropPropertiesToRemove'].forEach(prop => {
+ drop[prop] = undefined;
+ });
});
}
return e;
};
dragData.draggedDocuments.map(d => d.dragFactory); // does this help? trying to make sure the dragFactory Doc is loaded
StartDrag(eles, dragData, downX, downY, options, finishDrag);
- dragData.draggedViews.forEach(view => view.props.dragStarting?.());
+ dragData.dragStarting?.();
return true;
}
// drag a button template and drop a new button
- export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
+ export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: FieldType }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
const finishDrag = (e: DragCompleteEvent) => {
const bd = Docs.Create.ButtonDocument({ toolTip: title, z: 1, _width: 150, _height: 50, title, onClick: ScriptField.MakeScript(script) });
- params.map(p => Object.keys(vars).indexOf(p) !== -1 && (bd[DocData][p] = new PrefetchProxy(vars[p] as Doc))); // copy all "captured" arguments into document parameterfields
+ params.forEach(p => {
+ Object.keys(vars).indexOf(p) !== -1 && (bd[DocData][p] = new PrefetchProxy(vars[p] as Doc));
+ }); // copy all "captured" arguments into document parameterfields
initialize?.(bd);
bd[DocData]['onClick-paramFieldKeys'] = new List<string>(params);
e.docDragData && (e.docDragData.droppedDocuments = [bd]);
return e;
};
+ // eslint-disable-next-line no-param-reassign
options = options ?? {};
options.noAutoscroll = true; // these buttons are being dragged on the overlay layer, so scrollin the underlay is not appropriate
StartDrag(eles, new DragManager.DocumentDragData([]), downX, downY, options, finishDrag);
@@ -298,7 +302,7 @@ export namespace DragManager {
}
export function snapDragAspect(dragPt: number[], snapAspect: number) {
- let closest = Utils.SNAP_THRESHOLD;
+ let closest = ClientUtils.SNAP_THRESHOLD;
let near = dragPt;
const intersect = (x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, dragx: number, dragy: number) => {
if ((x1 === x2 && y1 === y2) || (x3 === x4 && y3 === y4)) return undefined; // Check if none of the lines are of length 0
@@ -307,7 +311,7 @@ export namespace DragManager {
const ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator;
// let ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator;
- //if (ua < 0 || ua > 1 || ub < 0 || ub > 1) return undefined; // is the intersection along the segments
+ // if (ua < 0 || ua > 1 || ub < 0 || ub > 1) return undefined; // is the intersection along the segments
// Return a object with the x and y coordinates of the intersection
const x = x1 + ua * (x2 - x1);
@@ -315,14 +319,14 @@ export namespace DragManager {
const dist = Math.sqrt((dragx - x) * (dragx - x) + (dragy - y) * (dragy - y));
return { pt: [x, y], dist };
};
- SnappingManager.VertSnapLines.forEach((xCoord, i) => {
+ SnappingManager.VertSnapLines.forEach(xCoord => {
const pt = intersect(dragPt[0], dragPt[1], dragPt[0] + snapAspect, dragPt[1] + 1, xCoord, -1, xCoord, 1, dragPt[0], dragPt[1]);
if (pt && pt.dist < closest) {
closest = pt.dist;
near = pt.pt;
}
});
- SnappingManager.HorizSnapLines.forEach((yCoord, i) => {
+ SnappingManager.HorizSnapLines.forEach(yCoord => {
const pt = intersect(dragPt[0], dragPt[1], dragPt[0] + snapAspect, dragPt[1] + 1, -1, yCoord, 1, yCoord, dragPt[0], dragPt[1]);
if (pt && pt.dist < closest) {
closest = pt.dist;
@@ -333,7 +337,7 @@ export namespace DragManager {
}
// snap to the active snap lines - if oneAxis is set (eg, for maintaining aspect ratios), then it only snaps to the nearest horizontal/vertical line
export function snapDrag(e: PointerEvent, xFromLeft: number, yFromTop: number, xFromRight: number, yFromBottom: number) {
- const snapThreshold = Utils.SNAP_THRESHOLD;
+ const snapThreshold = ClientUtils.SNAP_THRESHOLD;
const snapVal = (pts: number[], drag: number, snapLines: number[]) => {
if (snapLines.length) {
const offs = [pts[0], (pts[0] - pts[1]) / 2, -pts[1]]; // offsets from drag pt
@@ -350,14 +354,33 @@ export namespace DragManager {
y: snapVal([yFromTop, yFromBottom], e.pageY, SnappingManager.HorizSnapLines),
};
}
- export let docsBeingDragged: Doc[] = observable([]);
- export let CanEmbed = false;
- export let DocDragData: DocumentDragData | undefined;
- export function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void, dragUndoName?: string) {
+
+ async function dispatchDrag(target: Element, e: PointerEvent, complete: DragCompleteEvent, pos: { x: number; y: number }, finishDrag?: (e: DragCompleteEvent) => void, options?: DragOptions, endDrag?: () => void) {
+ const dropArgs = {
+ cancelable: true, // allows preventDefault() to be called to cancel the drop
+ bubbles: true,
+ detail: {
+ ...pos,
+ complete,
+ shiftKey: e.shiftKey,
+ altKey: e.altKey,
+ metaKey: e.metaKey,
+ ctrlKey: e.ctrlKey,
+ embedKey: SnappingManager.CanEmbed,
+ },
+ };
+ target.dispatchEvent(new CustomEvent<DropEvent>('dashPreDrop', dropArgs));
+ UndoManager.StartTempBatch(); // run drag/drop in temp batch in case drop is not allowed (so we can undo any intermediate changes)
+ await finishDrag?.(complete);
+ UndoManager.EndTempBatch(target.dispatchEvent(new CustomEvent<DropEvent>('dashOnDrop', dropArgs))); // event return val is true unless the event preventDefault() is called
+ 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;
const batch = UndoManager.StartBatch(dragUndoName ?? 'document drag');
- eles = eles.filter(e => e);
+ const eles = elesIn.filter(e => e);
SnappingManager.SetCanEmbed(dragData.canEmbed || false);
if (!dragDiv) {
dragDiv = document.createElement('div');
@@ -375,9 +398,9 @@ export namespace DragManager {
}
Object.assign(dragDiv.style, { width: '', height: '', overflow: '' });
dragDiv.hidden = false;
- const scalings: number[] = [],
- xs: number[] = [],
- ys: number[] = [];
+ const scalings: number[] = [];
+ const xs: number[] = [];
+ const ys: number[] = [];
const elesCont = {
left: Number.MAX_SAFE_INTEGER,
@@ -385,7 +408,7 @@ export namespace DragManager {
top: Number.MAX_SAFE_INTEGER,
bottom: Number.MIN_SAFE_INTEGER,
};
- let rot: number[] = [];
+ const rot: number[] = [];
const docsToDrag = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof AnchorAnnoDragData ? [dragData.dragDocument] : [];
const dragElements = eles.map(ele => {
// bcz: very hacky -- if dragged element is a freeForm view with a rotation, then extract the rotation in order to apply it to the dragged element
@@ -394,7 +417,7 @@ export namespace DragManager {
// if the parent isn't a freeform view, then the element's width and height are presumed to match the acutal doc's dimensions (eg, dragging from import sidebar menu)
let rotation: number | undefined;
for (let parEle: HTMLElement | null | undefined = ele.parentElement; parEle; parEle = parEle?.parentElement) {
- if (parEle.className === CollectionFreeFormDocumentView.CollectionFreeFormDocViewClassName) {
+ if (parEle.className === DragManager.dragClassName) {
rotation = (rotation ?? 0) + Number(parEle.style.transform.replace(/.*rotate\(([-0-9.e]*)deg\).*/, '$1') || 0);
}
parEle = parEle.parentElement;
@@ -471,16 +494,20 @@ export namespace DragManager {
.filter(pb => pb.width && pb.height)
.map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0));
}
- [dragElement, ...Array.from(dragElement.getElementsByTagName('*'))].forEach(ele => (ele as any).style && ((ele as any).style.pointerEvents = 'none'));
+ [dragElement, ...Array.from(dragElement.getElementsByTagName('*'))]
+ .map(dele => (dele as any).style)
+ .forEach(style => {
+ style && (style.pointerEvents = 'none');
+ });
dragDiv.appendChild(dragElement);
if (dragElement !== ele) {
- const children = [Array.from(ele.children), Array.from(dragElement.children)];
- while (children[0].length) {
- const childs = [children[0].pop(), children[1].pop()];
+ const dragChildren = [Array.from(ele.children), Array.from(dragElement.children)];
+ while (dragChildren[0].length) {
+ const childs = [dragChildren[0].pop(), dragChildren[1].pop()];
if (childs[0]?.children) {
- children[0].push(...Array.from(childs[0].children));
- children[1].push(...Array.from(childs[1]!.children));
+ dragChildren[0].push(...Array.from(childs[0].children));
+ dragChildren[1].push(...Array.from(childs[1]!.children));
}
if (childs[0]?.scrollTop) childs[1]!.scrollTop = childs[0].scrollTop;
}
@@ -493,7 +520,11 @@ export namespace DragManager {
const hideDragShowOriginalElements = (hide: boolean) => {
dragLabel.style.display = hide && !SnappingManager.CanEmbed ? '' : 'none';
!hide && dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
- setTimeout(() => eles.forEach(ele => (ele.hidden = hide)));
+ setTimeout(() =>
+ eles.forEach(ele => {
+ ele.hidden = hide;
+ })
+ );
};
options?.hideSource && hideDragShowOriginalElements(true);
@@ -505,22 +536,7 @@ export namespace DragManager {
const yFromBottom = elesCont.bottom - downY;
let scrollAwaiter: Opt<NodeJS.Timeout>;
- AbortDrag = () => {
- options?.dragComplete?.(new DragCompleteEvent(true, dragData));
- cleanupDrag(true);
- };
-
- const cleanupDrag = action((undo: boolean) => {
- (dragData as DocumentDragData).draggedViews?.forEach(view => view.props.dragEnding?.());
- hideDragShowOriginalElements(false);
- document.removeEventListener('pointermove', moveHandler, true);
- document.removeEventListener('pointerup', upHandler, true);
- SnappingManager.SetIsDragging(false);
- if (batch.end() && undo) UndoManager.Undo();
- docsBeingDragged.length = 0;
- SnappingManager.SetCanEmbed(false);
- });
- var startWindowDragTimer: any;
+ let startWindowDragTimer: any;
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) {
@@ -580,10 +596,10 @@ export namespace DragManager {
defaultPrevented: true,
eventPhase: e.eventPhase,
isTrusted: true,
- preventDefault: () => ('not implemented for this event' ? false : false),
- isDefaultPrevented: () => ('not implemented for this event' ? false : false),
- stopPropagation: () => ('not implemented for this event' ? false : false),
- isPropagationStopped: () => ('not implemented for this event' ? false : false),
+ 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,
persist: emptyFunction,
timeStamp: e.timeStamp,
type: 'dashDragMovePause',
@@ -602,7 +618,9 @@ export namespace DragManager {
const moveVec = { x: x - lastPt.x, y: y - lastPt.y };
lastPt = { x, y };
- dragElements.map((dragElement, i) => (dragElement.style.transform = `translate(${(xs[i] += moveVec.x)}px, ${(ys[i] += moveVec.y)}px) rotate(${rot[i]}deg) scale(${scalings[i]})`));
+ dragElements.forEach((dragElement, i) => {
+ dragElement.style.transform = `translate(${(xs[i] += moveVec.x)}px, ${(ys[i] += moveVec.y)}px) rotate(${rot[i]}deg) scale(${scalings[i]})`;
+ });
dragLabel.style.transform = `translate(${xs[0]}px, ${ys[0] - 20}px)`;
};
const upHandler = (e: PointerEvent) => {
@@ -610,36 +628,21 @@ export namespace DragManager {
startWindowDragTimer = undefined;
dispatchDrag(document.elementFromPoint(e.x, e.y) || document.body, e, new DragCompleteEvent(false, dragData), snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom), finishDrag, options, () => cleanupDrag(false));
};
+ const cleanupDrag = action((undo: boolean) => {
+ (dragData as DocumentDragData).dragEnding?.();
+ hideDragShowOriginalElements(false);
+ document.removeEventListener('pointermove', moveHandler, true);
+ document.removeEventListener('pointerup', upHandler, true);
+ SnappingManager.SetIsDragging(false);
+ if (batch.end() && undo) UndoManager.Undo();
+ docsBeingDragged.length = 0;
+ SnappingManager.SetCanEmbed(false);
+ });
+ AbortDrag = () => {
+ options?.dragComplete?.(new DragCompleteEvent(true, dragData));
+ cleanupDrag(true);
+ };
document.addEventListener('pointermove', moveHandler, true);
document.addEventListener('pointerup', upHandler, true);
}
-
- async function dispatchDrag(target: Element, e: PointerEvent, complete: DragCompleteEvent, pos: { x: number; y: number }, finishDrag?: (e: DragCompleteEvent) => void, options?: DragOptions, endDrag?: () => void) {
- const dropArgs = {
- cancelable: true, // allows preventDefault() to be called to cancel the drop
- bubbles: true,
- detail: {
- ...pos,
- complete,
- shiftKey: e.shiftKey,
- altKey: e.altKey,
- metaKey: e.metaKey,
- ctrlKey: e.ctrlKey,
- embedKey: SnappingManager.CanEmbed,
- },
- };
- target.dispatchEvent(new CustomEvent<DropEvent>('dashPreDrop', dropArgs));
- UndoManager.StartTempBatch(); // run drag/drop in temp batch in case drop is not allowed (so we can undo any intermediate changes)
- await finishDrag?.(complete);
- UndoManager.EndTempBatch(target.dispatchEvent(new CustomEvent<DropEvent>('dashOnDrop', dropArgs))); // event return val is true unless the event preventDefault() is called
- options?.dragComplete?.(complete);
- endDrag?.();
- }
}
-
-ScriptingGlobals.add(function toggleRaiseOnDrag(readOnly?: boolean) {
- if (readOnly) {
- return SelectionManager.Views.some(dv => dv.Document.keepZWhenDragged);
- }
- SelectionManager.Views.map(dv => (dv.Document.keepZWhenDragged = !dv.Document.keepZWhenDragged));
-});
diff --git a/src/client/util/DropActionTypes.ts b/src/client/util/DropActionTypes.ts
new file mode 100644
index 000000000..45b294d97
--- /dev/null
+++ b/src/client/util/DropActionTypes.ts
@@ -0,0 +1,9 @@
+export enum dropActionType {
+ embed = 'embed', // create a new embedding of the dragged document for the new location
+ copy = 'copy', // copy the dragged document
+ move = 'move', // move the dragged document to the drop location after removing it from where it was
+ add = 'add', // add the dragged document to the drop location without removing it from where it was
+ same = 'same', // only allow drop within same collection (or same hierarchical tree collection)
+ inPlace = 'inSame', // keep document in place (unless overridden by a drag modifier)
+ proto = 'proto',
+} // undefined = move, same = move but doesn't call dropPropertiesToRemove
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 3df3e36c6..0314af06b 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -1,10 +1,9 @@
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { Doc, DocListCast, StrListCast } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { ObjectField } from '../../fields/ObjectField';
import { RichTextField } from '../../fields/RichTextField';
-import { listSpec } from '../../fields/Schema';
import { ComputedField, ScriptField } from '../../fields/ScriptField';
-import { Cast, StrCast } from '../../fields/Types';
+import { StrCast } from '../../fields/Types';
import { ImageField } from '../../fields/URLField';
import { Docs } from '../documents/Documents';
import { DocumentType } from '../documents/DocumentTypes';
@@ -13,21 +12,7 @@ import { DragManager } from './DragManager';
import { ScriptingGlobals } from './ScriptingGlobals';
/**
- * Converts a Doc to a render template that can be applied to other Docs to customize how they render while
- * still using the other Doc as the backing data store (ie, dataDoc). During rendering, if a layout Doc is provided
- * with 'isTemplateDoc' set, then the layout Doc is treated as a template for the rendered Doc. The template Doc is
- * "expanded" to create an template instance for the rendered Doc.
- *
*
- * @param doc the doc to convert to a template
- * @returns 'doc'
- */
-export function MakeTemplate(doc: Doc) {
- doc.isTemplateDoc = makeTemplate(doc, true);
- return doc;
-}
-
-/**
* Recursively converts 'doc' into a template that can be used to render other documents.
*
* For recurive Docs in the template, their target fieldKey is defined by their title,
@@ -62,39 +47,61 @@ function makeTemplate(doc: Doc, first: boolean = true): boolean {
}
return isTemplate;
}
+
+/**
+ * Converts a Doc to a render template that can be applied to other Docs to customize how they render while
+ * still using the other Doc as the backing data store (ie, dataDoc). During rendering, if a layout Doc is provided
+ * with 'isTemplateDoc' set, then the layout Doc is treated as a template for the rendered Doc. The template Doc is
+ * "expanded" to create an template instance for the rendered Doc.
+ *
+ *
+ * @param doc the doc to convert to a template
+ * @returns 'doc'
+ */
+export function MakeTemplate(doc: Doc) {
+ doc.isTemplateDoc = makeTemplate(doc, true);
+ return doc;
+}
+
+export function makeUserTemplateButton(doc: Doc) {
+ const layoutDoc = doc; // doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
+ if (layoutDoc.type !== DocumentType.FONTICON) {
+ !layoutDoc.isTemplateDoc && makeTemplate(layoutDoc);
+ }
+ layoutDoc.isTemplateDoc = true;
+ const dbox = Docs.Create.FontIconDocument({
+ _nativeWidth: 100,
+ _nativeHeight: 100,
+ _width: 100,
+ _height: 100,
+ backgroundColor: StrCast(doc.backgroundColor),
+ title: StrCast(layoutDoc.title),
+ btnType: ButtonType.ClickButton,
+ icon: 'bolt',
+ isSystem: false,
+ });
+ dbox.title = ComputedField.MakeFunction('this.dragFactory.title');
+ dbox.dragFactory = layoutDoc;
+ dbox.dropPropertiesToRemove = doc.dropPropertiesToRemove instanceof ObjectField ? ObjectField.MakeCopy(doc.dropPropertiesToRemove) : undefined;
+ dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory)');
+ return dbox;
+}
export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
- data?.draggedDocuments.map((doc, i) => {
+ data?.draggedDocuments.forEach((doc, i) => {
let dbox = doc;
// bcz: isButtonBar is intended to allow a collection of linear buttons to be dropped and nested into another collection of buttons... it's not being used yet, and isn't very elegant
if (doc.type === DocumentType.FONTICON || StrCast(Doc.Layout(doc).layout).includes(FontIconBox.name)) {
if (data.dropPropertiesToRemove || dbox.dropPropertiesToRemove) {
- //dbox = Doc.MakeEmbedding(doc); // don't need to do anything if dropping an icon doc onto an icon bar since there should be no layout data for an icon
+ // dbox = Doc.MakeEmbedding(doc); // don't need to do anything if dropping an icon doc onto an icon bar since there should be no layout data for an icon
dbox = Doc.MakeEmbedding(dbox);
- const dragProps = Cast(dbox.dropPropertiesToRemove, listSpec('string'), []);
+ const dragProps = StrListCast(dbox.dropPropertiesToRemove);
const remProps = (data.dropPropertiesToRemove || []).concat(Array.from(dragProps));
- remProps.map(prop => (dbox[prop] = undefined));
+ remProps.forEach(prop => {
+ dbox[prop] = undefined;
+ });
}
} else if (!doc.onDragStart && !doc.isButtonBar) {
- const layoutDoc = doc; // doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
- if (layoutDoc.type !== DocumentType.FONTICON) {
- !layoutDoc.isTemplateDoc && makeTemplate(layoutDoc);
- }
- layoutDoc.isTemplateDoc = true;
- dbox = Docs.Create.FontIconDocument({
- _nativeWidth: 100,
- _nativeHeight: 100,
- _width: 100,
- _height: 100,
- backgroundColor: StrCast(doc.backgroundColor),
- title: StrCast(layoutDoc.title),
- btnType: ButtonType.ClickButton,
- icon: 'bolt',
- isSystem: false,
- });
- dbox.title = ComputedField.MakeFunction('this.dragFactory.title');
- dbox.dragFactory = layoutDoc;
- dbox.dropPropertiesToRemove = doc.dropPropertiesToRemove instanceof ObjectField ? ObjectField.MakeCopy(doc.dropPropertiesToRemove) : undefined;
- dbox.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory)');
+ dbox = makeUserTemplateButton(doc);
} else if (doc.isButtonBar) {
dbox.ignoreClick = true;
}
@@ -102,6 +109,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
});
}
ScriptingGlobals.add(
+ // eslint-disable-next-line prefer-arrow-callback
function convertToButtons(dragData: any) {
convertDropDataToButtons(dragData as DragManager.DocumentDragData);
},
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index f4f879208..5701a22c0 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -1,3 +1,5 @@
+/* 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';
@@ -5,19 +7,20 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import Select from 'react-select';
import * as RequestPromise from 'request-promise';
+import { ClientUtils } from '../../ClientUtils';
+import { Utils } from '../../Utils';
import { DateField } from '../../fields/DateField';
import { Doc, DocListCast, Opt } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { listSpec } from '../../fields/Schema';
import { Cast, StrCast } from '../../fields/Types';
-import { Utils } from '../../Utils';
import { MainViewModal } from '../views/MainViewModal';
+import { ObservableReactComponent } from '../views/ObservableReactComponent';
import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
import './GroupManager.scss';
import { GroupMemberView } from './GroupMemberView';
-import { SettingsManager } from './SettingsManager';
import { SharingManager, User } from './SharingManager';
-import { ObservableReactComponent } from '../views/ObservableReactComponent';
+import { SnappingManager } from './SnappingManager';
/**
* Interface for options for the react-select component
@@ -29,6 +32,7 @@ export interface UserOptions {
@observer
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.
@observable private users: string[] = []; // list of users populated from the database.
@@ -55,7 +59,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
*/
populateUsers = async () => {
if (Doc.UserDoc()[Id] !== Utils.GuestID()) {
- const userList = await RequestPromise.get(Utils.prepend('/getUsers'));
+ const userList = await RequestPromise.get(ClientUtils.prepend('/getUsers'));
const raw = JSON.parse(userList) as User[];
raw.map(action(user => !this.users.some(umail => umail === user.email) && this.users.push(user.email)));
}
@@ -73,7 +77,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
*/
@action
open = () => {
- // SelectionManager.DeselectAll();
+ // DocumentView.DeselectAll();
this.isOpen = true;
this.populateUsers();
};
@@ -135,7 +139,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
hasEditAccess(groupDoc: Doc): boolean {
if (!groupDoc) return false;
const accessList: string[] = JSON.parse(StrCast(groupDoc.owners));
- return accessList.includes(Doc.CurrentUserEmail) || this.adminGroupMembers?.includes(Doc.CurrentUserEmail);
+ return accessList.includes(ClientUtils.CurrentUserEmail()) || this.adminGroupMembers?.includes(ClientUtils.CurrentUserEmail());
}
/**
@@ -147,7 +151,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
const name = groupName.toLowerCase() === 'admin' ? 'Admin' : groupName;
const groupDoc = new Doc('GROUP:' + name, true);
groupDoc.title = name;
- groupDoc.owners = JSON.stringify([Doc.CurrentUserEmail]);
+ groupDoc.owners = JSON.stringify([ClientUtils.CurrentUserEmail()]);
groupDoc.members = JSON.stringify(memberEmails);
this.addGroup(groupDoc);
}
@@ -159,7 +163,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
addGroup(groupDoc: Doc): boolean {
if (this.GroupManagerDoc) {
Doc.AddDocToList(this.GroupManagerDoc, 'data', groupDoc);
- this.GroupManagerDoc['data_modificationDate'] = new DateField();
+ this.GroupManagerDoc.data_modificationDate = new DateField();
return true;
}
return false;
@@ -176,11 +180,11 @@ export class GroupManager extends ObservableReactComponent<{}> {
Doc.RemoveDocFromList(this.GroupManagerDoc, 'data', group);
SharingManager.Instance.removeGroup(group);
const members = JSON.parse(StrCast(group.members));
- if (members.includes(Doc.CurrentUserEmail)) {
+ if (members.includes(ClientUtils.CurrentUserEmail())) {
const index = DocListCast(this.GroupManagerDoc.data).findIndex(grp => grp === group);
index !== -1 && Cast(this.GroupManagerDoc.data, listSpec(Doc), [])?.splice(index, 1);
}
- this.GroupManagerDoc['data_modificationDate'] = new DateField();
+ this.GroupManagerDoc.data_modificationDate = new DateField();
if (group === this.currentGroup) {
this.currentGroup = undefined;
}
@@ -201,7 +205,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
!memberList.includes(email) && memberList.push(email);
groupDoc.members = JSON.stringify(memberList);
SharingManager.Instance.shareWithAddedMember(groupDoc, email);
- this.GroupManagerDoc && (this.GroupManagerDoc['data_modificationDate'] = new DateField());
+ this.GroupManagerDoc && (this.GroupManagerDoc.data_modificationDate = new DateField());
}
}
@@ -215,10 +219,9 @@ export class GroupManager extends ObservableReactComponent<{}> {
const memberList = JSON.parse(StrCast(groupDoc.members));
const index = memberList.indexOf(email);
if (index !== -1) {
- const user = memberList.splice(index, 1)[0];
groupDoc.members = JSON.stringify(memberList);
SharingManager.Instance.removeMember(groupDoc, email);
- this.GroupManagerDoc && (this.GroupManagerDoc['data_modificationDate'] = new DateField());
+ this.GroupManagerDoc && (this.GroupManagerDoc.data_modificationDate = new DateField());
}
}
}
@@ -260,7 +263,10 @@ export class GroupManager extends ObservableReactComponent<{}> {
alert('Please select a unique group name');
return;
}
- this.createGroupDoc(value, this.selectedUsers?.map(user => user.value));
+ this.createGroupDoc(
+ value,
+ this.selectedUsers?.map(user => user.value)
+ );
this.selectedUsers = null;
this.inputRef.current!.value = '';
this.buttonColour = '#979797';
@@ -271,7 +277,9 @@ export class GroupManager extends ObservableReactComponent<{}> {
TaskCompletionBox.textDisplayed = 'Group created!';
TaskCompletionBox.taskCompleted = true;
setTimeout(
- action(() => (TaskCompletionBox.taskCompleted = false)),
+ action(() => {
+ TaskCompletionBox.taskCompleted = false;
+ }),
2000
);
};
@@ -281,14 +289,14 @@ export class GroupManager extends ObservableReactComponent<{}> {
*/
private get groupCreationModal() {
const contents = (
- <div className="group-create" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}>
+ <div className="group-create" style={{ background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor }}>
<div className="group-heading" style={{ marginBottom: 0 }}>
<p>
<b>New Group</b>
</p>
<div className="close-button">
<Button
- icon={<FontAwesomeIcon icon={'times'} size={'lg'} />}
+ icon={<FontAwesomeIcon icon="times" size="lg" />}
onClick={action(() => {
this.createGroupModalOpen = false;
TaskCompletionBox.taskCompleted = false;
@@ -298,7 +306,17 @@ export class GroupManager extends ObservableReactComponent<{}> {
</div>
</div>
<div className="group-input" style={{ border: StrCast(Doc.UserDoc().userColor) }}>
- <input ref={this.inputRef} onKeyDown={this.handleKeyDown} autoFocus type="text" placeholder="Group name" onChange={action(() => (this.buttonColour = this.inputRef.current?.value ? 'black' : '#979797'))} />
+ <input
+ ref={this.inputRef}
+ onKeyDown={this.handleKeyDown}
+ // eslint-disable-next-line jsx-a11y/no-autofocus
+ autoFocus
+ type="text"
+ placeholder="Group name"
+ onChange={action(() => {
+ this.buttonColour = this.inputRef.current?.value ? 'black' : '#979797';
+ })}
+ />
</div>
<div style={{ border: StrCast(Doc.UserDoc().userColor) }}>
<Select
@@ -306,7 +324,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
isMulti
options={this.options}
onChange={this.handleChange}
- placeholder={'Select users'}
+ placeholder="Select users"
value={this.selectedUsers}
closeMenuOnSelect={false}
styles={{
@@ -331,8 +349,8 @@ export class GroupManager extends ObservableReactComponent<{}> {
}}
/>
</div>
- <div className={'create-button'}>
- <Button text={'Create'} type={Type.TERT} color={StrCast(Doc.UserDoc().userColor)} onClick={this.createGroup} />
+ <div className="create-button">
+ <Button text="Create" type={Type.TERT} color={StrCast(Doc.UserDoc().userColor)} onClick={this.createGroup} />
</div>
</div>
);
@@ -340,7 +358,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
return (
<MainViewModal
isDisplayed={this.createGroupModalOpen}
- interactive={true}
+ interactive
contents={contents}
dialogueBoxStyle={{ width: '90%', height: '70%' }}
closeOnExternalClick={action(() => {
@@ -366,30 +384,61 @@ export class GroupManager extends ObservableReactComponent<{}> {
const groups = this.groupSort === 'ascending' ? this.allGroups.sort(sortGroups) : this.groupSort === 'descending' ? this.allGroups.sort(sortGroups).reverse() : this.allGroups;
return (
- <div className="group-interface" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}>
+ <div className="group-interface" style={{ background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor }}>
{this.groupCreationModal}
- {this.currentGroup ? <GroupMemberView group={this.currentGroup} onCloseButtonClick={action(() => (this.currentGroup = undefined))} /> : null}
+ {this.currentGroup ? (
+ <GroupMemberView
+ group={this.currentGroup}
+ onCloseButtonClick={action(() => {
+ this.currentGroup = undefined;
+ })}
+ />
+ ) : null}
<div className="group-heading">
<p>
<b>Manage Groups</b>
</p>
- <Button icon={<FontAwesomeIcon icon={'plus'} />} iconPlacement={'left'} text={'Create Group'} type={Type.TERT} color={StrCast(Doc.UserDoc().userColor)} onClick={action(() => (this.createGroupModalOpen = true))} />
- <div className={'close-button'}>
- <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={this.close} color={StrCast(Doc.UserDoc().userColor)} />
+ <Button
+ icon={<FontAwesomeIcon icon="plus" />}
+ iconPlacement="left"
+ text="Create Group"
+ type={Type.TERT}
+ color={StrCast(Doc.UserDoc().userColor)}
+ onClick={action(() => {
+ this.createGroupModalOpen = true;
+ })}
+ />
+ <div className="close-button">
+ <Button icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={this.close} color={StrCast(Doc.UserDoc().userColor)} />
</div>
</div>
<div className="main-container">
- <div className="sort-groups" onClick={action(() => (this.groupSort = this.groupSort === 'ascending' ? 'descending' : this.groupSort === 'descending' ? 'none' : 'ascending'))}>
+ <div
+ className="sort-groups"
+ onClick={action(() => {
+ this.groupSort = this.groupSort === 'ascending' ? 'descending' : this.groupSort === 'descending' ? 'none' : 'ascending';
+ })}>
Name
<IconButton icon={<FontAwesomeIcon icon={this.groupSort === 'ascending' ? 'caret-up' : this.groupSort === 'descending' ? 'caret-down' : 'caret-right'} />} size={Size.XSMALL} color={StrCast(Doc.UserDoc().userColor)} />
</div>
- <div className={'style-divider'} style={{ background: StrCast(Doc.UserDoc().userColor) }} />
+ <div className="style-divider" style={{ background: StrCast(Doc.UserDoc().userColor) }} />
<div className="group-body" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), color: StrCast(Doc.UserDoc().userColor) }}>
{groups.map(group => (
<div className="group-row" key={StrCast(group.title || group.groupName)}>
<div className="group-name">{StrCast(group.title || group.groupName)}</div>
- <div className="group-info" onClick={action(() => (this.currentGroup = group))}>
- <IconButton icon={<FontAwesomeIcon icon={'info-circle'} />} size={Size.XSMALL} color={StrCast(Doc.UserDoc().userColor)} onClick={action(() => (this.currentGroup = group))} />
+ <div
+ className="group-info"
+ onClick={action(() => {
+ this.currentGroup = group;
+ })}>
+ <IconButton
+ icon={<FontAwesomeIcon icon="info-circle" />}
+ size={Size.XSMALL}
+ color={StrCast(Doc.UserDoc().userColor)}
+ onClick={action(() => {
+ this.currentGroup = group;
+ })}
+ />
</div>
</div>
))}
@@ -400,6 +449,6 @@ export class GroupManager extends ObservableReactComponent<{}> {
}
render() {
- return <MainViewModal contents={this.groupInterface} isDisplayed={this.isOpen} interactive={true} dialogueBoxStyle={{ zIndex: 1002 }} overlayStyle={{ zIndex: 1001 }} closeOnExternalClick={this.close} />;
+ return <MainViewModal contents={this.groupInterface} isDisplayed={this.isOpen} interactive dialogueBoxStyle={{ zIndex: 1002 }} overlayStyle={{ zIndex: 1001 }} closeOnExternalClick={this.close} />;
}
}
diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx
index 894583711..da9e1aa28 100644
--- a/src/client/util/GroupMemberView.tsx
+++ b/src/client/util/GroupMemberView.tsx
@@ -1,4 +1,7 @@
+/* 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';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -8,8 +11,7 @@ import { StrCast } from '../../fields/Types';
import { MainViewModal } from '../views/MainViewModal';
import { GroupManager, UserOptions } from './GroupManager';
import './GroupMemberView.scss';
-import { Button, IconButton, Size, Type } from 'browndash-components';
-import { SettingsManager } from './SettingsManager';
+import { SnappingManager } from './SnappingManager';
interface GroupMemberViewProps {
group: Doc;
@@ -32,26 +34,29 @@ export class GroupMemberView extends React.Component<GroupMemberViewProps> {
const hasEditAccess = GroupManager.Instance.hasEditAccess(this.group);
return !this.group ? null : (
- <div className="editing-interface" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}>
+ <div className="editing-interface" style={{ background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor }}>
<div className="editing-header">
<input
className="group-title"
style={{ marginLeft: !hasEditAccess ? '-14%' : 0 }}
value={StrCast(this.group.title || this.group.groupName)}
- onChange={e => (this.group.title = e.currentTarget.value)}
- disabled={!hasEditAccess}></input>
- <div className={'memberView-closeButton'}>
- <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={action(this.props.onCloseButtonClick)} color={StrCast(Doc.UserDoc().userColor)} />
+ onChange={e => {
+ this.group.title = e.currentTarget.value;
+ }}
+ disabled={!hasEditAccess}
+ />
+ <div className="memberView-closeButton">
+ <Button icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={action(this.props.onCloseButtonClick)} color={StrCast(Doc.UserDoc().userColor)} />
</div>
{GroupManager.Instance.hasEditAccess(this.group) ? (
<div className="group-buttons">
<div style={{ border: StrCast(Doc.UserDoc().userColor) }}>
<Select
className="add-member-dropdown"
- isSearchable={true}
+ isSearchable
options={options}
onChange={selectedOption => GroupManager.Instance.addMemberToGroup(this.group, (selectedOption as UserOptions).value)}
- placeholder={'Add members'}
+ placeholder="Add members"
value={null}
styles={{
control: () => ({
@@ -80,7 +85,12 @@ export class GroupMemberView extends React.Component<GroupMemberViewProps> {
</div>
</div>
) : null}
- <div className="sort-emails" style={{ paddingTop: hasEditAccess ? 0 : 35 }} onClick={action(() => (this.memberSort = this.memberSort === 'ascending' ? 'descending' : this.memberSort === 'descending' ? 'none' : 'ascending'))}>
+ <div
+ className="sort-emails"
+ style={{ paddingTop: hasEditAccess ? 0 : 35 }}
+ onClick={action(() => {
+ this.memberSort = this.memberSort === 'ascending' ? 'descending' : this.memberSort === 'descending' ? 'none' : 'ascending';
+ })}>
Emails {this.memberSort === 'ascending' ? '↑' : this.memberSort === 'descending' ? '↓' : ''} {/* → */}
</div>
</div>
@@ -90,8 +100,8 @@ export class GroupMemberView extends React.Component<GroupMemberViewProps> {
<div className="editing-row" key={member}>
<div className="user-email">{member}</div>
{hasEditAccess ? (
- <div className={'remove-button'} onClick={() => GroupManager.Instance.removeMemberFromGroup(this.group, member)}>
- <IconButton icon={<FontAwesomeIcon icon={'trash-alt'} />} size={Size.XSMALL} color={StrCast(Doc.UserDoc().userColor)} onClick={() => GroupManager.Instance.removeMemberFromGroup(this.group, member)} />
+ <div className="remove-button" onClick={() => GroupManager.Instance.removeMemberFromGroup(this.group, member)}>
+ <IconButton icon={<FontAwesomeIcon icon="trash-alt" />} size={Size.XSMALL} color={StrCast(Doc.UserDoc().userColor)} onClick={() => GroupManager.Instance.removeMemberFromGroup(this.group, member)} />
</div>
) : null}
</div>
@@ -102,6 +112,6 @@ export class GroupMemberView extends React.Component<GroupMemberViewProps> {
}
render() {
- return <MainViewModal isDisplayed={true} interactive={true} contents={this.editingInterface} dialogueBoxStyle={{ width: 400, height: 250 }} closeOnExternalClick={this.props.onCloseButtonClick} />;
+ return <MainViewModal isDisplayed interactive contents={this.editingInterface} dialogueBoxStyle={{ width: 400, height: 250 }} closeOnExternalClick={this.props.onCloseButtonClick} />;
}
}
diff --git a/src/client/util/History.ts b/src/client/util/History.ts
index 2f1a336cc..52d0223d5 100644
--- a/src/client/util/History.ts
+++ b/src/client/util/History.ts
@@ -1,6 +1,12 @@
+/* eslint-disable no-use-before-define */
+/* eslint-disable no-empty */
+/* eslint-disable no-continue */
+/* eslint-disable guard-for-in */
+/* eslint-disable no-restricted-syntax */
+/* eslint-disable no-param-reassign */
import * as qs from 'query-string';
import { Doc } from '../../fields/Doc';
-import { OmitKeys, Utils } from '../../Utils';
+import { OmitKeys, ClientUtils } from '../../ClientUtils';
import { DocServer } from '../DocServer';
import { DashboardView } from '../views/DashboardView';
@@ -32,6 +38,7 @@ export namespace HistoryUtil {
case 'doc':
onDocUrl(url);
break;
+ default:
}
}
}
@@ -124,11 +131,11 @@ export namespace HistoryUtil {
const val = customParser(pathname, opts, current);
if (val === null) {
return undefined;
- } else if (val === undefined) {
+ }
+ if (val === undefined) {
return current;
- } else {
- return val;
}
+ return val;
}
return current;
};
@@ -136,32 +143,33 @@ export namespace HistoryUtil {
function addStringifier(type: string, keys: string[], customStringifier?: (state: ParsedUrl, current: string) => string) {
stringifiers[type] = state => {
- let path = Utils.prepend(`/${type}`);
+ let path = ClientUtils.prepend(`/${type}`);
if (customStringifier) {
path = customStringifier(state, path);
}
const queryObj = OmitKeys(state, keys).extract;
const query: any = {};
- Object.keys(queryObj).forEach(key => (query[key] = queryObj[key] === null ? null : JSON.stringify(queryObj[key])));
+ Object.keys(queryObj).forEach(key => {
+ query[key] = queryObj[key] === null ? null : JSON.stringify(queryObj[key]);
+ });
const queryString = qs.stringify(query);
return path + (queryString ? `?${queryString}` : '');
};
}
addParser('doc', {}, { readonly: true, initializers: true, nro: true, sharing: true }, (pathname, opts, current) => {
- if (pathname.length !== 2) return undefined;
-
- current.initializers = current.initializers || {};
- const docId = pathname[1];
- current.docId = docId;
- });
- addStringifier('doc', ['initializers', 'readonly', 'nro'], (state, current) => {
- return `${current}/${state.docId}`;
+ if (pathname.length === 2) {
+ current.initializers = current.initializers || {};
+ const docId = pathname[1];
+ current.docId = docId;
+ }
+ return undefined;
});
+ addStringifier('doc', ['initializers', 'readonly', 'nro'], (state, current) => `${current}/${state.docId}`);
export function parseUrl(location: Location | URL): ParsedUrl | undefined {
const pathname = location.pathname.substring(1);
- const search = location.search;
+ const { search } = location;
const opts = search.length ? qs.parse(search, { sort: false }) : {};
const pathnameSplit = pathname.split('/');
diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts
index c5f307f44..5a6522dc8 100644
--- a/src/client/util/HypothesisUtils.ts
+++ b/src/client/util/HypothesisUtils.ts
@@ -1,15 +1,11 @@
import { action, runInAction } from 'mobx';
-import { simulateMouseClick } from '../../Utils';
+import { simulateMouseClick } from '../../ClientUtils';
import { Doc, Opt } from '../../fields/Doc';
import { Cast, StrCast } from '../../fields/Types';
import { WebField } from '../../fields/URLField';
-import { DocumentType } from '../documents/DocumentTypes';
import { Docs } from '../documents/Documents';
import { DocumentLinksButton } from '../views/nodes/DocumentLinksButton';
import { DocumentView } from '../views/nodes/DocumentView';
-import { DocumentManager } from './DocumentManager';
-import { SearchUtil } from './SearchUtil';
-import { SelectionManager } from './SelectionManager';
export namespace Hypothesis {
/**
@@ -17,6 +13,7 @@ export namespace Hypothesis {
* If none exist, create and return a new WebDocument.
*/
export const getSourceWebDoc = async (uri: string) => {
+ // eslint-disable-next-line no-use-before-define
const result = await findWebDoc(uri);
console.log(result ? 'existing doc found' : 'existing doc NOT found');
return result || Docs.Create.WebDocument(uri, { title: uri, _nativeWidth: 850, _height: 512, _width: 400, data_useCors: true }); // create and return a new Web doc with given uri if no matching docs are found
@@ -26,21 +23,21 @@ export namespace Hypothesis {
* Search for a WebDocument whose url field matches the given uri, return undefined if not found
*/
export const findWebDoc = async (uri: string) => {
- const currentDoc = SelectionManager.Docs.lastElement();
+ const currentDoc = DocumentView.Selected().lastElement()?.Document;
if (currentDoc && Cast(currentDoc.data, WebField)?.url.href === uri) return currentDoc; // always check first whether the currently selected doc is the annotation's source, only use Search otherwise
const results: Doc[] = [];
// await SearchUtil.Search('web', true).then(
// action(async (res: SearchUtil.DocSearchResult) => {
// const docs = res.docs;
- // const filteredDocs = docs.filter(doc => doc.author === Doc.CurrentUserEmail && doc.type === DocumentType.WEB && doc.data);
+ // const filteredDocs = docs.filter(doc => doc.author === ClientUtils.CurrentUserEmail() && doc.type === DocumentType.WEB && doc.data);
// filteredDocs.forEach(doc => {
// uri === Cast(doc.data, WebField)?.url.href && results.push(doc); // TODO check visited sites history?
// });
// })
// );
- const onScreenResults = results.filter(doc => DocumentManager.Instance.getFirstDocumentView(doc));
+ const onScreenResults = results.filter(doc => DocumentView.getFirstDocumentView(doc));
return onScreenResults.length ? onScreenResults[0] : results.length ? results[0] : undefined; // prioritize results that are currently on the screen
};
@@ -66,7 +63,7 @@ export namespace Hypothesis {
DocumentLinksButton.AnnotationId = annotationId;
DocumentLinksButton.AnnotationUri = annotationUri;
});
- const endLinkView = DocumentManager.Instance.getFirstDocumentView(sourceDoc);
+ const endLinkView = DocumentView.getFirstDocumentView(sourceDoc);
const rect = document.body.getBoundingClientRect();
const x = rect.x + rect.width / 2;
const y = 250;
@@ -77,17 +74,19 @@ export namespace Hypothesis {
/**
* Send message to Hypothes.is client to edit an annotation to add a Dash hyperlink
*/
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
export const makeLink = async (title: string, url: string, annotationId: string, annotationSourceDoc: Doc) => {
// if the annotation's source webpage isn't currently loaded in Dash, we're not able to access and edit the annotation from the client
// so we're loading the webpage and its annotations invisibly in a WebBox in MainView.tsx, until the editing is done
- //!DocumentManager.Instance.getFirstDocumentView(annotationSourceDoc) && runInAction(() => DocumentLinksButton.invisibleWebDoc = annotationSourceDoc);
+ //! DocumentManager.Instance.getFirstDocumentView(annotationSourceDoc) && runInAction(() => DocumentLinksButton.invisibleWebDoc = annotationSourceDoc);
- var success = false;
+ let success = false;
const onSuccess = action(() => {
console.log('Edit success!!');
success = true;
+ // eslint-disable-next-line no-use-before-define
clearTimeout(interval);
- //DocumentLinksButton.invisibleWebDoc = undefined;
+ // DocumentLinksButton.invisibleWebDoc = undefined;
document.removeEventListener('editSuccess', onSuccess);
});
@@ -109,7 +108,7 @@ export namespace Hypothesis {
action(() => {
if (!success) {
clearInterval(interval);
- //DocumentLinksButton.invisibleWebDoc = undefined;
+ // DocumentLinksButton.invisibleWebDoc = undefined;
}
}),
10000
@@ -123,12 +122,13 @@ export namespace Hypothesis {
export const deleteLink = async (linkDoc: Doc, sourceDoc: Doc, destinationDoc: Doc) => {
if (Cast(destinationDoc.data, WebField)?.url.href !== StrCast(linkDoc.annotationUri)) return; // check that the destinationDoc is a WebDocument containing the target annotation
- //!DocumentManager.Instance.getFirstDocumentView(destinationDoc) && runInAction(() => DocumentLinksButton.invisibleWebDoc = destinationDoc); // see note in makeLink
+ //! DocumentManager.Instance.getFirstDocumentView(destinationDoc) && runInAction(() => DocumentLinksButton.invisibleWebDoc = destinationDoc); // see note in makeLink
- var success = false;
+ let success = false;
const onSuccess = action(() => {
console.log('Edit success!');
success = true;
+ // eslint-disable-next-line no-use-before-define
clearTimeout(interval);
// DocumentLinksButton.invisibleWebDoc = undefined;
document.removeEventListener('editSuccess', onSuccess);
@@ -151,7 +151,7 @@ export namespace Hypothesis {
action(() => {
if (!success) {
clearInterval(interval);
- //DocumentLinksButton.invisibleWebDoc = undefined;
+ // DocumentLinksButton.invisibleWebDoc = undefined;
}
}),
10000
@@ -163,10 +163,11 @@ export namespace Hypothesis {
* Send message to Hypothes.is client to scroll to an annotation when it loads
*/
export const scrollToAnnotation = (annotationId: string, target: Doc) => {
- var success = false;
+ let success = false;
const onSuccess = () => {
console.log('Scroll success!!');
document.removeEventListener('scrollSuccess', onSuccess);
+ // eslint-disable-next-line no-use-before-define
clearInterval(interval);
success = true;
};
@@ -179,7 +180,7 @@ export namespace Hypothesis {
bubbles: true,
})
);
- const targetView: Opt<DocumentView> = DocumentManager.Instance.getFirstDocumentView(target);
+ const targetView: Opt<DocumentView> = DocumentView.getFirstDocumentView(target);
const position = targetView?.screenToViewTransform().inverse().transformPoint(0, 0);
targetView && position && simulateMouseClick(targetView.ContentDiv!, position[0], position[1], position[0], position[1], false);
}, 300);
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 398ba3c04..baa0786b7 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -17,7 +17,6 @@
// import { DocumentType } from '../../documents/DocumentTypes';
// import { Networking } from '../../Network';
// import { FieldView, FieldViewProps } from '../../views/nodes/FieldView';
-// import { DocumentManager } from '../DocumentManager';
// import './DirectoryImportBox.scss';
// import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from './ImportMetadataEntry';
// import * as React from 'react';
diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts
index d99828956..8d4eefa7e 100644
--- a/src/client/util/Import & Export/ImageUtils.ts
+++ b/src/client/util/Import & Export/ImageUtils.ts
@@ -1,10 +1,10 @@
+import { ClientUtils } from '../../../ClientUtils';
import { Doc } from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
+import { Id } from '../../../fields/FieldSymbols';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
-import { Cast, StrCast, NumCast } from '../../../fields/Types';
import { Networking } from '../../Network';
-import { Id } from '../../../fields/FieldSymbols';
-import { Utils } from '../../../Utils';
-import { DocData } from '../../../fields/DocSymbols';
export namespace ImageUtils {
export type imgInfo = {
@@ -16,7 +16,7 @@ export namespace ImageUtils {
};
export const ExtractImgInfo = async (document: Doc): Promise<imgInfo | undefined> => {
const field = Cast(document.data, ImageField);
- return field ? await Networking.PostToServer('/inspectImage', { source: field.url.href }) : undefined;
+ return field ? Networking.PostToServer('/inspectImage', { source: field.url.href }) : undefined;
};
export const AssignImgInfo = (document: Doc, data?: imgInfo) => {
@@ -35,7 +35,7 @@ export namespace ImageUtils {
export const ExportHierarchyToFileSystem = async (collection: Doc): Promise<void> => {
const a = document.createElement('a');
- a.href = Utils.prepend(`/imageHierarchyExport/${collection[Id]}`);
+ a.href = ClientUtils.prepend(`/imageHierarchyExport/${collection[Id]}`);
a.download = `Dash Export [${StrCast(collection.title)}].zip`;
a.click();
};
diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx
index 58a09b9c9..db1e3d6cd 100644
--- a/src/client/util/Import & Export/ImportMetadataEntry.tsx
+++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx
@@ -1,10 +1,13 @@
-import * as React from 'react';
-import { observer } from 'mobx-react';
-import { EditableView } from '../../views/EditableView';
-import { action, computed } from 'mobx';
+/* 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';
+import { observer } from 'mobx-react';
+import * as React from 'react';
import { Doc } from '../../../fields/Doc';
-import { StrCast, BoolCast } from '../../../fields/Types';
+import { BoolCast, StrCast } from '../../../fields/Types';
+import { EditableView } from '../../views/EditableView';
interface KeyValueProps {
Document: Doc;
@@ -93,18 +96,27 @@ export default class ImportMetadataEntry extends React.Component<KeyValueProps>
alignItems: 'center',
alignContent: 'center',
}}>
- <input onChange={e => (this.onDataDoc = e.target.checked)} ref={this.checkRef} style={{ margin: '0 10px 0 15px' }} type="checkbox" title={'Add to Data Document?'} checked={this.onDataDoc} />
- <div className={'key_container'} style={keyValueStyle}>
- <EditableView ref={this.keyRef} contents={this.key} SetValue={this.updateKey} GetValue={() => ''} oneLine={true} />
+ <input
+ onChange={e => {
+ this.onDataDoc = e.target.checked;
+ }}
+ ref={this.checkRef}
+ style={{ margin: '0 10px 0 15px' }}
+ type="checkbox"
+ title="Add to Data Document?"
+ checked={this.onDataDoc}
+ />
+ <div className="key_container" style={keyValueStyle}>
+ <EditableView ref={this.keyRef} contents={this.key} SetValue={this.updateKey} GetValue={() => ''} oneLine />
</div>
- <div className={'value_container'} style={keyValueStyle}>
- <EditableView ref={this.valueRef} contents={this.value} SetValue={this.updateValue} GetValue={() => ''} oneLine={true} />
+ <div className="value_container" style={keyValueStyle}>
+ <EditableView ref={this.valueRef} contents={this.value} SetValue={this.updateValue} GetValue={() => ''} oneLine />
</div>
- <div onClick={() => this.props.remove(this)} title={'Delete Entry'}>
+ <div onClick={() => this.props.remove(this)} title="Delete Entry">
<FontAwesomeIcon
- icon={'plus'}
- color={'red'}
- size={'1x'}
+ icon="plus"
+ color="red"
+ size="1x"
style={{
marginLeft: 15,
marginRight: 15,
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index a2f5826fe..a07550e09 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import { GestureUtils } from '../../pen-gestures/GestureUtils';
import { Utils } from '../../Utils';
+import { Gestures } from '../../pen-gestures/GestureTypes';
import './InteractionUtils.scss';
export namespace InteractionUtils {
@@ -9,81 +9,86 @@ export namespace InteractionUtils {
export const PENTYPE = 'pen';
export const ERASERTYPE = 'eraser';
- const POINTER_PEN_BUTTON = -1;
- const REACT_POINTER_PEN_BUTTON = 0;
const ERASER_BUTTON = 5;
- export class MultiTouchEvent<T extends React.TouchEvent | TouchEvent> {
- constructor(
- readonly fingers: number,
- readonly targetTouches: T extends React.TouchEvent ? React.Touch[] : Touch[],
- readonly touches: T extends React.TouchEvent ? React.Touch[] : Touch[],
- readonly changedTouches: T extends React.TouchEvent ? React.Touch[] : Touch[],
- readonly touchEvent: T extends React.TouchEvent ? React.TouchEvent : TouchEvent
- ) {}
- }
-
- export interface MultiTouchEventDisposer {
- (): void;
- }
-
- /**
- *
- * @param element - element to turn into a touch target
- * @param startFunc - event handler, typically Touchable.onTouchStart (classes that inherit touchable can pass in this.onTouchStart)
- */
- export function MakeMultiTouchTarget(element: HTMLElement, startFunc: (e: Event, me: MultiTouchEvent<React.TouchEvent>) => void): MultiTouchEventDisposer {
- const onMultiTouchStartHandler = (e: Event) => startFunc(e, (e as CustomEvent<MultiTouchEvent<React.TouchEvent>>).detail);
- // const onMultiTouchMoveHandler = moveFunc ? (e: Event) => moveFunc(e, (e as CustomEvent<MultiTouchEvent<TouchEvent>>).detail) : undefined;
- // const onMultiTouchEndHandler = endFunc ? (e: Event) => endFunc(e, (e as CustomEvent<MultiTouchEvent<TouchEvent>>).detail) : undefined;
- element.addEventListener('dashOnTouchStart', onMultiTouchStartHandler);
- // if (onMultiTouchMoveHandler) {
- // element.addEventListener("dashOnTouchMove", onMultiTouchMoveHandler);
- // }
- // if (onMultiTouchEndHandler) {
- // element.addEventListener("dashOnTouchEnd", onMultiTouchEndHandler);
- // }
- return () => {
- element.removeEventListener('dashOnTouchStart', onMultiTouchStartHandler);
- // if (onMultiTouchMoveHandler) {
- // element.removeEventListener("dashOnTouchMove", onMultiTouchMoveHandler);
- // }
- // if (onMultiTouchEndHandler) {
- // element.removeEventListener("dashOnTouchend", onMultiTouchEndHandler);
- // }
- };
- }
-
- /**
- * Turns an element onto a target for touch hold handling.
- * @param element - element to add events to
- * @param func - function to add to the event
- */
- export function MakeHoldTouchTarget(element: HTMLElement, func: (e: Event, me: MultiTouchEvent<React.TouchEvent>) => void): MultiTouchEventDisposer {
- const handler = (e: Event) => func(e, (e as CustomEvent<MultiTouchEvent<React.TouchEvent>>).detail);
- element.addEventListener('dashOnTouchHoldStart', handler);
- return () => {
- element.removeEventListener('dashOnTouchHoldStart', handler);
- };
- }
-
- export function GetMyTargetTouches(mte: InteractionUtils.MultiTouchEvent<React.TouchEvent | TouchEvent>, prevPoints: Map<number, React.Touch>, ignorePen: boolean): React.Touch[] {
- const myTouches = new Array<React.Touch>();
- for (const pt of mte.touches) {
- if (!ignorePen || ((pt as any).radiusX > 1 && (pt as any).radiusY > 1)) {
- for (const tPt of mte.targetTouches) {
- if (tPt?.screenX === pt?.screenX && tPt?.screenY === pt?.screenY) {
- if (pt && prevPoints.has(pt.identifier)) {
- myTouches.push(pt);
- }
- }
+ export function makePolygon(shape: string, 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;
+ let right = points[1].X;
+ 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)) {
+ // otherwise take max and min
+ const xs = points.map(p => p.X);
+ const ys = points.map(p => p.Y);
+ right = Math.max(...xs);
+ left = Math.min(...xs);
+ bottom = Math.max(...ys);
+ top = Math.min(...ys);
+ }
+ } else {
+ // if in the middle of drawing
+ // take first and last points
+ right = points[points.length - 1].X;
+ left = points[0].X;
+ bottom = points[points.length - 1].Y;
+ top = points[0].Y;
+ if (shape !== Gestures.Arrow && shape !== Gestures.Line && shape !== Gestures.Circle) {
+ // switch left/right and top/bottom if needed
+ if (left > right) {
+ const temp = right;
+ right = left;
+ left = temp;
+ }
+ if (top > bottom) {
+ const temp = top;
+ top = bottom;
+ bottom = temp;
}
}
}
- // if (mte.touches.length !== myTouches.length) {
- // throw Error("opo")
- // }
- return myTouches;
+ const polyPts = [];
+ switch (shape) {
+ case Gestures.Rectangle:
+ polyPts.push({ X: left, Y: top });
+ polyPts.push({ X: right, Y: top });
+ polyPts.push({ X: right, Y: bottom });
+ polyPts.push({ X: left, Y: bottom });
+ polyPts.push({ X: left, Y: top });
+ break;
+ case Gestures.Triangle:
+ polyPts.push({ X: left, Y: bottom });
+ polyPts.push({ X: right, Y: bottom });
+ polyPts.push({ X: (right + left) / 2, Y: top });
+ polyPts.push({ X: left, Y: bottom });
+ break;
+ case Gestures.Circle:
+ {
+ const centerX = (Math.max(left, right) + Math.min(left, right)) / 2;
+ const centerY = (Math.max(top, bottom) + Math.min(top, bottom)) / 2;
+ const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom));
+ for (let x = centerX - radius; x < centerX + radius; x++) {
+ const y = Math.sqrt(radius ** 2 - (x - centerX) ** 2) + centerY;
+ polyPts.push({ X: x, Y: y });
+ }
+ for (let x = centerX + radius; x > centerX - radius; x--) {
+ const y = Math.sqrt(radius ** 2 - (x - centerX) ** 2) + centerY;
+ const newY = centerY - (y - centerY);
+ polyPts.push({ X: x, Y: newY });
+ }
+ polyPts.push({ X: centerX - radius, Y: Math.sqrt(radius ** 2 - (-radius) ** 2) + centerY });
+ }
+ break;
+
+ case Gestures.Line:
+ default:
+ polyPts.push({ X: left, Y: top });
+ polyPts.push({ X: right, Y: bottom });
+ break;
+ }
+ return polyPts;
}
export function CreatePolyline(
@@ -101,20 +106,20 @@ export namespace InteractionUtils {
arrowEnd: string,
markerScale: number,
dash: string | undefined,
- scalex: number,
- scaley: number,
+ scalexIn: number,
+ scaleyIn: number,
shape: string,
pevents: string,
opacity: number,
nodefs: boolean,
downHdlr?: (e: React.PointerEvent) => void,
- mask?: boolean,
- dropshadow?: string
+ mask?: boolean
+ // dropshadow?: string
) {
const pts = shape ? makePolygon(shape, points) : points;
- if (isNaN(scalex)) scalex = 1;
- if (isNaN(scaley)) scaley = 1;
+ const scalex = isNaN(scalexIn) ? 1 : scalexIn;
+ const scaley = isNaN(scaleyIn) ? 1 : scaleyIn;
const toScr = (p: { X: number; Y: number }) => ` ${!p ? 0 : (p.X - left - width / 2) * scalex + width / 2}, ${!p ? 0 : (p.Y - top - width / 2) * scaley + width / 2} `;
const strpts = bezier
@@ -137,7 +142,7 @@ export namespace InteractionUtils {
<defs>
{!mask ? null : (
<filter id={`mask${defGuid}`} x="-1" y="-1" width="500%" height="500%">
- <feGaussianBlur result="blurOut" in="offOut" stdDeviation="5"></feGaussianBlur>
+ <feGaussianBlur result="blurOut" in="offOut" stdDeviation="5" />
</filter>
)}
{arrowStart !== 'dot' && arrowEnd !== 'dot' ? null : (
@@ -172,7 +177,7 @@ export namespace InteractionUtils {
<Tag
d={bezier ? strpts + (arrowStart || arrowEnd ? ' ' : '') : undefined}
points={bezier ? undefined : strpts}
- //filter={!dropshadow ? undefined : `drop-shadow(-1px -1px 0px ${dropshadow}) `}
+ // filter={!dropshadow ? undefined : `drop-shadow(-1px -1px 0px ${dropshadow}) `}
style={{
// filter: drawHalo ? "url(#inkSelectionHalo)" : undefined,
fill: fill && fill !== 'transparent' ? fill : 'none',
@@ -193,83 +198,6 @@ export namespace InteractionUtils {
);
}
- export function makePolygon(shape: string, points: { X: number; Y: number }[]) {
- 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 (shape === GestureUtils.Gestures.Arrow || shape === GestureUtils.Gestures.Line || shape === GestureUtils.Gestures.Circle) {
- //if arrow or line, the two end points should be the starting and the ending point
- var left = points[0].X;
- var top = points[0].Y;
- var right = points[1].X;
- var bottom = points[1].Y;
- } else {
- //otherwise take max and min
- const xs = points.map(p => p.X);
- const ys = points.map(p => p.Y);
- right = Math.max(...xs);
- left = Math.min(...xs);
- bottom = Math.max(...ys);
- top = Math.min(...ys);
- }
- } else {
- //if in the middle of drawing
- //take first and last points
- right = points[points.length - 1].X;
- left = points[0].X;
- bottom = points[points.length - 1].Y;
- top = points[0].Y;
- if (shape !== GestureUtils.Gestures.Arrow && shape !== GestureUtils.Gestures.Line && shape !== GestureUtils.Gestures.Circle) {
- //switch left/right and top/bottom if needed
- if (left > right) {
- const temp = right;
- right = left;
- left = temp;
- }
- if (top > bottom) {
- const temp = top;
- top = bottom;
- bottom = temp;
- }
- }
- }
- points = [];
- switch (shape) {
- case GestureUtils.Gestures.Rectangle:
- points.push({ X: left, Y: top });
- points.push({ X: right, Y: top });
- points.push({ X: right, Y: bottom });
- points.push({ X: left, Y: bottom });
- points.push({ X: left, Y: top });
- break;
- case GestureUtils.Gestures.Triangle:
- points.push({ X: left, Y: bottom });
- points.push({ X: right, Y: bottom });
- points.push({ X: (right + left) / 2, Y: top });
- points.push({ X: left, Y: bottom });
- break;
- case GestureUtils.Gestures.Circle:
- const centerX = (Math.max(left, right) + Math.min(left, right)) / 2;
- const centerY = (Math.max(top, bottom) + Math.min(top, bottom)) / 2;
- const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom));
- for (var x = centerX - radius; x < centerX + radius; x++) {
- const y = Math.sqrt(Math.pow(radius, 2) - Math.pow(x - centerX, 2)) + centerY;
- points.push({ X: x, Y: y });
- }
- for (var x = centerX + radius; x > centerX - radius; x--) {
- const y = Math.sqrt(Math.pow(radius, 2) - Math.pow(x - centerX, 2)) + centerY;
- const newY = centerY - (y - centerY);
- points.push({ X: x, Y: newY });
- }
- points.push({ X: centerX - radius, Y: Math.sqrt(Math.pow(radius, 2) - Math.pow(-radius, 2)) + centerY });
- break;
-
- case GestureUtils.Gestures.Line:
- points.push({ X: left, Y: top });
- points.push({ X: right, Y: bottom });
- break;
- }
- return points;
- }
/**
* Returns whether or not the pointer event passed in is of the type passed in
* @param e - pointer event. this event could be from a mouse, a pen, or a finger
@@ -279,10 +207,11 @@ export namespace InteractionUtils {
// prettier-ignore
switch (type) {
// pen and eraser are both pointer type 'pen', but pen is button 0 and eraser is button 5. -syip2
- case PENTYPE: return e.pointerType === PENTYPE && (e.button === -1 || e.button === 0);
+ case PENTYPE: return e.pointerType === PENTYPE && (e.button === -1 || e.button === 0);
case ERASERTYPE: return e.pointerType === PENTYPE && e.button === (e instanceof PointerEvent ? ERASER_BUTTON : ERASER_BUTTON);
- case TOUCHTYPE: return e.pointerType === TOUCHTYPE;
- }
+ case TOUCHTYPE: return e.pointerType === TOUCHTYPE;
+ default:
+ } // prettier-ignore
return e.pointerType === type;
}
@@ -292,7 +221,7 @@ export namespace InteractionUtils {
* @param pt2
*/
export function TwoPointEuclidist(pt1: React.Touch, pt2: React.Touch): number {
- return Math.sqrt(Math.pow(pt1.clientX - pt2.clientX, 2) + Math.pow(pt1.clientY - pt2.clientY, 2));
+ return Math.sqrt((pt1.clientX - pt2.clientX) ** 2 + (pt1.clientY - pt2.clientY) ** 2);
}
/**
@@ -349,72 +278,4 @@ export namespace InteractionUtils {
}
return 0;
}
-
- export function IsDragging(oldTouches: Map<number, React.Touch>, newTouches: React.Touch[], leniency: number): boolean {
- for (const touch of newTouches) {
- if (touch) {
- const oldTouch = oldTouches.get(touch.identifier);
- if (oldTouch) {
- if (TwoPointEuclidist(touch, oldTouch) >= leniency) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- // These might not be very useful anymore, but I'll leave them here for now -syip2
- {
- /**
- * Returns the type of Touch Interaction from a list of points.
- * Also returns any data that is associated with a Touch Interaction
- * @param pts - List of points
- */
- // export function InterpretPointers(pts: React.Touch[]): { type: Opt<TouchInteraction>, data?: any } {
- // const leniency = 200;
- // switch (pts.length) {
- // case 1:
- // return { type: OneFinger };
- // case 2:
- // return { type: TwoSeperateFingers };
- // case 3:
- // let pt1 = pts[0];
- // let pt2 = pts[1];
- // let pt3 = pts[2];
- // if (pt1 && pt2 && pt3) {
- // let dist12 = TwoPointEuclidist(pt1, pt2);
- // let dist23 = TwoPointEuclidist(pt2, pt3);
- // let dist13 = TwoPointEuclidist(pt1, pt3);
- // let dist12close = dist12 < leniency;
- // let dist23close = dist23 < leniency;
- // let dist13close = dist13 < leniency;
- // let xor2313 = dist23close ? !dist13close : dist13close;
- // let xor = dist12close ? !xor2313 : xor2313;
- // // three input xor because javascript doesn't have logical xor's
- // if (xor) {
- // let points: number[] = [];
- // let min = Math.min(dist12, dist23, dist13);
- // switch (min) {
- // case dist12:
- // points = [0, 1, 2];
- // break;
- // case dist23:
- // points = [1, 2, 0];
- // break;
- // case dist13:
- // points = [0, 2, 1];
- // break;
- // }
- // return { type: TwoToOneFingers, data: points };
- // }
- // else {
- // return { type: ThreeSeperateFingers, data: null };
- // }
- // }
- // default:
- // return { type: undefined };
- // }
- // }
- }
}
diff --git a/src/client/util/KeyCodes.ts b/src/client/util/KeyCodes.ts
index de2457a5a..fb21f78ee 100644
--- a/src/client/util/KeyCodes.ts
+++ b/src/client/util/KeyCodes.ts
@@ -133,4 +133,4 @@ export class KeyCodes {
public static NUM_9: number = 57;
public static SUBTRACT: number = 189;
public static ADD: number = 187;
-} \ No newline at end of file
+}
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index 20261859c..9a0edcfec 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -1,15 +1,12 @@
import { action, runInAction } from 'mobx';
-import { Doc, DocListCast, Field, FieldResult, Opt } from '../../fields/Doc';
-import { ScriptField } from '../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../fields/Types';
+import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { DocumentType } from '../documents/DocumentTypes';
-import { OpenWhere } from '../views/nodes/DocumentView';
-import { FocusViewOptions } from '../views/nodes/FieldView';
+import { DocumentView } from '../views/nodes/DocumentView';
+import { FocusViewOptions } from '../views/nodes/FocusViewOptions';
+import { OpenWhere } from '../views/nodes/OpenWhere';
import { PresBox } from '../views/nodes/trails';
-import { DocumentManager } from './DocumentManager';
-import { LinkManager } from './LinkManager';
import { ScriptingGlobals } from './ScriptingGlobals';
-import { SelectionManager } from './SelectionManager';
import { SnappingManager } from './SnappingManager';
import { UndoManager } from './UndoManager';
/*
@@ -25,6 +22,9 @@ import { UndoManager } from './UndoManager';
* - user defined kvps
*/
export class LinkFollower {
+ public static Init() {
+ DocumentView.FollowLink = LinkFollower.FollowLink;
+ }
// follows a link - if the target is on screen, it highlights/pans to it.
// if the target isn't onscreen, then it will open up the target in the lightbox, or in place
// depending on the followLinkLocation property of the source (or the link itself as a fallback);
@@ -43,9 +43,9 @@ export class LinkFollower {
};
public static traverseLink(link: Opt<Doc>, sourceDoc: Doc, finished?: () => void, traverseBacklink?: boolean) {
- const getView = (doc: Doc) => DocumentManager.Instance.getFirstDocumentView(DocCast(doc.layout_unrendered ? doc.annotationOn : doc));
- const isAnchor = (sourceDoc: Doc, anchor: Doc) => Doc.AreProtosEqual(anchor, sourceDoc) || Doc.AreProtosEqual(anchor.annotationOn as Doc, sourceDoc);
- const linkDocs = link ? [link] : LinkManager.Links(sourceDoc);
+ const getView = (doc: Doc) => DocumentView.getFirstDocumentView(DocCast(doc.layout_unrendered ? doc.annotationOn : doc));
+ const isAnchor = (source: Doc, anchor: Doc) => Doc.AreProtosEqual(anchor, source) || Doc.AreProtosEqual(anchor.annotationOn as Doc, source);
+ const linkDocs = link ? [link] : Doc.Links(sourceDoc);
const fwdLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_1 as Doc)); // link docs where 'sourceDoc' is link_anchor_1
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)));
@@ -53,7 +53,7 @@ export class LinkFollower {
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);
- var count = 0;
+ let count = 0;
const allFinished = () => ++count === followLinks.length && finished?.();
if (!followLinks.length) {
finished?.();
@@ -69,7 +69,7 @@ export class LinkFollower {
? linkDoc.link_anchor_2
: linkDoc.link_anchor_1
) as Doc;
- const srcAnchor = LinkManager.getOppositeAnchor(linkDoc, target) ?? sourceDoc;
+ const srcAnchor: Doc = Doc.getOppositeAnchor(linkDoc, target) ?? sourceDoc;
if (target) {
const doFollow = (canToggle?: boolean) => {
const toggleTarget = canToggle && BoolCast(sourceDoc.followLinkToggle);
@@ -88,14 +88,14 @@ export class LinkFollower {
zoomTextSelections: BoolCast(srcAnchor.followLinkZoomText),
};
if (target.type === DocumentType.PRES) {
- const containerDocContext = DocumentManager.GetContextPath(sourceDoc, true); // gather all views that affect layout of sourceDoc so we can revert them after playing the rail
- SelectionManager.DeselectAll();
- if (!DocumentManager.Instance.AddViewRenderedCb(target, dv => containerDocContext.length && (dv.ComponentView as PresBox).PlayTrail(containerDocContext))) {
+ const containerDocContext = DocumentView.getContextPath(sourceDoc, true); // gather all views that affect layout of sourceDoc so we can revert them after playing the rail
+ DocumentView.DeselectAll();
+ if (!DocumentView.addViewRenderedCb(target, dv => containerDocContext.length && dv.ComponentView?.playTrail?.(containerDocContext))) {
PresBox.OpenPresMinimized(target, [0, 0]);
}
finished?.();
} else {
- DocumentManager.Instance.showDocument(target, options, allFinished);
+ DocumentView.showDocument(target, options, allFinished);
}
};
let movedTarget = false;
@@ -110,18 +110,20 @@ export class LinkFollower {
movedTarget = true;
}
Doc.SetContainer(target, sourceDocParent);
- const moveTo = [NumCast(sourceDoc.x) + NumCast(sourceDoc.followLinkXoffset), NumCast(sourceDoc.y) + NumCast(sourceDoc.followLinkYoffset)];
- if (srcAnchor.followLinkXoffset !== undefined && moveTo[0] !== target.x) {
- target.x = moveTo[0];
- movedTarget = true;
- }
- if (srcAnchor.followLinkYoffset !== undefined && moveTo[1] !== target.y) {
- target.y = moveTo[1];
- movedTarget = true;
- }
- if (movedTarget) setTimeout(doFollow);
- else doFollow(true);
- } else doFollow(true);
+ }
+ const moveTo = [NumCast(sourceDoc.x) + NumCast(sourceDoc.followLinkXoffset), NumCast(sourceDoc.y) + NumCast(sourceDoc.followLinkYoffset)];
+ if (srcAnchor.followLinkXoffset !== undefined && moveTo[0] !== target.x) {
+ // eslint-disable-next-line prefer-destructuring
+ target.x = moveTo[0];
+ movedTarget = true;
+ }
+ if (srcAnchor.followLinkYoffset !== undefined && moveTo[1] !== target.y) {
+ // eslint-disable-next-line prefer-destructuring
+ target.y = moveTo[1];
+ movedTarget = true;
+ }
+ if (movedTarget) setTimeout(doFollow);
+ else doFollow(true);
} else {
allFinished();
}
@@ -130,14 +132,8 @@ export class LinkFollower {
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function followLink(doc: Doc, altKey: boolean) {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
return LinkFollower.FollowLink(undefined, doc, altKey) ? undefined : { select: true };
});
-
-export function FollowLinkScript() {
- return ScriptField.MakeScript('return followLink(this,altKey)', { altKey: 'boolean' });
-}
-export function IsFollowLinkScript(field: FieldResult<Field>) {
- return ScriptCast(field)?.script.originalScript.includes('return followLink(');
-}
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index dd3b9bd07..56d5dce4e 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -1,12 +1,16 @@
-import { action, makeObservable, observable, observe, runInAction } from 'mobx';
+import { action, makeObservable, observable, observe } from 'mobx';
import { computedFn } from 'mobx-utils';
-import { Doc, DocListCast, DocListCastAsync, Field, Opt } from '../../fields/Doc';
+import * as rp from 'request-promise';
+import { ClientUtils } from '../../ClientUtils';
+import { Doc, DocListCast, DocListCastAsync, FieldType, Opt } from '../../fields/Doc';
import { DirectLinks, DocData } from '../../fields/DocSymbols';
import { FieldLoader } from '../../fields/FieldLoader';
+import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
import { ProxyField } from '../../fields/Proxy';
import { Cast, DocCast, PromiseValue, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
+import { DocumentType } from '../documents/DocumentTypes';
import { ScriptingGlobals } from './ScriptingGlobals';
/*
* link doc:
@@ -21,12 +25,13 @@ import { ScriptingGlobals } from './ScriptingGlobals';
* - user defined kvps
*/
export class LinkManager {
+ // eslint-disable-next-line no-use-before-define
@observable static _instance: LinkManager;
@observable.shallow userLinkDBs: Doc[] = [];
@observable public currentLink: Opt<Doc> = undefined;
@observable public currentLinkAnchor: Opt<Doc> = undefined;
- public static get Instance() {
- return LinkManager._instance;
+ public static get Instance(): LinkManager {
+ return Doc.UserDoc() ? LinkManager._instance ?? new LinkManager() : (undefined as any as LinkManager);
}
public static Links(doc: Doc | undefined) {
@@ -42,9 +47,13 @@ export class LinkManager {
this.userLinkDBs.push(linkDb);
};
public static AutoKeywords = 'keywords:Usages';
- constructor() {
+ private constructor() {
makeObservable(this);
LinkManager._instance = this;
+ Doc.AddLink = this.addLink;
+ Doc.DeleteLink = this.deleteLink;
+ Doc.Links = LinkManager.Links;
+ Doc.getOppositeAnchor = LinkManager.getOppositeAnchor;
this.createlink_relationshipLists();
// since this is an action, not a reaction, we get only one shot to add this link to the Anchor docs
// Thus make sure all promised values are resolved from link -> link.proto -> link.link_anchor_[1,2] -> link.link_anchor_[1,2].proto
@@ -56,10 +65,10 @@ export class LinkManager {
Promise.all(lAnchs.map(lAnch => PromiseValue(lAnch?.proto as Doc))).then((lAnchProtos: Opt<Doc>[]) =>
Promise.all(lAnchProtos.map(lAnchProto => PromiseValue(lAnchProto?.proto as Doc))).then(
link &&
- action(lAnchProtoProtos => {
+ action(() => {
Doc.AddDocToList(Doc.UserDoc(), 'links', link);
- lAnchs[0] && lAnchs[0][DocData][DirectLinks].add(link);
- lAnchs[1] && lAnchs[1][DocData][DirectLinks].add(link);
+ lAnchs[0]?.[DocData][DirectLinks].add(link);
+ lAnchs[1]?.[DocData][DirectLinks].add(link);
})
)
)
@@ -73,7 +82,7 @@ export class LinkManager {
Promise.all([lproto?.link_anchor_1 as Doc, lproto?.link_anchor_2 as Doc].map(PromiseValue)).then((lAnchs: Opt<Doc>[]) =>
Promise.all(lAnchs.map(lAnch => PromiseValue(lAnch?.proto as Doc))).then((lAnchProtos: Opt<Doc>[]) =>
Promise.all(lAnchProtos.map(lAnchProto => PromiseValue(lAnchProto?.proto as Doc))).then(
- action(lAnchProtoProtos => {
+ action(() => {
link && lAnchs[0] && lAnchs[0][DocData][DirectLinks].delete(link);
link && lAnchs[1] && lAnchs[1][DocData][DirectLinks].delete(link);
})
@@ -84,7 +93,7 @@ export class LinkManager {
);
const watchUserLinkDB = (userLinkDBDoc: Doc) => {
- const toRealField = (field: Field) => (field instanceof ProxyField ? field.value : field); // see List.ts. data structure is not a simple list of Docs, but a list of ProxyField/Fields
+ 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(
userLinkDBDoc.data,
@@ -95,7 +104,8 @@ export class LinkManager {
(change as any).added.forEach((link: any) => addLinkToDoc(toRealField(link)));
(change as any).removed.forEach((link: any) => remLinkFromDoc(toRealField(link)));
break;
- case 'update': //let oldValue = change.oldValue;
+ case 'update': // let oldValue = change.oldValue;
+ default:
}
},
true
@@ -115,6 +125,8 @@ export class LinkManager {
added?.forEach((link: any) => addLinkToDoc(toRealField(link)));
removed?.forEach((link: any) => remLinkFromDoc(toRealField(link)));
});
+ break;
+ default:
}
},
true
@@ -128,7 +140,8 @@ export class LinkManager {
case 'splice':
(change as any).added.forEach(watchUserLinkDB);
break;
- case 'update': //let oldValue = change.oldValue;
+ case 'update': // let oldValue = change.oldValue;
+ default:
}
},
true
@@ -138,7 +151,7 @@ export class LinkManager {
}
public createlink_relationshipLists = () => {
- //create new lists for link relations and their associated colors if the lists don't already exist
+ // create new lists for link relations and their associated colors if the lists don't already exist
!Doc.UserDoc().link_relationshipList && (Doc.UserDoc().link_relationshipList = new List<string>());
!Doc.UserDoc().link_ColorList && (Doc.UserDoc().link_ColorList = new List<string>());
!Doc.UserDoc().link_relationshipSizes && (Doc.UserDoc().link_relationshipSizes = new List<number>());
@@ -148,33 +161,48 @@ export class LinkManager {
Doc.AddDocToList(Doc.UserDoc(), 'links', linkDoc);
if (!checkExists || !DocListCast(Doc.LinkDBDoc().data).includes(linkDoc)) {
Doc.AddDocToList(Doc.LinkDBDoc(), 'data', linkDoc);
- setTimeout(DocServer.UPDATE_SERVER_CACHE, 100);
+ // eslint-disable-next-line no-use-before-define
+ setTimeout(UPDATE_SERVER_CACHE, 100);
}
}
public deleteLink(linkDoc: Doc) {
- return Doc.RemoveDocFromList(Doc.LinkDBDoc(), 'data', linkDoc);
+ const ret = Doc.RemoveDocFromList(Doc.LinkDBDoc(), 'data', linkDoc);
+ linkDoc[DocData].link_anchor_1 = linkDoc[DocData].link_anchor_2 = undefined;
+ return ret;
}
public deleteAllLinksOnAnchor(anchor: Doc) {
- LinkManager.Instance.relatedLinker(anchor).forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc));
+ LinkManager.Instance.relatedLinker(anchor).forEach(LinkManager.Instance.deleteLink);
}
public getAllRelatedLinks(anchor: Doc) {
return this.relatedLinker(anchor);
} // finds all links that contain the given anchor
public getAllDirectLinks(anchor?: Doc): Doc[] {
- return anchor ? Array.from(anchor[DirectLinks]) : [];
+ return anchor ? Array.from(anchor[DocData][DirectLinks]) : [];
} // finds all links that contain the given anchor
- relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc): Doc[] {
+ computedRelatedLinks = (anchor: Doc, processed: Doc[]): Doc[] => {
+ if (Doc.IsSystem(anchor)) return [];
if (!anchor || anchor instanceof Promise || Doc.GetProto(anchor) instanceof Promise) {
console.log('WAITING FOR DOC/PROTO IN LINKMANAGER');
return [];
}
- const dirLinks = Doc.GetProto(anchor)[DirectLinks];
- const annos = DocListCast(anchor[Doc.LayoutFieldKey(anchor) + '_annotations']);
- if (!annos) debugger;
- return annos.reduce((list, anno) => [...list, ...LinkManager.Instance.relatedLinker(anno)], Array.from(dirLinks).slice());
- }, true);
+
+ const dirLinks = Array.from(anchor[DocData][DirectLinks]).filter(l => Doc.GetProto(anchor) === anchor[DocData] || ['1', '2'].includes(LinkManager.anchorIndex(l, anchor) as any));
+ 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(
+ annos.reduce((set, anno) => {
+ if (!processed.includes(anno)) {
+ processed.push(anno);
+ this.computedRelatedLinks(anno, processed).forEach(link => set.add(link));
+ }
+ return set;
+ }, new Set<Doc>(dirLinks))
+ );
+ };
+
+ relatedLinker = computedFn((anchor: Doc): Doc[] => this.computedRelatedLinks(anchor, [anchor]), true);
// returns map of group type to anchor's links in that group type
public getRelatedGroupedLinks(anchor: Doc): Map<string, Array<Doc>> {
@@ -182,7 +210,7 @@ export class LinkManager {
this.relatedLinker(anchor).forEach(link => {
if (link.link_relationship && link.link_relationship !== '-ungrouped-') {
const relation = StrCast(link.link_relationship);
- const anchorRelation = relation.indexOf(':') !== -1 ? relation.split(':')[Doc.AreProtosEqual(Cast(link.link_anchor_1, Doc, null), anchor) ? 0 : 1] : relation;
+ const anchorRelation: string = relation.indexOf(':') !== -1 ? relation.split(':')[Doc.AreProtosEqual(Cast(link.link_anchor_1, Doc, null), anchor) ? 0 : 1] : relation;
const group = anchorGroups.get(anchorRelation);
anchorGroups.set(anchorRelation, group ? [...group, link] : [link]);
} else {
@@ -208,23 +236,53 @@ export class LinkManager {
const a1 = DocCast(linkDoc.link_anchor_1);
const a2 = DocCast(linkDoc.link_anchor_2);
if (linkDoc.link_matchEmbeddings) {
- return [a2, a2.annotationOn].includes(anchor) ? '2' : '1';
+ return [a2, a2?.annotationOn].includes(anchor) ? '2' : '1';
}
- if (Doc.AreProtosEqual(DocCast(anchor.annotationOn, anchor), DocCast(a1?.annotationOn, a1))) return '1';
- if (Doc.AreProtosEqual(DocCast(anchor.annotationOn, anchor), DocCast(a2?.annotationOn, a2))) return '2';
+ if (Doc.AreProtosEqual(DocCast(anchor?.annotationOn, anchor), DocCast(a1?.annotationOn, a1))) return '1';
+ if (Doc.AreProtosEqual(DocCast(anchor?.annotationOn, anchor), DocCast(a2?.annotationOn, a2))) return '2';
if (Doc.AreProtosEqual(anchor, linkDoc)) return '0';
-
- // const a1 = DocCast(linkDoc.link_anchor_1);
- // const a2 = DocCast(linkDoc.link_anchor_2);
- // if (linkDoc.link_matchEmbeddings) {
- // return [a2, a2.annotationOn].includes(anchor) ? '2' : '1';
- // }
- // if (Doc.AreProtosEqual(a2, anchor) || Doc.AreProtosEqual(a2.annotationOn as Doc, anchor)) return '2';
- // return Doc.AreProtosEqual(a1, anchor) || Doc.AreProtosEqual(a1.annotationOn as Doc, anchor) ? '1' : '2';
+ return undefined;
}
}
+let cacheDocumentIds = ''; // ; separate string of all documents ids in the user's working set (cached on the server)
+export function UPDATE_SERVER_CACHE() {
+ const prototypes = Object.values(DocumentType)
+ .filter(type => type !== DocumentType.NONE)
+ .map(type => DocServer.GetCachedRefField(type + 'Proto'))
+ .filter(doc => doc instanceof Doc)
+ .map(doc => doc as Doc);
+ const references = new Set<Doc>(prototypes);
+ Doc.FindReferences(Doc.UserDoc(), references, undefined);
+ DocListCast(DocCast(Doc.UserDoc().myLinkDatabase).data).forEach(link => {
+ if (!references.has(DocCast(link.link_anchor_1)) && !references.has(DocCast(link.link_anchor_2))) {
+ Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myLinkDatabase), 'data', link);
+ Doc.AddDocToList(Doc.MyRecentlyClosed, undefined, link);
+ }
+ });
+ LinkManager.Instance.userLinkDBs.forEach(linkDb => Doc.FindReferences(linkDb, references, undefined));
+ const filtered = Array.from(references);
+
+ const newCacheUpdate = filtered.map(doc => doc[Id]).join(';');
+ if (newCacheUpdate === cacheDocumentIds) return;
+ cacheDocumentIds = newCacheUpdate;
+
+ // print out cached docs
+ Doc.MyDockedBtns.linearView_IsOpen && console.log('Set cached docs = ');
+ const isFiltered = filtered.filter(doc => !Doc.IsSystem(doc));
+ const strings = isFiltered.map(doc => StrCast(doc.title) + ' ' + (Doc.IsDataProto(doc) ? '(data)' : '(embedding)'));
+ Doc.MyDockedBtns.linearView_IsOpen && strings.sort().forEach((str, i) => console.log(i.toString() + ' ' + str));
+
+ rp.post(ClientUtils.prepend('/setCacheDocumentIds'), {
+ body: {
+ cacheDocumentIds,
+ },
+ json: true,
+ });
+}
+
ScriptingGlobals.add(
+ // eslint-disable-next-line prefer-arrow-callback
function links(doc: any) {
return new List(LinkManager.Links(doc));
},
diff --git a/src/client/util/PingManager.ts b/src/client/util/PingManager.ts
index 7638e2ce0..255e9cee0 100644
--- a/src/client/util/PingManager.ts
+++ b/src/client/util/PingManager.ts
@@ -1,8 +1,10 @@
import { action, makeObservable, observable, runInAction } from 'mobx';
import { Networking } from '../Network';
-import { CurrentUserUtils } from './CurrentUserUtils';
+import { SnappingManager } from './SnappingManager';
+
export class PingManager {
// create static instance and getter for global use
+ // eslint-disable-next-line no-use-before-define
@observable static _instance: PingManager;
@observable IsBeating = true;
static get Instance(): PingManager {
@@ -29,7 +31,9 @@ export class PingManager {
sendPing = async (): Promise<void> => {
try {
const res = await Networking.PostToServer('/ping', { date: new Date() });
- runInAction(() => (CurrentUserUtils.ServerVersion = res.message));
+ runInAction(() => {
+ SnappingManager.SetServerVersion(res.message);
+ });
!this.IsBeating && this.setIsBeating(true);
} catch {
if (this.IsBeating) {
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index f96d8a5df..a07ad2047 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -2,24 +2,17 @@ import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { MainViewModal } from '../views/MainViewModal';
-import { SettingsManager } from './SettingsManager';
-import { Doc } from '../../fields/Doc';
-import { StrCast } from '../../fields/Types';
+import { SnappingManager } from './SnappingManager';
@observer
export class RTFMarkup extends React.Component<{}> {
+ // eslint-disable-next-line no-use-before-define
static Instance: RTFMarkup;
@observable private isOpen = false; // whether the SharingManager modal is open or not
- // private get linkVisible() {
- // return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false;
- // }
-
- @action
- public open = () => (this.isOpen = true);
-
- @action
- public close = () => (this.isOpen = false);
+ public setOpen = action((status: boolean) => {
+ this.isOpen = status;
+ });
constructor(props: {}) {
super(props);
@@ -27,17 +20,15 @@ export class RTFMarkup extends React.Component<{}> {
RTFMarkup.Instance = this;
}
- @observable _stats: { [key: string]: any } | undefined = undefined;
-
/**
* @returns the main interface of the SharingManager.
*/
@computed get cheatSheet() {
return (
- <div style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor, textAlign: 'initial', height: '100%' }}>
+ <div style={{ background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, textAlign: 'initial', height: '100%' }}>
<p>
- <b style={{ fontSize: 'larger' }}>{`wiki:phrase`}</b>
- {` display wikipedia page for entered text (terminate with carriage return)`}
+ <b style={{ fontSize: 'larger' }}>(( any text ))</b>
+ {` submit text to Chat GPT to have results appended afterward`}
</p>
<p>
<b style={{ fontSize: 'larger' }}>{`#tag `}</b>
@@ -48,10 +39,6 @@ export class RTFMarkup extends React.Component<{}> {
{` set heading style based on number of '#'s between 1 and 6`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`#tag `}</b>
- {` add hashtag metadata to document. e.g, #idea`}
- </p>
- <p>
<b style={{ fontSize: 'larger' }}>{`>> `}</b>
{` add a sidebar text document inline`}
</p>
@@ -61,7 +48,7 @@ export class RTFMarkup extends React.Component<{}> {
</p>
<p>
<b style={{ fontSize: 'larger' }}>{`cmd-f `}</b>
- {` collapse to an inline footnote)`}
+ {` collapse to an inline footnote`}
</p>
<p>
<b style={{ fontSize: 'larger' }}>{`cmd-e `}</b>
@@ -116,20 +103,24 @@ export class RTFMarkup extends React.Component<{}> {
{` start a block of text that begins with a hanging indent`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`[:doctitle]] `}</b>
+ <b style={{ fontSize: 'larger' }}>@(wiki:phrase)</b>
+ {` display wikipedia page for entered text (terminate with carriage return)`}
+ </p>
+ <p>
+ <b style={{ fontSize: 'larger' }}>{`@(doctitle) `}</b>
{` hyperlink to document specified by it’s title`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`[[fieldname]] `}</b>
- {` display value of fieldname`}
+ <b style={{ fontSize: 'larger' }}>{`[@(doctitle.)fieldname] `}</b>
+ {` display value of fieldname of text document (unless (doctitle.) is used to indicate another document by it's title)`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`[[fieldname=value]] `}</b>
- {` assign value to fieldname of document and display it`}
+ <b style={{ fontSize: 'larger' }}>{`[@fieldname:value] `}</b>
+ {` assign value to fieldname to data document and display it (if '=' is used instead of ':' the value is set on the layout Doc. if value is wrapped in (()) then it will be sent to ChatGPT and the response will replace the value)`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`[[fieldname:doctitle]] `}</b>
- {` show value of fieldname from doc specified by it’s title`}
+ <b style={{ fontSize: 'larger' }}>{`[@fieldname:=expression] `}</b>
+ {` assign a computed expression to fieldname to data document and display it (if '=:=' is used instead of ':=' the expression is set on the layout Doc. if value is wrapped in (()) then it will be sent to ChatGPT and the prompt/response will replace the value)`}
</p>
</div>
);
@@ -138,11 +129,11 @@ export class RTFMarkup extends React.Component<{}> {
render() {
return (
<MainViewModal
- dialogueBoxStyle={{ backgroundColor: SettingsManager.userBackgroundColor, color: SettingsManager.userColor, padding: '16px' }}
+ dialogueBoxStyle={{ backgroundColor: SnappingManager.userBackgroundColor, alignContent: 'normal', color: SnappingManager.userColor, padding: '16px' }}
contents={this.cheatSheet}
isDisplayed={this.isOpen}
- interactive={true}
- closeOnExternalClick={this.close}
+ interactive
+ closeOnExternalClick={() => this.setOpen(false)}
/>
);
}
diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts
index b881f18b4..c5afe549c 100644
--- a/src/client/util/ReplayMovements.ts
+++ b/src/client/util/ReplayMovements.ts
@@ -1,19 +1,21 @@
import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { Doc, IdToDoc } from '../../fields/Doc';
-import { CollectionDockingView } from '../views/collections/CollectionDockingView';
import { CollectionFreeFormView } from '../views/collections/collectionFreeForm';
-import { OpenWhereMod } from '../views/nodes/DocumentView';
-import { VideoBox } from '../views/nodes/VideoBox';
-import { DocumentManager } from './DocumentManager';
+import { DocumentView } from '../views/nodes/DocumentView';
+import { OpenWhereMod } from '../views/nodes/OpenWhere';
+import { SnappingManager } from './SnappingManager';
import { Movement, Presentation } from './TrackMovements';
+import { ViewBoxInterface } from '../views/ViewBoxInterface';
+import { StrCast } from '../../fields/Types';
export class ReplayMovements {
private timers: NodeJS.Timeout[] | null;
private videoBoxDisposeFunc: IReactionDisposer | null;
- private videoBox: VideoBox | null;
+ private videoBox: ViewBoxInterface<any> | null;
private isPlaying: boolean;
// create static instance and getter for global use
+ // eslint-disable-next-line no-use-before-define
@observable static _instance: ReplayMovements;
static get Instance(): ReplayMovements {
return ReplayMovements._instance;
@@ -28,6 +30,22 @@ export class ReplayMovements {
this.videoBoxDisposeFunc = null;
this.videoBox = null;
this.isPlaying = false;
+
+ reaction(
+ () => SnappingManager.UserPanned,
+ () => {
+ if (Doc.UserDoc()?.presentationMode === 'watching') this.pauseFromInteraction();
+ }
+ );
+ reaction(
+ () => DocumentView.Selected().slice(),
+ selviews => {
+ const selVideo = selviews.find(dv => dv.ComponentView?.playFrom);
+ if (selVideo?.ComponentView?.Play) {
+ this.setVideoBox(selVideo.ComponentView);
+ } else this.removeVideoBox();
+ }
+ );
}
// pausing movements will dispose all timers that are planned to replay the movements
@@ -44,18 +62,16 @@ export class ReplayMovements {
this.timers?.map(timer => clearTimeout(timer));
};
- setVideoBox = async (videoBox: VideoBox) => {
- // console.info('setVideoBox', videoBox);
+ setVideoBox = async (videoBox: ViewBoxInterface<any>) => {
if (this.videoBox !== null) {
console.warn('setVideoBox on already videoBox');
}
- if (this.videoBoxDisposeFunc !== null) {
- console.warn('setVideoBox on already videoBox dispose func');
- this.videoBoxDisposeFunc();
- }
+ this.videoBoxDisposeFunc?.();
+
+ const data = StrCast(videoBox.dataDoc?.[videoBox.fieldKey + '_presentation']);
+ const presentation = data ? JSON.parse(data) : null;
- const { presentation } = videoBox;
- if (presentation == null) {
+ if (presentation === null) {
console.warn('setVideoBox on null videoBox presentation');
return;
}
@@ -63,18 +79,14 @@ export class ReplayMovements {
this.loadPresentation(presentation);
this.videoBoxDisposeFunc = reaction(
- () => ({ playing: videoBox._playing, timeViewed: videoBox.player?.currentTime || 0 }),
+ () => ({ playing: videoBox.IsPlaying?.(), timeViewed: videoBox.PlayerTime?.() || 0 }),
({ playing, timeViewed }) => (playing ? this.playMovements(presentation, timeViewed) : this.pauseMovements())
);
this.videoBox = videoBox;
};
removeVideoBox = () => {
- if (this.videoBoxDisposeFunc == null) {
- console.warn('removeVideoBox on null videoBox');
- return;
- }
- this.videoBoxDisposeFunc();
+ this.videoBoxDisposeFunc?.();
this.videoBox = null;
this.videoBoxDisposeFunc = null;
@@ -82,7 +94,7 @@ export class ReplayMovements {
// should be called from interacting with the screen
pauseFromInteraction = () => {
- this.videoBox?.Pause();
+ this.videoBox?.Pause?.();
this.pauseMovements();
};
@@ -90,7 +102,7 @@ export class ReplayMovements {
loadPresentation = (presentation: Presentation) => {
const { movements } = presentation;
if (movements === null) {
- throw '[recordingApi.ts] followMovements() failed: no presentation data';
+ throw new Error('[recordingApi.ts] followMovements() failed: no presentation data');
}
movements.forEach((movement, i) => {
@@ -105,10 +117,8 @@ export class ReplayMovements {
// returns undefined if the docView isn't open on the screen
getCollectionFFView = (doc: Doc) => {
- const isInView = DocumentManager.Instance.getDocumentView(doc);
- if (isInView) {
- return isInView.ComponentView as CollectionFreeFormView;
- }
+ const isInView = DocumentView.getDocumentView(doc);
+ return isInView?.ComponentView as CollectionFreeFormView;
};
// will open the doc in a tab then return the CollectionFFView that holds it
@@ -118,8 +128,8 @@ export class ReplayMovements {
return undefined;
}
// console.log('openTab', docId, doc);
- CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
- const docView = DocumentManager.Instance.getDocumentView(doc);
+ DocumentView.addSplit(doc, OpenWhereMod.right);
+ const docView = DocumentView.getDocumentView(doc);
// BUG - this returns undefined if the doc is already open
return docView?.ComponentView as CollectionFreeFormView;
};
@@ -136,9 +146,9 @@ export class ReplayMovements {
if (movements === null) return new Map();
// generate a set of all unique docIds
const docIdtoFirstMove = new Map<Doc, Movement>();
- for (const move of movements) {
+ movements.forEach(move => {
if (!docIdtoFirstMove.has(move.doc)) docIdtoFirstMove.set(move.doc, move);
- }
+ });
return docIdtoFirstMove;
};
@@ -151,10 +161,10 @@ export class ReplayMovements {
// console.info('playMovements', presentation, timeViewed, docIdtoDoc);
if (presentation.movements === null || presentation.movements.length === 0) {
- //|| this.playFFView === null) {
- return new Error('[recordingApi.ts] followMovements() failed: no presentation data');
+ // || this.playFFView === null) {
+ return '[recordingApi.ts] followMovements() failed: no presentation data';
}
- if (this.isPlaying) return;
+ if (this.isPlaying) return undefined;
this.isPlaying = true;
Doc.UserDoc().presentationMode = 'watching';
@@ -170,10 +180,10 @@ export class ReplayMovements {
// for the open tabs, set it to the first move
const docIdtoFirstMove = this.getFirstMovements(filteredMovements);
- for (const [doc, firstMove] of docIdtoFirstMove) {
+ Array.from(docIdtoFirstMove).forEach(([doc, firstMove]) => {
const colFFView = this.getCollectionFFView(doc);
if (colFFView) this.zoomAndPan(firstMove, colFFView);
- }
+ });
};
handleFirstMovements();
@@ -197,5 +207,6 @@ export class ReplayMovements {
}
}, timeDiff);
});
+ return undefined;
};
}
diff --git a/src/client/util/ScriptManager.ts b/src/client/util/ScriptManager.ts
index 87509f2ea..9158f6c0b 100644
--- a/src/client/util/ScriptManager.ts
+++ b/src/client/util/ScriptManager.ts
@@ -7,8 +7,10 @@ import { ScriptingGlobals } from './ScriptingGlobals';
export class ScriptManager {
static _initialized = false;
+ // eslint-disable-next-line no-use-before-define
private static _instance: ScriptManager;
public static get Instance(): ScriptManager {
+ // eslint-disable-next-line no-return-assign
return this._instance || (this._instance = new this());
}
private constructor() {
@@ -58,14 +60,16 @@ export class ScriptManager {
const params = Cast(scriptDoc['data-params'], listSpec('string'), []);
const paramNames = params.reduce((o: string, p: string) => {
+ let out = o;
if (params.indexOf(p) === params.length - 1) {
- o = o + p.split(':')[0].trim();
+ out += p.split(':')[0].trim();
} else {
- o = o + p.split(':')[0].trim() + ',';
+ out += p.split(':')[0].trim() + ',';
}
- return o;
+ return out;
}, '' as string);
+ // eslint-disable-next-line no-new-func
const f = new Function(paramNames, StrCast(scriptDoc.script));
Object.defineProperty(f, 'name', { value: StrCast(scriptDoc.name), writable: false });
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index f5e162d16..6948469cc 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -1,15 +1,17 @@
+/* eslint-disable import/no-unresolved */
+/* eslint-disable import/no-webpack-loader-syntax */
// export const ts = (window as any).ts;
// // @ts-ignore
// import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts'
-// // @ts-ignore
// import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts'
-// @ts-ignore
+// eslint-disable-next-line node/no-unpublished-import
import * as typescriptlib from '!!raw-loader!./type_decls.d';
import * as ts from 'typescript';
-import { Doc, Field } from '../../fields/Doc';
+import { Doc, FieldType } from '../../fields/Doc';
import { RefField } from '../../fields/RefField';
import { ScriptField } from '../../fields/ScriptField';
-import { scriptingGlobals, ScriptingGlobals } from './ScriptingGlobals';
+import { ScriptingGlobals, scriptingGlobals } from './ScriptingGlobals';
+
export { ts };
export interface ScriptSuccess {
@@ -30,6 +32,7 @@ export type ScriptParam = { [name: string]: string };
export interface CompiledScript {
readonly compiled: true;
readonly originalScript: string;
+ // eslint-disable-next-line no-use-before-define
readonly options: Readonly<ScriptOptions>;
run(args?: { [name: string]: any }, onError?: (res: any) => void, errorVal?: any): ScriptResult;
}
@@ -47,6 +50,7 @@ export function isCompileError(toBeDetermined: CompileResult): toBeDetermined is
return false;
}
+// eslint-disable-next-line no-use-before-define
function Run(script: string | undefined, customParams: string[], diagnostics: any[], originalScript: string, options: ScriptOptions): CompileResult {
const errors = diagnostics.filter(diag => diag.category === ts.DiagnosticCategory.Error);
if ((options.typecheck !== false && errors.length) || !script) {
@@ -60,6 +64,7 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
// let params: any[] = [Docs, ...fieldTypes];
const compiledFunction = (() => {
try {
+ // eslint-disable-next-line no-new-func
return new Function(...paramNames, `return ${script}`);
} catch (e) {
console.log(e);
@@ -68,35 +73,27 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
})();
if (!compiledFunction) return { compiled: false, errors };
const { capturedVariables = {} } = options;
+ // eslint-disable-next-line default-param-last
const run = (args: { [name: string]: any } = {}, onError?: (e: any) => void, errorVal?: any): ScriptResult => {
const argsArray: any[] = [];
+ // eslint-disable-next-line no-restricted-syntax
for (const name of customParams) {
- if (name === 'this') {
- continue;
- }
- if (name in args) {
- argsArray.push(args[name]);
- } else {
- argsArray.push(capturedVariables[name]);
+ if (name !== 'this') {
+ argsArray.push(name in args ? args[name] : capturedVariables[name]);
}
}
const thisParam = args.this || capturedVariables.this;
- let batch: { end(): void } | undefined = undefined;
+ let batch: { end(): void } | undefined;
try {
if (!options.editable) {
batch = Doc.MakeReadOnly();
}
const result = compiledFunction.apply(thisParam, params).apply(thisParam, argsArray);
- if (batch) {
- batch.end();
- }
-
+ batch?.end();
return { success: true, result };
} catch (error) {
- if (batch) {
- batch.end();
- }
+ batch?.end();
onError?.(script + ' ' + error);
return { success: false, error, result: errorVal };
}
@@ -114,7 +111,7 @@ class ScriptingCompilerHost {
files: File[] = [];
// getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined): ts.SourceFile | undefined {
- getSourceFile(fileName: string, languageVersion: any, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined): any | undefined {
+ getSourceFile(fileName: string, languageVersion: any /* , onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined */): any | undefined {
const contents = this.readFile(fileName);
if (contents !== undefined) {
return ts.createSourceFile(fileName, contents, languageVersion, true);
@@ -123,11 +120,11 @@ class ScriptingCompilerHost {
}
// getDefaultLibFileName(options: ts.CompilerOptions): string {
- getDefaultLibFileName(options: any): string {
+ getDefaultLibFileName(/* options: any */): string {
return 'node_modules/typescript/lib/lib.d.ts'; // No idea what this means...
}
writeFile(fileName: string, content: string) {
- const file = this.files.find(file => file.fileName === fileName);
+ const file = this.files.find(f => f.fileName === fileName);
if (file) {
file.content = content;
} else {
@@ -150,7 +147,7 @@ class ScriptingCompilerHost {
return this.files.some(file => file.fileName === fileName);
}
readFile(fileName: string): string | undefined {
- const file = this.files.find(file => file.fileName === fileName);
+ const file = this.files.find(f => f.fileName === fileName);
if (file) {
return file.content;
}
@@ -162,7 +159,7 @@ export type Traverser = (node: ts.Node, indentation: string) => boolean | void;
export type TraverserParam = Traverser | { onEnter: Traverser; onLeave: Traverser };
export type Transformer = {
transformer: ts.TransformerFactory<ts.Node>;
- getVars?: () => { [name: string]: Field };
+ getVars?: () => { [name: string]: FieldType };
};
export interface ScriptOptions {
requiredType?: string; // does function required a typed return value
@@ -198,7 +195,6 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
if (found) return found as CompiledScript;
const { requiredType = '', addReturn = false, params = {}, capturedVariables = {}, typecheck = true } = options;
if (options.params && !options.params.this) options.params.this = Doc.name;
- if (options.params && !options.params.self) options.params.self = Doc.name;
if (options.globals) {
ScriptingGlobals.setScriptingGlobals(options.globals);
}
@@ -215,12 +211,13 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
const newCaptures = options.transformer.getVars?.();
if (Object.keys(newCaptures ?? {}).length) {
// tslint:disable-next-line: prefer-object-spread
- //options.capturedVariables = Object.assign(capturedVariables, newCaptures!) as any;
+ // options.capturedVariables = Object.assign(capturedVariables, newCaptures!) as any;
- const transformed = result.transformed;
+ const { transformed } = result;
const printer = ts.createPrinter({
newLine: ts.NewLineKind.LineFeed,
});
+ // eslint-disable-next-line no-param-reassign
script = printer.printFile(transformed[0].getSourceFile());
}
result.dispose();
@@ -229,19 +226,23 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
if ('this' in params || 'this' in capturedVariables) {
paramNames.push('this');
}
+ // eslint-disable-next-line no-restricted-syntax
for (const key in params) {
- if (key === 'this') continue;
- paramNames.push(key);
+ if (key !== 'this') {
+ paramNames.push(key);
+ }
}
const paramList = paramNames.map(key => {
const val = params[key];
return `${key}: ${val}`;
});
+ // eslint-disable-next-line no-restricted-syntax
for (const key in capturedVariables) {
- if (key === 'this') continue;
- const val = capturedVariables[key];
- paramNames.push(key);
- paramList.push(`${key}: ${typeof val === 'object' ? Object.getPrototypeOf(val).constructor.name : typeof val}`);
+ if (key !== 'this') {
+ const val = capturedVariables[key];
+ paramNames.push(key);
+ paramList.push(`${key}: ${typeof val === 'object' ? Object.getPrototypeOf(val).constructor.name : typeof val}`);
+ }
}
const paramString = paramList.join(', ');
const body = addReturn && !script.startsWith('{ return') ? `return ${script};` : script;
@@ -255,7 +256,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
const outputText = host.readFile('file.js');
const diagnostics = ts.getPreEmitDiagnostics(program).concat(testResult.diagnostics);
-
+ if (script.startsWith('@')) options.typecheck = true; // need the compilation to fail so that the script will return itself as a string (instead of nothing)
const result = Run(outputText, paramNames, diagnostics, script, options);
if (options.globals) {
@@ -264,8 +265,3 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
!signature.includes('XXX') && ScriptField._scriptFieldCache.set(script + ':' + signature, result as CompiledScript);
return result;
}
-
-ScriptingGlobals.add(CompileScript);
-ScriptingGlobals.add(function runScript(doc: Doc, script: ScriptField) {
- return script?.script.run({ this: doc }).result;
-});
diff --git a/src/client/util/ScriptingGlobals.ts b/src/client/util/ScriptingGlobals.ts
index f151acd81..ac524394a 100644
--- a/src/client/util/ScriptingGlobals.ts
+++ b/src/client/util/ScriptingGlobals.ts
@@ -1,8 +1,18 @@
+import ts from 'typescript';
-import * as ts from "typescript";
export { ts };
+const _scriptingGlobals: { [name: string]: any } = {};
+const _scriptingDescriptions: { [name: string]: any } = {};
+const _scriptingParams: { [name: string]: any } = {};
+// eslint-disable-next-line import/no-mutable-exports
+export let scriptingGlobals: { [name: string]: any } = _scriptingGlobals;
export namespace ScriptingGlobals {
+ export function getGlobals() { return Object.keys(_scriptingGlobals); } // prettier-ignore
+ export function getGlobalObj() { return _scriptingGlobals; } // prettier-ignore
+ export function getDescriptions() { return _scriptingDescriptions; } // prettier-ignore
+ export function getParameters() { return _scriptingParams; } // prettier-ignore
+
export function add(global: { name: string }): void;
export function add(name: string, global: any): void;
export function add(global: { name: string }, decription?: string, params?: string): void;
@@ -11,7 +21,7 @@ export namespace ScriptingGlobals {
let obj: any;
if (second !== undefined) {
- if (typeof first === "string") {
+ if (typeof first === 'string') {
n = first;
obj = second;
} else {
@@ -22,18 +32,21 @@ export namespace ScriptingGlobals {
_scriptingParams[n] = third;
}
}
- } else if (first && typeof first.name === "string") {
+ } else if (first && typeof first.name === 'string') {
n = first.name;
obj = first;
} else {
- throw new Error("Must either register an object with a name, or give a name and an object");
+ throw new Error('Must either register an object with a name, or give a name and an object');
}
- if (n === undefined || n === "undefined") {
+ if (n === undefined || n === 'undefined') {
return false;
- } else if (_scriptingGlobals.hasOwnProperty(n)) {
+ }
+ // eslint-disable-next-line no-prototype-builtins
+ if (_scriptingGlobals.hasOwnProperty(n)) {
throw new Error(`Global with name ${n} is already registered, choose another name`);
}
_scriptingGlobals[n] = obj;
+ return true;
}
export function makeMutableGlobalsCopy(globals?: { [name: string]: any }) {
return { ..._scriptingGlobals, ...(globals || {}) };
@@ -57,25 +70,16 @@ export namespace ScriptingGlobals {
return false;
}
- export function resetScriptingGlobals() { scriptingGlobals = _scriptingGlobals; }
+ export function resetScriptingGlobals() {
+ scriptingGlobals = _scriptingGlobals;
+ }
// const types = Object.keys(ts.SyntaxKind).map(kind => ts.SyntaxKind[kind]);
- export function printNodeType(node: any, indentation = "") { console.log(indentation + ts.SyntaxKind[node.kind]); }
-
- export function getGlobals() { return Object.keys(_scriptingGlobals); }
-
- export function getGlobalObj() { return _scriptingGlobals; }
-
- export function getDescriptions() { return _scriptingDescriptions; }
-
- export function getParameters() { return _scriptingParams; }
+ export function printNodeType(node: any, indentation = '') {
+ console.log(indentation + ts.SyntaxKind[node.kind]);
+ }
}
-export function scriptingGlobal(constructor: { new(...args: any[]): any }) {
+export function scriptingGlobal(constructor: { new (...args: any[]): any }) {
ScriptingGlobals.add(constructor);
}
-
-const _scriptingGlobals: { [name: string]: any } = {};
-export let scriptingGlobals: { [name: string]: any } = _scriptingGlobals;
-const _scriptingDescriptions: { [name: string]: any } = {};
-const _scriptingParams: { [name: string]: any } = {}; \ No newline at end of file
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index fff2737b6..609fedfa9 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -1,5 +1,5 @@
import { ObservableMap } from 'mobx';
-import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
+import { Doc, DocListCast, Field, FieldType, Opt } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { StrCast } from '../../fields/Types';
import { DocumentType } from '../documents/DocumentTypes';
@@ -8,16 +8,16 @@ import { DocOptions, FInfo } from '../documents/Documents';
export namespace SearchUtil {
export type HighlightingResult = { [id: string]: { [key: string]: string[] } };
- export function SearchCollection(collectionDoc: Opt<Doc>, query: string, matchKeyNames: boolean, onlyKeys?: string[]) {
+ export function SearchCollection(collectionDoc: Opt<Doc>, queryIn: string, matchKeyNames: boolean, onlyKeys?: string[]) {
const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.CONFIG, DocumentType.KVP, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
const blockedKeys = matchKeyNames
? []
: Object.entries(DocOptions)
- .filter(([key, info]: [string, FInfo]) => !info?.searchable())
+ .filter(([, info]: [string, FInfo]) => !info?.searchable())
.map(([key]) => key);
- const exact = query.startsWith('=');
- query = query.toLowerCase().split('=').lastElement();
+ const exact = queryIn.startsWith('=');
+ const query = queryIn.toLowerCase().split('=').lastElement();
const results = new ObservableMap<Doc, string[]>();
if (collectionDoc) {
@@ -30,7 +30,7 @@ export namespace SearchUtil {
(onlyKeys ?? SearchUtil.documentKeys(doc)).forEach(
key =>
(val => (exact ? val === query.toLowerCase() : val.includes(query.toLowerCase())))(
- matchKeyNames ? key : Field.toString(doc[key] as Field))
+ matchKeyNames ? key : Field.toString(doc[key] as FieldType))
&& hlights.add(key)
); // prettier-ignore
blockedKeys.forEach(key => hlights.delete(key));
@@ -51,7 +51,11 @@ export namespace SearchUtil {
*/
export function documentKeys(doc: Doc) {
const keys: { [key: string]: boolean } = {};
- Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => (keys[key] = false)));
+ Doc.GetAllPrototypes(doc).map(proto =>
+ Object.keys(proto).forEach(key => {
+ keys[key] = false;
+ })
+ );
return Array.from(Object.keys(keys));
}
@@ -62,16 +66,18 @@ export namespace SearchUtil {
* This method iterates through an array of docs and all docs within those docs, calling
* the function func on each doc.
*/
- export function foreachRecursiveDoc(docs: Doc[], func: (depth: number, doc: Doc) => void) {
+ export function foreachRecursiveDoc(docsIn: Doc[], func: (depth: number, doc: Doc) => void) {
+ let docs = docsIn;
let newarray: Doc[] = [];
- var depth = 0;
+ let depth = 0;
const visited: Doc[] = [];
while (docs.length > 0) {
newarray = [];
+ // eslint-disable-next-line no-loop-func
docs.filter(d => d && !visited.includes(d)).forEach(d => {
visited.push(d);
const fieldKey = Doc.LayoutFieldKey(d);
- const annos = !Field.toString(Doc.LayoutField(d) as Field).includes('CollectionView');
+ const annos = !Field.toString(Doc.LayoutField(d) as FieldType).includes('CollectionView');
const data = d[annos ? fieldKey + '_annotations' : fieldKey];
data && newarray.push(...DocListCast(data));
const sidebar = d[fieldKey + '_sidebar'];
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 36b926053..0b942116c 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,6 +1,5 @@
import { action, makeObservable, observable, runInAction } from 'mobx';
import { Doc, Opt } from '../../fields/Doc';
-import { DocViews } from '../../fields/DocSymbols';
import { List } from '../../fields/List';
import { listSpec } from '../../fields/Schema';
import { Cast, DocCast } from '../../fields/Types';
@@ -11,6 +10,7 @@ import { ScriptingGlobals } from './ScriptingGlobals';
import { UndoManager } from './UndoManager';
export class SelectionManager {
+ // eslint-disable-next-line no-use-before-define
private static _manager: SelectionManager;
private static get Instance() {
return SelectionManager._manager ?? new SelectionManager();
@@ -23,6 +23,13 @@ export class SelectionManager {
private constructor() {
SelectionManager._manager = this;
makeObservable(this);
+ DocumentView.DeselectAll = SelectionManager.DeselectAll;
+ DocumentView.DeselectView = SelectionManager.DeselectView;
+ DocumentView.SelectView = SelectionManager.SelectView;
+ DocumentView.SelectedDocs = SelectionManager.Docs;
+ DocumentView.Selected = SelectionManager.Views;
+ DocumentView.SelectSchemaDoc = SelectionManager.SelectSchemaViewDoc;
+ DocumentView.SelectedSchemaDoc = () => this.SelectedSchemaDocument;
}
@action
@@ -53,35 +60,41 @@ export class SelectionManager {
public static DeselectAll = (except?: Doc): void => {
const found = this.Instance.SelectedViews.find(dv => dv.Document === except);
runInAction(() => {
- LinkManager.Instance.currentLink = undefined;
- LinkManager.Instance.currentLinkAnchor = undefined;
+ if (LinkManager.Instance) {
+ LinkManager.Instance.currentLink = undefined;
+ LinkManager.Instance.currentLinkAnchor = undefined;
+ }
this.Instance.SelectedSchemaDocument = undefined;
});
this.Instance.SelectedViews.forEach(dv => {
dv.IsSelected = false;
dv._props.whenChildContentsActiveChanged(false);
});
- runInAction(() => (this.Instance.SelectedViews.length = 0));
+ runInAction(() => {
+ this.Instance.SelectedViews.length = 0;
+ });
if (found) this.SelectView(found, false);
};
- public static IsSelected = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []).some(dv => dv?.IsSelected);
- public static get Views() { return this.Instance.SelectedViews; } // prettier-ignore
- public static get SelectedSchemaDoc() { return this.Instance.SelectedSchemaDocument; } // prettier-ignore
- public static get Docs() { return this.Instance.SelectedViews.map(dv => dv.Document).filter(doc => doc?._type_collection !== CollectionViewType.Docking); } // prettier-ignore
+ public static Views() { return SelectionManager.Instance.SelectedViews; } // prettier-ignore
+ public static get SelectedSchemaDoc() { return SelectionManager.Instance.SelectedSchemaDocument; } // prettier-ignore
+ public static Docs() { return SelectionManager.Instance.SelectedViews.map(dv => dv.Document).filter(doc => doc?._type_collection !== CollectionViewType.Docking); } // prettier-ignore
}
-ScriptingGlobals.add(function SelectionManager_selectedDocType(type: string, expertMode: boolean, checkContext?: boolean) {
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function SelectedDocType(type: string, expertMode: boolean, checkContext?: boolean) {
if (Doc.noviceMode && expertMode) return false;
if (type === 'tab') {
- return SelectionManager.Views.lastElement()?._props.renderDepth === 0;
+ return DocumentView.Selected().lastElement()?._props.renderDepth === 0;
}
- let selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(SelectionManager.SelectedSchemaDoc ?? SelectionManager.Docs.lastElement());
+ const selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(DocumentView.SelectedSchemaDoc() ?? SelectionManager.Docs().lastElement());
return selected?.type === type || selected?.type_collection === type || !type;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function deselectAll() {
SelectionManager.DeselectAll();
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function undo() {
SelectionManager.DeselectAll();
return UndoManager.Undo();
@@ -89,20 +102,20 @@ ScriptingGlobals.add(function undo() {
export function ShowUndoStack() {
SelectionManager.DeselectAll();
- var buffer = '';
+ let buffer = '';
UndoManager.undoStack.forEach((batch, i) => {
buffer += 'Batch => ' + UndoManager.undoStackNames[i] + '\n';
- ///batch.forEach(undo => (buffer += ' ' + undo.prop + '\n'));
+ // /batch.forEach(undo => (buffer += ' ' + undo.prop + '\n'));
});
alert(buffer);
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function redo() {
SelectionManager.DeselectAll();
return UndoManager.Redo();
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
- const docs = SelectionManager.Views.map(dv => dv.Document).filter(
- d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.KVP && (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null))
- );
+ const docs = SelectionManager.Docs().filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.KVP && (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null)));
return docs.length ? new List(docs) : prevValue;
});
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index 8daa69890..d9d22437c 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -1,5 +1,5 @@
import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema } from 'serializr';
-import { Field } from '../../fields/Doc';
+// import { Field } from '../../fields/Doc';
let serializing = 0;
export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any, newValue: any) {
@@ -7,12 +7,16 @@ export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any,
cb(err, newValue);
serializing--;
}
+
+const serializationTypes: { [name: string]: { ctor: { new (): any }; afterDeserialize?: (obj: any) => void | Promise<any> } } = {};
+const reverseMap: { [ctor: string]: string } = {};
+
export namespace SerializationHelper {
export function IsSerializing() {
return serializing > 0;
}
- export function Serialize(obj: Field): any {
+ export function Serialize(obj: any /* Field */): any {
if (obj === undefined || obj === null) {
return null;
}
@@ -24,7 +28,7 @@ export namespace SerializationHelper {
serializing++;
if (!(obj.constructor.name in reverseMap)) {
serializing--;
- throw Error('Error: ' + `type '${obj.constructor.name}' not registered. Make sure you register it using a @Deserializable decorator`);
+ throw Error(`Error: type '${obj.constructor.name}' not registered. Make sure you register it using a @Deserializable decorator`);
}
const json = serialize(obj);
@@ -52,30 +56,29 @@ export namespace SerializationHelper {
}
const type = serializationTypes[obj.__type];
- const value = await new Promise(res => deserialize(type.ctor, obj, (err, result) => res(result)));
+ const value = await new Promise(res => {
+ deserialize(type.ctor, obj, (err, result) => res(result));
+ });
type.afterDeserialize?.(value);
return value;
}
}
-const serializationTypes: { [name: string]: { ctor: { new (): any }; afterDeserialize?: (obj: any) => void | Promise<any> } } = {};
-const reverseMap: { [ctor: string]: string } = {};
-
-export function Deserializable(className: string, afterDeserialize?: (obj: any) => void | Promise<any>, constructorArgs?: [string]): (constructor: { new (...args: any[]): any }) => void {
- function addToMap(className: string, ctor: { new (...args: any[]): any }) {
- const schema = getDefaultModelSchema(ctor) as any;
- if (schema.targetClass !== ctor || constructorArgs) {
- setDefaultModelSchema(ctor, { ...schema, factory: (context: any) => new ctor(...(constructorArgs ?? [])?.map(arg => context.json[arg])) });
+export function Deserializable(classNameForSerializer: string, afterDeserialize?: (obj: any) => void | Promise<any>, constructorArgs?: [string]): (constructor: { new (...args: any[]): any }) => void {
+ function addToMap(className: string, Ctor: { new (...args: any[]): any }) {
+ const schema = getDefaultModelSchema(Ctor) as any;
+ if (schema.targetClass !== Ctor || constructorArgs) {
+ setDefaultModelSchema(Ctor, { ...schema, factory: (context: any) => new Ctor(...(constructorArgs ?? []).map(arg => context.json[arg])) });
}
if (!(className in serializationTypes)) {
- serializationTypes[className] = { ctor, afterDeserialize };
- reverseMap[ctor.name] = className;
+ serializationTypes[className] = { ctor: Ctor, afterDeserialize };
+ reverseMap[Ctor.name] = className;
} else {
throw new Error(`Name ${className} has already been registered as deserializable`);
}
}
- return (ctor: { new (...args: any[]): any }) => addToMap(className, ctor);
+ return (ctor: { new (...args: any[]): any }) => addToMap(classNameForSerializer, ctor);
}
export function autoObject(): PropSchema {
diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx
index c8df9182d..57363663d 100644
--- a/src/client/util/ServerStats.tsx
+++ b/src/client/util/ServerStats.tsx
@@ -1,44 +1,28 @@
-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 { MainViewModal } from '../views/MainViewModal';
import './SharingManager.scss';
import { PingManager } from './PingManager';
-import { StrCast } from '../../fields/Types';
-import { Doc } from '../../fields/Doc';
import { SettingsManager } from './SettingsManager';
@observer
export class ServerStats extends React.Component<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: ServerStats;
@observable private isOpen = false; // whether the SharingManager modal is open or not
+ @observable _stats: { [key: string]: any } | undefined = undefined;
// private get linkVisible() {
- // return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false;
+ // return this.targetDoc ? this.targetDoc['acl_' + PublicKey] !== SharingPermissions.None : false;
// }
- @action
- public open = async () => {
- /**
- * Populates the list of users.
- */
- fetch('/stats').then((res: Response) => res.text().then(action(stats => (this._stats = JSON.parse(stats)))));
-
- this.isOpen = true;
- };
-
- public close = action(() => {
- this.isOpen = false;
- });
-
constructor(props: {}) {
super(props);
makeObservable(this);
ServerStats.Instance = this;
}
- @observable _stats: { [key: string]: any } | undefined = undefined;
-
/**
* @returns the main interface of the SharingManager.
*/
@@ -63,7 +47,28 @@ export class ServerStats extends React.Component<{}> {
);
}
+ // eslint-disable-next-line react/sort-comp
+ public close = action(() => {
+ this.isOpen = false;
+ });
+ public open = async () => {
+ /**
+ * Populates the list of users.
+ */
+ fetch('/stats').then((res: Response) =>
+ res.text().then(
+ action(stats => {
+ this._stats = JSON.parse(stats);
+ })
+ )
+ );
+
+ runInAction(() => {
+ this.isOpen = true;
+ });
+ };
+
render() {
- return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} />;
+ return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive closeOnExternalClick={this.close} />;
}
}
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 682704770..d3c10f9f4 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -1,23 +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 { Button, ColorPicker, Dropdown, DropdownType, EditableText, Group, NumberDropdown, Size, Toggle, ToggleType, Type } from 'browndash-components';
-import { action, computed, makeObservable, observable, runInAction } from 'mobx';
+import { action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { BsGoogle } from 'react-icons/bs';
import { FaFillDrip, FaPalette } from 'react-icons/fa';
-import { Utils, addStyleSheet, addStyleSheetRule } from '../../Utils';
-import { Doc, Opt } from '../../fields/Doc';
+import { ClientUtils, addStyleSheet, addStyleSheetRule } from '../../ClientUtils';
+import { Doc } from '../../fields/Doc';
import { DashVersion } from '../../fields/DocSymbols';
import { BoolCast, Cast, NumCast, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
import { Networking } from '../Network';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
-import { GestureOverlay } from '../views/GestureOverlay';
import { MainViewModal } from '../views/MainViewModal';
-import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
import { GroupManager } from './GroupManager';
import './SettingsManager.scss';
-import { undoBatch } from './UndoManager';
+import { SnappingManager, freeformScrollMode } from './SnappingManager';
+import { undoable } from './UndoManager';
export enum ColorScheme {
Dark = 'Dark',
@@ -27,60 +28,124 @@ export enum ColorScheme {
Cupcake = 'Cupcake',
}
-export enum freeformScrollMode {
- Pan = 'pan',
- Zoom = 'zoom',
-}
-
@observer
export class SettingsManager extends React.Component<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: SettingsManager;
static _settingsStyle = addStyleSheet();
- @observable public isOpen = false;
- @observable private passwordResultText = '';
- @observable private playgroundMode = false;
+ @observable private _passwordResultText = '';
+ @observable private _playgroundMode = false;
+
+ @observable private _curr_password = '';
+ @observable private _new_password = '';
+ @observable private _new_confirm = '';
+ @observable private _activeTab = 'Accounts';
+ @observable private _isOpen = false;
- @observable private curr_password = '';
- @observable private new_password = '';
- @observable private new_confirm = '';
- @observable private _lastPressedSidebarBtn: Opt<Doc> = undefined; // bcz: this is a hack to handle highlighting buttons in the leftpanel menu .. need to find a cleaner approach
- @observable activeTab = 'Accounts';
+ private googleAuthorize = action(() => GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true));
- @observable public propertiesWidth: number = 0;
+ public closeMgr = action(() => {
+ this._isOpen = false;
+ });
+ // eslint-disable-next-line react/no-unused-class-component-methods
+ public openMgr = action(() => {
+ this._isOpen = true;
+ });
+
+ private matchSystem = undoable(() => {
+ if (Doc.UserDoc().userThemeSystem) {
+ if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark);
+ if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light);
+ }
+ }, 'match system theme');
+ private setFreeformScrollMode = undoable((mode: string) => {
+ Doc.UserDoc().freeformScrollMode = mode;
+ }, 'set scroll mode');
+ private selectUserMode = undoable((mode: string) => {
+ Doc.noviceMode = mode === 'Novice';
+ }, 'change user mode');
+ private changeFontFamily = undoable((font: string) => {
+ Doc.UserDoc().fontFamily = font;
+ }, 'change font family');
+ private switchUserBackgroundColor = undoable((color: string) => {
+ Doc.UserDoc().userBackgroundColor = color;
+ addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${color} !important` });
+ }, 'change background color');
+ private switchUserColor = undoable((color: string) => {
+ Doc.UserDoc().userColor = color;
+ }, 'change user color');
+ switchUserVariantColor = undoable((color: string) => {
+ Doc.UserDoc().userVariantColor = color;
+ }, 'change variant color');
+ userThemeSystemToggle = undoable(() => {
+ Doc.UserDoc().userThemeSystem = !Doc.UserDoc().userThemeSystem;
+ this.matchSystem();
+ }, 'change theme color');
+ playgroundModeToggle = undoable(
+ action(() => {
+ this._playgroundMode = !this._playgroundMode;
+ if (this._playgroundMode) {
+ DocServer.Control.makeReadOnly();
+ addStyleSheetRule(SettingsManager._settingsStyle, 'topbar-inner-container', { background: 'red !important' });
+ } else ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Control.makeEditable();
+ }),
+ 'set playgorund mode'
+ );
+ changeColorScheme = undoable(
+ action((scheme: string) => {
+ Doc.UserDoc().userTheme = scheme;
+ switch (scheme) {
+ case ColorScheme.Light:
+ this.switchUserColor('#323232');
+ this.switchUserBackgroundColor('#DFDFDF');
+ this.switchUserVariantColor('#BDDDF5');
+ break;
+ case ColorScheme.Dark:
+ this.switchUserColor('#DFDFDF');
+ this.switchUserBackgroundColor('#323232');
+ this.switchUserVariantColor('#4476F7');
+ break;
+ case ColorScheme.CoolBlue:
+ this.switchUserColor('#ADEAFF');
+ this.switchUserBackgroundColor('#060A15');
+ this.switchUserVariantColor('#3C51FF');
+ break;
+ case ColorScheme.Cupcake:
+ this.switchUserColor('#3BC7FF');
+ this.switchUserBackgroundColor('#fffdf7');
+ this.switchUserVariantColor('#FFD7F3');
+ break;
+ case ColorScheme.Custom:
+ break;
+ default:
+ }
+ }),
+ 'change color scheme'
+ );
constructor(props: {}) {
super(props);
makeObservable(this);
SettingsManager.Instance = this;
this.matchSystem();
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
if (Doc.UserDoc().userThemeSystem) {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark);
if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light);
}
// undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
});
+ reaction(
+ () => [SettingsManager.userBackgroundColor, SettingsManager.userColor, SettingsManager.userVariantColor],
+ ([back, user, variant]) => {
+ SnappingManager.userBackgroundColor = back;
+ SnappingManager.userVariantColor = variant;
+ SnappingManager.userColor = user;
+ },
+ { fireImmediately: true }
+ );
+ SnappingManager.SettingsStyle = SettingsManager._settingsStyle;
}
- matchSystem = () => {
- if (Doc.UserDoc().userThemeSystem) {
- if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark);
- if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light);
- }
- };
-
- public close = action(() => (this.isOpen = false));
- public open = action(() => (this.isOpen = true));
-
- private googleAuthorize = action(() => GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true));
- private changePassword = async () => {
- if (!(this.curr_password && this.new_password && this.new_confirm)) {
- runInAction(() => (this.passwordResultText = "Error: Hey, we're missing some fields!"));
- } else {
- const passwordBundle = { curr_pass: this.curr_password, new_pass: this.new_password, new_confirm: this.new_confirm };
- const { error } = await Networking.PostToServer('/internalResetPassword', passwordBundle);
- runInAction(() => (this.passwordResultText = error ? 'Error: ' + error[0].msg + '...' : 'Password successfully updated!'));
- }
- };
@computed public static get userColor() {
return StrCast(Doc.UserDoc().userColor);
@@ -94,60 +159,6 @@ export class SettingsManager extends React.Component<{}> {
return StrCast(Doc.UserDoc().userBackgroundColor);
}
- public get LastPressedBtn() { return this._lastPressedSidebarBtn; } // prettier-ignore
- public SetLastPressedBtn = (state?:Doc) => runInAction(() => (this._lastPressedSidebarBtn = state)); // prettier-ignore
-
- @undoBatch selectUserMode = action((mode: string) => (Doc.noviceMode = mode === 'Novice'));
- @undoBatch changelayout_showTitle = action((e: React.ChangeEvent) => (Doc.UserDoc().layout_showTitle = (e.currentTarget as any).value ? 'title' : undefined));
- @undoBatch changeFontFamily = action((font: string) => (Doc.UserDoc().fontFamily = font));
- @undoBatch changeFontSize = action((val: number) => (Doc.UserDoc().fontSize = val));
- @undoBatch switchUserBackgroundColor = action((color: string) => {
- Doc.UserDoc().userBackgroundColor = color;
- addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${color} !important` });
- });
- @undoBatch switchUserColor = action((color: string) => (Doc.UserDoc().userColor = color));
- @undoBatch switchUserVariantColor = action((color: string) => (Doc.UserDoc().userVariantColor = color));
- @undoBatch userThemeSystemToggle = action(() => {
- Doc.UserDoc().userThemeSystem = !Doc.UserDoc().userThemeSystem;
- this.matchSystem();
- });
- @undoBatch playgroundModeToggle = action(() => {
- this.playgroundMode = !this.playgroundMode;
- if (this.playgroundMode) {
- DocServer.Control.makeReadOnly();
- addStyleSheetRule(SettingsManager._settingsStyle, 'topbar-inner-container', { background: 'red !important' });
- } else Doc.CurrentUserEmail !== 'guest' && DocServer.Control.makeEditable();
- });
-
- @undoBatch
- changeColorScheme = action((scheme: string) => {
- Doc.UserDoc().userTheme = scheme;
- switch (scheme) {
- case ColorScheme.Light:
- this.switchUserColor('#323232');
- this.switchUserBackgroundColor('#DFDFDF');
- this.switchUserVariantColor('#BDDDF5');
- break;
- case ColorScheme.Dark:
- this.switchUserColor('#DFDFDF');
- this.switchUserBackgroundColor('#323232');
- this.switchUserVariantColor('#4476F7');
- break;
- case ColorScheme.CoolBlue:
- this.switchUserColor('#ADEAFF');
- this.switchUserBackgroundColor('#060A15');
- this.switchUserVariantColor('#3C51FF');
- break;
- case ColorScheme.Cupcake:
- this.switchUserColor('#3BC7FF');
- this.switchUserBackgroundColor('#fffdf7');
- this.switchUserVariantColor('#FFD7F3');
- break;
- case ColorScheme.Custom:
- break;
- }
- });
-
@computed get colorsContent() {
const schemeMap = Array.from(Object.keys(ColorScheme));
const userTheme = StrCast(Doc.UserDoc().userTheme);
@@ -176,7 +187,7 @@ export class SettingsManager extends React.Component<{}> {
{userTheme === ColorScheme.Custom && (
<Group formLabel="Custom Theme">
<ColorPicker
- tooltip={'User Color'} //
+ tooltip="User Color" //
color={SettingsManager.userColor}
type={Type.SEC}
icon={<FaFillDrip />}
@@ -185,7 +196,7 @@ export class SettingsManager extends React.Component<{}> {
setFinalColor={this.switchUserColor}
/>
<ColorPicker
- tooltip={'User Background Color'}
+ tooltip="User Background Color"
color={SettingsManager.userColor}
type={Type.SEC}
icon={<FaPalette />}
@@ -194,7 +205,7 @@ export class SettingsManager extends React.Component<{}> {
setFinalColor={this.switchUserBackgroundColor}
/>
<ColorPicker
- tooltip={'User Variant Color'}
+ tooltip="User Variant Color"
color={SettingsManager.userColor}
type={Type.SEC}
icon={<FaPalette />}
@@ -212,79 +223,84 @@ export class SettingsManager extends React.Component<{}> {
return (
<div className="prefs-content">
<Toggle
- formLabel={'Show document header'}
- formLabelPlacement={'right'}
+ formLabel="Show document header"
+ formLabelPlacement="right"
toggleType={ToggleType.SWITCH}
- onClick={e => (Doc.UserDoc().layout_showTitle = Doc.UserDoc().layout_showTitle ? undefined : 'author_date')}
+ onClick={() => {
+ Doc.UserDoc().layout_showTitle = Doc.UserDoc().layout_showTitle ? undefined : 'author_date';
+ }}
toggleStatus={Doc.UserDoc().layout_showTitle !== undefined}
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
<Toggle
- formLabel={'Show Full Toolbar'}
- formLabelPlacement={'right'}
- toggleType={ToggleType.SWITCH}
- onClick={e => (Doc.UserDoc()['documentLinksButton-fullMenu'] = !Doc.UserDoc()['documentLinksButton-fullMenu'])}
- toggleStatus={BoolCast(Doc.UserDoc()['documentLinksButton-fullMenu'])}
- size={Size.XSMALL}
- color={SettingsManager.userColor}
- />
- <Toggle
- formLabel={'Show Button Labels'}
- formLabelPlacement={'right'}
+ formLabel="Show Full Toolbar"
+ formLabelPlacement="right"
toggleType={ToggleType.SWITCH}
- onClick={e => (FontIconBox.ShowIconLabels = !FontIconBox.ShowIconLabels)}
- toggleStatus={FontIconBox.ShowIconLabels}
+ onClick={() => {
+ Doc.UserDoc().documentLinksButton_fullMenu = !Doc.UserDoc().documentLinksButton_fullMenu;
+ }}
+ toggleStatus={BoolCast(Doc.UserDoc().documentLinksButton_fullMenu)}
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
<Toggle
- formLabel={'Recognize Ink Gestures'}
- formLabelPlacement={'right'}
+ formLabel="Recognize Ink Gestures"
+ formLabelPlacement="right"
toggleType={ToggleType.SWITCH}
- onClick={e => (GestureOverlay.RecognizeGestures = !GestureOverlay.RecognizeGestures)}
- toggleStatus={GestureOverlay.RecognizeGestures}
+ onClick={() => {
+ Doc.UserDoc().recognizeGestures = !Doc.UserDoc().recognizeGestures;
+ }}
+ toggleStatus={BoolCast(Doc.UserDoc().recognizeGestures)}
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
<Toggle
- formLabel={'Hide Labels In Ink Shapes'}
- formLabelPlacement={'right'}
+ formLabel="Hide Labels In Ink Shapes"
+ formLabelPlacement="right"
toggleType={ToggleType.SWITCH}
- onClick={e => (Doc.UserDoc().activeInkHideTextLabels = !Doc.UserDoc().activeInkHideTextLabels)}
+ onClick={() => {
+ Doc.UserDoc().activeInkHideTextLabels = !Doc.UserDoc().activeInkHideTextLabels;
+ }}
toggleStatus={BoolCast(Doc.UserDoc().activeInkHideTextLabels)}
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
<Toggle
- formLabel={'Open Ink Docs in Lightbox'}
- formLabelPlacement={'right'}
+ formLabel="Open Ink Docs in Lightbox"
+ formLabelPlacement="right"
toggleType={ToggleType.SWITCH}
- onClick={e => (Doc.UserDoc().openInkInLightbox = !Doc.UserDoc().openInkInLightbox)}
+ onClick={() => {
+ Doc.UserDoc().openInkInLightbox = !Doc.UserDoc().openInkInLightbox;
+ }}
toggleStatus={BoolCast(Doc.UserDoc().openInkInLightbox)}
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
- <Toggle
- formLabel={'Show Link Lines'}
- formLabelPlacement={'right'}
+ {/* <Toggle
+ formLabel="Show Link Lines"
+ formLabelPlacement="right"
toggleType={ToggleType.SWITCH}
- onClick={e => (Doc.UserDoc().showLinkLines = !Doc.UserDoc().showLinkLines)}
+ onClick={() => {
+ Doc.UserDoc().showLinkLines = !Doc.UserDoc().showLinkLines;
+ }}
toggleStatus={BoolCast(Doc.UserDoc().showLinkLines)}
size={Size.XSMALL}
color={SettingsManager.userColor}
- />
+ /> */}
<Group formLabel="Title Height">
<NumberDropdown
number={NumCast(Doc.UserDoc().headerHeight, 30)}
color={SettingsManager.userColor}
- numberDropdownType={'slider'}
+ numberDropdownType="slider"
min={6}
max={60}
step={2}
type={Type.TERT}
- unit={'px'}
- setNumber={val => console.log('GOT: ' + (Doc.UserDoc().headerHeight = val))}
+ unit="px"
+ setNumber={val => {
+ Doc.UserDoc().headerHeight = val;
+ }}
/>
</Group>
</div>
@@ -308,7 +324,6 @@ export class SettingsManager extends React.Component<{}> {
@computed get textContent() {
const fontFamilies = ['Times New Roman', 'Arial', 'Georgia', 'Comic Sans MS', 'Tahoma', 'Impact', 'Crimson Text', 'Roboto'];
- const fontSizes = ['7px', '8px', '9px', '10px', '12px', '14px', '16px', '18px', '20px', '24px', '32px', '48px', '72px'];
return (
<div className="tab-content appearances-content">
@@ -316,7 +331,7 @@ export class SettingsManager extends React.Component<{}> {
<div className="tab-column-title">Text</div>
<div className="tab-column-content">
{/* <NumberInput/> */}
- <Group formLabel={'Default Font'}>
+ <Group formLabel="Default Font">
<NumberDropdown
color={SettingsManager.userColor}
numberDropdownType="slider"
@@ -325,20 +340,20 @@ export class SettingsManager extends React.Component<{}> {
step={2}
type={Type.PRIM}
number={NumCast(Doc.UserDoc().fontSize, Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')))}
- unit={'px'}
- setNumber={val => (Doc.UserDoc().fontSize = val + 'px')}
+ unit="px"
+ setNumber={val => {
+ Doc.UserDoc().fontSize = val + 'px';
+ }}
/>
<Dropdown
- items={fontFamilies.map(val => {
- return {
- text: val,
- val: val,
- style: {
- fontFamily: val,
- },
- };
- })}
- closeOnSelect={true}
+ items={fontFamilies.map(val => ({
+ text: val,
+ val: val,
+ style: {
+ fontFamily: val,
+ },
+ }))}
+ closeOnSelect
dropdownType={DropdownType.SELECT}
type={Type.TERT}
selectedVal={StrCast(Doc.UserDoc().fontFamily)}
@@ -355,30 +370,15 @@ export class SettingsManager extends React.Component<{}> {
);
}
- @action
- changeVal = (value: string, pass: string) => {
- switch (pass) {
- case 'curr':
- this.curr_password = value;
- break;
- case 'new':
- this.new_password = value;
- break;
- case 'conf':
- this.new_confirm = value;
- break;
- }
- };
-
@computed get passwordContent() {
return (
<div className="password-content">
- <EditableText placeholder="Current password" type={Type.SEC} color={SettingsManager.userColor} val={''} setVal={val => this.changeVal(val as string, 'curr')} fillWidth password />
- <EditableText placeholder="New password" type={Type.SEC} color={SettingsManager.userColor} val={''} setVal={val => this.changeVal(val as string, 'new')} fillWidth password />
- <EditableText placeholder="Confirm new password" type={Type.SEC} color={SettingsManager.userColor} val={''} setVal={val => this.changeVal(val as string, 'conf')} fillWidth password />
- {!this.passwordResultText ? null : <div className={`${this.passwordResultText.startsWith('Error') ? 'error' : 'success'}-text`}>{this.passwordResultText}</div>}
- <Button type={Type.SEC} text={'Forgot Password'} color={SettingsManager.userColor} />
- <Button type={Type.TERT} text={'Submit'} onClick={this.changePassword} color={SettingsManager.userColor} />
+ <EditableText placeholder="Current password" type={Type.SEC} color={SettingsManager.userColor} val="" setVal={val => this.changeVal(val as string, 'curr')} fillWidth password />
+ <EditableText placeholder="New password" type={Type.SEC} color={SettingsManager.userColor} val="" setVal={val => this.changeVal(val as string, 'new')} fillWidth password />
+ <EditableText placeholder="Confirm new password" type={Type.SEC} color={SettingsManager.userColor} val="" setVal={val => this.changeVal(val as string, 'conf')} fillWidth password />
+ {!this._passwordResultText ? null : <div className={`${this._passwordResultText.startsWith('Error') ? 'error' : 'success'}-text`}>{this._passwordResultText}</div>}
+ <Button type={Type.SEC} text="Forgot Password" color={SettingsManager.userColor} />
+ <Button type={Type.TERT} text="Submit" onClick={this.changePassword} color={SettingsManager.userColor} />
</div>
);
}
@@ -386,7 +386,7 @@ export class SettingsManager extends React.Component<{}> {
@computed get accountOthersContent() {
return (
<div className="account-others-content">
- <Button type={Type.TERT} text={'Connect to Google'} iconPlacement="left" icon={<BsGoogle />} onClick={() => this.googleAuthorize()} />
+ <Button type={Type.TERT} text="Connect to Google" iconPlacement="left" icon={<BsGoogle />} onClick={() => this.googleAuthorize()} />
</div>
);
}
@@ -406,10 +406,6 @@ export class SettingsManager extends React.Component<{}> {
);
}
- setFreeformScrollMode = (mode: string) => {
- Doc.UserDoc().freeformScrollMode = mode;
- };
-
@computed get modesContent() {
return (
<div className="tab-content modes-content">
@@ -417,8 +413,8 @@ export class SettingsManager extends React.Component<{}> {
<div className="tab-column-title">Modes</div>
<div className="tab-column-content">
<Dropdown
- formLabel={'Mode'}
- closeOnSelect={true}
+ formLabel="Mode"
+ closeOnSelect
items={[
{
text: 'Novice',
@@ -442,7 +438,7 @@ export class SettingsManager extends React.Component<{}> {
color={SettingsManager.userColor}
fillWidth
/>
- <Toggle formLabel={'Playground Mode'} toggleType={ToggleType.SWITCH} toggleStatus={this.playgroundMode} onClick={this.playgroundModeToggle} color={SettingsManager.userColor} />
+ <Toggle formLabel="Playground Mode" toggleType={ToggleType.SWITCH} toggleStatus={this._playgroundMode} onClick={this.playgroundModeToggle} color={SettingsManager.userColor} />
</div>
<div className="tab-column-title" style={{ marginTop: 20, marginBottom: 10 }}>
Freeform Navigation
@@ -450,7 +446,7 @@ export class SettingsManager extends React.Component<{}> {
<div className="tab-column-content">
<Dropdown
formLabel="Scroll Mode"
- closeOnSelect={true}
+ closeOnSelect
items={[
{
text: 'Scroll to Pan',
@@ -475,15 +471,34 @@ export class SettingsManager extends React.Component<{}> {
<div className="tab-column">
<div className="tab-column-title">Permissions</div>
<div className="tab-column-content">
- <Button text={'Manage Groups'} type={Type.TERT} onClick={() => GroupManager.Instance?.open()} color={SettingsManager.userColor} />
+ <Button text="Manage Groups" type={Type.TERT} onClick={() => GroupManager.Instance?.open()} color={SettingsManager.userColor} />
<Toggle
toggleType={ToggleType.SWITCH}
- formLabel={'Default access private'}
+ formLabel="Default access private"
color={SettingsManager.userColor}
toggleStatus={BoolCast(Doc.defaultAclPrivate)}
- onClick={action(() => (Doc.defaultAclPrivate = !Doc.defaultAclPrivate))}
+ onClick={action(() => {
+ Doc.defaultAclPrivate = !Doc.defaultAclPrivate;
+ })}
+ />
+ <Toggle
+ toggleType={ToggleType.SWITCH}
+ formLabel="Enable Sharing UI"
+ color={SettingsManager.userColor}
+ toggleStatus={BoolCast(Doc.IsSharingEnabled)}
+ onClick={action(() => {
+ Doc.IsSharingEnabled = !Doc.IsSharingEnabled;
+ })}
+ />
+ <Toggle
+ toggleType={ToggleType.SWITCH}
+ formLabel="Disable Info UI"
+ color={SettingsManager.userColor}
+ toggleStatus={BoolCast(Doc.IsInfoUIDisabled)}
+ onClick={action(() => {
+ Doc.IsInfoUIDisabled = !Doc.IsInfoUIDisabled;
+ })}
/>
- <Toggle toggleType={ToggleType.SWITCH} formLabel={'Enable Sharing UI'} color={SettingsManager.userColor} toggleStatus={BoolCast(Doc.IsSharingEnabled)} onClick={action(() => (Doc.IsSharingEnabled = !Doc.IsSharingEnabled))} />
</div>
</div>
</div>
@@ -505,7 +520,7 @@ export class SettingsManager extends React.Component<{}> {
<div className="settings-panel" style={{ background: SettingsManager.userColor }}>
<div className="settings-tabs">
{tabs.map(tab => {
- const isActive = this.activeTab === tab.title;
+ const isActive = this._activeTab === tab.title;
return (
<div
key={tab.title}
@@ -514,7 +529,9 @@ export class SettingsManager extends React.Component<{}> {
color: isActive ? SettingsManager.userColor : SettingsManager.userBackgroundColor,
}}
className={'tab-control ' + (isActive ? 'active' : 'inactive')}
- onClick={action(() => (this.activeTab = tab.title))}>
+ onClick={action(() => {
+ this._activeTab = tab.title;
+ })}>
{tab.title}
</div>
);
@@ -524,19 +541,19 @@ export class SettingsManager extends React.Component<{}> {
<div className="settings-user">
<div style={{ color: SettingsManager.userBackgroundColor }}>{DashVersion}</div>
<div className="settings-username" style={{ color: SettingsManager.userBackgroundColor }}>
- {Doc.CurrentUserEmail}
+ {ClientUtils.CurrentUserEmail()}
</div>
- <Button text={Doc.GuestDashboard ? 'Exit' : 'Log Out'} type={Type.TERT} color={SettingsManager.userVariantColor} onClick={() => window.location.assign(Utils.prepend('/logout'))} />
+ <Button text={Doc.GuestDashboard ? 'Exit' : 'Log Out'} type={Type.TERT} color={SettingsManager.userVariantColor} onClick={() => window.location.assign(ClientUtils.prepend('/logout'))} />
</div>
</div>
<div className="close-button">
- <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={this.close} color={SettingsManager.userColor} />
+ <Button icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={this.closeMgr} color={SettingsManager.userColor} />
</div>
<div className="settings-content" style={{ color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }}>
{tabs.map(tab => (
- <div key={tab.title} className={'tab-section ' + (this.activeTab === tab.title ? 'active' : 'inactive')}>
+ <div key={tab.title} className={'tab-section ' + (this._activeTab === tab.title ? 'active' : 'inactive')}>
{tab.ele}
</div>
))}
@@ -545,13 +562,37 @@ export class SettingsManager extends React.Component<{}> {
);
}
+ private changePassword = async () => {
+ if (!(this._curr_password && this._new_password && this._new_confirm)) {
+ runInAction(() => {
+ this._passwordResultText = "Error: Hey, we're missing some fields!";
+ });
+ } else {
+ const passwordBundle = { curr_pass: this._curr_password, new_pass: this._new_password, new_confirm: this._new_confirm };
+ const { error } = await Networking.PostToServer('/internalResetPassword', passwordBundle);
+ runInAction(() => {
+ this._passwordResultText = error ? 'Error: ' + error[0].msg + '...' : 'Password successfully updated!';
+ });
+ }
+ };
+
+ @action
+ changeVal = (value: string, pass: string) => {
+ switch (pass) {
+ case 'curr': this._curr_password = value; break;
+ case 'new': this._new_password = value; break;
+ case 'conf': this._new_confirm = value; break;
+ default:
+ } // prettier-ignore
+ };
+
render() {
return (
<MainViewModal
contents={this.settingsInterface}
- isDisplayed={this.isOpen}
- interactive={true}
- closeOnExternalClick={this.close}
+ isDisplayed={this._isOpen}
+ interactive
+ closeOnExternalClick={this.closeMgr}
dialogueBoxStyle={{ width: 'fit-content', height: '300px', background: Cast(Doc.UserDoc().userColor, 'string', null) }}
/>
);
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index fddf735e3..c2a52cae9 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -1,3 +1,6 @@
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* 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 { concat, intersection } from 'lodash';
@@ -6,25 +9,23 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import Select from 'react-select';
import * as RequestPromise from 'request-promise';
+import { ClientUtils } from '../../ClientUtils';
+import { Utils } from '../../Utils';
import { Doc, DocListCast, DocListCastAsync, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
import { AclAdmin, AclPrivate, DocAcl, DocData } from '../../fields/DocSymbols';
import { FieldLoader } from '../../fields/FieldLoader';
import { Id } from '../../fields/FieldSymbols';
import { StrCast } from '../../fields/Types';
-import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from '../../fields/util';
-import { Utils } from '../../Utils';
+import { GetEffectiveAcl, SharingPermissions, TraceMobx, distributeAcls, normalizeEmail } from '../../fields/util';
import { DocServer } from '../DocServer';
-import { DictationOverlay } from '../views/DictationOverlay';
import { MainViewModal } from '../views/MainViewModal';
import { DocumentView } from '../views/nodes/DocumentView';
import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
-import { DocumentManager } from './DocumentManager';
import { GroupManager, UserOptions } from './GroupManager';
import { GroupMemberView } from './GroupMemberView';
import { SearchUtil } from './SearchUtil';
-import { SelectionManager } from './SelectionManager';
-import { SettingsManager } from './SettingsManager';
import './SharingManager.scss';
+import { SnappingManager } from './SnappingManager';
import { undoable } from './UndoManager';
export interface User {
@@ -64,63 +65,36 @@ interface ValidatedUser {
@observer
export class SharingManager extends React.Component<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: SharingManager;
+ private shareDocumentButtonRef: React.RefObject<HTMLButtonElement> = React.createRef(); // ref for the share button, used for the position of the popup
+ private populating: boolean = false; // whether the list of users is populating or not
@observable private isOpen = false; // whether the SharingManager modal is open or not
@observable public users: ValidatedUser[] = []; // the list of users with sharing docs
@observable private targetDoc: Doc | undefined = undefined; // the document being shared
@observable private targetDocView: DocumentView | undefined = undefined; // the DocumentView of the document being shared
// @observable private copied = false;
@observable private dialogueBoxOpacity = 1; // for the modal
- @observable private overlayOpacity = 0.4; // for the modal
@observable private selectedUsers: UserOptions[] | null = null; // users (individuals/groups) selected to share with
@observable private permissions: SharingPermissions = SharingPermissions.Edit; // the permission with which to share with other users
@observable private individualSort: 'ascending' | 'descending' | 'none' = 'none'; // sorting options for the list of individuals
@observable private groupSort: 'ascending' | 'descending' | 'none' = 'none'; // sorting options for the list of groups
- private shareDocumentButtonRef: React.RefObject<HTMLButtonElement> = React.createRef(); // ref for the share button, used for the position of the popup
// if both showUserOptions and showGroupOptions are false then both are displayed
@observable private showUserOptions: boolean = false; // whether to show individuals as options when sharing (in the react-select component)
@observable private showGroupOptions: boolean = false; // // whether to show groups as options when sharing (in the react-select component)
- private populating: boolean = false; // whether the list of users is populating or not
@observable private upgradeNested: boolean = false; // whether child docs in a collection/dashboard should be changed to be less private - initially selected so default is upgrade all
@observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used
@observable private myDocAcls: boolean = false; // whether the My Docs checkbox is selected or not
- @observable private _buttonDown = false;
// private get linkVisible() {
- // return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false;
+ // return this.targetDoc ? this.targetDoc['acl_' + PublicKey] !== SharingPermissions.None : false;
// }
- public open = (target?: DocumentView, target_doc?: Doc) => {
- this.populateUsers();
- runInAction(() => {
- this.targetDocView = target;
- this.targetDoc = target_doc || target?.Document;
- DictationOverlay.Instance.hasActiveModal = true;
- this.isOpen = this.targetDoc !== undefined;
- this.permissions = SharingPermissions.Augment;
- this.upgradeNested = true;
- });
- };
-
- public close = action(() => {
- this.isOpen = false;
- this.selectedUsers = null; // resets the list of users and selected users (in the react-select component)
- TaskCompletionBox.taskCompleted = false;
- setTimeout(
- action(() => {
- // this.copied = false;
- DictationOverlay.Instance.hasActiveModal = false;
- this.targetDoc = undefined;
- }),
- 500
- );
- this.layoutDocAcls = false;
- });
-
constructor(props: {}) {
super(props);
makeObservable(this);
SharingManager.Instance = this;
+ DocumentView.ShareOpen = this.open;
}
/**
@@ -131,223 +105,6 @@ export class SharingManager extends React.Component<{}> {
}
/**
- * Populates the list of validated users (this.users) by adding registered users which have a sharingDocument.
- */
- populateUsers = async () => {
- if (!this.populating && Doc.UserDoc()[Id] !== Utils.GuestID()) {
- this.populating = true;
- const userList = await RequestPromise.get(Utils.prepend('/getUsers'));
- const raw = (JSON.parse(userList) as User[]).filter(user => user.email !== 'guest' && user.email !== Doc.CurrentUserEmail);
- runInAction(() => (FieldLoader.ServerLoadStatus.message = 'users'));
- const docs = await DocServer.GetRefFields(raw.reduce((list, user) => [...list, user.sharingDocumentId, user.linkDatabaseId], [] as string[]));
- raw.map(
- action((newUser: User) => {
- const sharingDoc = docs[newUser.sharingDocumentId];
- const linkDatabase = docs[newUser.linkDatabaseId];
- if (sharingDoc instanceof Doc && linkDatabase instanceof Doc) {
- if (!this.users.find(user => user.user.email === newUser.email)) {
- this.users.push({ user: newUser, sharingDoc, linkDatabase, userColor: StrCast(sharingDoc.userColor) });
- //LinkManager.addLinkDB(linkDatabase);
- }
- }
- })
- );
- this.populating = false;
- }
- };
-
- /**
- * Shares the document with a user.
- */
- setInternalSharing = undoable((recipient: ValidatedUser, permission: string, targetDoc: Doc | undefined) => {
- const { user, sharingDoc } = recipient;
- const target = targetDoc || this.targetDoc!;
- const acl = `acl-${normalizeEmail(user.email)}`;
- const docs = SelectionManager.Views.length < 2 ? [target] : SelectionManager.Views.map(docView => docView.Document);
- docs.map(doc => (this.layoutDocAcls || doc.dockingConfig ? doc : Doc.GetProto(doc))).forEach(doc => {
- distributeAcls(acl, permission as SharingPermissions, doc, undefined, this.upgradeNested ? true : undefined);
- if (permission !== SharingPermissions.None) {
- Doc.AddDocToList(sharingDoc, doc.dockingConfig ? dashStorage : storage, doc);
- } else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, ((doc.createdFrom as Doc) || doc).dockingConfig ? dashStorage : storage, (doc.createdFrom as Doc) || doc);
- });
- }, 'set Doc permissions');
-
- /**
- * Sets the permission on the target for the group.
- * @param group
- * @param permission
- */
- setInternalGroupSharing = undoable((group: Doc | { title: string }, permission: string, targetDoc?: Doc) => {
- const target = targetDoc || this.targetDoc!;
- const acl = `acl-${normalizeEmail(StrCast(group.title))}`;
-
- const docs = SelectionManager.Views.length < 2 ? [target] : SelectionManager.Views.map(docView => docView.Document);
- docs.map(doc => (this.layoutDocAcls || doc.dockingConfig ? doc : Doc.GetProto(doc))).forEach(doc => {
- distributeAcls(acl, permission as SharingPermissions, doc, undefined, this.upgradeNested ? true : undefined);
-
- if (group instanceof Doc) {
- Doc.AddDocToList(group, 'docsShared', doc);
-
- this.users
- .filter(({ user: { email } }) => JSON.parse(StrCast(group.members)).includes(email))
- .forEach(({ user, sharingDoc }) => {
- if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, doc.dockingConfig ? dashStorage : storage, doc); // add the doc to the sharingDoc if it hasn't already been added
- else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, ((doc.createdFrom as Doc) || doc).dockingConfig ? dashStorage : storage, (doc.createdFrom as Doc) || doc); // remove the doc from the list if it already exists
- });
- }
- });
- }, 'set group permissions');
-
- /**
- * Shares the documents shared with a group with a new user who has been added to that group.
- * @param group
- * @param emailId
- */
- shareWithAddedMember = (group: Doc, emailId: string, retry: boolean = true) => {
- const user = this.users.find(({ user: { email } }) => email === emailId)!;
- const self = this;
- if (group.docsShared) {
- if (!user) retry && this.populateUsers().then(() => self.shareWithAddedMember(group, emailId, false));
- else {
- DocListCastAsync(user.sharingDoc[storage]).then(userdocs =>
- DocListCastAsync(group.docsShared).then(dl => {
- const filtered = dl?.filter(doc => !doc.dockingConfig && !userdocs?.includes(doc));
- filtered && userdocs?.push(...filtered);
- })
- );
- DocListCastAsync(user.sharingDoc[dashStorage]).then(userdocs =>
- DocListCastAsync(group.docsShared).then(dl => {
- const filtered = dl?.filter(doc => doc.dockingConfig && !userdocs?.includes(doc));
- filtered && userdocs?.push(...filtered);
- })
- );
- }
- }
- };
-
- /**
- * Called from the properties sidebar to change permissions of a user.
- */
- shareFromPropertiesSidebar = undoable((shareWith: string, permission: SharingPermissions, docs: Doc[], layout: boolean) => {
- if (layout) this.layoutDocAcls = true;
- if (shareWith !== 'Guest') {
- const user = this.users.find(({ user: { email } }) => email === (shareWith === 'Me' ? Doc.CurrentUserEmail : shareWith));
- docs.forEach(doc => {
- if (user) this.setInternalSharing(user, permission, doc);
- else this.setInternalGroupSharing(GroupManager.Instance.getGroup(shareWith)!, permission, doc, undefined, true);
- });
- } else {
- docs.forEach(doc => {
- if (GetEffectiveAcl(doc) === AclAdmin) {
- distributeAcls(`acl-${shareWith}`, permission, doc, undefined);
- }
- });
- }
- this.layoutDocAcls = false;
- }, 'sidebar set permissions');
-
- /**
- * Removes the documents shared with a user through a group when the user is removed from the group.
- * @param group
- * @param emailId
- */
- removeMember = (group: Doc, emailId: string) => {
- const user: ValidatedUser = this.users.find(({ user: { email } }) => email === emailId)!;
-
- if (group.docsShared && user) {
- DocListCastAsync(user.sharingDoc[storage]).then(userdocs =>
- DocListCastAsync(group.docsShared).then(dl => {
- const remaining = userdocs?.filter(doc => !dl?.includes(doc)) || [];
- userdocs?.splice(0, userdocs.length, ...remaining);
- })
- );
- DocListCastAsync(user.sharingDoc[dashStorage]).then(userdocs =>
- DocListCastAsync(group.docsShared).then(dl => {
- const remaining = userdocs?.filter(doc => !dl?.includes(doc)) || [];
- userdocs?.splice(0, userdocs.length, ...remaining);
- })
- );
- }
- };
-
- /**
- * Removes a group's permissions from documents that have been shared with it.
- * @param group
- */
- removeGroup = (group: Doc) => {
- if (group.docsShared) {
- DocListCast(group.docsShared).forEach(doc => {
- const acl = `acl-${StrCast(group.title)}`;
- distributeAcls(acl, SharingPermissions.None, doc);
-
- const members: string[] = JSON.parse(StrCast(group.members));
- const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email));
-
- users.forEach(({ sharingDoc }) => Doc.RemoveDocFromList(sharingDoc, storage, doc));
- });
- }
- };
-
- // private setExternalSharing = (permission: string) => {
- // const targetDoc = this.targetDoc;
- // if (!targetDoc) {
- // return;
- // }
- // targetDoc["acl-" + PublicKey] = permission;
- // }s
-
- /**
- * Copies the Public sharing url to the user's clipboard.
- */
- private copyURL = (e: any) => {
- Utils.CopyText(Utils.shareUrl(this.targetDoc![Id]));
- };
-
- /**
- * Returns the SharingPermissions (Admin, Can Edit etc) access that's used to share
- */
- private sharingOptions(uniform: boolean, showGuestOptions?: boolean) {
- const dropdownValues: string[] = showGuestOptions ? [SharingPermissions.None, SharingPermissions.View] : Object.values(SharingPermissions);
- if (!uniform) dropdownValues.unshift('-multiple-');
- return dropdownValues.map(permission => (
- <option key={permission} value={permission}>
- {concat(ReverseHierarchyMap.get(permission)?.image, ' ', permission)}
- </option>
- ));
- }
-
- private focusOn = (contents: string) => {
- const title = this.targetDoc ? StrCast(this.targetDoc.title) : '';
- const docs = SelectionManager.Views.length > 1 ? SelectionManager.Views.map(docView => docView.props.Document) : [this.targetDoc];
- return (
- <span
- className="focus-span"
- title={title}
- onClick={() => {
- if (this.targetDoc && this.targetDocView && docs.length === 1) {
- DocumentManager.Instance.showDocument(this.targetDoc, { willZoomCentered: true });
- }
- }}
- onPointerEnter={action(() => {
- if (docs.length) {
- docs.forEach(doc => doc && Doc.BrushDoc(doc));
- this.dialogueBoxOpacity = 0.1;
- this.overlayOpacity = 0.1;
- }
- })}
- onPointerLeave={action(() => {
- if (docs.length) {
- docs.forEach(doc => doc && Doc.UnBrushDoc(doc));
- this.dialogueBoxOpacity = 1;
- this.overlayOpacity = 0.4;
- }
- })}>
- {contents}
- </span>
- );
- };
-
- /**
* Handles changes in the users selected in react-select
*/
@action
@@ -366,57 +123,6 @@ export class SharingManager extends React.Component<{}> {
);
/**
- * Calls the relevant method for sharing, displays the popup, and resets the relevant variables.
- */
- share = undoable(
- action(() => {
- if (this.selectedUsers) {
- this.selectedUsers.forEach(user => {
- if (user.value.includes(indType)) {
- this.setInternalSharing(this.users.find(u => u.user.email === user.label)!, this.permissions, undefined);
- } else {
- this.setInternalGroupSharing(GroupManager.Instance.getGroup(user.label)!, this.permissions);
- }
- });
-
- if (this.shareDocumentButtonRef.current) {
- const { left, width, top, height } = this.shareDocumentButtonRef.current.getBoundingClientRect();
- TaskCompletionBox.popupX = left - 1.5 * width;
- TaskCompletionBox.popupY = top - 1.5 * height;
- TaskCompletionBox.textDisplayed = 'Document shared!';
- TaskCompletionBox.taskCompleted = true;
- setTimeout(
- action(() => (TaskCompletionBox.taskCompleted = false)),
- 2000
- );
- }
-
- this.layoutDocAcls = false;
- this.selectedUsers = null;
- }
- }),
- 'share Doc'
- );
-
- /**
- * Sorting algorithm to sort users.
- */
- sortUsers = (u1: ValidatedUser, u2: ValidatedUser) => {
- const { email: e1 } = u1.user;
- const { email: e2 } = u2.user;
- return e1 < e2 ? -1 : e1 === e2 ? 0 : 1;
- };
-
- /**
- * Sorting algorithm to sort groups.
- */
- sortGroups = (group1: Doc, group2: Doc) => {
- const g1 = StrCast(group1.title);
- const g2 = StrCast(group2.title);
- return g1 < g2 ? -1 : g1 === g2 ? 0 : 1;
- };
-
- /**
* @returns the main interface of the SharingManager.
*/
@computed get sharingInterface() {
@@ -445,7 +151,7 @@ export class SharingManager extends React.Component<{}> {
const users = this.individualSort === 'ascending' ? this.users.slice().sort(this.sortUsers) : this.individualSort === 'descending' ? this.users.slice().sort(this.sortUsers).reverse() : this.users;
const groups = this.groupSort === 'ascending' ? groupList.slice().sort(this.sortGroups) : this.groupSort === 'descending' ? groupList.slice().sort(this.sortGroups).reverse() : groupList;
- let docs = SelectionManager.Views.length < 2 ? [this.targetDoc] : SelectionManager.Views.map(docView => docView.Document);
+ let docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document);
if (this.myDocAcls) {
const newDocs: Doc[] = [];
@@ -464,18 +170,18 @@ export class SharingManager extends React.Component<{}> {
// the list of users shared with
const userListContents = users
- // .filter(({ user }) => (docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(user.email)}`) : docs[0]?.author !== user.email))
+ // .filter(({ user }) => (docs.length > 1 ? commonKeys.includes(`acl_${normalizeEmail(user.email)}`) : docs[0]?.author !== user.email))
.filter(({ user }) => docs[0]?.author !== user.email)
.map(({ user, linkDatabase, sharingDoc, userColor }) => {
- const userKey = `acl-${normalizeEmail(user.email)}`;
+ const userKey = `acl_${normalizeEmail(user.email)}`;
const uniform = docs.every(doc => doc?.[DocAcl]?.[userKey] === docs[0]?.[DocAcl]?.[userKey]);
// const permissions = uniform ? StrCast(targetDoc?.[userKey]) : '-multiple-';
let permissions = targetDoc[DocAcl][userKey] ? HierarchyMapping.get(targetDoc[DocAcl][userKey])?.name : StrCast(targetDoc[userKey]);
permissions = uniform ? StrCast(targetDoc?.[userKey]) : '-multiple-';
return !permissions ? null : (
- <div key={userKey} className={'container'}>
- <span className={'padding'}>{user.email}</span>
+ <div key={userKey} className="container">
+ <span className="padding">{user.email}</span>
<div className="edit-actions">
{admin || this.myDocAcls ? (
<select className={`permissions-dropdown-${permissions}`} value={permissions} onChange={e => this.setInternalSharing({ user, linkDatabase, sharingDoc, userColor }, e.currentTarget.value, undefined)}>
@@ -496,21 +202,21 @@ export class SharingManager extends React.Component<{}> {
const sameAuthor = docs.every(doc => doc?.author === docs[0]?.author);
// the owner of the doc and the current user are placed at the top of the user list.
- const userKey = `acl-${normalizeEmail(Doc.CurrentUserEmail)}`;
+ const userKey = `acl_${normalizeEmail(ClientUtils.CurrentUserEmail())}`;
const curUserPermission = StrCast(targetDoc[userKey]);
// const curUserPermission = HierarchyMapping.get(effectiveAcls[0])!.name
userListContents.unshift(
sameAuthor ? (
- <div key={'owner'} className={'container'}>
- <span className="padding">{targetDoc?.author === Doc.CurrentUserEmail ? 'Me' : StrCast(targetDoc?.author)}</span>
+ <div key="owner" className="container">
+ <span className="padding">{targetDoc?.author === ClientUtils.CurrentUserEmail() ? 'Me' : StrCast(targetDoc?.author)}</span>
<div className="edit-actions">
- <div className={'permissions-dropdown'}>Owner</div>
+ <div className="permissions-dropdown">Owner</div>
</div>
</div>
) : null,
- sameAuthor && targetDoc?.author !== Doc.CurrentUserEmail ? (
- <div key={'me'} className={'container'}>
- <span className={'padding'}>Me</span>
+ sameAuthor && targetDoc?.author !== ClientUtils.CurrentUserEmail() ? (
+ <div key="me" className="container">
+ <span className="padding">Me</span>
<div className="edit-actions">
<div className={`permissions-dropdown-${curUserPermission}`}>
{effectiveAcls.every(acl => acl === effectiveAcls[0]) ? concat(ReverseHierarchyMap.get(curUserPermission!)?.image, ' ', curUserPermission) : '-multiple-'}
@@ -522,19 +228,28 @@ export class SharingManager extends React.Component<{}> {
);
// the list of groups shared with
- const groupListMap: (Doc | { title: string })[] = groups.filter(({ title }) => (docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(StrCast(title))}`) : true));
- groupListMap.unshift({ title: 'Guest' }); //, { title: "ALL" });
+ const groupListMap: (Doc | { title: string })[] = groups.filter(({ title }) => (docs.length > 1 ? commonKeys.includes(`acl_${normalizeEmail(StrCast(title))}`) : true));
+ groupListMap.unshift({ title: 'Guest' }); // , { title: "ALL" });
const groupListContents = groupListMap.map(group => {
- let groupKey = `acl-${StrCast(group.title)}`;
+ const groupKey = `acl_${StrCast(group.title)}`;
const uniform = docs.every(doc => doc?.[DocAcl]?.[groupKey] === docs[0]?.[DocAcl]?.[groupKey]);
const permissions = uniform ? StrCast(targetDoc?.[groupKey]) : '-multiple-';
return !permissions ? null : (
- <div key={groupKey} className={'container'} style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}>
- <div className={'padding'}>{StrCast(group.title)}</div>
+ <div key={groupKey} className="container" style={{ background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor }}>
+ <div className="padding">{StrCast(group.title)}</div>
&nbsp;
- {group instanceof Doc ? <IconButton icon={<FontAwesomeIcon icon={'info-circle'} />} size={Size.XSMALL} color={SettingsManager.userColor} onClick={action(() => (GroupManager.Instance.currentGroup = group))} /> : null}
- <div className={'edit-actions'}>
+ {group instanceof Doc ? (
+ <IconButton
+ icon={<FontAwesomeIcon icon="info-circle" />}
+ size={Size.XSMALL}
+ color={SnappingManager.userColor}
+ onClick={action(() => {
+ GroupManager.Instance.currentGroup = group;
+ })}
+ />
+ ) : null}
+ <div className="edit-actions">
{admin || this.myDocAcls ? (
<select className={`permissions-dropdown-${permissions}`} value={permissions} onChange={e => this.setInternalGroupSharing(group, e.currentTarget.value)}>
{this.sharingOptions(uniform, group.title === 'Guest')}
@@ -551,25 +266,32 @@ export class SharingManager extends React.Component<{}> {
});
return (
<div className="sharing-interface">
- {GroupManager.Instance?.currentGroup ? <GroupMemberView group={GroupManager.Instance.currentGroup} onCloseButtonClick={action(() => (GroupManager.Instance.currentGroup = undefined))} /> : null}
+ {GroupManager.Instance?.currentGroup ? (
+ <GroupMemberView
+ group={GroupManager.Instance.currentGroup}
+ onCloseButtonClick={action(() => {
+ GroupManager.Instance.currentGroup = undefined;
+ })}
+ />
+ ) : null}
<div
className="sharing-contents"
style={{
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
color: StrCast(Doc.UserDoc().userColor),
}}>
- <p className="share-title" style={{ color: SettingsManager.userColor }}>
+ <p className="share-title" style={{ color: SnappingManager.userColor }}>
<div className="share-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/collaboration/', '_blank')}>
- <FontAwesomeIcon icon={'question-circle'} size={'sm'} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/collaboration/', '_blank')} />
+ <FontAwesomeIcon icon="question-circle" size="sm" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/collaboration/', '_blank')} />
</div>
<b>Share </b>
{this.focusOn(docs.length < 2 ? StrCast(targetDoc?.title, 'this document') : '-multiple-')}
</p>
<div className="share-copy-link">
- <Button type={Type.TERT} color={SettingsManager.userColor} icon={<FontAwesomeIcon icon={'copy'} size="sm" />} iconPlacement={'left'} text={'Copy Guest URL'} onClick={this.copyURL} />
+ <Button type={Type.TERT} color={SnappingManager.userColor} icon={<FontAwesomeIcon icon="copy" size="sm" />} iconPlacement="left" text="Copy Guest URL" onClick={this.copyURL} />
</div>
<div className="close-button">
- <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={this.close} color={SettingsManager.userColor} />
+ <Button icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={this.close} color={SnappingManager.userColor} />
</div>
{admin ? (
<div className="share-container">
@@ -611,19 +333,45 @@ export class SharingManager extends React.Component<{}> {
</select>
</div>
<div className="share-button">
- <Button text={'SHARE'} type={Type.TERT} color={SettingsManager.userColor} onClick={this.share} />
+ <Button text="SHARE" type={Type.TERT} color={SnappingManager.userColor} onClick={this.share} />
</div>
</div>
<div className="sort-checkboxes">
- <input type="checkbox" onChange={action(() => (this.showUserOptions = !this.showUserOptions))} /> <label style={{ marginRight: 10 }}>Individuals</label>
- <input type="checkbox" onChange={action(() => (this.showGroupOptions = !this.showGroupOptions))} /> <label>Groups</label>
+ <input
+ type="checkbox"
+ onChange={action(() => {
+ this.showUserOptions = !this.showUserOptions;
+ })}
+ />{' '}
+ <label style={{ marginRight: 10 }}>Individuals</label>
+ <input
+ type="checkbox"
+ onChange={action(() => {
+ this.showGroupOptions = !this.showGroupOptions;
+ })}
+ />{' '}
+ <label>Groups</label>
</div>
<div className="acl-container">
{Doc.noviceMode ? null : (
<div className="layoutDoc-acls">
- <input type="checkbox" onChange={action(() => (this.upgradeNested = !this.upgradeNested))} checked={this.upgradeNested} /> <label>Upgrade Nested </label>
- <input type="checkbox" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} /> <label>Layout</label>
+ <input
+ type="checkbox"
+ onChange={action(() => {
+ this.upgradeNested = !this.upgradeNested;
+ })}
+ checked={this.upgradeNested}
+ />{' '}
+ <label>Upgrade Nested </label>
+ <input
+ type="checkbox"
+ onChange={action(() => {
+ this.layoutDocAcls = !this.layoutDocAcls;
+ })}
+ checked={this.layoutDocAcls}
+ />{' '}
+ <label>Layout</label>
</div>
)}
</div>
@@ -632,14 +380,25 @@ export class SharingManager extends React.Component<{}> {
<div className="share-container">
<div className="acl-container">
<div className="layoutDoc-acls">
- <input type="checkbox" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} /> <label>Layout</label>
+ <input
+ type="checkbox"
+ onChange={action(() => {
+ this.layoutDocAcls = !this.layoutDocAcls;
+ })}
+ checked={this.layoutDocAcls}
+ />{' '}
+ <label>Layout</label>
</div>
</div>
</div>
)}
<div className="main-container" style={{ color: StrCast(Doc.UserDoc().userColor), border: StrCast(Doc.UserDoc().userColor) }}>
- <div className={'individual-container'}>
- <div className="user-sort" onClick={action(() => (this.individualSort = this.individualSort === 'ascending' ? 'descending' : this.individualSort === 'descending' ? 'none' : 'ascending'))}>
+ <div className="individual-container">
+ <div
+ className="user-sort"
+ onClick={action(() => {
+ this.individualSort = this.individualSort === 'ascending' ? 'descending' : this.individualSort === 'descending' ? 'none' : 'ascending';
+ })}>
<div className="title-individual">
Individuals
<IconButton
@@ -651,11 +410,15 @@ export class SharingManager extends React.Component<{}> {
</div>
<div className="users-list">{userListContents}</div>
</div>
- <div className={'group-container'}>
- <div className="user-sort" onClick={action(() => (this.groupSort = this.groupSort === 'ascending' ? 'descending' : this.groupSort === 'descending' ? 'none' : 'ascending'))}>
+ <div className="group-container">
+ <div
+ className="user-sort"
+ onClick={action(() => {
+ this.groupSort = this.groupSort === 'ascending' ? 'descending' : this.groupSort === 'descending' ? 'none' : 'ascending';
+ })}>
<div className="title-group">
Groups
- <IconButton icon={<FontAwesomeIcon icon={'info-circle'} />} size={Size.XSMALL} color={StrCast(Doc.UserDoc().userColor)} onClick={action(() => GroupManager.Instance.open())} />
+ <IconButton icon={<FontAwesomeIcon icon="info-circle" />} size={Size.XSMALL} color={StrCast(Doc.UserDoc().userColor)} onClick={action(() => GroupManager.Instance.open())} />
<IconButton
icon={<FontAwesomeIcon icon={this.groupSort === 'ascending' ? 'caret-up' : this.groupSort === 'descending' ? 'caret-down' : 'caret-right'} />}
size={Size.XSMALL}
@@ -663,7 +426,7 @@ export class SharingManager extends React.Component<{}> {
/>
</div>
</div>
- <div className={'groups-list'}>{groupListContents}</div>
+ <div className="groups-list">{groupListContents}</div>
</div>
</div>
</div>
@@ -671,7 +434,307 @@ export class SharingManager extends React.Component<{}> {
);
}
+ /**
+ * Shares the document with a user.
+ */
+ setInternalSharing = undoable((recipient: ValidatedUser, permission: string, targetDoc: Doc | undefined) => {
+ const { user, sharingDoc } = recipient;
+ const target = targetDoc || this.targetDoc!;
+ const acl = `acl_${normalizeEmail(user.email)}`;
+ const docs = DocumentView.Selected().length < 2 ? [target] : DocumentView.Selected().map(docView => docView.Document);
+ docs.map(doc => (this.layoutDocAcls || doc.dockingConfig ? doc : Doc.GetProto(doc))).forEach(doc => {
+ distributeAcls(acl, permission as SharingPermissions, doc, undefined, this.upgradeNested ? true : undefined);
+ if (permission !== SharingPermissions.None) {
+ Doc.AddDocToList(sharingDoc, doc.dockingConfig ? dashStorage : storage, doc);
+ } else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, ((doc.createdFrom as Doc) || doc).dockingConfig ? dashStorage : storage, (doc.createdFrom as Doc) || doc);
+ });
+ }, 'set Doc permissions');
+
+ /**
+ * Sets the permission on the target for the group.
+ * @param group
+ * @param permission
+ */
+ setInternalGroupSharing = undoable((group: Doc | { title: string }, permission: string, targetDoc?: Doc) => {
+ const target = targetDoc || this.targetDoc!;
+ const acl = `acl_${normalizeEmail(StrCast(group.title))}`;
+
+ const docs = DocumentView.Selected().length < 2 ? [target] : DocumentView.Selected().map(docView => docView.Document);
+ docs.map(doc => (this.layoutDocAcls || doc.dockingConfig ? doc : Doc.GetProto(doc))).forEach(doc => {
+ distributeAcls(acl, permission as SharingPermissions, doc, undefined, this.upgradeNested ? true : undefined);
+
+ if (group instanceof Doc) {
+ Doc.AddDocToList(group, 'docsShared', doc);
+
+ this.users
+ .filter(({ user: { email } }) => JSON.parse(StrCast(group.members)).includes(email))
+ .forEach(({ user, sharingDoc }) => {
+ if (permission !== SharingPermissions.None)
+ Doc.AddDocToList(sharingDoc, doc.dockingConfig ? dashStorage : storage, doc); // add the doc to the sharingDoc if it hasn't already been added
+ else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, ((doc.createdFrom as Doc) || doc).dockingConfig ? dashStorage : storage, (doc.createdFrom as Doc) || doc); // remove the doc from the list if it already exists
+ });
+ }
+ });
+ }, 'set group permissions');
+ /**
+ * Populates the list of validated users (this.users) by adding registered users which have a sharingDocument.
+ */
+ populateUsers = async () => {
+ if (!this.populating && Doc.UserDoc()[Id] !== Utils.GuestID()) {
+ this.populating = true;
+ const userList = await RequestPromise.get(ClientUtils.prepend('/getUsers'));
+ const raw = (JSON.parse(userList) as User[]).filter(user => user.email !== 'guest' && user.email !== ClientUtils.CurrentUserEmail());
+ runInAction(() => {
+ FieldLoader.ServerLoadStatus.message = 'users';
+ });
+ const docs = await DocServer.GetRefFields(raw.reduce((list, user) => [...list, user.sharingDocumentId, user.linkDatabaseId], [] as string[]));
+ raw.map(
+ action((newUser: User) => {
+ const sharingDoc = docs[newUser.sharingDocumentId];
+ const linkDatabase = docs[newUser.linkDatabaseId];
+ if (sharingDoc instanceof Doc && linkDatabase instanceof Doc) {
+ if (!this.users.find(user => user.user.email === newUser.email)) {
+ this.users.push({ user: newUser, sharingDoc, linkDatabase, userColor: StrCast(sharingDoc.userColor) });
+ // LinkManager.addLinkDB(linkDatabase);
+ }
+ }
+ })
+ );
+ this.populating = false;
+ }
+ };
+
+ // eslint-disable-next-line react/sort-comp
+ public close = action(() => {
+ this.isOpen = false;
+ this.selectedUsers = null; // resets the list of users and selected users (in the react-select component)
+ TaskCompletionBox.taskCompleted = false;
+ setTimeout(
+ action(() => {
+ // this.copied = false;
+ this.targetDoc = undefined;
+ }),
+ 500
+ );
+ this.layoutDocAcls = false;
+ });
+
+ // eslint-disable-next-line react/no-unused-class-component-methods
+ public open = (target?: DocumentView, targetDoc?: Doc) => {
+ this.populateUsers();
+ runInAction(() => {
+ this.targetDocView = target;
+ this.targetDoc = targetDoc || target?.Document;
+ this.isOpen = this.targetDoc !== undefined;
+ this.permissions = SharingPermissions.Augment;
+ this.upgradeNested = true;
+ });
+ };
+
+ /**
+ * Shares the documents shared with a group with a new user who has been added to that group.
+ * @param group
+ * @param emailId
+ */
+ // eslint-disable-next-line react/no-unused-class-component-methods
+ shareWithAddedMember = (group: Doc, emailId: string, retry: boolean = true) => {
+ const user = this.users.find(({ user: { email } }) => email === emailId)!;
+ const self = this;
+ if (group.docsShared) {
+ if (!user) retry && this.populateUsers().then(() => self.shareWithAddedMember(group, emailId, false));
+ else {
+ DocListCastAsync(user.sharingDoc[storage]).then(userdocs =>
+ DocListCastAsync(group.docsShared).then(dl => {
+ const filtered = dl?.filter(doc => !doc.dockingConfig && !userdocs?.includes(doc));
+ filtered && userdocs?.push(...filtered);
+ })
+ );
+ DocListCastAsync(user.sharingDoc[dashStorage]).then(userdocs =>
+ DocListCastAsync(group.docsShared).then(dl => {
+ const filtered = dl?.filter(doc => doc.dockingConfig && !userdocs?.includes(doc));
+ filtered && userdocs?.push(...filtered);
+ })
+ );
+ }
+ }
+ };
+
+ /**
+ * Called from the properties sidebar to change permissions of a user.
+ */
+ // eslint-disable-next-line react/no-unused-class-component-methods
+ shareFromPropertiesSidebar = undoable((shareWith: string, permission: SharingPermissions, docs: Doc[], layout: boolean) => {
+ if (layout) this.layoutDocAcls = true;
+ if (shareWith !== 'Guest') {
+ const user = this.users.find(({ user: { email } }) => email === (shareWith === 'Me' ? ClientUtils.CurrentUserEmail() : shareWith));
+ docs.forEach(doc => {
+ if (user) this.setInternalSharing(user, permission, doc);
+ else this.setInternalGroupSharing(GroupManager.Instance.getGroup(shareWith)!, permission, doc, undefined, true);
+ });
+ } else {
+ docs.forEach(doc => {
+ if (GetEffectiveAcl(doc) === AclAdmin) {
+ distributeAcls(`acl_${shareWith}`, permission, doc, undefined);
+ }
+ });
+ }
+ this.layoutDocAcls = false;
+ }, 'sidebar set permissions');
+
+ /**
+ * Removes the documents shared with a user through a group when the user is removed from the group.
+ * @param group
+ * @param emailId
+ */
+ // eslint-disable-next-line react/no-unused-class-component-methods
+ removeMember = (group: Doc, emailId: string) => {
+ const user: ValidatedUser = this.users.find(({ user: { email } }) => email === emailId)!;
+
+ if (group.docsShared && user) {
+ DocListCastAsync(user.sharingDoc[storage]).then(userdocs =>
+ DocListCastAsync(group.docsShared).then(dl => {
+ const remaining = userdocs?.filter(doc => !dl?.includes(doc)) || [];
+ userdocs?.splice(0, userdocs.length, ...remaining);
+ })
+ );
+ DocListCastAsync(user.sharingDoc[dashStorage]).then(userdocs =>
+ DocListCastAsync(group.docsShared).then(dl => {
+ const remaining = userdocs?.filter(doc => !dl?.includes(doc)) || [];
+ userdocs?.splice(0, userdocs.length, ...remaining);
+ })
+ );
+ }
+ };
+
+ /**
+ * Removes a group's permissions from documents that have been shared with it.
+ * @param group
+ */
+ // eslint-disable-next-line react/no-unused-class-component-methods
+ removeGroup = (group: Doc) => {
+ if (group.docsShared) {
+ DocListCast(group.docsShared).forEach(doc => {
+ const acl = `acl_${StrCast(group.title)}`;
+ distributeAcls(acl, SharingPermissions.None, doc);
+
+ const members: string[] = JSON.parse(StrCast(group.members));
+ const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email));
+
+ users.forEach(({ sharingDoc }) => Doc.RemoveDocFromList(sharingDoc, storage, doc));
+ });
+ }
+ };
+
+ // private setExternalSharing = (permission: string) => {
+ // const targetDoc = this.targetDoc;
+ // if (!targetDoc) {
+ // return;
+ // }
+ // targetDoc['acl_' + PublicKey] = permission;
+ // }s
+
+ /**
+ * Copies the Public sharing url to the user's clipboard.
+ */
+ private copyURL = () => {
+ ClientUtils.CopyText(ClientUtils.shareUrl(this.targetDoc![Id]));
+ };
+
+ private focusOn = (contents: string) => {
+ const title = this.targetDoc ? StrCast(this.targetDoc.title) : '';
+ const docs = DocumentView.Selected().length > 1 ? DocumentView.Selected().map(docView => docView.props.Document) : [this.targetDoc];
+ return (
+ <span
+ className="focus-span"
+ title={title}
+ onClick={() => {
+ if (this.targetDoc && this.targetDocView && docs.length === 1) {
+ DocumentView.showDocument(this.targetDoc, { willZoomCentered: true });
+ }
+ }}
+ onPointerEnter={action(() => {
+ if (docs.length) {
+ docs.forEach(doc => doc && Doc.BrushDoc(doc));
+ this.dialogueBoxOpacity = 0.1;
+ }
+ })}
+ onPointerLeave={action(() => {
+ if (docs.length) {
+ docs.forEach(doc => doc && Doc.UnBrushDoc(doc));
+ this.dialogueBoxOpacity = 1;
+ }
+ })}>
+ {contents}
+ </span>
+ );
+ };
+
+ /**
+ * Calls the relevant method for sharing, displays the popup, and resets the relevant variables.
+ */
+ share = undoable(
+ action(() => {
+ if (this.selectedUsers) {
+ this.selectedUsers.forEach(user => {
+ if (user.value.includes(indType)) {
+ this.setInternalSharing(this.users.find(u => u.user.email === user.label)!, this.permissions, undefined);
+ } else {
+ this.setInternalGroupSharing(GroupManager.Instance.getGroup(user.label)!, this.permissions);
+ }
+ });
+
+ if (this.shareDocumentButtonRef.current) {
+ const { left, width, top, height } = this.shareDocumentButtonRef.current.getBoundingClientRect();
+ TaskCompletionBox.popupX = left - 1.5 * width;
+ TaskCompletionBox.popupY = top - 1.5 * height;
+ TaskCompletionBox.textDisplayed = 'Document shared!';
+ TaskCompletionBox.taskCompleted = true;
+ setTimeout(
+ action(() => {
+ TaskCompletionBox.taskCompleted = false;
+ }),
+ 2000
+ );
+ }
+
+ this.layoutDocAcls = false;
+ this.selectedUsers = null;
+ }
+ }),
+ 'share Doc'
+ );
+
+ /**
+ * Sorting algorithm to sort users.
+ */
+ sortUsers = (u1: ValidatedUser, u2: ValidatedUser) => {
+ const { email: e1 } = u1.user;
+ const { email: e2 } = u2.user;
+ return e1 < e2 ? -1 : e1 === e2 ? 0 : 1;
+ };
+
+ /**
+ * Sorting algorithm to sort groups.
+ */
+ sortGroups = (group1: Doc, group2: Doc) => {
+ const g1 = StrCast(group1.title);
+ const g2 = StrCast(group2.title);
+ return g1 < g2 ? -1 : g1 === g2 ? 0 : 1;
+ };
+ /**
+ * Returns the SharingPermissions (Admin, Can Edit etc) access that's used to share
+ */
+ private sharingOptions(uniform: boolean, showGuestOptions?: boolean) {
+ const dropdownValues: string[] = showGuestOptions ? [SharingPermissions.None, SharingPermissions.View] : Object.values(SharingPermissions);
+ if (!uniform) dropdownValues.unshift('-multiple-');
+ return dropdownValues.map(permission => (
+ <option key={permission} value={permission}>
+ {concat(ReverseHierarchyMap.get(permission)?.image, ' ', permission)}
+ </option>
+ ));
+ }
+
render() {
- return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive={true} dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.close} />;
+ return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} closeOnExternalClick={this.close} />;
}
}
diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts
index 40c3f76fb..1337d271f 100644
--- a/src/client/util/SnappingManager.ts
+++ b/src/client/util/SnappingManager.ts
@@ -1,7 +1,11 @@
-import { observable, action, runInAction, reaction, makeObservable } from 'mobx';
-import { Doc, Opt } from '../../fields/Doc';
+import { observable, action, runInAction, makeObservable } from 'mobx';
+export enum freeformScrollMode {
+ Pan = 'pan',
+ Zoom = 'zoom',
+}
export class SnappingManager {
+ // eslint-disable-next-line no-use-before-define
private static _manager: SnappingManager;
private static get Instance() {
return SnappingManager._manager ?? new SnappingManager();
@@ -9,20 +13,29 @@ export class SnappingManager {
@observable _shiftKey = false;
@observable _ctrlKey = false;
+ @observable _metaKey = false;
+ @observable _showPresPaths = false;
@observable _isLinkFollowing = false;
@observable _isDragging: boolean = false;
- @observable _isResizing: Doc | undefined = undefined;
+ @observable _isResizing: string | undefined = undefined; // the string is the Id of the document being resized
@observable _canEmbed: boolean = false;
@observable _horizSnapLines: number[] = [];
@observable _vertSnapLines: number[] = [];
@observable _exploreMode = false;
+ @observable _userPanned = false;
+ @observable _serverVersion: string = '';
+ @observable _lastBtnId: string = '';
+ @observable _propertyWid: number = 0;
+ @observable _printToConsole: boolean = false;
private constructor() {
SnappingManager._manager = this;
makeObservable(this);
}
- @action public static clearSnapLines = () => (this.Instance._vertSnapLines.length = this.Instance._horizSnapLines.length = 0);
+ @action public static clearSnapLines = () => {
+ this.Instance._vertSnapLines.length = this.Instance._horizSnapLines.length = 0;
+ };
@action public static addSnapLines = (horizLines: number[], vertLines: number[]) => {
this.Instance._horizSnapLines.push(...horizLines);
this.Instance._vertSnapLines.push(...vertLines);
@@ -32,16 +45,36 @@ export class SnappingManager {
public static get VertSnapLines() { return this.Instance._vertSnapLines; } // prettier-ignore
public static get ShiftKey() { return this.Instance._shiftKey; } // prettier-ignore
public static get CtrlKey() { return this.Instance._ctrlKey; } // prettier-ignore
+ public static get MetaKey() { return this.Instance._metaKey; } // prettier-ignore
+ public static get ShowPresPaths() { return this.Instance._showPresPaths; } // prettier-ignore
public static get IsLinkFollowing(){ return this.Instance._isLinkFollowing; } // prettier-ignore
public static get IsDragging() { return this.Instance._isDragging; } // prettier-ignore
public static get IsResizing() { return this.Instance._isResizing; } // prettier-ignore
public static get CanEmbed() { return this.Instance._canEmbed; } // prettier-ignore
public static get ExploreMode() { return this.Instance._exploreMode; } // prettier-ignore
- public static SetShiftKey = (down: boolean) => runInAction(() => (this.Instance._shiftKey = down)); // prettier-ignore
- public static SetCtrlKey = (down: boolean) => runInAction(() => (this.Instance._ctrlKey = down)); // prettier-ignore
- public static SetIsLinkFollowing= (follow: boolean) => runInAction(() => (this.Instance._isLinkFollowing = follow)); // prettier-ignore
- public static SetIsDragging = (drag: boolean) => runInAction(() => (this.Instance._isDragging = drag)); // prettier-ignore
- public static SetIsResizing = (doc: Opt<Doc>) => runInAction(() => (this.Instance._isResizing = doc)); // prettier-ignore
- public static SetCanEmbed = (embed:boolean) => runInAction(() => (this.Instance._canEmbed = embed)); // prettier-ignore
- public static SetExploreMode = (state:boolean) => runInAction(() => (this.Instance._exploreMode = state)); // prettier-ignore
+ public static get UserPanned() { return this.Instance._userPanned; } // prettier-ignore
+ public static get ServerVersion() { return this.Instance._serverVersion; } // prettier-ignore
+ public static get LastPressedBtn() { return this.Instance._lastBtnId; } // prettier-ignore
+ public static get PropertiesWidth(){ return this.Instance._propertyWid; } // prettier-ignore
+ public static get PrintToConsole() { return this.Instance._printToConsole; } // prettier-ignore
+
+ public static SetShiftKey = (down: boolean) => runInAction(() => {this.Instance._shiftKey = down}); // prettier-ignore
+ public static SetCtrlKey = (down: boolean) => runInAction(() => {this.Instance._ctrlKey = down}); // prettier-ignore
+ public static SetMetaKey = (down: boolean) => runInAction(() => {this.Instance._metaKey = down}); // prettier-ignore
+ public static SetShowPresPaths = (paths:boolean) => runInAction(() => {this.Instance._showPresPaths = paths}); // prettier-ignore
+ public static SetIsLinkFollowing= (follow:boolean)=> runInAction(() => {this.Instance._isLinkFollowing = follow}); // prettier-ignore
+ public static SetIsDragging = (drag: boolean) => runInAction(() => {this.Instance._isDragging = drag}); // prettier-ignore
+ public static SetIsResizing = (docid?:string) => runInAction(() => {this.Instance._isResizing = docid}); // prettier-ignore
+ public static SetCanEmbed = (embed:boolean) => runInAction(() => {this.Instance._canEmbed = embed}); // prettier-ignore
+ public static SetExploreMode = (state:boolean) => runInAction(() => {this.Instance._exploreMode = state}); // prettier-ignore
+ public static TriggerUserPanned = () => runInAction(() => {this.Instance._userPanned = !this.Instance._userPanned}); // prettier-ignore
+ public static SetServerVersion = (version:string) =>runInAction(() => {this.Instance._serverVersion = version}); // prettier-ignore
+ public static SetLastPressedBtn = (id:string) =>runInAction(() => {this.Instance._lastBtnId = id}); // prettier-ignore
+ public static SetPropertiesWidth= (wid:number) =>runInAction(() => {this.Instance._propertyWid = wid}); // prettier-ignore
+ public static SetPrintToConsole = (state:boolean) =>runInAction(() => {this.Instance._printToConsole = state}); // prettier-ignore
+
+ public static userColor: string | undefined;
+ public static userVariantColor: string | undefined;
+ public static userBackgroundColor: string | undefined;
+ public static SettingsStyle: any;
}
diff --git a/src/client/util/TrackMovements.ts b/src/client/util/TrackMovements.ts
index f9c2d522f..25a3c9ad8 100644
--- a/src/client/util/TrackMovements.ts
+++ b/src/client/util/TrackMovements.ts
@@ -1,8 +1,7 @@
-import { IReactionDisposer, makeObservable, observable, observe, reaction } from 'mobx';
+import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { NumCast } from '../../fields/Types';
import { Doc, DocListCast } from '../../fields/Doc';
import { CollectionDockingView } from '../views/collections/CollectionDockingView';
-import { Id } from '../../fields/FieldSymbols';
import { CollectionViewType } from '../documents/DocumentTypes';
export type Movement = {
@@ -33,6 +32,7 @@ export class TrackMovements {
private tabChangeDisposeFunc: IReactionDisposer | null;
// create static instance and getter for global use
+ // eslint-disable-next-line no-use-before-define
@observable static _instance: TrackMovements;
static get Instance(): TrackMovements {
return TrackMovements._instance;
@@ -92,12 +92,13 @@ export class TrackMovements {
// so that the size comparisons are correct, we must filter to only the FFViews
const isFFView = (doc: Doc) => doc && doc._type_collection === CollectionViewType.Freeform;
const tabbedFFViews = new Set<Doc>();
- for (const DashDoc of tabbedDocs) {
+ tabbedDocs.forEach(DashDoc => {
if (isFFView(DashDoc)) tabbedFFViews.add(DashDoc);
- }
+ });
// new tab was added - need to add it
if (tabbedFFViews.size > this.recordingFFViews.size) {
+ // eslint-disable-next-line no-restricted-syntax
for (const DashDoc of tabbedDocs) {
if (!this.recordingFFViews.has(DashDoc)) {
if (isFFView(DashDoc)) {
@@ -111,6 +112,7 @@ export class TrackMovements {
}
// tab was removed - need to remove it from recordingFFViews
else if (tabbedFFViews.size < this.recordingFFViews.size) {
+ // eslint-disable-next-line no-restricted-syntax
for (const [doc] of this.recordingFFViews) {
if (!tabbedFFViews.has(doc)) {
this.removeRecordingFFView(doc);
@@ -208,11 +210,11 @@ export class TrackMovements {
return;
}
- for (const [id, disposeFunc] of this.recordingFFViews) {
+ Array.from(this.recordingFFViews).forEach(([id, disposeFunc]) => {
// console.info('calling dispose func : docId', id);
disposeFunc();
- this.recordingFFViews.delete(id);
- }
+ this.recordingFFViews?.delete(id);
+ });
};
private trackMovement = (panX: number, panY: number, doc: Doc, scale: number = 0) => {
@@ -241,9 +243,9 @@ export class TrackMovements {
// method that concatenates an array of presentatations into one
public concatPresentations = (presentations: Presentation[]): Presentation => {
// these three will lead to the combined presentation
- let combinedMovements: Movement[] = [];
+ const combinedMovements: Movement[] = [];
let sumTime = 0;
- let combinedMetas: any[] = [];
+ const combinedMetas: any[] = [];
presentations.forEach(presentation => {
const { movements, totalTime, meta } = presentation;
@@ -251,9 +253,7 @@ export class TrackMovements {
// update movements if they had one
if (movements) {
// add the summed time to the movements
- const addedTimeMovements = movements.map(move => {
- return { ...move, time: move.time + sumTime };
- });
+ const addedTimeMovements = movements.map(move => ({ ...move, time: move.time + sumTime }));
// concat the movements already in the combined presentation with these new ones
combinedMovements.push(...addedTimeMovements);
}
diff --git a/src/client/util/Transform.ts b/src/client/util/Transform.ts
index dca37c960..1a07dd6ae 100644
--- a/src/client/util/Transform.ts
+++ b/src/client/util/Transform.ts
@@ -116,20 +116,14 @@ export class Transform {
preTransformed = (transform: Transform): Transform => this.copy().preTransform(transform);
- transformPoint = (x: number, y: number): [number, number] => {
- x *= this._scale;
- x += this._translateX;
- y *= this._scale;
- y += this._translateY;
- return [x, y];
- };
+ transformPoint = (x: number, y: number): [number, number] => [x * this._scale + this._translateX, y * this._scale + this._translateY];
transformDirection = (x: number, y: number): [number, number] => [x * this._scale, y * this._scale];
transformBounds(x: number, y: number, width: number, height: number): { x: number; y: number; width: number; height: number } {
- [x, y] = this.transformPoint(x, y);
- [width, height] = this.transformDirection(width, height);
- return { x, y, width, height };
+ const [tx, ty] = this.transformPoint(x, y);
+ const [twidth, theight] = this.transformDirection(width, height);
+ return { x: tx, y: ty, width: twidth, height: theight };
}
inverse = () => new Transform(-this._translateX / this._scale, -this._translateY / this._scale, 1 / this._scale, -this._rotate);
diff --git a/src/client/util/TypedEvent.ts b/src/client/util/TypedEvent.ts
index 90fd299c1..9ef2aa8d7 100644
--- a/src/client/util/TypedEvent.ts
+++ b/src/client/util/TypedEvent.ts
@@ -14,27 +14,27 @@ export class TypedEvent<T> {
on = (listener: Listener<T>): Disposable => {
this.listeners.push(listener);
return {
- dispose: () => this.off(listener)
+ dispose: () => this.off(listener),
};
- }
+ };
once = (listener: Listener<T>): void => {
this.listenersOncer.push(listener);
- }
+ };
off = (listener: Listener<T>) => {
const callbackIndex = this.listeners.indexOf(listener);
if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1);
- }
+ };
emit = (event: T) => {
/** Update any general listeners */
- this.listeners.forEach((listener) => listener(event));
+ this.listeners.forEach(listener => listener(event));
/** Clear the `once` queue */
- this.listenersOncer.forEach((listener) => listener(event));
+ this.listenersOncer.forEach(listener => listener(event));
this.listenersOncer = [];
- }
+ };
- pipe = (te: TypedEvent<T>): Disposable => this.on((e) => te.emit(e));
-} \ No newline at end of file
+ pipe = (te: TypedEvent<T>): Disposable => this.on(e => te.emit(e));
+}
diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts
index 421855bf3..534ffd2c8 100644
--- a/src/client/util/UndoManager.ts
+++ b/src/client/util/UndoManager.ts
@@ -1,7 +1,9 @@
-import { observable, action, runInAction } from 'mobx';
-import { Field } from '../../fields/Doc';
-import { RichTextField } from '../../fields/RichTextField';
+/* eslint-disable prefer-spread */
+/* eslint-disable no-use-before-define */
+import { action, observable, runInAction } from 'mobx';
import { Without } from '../../Utils';
+import { RichTextField } from '../../fields/RichTextField';
+import { SnappingManager } from './SnappingManager';
function getBatchName(target: any, key: string | symbol): string {
const keyName = key.toString();
@@ -37,10 +39,11 @@ function propertyDecorator(target: any, key: string | symbol) {
}
export function undoable(fn: (...args: any[]) => any, batchName: string): (...args: any[]) => any {
- return function () {
+ return function (...fargs) {
const batch = UndoManager.StartBatch(batchName);
try {
- return fn.apply(undefined, arguments as any);
+ // eslint-disable-next-line prefer-rest-params
+ return fn.apply(undefined, fargs);
} finally {
batch.end();
}
@@ -48,13 +51,15 @@ export function undoable(fn: (...args: any[]) => any, batchName: string): (...ar
}
export function undoBatch(target: any, key: string | symbol, descriptor?: TypedPropertyDescriptor<any>): any;
+// eslint-disable-next-line no-redeclare
export function undoBatch(fn: (...args: any[]) => any): (...args: any[]) => any;
+// eslint-disable-next-line no-redeclare
export function undoBatch(target: any, key?: string | symbol, descriptor?: TypedPropertyDescriptor<any>): any {
if (!key) {
- return function () {
+ return function (...fargs: any[]) {
const batch = UndoManager.StartBatch('');
try {
- return target.apply(undefined, arguments);
+ return target.apply(undefined, fargs);
} finally {
batch.end();
}
@@ -62,7 +67,7 @@ export function undoBatch(target: any, key?: string | symbol, descriptor?: Typed
}
if (!descriptor) {
propertyDecorator(target, key);
- return;
+ return undefined;
}
const oldFunction = descriptor.value;
@@ -86,24 +91,29 @@ export namespace UndoManager {
}
type UndoBatch = UndoEvent[];
- export let undoStackNames: string[] = observable([]);
- export let redoStackNames: string[] = observable([]);
- export let undoStack: UndoBatch[] = observable([]);
- export let redoStack: UndoBatch[] = observable([]);
let currentBatch: UndoBatch | undefined;
- export let batchCounter = observable.box(0);
let undoing = false;
- export let tempEvents: UndoEvent[] | undefined = undefined;
+ let tempEvents: UndoEvent[] | undefined;
+ export const undoStackNames: string[] = observable([]);
+ export const redoStackNames: string[] = observable([]);
+ export const undoStack: UndoBatch[] = observable([]);
+ export const redoStack: UndoBatch[] = observable([]);
+ export const batchCounter = observable.box(0);
+ let _fieldPrinter: (val: any) => string = val => val?.toString();
+ export function SetFieldPrinter(printer: (val: any) => string) {
+ _fieldPrinter = printer;
+ }
export function AddEvent(event: UndoEvent, value?: any): void {
if (currentBatch && batchCounter.get() && !undoing) {
- console.log(
- ' '.slice(0, batchCounter.get()) +
- 'UndoEvent : ' +
- event.prop +
- ' = ' +
- (value instanceof RichTextField ? value.Text : value instanceof Array ? value.map(val => Field.toJavascriptString(val)).join(',') : Field.toJavascriptString(value))
- );
+ SnappingManager.PrintToConsole &&
+ console.log(
+ ' '.slice(0, batchCounter.get()) +
+ 'UndoEvent : ' +
+ event.prop +
+ ' = ' + // prettier-ignore
+ (value instanceof RichTextField ? value.Text : value instanceof Array ? value.map(_fieldPrinter).join(',') : _fieldPrinter(value))
+ );
currentBatch.push(event);
tempEvents?.push(event);
}
@@ -128,21 +138,22 @@ export namespace UndoManager {
}
export function FilterBatches(fieldTypes: string[]) {
const fieldCounts: { [key: string]: number } = {};
- const lastStack = UndoManager.undoStack.slice(-1)[0]; //.lastElement();
+ const lastStack = UndoManager.undoStack.slice(-1)[0]; // .lastElement();
if (lastStack) {
- lastStack.forEach(ev => fieldTypes.includes(ev.prop) && (fieldCounts[ev.prop] = (fieldCounts[ev.prop] || 0) + 1));
+ lastStack.forEach(ev => {
+ fieldTypes.includes(ev.prop) && (fieldCounts[ev.prop] = (fieldCounts[ev.prop] || 0) + 1);
+ });
const fieldCount2: { [key: string]: number } = {};
- runInAction(
- () =>
- (UndoManager.undoStack[UndoManager.undoStack.length - 1] = lastStack.filter(ev => {
- if (fieldTypes.includes(ev.prop)) {
- fieldCount2[ev.prop] = (fieldCount2[ev.prop] || 0) + 1;
- if (fieldCount2[ev.prop] === 1 || fieldCount2[ev.prop] === fieldCounts[ev.prop]) return true;
- return false;
- }
- return true;
- }))
- );
+ runInAction(() => {
+ UndoManager.undoStack[UndoManager.undoStack.length - 1] = lastStack.filter(ev => {
+ if (fieldTypes.includes(ev.prop)) {
+ fieldCount2[ev.prop] = (fieldCount2[ev.prop] || 0) + 1;
+ if (fieldCount2[ev.prop] === 1 || fieldCount2[ev.prop] === fieldCounts[ev.prop]) return true;
+ return false;
+ }
+ return true;
+ });
+ });
}
}
export function TraceOpenBatches() {
@@ -159,11 +170,10 @@ export namespace UndoManager {
if (this.disposed) {
console.log('WARNING: undo batch already disposed');
return false;
- } else {
- this.disposed = true;
- openBatches.splice(openBatches.indexOf(this));
- return EndBatch(this.batchName, cancel);
}
+ this.disposed = true;
+ openBatches.splice(openBatches.indexOf(this));
+ return EndBatch(this.batchName, cancel);
};
end = () => this.dispose(false);
@@ -171,7 +181,7 @@ export namespace UndoManager {
}
export function StartBatch(batchName: string): Batch {
- console.log(' '.slice(0, batchCounter.get()) + 'Start ' + batchCounter + ' ' + batchName);
+ SnappingManager.PrintToConsole && console.log(' '.slice(0, batchCounter.get()) + 'Start ' + batchCounter + ' ' + batchName);
runInAction(() => batchCounter.set(batchCounter.get() + 1));
if (currentBatch === undefined) {
currentBatch = [];
@@ -181,7 +191,7 @@ export namespace UndoManager {
const EndBatch = action((batchName: string, cancel: boolean = false) => {
runInAction(() => batchCounter.set(batchCounter.get() - 1));
- console.log(' '.slice(0, batchCounter.get()) + 'End ' + batchName + ' (' + currentBatch?.length + ')');
+ SnappingManager.PrintToConsole && console.log(' '.slice(0, batchCounter.get()) + 'End ' + batchName + ' (' + (currentBatch?.length ?? 0) + ')');
if (batchCounter.get() === 0 && currentBatch?.length) {
if (!cancel) {
undoStack.push(currentBatch);
@@ -198,10 +208,10 @@ export namespace UndoManager {
export function StartTempBatch() {
tempEvents = [];
}
- export function EndTempBatch<T>(success: boolean) {
+ export function EndTempBatch(success: boolean) {
UndoManager.UndoTempBatch(success);
}
- //TODO Make this return the return value
+ // TODO Make this return the return value
export function RunInBatch<T>(fn: () => T, batchName: string) {
const batch = StartBatch(batchName);
try {
@@ -233,9 +243,11 @@ export namespace UndoManager {
}
undoing = true;
- for (let i = commands.length - 1; i >= 0; i--) {
- commands[i].undo();
- }
+ // eslint-disable-next-line prettier/prettier
+ commands
+ .slice()
+ .reverse()
+ .forEach(command => command.undo());
undoing = false;
redoStackNames.push(names ?? '???');
@@ -254,9 +266,7 @@ export namespace UndoManager {
}
undoing = true;
- for (const command of commands) {
- command.redo();
- }
+ commands.forEach(command => command.redo());
undoing = false;
undoStackNames.push(names ?? '???');
diff --git a/src/client/util/bezierFit.ts b/src/client/util/bezierFit.ts
index 8fc6de6f9..d6f3f2340 100644
--- a/src/client/util/bezierFit.ts
+++ b/src/client/util/bezierFit.ts
@@ -1,4 +1,8 @@
-import { Point } from "../../pen-gestures/ndollar";
+/* eslint-disable no-use-before-define */
+/* eslint-disable prefer-destructuring */
+/* eslint-disable no-param-reassign */
+/* eslint-disable camelcase */
+import { Point } from '../../pen-gestures/ndollar';
class SmartRect {
minx: number = 0;
@@ -6,20 +10,43 @@ class SmartRect {
maxx: number = 0;
maxy: number = 0;
- constructor(mix: number = 0, miy: number = 0, max: number = 0, may: number = 0) { this.minx = mix; this.miny = miy; this.maxx = max; this.maxy = may; }
+ constructor(mix: number = 0, miy: number = 0, max: number = 0, may: number = 0) {
+ this.minx = mix;
+ this.miny = miy;
+ this.maxx = max;
+ this.maxy = may;
+ }
- public get Center() { return new Point((this.maxx + this.minx) / 2.0, (this.maxy + this.miny) / 2.0); }
- public get TopLeft() { return new Point(this.minx, this.miny); }
- public get TopRight() { return new Point(this.maxx, this.miny); }
- public get BotLeft() { return new Point(this.minx, this.maxy); }
- public get BotRight() { return new Point(this.maxx, this.maxy); }
- public get Width() { return this.maxx - this.minx; }
- public get Height() { return this.maxy - this.miny; }
- public static Intersect(a: SmartRect, b: SmartRect) { return a.Intersect(b); }
- public Intersect(b: SmartRect) { return !((this.minx > b.maxx) || (this.miny > b.maxy) || (b.minx > this.maxx) || (b.miny > this.maxy)); }
+ public get Center() {
+ return new Point((this.maxx + this.minx) / 2.0, (this.maxy + this.miny) / 2.0);
+ }
+ public get TopLeft() {
+ return new Point(this.minx, this.miny);
+ }
+ public get TopRight() {
+ return new Point(this.maxx, this.miny);
+ }
+ public get BotLeft() {
+ return new Point(this.minx, this.maxy);
+ }
+ public get BotRight() {
+ return new Point(this.maxx, this.maxy);
+ }
+ public get Width() {
+ return this.maxx - this.minx;
+ }
+ public get Height() {
+ return this.maxy - this.miny;
+ }
+ public static Intersect(a: SmartRect, b: SmartRect) {
+ return a.Intersect(b);
+ }
+ public Intersect(b: SmartRect) {
+ return !(this.minx > b.maxx || this.miny > b.maxy || b.minx > this.maxx || b.miny > this.maxy);
+ }
public ContainsPercentage(other: SmartRect, axis: Point) {
- var ret = 0;
+ let ret = 0;
const minx = Math.max(other.TopLeft.X * axis.X + other.TopLeft.Y * axis.Y, this.TopLeft.X * axis.X + this.TopLeft.Y * axis.Y);
const maxx = Math.max(other.BotRight.X * axis.X + other.BotRight.Y * axis.Y, this.BotRight.X * axis.X + this.BotRight.Y * axis.Y);
ret = maxx > minx ? (maxx - minx) / (axis === new Point(1, 0) ? other.Width : other.Height) : 0;
@@ -36,7 +63,7 @@ class SmartRect {
if (r.minx > r.maxx) [r.minx, r.maxx] = [r.maxx, r.minx];
if (r.miny > r.maxy) [r.miny, r.maxy] = [r.maxy, r.miny];
- for (const pt of p) {
+ p.forEach(pt => {
if (pt.X < r.minx) {
r.minx = pt.X;
} else if (pt.X > r.maxx) {
@@ -47,7 +74,7 @@ class SmartRect {
} else if (pt.Y > r.maxy) {
r.maxy = pt.Y;
}
- }
+ });
}
return r;
}
@@ -64,18 +91,18 @@ export function Normalize(p: Point) {
function ReparameterizeBezier(d: Point[], first: number, last: number, u: number[], bezCurve: Point[]) {
const uPrime = new Array<number>(last - first + 1); // New parameter values
- for (var i = first; i <= last; i++) {
+ for (let i = first; i <= last; i++) {
uPrime[i - first] = NewtonRaphsonRootFind(bezCurve, d[i], u[i - first]);
}
return uPrime;
}
function ComputeMaxError(d: Point[], first: number, last: number, bezCurve: Point[], u: number[]) {
- var maxError = 0; // Maximum error
- var splitPoint2D = (last - first + 1) / 2;
- for (var i = first + 1; i < last; i++) {
- const P = [0, 0]; // point on curve
+ let maxError = 0; // Maximum error
+ let splitPoint2D = (last - first + 1) / 2;
+ for (let i = first + 1; i < last; i++) {
+ const P = [0, 0]; // point on curve
EvalBezierFast(bezCurve, u[i - first], P);
- const dx = P[0] - d[i].X;// offset from point to curve
+ const dx = P[0] - d[i].X; // offset from point to curve
const dy = P[1] - d[i].Y;
const dist = Math.sqrt(dx * dx + dy * dy); // Current error
if (dist >= maxError) {
@@ -88,11 +115,11 @@ function ComputeMaxError(d: Point[], first: number, last: number, bezCurve: Poin
return { maxError, splitPoint2D };
}
function ChordLengthParameterize(d: Point[], first: number, last: number) {
- const u = new Array<number>(last - first + 1);// Parameterization
+ const u = new Array<number>(last - first + 1); // Parameterization
- var prev = 0.0;
+ let prev = 0.0;
u[0] = prev;
- for (var i = first + 1; i <= last; i++) {
+ for (let i = first + 1; i <= last; i++) {
const lastd = d[i - 1];
const curd = d[i];
const dx = lastd.X - curd.X;
@@ -101,27 +128,38 @@ function ChordLengthParameterize(d: Point[], first: number, last: number) {
}
const ulastfirst = u[last - first];
- for (var i = first + 1; i <= last; i++) {
+ for (let i = first + 1; i <= last; i++) {
u[i - first] /= ulastfirst;
}
return u;
}
/*
-* B0, B1, B2, B3 :
-* Bezier multipliers
-*/
-function B0(u: number) { const tmp = 1.0 - u; return tmp * tmp * tmp; }
-function B1(u: number) { const tmp = 1.0 - u; return 3 * u * tmp * tmp; }
-function B2(u: number) { const tmp = 1.0 - u; return 3 * u * u * tmp; }
-function B3(u: number) { return u * u * u; }
+ * B0, B1, B2, B3 :
+ * Bezier multipliers
+ */
+function B0(u: number) {
+ const tmp = 1.0 - u;
+ return tmp * tmp * tmp;
+}
+function B1(u: number) {
+ const tmp = 1.0 - u;
+ return 3 * u * tmp * tmp;
+}
+function B2(u: number) {
+ const tmp = 1.0 - u;
+ return 3 * u * u * tmp;
+}
+function B3(u: number) {
+ return u * u * u;
+}
function bounds(p: Point[]) {
const r = new SmartRect(p[0].X, p[0].Y, p[3].X, p[3].Y); // These are the most likely to be extremal
- if (r.minx > r.maxx) (r.minx, r.maxx);
+ if (r.minx > r.maxx) [r.minx, r.maxx] = [r.maxx, r.minx];
if (r.miny > r.maxy) [r.miny, r.maxy] = [r.maxy, r.miny]; // swap min & max
- for (var i = 1; i < 3; i++) {
+ for (let i = 1; i < 3; i++) {
if (p[i].X < r.minx) r.minx = p[i].X;
else if (p[i].X > r.maxx) r.maxx = p[i].X;
@@ -131,37 +169,36 @@ function bounds(p: Point[]) {
return r;
}
-
function splitCubic(p: Point[], t: number, left: Point[], right: Point[]) {
const sz = 4;
const Vtemp = new Array<Array<Point>>(4);
- for (var i = 0; i < 4; i++) Vtemp[i] = new Array<Point>(4);
+ for (let i = 0; i < 4; i++) Vtemp[i] = new Array<Point>(4);
/* Copy control points */
// std::copy(p.begin(), p.end(), Vtemp[0]);
- for (var i = 0; i < sz; i++) {
+ for (let i = 0; i < sz; i++) {
Vtemp[0][i].X = p[i].X;
Vtemp[0][i].Y = p[i].Y;
}
/* Triangle computation */
- for (var i = 1; i < sz; i++) {
- for (var j = 0; j < sz - i; j++) {
+ for (let i = 1; i < sz; i++) {
+ for (let j = 0; j < sz - i; j++) {
const a = Vtemp[i - 1][j];
const b = Vtemp[i - 1][j + 1];
Vtemp[i][j].X = b.X * t + a.X * (1 - t);
- Vtemp[i][j].Y = b.Y * t + a.Y * (1 - t); // Vtemp[i][j] = Point2D::Lerp(Vtemp[i - 1][j], Vtemp[i - 1][j + 1], t);
+ Vtemp[i][j].Y = b.Y * t + a.Y * (1 - t); // Vtemp[i][j] = Point2D::Lerp(Vtemp[i - 1][j], Vtemp[i - 1][j + 1], t);
}
}
if (left) {
- for (var j = 0; j < sz; j++) {
+ for (let j = 0; j < sz; j++) {
left[j].X = Vtemp[j][0].X;
left[j].Y = Vtemp[j][0].Y;
}
}
if (right) {
- for (var j = 0; j < sz; j++) {
+ for (let j = 0; j < sz; j++) {
right[j].X = Vtemp[sz - 1 - j][j].X;
right[j].Y = Vtemp[sz - 1 - j][j].Y;
}
@@ -169,51 +206,54 @@ function splitCubic(p: Point[], t: number, left: Point[], right: Point[]) {
}
/*
-* Recursively intersect two curves keeping track of their real parameters
-* and depths of intersection.
-* The results are returned in a 2-D array of doubles indicating the parameters
-* for which intersections are found. The parameters are in the order the
-* intersections were found, which is probably not in sorted order.
-* When an intersection is found, the parameter value for each of the two
-* is stored in the index elements array, and the index is incremented.
-*
-* If either of the curves has subdivisions left before it is straight
-* (depth > 0)
-* that curve (possibly both) is (are) subdivided at its (their) midpoint(s).
-* the depth(s) is (are) decremented, and the parameter value(s) corresponding
-* to the midpoints(s) is (are) computed.
-* Then each of the subcurves of one curve is intersected with each of the
-* subcurves of the other curve, first by testing the bounding boxes for
-* interference. If there is any bounding box interference, the corresponding
-* subcurves are recursively intersected.
-*
-* If neither curve has subdivisions left, the line segments from the first
-* to last control point of each segment are intersected. (Actually the
-* only the parameter value corresponding to the intersection point is found).
-*
-* The apriori flatness test is probably more efficient than testing at each
-* level of recursion, although a test after three or four levels would
-* probably be worthwhile, since many curves become flat faster than their
-* asymptotic rate for the first few levels of recursion.
-*
-* The bounding box test fails much more frequently than it succeeds, providing
-* substantial pruning of the search space.
-*
-* Each (sub)curve is subdivided only once, hence it is not possible that for
-* one final line intersection test the subdivision was at one level, while
-* for another final line intersection test the subdivision (of the same curve)
-* was at another. Since the line segments share endpoints, the intersection
-* is robust: a near-tangential intersection will yield zero or two
-* intersections.
-*/
+ * Recursively intersect two curves keeping track of their real parameters
+ * and depths of intersection.
+ * The results are returned in a 2-D array of doubles indicating the parameters
+ * for which intersections are found. The parameters are in the order the
+ * intersections were found, which is probably not in sorted order.
+ * When an intersection is found, the parameter value for each of the two
+ * is stored in the index elements array, and the index is incremented.
+ *
+ * If either of the curves has subdivisions left before it is straight
+ * (depth > 0)
+ * that curve (possibly both) is (are) subdivided at its (their) midpoint(s).
+ * the depth(s) is (are) decremented, and the parameter value(s) corresponding
+ * to the midpoints(s) is (are) computed.
+ * Then each of the subcurves of one curve is intersected with each of the
+ * subcurves of the other curve, first by testing the bounding boxes for
+ * interference. If there is any bounding box interference, the corresponding
+ * subcurves are recursively intersected.
+ *
+ * If neither curve has subdivisions left, the line segments from the first
+ * to last control point of each segment are intersected. (Actually the
+ * only the parameter value corresponding to the intersection point is found).
+ *
+ * The apriori flatness test is probably more efficient than testing at each
+ * level of recursion, although a test after three or four levels would
+ * probably be worthwhile, since many curves become flat faster than their
+ * asymptotic rate for the first few levels of recursion.
+ *
+ * The bounding box test fails much more frequently than it succeeds, providing
+ * substantial pruning of the search space.
+ *
+ * Each (sub)curve is subdivided only once, hence it is not possible that for
+ * one final line intersection test the subdivision was at one level, while
+ * for another final line intersection test the subdivision (of the same curve)
+ * was at another. Since the line segments share endpoints, the intersection
+ * is robust: a near-tangential intersection will yield zero or two
+ * intersections.
+ */
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
function recursively_intersect(a: Point[], t0: number, t1: number, deptha: number, b: Point[], u0: number, u1: number, depthb: number, parameters: number[][]) {
if (deptha > 0) {
- const a1 = new Array<Point>(4), a2 = new Array<Point>(4);
+ const a1 = new Array<Point>(4);
+ const a2 = new Array<Point>(4);
splitCubic(a, 0.5, a1, a2);
const tmid = (t0 + t1) * 0.5;
deptha--;
if (depthb > 0) {
- const b1 = new Array<Point>(4), b2 = new Array<Point>(4);
+ const b1 = new Array<Point>(4);
+ const b2 = new Array<Point>(4);
splitCubic(b, 0.5, b1, b2);
const umid = (u0 + u1) * 0.5;
depthb--;
@@ -229,8 +269,7 @@ function recursively_intersect(a: Point[], t0: number, t1: number, deptha: numbe
if (SmartRect.Intersect(bounds(a2), bounds(b2))) {
recursively_intersect(a2, tmid, t1, deptha, b2, umid, u1, depthb, parameters);
}
- }
- else {
+ } else {
if (SmartRect.Intersect(bounds(a1), bounds(b))) {
recursively_intersect(a1, t0, tmid, deptha, b, u0, u1, depthb, parameters);
}
@@ -238,50 +277,45 @@ function recursively_intersect(a: Point[], t0: number, t1: number, deptha: numbe
recursively_intersect(a2, tmid, t1, deptha, b, u0, u1, depthb, parameters);
}
}
- }
+ } else if (depthb > 0) {
+ const b1 = new Array<Point>(4);
+ const b2 = new Array<Point>(4);
+ splitCubic(b, 0.5, b1, b2);
+ const umid = (u0 + u1) * 0.5;
+ depthb--;
+ if (SmartRect.Intersect(bounds(a), bounds(b1))) {
+ recursively_intersect(a, t0, t1, deptha, b1, u0, umid, depthb, parameters);
+ }
+ if (SmartRect.Intersect(bounds(a), bounds(b2))) {
+ recursively_intersect(a, t0, t1, deptha, b2, umid, u1, depthb, parameters);
+ }
+ } // Both segments are fully subdivided; now do line segments
else {
- if (depthb > 0) {
- const b1 = new Array<Point>(4), b2 = new Array<Point>(4);
- splitCubic(b, 0.5, b1, b2);
- const umid = (u0 + u1) * 0.5;
- depthb--;
- if (SmartRect.Intersect(bounds(a), bounds(b1))) {
- recursively_intersect(a, t0, t1, deptha, b1, u0, umid, depthb, parameters);
- }
- if (SmartRect.Intersect(bounds(a), bounds(b2))) {
- recursively_intersect(a, t0, t1, deptha, b2, umid, u1, depthb, parameters);
- }
+ const xlk = a[3].X - a[0].X;
+ const ylk = a[3].Y - a[0].Y;
+ const xnm = b[3].X - b[0].X;
+ const ynm = b[3].Y - b[0].Y;
+ const xmk = b[0].X - a[0].X;
+ const ymk = b[0].Y - a[0].Y;
+ const det = xnm * ylk - ynm * xlk;
+ if (1.0 + det === 1.0) {
+ return;
}
- else // Both segments are fully subdivided; now do line segments
- {
- const xlk = a[3].X - a[0].X;
- const ylk = a[3].Y - a[0].Y;
- const xnm = b[3].X - b[0].X;
- const ynm = b[3].Y - b[0].Y;
- const xmk = b[0].X - a[0].X;
- const ymk = b[0].Y - a[0].Y;
- const det = xnm * ylk - ynm * xlk;
- if (1.0 + det === 1.0) {
- return;
- }
- else {
- const detinv = 1.0 / det;
- const s = (xnm * ymk - ynm * xmk) * detinv;
- const t = (xlk * ymk - ylk * xmk) * detinv;
- if ((s < 0.0) || (s > 1.0) || (t < 0.0) || (t > 1.0) || Number.isNaN(s) || Number.isNaN(t)) {
- return;
- }
- parameters.push([t0 + s * (t1 - t0), u0 + t * (u1 - u0)]);
- }
+ const detinv = 1.0 / det;
+ const s = (xnm * ymk - ynm * xmk) * detinv;
+ const t = (xlk * ymk - ylk * xmk) * detinv;
+ if (s < 0.0 || s > 1.0 || t < 0.0 || t > 1.0 || isNaN(s) || isNaN(t)) {
+ return;
}
+ parameters.push([t0 + s * (t1 - t0), u0 + t * (u1 - u0)]);
}
}
/*
-* EvalBezier :
-* Evaluate a Bezier curve at a particular parameter value
-*
-*/
+ * EvalBezier :
+ * Evaluate a Bezier curve at a particular parameter value
+ *
+ */
const MAX_DEGREE = 5;
function EvalBezier(V: Point[], degree: number, t: number, result: number[]) {
if (degree + 1 > MAX_DEGREE) {
@@ -293,35 +327,36 @@ function EvalBezier(V: Point[], degree: number, t: number, result: number[]) {
const Vtemp = [new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)]; // Local copy of control points
/* Copy array */
- for (var i = 0; i <= degree; i++) {
+ for (let i = 0; i <= degree; i++) {
Vtemp[i].X = V[i].X;
Vtemp[i].Y = V[i].Y;
}
/* Triangle computation */
- for (var i = 1; i <= degree; i++) {
- for (var j = 0; j <= degree - i; j++) {
+ for (let i = 1; i <= degree; i++) {
+ for (let j = 0; j <= degree - i; j++) {
Vtemp[j].X = (1.0 - t) * Vtemp[j].X + t * Vtemp[j + 1].X;
Vtemp[j].Y = (1.0 - t) * Vtemp[j].Y + t * Vtemp[j + 1].Y;
}
}
result[0] = Vtemp[0].X;
- result[1] = Vtemp[0].Y;// Point on curve at parameter t
+ result[1] = Vtemp[0].Y; // Point on curve at parameter t
}
function EvalBezierFast(p: Point[], t: number, result: number[]) {
const n = 3;
const u = 1.0 - t;
- var bc = 1, tn = 1;
- var tmpX = p[0].X * u;
- var tmpY = p[0].Y * u;
- tn = tn * t;
- bc = bc * (n - 1 + 1) / 1;
+ let bc = 1;
+ let tn = 1;
+ let tmpX = p[0].X * u;
+ let tmpY = p[0].Y * u;
+ tn *= t;
+ bc = (bc * (n - 1 + 1)) / 1;
tmpX = (tmpX + tn * bc * p[1].X) * u;
tmpY = (tmpY + tn * bc * p[1].Y) * u;
- tn = tn * t;
- bc = bc * (n - 2 + 1) / 2;
+ tn *= t;
+ bc = (bc * (n - 2 + 1)) / 2;
tmpX = (tmpX + tn * bc * p[2].X) * u;
tmpY = (tmpY + tn * bc * p[2].Y) * u;
@@ -329,9 +364,9 @@ function EvalBezierFast(p: Point[], t: number, result: number[]) {
result[1] = tmpY + tn * t * p[3].Y;
}
/*
-* ComputeLeftTangent, ComputeRightTangent, ComputeCenterTangent :
-*Approximate unit tangents at endpoints and "center" of digitized curve
-*/
+ * ComputeLeftTangent, ComputeRightTangent, ComputeCenterTangent :
+ *Approximate unit tangents at endpoints and "center" of digitized curve
+ */
function ComputeLeftTangent(d: Point[], end: number) {
const use = 1;
const tHat1 = new Point(d[end + use].X - d[end].X, d[end + use].Y - d[end].Y);
@@ -348,19 +383,19 @@ function ComputeCenterTangent(d: Point[], center: number) {
}
const V1 = ComputeLeftTangent(d, center); // d[center] - d[center-1];
const V2 = ComputeRightTangent(d, center); // d[center] - d[center + 1];
- var tHatCenter = new Point((-V1.X + V2.X) / 2.0, (-V1.Y + V2.Y) / 2.0);
+ let tHatCenter = new Point((-V1.X + V2.X) / 2.0, (-V1.Y + V2.Y) / 2.0);
if (tHatCenter === new Point(0, 0)) {
- tHatCenter = new Point(-V1.Y, -V1.X);// V1.Perp();
+ tHatCenter = new Point(-V1.Y, -V1.X); // V1.Perp();
}
return Normalize(tHatCenter);
}
function GenerateBezier(d: Point[], first: number, last: number, uPrime: number[], tHat1: Point, tHat2: Point, result: Point[] /* must be prealloacted to size 4 */) {
const nPts = last - first + 1; // Number of pts in sub-curve
- const Ax = new Array<number>(nPts * 2);// Precomputed rhs for eqn //std::vector<Vector2D> A(nPts * 2);
- const Ay = new Array<number>(nPts * 2);// Precomputed rhs for eqn //std::vector<Vector2D> A(nPts * 2);
+ const Ax = new Array<number>(nPts * 2); // Precomputed rhs for eqn //std::vector<Vector2D> A(nPts * 2);
+ const Ay = new Array<number>(nPts * 2); // Precomputed rhs for eqn //std::vector<Vector2D> A(nPts * 2);
/* Compute the A's */
- for (var i = 0; i < nPts; i++) {
+ for (let i = 0; i < nPts; i++) {
const uprime = uPrime[i];
const b1 = B1(uprime);
const b2 = B2(uprime);
@@ -371,39 +406,42 @@ function GenerateBezier(d: Point[], first: number, last: number, uPrime: number[
}
/* Create the C and X matrices */
- const C = [[0, 0], [0, 0]];
+ const C = [
+ [0, 0],
+ [0, 0],
+ ];
const df = d[first];
const dl = d[last];
- const X = [0, 0]; // Matrix X
- for (var i = 0; i < nPts; i++) {
- C[0][0] += Ax[i] * Ax[i] + Ay[i] * Ay[i]; //A[i+0*nPts].Dot(A[i+0*nPts]);
- C[0][1] += Ax[i] * Ax[i + nPts] + Ay[i] * Ay[i + nPts];//A[i+0*nPts].Dot(A[i+1*nPts]);
+ const X = [0, 0]; // Matrix X
+ for (let i = 0; i < nPts; i++) {
+ C[0][0] += Ax[i] * Ax[i] + Ay[i] * Ay[i]; // A[i+0*nPts].Dot(A[i+0*nPts]);
+ C[0][1] += Ax[i] * Ax[i + nPts] + Ay[i] * Ay[i + nPts]; // A[i+0*nPts].Dot(A[i+1*nPts]);
C[1][0] = C[0][1];
- C[1][1] += Ax[i + nPts] * Ax[i + nPts] + Ay[i + nPts] * Ay[i + nPts];// A[i+1*nPts].Dot(A[i+1*nPts]);
+ C[1][1] += Ax[i + nPts] * Ax[i + nPts] + Ay[i + nPts] * Ay[i + nPts]; // A[i+1*nPts].Dot(A[i+1*nPts]);
const uprime = uPrime[i];
const b0plb1 = B0(uprime) + B1(uprime);
const b2plb3 = B2(uprime) + B3(uprime);
const df1 = d[first + i];
- const tmpX = df1.X - (df.X * b0plb1 + (dl.X * b2plb3));
- const tmpY = df1.Y - (df.Y * b0plb1 + (dl.Y * b2plb3));
+ const tmpX = df1.X - (df.X * b0plb1 + dl.X * b2plb3);
+ const tmpY = df1.Y - (df.Y * b0plb1 + dl.Y * b2plb3);
X[0] += Ax[i] * tmpX + Ay[i] * tmpY; // A[i+0*nPts].Dot(tmp)
- X[1] += Ax[i + nPts] * tmpX + Ay[i + nPts] * tmpY; //A[i+1*nPts].Dot(tmp)
+ X[1] += Ax[i + nPts] * tmpX + Ay[i + nPts] * tmpY; // A[i+1*nPts].Dot(tmp)
}
/* Compute the determinants of C and X */
- const det_C0_C1 = (C[0][0] * C[1][1] - C[1][0] * C[0][1]) || (C[0][0] * C[1][1]) * 10e-12;
+ const det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1] || C[0][0] * C[1][1] * 10e-12;
const det_C0_X = C[0][0] * X[1] - C[0][1] * X[0];
const det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1];
/* Finally, derive alpha values */
- var alpha_l = (det_C0_C1 === 0) ? 0.0 : det_X_C1 / det_C0_C1;
- var alpha_r = (det_C0_C1 === 0) ? 0.0 : det_C0_X / det_C0_C1;
+ let alpha_l = det_C0_C1 === 0 ? 0.0 : det_X_C1 / det_C0_C1;
+ let alpha_r = det_C0_C1 === 0 ? 0.0 : det_C0_X / det_C0_C1;
/* If alpha negative, use the Wu/Barsky heuristic (see text) */
/* (if alpha is 0, you get coincident control points that lead to
- * divide by zero in any subsequent NewtonRaphsonRootFind() call. */
+ * divide by zero in any subsequent NewtonRaphsonRootFind() call. */
const segLength = Math.sqrt((df.X - dl.X) * (df.X - dl.X) + (df.Y - dl.Y) * (df.Y - dl.Y));
const epsilon = 1.0e-6 * segLength;
if (alpha_l < epsilon || alpha_r < epsilon) {
@@ -415,10 +453,10 @@ function GenerateBezier(d: Point[], first: number, last: number, uPrime: number[
/* positioned exactly at the first and last data points */
/* Control points 1 and 2 are positioned an alpha distance out */
/* on the tangent vectors, left and right, respectively */
- result[0] = df;// RETURN bezier curve ctl pts
+ result[0] = df; // RETURN bezier curve ctl pts
result[3] = dl;
- result[1] = new Point(df.X + (tHat1.X * alpha_l), df.Y + (tHat1.Y * alpha_l));
- result[2] = new Point(dl.X + (tHat2.X * alpha_r), dl.Y + (tHat2.Y * alpha_r));
+ result[1] = new Point(df.X + tHat1.X * alpha_l, df.Y + tHat1.Y * alpha_l);
+ result[2] = new Point(dl.X + tHat2.X * alpha_r, dl.Y + tHat2.Y * alpha_r);
}
/*
@@ -426,21 +464,24 @@ function GenerateBezier(d: Point[], first: number, last: number, uPrime: number[
* Use Newton-Raphson iteration to find better root.
*/
function NewtonRaphsonRootFind(Q: Point[], P: Point, u: number) {
- const Q1 = [new Point(0, 0), new Point(0, 0), new Point(0, 0)], Q2 = [new Point(0, 0), new Point(0, 0)]; // Q' and Q''
- const Q_u = [0, 0], Q1_u = [0, 0], Q2_u = [0, 0]; //u evaluated at Q, Q', & Q''
+ const Q1 = [new Point(0, 0), new Point(0, 0), new Point(0, 0)];
+ const Q2 = [new Point(0, 0), new Point(0, 0)]; // Q' and Q''
+ const Q_u = [0, 0];
+ const Q1_u = [0, 0];
+ const Q2_u = [0, 0]; // u evaluated at Q, Q', & Q''
/* Compute Q(u) */
- var uPrime: number; // Improved u
+ let uPrime: number; // Improved u
EvalBezierFast(Q, u, Q_u);
/* Generate control vertices for Q' */
- for (var i = 0; i <= 2; i++) {
+ for (let i = 0; i <= 2; i++) {
Q1[i].X = (Q[i + 1].X - Q[i].X) * 3.0;
Q1[i].Y = (Q[i + 1].Y - Q[i].Y) * 3.0;
}
/* Generate control vertices for Q'' */
- for (var i = 0; i <= 1; i++) {
+ for (let i = 0; i <= 1; i++) {
Q2[i].X = (Q1[i + 1].X - Q1[i].X) * 2.0;
Q2[i].Y = (Q1[i + 1].Y - Q1[i].Y) * 2.0;
}
@@ -450,20 +491,20 @@ function NewtonRaphsonRootFind(Q: Point[], P: Point, u: number) {
EvalBezier(Q2, 1, u, Q2_u);
/* Compute f(u)/f'(u) */
- const numerator = (Q_u[0] - P.X) * (Q1_u[0]) + (Q_u[1] - P.Y) * (Q1_u[1]);
- const denominator = (Q1_u[0]) * (Q1_u[0]) + (Q1_u[1]) * (Q1_u[1]) + (Q_u[0] - P.X) * (Q2_u[0]) + (Q_u[1] - P.Y) * (Q2_u[1]);
+ const numerator = (Q_u[0] - P.X) * Q1_u[0] + (Q_u[1] - P.Y) * Q1_u[1];
+ const denominator = Q1_u[0] * Q1_u[0] + Q1_u[1] * Q1_u[1] + (Q_u[0] - P.X) * Q2_u[0] + (Q_u[1] - P.Y) * Q2_u[1];
if (denominator === 0.0) {
uPrime = u;
- } else uPrime = u - (numerator / denominator);/* u = u - f(u)/f'(u) */
+ } else uPrime = u - numerator / denominator; /* u = u - f(u)/f'(u) */
return uPrime;
}
function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2: Point, error: number, result: Point[]) {
- const bezCurve = new Array<Point>(4); // Control points of fitted Bezier curve
- const maxIterations = 4; // Max times to try iterating
+ const bezCurve = new Array<Point>(4); // Control points of fitted Bezier curve
+ const maxIterations = 4; // Max times to try iterating
const iterationError = error * error; // Error below which you try iterating
- const nPts = last - first + 1; // Number of points in subset
+ const nPts = last - first + 1; // Number of points in subset
/* Use heuristic if region only has two points in it */
if (nPts === 2) {
@@ -471,8 +512,8 @@ function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2:
bezCurve[0] = d[first];
bezCurve[3] = d[last];
- bezCurve[1] = new Point(bezCurve[0].X + (tHat1.X * dist), bezCurve[0].Y + (tHat1.Y * dist));
- bezCurve[2] = new Point(bezCurve[3].X + (tHat2.X * dist), bezCurve[3].Y + (tHat2.Y * dist));
+ bezCurve[1] = new Point(bezCurve[0].X + tHat1.X * dist, bezCurve[0].Y + tHat1.Y * dist);
+ bezCurve[2] = new Point(bezCurve[3].X + tHat2.X * dist, bezCurve[3].Y + tHat2.Y * dist);
result.push(bezCurve[1]);
result.push(bezCurve[2]);
@@ -481,11 +522,11 @@ function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2:
}
/* Parameterize points, and attempt to fit curve */
- var u = ChordLengthParameterize(d, first, last);
+ let u = ChordLengthParameterize(d, first, last);
GenerateBezier(d, first, last, u, tHat1, tHat2, bezCurve);
/* Find max deviation of points to fitted curve */
- const { maxError, splitPoint2D } = ComputeMaxError(d, first, last, bezCurve, u); // Maximum fitting error
+ const { maxError, splitPoint2D } = ComputeMaxError(d, first, last, bezCurve, u); // Maximum fitting error
if (maxError < Math.abs(error)) {
result.push(bezCurve[1]);
result.push(bezCurve[2]);
@@ -496,11 +537,11 @@ function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2:
/* If error not too large, try some reparameterization */
/* and iteration */
if (maxError < iterationError) {
- for (var i = 0; i < maxIterations; i++) {
- const uPrime = ReparameterizeBezier(d, first, last, u, bezCurve); // Improved parameter values
+ for (let i = 0; i < maxIterations; i++) {
+ const uPrime = ReparameterizeBezier(d, first, last, u, bezCurve); // Improved parameter values
GenerateBezier(d, first, last, uPrime, tHat1, tHat2, bezCurve);
- const { maxError } = ComputeMaxError(d, first, last, bezCurve, uPrime);
- if (maxError < error) {
+ const { maxError: maximumError } = ComputeMaxError(d, first, last, bezCurve, uPrime);
+ if (maximumError < error) {
result.push(bezCurve[1]);
result.push(bezCurve[2]);
result.push(bezCurve[3]);
@@ -527,13 +568,13 @@ export function FitOneCurve(d: Point[], tHat1?: Point, tHat2?: Point) {
tHat1 = tHat1 ?? Normalize(ComputeLeftTangent(d, 0));
tHat2 = tHat2 ?? Normalize(ComputeRightTangent(d, d.length - 1));
tHat2 = new Point(-tHat2.X, -tHat2.Y);
- var u = ChordLengthParameterize(d, 0, d.length - 1);
+ let u = ChordLengthParameterize(d, 0, d.length - 1);
const bezCurveCtrls = [new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)];
- GenerateBezier(d, 0, d.length - 1, u, tHat1, tHat2, bezCurveCtrls); /* Find max deviation of points to fitted curve */
- var finalCtrls = bezCurveCtrls.slice();
- var { maxError: error } = ComputeMaxError(d, 0, d.length - 1, bezCurveCtrls, u);
- for (var i = 0; i < 10; i++) {
- const uPrime = ReparameterizeBezier(d, 0, d.length - 1, u, bezCurveCtrls); // Improved parameter values
+ GenerateBezier(d, 0, d.length - 1, u, tHat1, tHat2, bezCurveCtrls); /* Find max deviation of points to fitted curve */
+ let finalCtrls = bezCurveCtrls.slice();
+ let { maxError: error } = ComputeMaxError(d, 0, d.length - 1, bezCurveCtrls, u);
+ for (let i = 0; i < 10; i++) {
+ const uPrime = ReparameterizeBezier(d, 0, d.length - 1, u, bezCurveCtrls); // Improved parameter values
GenerateBezier(d, 0, d.length - 1, uPrime, tHat1, tHat2, bezCurveCtrls);
const { maxError } = ComputeMaxError(d, 0, d.length - 1, bezCurveCtrls, uPrime);
if (maxError < error) {
@@ -1428,4 +1469,4 @@ spliceR[0] += v;
}
#endif
-*/ \ No newline at end of file
+*/
diff --git a/src/client/util/reportManager/ReportManager.tsx b/src/client/util/reportManager/ReportManager.tsx
index 0c49aeed4..2224e642d 100644
--- a/src/client/util/reportManager/ReportManager.tsx
+++ b/src/client/util/reportManager/ReportManager.tsx
@@ -1,33 +1,39 @@
-import * as React from 'react';
-import * as uuid from 'uuid';
-import '.././SettingsManager.scss';
-import './ReportManager.scss';
-import ReactLoading from 'react-loading';
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* eslint-disable jsx-a11y/media-has-caption */
+/* eslint-disable react/no-unused-class-component-methods */
+import { Octokit } from '@octokit/core';
+import { Button, Dropdown, DropdownType, IconButton, Type } from 'browndash-components';
import { action, makeObservable, observable } from 'mobx';
-import { BsX, BsArrowsAngleExpand, BsArrowsAngleContract } from 'react-icons/bs';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { BsArrowsAngleContract, BsArrowsAngleExpand, BsX } from 'react-icons/bs';
import { CgClose } from 'react-icons/cg';
import { HiOutlineArrowLeft } from 'react-icons/hi';
-import { Issue } from './reportManagerSchema';
-import { observer } from 'mobx-react';
+import { MdRefresh } from 'react-icons/md';
+import ReactLoading from 'react-loading';
+import * as uuid from 'uuid';
+import { ClientUtils } from '../../../ClientUtils';
import { Doc } from '../../../fields/Doc';
-import { MainViewModal } from '../../views/MainViewModal';
-import { Octokit } from '@octokit/core';
-import { Button, Dropdown, DropdownType, IconButton, Type } from 'browndash-components';
-import { BugType, FileData, Priority, ReportForm, ViewState, bugDropdownItems, darkColors, emptyReportForm, formatTitle, getAllIssues, isDarkMode, lightColors, passesTagFilter, priorityDropdownItems, uploadFilesToServer } from './reportManagerUtils';
-import { Filter, FormInput, FormTextArea, IssueCard, IssueView, Tag } from './ReportManagerComponents';
import { StrCast } from '../../../fields/Types';
-import { MdRefresh } from 'react-icons/md';
+import { MainViewModal } from '../../views/MainViewModal';
+import '../SettingsManager.scss';
import { SettingsManager } from '../SettingsManager';
+import './ReportManager.scss';
+import { Filter, FormInput, FormTextArea, IssueCard, IssueView } from './ReportManagerComponents';
+import { Issue } from './reportManagerSchema';
+import { BugType, FileData, Priority, ReportForm, ViewState, bugDropdownItems, darkColors, emptyReportForm, formatTitle, getAllIssues, isDarkMode, lightColors, passesTagFilter, priorityDropdownItems, uploadFilesToServer } from './reportManagerUtils';
/**
* Class for reporting and viewing Github issues within the app.
*/
@observer
export class ReportManager extends React.Component<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: ReportManager;
@observable private isOpen = false;
@observable private query = '';
+ // eslint-disable-next-line react/sort-comp
@action private setQuery = (q: string) => {
this.query = q;
};
@@ -82,7 +88,9 @@ export class ReportManager extends React.Component<{}> {
this.formData = newData;
});
- public close = action(() => (this.isOpen = false));
+ public close = action(() => {
+ this.isOpen = false;
+ });
public open = action(async () => {
this.isOpen = true;
if (this.shownIssues.length === 0) {
@@ -133,7 +141,7 @@ export class ReportManager extends React.Component<{}> {
const req = await this.octokit.request('POST /repos/{owner}/{repo}/issues', {
owner: 'brown-dash',
repo: 'Dash-Web',
- title: formatTitle(this.formData.title, Doc.CurrentUserEmail),
+ title: formatTitle(this.formData.title, ClientUtils.CurrentUserEmail()),
body: `${this.formData.description} ${formattedLinks.length > 0 ? `\n\nFiles:\n${formattedLinks.join('\n')}` : ''}`,
labels: ['from-dash-app', this.formData.type, this.formData.priority],
});
@@ -164,7 +172,7 @@ export class ReportManager extends React.Component<{}> {
* @returns JSX element of a piece of media (image, video, audio)
*/
private getMediaPreview = (fileData: FileData): JSX.Element => {
- const file = fileData.file;
+ const { file } = fileData;
const mimeType = file.type;
const preview = URL.createObjectURL(file);
@@ -179,7 +187,8 @@ export class ReportManager extends React.Component<{}> {
</div>
</div>
);
- } else if (mimeType.startsWith('video/')) {
+ }
+ if (mimeType.startsWith('video/')) {
return (
<div key={fileData._id} className="report-media-wrapper">
<div className="report-media-content">
@@ -193,7 +202,8 @@ export class ReportManager extends React.Component<{}> {
</div>
</div>
);
- } else if (mimeType.startsWith('audio/')) {
+ }
+ if (mimeType.startsWith('audio/')) {
return (
<div key={fileData._id} className="report-audio-wrapper">
<audio src={preview} controls />
@@ -203,7 +213,7 @@ export class ReportManager extends React.Component<{}> {
</div>
);
}
- return <></>;
+ return <div />;
};
/**
@@ -306,8 +316,8 @@ export class ReportManager extends React.Component<{}> {
<div className="report-selects">
<Dropdown
color={StrCast(Doc.UserDoc().userColor)}
- formLabel={'Type'}
- closeOnSelect={true}
+ formLabel="Type"
+ closeOnSelect
items={bugDropdownItems}
selectedVal={this.formData.type}
setSelectedVal={val => {
@@ -319,8 +329,8 @@ export class ReportManager extends React.Component<{}> {
/>
<Dropdown
color={StrCast(Doc.UserDoc().userColor)}
- formLabel={'Priority'}
- closeOnSelect={true}
+ formLabel="Priority"
+ closeOnSelect
items={priorityDropdownItems}
selectedVal={this.formData.priority}
setSelectedVal={val => {
@@ -346,7 +356,7 @@ export class ReportManager extends React.Component<{}> {
text="Submit"
type={Type.TERT}
color={StrCast(Doc.UserDoc().userVariantColor)}
- icon={<ReactLoading type="spin" color={'#ffffff'} width={20} height={20} />}
+ icon={<ReactLoading type="spin" color="#ffffff" width={20} height={20} />}
iconPlacement="right"
onClick={() => {
this.reportIssue();
@@ -363,7 +373,7 @@ export class ReportManager extends React.Component<{}> {
/>
)}
<div style={{ position: 'absolute', top: '4px', right: '4px' }}>
- <IconButton color={StrCast(Doc.UserDoc().userColor)} tooltip="close" icon={<CgClose size={'16px'} />} onClick={this.close} />
+ <IconButton color={StrCast(Doc.UserDoc().userColor)} tooltip="close" icon={<CgClose size="16px" />} onClick={this.close} />
</div>
</div>
);
@@ -375,9 +385,8 @@ export class ReportManager extends React.Component<{}> {
private reportComponent = () => {
if (this.viewState === ViewState.VIEW) {
return this.viewIssuesComponent();
- } else {
- return this.reportIssueComponent();
}
+ return this.reportIssueComponent();
};
render() {
@@ -385,7 +394,7 @@ export class ReportManager extends React.Component<{}> {
<MainViewModal
contents={this.reportComponent()}
isDisplayed={this.isOpen}
- interactive={true}
+ interactive
closeOnExternalClick={this.close}
dialogueBoxStyle={{ width: 'auto', minWidth: '300px', height: '85vh', maxHeight: '90vh', background: StrCast(Doc.UserDoc().userBackgroundColor), borderRadius: '8px' }}
/>
diff --git a/src/client/util/reportManager/ReportManagerComponents.tsx b/src/client/util/reportManager/ReportManagerComponents.tsx
index 1e226bf6d..cecebc648 100644
--- a/src/client/util/reportManager/ReportManagerComponents.tsx
+++ b/src/client/util/reportManager/ReportManagerComponents.tsx
@@ -1,9 +1,15 @@
+/* eslint-disable react/require-default-props */
+/* eslint-disable prefer-destructuring */
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable no-use-before-define */
import * as React from 'react';
-import { Issue } from './reportManagerSchema';
-import { darkColors, dashBlue, getLabelColors, isDarkMode, lightColors } from './reportManagerUtils';
import ReactMarkdown from 'react-markdown';
import rehypeRaw from 'rehype-raw';
import remarkGfm from 'remark-gfm';
+import { darkColors, dashBlue, getLabelColors, isDarkMode, lightColors } from './reportManagerUtils';
+import { Issue } from './reportManagerSchema';
import { StrCast } from '../../../fields/Types';
import { Doc } from '../../../fields/Doc';
@@ -18,7 +24,7 @@ interface FilterProps<T> {
}
// filter ui for issues (horizontal list of tags)
-export const Filter = <T extends string>({ items, activeValue, setActiveValue }: FilterProps<T>) => {
+export function Filter<T extends string>({ items, activeValue, setActiveValue }: FilterProps<T>) {
// establishing theme
const darkMode = isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor));
const colors = darkMode ? darkColors : lightColors;
@@ -28,7 +34,7 @@ export const Filter = <T extends string>({ items, activeValue, setActiveValue }:
return (
<div className="issues-filter">
<Tag
- text={'All'}
+ text="All"
onClick={() => {
setActiveValue(null);
}}
@@ -38,25 +44,23 @@ export const Filter = <T extends string>({ items, activeValue, setActiveValue }:
borderColor={activeValue === null ? StrCast(Doc.UserDoc().userColor) : colors.border}
border
/>
- {items.map(item => {
- return (
- <Tag
- key={item}
- text={item}
- onClick={() => {
- setActiveValue(item);
- }}
- fontSize="12px"
- backgroundColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : 'transparent'}
- color={activeValue === item ? activeTagTextColor : colors.textGrey}
- border
- borderColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : colors.border}
- />
- );
- })}
+ {items.map(item => (
+ <Tag
+ key={item}
+ text={item}
+ onClick={() => {
+ setActiveValue(item);
+ }}
+ fontSize="12px"
+ backgroundColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : 'transparent'}
+ color={activeValue === item ? activeTagTextColor : colors.textGrey}
+ border
+ borderColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : colors.border}
+ />
+ ))}
</div>
);
-};
+}
interface IssueCardProps {
issue: Issue;
@@ -64,7 +68,7 @@ interface IssueCardProps {
}
// Component for the issue cards list on the left
-export const IssueCard = ({ issue, onSelect }: IssueCardProps) => {
+export function IssueCard({ issue, onSelect }: IssueCardProps) {
const [textColor, setTextColor] = React.useState('');
const [bgColor, setBgColor] = React.useState('transparent');
const [borderColor, setBorderColor] = React.useState('transparent');
@@ -103,14 +107,14 @@ export const IssueCard = ({ issue, onSelect }: IssueCardProps) => {
<h3 className="issue-title">{issue.title}</h3>
</div>
);
-};
+}
interface IssueViewProps {
issue: Issue;
}
// Detailed issue view that displays on the right
-export const IssueView = ({ issue }: IssueViewProps) => {
+export function IssueView({ issue }: IssueViewProps) {
const [issueBody, setIssueBody] = React.useState('');
// Parses the issue body into a formatted markdown (main functionality is replacing urls with tags)
@@ -127,15 +131,16 @@ export const IssueView = ({ issue }: IssueViewProps) => {
parts.map(async part => {
if (imgTagRegex.test(part) || videoTagRegex.test(part) || audioTagRegex.test(part)) {
return `\n${await parseFileTag(part)}\n`;
- } else if (fileRegex.test(part)) {
+ }
+ if (fileRegex.test(part)) {
const tag = await parseDashFiles(part);
return tag;
- } else if (localRegex.test(part)) {
+ }
+ if (localRegex.test(part)) {
const tag = await parseLocalFiles(part);
return tag;
- } else {
- return part;
}
+ return part;
})
);
@@ -143,7 +148,7 @@ export const IssueView = ({ issue }: IssueViewProps) => {
};
// Extracts the src from an image tag and either returns the raw url if not accessible or a new image tag
- const parseFileTag = async (tag: string): Promise<string> => {
+ const parseFileTag = async (tag: string): Promise<string | undefined> => {
const regex = /src="([^"]+)"/;
let url = '';
const match = tag.match(regex);
@@ -160,18 +165,19 @@ export const IssueView = ({ issue }: IssueViewProps) => {
case '.png':
case '.jpeg':
case '.gif':
- return await getDisplayedFile(url, 'image');
+ return getDisplayedFile(url, 'image');
// video
case '.mp4':
case '.mpeg':
case '.webm':
case '.mov':
- return await getDisplayedFile(url, 'video');
- //audio
+ return getDisplayedFile(url, 'video');
+ // audio
case '.mp3':
case '.wav':
case '.ogg':
- return await getDisplayedFile(url, 'audio');
+ return getDisplayedFile(url, 'audio');
+ default:
}
return tag;
};
@@ -183,14 +189,15 @@ export const IssueView = ({ issue }: IssueViewProps) => {
const dashAudioRegex = /https:\/\/browndash\.com\/files[/\\]audio/;
if (dashImgRegex.test(url)) {
- return await getDisplayedFile(url, 'image');
- } else if (dashVideoRegex.test(url)) {
- return await getDisplayedFile(url, 'video');
- } else if (dashAudioRegex.test(url)) {
- return await getDisplayedFile(url, 'audio');
- } else {
- return url;
+ return getDisplayedFile(url, 'image');
}
+ if (dashVideoRegex.test(url)) {
+ return getDisplayedFile(url, 'video');
+ }
+ if (dashAudioRegex.test(url)) {
+ return getDisplayedFile(url, 'audio');
+ }
+ return url;
};
// Returns the corresponding HTML tag for a src url
@@ -200,31 +207,37 @@ export const IssueView = ({ issue }: IssueViewProps) => {
const dashAudioRegex = /http:\/\/localhost:1050\.com\/files[/\\]audio/;
if (imgRegex.test(url)) {
- return await getDisplayedFile(url, 'image');
- } else if (dashVideoRegex.test(url)) {
- return await getDisplayedFile(url, 'video');
- } else if (dashAudioRegex.test(url)) {
- return await getDisplayedFile(url, 'audio');
- } else {
- return url;
+ return getDisplayedFile(url, 'image');
+ }
+ if (dashVideoRegex.test(url)) {
+ return getDisplayedFile(url, 'video');
+ }
+ if (dashAudioRegex.test(url)) {
+ return getDisplayedFile(url, 'audio');
}
+ return url;
};
- const getDisplayedFile = async (url: string, fileType: 'image' | 'video' | 'audio'): Promise<string> => {
+ const getDisplayedFile = async (url: string, fileType: 'image' | 'video' | 'audio'): Promise<string | undefined> => {
switch (fileType) {
- case 'image':
+ case 'image': {
const imgValid = await isImgValid(url);
if (!imgValid) return `\n${url} (This image could not be loaded)\n`;
return `\n${url}\n<img width="100%" alt="Issue asset" src=${url} />\n`;
- case 'video':
+ }
+ case 'video': {
const videoValid = await isVideoValid(url);
if (!videoValid) return `\n${url} (This video could not be loaded)\n`;
return `\n${url}\n<video class="report-default-video" width="100%" controls alt="Issue asset" src=${url} />\n`;
- case 'audio':
+ }
+ case 'audio': {
const audioValid = await isAudioValid(url);
if (!audioValid) return `\n${url} (This audio could not be loaded)\n`;
return `\n${url}\n<audio src=${url} controls />\n`;
+ }
+ default:
}
+ return undefined;
};
// Loads an image and returns a promise that resolves as whether the image is valid or not
@@ -270,7 +283,7 @@ export const IssueView = ({ issue }: IssueViewProps) => {
<div className="issue-view">
<span className="issue-label">
Issue{' '}
- <a className="issue-link" href={issue.html_url} target="_blank">
+ <a className="issue-link" href={issue.html_url} target="_blank" rel="noreferrer">
#{issue.number}
</a>
</span>
@@ -292,7 +305,7 @@ export const IssueView = ({ issue }: IssueViewProps) => {
<ReactMarkdown children={issueBody} className="issue-content" remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} />
</div>
);
-};
+}
interface TagProps {
text: string;
@@ -305,7 +318,7 @@ interface TagProps {
}
// Small tag for labels of the issue
-export const Tag = ({ text, color, backgroundColor, fontSize, border, borderColor, onClick }: TagProps) => {
+export function Tag({ text, color, backgroundColor, fontSize, border, borderColor, onClick }: TagProps) {
return (
<div
onClick={onClick ?? (() => {})}
@@ -314,14 +327,14 @@ export const Tag = ({ text, color, backgroundColor, fontSize, border, borderColo
{text}
</div>
);
-};
+}
interface FormInputProps {
value: string;
placeholder: string;
onChange: (val: string) => void;
}
-export const FormInput = ({ value, placeholder, onChange }: FormInputProps) => {
+export function FormInput({ value, placeholder, onChange }: FormInputProps) {
const [inputBorderColor, setInputBorderColor] = React.useState('');
return (
@@ -349,9 +362,9 @@ export const FormInput = ({ value, placeholder, onChange }: FormInputProps) => {
}}
/>
);
-};
+}
-export const FormTextArea = ({ value, placeholder, onChange }: FormInputProps) => {
+export function FormTextArea({ value, placeholder, onChange }: FormInputProps) {
const [textAreaBorderColor, setTextAreaBorderColor] = React.useState('');
return (
@@ -378,4 +391,4 @@ export const FormTextArea = ({ value, placeholder, onChange }: FormInputProps) =
}}
/>
);
-};
+}
diff --git a/src/client/util/reportManager/reportManagerSchema.ts b/src/client/util/reportManager/reportManagerSchema.ts
index 9a1c7c3e9..171c24393 100644
--- a/src/client/util/reportManager/reportManagerSchema.ts
+++ b/src/client/util/reportManager/reportManagerSchema.ts
@@ -1,3 +1,4 @@
+/* eslint-disable no-use-before-define */
/**
* Issue interface schema from Github.
*/
diff --git a/src/client/util/reportManager/reportManagerUtils.ts b/src/client/util/reportManager/reportManagerUtils.ts
index 22e5eebbb..f14967e0a 100644
--- a/src/client/util/reportManager/reportManagerUtils.ts
+++ b/src/client/util/reportManager/reportManagerUtils.ts
@@ -63,9 +63,8 @@ export const getAllIssues = async (octokit: Octokit): Promise<any[]> => {
// 200 status means success
if (res.status === 200) {
return res.data;
- } else {
- throw new Error('Error getting issues');
}
+ throw new Error('Error getting issues');
};
/**
@@ -104,9 +103,7 @@ export const fileLinktoServerLink = (fileLink: string): string => {
* @param link response from file upload
* @returns server file path
*/
-export const getServerPath = (link: any): string => {
- return link.result.accessPaths.agnostic.server as string;
-};
+export const getServerPath = (link: any): string => link.result.accessPaths.agnostic.server as string;
/**
* Uploads media files to the server.
@@ -124,6 +121,7 @@ export const uploadFilesToServer = async (mediaFiles: FileData[]): Promise<strin
alert(err);
}
}
+ return undefined;
};
// helper functions
@@ -141,18 +139,16 @@ export const passesTagFilter = (issue: Issue, priorityFilter: string | null, bug
passesPriority = issue.labels.some(label => {
if (typeof label === 'string') {
return label === priorityFilter;
- } else {
- return label.name === priorityFilter;
}
+ return label.name === priorityFilter;
});
}
if (bugFilter) {
passesBug = issue.labels.some(label => {
if (typeof label === 'string') {
return label === bugFilter;
- } else {
- return label.name === bugFilter;
}
+ return label.name === bugFilter;
});
}
return passesPriority && passesBug;
@@ -217,7 +213,8 @@ export const bugColors: { [key: string]: string[] } = {
export const getLabelColors = (label: string): string[] => {
if (prioritySet.has(label as Priority)) {
return priorityColors[label];
- } else if (bugSet.has(label as BugType)) {
+ }
+ if (bugSet.has(label as BugType)) {
return bugColors[label];
}
return ['#0f73f6', '#ffffff'];
diff --git a/src/client/util/request-image-size.ts b/src/client/util/request-image-size.ts
index 57e8516ac..0f98a2710 100644
--- a/src/client/util/request-image-size.ts
+++ b/src/client/util/request-image-size.ts
@@ -14,19 +14,17 @@ const imageSize = require('image-size');
const HttpError = require('standard-http-error');
module.exports = function requestImageSize(options: any) {
- let opts = {
+ let opts: any = {
encoding: null,
};
if (options && typeof options === 'object') {
opts = Object.assign(options, opts);
} else if (options && typeof options === 'string') {
- opts = Object.assign(
- {
- uri: options,
- },
- opts
- );
+ opts = {
+ uri: options,
+ ...opts,
+ };
} else {
return Promise.reject(new Error('You should provide an URI string or a "request" options object.'));
}
@@ -38,7 +36,8 @@ module.exports = function requestImageSize(options: any) {
req.on('response', (res: any) => {
if (res.statusCode >= 400) {
- return reject(new HttpError(res.statusCode, res.statusMessage));
+ reject(new HttpError(res.statusCode, res.statusMessage));
+ return;
}
let buffer = Buffer.from([]);
@@ -51,20 +50,23 @@ module.exports = function requestImageSize(options: any) {
size = imageSize(buffer);
if (size) {
resolve(size);
- return req.abort();
+ req.abort();
}
- } catch (err) {}
+ } catch (err) {
+ /* empty */
+ }
});
res.on('error', reject);
res.on('end', () => {
if (!size) {
- return reject(new Error('Image has no size'));
+ reject(new Error('Image has no size'));
+ return;
}
size.downloaded = buffer.length;
- return resolve(size);
+ resolve(size);
});
});
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index db7e64deb..303672d90 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -1,8 +1,9 @@
import { action, makeObservable, observable, runInAction } from 'mobx';
import * as React from 'react';
-import { SettingsManager } from '../util/SettingsManager';
+import { SnappingManager } from '../util/SnappingManager';
import './AntimodeMenu.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
+
export interface AntimodeMenuProps {}
/**
@@ -76,7 +77,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
};
@action
- protected pointerLeave = (e: React.PointerEvent) => {
+ protected pointerLeave = () => {
if (!this.Pinned && this._canFade) {
this._transitionProperty = 'opacity';
this._transitionDuration = '0.5s';
@@ -87,7 +88,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
};
@action
- protected pointerEntered = (e: React.PointerEvent) => {
+ protected pointerEntered = () => {
this._transitionProperty = 'opacity';
this._transitionDuration = '0.1s';
this._transitionDelay = '';
@@ -95,8 +96,10 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
};
@action
- protected togglePin = (e: React.MouseEvent) => {
- runInAction(() => (this.Pinned = !this.Pinned));
+ protected togglePin = () => {
+ runInAction(() => {
+ this.Pinned = !this.Pinned;
+ });
};
protected dragStart = (e: React.PointerEvent) => {
@@ -114,8 +117,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
@action
protected dragging = (e: PointerEvent) => {
- const width = this._mainCont.current!.getBoundingClientRect().width;
- const height = this._mainCont.current!.getBoundingClientRect().height;
+ const { width, height } = this._mainCont.current!.getBoundingClientRect();
const left = e.pageX - this._offsetX;
const top = e.pageY - this._offsetY;
@@ -139,9 +141,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
e.preventDefault();
};
- protected getDragger = () => {
- return <div className="antimodeMenu-dragger" key="dragger" onPointerDown={this.dragStart} style={{ width: '20px' }} />;
- };
+ protected getDragger = () => <div className="antimodeMenu-dragger" key="dragger" onPointerDown={this.dragStart} style={{ width: '20px' }} />;
protected getElement(buttons: JSX.Element, expanded: boolean = false) {
const containerClass = expanded ? 'antimodeMenu-cont expanded' : 'antimodeMenu-cont';
@@ -157,7 +157,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
left: this._left,
top: this._top,
opacity: this._opacity,
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
@@ -183,7 +183,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
height: 'inherit',
width: 200,
opacity: this._opacity,
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
@@ -206,7 +206,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
left: this._left,
top: this._top,
opacity: this._opacity,
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
diff --git a/src/client/views/ComponentDecorations.tsx b/src/client/views/ComponentDecorations.tsx
index ca4e5f2bc..929b549e0 100644
--- a/src/client/views/ComponentDecorations.tsx
+++ b/src/client/views/ComponentDecorations.tsx
@@ -1,14 +1,15 @@
import { observer } from 'mobx-react';
-import { SelectionManager } from '../util/SelectionManager';
-import './ComponentDecorations.scss';
import * as React from 'react';
+import './ComponentDecorations.scss';
+import { DocumentView } from './nodes/DocumentView';
@observer
export class ComponentDecorations extends React.Component<{ boundsTop: number; boundsLeft: number }, { value: string }> {
+ // eslint-disable-next-line no-use-before-define
static Instance: ComponentDecorations;
render() {
- const seldoc = SelectionManager.Views.lastElement();
+ const seldoc = DocumentView.Selected().lastElement();
return seldoc?.ComponentView?.componentUI?.(this.props.boundsLeft, this.props.boundsTop) ?? null;
}
}
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index 8f4e43978..d784a14b8 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -1,16 +1,19 @@
+/* eslint-disable react/no-array-index-key */
+/* eslint-disable react/jsx-props-no-spreading */
+/* eslint-disable default-param-last */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { StrCast } from '../../fields/Types';
-import { SettingsManager } from '../util/SettingsManager';
+import { DivHeight, DivWidth } from '../../ClientUtils';
+import { SnappingManager } from '../util/SnappingManager';
import './ContextMenu.scss';
import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from './ContextMenuItem';
import { ObservableReactComponent } from './ObservableReactComponent';
-import { DivHeight, DivWidth } from '../../Utils';
@observer
export class ContextMenu extends ObservableReactComponent<{}> {
+ // eslint-disable-next-line no-use-before-define
static Instance: ContextMenu;
private _ignoreUp = false;
@@ -124,8 +127,8 @@ export class ContextMenu extends ObservableReactComponent<{}> {
@action
displayMenu = (x: number, y: number, initSearch = '', showSearch = false, onDisplay?: () => void) => {
- //maxX and maxY will change if the UI/font size changes, but will work for any amount
- //of items added to the menu
+ // maxX and maxY will change if the UI/font size changes, but will work for any amount
+ // of items added to the menu
this._showSearch = showSearch;
this._pageX = x;
@@ -147,15 +150,13 @@ export class ContextMenu extends ObservableReactComponent<{}> {
@computed get filteredItems(): (OriginalMenuProps | string[])[] {
const searchString = this._searchString.toLowerCase().split(' ');
- const matches = (descriptions: string[]): boolean => {
- return searchString.every(s => descriptions.some(desc => desc.toLowerCase().includes(s)));
- };
+ const matches = (descriptions: string[]) => searchString.every(s => descriptions.some(desc => desc.toLowerCase().includes(s)));
const flattenItems = (items: ContextMenuProps[], groupFunc: (groupName: any) => string[]) => {
let eles: (OriginalMenuProps | string[])[] = [];
const leaves: OriginalMenuProps[] = [];
- for (const item of items) {
- const description = item.description;
+ items.forEach(item => {
+ const { description } = item;
const path = groupFunc(description);
if ('subitems' in item) {
const children = flattenItems(item.subitems, name => [...groupFunc(description), name]);
@@ -163,13 +164,10 @@ export class ContextMenu extends ObservableReactComponent<{}> {
eles.push(path);
eles = eles.concat(children);
}
- } else {
- if (!matches(path)) {
- continue;
- }
+ } else if (matches(path)) {
leaves.push(item);
}
- }
+ });
eles = [...leaves, ...eles];
@@ -192,7 +190,7 @@ export class ContextMenu extends ObservableReactComponent<{}> {
key={index + value.join(' -> ')}
className="contextMenu-group"
style={{
- background: StrCast(SettingsManager.userVariantColor),
+ background: SnappingManager.userVariantColor,
}}>
<div className="contextMenu-description">{value.join(' -> ')}</div>
</div>
@@ -218,16 +216,17 @@ export class ContextMenu extends ObservableReactComponent<{}> {
this._width = DivWidth(r);
this._height = DivHeight(r);
}
+ this._searchRef.current?.focus();
})}
style={{
display: this._display ? '' : 'none',
left: this.pageX,
- ...(this._yRelativeToTop ? { top: this.pageY } : { bottom: this.pageY }),
- background: SettingsManager.userBackgroundColor,
- color: SettingsManager.userColor,
+ ...(this._yRelativeToTop ? { top: Math.max(0, this.pageY) } : { bottom: this.pageY }),
+ background: SnappingManager.userBackgroundColor,
+ color: SnappingManager.userColor,
}}>
{!this.itemsNeedSearch ? null : (
- <span className={'search-icon'}>
+ <span className="search-icon">
<span className="icon-background">
<FontAwesomeIcon icon="search" size="lg" />
</span>
@@ -240,6 +239,7 @@ export class ContextMenu extends ObservableReactComponent<{}> {
value={this._searchString}
onKeyDown={this.onKeyDown}
onChange={this.onChange}
+ // eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
/>
</span>
@@ -265,7 +265,8 @@ export class ContextMenu extends ObservableReactComponent<{}> {
const item = this.flatItems[this._selectedIndex];
if (item) {
item.event({ x: this.pageX, y: this.pageY });
- } else if (this._searchString.startsWith(this._defaultPrefix)) {
+ } else {
+ // if (this._searchString.startsWith(this._defaultPrefix)) {
this._defaultItem?.(this._searchString.substring(this._defaultPrefix.length));
}
this.closeMenu();
@@ -279,12 +280,10 @@ export class ContextMenu extends ObservableReactComponent<{}> {
this._searchString = e.target.value;
if (!this._searchString) {
this._selectedIndex = -1;
+ } else if (this._selectedIndex === -1) {
+ this._selectedIndex = 0;
} else {
- if (this._selectedIndex === -1) {
- this._selectedIndex = 0;
- } else {
- this._selectedIndex = Math.min(this.flatItems.length - 1, this._selectedIndex);
- }
+ this._selectedIndex = Math.min(this.flatItems.length - 1, this._selectedIndex);
}
};
}
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index b2076e1a5..eb1030eec 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -1,26 +1,28 @@
-import * as React from 'react';
-import { observable, action, runInAction, makeObservable } from 'mobx';
-import { observer } from 'mobx-react';
+/* eslint-disable react/jsx-props-no-spreading */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, makeObservable, observable, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { SnappingManager } from '../util/SnappingManager';
import { UndoManager } from '../util/UndoManager';
-import { SettingsManager } from '../util/SettingsManager';
import { ObservableReactComponent } from './ObservableReactComponent';
export interface OriginalMenuProps {
description: string;
event: (stuff?: any) => void;
undoable?: boolean;
- icon: IconProp | JSX.Element; //maybe should be optional (icon?)
+ 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?)
+ icon: IconProp; // maybe should be optional (icon?)
closeMenu?: () => void;
}
@@ -37,7 +39,9 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
}
componentDidMount() {
- runInAction(() => (this._items.length = 0));
+ runInAction(() => {
+ this._items.length = 0;
+ });
if ((this._props as SubmenuProps)?.subitems) {
(this._props as SubmenuProps).subitems?.forEach(i => runInAction(() => this._items.push(i)));
}
@@ -67,7 +71,9 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
this._overPosY = e.clientY;
this._overPosX = e.clientX;
this.currentTimeout = setTimeout(
- action(() => (this.overItem = true)),
+ action(() => {
+ this.overItem = true;
+ }),
ContextMenuItem.timeout
);
};
@@ -81,7 +87,9 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
return;
}
this.currentTimeout = setTimeout(
- action(() => (this.overItem = false)),
+ action(() => {
+ this.overItem = false;
+ }),
ContextMenuItem.timeout
);
};
@@ -97,14 +105,15 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
{this._props.icon ? <span className="contextMenu-item-icon-background">{this.isJSXElement(this._props.icon) ? this._props.icon : <FontAwesomeIcon icon={this._props.icon} size="sm" />}</span> : null}
<div className="contextMenu-description">{this._props.description.replace(':', '')}</div>
<div
- className={`contextMenu-item-background`}
+ className="contextMenu-item-background"
style={{
- background: SettingsManager.userColor,
+ background: SnappingManager.userColor,
}}
/>
</div>
);
- } else if ('subitems' in this._props) {
+ }
+ 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' : '';
@@ -113,9 +122,9 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
<div
className="contextMenu-subMenu-cont"
style={{
- marginLeft: window.innerHeight - this._overPosX - 50 > 0 ? '90%' : '20%',
+ marginLeft: window.innerWidth - this._overPosX - 50 > 0 ? '90%' : '20%',
marginTop,
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
}}>
{this._items.map(prop => (
<ContextMenuItem {...prop} key={prop.description} closeMenu={this._props.closeMenu} />
@@ -144,17 +153,18 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
) : null}
<div className="contextMenu-description" onMouseEnter={this.onPointerEnter} style={{ alignItems: 'center', alignSelf: 'center' }}>
{this._props.description}
- <FontAwesomeIcon icon={'angle-right'} size="lg" style={{ position: 'absolute', right: '10px' }} />
+ <FontAwesomeIcon icon="angle-right" size="lg" style={{ position: 'absolute', right: '10px' }} />
</div>
<div
- className={`contextMenu-item-background`}
+ className="contextMenu-item-background"
style={{
- background: SettingsManager.userColor,
+ background: SnappingManager.userColor,
}}
/>
{submenu}
</div>
);
}
+ return null;
}
}
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 146ac5b01..b7383a37e 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -1,9 +1,12 @@
+/* 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, ColorPicker, EditableText, Size, Type } from 'browndash-components';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaPlus } from 'react-icons/fa';
+import { ClientUtils } from '../../ClientUtils';
import { Doc, DocListCast } from '../../fields/Doc';
import { AclPrivate, DocAcl, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
@@ -12,34 +15,73 @@ import { PrefetchProxy } from '../../fields/Proxy';
import { listSpec } from '../../fields/Schema';
import { ScriptField } from '../../fields/ScriptField';
import { Cast, ImageCast, StrCast } from '../../fields/Types';
-import { normalizeEmail } from '../../fields/util';
+import { SharingPermissions, inheritParentAcls, normalizeEmail } from '../../fields/util';
import { DocServer } from '../DocServer';
-import { Docs, DocumentOptions, DocUtils } from '../documents/Documents';
+import { DocUtils } from '../documents/DocUtils';
+import { Docs, DocumentOptions } from '../documents/Documents';
+import { dropActionType } from '../util/DropActionTypes';
import { HistoryUtil } from '../util/History';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
-import { SettingsManager } from '../util/SettingsManager';
-import { SharingManager } from '../util/SharingManager';
-import { undoable, undoBatch, UndoManager } from '../util/UndoManager';
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { CollectionView } from './collections/CollectionView';
+import { SnappingManager } from '../util/SnappingManager';
+import { undoBatch, undoable } from '../util/UndoManager';
import { ContextMenu } from './ContextMenu';
import './DashboardView.scss';
-import { Colors } from './global/globalEnums';
import { MainViewModal } from './MainViewModal';
-import { ButtonType } from './nodes/FontIconBox/FontIconBox';
import { ObservableReactComponent } from './ObservableReactComponent';
-import { dropActionType } from '../util/DragManager';
+import { Colors } from './global/globalEnums';
+import { DocumentView } from './nodes/DocumentView';
+import { ButtonType } from './nodes/FontIconBox/FontIconBox';
enum DashboardGroup {
MyDashboards,
SharedDashboards,
}
+export type DocConfig = {
+ doc: Doc;
+ initialWidth?: number;
+ path?: Doc[];
+};
+
// DashboardView is the view with the dashboard previews, rendered when the app first loads
@observer
export class DashboardView extends ObservableReactComponent<{}> {
public static _urlState: HistoryUtil.DocUrl;
+ public static makeDocumentConfig(document: Doc, panelName?: string, width?: number, keyValue?: boolean) {
+ return {
+ type: 'react-component',
+ component: 'DocumentFrameRenderer',
+ title: document.title,
+ width: width,
+ props: {
+ documentId: document[Id],
+ keyValue,
+ panelName, // name of tab that can be used to close or replace its contents
+ },
+ };
+ }
+ static StandardCollectionDockingDocument(configs: Array<DocConfig>, options: DocumentOptions, id?: string, type: string = 'row') {
+ const layoutConfig = {
+ content: [
+ {
+ type: type,
+ content: [...configs.map(config => DashboardView.makeDocumentConfig(config.doc, undefined, config.initialWidth))],
+ },
+ ],
+ };
+ const doc = Docs.Create.DockDocument(
+ configs.map(c => c.doc),
+ JSON.stringify(layoutConfig),
+ ClientUtils.CurrentUserEmail() === 'guest' ? options : { acl_Guest: SharingPermissions.View, ...options },
+ id
+ );
+ configs.forEach(c => {
+ Doc.SetContainer(c.doc, doc);
+ inheritParentAcls(doc, c.doc, false);
+ });
+ return doc;
+ }
constructor(props: any) {
super(props);
makeObservable(this);
@@ -49,10 +91,18 @@ export class DashboardView extends ObservableReactComponent<{}> {
@observable private selectedDashboardGroup = DashboardGroup.MyDashboards;
@observable private newDashboardName = '';
@observable private newDashboardColor = '#AFAFAF';
- @action abortCreateNewDashboard = () => (this.openModal = false);
- @action setNewDashboardName = (name: string) => (this.newDashboardName = name);
- @action setNewDashboardColor = (color: string) => (this.newDashboardColor = color);
- @action selectDashboardGroup = (group: DashboardGroup) => (this.selectedDashboardGroup = group);
+ @action abortCreateNewDashboard = () => {
+ this.openModal = false;
+ };
+ @action setNewDashboardName = (name: string) => {
+ this.newDashboardName = name;
+ };
+ @action setNewDashboardColor = (color: string) => {
+ this.newDashboardColor = color;
+ };
+ @action selectDashboardGroup = (group: DashboardGroup) => {
+ this.selectedDashboardGroup = group;
+ };
clickDashboard = (e: React.MouseEvent, dashboard: Doc) => {
if (this.selectedDashboardGroup === DashboardGroup.SharedDashboards) {
@@ -65,7 +115,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
getDashboards = (whichGroup: DashboardGroup) => {
if (whichGroup === DashboardGroup.MyDashboards) {
- return DocListCast(Doc.MyDashboards.data).filter(dashboard => dashboard[DocData].author === Doc.CurrentUserEmail);
+ return DocListCast(Doc.MyDashboards.data).filter(dashboard => dashboard[DocData].author === ClientUtils.CurrentUserEmail());
}
return DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc.dockingConfig);
};
@@ -84,11 +134,11 @@ export class DashboardView extends ObservableReactComponent<{}> {
<div
className="new-dashboard"
style={{
- background: SettingsManager.userBackgroundColor,
- color: SettingsManager.userColor,
+ background: SnappingManager.userBackgroundColor,
+ color: SnappingManager.userColor,
}}>
<div className="header">Create New Dashboard</div>
- <EditableText formLabel="Title" placeholder={this.newDashboardName} type={Type.SEC} color={SettingsManager.userColor} setVal={val => this.setNewDashboardName(val as string)} fillWidth />
+ <EditableText formLabel="Title" placeholder={this.newDashboardName} type={Type.SEC} color={SnappingManager.userColor} setVal={val => this.setNewDashboardName(val as string)} fillWidth />
<ColorPicker
formLabel="Background" //
colorPickerType="github"
@@ -98,8 +148,8 @@ export class DashboardView extends ObservableReactComponent<{}> {
setSelectedColor={this.setNewDashboardColor}
/>
<div className="button-bar">
- <Button text="Cancel" color={SettingsManager.userColor} onClick={this.abortCreateNewDashboard} />
- <Button text="Create" color={SettingsManager.userVariantColor} type={Type.TERT} onClick={() => this.createNewDashboard(this.newDashboardName, this.newDashboardColor)} />
+ <Button text="Cancel" color={SnappingManager.userColor} onClick={this.abortCreateNewDashboard} />
+ <Button text="Create" color={SnappingManager.userVariantColor} type={Type.TERT} onClick={() => this.createNewDashboard(this.newDashboardName, this.newDashboardColor)} />
</div>
</div>
);
@@ -120,7 +170,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
ContextMenu.Instance.addItem({
description: `Share Dashboard`,
- event: () => SharingManager.Instance.open(undefined, dashboard),
+ event: () => DocumentView.ShareOpen(undefined, dashboard),
icon: 'edit',
});
ContextMenu.Instance.addItem({
@@ -133,15 +183,15 @@ export class DashboardView extends ObservableReactComponent<{}> {
};
render() {
- const color = SettingsManager.userColor;
- const variant = SettingsManager.userVariantColor;
+ const color = SnappingManager.userColor;
+ const variant = SnappingManager.userVariantColor;
return (
<>
<div className="dashboard-view">
<div className="left-menu">
- <Button text="My Dashboards" active={this.selectedDashboardGroup === DashboardGroup.MyDashboards} color={color} align={'flex-start'} onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)} fillWidth />
+ <Button text="My Dashboards" active={this.selectedDashboardGroup === DashboardGroup.MyDashboards} color={color} align="flex-start" onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)} fillWidth />
<Button
- text={'Shared Dashboards' + ' (' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
+ text={'Shared Dashboards (' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
active={this.selectedDashboardGroup === DashboardGroup.SharedDashboards}
color={this.getDashboards(DashboardGroup.SharedDashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'green' : color}
align="flex-start"
@@ -156,7 +206,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
: this.getDashboards(this.selectedDashboardGroup).map(dashboard => {
const href = ImageCast(dashboard.thumb)?.url?.href;
const shared = Object.keys(dashboard[DocAcl])
- .filter(key => key !== `acl-${normalizeEmail(Doc.CurrentUserEmail)}` && !['acl-Me', 'acl-Guest'].includes(key))
+ .filter(key => key !== `acl_${normalizeEmail(ClientUtils.CurrentUserEmail())}` && !['acl_Me', 'acl_Guest'].includes(key))
.some(key => dashboard[DocAcl][key] !== AclPrivate);
return (
<div
@@ -166,14 +216,22 @@ export class DashboardView extends ObservableReactComponent<{}> {
onContextMenu={e => this.onContextMenu(dashboard, e)}
onClick={e => this.clickDashboard(e, dashboard)}>
<img
+ alt=""
src={
href ??
'https://media.istockphoto.com/photos/hot-air-balloons-flying-over-the-botan-canyon-in-turkey-picture-id1297349747?b=1&k=20&m=1297349747&s=170667a&w=0&h=oH31fJty_4xWl_JQ4OIQWZKP8C6ji9Mz7L4XmEnbqRU='
}
/>
<div className="info">
- <EditableText type={Type.PRIM} color={color} val={StrCast(dashboard.title)} setVal={val => (dashboard[DocData].title = val)} />
- {this.selectedDashboardGroup === DashboardGroup.SharedDashboards && this.isUnviewedSharedDashboard(dashboard) ? <div>unviewed</div> : <div></div>}
+ <EditableText
+ type={Type.PRIM}
+ color={color}
+ val={StrCast(dashboard.title)}
+ setVal={val => {
+ dashboard[DocData].title = val;
+ }}
+ />
+ {this.selectedDashboardGroup === DashboardGroup.SharedDashboards && this.isUnviewedSharedDashboard(dashboard) ? <div>unviewed</div> : <div />}
<div
className="more"
onPointerDown={e => {
@@ -187,7 +245,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
<div
className="background"
style={{
- background: SettingsManager.userColor,
+ background: SnappingManager.userColor,
filter: 'opacity(0.2)',
}}
/>
@@ -201,7 +259,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
<div
className="background"
style={{
- background: SettingsManager.userColor,
+ background: SnappingManager.userColor,
filter: 'opacity(0.2)',
}}
/>
@@ -209,7 +267,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
)}
</div>
</div>
- <MainViewModal contents={this.namingInterface} isDisplayed={this.openModal} interactive={true} closeOnExternalClick={this.abortCreateNewDashboard} dialogueBoxStyle={{ width: '400px', height: '180px', color: Colors.LIGHT_GRAY }} />
+ <MainViewModal contents={this.namingInterface} isDisplayed={this.openModal} interactive closeOnExternalClick={this.abortCreateNewDashboard} dialogueBoxStyle={{ width: '400px', height: '180px', color: Colors.LIGHT_GRAY }} />
</>
);
}
@@ -217,9 +275,6 @@ export class DashboardView extends ObservableReactComponent<{}> {
public static closeActiveDashboard() {
Doc.ActiveDashboard = undefined;
}
- public static snapshotDashboard() {
- return CollectionDockingView.TakeSnapshot(Doc.ActiveDashboard);
- }
public static openSharedDashboard = (dashboard: Doc) => {
Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard);
@@ -250,16 +305,12 @@ export class DashboardView extends ObservableReactComponent<{}> {
});
if (state.readonly === true || state.readonly === null) {
DocServer.Control.makeReadOnly();
- } else if (state.safe) {
- if (!state.nro) {
- DocServer.Control.makeReadOnly();
- }
- CollectionView.SetSafeMode(true);
} else if (state.nro || state.nro === null || state.readonly === false) {
+ /* empty */
} else if (doc.readOnly) {
DocServer.Control.makeReadOnly();
} else {
- Doc.CurrentUserEmail !== 'guest' && DocServer.Control.makeEditable();
+ ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Control.makeEditable();
}
}
@@ -278,7 +329,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
public static resetDashboard = (dashboard: Doc) => {
const config = StrCast(dashboard.dockingConfig);
- const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const matches = config.match(/"documentId":"[a-z0-9-]+"/g);
const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) ?? [];
const components =
@@ -372,12 +423,12 @@ export class DashboardView extends ObservableReactComponent<{}> {
title: `Untitled Tab 1`,
};
- const title = name ? name : `Dashboard ${dashboardCount}`;
+ const title = name || `Dashboard ${dashboardCount}`;
const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
- const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
+ const dashboardDoc = DashboardView.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc, undefined, undefined, true);
- dashboardDoc['pane-count'] = 1;
+ dashboardDoc.pane_count = 1;
freeformDoc.embedContainer = dashboardDoc;
dashboardDoc.myOverlayDocs = new List<Doc>();
dashboardDoc.myPublishedDocs = new List<Doc>();
@@ -473,23 +524,23 @@ export class DashboardView extends ObservableReactComponent<{}> {
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function createNewDashboard() {
return DashboardView.createNewDashboard();
}, 'creates a new dashboard when called');
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function shareDashboard(dashboard: Doc) {
- SharingManager.Instance.open(undefined, dashboard);
+ DocumentView.ShareOpen(undefined, dashboard);
}, 'opens sharing dialog for Dashboard');
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function removeDashboard(dashboard: Doc) {
DashboardView.removeDashboard(dashboard);
}, 'Remove Dashboard from Dashboards');
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function resetDashboard(dashboard: Doc) {
DashboardView.resetDashboard(dashboard);
}, 'move all dashboard tabs to single stack');
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function addToDashboards(dashboard: Doc) {
DashboardView.openDashboard(Doc.MakeEmbedding(dashboard));
}, 'adds Dashboard to set of Dashboards');
-ScriptingGlobals.add(async function snapshotDashboard() {
- const batch = UndoManager.StartBatch('snapshot');
- await DashboardView.snapshotDashboard();
- batch.end();
-}, 'creates a snapshot copy of a dashboard');
diff --git a/src/client/views/DictationOverlay.tsx b/src/client/views/DictationOverlay.tsx
index e098bc361..b242acdba 100644
--- a/src/client/views/DictationOverlay.tsx
+++ b/src/client/views/DictationOverlay.tsx
@@ -7,14 +7,14 @@ import { MainViewModal } from './MainViewModal';
@observer
export class DictationOverlay extends React.Component {
+ // eslint-disable-next-line no-use-before-define
public static Instance: DictationOverlay;
@observable private _dictationState = DictationManager.placeholder;
@observable private _dictationSuccessState: boolean | undefined = undefined;
@observable private _dictationDisplayState = false;
@observable private _dictationListeningState: DictationManager.Controls.ListeningUIStatus = false;
- public isPointerDown = false;
- public overlayTimeout: NodeJS.Timeout | undefined;
+ // eslint-disable-next-line react/no-unused-class-component-methods
public hasActiveModal = false;
constructor(props: any) {
@@ -23,47 +23,32 @@ export class DictationOverlay extends React.Component {
DictationOverlay.Instance = this;
}
- public initiateDictationFade = () => {
- const duration = DictationManager.Commands.dictationFadeDuration;
- this.overlayTimeout = setTimeout(() => {
- this.dictationOverlayVisible = false;
- this.dictationSuccess = undefined;
- DictationOverlay.Instance.hasActiveModal = false;
- setTimeout(() => (this.dictatedPhrase = DictationManager.placeholder), 500);
- }, duration);
- };
- public cancelDictationFade = () => {
- if (this.overlayTimeout) {
- clearTimeout(this.overlayTimeout);
- this.overlayTimeout = undefined;
- }
- };
-
- @computed public get dictatedPhrase() {
- return this._dictationState;
- }
- @computed public get dictationSuccess() {
- return this._dictationSuccessState;
- }
- @computed public get dictationOverlayVisible() {
- return this._dictationDisplayState;
- }
- @computed public get isListening() {
- return this._dictationListeningState;
- }
-
+ @computed public get dictatedPhrase() { return this._dictationState; } // prettier-ignore
public set dictatedPhrase(value: string) {
- runInAction(() => (this._dictationState = value));
+ runInAction(() => {
+ this._dictationState = value;
+ });
}
+ @computed public get dictationSuccess() { return this._dictationSuccessState; } // prettier-ignore
public set dictationSuccess(value: boolean | undefined) {
- runInAction(() => (this._dictationSuccessState = value));
+ runInAction(() => { this._dictationSuccessState = value; }); // prettier-ignore
}
+ @computed public get dictationOverlayVisible() { return this._dictationDisplayState; } // prettier-ignore
public set dictationOverlayVisible(value: boolean) {
- runInAction(() => (this._dictationDisplayState = value));
+ runInAction(() => { this._dictationDisplayState = value; }); // prettier-ignore
}
+ @computed public get isListening() { return this._dictationListeningState; } // prettier-ignore
public set isListening(value: DictationManager.Controls.ListeningUIStatus) {
- runInAction(() => (this._dictationListeningState = value));
+ runInAction(() => { this._dictationListeningState = value; }); // prettier-ignore
}
+ public initiateDictationFade = () => {
+ setTimeout(() => {
+ this.dictationOverlayVisible = false;
+ this.dictationSuccess = undefined;
+ DictationOverlay.Instance.hasActiveModal = false;
+ setTimeout(() => { this.dictatedPhrase = DictationManager.placeholder; }, 500); // prettier-ignore
+ }, DictationManager.Commands.dictationFadeDuration);
+ };
render() {
const success = this.dictationSuccess;
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index a25a8f77a..e5752dcd2 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -1,64 +1,18 @@
import { action, computed, makeObservable, observable } from 'mobx';
import * as React from 'react';
-import { returnFalse } from '../../Utils';
+import { returnFalse } from '../../ClientUtils';
import { DateField } from '../../fields/DateField';
-import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
+import { Doc, DocListCast, Opt } from '../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, DocData } from '../../fields/DocSymbols';
import { List } from '../../fields/List';
+import { toList } from '../../fields/Types';
import { GetEffectiveAcl, inheritParentAcls } from '../../fields/util';
import { DocumentType } from '../documents/DocumentTypes';
-import { DocUtils } from '../documents/Documents';
-import { DocumentManager } from '../util/DocumentManager';
import { ObservableReactComponent } from './ObservableReactComponent';
-import { CollectionFreeFormView } from './collections/collectionFreeForm';
-import { FieldViewProps, FocusViewOptions } from './nodes/FieldView';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
-import { PinProps } from './nodes/trails';
-import { RefField } from '../../fields/RefField';
-import { DragManager } from '../util/DragManager';
+import { ViewBoxInterface } from './ViewBoxInterface';
+import { FieldViewProps } from './nodes/FieldView';
/**
- * Shared interface among all viewBox'es (ie, react classes that render the contents of a Doc)
- * Many of these methods only make sense for specific viewBox'es, but they should be written to
- * be as general as possible
- */
-export interface ViewBoxInterface {
- fieldKey?: string;
- annotationKey?: string;
- 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)
- restoreView?: (viewSpec: Doc) => boolean;
- scrollPreview?: (docView: DocumentView, doc: Doc, focusSpeed: number, options: FocusViewOptions) => Opt<number>; // returns the duration of the focus
- brushView?: (view: { width: number; height: number; panX: number; panY: number }, transTime: number, holdTime: number) => void; // highlight a region of a view (used by freeforms)
- getView?: (doc: Doc, options: FocusViewOptions) => Promise<Opt<DocumentView>>; // returns a nested DocumentView for the specified doc or undefined
- addDocTab?: (doc: Doc, where: OpenWhere) => boolean; // determines how to add a document - used in following links to open the target ina local lightbox
- addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean; // add a document (used only by collections)
- removeDocument?: (doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean, dontAddToRemoved?: boolean) => boolean; // add a document (used only by collections)
- select?: (ctrlKey: boolean, shiftKey: boolean) => void;
- focus?: (textAnchor: Doc, options: FocusViewOptions) => Opt<number>;
- viewTransition?: () => Opt<string>; // duration of a view transition animation
- isAnyChildContentActive?: () => boolean; // is any child content of the document active
- onClickScriptDisable?: () => 'never' | 'always'; // disable click scripts : never, always, or undefined = only when selected
- getKeyFrameEditing?: () => boolean; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
- setKeyFrameEditing?: (set: boolean) => void; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
- playFrom?: (time: number, endTime?: number) => void;
- Pause?: () => void; // pause a media document (eg, audio/video)
- IsPlaying?: () => boolean; // is a media document playing
- TogglePause?: (keep?: boolean) => void; // toggle media document playing state
- setFocus?: () => void; // sets input focus to the componentView
- setData?: (data: Field | Promise<RefField | undefined>) => boolean;
- componentUI?: (boundsLeft: number, boundsTop: number) => JSX.Element | null;
- dragStarting?: (snapToDraggedDoc: boolean, showGroupDragTarget: boolean, visited: Set<Doc>) => void;
- dragConfig?: (dragData: DragManager.DocumentDragData) => void; // function to setup dragData in custom way (see TreeViews which add a tree view flag)
- incrementalRendering?: () => void;
- infoUI?: () => JSX.Element | null;
- screenBounds?: () => Opt<{ left: number; top: number; right: number; bottom: number; transition?: string }>;
- ptToScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
- ptFromScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
- snapPt?: (pt: { X: number; Y: number }, excludeSegs?: number[]) => { nearestPt: { X: number; Y: number }; distance: number };
- search?: (str: string, bwd?: boolean, clear?: boolean) => boolean;
-}
-/**
* DocComponent returns a React base class used by Doc views with accessors for unpacking the Document,layoutDoc, and dataDoc's
* (note: this should not be used for the 'Box' views that render the contents of Doc views)
* Example derived views: CollectionFreeFormDocumentView, DocumentView, DocumentViewInternal)
@@ -75,15 +29,25 @@ export function DocComponent<P extends DocComponentProps>() {
makeObservable(this);
}
- //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then
+ /**
+ * This is the document being rendered. In the case of a compound template, it
+ * may not be the actual document rendered and it also may not be the 'real' root document.
+ * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,)
+ */
get Document() {
return this._props.Document;
}
- // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info
+
+ /**
+ * This is the document being rendered. It may be a template so it may or may no inherit from the data doc.
+ */
@computed get layoutDoc() {
return this._props.LayoutTemplateString ? this.Document : Doc.Layout(this.Document, this._props.LayoutTemplate?.());
}
- // This is the data part of a document -- ie, the data that is constant across all views of the document
+
+ /**
+ * This is the unique data repository for a dcoument that stores the intrinsic document data
+ */
@computed get dataDoc() {
return this.Document[DocData];
}
@@ -98,7 +62,7 @@ export function DocComponent<P extends DocComponentProps>() {
* Example views include: InkingStroke, FontIconBox, EquationBox, etc
*/
export function ViewBoxBaseComponent<P extends FieldViewProps>() {
- class Component extends ObservableReactComponent<React.PropsWithChildren<P>> {
+ class Component extends ViewBoxInterface<P> {
constructor(props: P) {
super(props);
makeObservable(this);
@@ -109,19 +73,32 @@ export function ViewBoxBaseComponent<P extends FieldViewProps>() {
get DocumentView() {
return this._props.DocumentView;
}
- //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then
+
+ /**
+ * This is the document being rendered. In the case of a compound template, it
+ * may not be the actual document rendered and it also may not be the 'real' root document.
+ * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,)
+ */
get Document() {
return this._props.Document;
}
- // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info
+ /**
+ * This is the document being rendered. It may be a template so it may or may no inherit from the data doc.
+ */
@computed get layoutDoc() {
return Doc.Layout(this.Document);
}
- // This is the data part of a document -- ie, the data that is constant across all views of the document
+
+ /**
+ * 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];
}
- // key where data is stored
+
+ /**
+ * this is the field key where the primary rendering data is stored for the layout doc (e.g., it's often the 'data' field for a collection, or the 'text' field for rich text)
+ */
get fieldKey() {
return this._props.fieldKey;
}
@@ -140,7 +117,7 @@ export function ViewBoxBaseComponent<P extends FieldViewProps>() {
* Example views include: PDFBox, ImageBox, MapBox, etc
*/
export function ViewBoxAnnotatableComponent<P extends FieldViewProps>() {
- class Component extends ObservableReactComponent<React.PropsWithChildren<P>> {
+ class Component extends ViewBoxInterface<P> {
@observable _annotationKeySuffix = () => 'annotations';
@observable _isAnyChildContentActive = false;
@@ -154,32 +131,46 @@ export function ViewBoxAnnotatableComponent<P extends FieldViewProps>() {
get DocumentView() {
return this._props.DocumentView;
}
- //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then
+
+ /**
+ * This is the document being rendered. In the case of a compound template, it
+ * may not be the actual document rendered and it also may not be the 'real' root document.
+ * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,)
+ */
@computed get Document() {
return this._props.Document;
}
- // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info
+ /**
+ * This is the document being rendered. It may be a template so it may or may no inherit from the data doc.
+ */
@computed get layoutDoc() {
return Doc.Layout(this.Document);
}
- // This is the data part of a document -- ie, the data that is constant across all views of the document
+
+ /**
+ * 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];
}
- // key where data is stored
+ /**
+ * this is the field key where the primary rendering data is stored for the layout doc (e.g., it's often the 'data' field for a collection, or the 'text' field for rich text)
+ */
@computed get fieldKey() {
return this._props.fieldKey;
}
+
+ /**
+ * this is field key where the list of annotations is stored
+ */
@computed public get annotationKey() {
return this.fieldKey + (this._annotationKeySuffix() ? '_' + this._annotationKeySuffix() : '');
}
- @action.bound
- removeDocument(doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean, dontAddToRemoved?: boolean): boolean {
+ override removeDocument = (docIn: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean, dontAddToRemoved?: boolean): boolean => {
const effectiveAcl = GetEffectiveAcl(this.dataDoc);
- const indocs = doc instanceof Doc ? [doc] : doc;
- const docs = indocs.filter(doc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(doc) === AclAdmin);
+ const docs = toList(docIn).filter(fdoc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(fdoc) === AclAdmin);
// docs.forEach(doc => doc.annotationOn === this.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true));
const targetDataDoc = this.Document[DocData]; // this.dataDoc; // we want to write to the template, not the actual data doc
@@ -188,44 +179,39 @@ export function ViewBoxAnnotatableComponent<P extends FieldViewProps>() {
if (toRemove.length !== 0) {
const recentlyClosed = this.Document !== Doc.MyRecentlyClosed ? Doc.MyRecentlyClosed : undefined;
- toRemove.forEach(doc => {
- leavePushpin && DocUtils.LeavePushpin(doc, annotationKey ?? this.annotationKey);
- Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, doc, true);
- doc.embedContainer = undefined;
- if (recentlyClosed && !dontAddToRemoved && doc.type !== DocumentType.LOADING) {
- Doc.AddDocToList(recentlyClosed, 'data', doc, undefined, true, true);
- Doc.RemoveEmbedding(doc, doc);
+ toRemove.forEach(rdoc => {
+ // leavePushpin && DocUtils.LeavePushpin(doc, annotationKey ?? this.annotationKey);
+ Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, rdoc, true);
+ rdoc.embedContainer = undefined;
+ if (recentlyClosed && !dontAddToRemoved && rdoc.type !== DocumentType.LOADING) {
+ Doc.AddDocToList(recentlyClosed, 'data', rdoc, undefined, true, true);
+ Doc.RemoveEmbedding(rdoc, rdoc);
}
});
- if (targetDataDoc.isGroup && DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]).length < 2) {
- (DocumentManager.Instance.getFirstDocumentView(targetDataDoc)?.ComponentView as CollectionFreeFormView)?.promoteCollection();
- } else {
- this.isAnyChildContentActive() && this._props.select(false);
- }
+ this.isAnyChildContentActive() && this._props.select(false);
return true;
}
return false;
- }
+ };
// this is called with the document that was dragged and the collection to move it into.
// if the target collection is the same as this collection, then the move will be allowed.
// otherwise, the document being moved must be able to be removed from its container before
// moving it into the target.
- @action.bound
- moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string): boolean => {
+ moveDocument = (docs: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string): boolean => {
if (Doc.AreProtosEqual(this._props.Document, targetCollection)) {
return true;
}
- const first = doc instanceof Doc ? doc : doc[0];
+ const first = toList(docs)[0];
if (!first?._dragOnlyWithinContainer && addDocument !== returnFalse) {
- return this.removeDocument(doc, annotationKey, false, true) && addDocument(doc, annotationKey);
+ return this.removeDocument(docs, annotationKey, false, true) && addDocument(docs, annotationKey);
}
return false;
};
- @action.bound
- addDocument = (doc: Doc | Doc[], annotationKey?: string): boolean => {
- const docs = doc instanceof Doc ? [doc] : doc;
- if (this._props.filterAddDocument?.(docs) === false || docs.find(doc => Doc.AreProtosEqual(doc, this.Document) && Doc.LayoutField(doc) === Doc.LayoutField(this.Document))) {
+
+ override addDocument = (docIn: Doc | Doc[], annotationKey?: string): boolean => {
+ const docs = toList(docIn);
+ if (this._props.filterAddDocument?.(docs) === false || docs.find(fdoc => Doc.AreProtosEqual(fdoc, this.Document) && Doc.LayoutField(fdoc) === Doc.LayoutField(this.Document))) {
return false;
}
const targetDataDoc = this.Document[DocData]; // this.dataDoc; // we want to write to the template, not the actual data doc
@@ -237,17 +223,17 @@ export function ViewBoxAnnotatableComponent<P extends FieldViewProps>() {
const added = docs;
if (added.length) {
if ([AclAugment, AclEdit, AclAdmin].includes(effectiveAcl)) {
- added.forEach(doc => {
- doc._dragOnlyWithinContainer = undefined;
- if (annotationKey ?? this._annotationKeySuffix()) doc[DocData].annotationOn = this.Document;
- else doc[DocData].annotationOn = undefined;
- Doc.SetContainer(doc, this.Document);
- inheritParentAcls(targetDataDoc, doc, true);
+ added.forEach(adoc => {
+ adoc._dragOnlyWithinContainer = undefined;
+ if (annotationKey ?? this._annotationKeySuffix()) adoc[DocData].annotationOn = this.Document;
+ else adoc[DocData].annotationOn = undefined;
+ Doc.SetContainer(adoc, this.Document);
+ inheritParentAcls(targetDataDoc, adoc, true);
});
const annoDocs = Doc.Get(targetDataDoc, annotationKey ?? this.annotationKey, true) as List<Doc>; // get the dataDoc directly ... when using templates there may be some default items already there, but we can't change them, so we copy them below (should really be some kind of inheritance since the template contents could change)
if (annoDocs instanceof List) annoDocs.push(...added.filter(add => !annoDocs.includes(add)));
- else targetDataDoc[annotationKey ?? this.annotationKey] = new List<Doc>([...added, ...(annoDocs === undefined ? DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]) : [])]);
+ else targetDataDoc[annotationKey || this.annotationKey] = new List<Doc>([...added, ...(annoDocs === undefined ? DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]) : [])]);
targetDataDoc[(annotationKey ?? this.annotationKey) + '_modificationDate'] = new DateField();
}
}
@@ -256,7 +242,10 @@ export function ViewBoxAnnotatableComponent<P extends FieldViewProps>() {
isAnyChildContentActive = () => this._isAnyChildContentActive;
- whenChildContentsActiveChanged = action((isActive: boolean) => this._props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive)));
+ whenChildContentsActiveChanged = action((isActive: boolean) => {
+ this._isAnyChildContentActive = isActive;
+ this._props.whenChildContentsActiveChanged(isActive);
+ });
}
return Component;
}
diff --git a/src/client/views/DocViewUtils.ts b/src/client/views/DocViewUtils.ts
new file mode 100644
index 000000000..1f5f29c7e
--- /dev/null
+++ b/src/client/views/DocViewUtils.ts
@@ -0,0 +1,21 @@
+/* eslint-disable prefer-destructuring */
+/* eslint-disable default-param-last */
+/* eslint-disable no-use-before-define */
+import { runInAction } from 'mobx';
+import { Doc, SetActiveAudioLinker } from '../../fields/Doc';
+import { DocUtils } from '../documents/DocUtils';
+import { FieldViewProps } from './nodes/FieldView';
+
+export namespace DocViewUtils {
+ export const ActiveRecordings: { props: FieldViewProps; getAnchor: (addAsAnnotation: boolean) => Doc }[] = [];
+
+ export function MakeLinkToActiveAudio(getSourceDoc: () => Doc | undefined, broadcastEvent = true) {
+ broadcastEvent && runInAction(() => { Doc.RecordingEvent += 1; }); // prettier-ignore
+ return ActiveRecordings.map(audio => {
+ const sourceDoc = getSourceDoc();
+ return sourceDoc && DocUtils.MakeLink(sourceDoc, audio.getAnchor(true) || audio.props.Document, { link_relationship: 'recording annotation:linked recording', link_description: 'recording timeline' });
+ });
+ }
+
+ SetActiveAudioLinker(MakeLinkToActiveAudio);
+}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index d65e0b406..487868169 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -1,37 +1,42 @@
+/* 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';
import { Tooltip } from '@mui/material';
-import { action, computed, makeObservable, observable, runInAction } from 'mobx';
+import { Popup } from 'browndash-components';
+import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../Utils';
+import { FaEdit } from 'react-icons/fa';
+import { returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../ClientUtils';
+import { emptyFunction } from '../../Utils';
import { Doc } from '../../fields/Doc';
import { Cast, DocCast } from '../../fields/Types';
-import { DocUtils } from '../documents/Documents';
+import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils';
import { CalendarManager } from '../util/CalendarManager';
-import { DragManager, dropActionType } from '../util/DragManager';
-import { IsFollowLinkScript } from '../util/LinkFollower';
-import { SelectionManager } from '../util/SelectionManager';
+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 './DocumentButtonBar.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
-import { TabDocView } from './collections/TabDocView';
+import { PinProps } from './PinFuncs';
+import { TemplateMenu } from './TemplateMenu';
import { Colors } from './global/globalEnums';
import { LinkPopup } from './linking/LinkPopup';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
-import { DocumentView, DocumentViewInternal, OpenWhere } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
import { DashFieldView } from './nodes/formattedText/DashFieldView';
-import { PinProps } from './nodes/trails';
-import { faCalendarDays } from '@fortawesome/free-solid-svg-icons';
-import { Popup } from 'browndash-components';
-import { TemplateMenu } from './TemplateMenu';
-import { FaEdit } from 'react-icons/fa';
@observer
export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (DocumentView | undefined)[]; stack?: any }> {
private _dragRef = React.createRef<HTMLDivElement>();
- @observable public static Instance: DocumentButtonBar;
+ // eslint-disable-next-line no-use-before-define
+ public static Instance: DocumentButtonBar;
constructor(props: any) {
super(props);
@@ -43,7 +48,6 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
return this._props.views()?.[0];
}
- @observable subFollow = '';
@computed
get followLinkButton() {
const targetDoc = this.view0?.Document;
@@ -58,8 +62,12 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
key={icon.toString()}
size="sm"
icon={icon}
- onPointerEnter={action(e => (this.subPin = allDocs ? 'All ' : ''))}
- onPointerLeave={action(e => (this.subPin = ''))}
+ onPointerEnter={action(() => {
+ this.subPin = allDocs ? 'All ' : '';
+ })}
+ onPointerLeave={action(() => {
+ this.subPin = '';
+ })}
onClick={e => {
this._props.views().forEach(dv => click(dv!.Document));
e.stopPropagation();
@@ -75,12 +83,14 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
<div
className="documentButtonBar-icon documentButtonBar-follow"
style={{ backgroundColor: followLink ? Colors.LIGHT_BLUE : Colors.DARK_GRAY, color: followLink ? Colors.BLACK : Colors.WHITE }}
- onClick={undoBatch(e => this._props.views().map(view => view?.toggleFollowLink(undefined, false)))}>
+ onClick={undoBatch(() => this._props.views().map(view => view?.toggleFollowLink(undefined, false)))}>
<div className="documentButtonBar-followTypes">
{followBtn(
true,
- (doc: Doc) => (doc.followAllLinks = !doc.followAllLinks),
- (doc?: Doc) => (doc?.followAllLinks ? true : false),
+ (doc: Doc) => {
+ doc.followAllLinks = !doc.followAllLinks;
+ },
+ (doc?: Doc) => !!doc?.followAllLinks,
'window-maximize'
)}
</div>
@@ -98,22 +108,22 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
<div className="documentButtonBar-linkTypes">
<Tooltip title={<div>search for target</div>}>
<div className="documentButtonBar-button">
- <button style={{ backgroundColor: 'transparent', width: 35, height: 35, display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative' }} onPointerDown={this.toggleLinkSearch}>
- <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(1.5)' }} icon={'search'} size="lg" />
- <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(0.5)', transformOrigin: 'center', top: 9, left: 2 }} icon={'link'} size="lg" />
+ <button type="button" style={{ backgroundColor: 'transparent', width: 35, height: 35, display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative' }} onPointerDown={this.toggleLinkSearch}>
+ <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(1.5)' }} icon="search" size="lg" />
+ <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(0.5)', transformOrigin: 'center', top: 9, left: 2 }} icon="link" size="lg" />
</button>
</div>
</Tooltip>
<Tooltip title={<div>open linked trail</div>}>
<div className="documentButtonBar-button">
- <button style={{ backgroundColor: 'transparent', width: 35, height: 35, display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative' }} onPointerDown={this.toggleTrail}>
+ <button type="button" style={{ backgroundColor: 'transparent', width: 35, height: 35, display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative' }} onPointerDown={this.toggleTrail}>
<FontAwesomeIcon icon="taxi" size="lg" />
</button>
</div>
</Tooltip>
</div>
<div style={{ width: 25, height: 25 }}>
- <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={true} />
+ <DocumentLinksButton View={this.view0} AlwaysOn InMenu StartLink />
</div>
</div>
);
@@ -132,8 +142,12 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
key={icon.toString()}
size="sm"
icon={icon}
- onPointerEnter={action(e => (this.subEndLink = (pinLayout ? 'Layout' : '') + (pinLayout && pinContent ? ' &' : '') + (pinContent ? ' Content' : '')))}
- onPointerLeave={action(e => (this.subEndLink = ''))}
+ onPointerEnter={action(() => {
+ this.subEndLink = (pinLayout ? 'Layout' : '') + (pinLayout && pinContent ? ' &' : '') + (pinContent ? ' Content' : '');
+ })}
+ onPointerLeave={action(() => {
+ this.subEndLink = '';
+ })}
onClick={e => {
this.view0 &&
DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.view0.Document, true, this.view0, {
@@ -155,7 +169,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
{linkBtn(false, true, 'address-card')}
{linkBtn(true, true, 'id-card')}
</div>
- <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={false} />
+ <DocumentLinksButton View={this.view0} AlwaysOn InMenu StartLink={false} />
</div>
);
}
@@ -175,21 +189,22 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
key={icon.toString()}
size="sm"
icon={icon}
- onPointerEnter={action(
- e =>
- (this.subPin =
- (pinLayoutView ? 'Layout' : '') +
- (pinLayoutView && pinContentView ? ' &' : '') +
- (pinContentView ? ' Content View' : '') +
- (pinLayoutView && pinContentView ? '(shift+alt)' : pinLayoutView ? '(shift)' : pinContentView ? '(alt)' : ''))
- )}
- onPointerLeave={action(e => (this.subPin = ''))}
+ onPointerEnter={action(() => {
+ this.subPin =
+ (pinLayoutView ? 'Layout' : '') +
+ (pinLayoutView && pinContentView ? ' &' : '') +
+ (pinContentView ? ' Content View' : '') +
+ (pinLayoutView && pinContentView ? '(shift+alt)' : pinLayoutView ? '(shift)' : pinContentView ? '(alt)' : '');
+ })}
+ onPointerLeave={action(() => {
+ this.subPin = '';
+ })}
onClick={e => {
const docs = this._props
.views()
.filter(v => v)
.map(dv => dv!.Document);
- TabDocView.PinDoc(docs, {
+ DocumentView.PinDoc(docs, {
pinAudioPlay: true,
pinDocLayout: pinLayoutView,
pinData: { dataview: pinContentView },
@@ -204,7 +219,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
);
};
return !targetDoc ? null : (
- <Tooltip title={<div className="dash-tooltip">{`Pin Document ${SelectionManager.Views.length > 1 ? 'multiple documents' : ''} to Trail`}</div>}>
+ <Tooltip title={<div className="dash-tooltip">{`Pin Document ${DocumentView.Selected().length > 1 ? 'multiple documents' : ''} to Trail`}</div>}>
<div
className="documentButtonBar-icon documentButtonBar-pin"
onClick={e => {
@@ -212,7 +227,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
.views()
.filter(v => v)
.map(dv => dv!.Document);
- TabDocView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: e.shiftKey, pinData: { dataview: e.altKey }, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
+ DocumentView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: e.shiftKey, pinData: { dataview: e.altKey }, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
e.stopPropagation();
}}>
<div className="documentButtonBar-pinTypes">
@@ -230,8 +245,8 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
get shareButton() {
const targetDoc = this.view0?.Document;
return !targetDoc ? null : (
- <Tooltip title={<div className="dash-tooltip">{'Open Sharing Manager'}</div>}>
- <div className="documentButtonBar-icon" style={{ color: 'white' }} onClick={e => SharingManager.Instance.open(this.view0, targetDoc)}>
+ <Tooltip title={<div className="dash-tooltip">Open Sharing Manager</div>}>
+ <div className="documentButtonBar-icon" style={{ color: 'white' }} onClick={() => SharingManager.Instance.open(this.view0, targetDoc)}>
<FontAwesomeIcon className="documentdecorations-icon" icon="users" />
</div>
</Tooltip>
@@ -242,8 +257,8 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
get menuButton() {
const targetDoc = this.view0?.Document;
return !targetDoc ? null : (
- <Tooltip title={<div className="dash-tooltip">{`Open Context Menu`}</div>}>
- <div className="documentButtonBar-icon" style={{ color: 'white', cursor: 'pointer' }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => this.openContextMenu(e))}>
+ <Tooltip title={<div className="dash-tooltip">Open Context Menu</div>}>
+ <div className="documentButtonBar-icon" style={{ color: 'white', cursor: 'pointer' }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => this.openContextMenu(clickEv))}>
<FontAwesomeIcon className="documentdecorations-icon" icon="bars" />
</div>
</Tooltip>
@@ -258,8 +273,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
<div
className="documentButtonBar-icon"
style={{ color: 'white' }}
- onClick={e => {
- console.log('hi: ', CalendarManager.Instance);
+ onClick={() => {
CalendarManager.Instance.open(this.view0, targetDoc);
}}>
<FontAwesomeIcon className="documentdecorations-icon" icon={faCalendarDays as IconLookup} />
@@ -280,7 +294,18 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
style={{ backgroundColor: this._isRecording ? Colors.ERROR_RED : Colors.DARK_GRAY, color: Colors.WHITE }}
onPointerDown={action((e: React.PointerEvent) => {
this._isRecording = true;
- this._props.views().map(view => view && DocumentViewInternal.recordAudioAnnotation(view.dataDoc, view.LayoutFieldKey, stopFunc => (this._stopFunc = stopFunc), emptyFunction));
+ this._props.views().map(
+ view =>
+ view &&
+ DictationManager.recordAudioAnnotation(
+ view.dataDoc,
+ view.LayoutFieldKey,
+ stopFunc => {
+ this._stopFunc = stopFunc;
+ },
+ emptyFunction
+ )
+ );
const b = UndoManager.StartBatch('Recording');
setupMoveUpEvents(
this,
@@ -308,10 +333,10 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
if (this._dragRef.current) {
const dragDocView = this.view0!;
const dragData = new DragManager.DocumentDragData([dragDocView.Document]);
- const [left, top] = dragDocView.screenToContentsTransform().inverse().transformPoint(0, 0);
+ const origin = dragDocView.screenToContentsTransform().inverse().transformPoint(0, 0);
dragData.defaultDropAction = dropActionType.embed;
dragData.canEmbed = true;
- DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, { hideSource: false });
+ DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, origin[0], origin[1], { hideSource: false });
return true;
}
return false;
@@ -334,8 +359,19 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
@computed
get templateButton() {
return !this.view0 ? null : (
- <Tooltip title={<div className="dash-tooltip">Tap to Customize Layout. Drag an embedding</div>} open={this._tooltipOpen} onClose={action(() => (this._tooltipOpen = false))} placement="bottom">
- <div className="documentButtonBar-linkFlyout" ref={this._dragRef} onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}>
+ <Tooltip
+ title={<div className="dash-tooltip">Tap to Customize Layout. Drag an embedding</div>}
+ open={this._tooltipOpen}
+ onClose={action(() => {
+ this._tooltipOpen = false;
+ })}
+ placement="bottom">
+ <div
+ className="documentButtonBar-linkFlyout"
+ ref={this._dragRef}
+ onPointerEnter={action(() => {
+ !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true);
+ })}>
<Popup icon={<FaEdit />} popup={this.templateMenu} popupContainsPt={returnTrue} />
</div>
</Tooltip>
@@ -343,7 +379,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
}
openContextMenu = (e: PointerEvent) => {
- let child = SelectionManager.Views[0].ContentDiv!.children[0];
+ let child = DocumentView.Selected()[0].ContentDiv!.children[0];
while (child.children.length) {
const next = Array.from(child.children).find(c => c.className?.toString().includes('SVGAnimatedString') || typeof c.className === 'string');
if (next?.className?.toString().includes(DocumentView.ROOT_DIV)) break;
@@ -363,17 +399,17 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
@observable _captureEndLinkLayout = false;
@action
- captureEndLinkLayout = (e: React.PointerEvent) => {
+ captureEndLinkLayout = () => {
this._captureEndLinkLayout = !this._captureEndLinkLayout;
};
@observable _captureEndLinkContent = false;
@action
- captureEndLinkContent = (e: React.PointerEvent) => {
+ captureEndLinkContent = () => {
this._captureEndLinkContent = !this._captureEndLinkContent;
};
@action
- captureEndLinkState = (e: React.PointerEvent) => {
+ captureEndLinkState = () => {
this._captureEndLinkContent = this._captureEndLinkLayout = !this._captureEndLinkLayout;
};
@@ -400,28 +436,23 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
return (
<div className="documentButtonBar">
<div className="documentButtonBar-button">
- <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} ShowCount={true} />
+ <DocumentLinksButton View={this.view0} AlwaysOn InMenu ShowCount />
</div>
{this._showLinkPopup ? (
<div style={{ position: 'absolute', zIndex: 1000 }}>
- <LinkPopup
- key="popup"
- linkCreated={link => (link.link_displayLine = !IsFollowLinkScript(this._props.views().lastElement()?.Document.onClick))}
- linkCreateAnchor={() => this._props.views().lastElement()?.ComponentView?.getAnchor?.(true)}
- linkFrom={() => this._props.views().lastElement()?.Document}
- />
+ <LinkPopup key="popup" linkCreated={emptyFunction} linkCreateAnchor={() => this._props.views().lastElement()?.ComponentView?.getAnchor?.(true)} linkFrom={() => this._props.views().lastElement()?.Document} />
</div>
) : (
<div className="documentButtonBar-button">{this.linkButton}</div>
)}
{DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== doc ? <div className="documentButtonBar-button">{this.endLinkButton} </div> : null}
- {Doc.noviceMode ? null : <div className="documentButtonBar-button">{this.templateButton}</div>}
- {!SelectionManager.Views?.some(v => v.allLinks.length) ? null : <div className="documentButtonBar-button">{this.followLinkButton}</div>}
+ <div className="documentButtonBar-button">{this.templateButton}</div>
+ {!DocumentView.Selected().some(v => v.allLinks.length) ? null : <div className="documentButtonBar-button">{this.followLinkButton}</div>}
<div className="documentButtonBar-button">{this.pinButton}</div>
<div className="documentButtonBar-button">{this.recordButton}</div>
<div className="documentButtonBar-button">{this.calendarButton}</div>
- {!Doc.UserDoc()['documentLinksButton-fullMenu'] ? null : <div className="documentButtonBar-button">{this.shareButton}</div>}
+ {!Doc.UserDoc().documentLinksButton_fullMenu ? null : <div className="documentButtonBar-button">{this.shareButton}</div>}
<div className="documentButtonBar-button">{this.menuButton}</div>
</div>
);
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index ac0ef054c..239c0a977 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -14,7 +14,7 @@ $resizeHandler: 8px;
height: 30;
width: 30;
right: -40;
- bottom: -40;
+ bottom: -20;
//top: calc(50% - 15px);
position: absolute;
pointer-events: all;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 2fb9f0fc1..93c3e3338 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -5,20 +5,19 @@ import { action, computed, makeObservable, observable, runInAction } from 'mobx'
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaUndo } from 'react-icons/fa';
-import { Utils, emptyFunction, lightOrDark, numberValue, returnFalse, setupMoveUpEvents } from '../../Utils';
+import { lightOrDark, returnFalse, setupMoveUpEvents } from '../../ClientUtils';
+import { Utils, emptyFunction, numberValue } from '../../Utils';
import { DateField } from '../../fields/DateField';
-import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
+import { Doc, DocListCast, Field, FieldType, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols';
+import { Id } from '../../fields/FieldSymbols';
import { InkField } from '../../fields/InkField';
-import { RichTextField } from '../../fields/RichTextField';
import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { GetEffectiveAcl } from '../../fields/util';
import { DocumentType } from '../documents/DocumentTypes';
import { Docs } from '../documents/Documents';
-import { DocumentManager } from '../util/DocumentManager';
import { DragManager } from '../util/DragManager';
-import { SelectionManager } from '../util/SelectionManager';
import { SettingsManager } from '../util/SettingsManager';
import { SnappingManager } from '../util/SnappingManager';
import { UndoManager } from '../util/UndoManager';
@@ -26,13 +25,14 @@ import { DocumentButtonBar } from './DocumentButtonBar';
import './DocumentDecorations.scss';
import { InkStrokeProperties } from './InkStrokeProperties';
import { InkingStroke } from './InkingStroke';
-import { LightboxView } from './LightboxView';
import { ObservableReactComponent } from './ObservableReactComponent';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { Colors } from './global/globalEnums';
-import { DocumentView, OpenWhereMod } from './nodes/DocumentView';
+import { CollectionFreeFormDocumentView } from './nodes/CollectionFreeFormDocumentView';
+import { DocumentView } from './nodes/DocumentView';
import { ImageBox } from './nodes/ImageBox';
+import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
interface DocumentDecorationsProps {
@@ -43,6 +43,7 @@ interface DocumentDecorationsProps {
}
@observer
export class DocumentDecorations extends ObservableReactComponent<DocumentDecorationsProps> {
+ // eslint-disable-next-line no-use-before-define
static Instance: DocumentDecorations;
private _resizeHdlId = '';
private _keyinput = React.createRef<HTMLInputElement>();
@@ -57,7 +58,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@observable _showNothing = true;
@observable private _accumulatedTitle = '';
- @observable private _titleControlString: string = '#title';
+ @observable private _titleControlString: string = '$title';
@observable private _editingTitle = false;
@observable private _hidden = false;
@observable private _isRotating: boolean = false;
@@ -73,11 +74,18 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
DocumentDecorations.Instance = this;
document.addEventListener('pointermove', // show decorations whenever pointer moves outside of selection bounds.
action(e => {
+ let inputting = false;
+ if (this._titleControlString.startsWith('$')) {
+ const titleFieldKey = this._titleControlString.substring(1);
+ if (DocumentView.Selected()[0]?.Document[titleFieldKey] !== this._accumulatedTitle) {
+ inputting = true;
+ }
+ }
const center = {x: (this.Bounds.x+this.Bounds.r)/2, y: (this.Bounds.y+this.Bounds.b)/2};
const {x,y} = Utils.rotPt(e.clientX - center.x,
e.clientY - center.y,
- NumCast(SelectionManager.Views.lastElement()?.screenToViewTransform().Rotate));
- (this._showNothing = !DocumentButtonBar.Instance?._tooltipOpen && !(this.Bounds.x !== Number.MAX_VALUE && //
+ NumCast(DocumentView.Selected().lastElement()?.screenToViewTransform().Rotate));
+ (this._showNothing = !inputting && !DocumentButtonBar.Instance?._tooltipOpen && !(this.Bounds.x !== Number.MAX_VALUE && //
(this.Bounds.x > center.x+x || this.Bounds.r < center.x+x ||
this.Bounds.y > center.y+y || this.Bounds.b < center.y+y )));
})); // prettier-ignore
@@ -86,7 +94,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@computed get ClippedBounds() {
const bounds = { ...this.Bounds };
const leftBounds = this._props.boundsLeft;
- const topBounds = LightboxView.LightboxDoc ? 0 : this._props.boundsTop;
+ const topBounds = DocumentView.LightboxDoc() ? 0 : this._props.boundsTop;
bounds.x = Math.max(leftBounds, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2;
bounds.y = Math.max(topBounds, bounds.y - this._resizeBorderWidth / 2 - this._titleHeight) + this._resizeBorderWidth / 2 + this._titleHeight;
const borderRadiusDraggerWidth = 15;
@@ -98,7 +106,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@computed get Bounds() {
return (SnappingManager.IsLinkFollowing || SnappingManager.ExploreMode) ?
{ x: 0, y: 0, r: 0, b: 0 }
- : SelectionManager.Views
+ : DocumentView.Selected()
.filter(dv => dv._props.renderDepth > 0)
.map(dv => dv.getBounds)
.reduce((bounds, rect) => !rect ? bounds
@@ -111,46 +119,23 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@action
titleBlur = () => {
- if (this._accumulatedTitle.startsWith('#') || this._accumulatedTitle.startsWith('=')) {
+ if (this._accumulatedTitle.startsWith('$')) {
this._titleControlString = this._accumulatedTitle;
- } else if (this._titleControlString.startsWith('#')) {
+ } else if (this._titleControlString.startsWith('$')) {
if (this._accumulatedTitle.startsWith('-->#')) {
- SelectionManager.Docs.forEach(doc => (doc[DocData].onViewMounted = ScriptField.MakeScript(`updateTagsCollection(this)`)));
+ DocumentView.SelectedDocs().forEach(doc => {
+ doc[DocData].onViewMounted = ScriptField.MakeScript(`updateTagsCollection(this)`);
+ });
}
const titleFieldKey = this._titleControlString.substring(1);
UndoManager.RunInBatch(
() =>
titleFieldKey &&
- SelectionManager.Views.forEach(d => {
+ DocumentView.Selected().forEach(dv => {
if (titleFieldKey === 'title') {
- d.dataDoc.title_custom = !this._accumulatedTitle.startsWith('-');
- if (StrCast(d.Document.title).startsWith('@') && !this._accumulatedTitle.startsWith('@')) {
- Doc.RemFromMyPublished(d.Document);
- }
- if (!StrCast(d.Document.title).startsWith('@') && this._accumulatedTitle.startsWith('@')) {
- Doc.AddToMyPublished(d.Document);
- }
- }
- //@ts-ignore
- const titleField = +this._accumulatedTitle == this._accumulatedTitle ? +this._accumulatedTitle : this._accumulatedTitle;
-
- if (titleField.toString().startsWith('<this>')) {
- const title = titleField.toString().replace(/<this>\.?/, '');
- const curKey = Doc.LayoutFieldKey(d.Document);
- if (curKey !== title) {
- if (title) {
- if (d.dataDoc[title] === undefined || d.dataDoc[title] instanceof RichTextField || typeof d.dataDoc[title] === 'string') {
- d.Document.layout_fieldKey = `layout_${title}`;
- d.Document[`layout_${title}`] = FormattedTextBox.LayoutString(title);
- d.Document[`${title}_nativeWidth`] = d.Document[`${title}_nativeHeight`] = 0;
- }
- } else {
- d.Document.layout_fieldKey = undefined;
- }
- }
- } else {
- Doc.SetInPlace(d.Document, titleFieldKey, titleField, true);
+ dv.dataDoc.title_custom = !this._accumulatedTitle.startsWith('-');
}
+ Doc.SetField(dv.Document, titleFieldKey, this._accumulatedTitle);
}),
'edit title'
);
@@ -165,23 +150,24 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
};
onContainerDown = (e: React.PointerEvent) => {
- const effectiveLayoutAcl = GetEffectiveAcl(SelectionManager.Views[0].Document);
- if (effectiveLayoutAcl == AclAdmin || effectiveLayoutAcl == AclEdit || effectiveLayoutAcl == AclAugment) {
- setupMoveUpEvents(this, e, e => this.onBackgroundMove(true, e), emptyFunction, emptyFunction);
+ const effectiveLayoutAcl = GetEffectiveAcl(DocumentView.Selected()[0].Document);
+ if (effectiveLayoutAcl === AclAdmin || effectiveLayoutAcl === AclEdit || effectiveLayoutAcl === AclAugment) {
+ setupMoveUpEvents(this, e, moveEv => this.onBackgroundMove(true, moveEv), emptyFunction, emptyFunction);
e.stopPropagation();
}
};
onTitleDown = (e: React.PointerEvent) => {
- const effectiveLayoutAcl = GetEffectiveAcl(SelectionManager.Views[0].Document);
- if (effectiveLayoutAcl == AclAdmin || effectiveLayoutAcl == AclEdit || effectiveLayoutAcl == AclAugment) {
+ const effectiveLayoutAcl = GetEffectiveAcl(DocumentView.SelectedDocs()[0]);
+ if (effectiveLayoutAcl === AclAdmin || effectiveLayoutAcl === AclEdit || effectiveLayoutAcl === AclAugment) {
setupMoveUpEvents(
this,
e,
- e => this.onBackgroundMove(true, e),
+ moveEv => this.onBackgroundMove(true, moveEv),
emptyFunction,
- action(e => {
- !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString);
+ action(() => {
+ const selected = DocumentView.SelectedDocs().length === 1 ? DocumentView.SelectedDocs()[0] : undefined;
+ !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('$') ? (selected && Field.toKeyValueString(selected, this._titleControlString.substring(1))) || '-unset-' : this._titleControlString);
this._editingTitle = true;
this._keyinput.current && setTimeout(this._keyinput.current.focus);
})
@@ -191,24 +177,21 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
};
onBackgroundDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, e => this.onBackgroundMove(false, e), emptyFunction, emptyFunction);
+ setupMoveUpEvents(this, e, moveEv => this.onBackgroundMove(false, moveEv), emptyFunction, emptyFunction);
e.stopPropagation();
};
@action
onBackgroundMove = (dragTitle: boolean, e: PointerEvent): boolean => {
- const dragDocView = SelectionManager.Views[0];
+ const dragDocView = DocumentView.Selected()[0];
const effectiveLayoutAcl = GetEffectiveAcl(dragDocView.Document);
- if (effectiveLayoutAcl != AclAdmin && effectiveLayoutAcl != AclEdit && effectiveLayoutAcl != AclAugment) {
+ if (effectiveLayoutAcl !== AclAdmin && effectiveLayoutAcl !== AclEdit && effectiveLayoutAcl !== AclAugment) {
return false;
}
const containers = new Set<Doc | undefined>();
- SelectionManager.Views.forEach(v => containers.add(DocCast(v.Document.embedContainer)));
+ DocumentView.Selected().forEach(v => containers.add(DocCast(v.Document.embedContainer)));
if (containers.size > 1) return false;
const { left, top } = dragDocView.getBounds || { left: 0, top: 0 };
- const dragData = new DragManager.DocumentDragData(
- SelectionManager.Views.map(dv => dv.Document),
- dragDocView._props.dropAction
- );
+ const dragData = new DragManager.DocumentDragData(DocumentView.SelectedDocs(), dragDocView._props.dropAction);
dragData.offset = dragDocView.screenToContentsTransform().transformDirection(e.x - left, e.y - top);
dragData.moveDocument = dragDocView._props.moveDocument;
dragData.removeDocument = dragDocView._props.removeDocument;
@@ -216,12 +199,14 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
dragData.canEmbed = dragTitle;
this._hidden = true;
DragManager.StartDocumentDrag(
- SelectionManager.Views.map(dv => dv.ContentDiv!),
+ DocumentView.Selected().map(dv => dv.ContentDiv!),
dragData,
e.x,
e.y,
{
- dragComplete: action(e => (this._hidden = false)),
+ dragComplete: action(() => {
+ this._hidden = false;
+ }),
hideSource: true,
}
);
@@ -231,22 +216,23 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
_deleteAfterIconify = false;
_iconifyBatch: UndoManager.Batch | undefined;
onCloseClick = (forceDeleteOrIconify: boolean | undefined) => {
- const views = SelectionManager.Views.filter(v => v && v._props.renderDepth > 0);
+ const views = DocumentView.Selected().filter(v => v && v._props.renderDepth > 0);
if (forceDeleteOrIconify === false && this._iconifyBatch) return;
- this._deleteAfterIconify = forceDeleteOrIconify || this._iconifyBatch ? true : false;
- var iconifyingCount = views.length;
+ this._deleteAfterIconify = !!(forceDeleteOrIconify || this._iconifyBatch);
+ let iconifyingCount = views.length;
const finished = action((force?: boolean) => {
if ((force || --iconifyingCount === 0) && this._iconifyBatch) {
if (this._deleteAfterIconify) {
views.forEach(iconView => {
- Doc.setNativeView(iconView.Document);
- if (iconView.Document.activeFrame) {
- iconView.Document.opacity = 0; // bcz: hacky ... allows inkMasks and other documents to be "turned off" without removing them from the animated collection which allows them to function properly in a presenation.
+ const iconViewDoc = iconView.Document;
+ Doc.setNativeView(iconViewDoc);
+ if (iconViewDoc.activeFrame) {
+ iconViewDoc.opacity = 0; // bcz: hacky ... allows inkMasks and other documents to be "turned off" without removing them from the animated collection which allows them to function properly in a presenation.
} else {
iconView._props.removeDocument?.(iconView.Document);
}
});
- views.forEach(SelectionManager.DeselectView);
+ views.forEach(DocumentView.DeselectView);
}
this._iconifyBatch?.end();
this._iconifyBatch = undefined;
@@ -256,6 +242,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
(document.activeElement as any).blur?.();
this._iconifyBatch = UndoManager.StartBatch(forceDeleteOrIconify ? 'delete selected docs' : 'iconifying');
} else {
+ // eslint-disable-next-line no-param-reassign
forceDeleteOrIconify = false; // can't force immediate close in the middle of iconifying -- have to wait until iconifying completes
}
@@ -264,70 +251,66 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
};
onMaximizeDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, () => DragManager.StartWindowDrag?.(e, [SelectionManager.Views.lastElement().Document]) ?? false, emptyFunction, this.onMaximizeClick, false, false);
+ setupMoveUpEvents(this, e, () => DragManager.StartWindowDrag?.(e, [DocumentView.SelectedDocs().lastElement()]) ?? false, emptyFunction, this.onMaximizeClick, false, false);
e.stopPropagation();
};
onMaximizeClick = (e: any): void => {
- const selectedDocs = SelectionManager.Views;
- if (selectedDocs.length) {
+ const selView = DocumentView.Selected()[0];
+ if (selView) {
if (e.ctrlKey) {
// open an embedding in a new tab with Ctrl Key
- CollectionDockingView.AddSplit(Doc.BestEmbedding(selectedDocs[0].Document), OpenWhereMod.right);
+ CollectionDockingView.AddSplit(Doc.BestEmbedding(selView.Document), OpenWhereMod.right);
} else if (e.shiftKey) {
// open centered in a new workspace with Shift Key
- const embedding = Doc.MakeEmbedding(selectedDocs[0].Document);
+ const embedding = Doc.MakeEmbedding(selView.Document);
embedding.embedContainer = undefined;
embedding.x = -NumCast(embedding._width) / 2;
embedding.y = -NumCast(embedding._height) / 2;
CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([embedding], { title: 'Tab for ' + embedding.title }), OpenWhereMod.right);
} else if (e.altKey) {
// open same document in new tab
- CollectionDockingView.ToggleSplit(selectedDocs[0].Document, OpenWhereMod.right);
+ CollectionDockingView.ToggleSplit(selView.Document, OpenWhereMod.right);
} else {
- var openDoc = selectedDocs[0].Document;
+ let openDoc = selView.Document;
if (openDoc.layout_fieldKey === 'layout_icon') {
openDoc = Doc.GetEmbeddings(openDoc).find(embedding => !embedding.embedContainer) ?? Doc.MakeEmbedding(openDoc);
Doc.deiconifyView(openDoc);
}
- LightboxView.Instance.SetLightboxDoc(
- openDoc,
- undefined,
- selectedDocs.slice(1).map(view => view.Document)
- );
+ selView._props.addDocTab(openDoc, OpenWhere.lightboxAlways);
}
}
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
};
onIconifyClick = (): void => {
- SelectionManager.Views.forEach(dv => dv?.iconify());
- SelectionManager.DeselectAll();
+ DocumentView.Selected().forEach(dv => dv?.iconify());
+ DocumentView.DeselectAll();
};
- onSelectContainerDocClick = () => SelectionManager.Views?.[0]?.containerViewPath?.().lastElement()?.select(false);
+ onSelectContainerDocClick = () => DocumentView.Selected()?.[0]?.containerViewPath?.().lastElement()?.select(false);
/**
* sets up events when user clicks on the border radius editor
*/
@action
onRadiusDown = (e: React.PointerEvent): void => {
- SnappingManager.SetIsResizing(SelectionManager.Docs.lastElement());
+ SnappingManager.SetIsResizing(DocumentView.SelectedDocs().lastElement()?.[Id]);
this._isRounding = true;
this._resizeUndo = UndoManager.StartBatch('DocDecs set radius');
setupMoveUpEvents(
this,
e,
- e => {
+ moveEv => {
const [x, y] = [this.Bounds.x + 3, this.Bounds.y + 3];
const maxDist = Math.min((this.Bounds.r - this.Bounds.x) / 2, (this.Bounds.b - this.Bounds.y) / 2);
- const dist = e.clientX < x && e.clientY < y ? 0 : Math.sqrt((e.clientX - x) * (e.clientX - x) + (e.clientY - y) * (e.clientY - y));
- SelectionManager.Docs.map(doc => {
+ const dist = moveEv.clientX < x && moveEv.clientY < y ? 0 : Math.sqrt((moveEv.clientX - x) * (moveEv.clientX - x) + (moveEv.clientY - y) * (moveEv.clientY - y));
+ DocumentView.SelectedDocs().forEach(doc => {
const docMax = Math.min(NumCast(doc.width) / 2, NumCast(doc.height) / 2);
const radius = Math.min(1, dist / maxDist) * docMax; // set radius based on ratio of drag distance to half diagonal distance of bounding box
doc._layout_borderRounding = `${radius}px`;
});
return false;
},
- action(e => {
+ action(() => {
SnappingManager.SetIsResizing(undefined);
this._isRounding = false;
this._resizeUndo?.end();
@@ -345,31 +328,34 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
e,
returnFalse, // don't care about move or up event,
emptyFunction, // just care about whether we get a click event
- e => UndoManager.RunInBatch(() => SelectionManager.Docs.forEach(doc => Doc.toggleLockedPosition(doc)), 'toggleBackground')
+ () => UndoManager.RunInBatch(() => DocumentView.Selected().forEach(dv => Doc.toggleLockedPosition(dv.Document)), 'toggleBackground')
);
e.stopPropagation();
};
setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => {
+ const selDoc = seldocview.Document;
const newloccentern = seldocview.screenToContentsTransform().transformPoint(rotCenter[0], rotCenter[1]);
const newlocenter = [newloccentern[0] - NumCast(seldocview.layoutDoc._width) / 2, newloccentern[1] - NumCast(seldocview.layoutDoc._height) / 2];
const final = Utils.rotPt(newlocenter[0], newlocenter[1], -(NumCast(seldocview.Document._rotation) / 180) * Math.PI);
- seldocview.Document.rotation_centerX = final.x / NumCast(seldocview.layoutDoc._width);
- seldocview.Document.rotation_centerY = final.y / NumCast(seldocview.layoutDoc._height);
+ selDoc._rotation_centerX = final.x / NumCast(seldocview.layoutDoc._width);
+ selDoc._rotation_centerY = final.y / NumCast(seldocview.layoutDoc._height);
};
@action
onRotateCenterDown = (e: React.PointerEvent): void => {
this._isRotating = true;
- const seldocview = SelectionManager.Views[0];
+ const seldocview = DocumentView.Selected()[0];
setupMoveUpEvents(
this,
e,
- (e: PointerEvent, down: number[], delta: number[]) => // return false to keep getting events
+ (moveEv: PointerEvent, down: number[], delta: number[]) => // return false to keep getting events
this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]) as any as boolean,
- action(e => (this._isRotating = false)), // upEvent
- action(e => (seldocview.Document.rotation_centerX = seldocview.Document.rotation_centerY = 0))
+ action(() => { this._isRotating = false; }), // upEvent
+ action(() => { seldocview.Document._rotation_centerX = seldocview.Document._rotation_centerY = 0; }),
+ true
); // prettier-ignore
+ e.stopPropagation();
};
@action
@@ -377,11 +363,11 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
this._isRotating = true;
const rcScreen = { X: this.rotCenter[0], Y: this.rotCenter[1] };
const rotateUndo = UndoManager.StartBatch('drag rotation');
- const selectedInk = SelectionManager.Views.filter(i => i.ComponentView instanceof InkingStroke);
+ const selectedInk = DocumentView.Selected().filter(i => i.ComponentView instanceof InkingStroke);
const centerPoint = this.rotCenter.slice();
const infos = new Map<Doc, { unrotatedDocPos: { x: number; y: number }; startRotCtr: { x: number; y: number }; accumRot: number }>();
- const seldocview = SelectionManager.Views[0];
- SelectionManager.Views.forEach(dv => {
+ const seldocview = DocumentView.Selected()[0];
+ DocumentView.Selected().forEach(dv => {
const accumRot = (NumCast(dv.Document._rotation) / 180) * Math.PI;
const localRotCtr = dv.screenToViewTransform().transformPoint(rcScreen.X, rcScreen.Y);
const localRotCtrOffset = [localRotCtr[0] - NumCast(dv.Document.width) / 2, localRotCtr[1] - NumCast(dv.Document.height) / 2];
@@ -390,7 +376,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
infos.set(dv.Document, { unrotatedDocPos, startRotCtr, accumRot });
});
const infoRot = (angle: number, isAbs = false) => {
- SelectionManager.Views.forEach(
+ DocumentView.Selected().forEach(
action(dv => {
const { unrotatedDocPos, startRotCtr, accumRot } = infos.get(dv.Document)!;
const endRotCtr = Utils.rotPt(startRotCtr.x, startRotCtr.y, isAbs ? angle : accumRot + angle);
@@ -404,9 +390,9 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
setupMoveUpEvents(
this,
e,
- (e: PointerEvent, down: number[], delta: number[]) => {
- const previousPoint = { X: e.clientX, Y: e.clientY };
- const movedPoint = { X: e.clientX - delta[0], Y: e.clientY - delta[1] };
+ (moveEv: PointerEvent, down: number[], delta: number[]) => {
+ const previousPoint = { X: moveEv.clientX, Y: moveEv.clientY };
+ const movedPoint = { X: moveEv.clientX - delta[0], Y: moveEv.clientY - delta[1] };
const deltaAng = InkStrokeProperties.angleChange(movedPoint, previousPoint, rcScreen);
if (selectedInk.length) {
deltaAng && InkStrokeProperties.Instance.rotateInk(selectedInk, deltaAng, rcScreen);
@@ -432,21 +418,27 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
this._isRotating = false;
rotateUndo?.end();
}), // upEvent
- action(e => (this._showRotCenter = !this._showRotCenter)) // clickEvent
+ action(() => {
+ this._showRotCenter = !this._showRotCenter;
+ }) // clickEvent
);
};
@action
onPointerDown = (e: React.PointerEvent): void => {
- SnappingManager.SetIsResizing(SelectionManager.Docs.lastElement()); // turns off pointer events on things like youtube videos and web pages so that dragging doesn't get "stuck" when cursor moves over them
+ SnappingManager.SetIsResizing(DocumentView.Selected().lastElement()?.Document[Id]); // turns off pointer events on things like youtube videos and web pages so that dragging doesn't get "stuck" when cursor moves over them
setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, emptyFunction);
e.stopPropagation();
- this._resizeHdlId = e.currentTarget.className;
+ const id = (this._resizeHdlId = e.currentTarget.className);
+ const pad = id.includes('Left') || id.includes('Right') ? Number(getComputedStyle(e.target as any).width.replace('px', '')) / 2 : 0;
const bounds = e.currentTarget.getBoundingClientRect();
- this._offset = { x: this._resizeHdlId.toLowerCase().includes('left') ? bounds.right - e.clientX : bounds.left - e.clientX, y: this._resizeHdlId.toLowerCase().includes('top') ? bounds.bottom - e.clientY : bounds.top - e.clientY };
+ this._offset = {
+ x: id.toLowerCase().includes('left') ? bounds.right - e.clientX - pad : bounds.left - e.clientX + pad, //
+ y: id.toLowerCase().includes('top') ? bounds.bottom - e.clientY - pad : bounds.top - e.clientY + pad,
+ };
this._resizeUndo = UndoManager.StartBatch('drag resizing');
this._snapPt = { x: e.pageX, y: e.pageY };
- SelectionManager.Views.forEach(docView => docView.CollectionFreeFormView?.dragStarting(false, false));
+ DocumentView.Selected().forEach(docView => CollectionFreeFormView.from(docView)?.dragStarting(false, false));
};
projectDragToAspect = (e: PointerEvent, docView: DocumentView, fixedAspect: number) => {
@@ -463,12 +455,12 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
const tl = docView.screenToContentsTransform().inverse().transformPoint(0, 0);
return project([e.clientX + this._offset.x, e.clientY + this._offset.y], tl, [tl[0] + fixedAspect, tl[1] + 1]);
};
- onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => {
- const first = SelectionManager.Views[0];
+ onPointerMove = (e: PointerEvent): boolean => {
+ const first = DocumentView.Selected()[0];
const effectiveAcl = GetEffectiveAcl(first.Document);
- if (!(effectiveAcl == AclAdmin || effectiveAcl == AclEdit || effectiveAcl == AclAugment)) return false;
+ if (!(effectiveAcl === AclAdmin || effectiveAcl === AclEdit || effectiveAcl === AclAugment)) return false;
if (!first) return false;
- var fixedAspect = Doc.NativeAspect(first.layoutDoc);
+ const fixedAspect = Doc.NativeAspect(first.layoutDoc);
const dragHdl = this._resizeHdlId.split(' ')[0].replace('documentDecorations-', '').replace('Resizer', '');
const thisPt = // do snapping of drag point
@@ -481,12 +473,12 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
!this._interactionLock && runInAction(async () => { // resize selected docs if we're not in the middle of a resize (ie, throttle input events to frame rate)
this._interactionLock = true;
this._snapPt = thisPt;
- e.ctrlKey && (SelectionManager.Views.forEach(docView => !Doc.NativeHeight(docView.Document) && docView.toggleNativeDimensions()));
- const fixedAspect = SelectionManager.Docs.some(this.hasFixedAspect);
- const scaleAspect = {x:scale.x === 1 && fixedAspect ? scale.y : scale.x, y: scale.x !== 1 && fixedAspect ? scale.x : scale.y};
- SelectionManager.Views.forEach(docView =>
+ e.ctrlKey && (DocumentView.Selected().forEach(docView => !Doc.NativeHeight(docView.Document) && docView.toggleNativeDimensions()));
+ const hasFixedAspect = DocumentView.Selected().map(dv => dv.Document).some(this.hasFixedAspect);
+ const scaleAspect = {x:scale.x === 1 && hasFixedAspect ? scale.y : scale.x, y: scale.x !== 1 && hasFixedAspect ? scale.x : scale.y};
+ DocumentView.Selected().forEach(docView =>
this.resizeView(docView, refPt, scaleAspect, { dragHdl, ctrlKey:e.ctrlKey })); // prettier-ignore
- await new Promise<any>(res => setTimeout(() => res(this._interactionLock = undefined)));
+ await new Promise<any>(res => { setTimeout(() => { res(this._interactionLock = undefined)})});
}); // prettier-ignore
return false;
@@ -523,7 +515,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
const doc = docView.Document;
if (doc.isGroup) {
DocListCast(doc.data)
- .map(member => DocumentManager.Instance.getDocumentView(member, docView)!)
+ .map(member => DocumentView.getDocumentView(member, docView)!)
.forEach(member => this.resizeView(member, refPt, scale, opts));
doc.xPadding = NumCast(doc.xPadding) * scale.x;
doc.yPadding = NumCast(doc.yPadding) * scale.y;
@@ -563,10 +555,11 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
doc._layout_modificationDate = new DateField();
if (scale.y !== 1) {
- docView.layoutDoc._layout_autoHeight = undefined;
+ const docLayout = docView.layoutDoc;
+ docLayout._layout_autoHeight = undefined;
if (docView.layoutDoc._layout_autoHeight) {
// if autoHeight is still on because of a prototype
- docView.layoutDoc._layout_autoHeight = false; // then don't inherit, but explicitly set it to false
+ docLayout._layout_autoHeight = false; // then don't inherit, but explicitly set it to false
}
}
}
@@ -596,15 +589,17 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
};
@action
- onPointerUp = (e: PointerEvent): void => {
+ onPointerUp = (): void => {
SnappingManager.SetIsResizing(undefined);
SnappingManager.clearSnapLines();
this._resizeHdlId = '';
this._resizeUndo?.end();
// detect layout_autoHeight gesture and apply
- SelectionManager.Views.forEach(view => NumCast(view.Document._height) < 20 && (view.layoutDoc._layout_autoHeight = true));
- //need to change points for resize, or else rotation/control points will fail.
+ DocumentView.Selected().forEach(view => {
+ NumCast(view.Document._height) < 20 && (view.layoutDoc._layout_autoHeight = true);
+ });
+ // need to change points for resize, or else rotation/control points will fail.
this._inkDragDocs
.map(oldbds => ({ oldbds, inkPts: Cast(oldbds.doc.data, InkField)?.inkData || [] }))
.forEach(({ oldbds: { doc, x, y, width, height }, inkPts }) => {
@@ -620,25 +615,22 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@computed
get selectionTitle(): string {
- if (SelectionManager.Views.length === 1) {
- const selected = SelectionManager.Views[0];
- if (this._titleControlString.startsWith('=')) {
- return ScriptField.MakeFunction(this._titleControlString.substring(1), { doc: Doc.name })?.script.run({ self: selected.Document, this: selected.layoutDoc }, console.log).result?.toString() || '';
- }
- if (this._titleControlString.startsWith('#')) {
- return Field.toString(selected.Document[this._titleControlString.substring(1)] as Field) || '-unset-';
+ if (DocumentView.Selected().length === 1) {
+ const selected = DocumentView.Selected()[0];
+ if (this._titleControlString.startsWith('$')) {
+ return Field.toJavascriptString(selected.Document[this._titleControlString.substring(1)] as FieldType) || '-unset-';
}
return this._accumulatedTitle;
}
- return SelectionManager.Views.length > 1 ? '-multiple-' : '-unset-';
+ return DocumentView.Selected().length > 1 ? '-multiple-' : '-unset-';
}
@computed get rotCenter() {
- const lastView = SelectionManager.Views.lastElement();
+ const lastView = DocumentView.Selected().lastElement();
if (lastView) {
const invXf = lastView.screenToContentsTransform().inverse();
const seldoc = lastView.layoutDoc;
- const loccenter = Utils.rotPt(NumCast(seldoc.rotation_centerX) * NumCast(seldoc._width), NumCast(seldoc.rotation_centerY) * NumCast(seldoc._height), invXf.Rotate);
+ const loccenter = Utils.rotPt(NumCast(seldoc._rotation_centerX) * NumCast(seldoc._width), NumCast(seldoc._rotation_centerY) * NumCast(seldoc._height), invXf.Rotate);
return invXf.transformPoint(loccenter.x + NumCast(seldoc._width) / 2, loccenter.y + NumCast(seldoc._height) / 2);
}
return this._rotCenter;
@@ -646,7 +638,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
render() {
const { b, r, x, y } = this.Bounds;
- const seldocview = SelectionManager.Views.lastElement();
+ const seldocview = DocumentView.Selected().lastElement();
if (SnappingManager.IsDragging || r - x < 1 || x === Number.MAX_VALUE || !seldocview || this._hidden || isNaN(r) || isNaN(b) || isNaN(x) || isNaN(y)) {
setTimeout(
action(() => {
@@ -661,7 +653,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
const acl = GetEffectiveAcl(!this._showLayoutAcl ? Doc.GetProto(seldocview.Document) : seldocview.Document);
const docShareMode = HierarchyMapping.get(acl)!.name;
const shareMode = StrCast(docShareMode);
- var shareSymbolIcon = ReverseHierarchyMap.get(shareMode)?.image;
+ const shareSymbolIcon = ReverseHierarchyMap.get(shareMode)?.image;
// hide the decorations if the parent chooses to hide it or if the document itself hides it
const hideDecorations = SnappingManager.IsResizing || seldocview._props.hideDecorations || seldocview.Document.layout_hideDecorations;
@@ -675,7 +667,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
hideDecorations ||
seldocview._props.hideOpenButton ||
seldocview.Document.layout_hideOpenButton ||
- SelectionManager.Views.some(docView => docView.Document._dragOnlyWithinContainer || docView.Document.isGroup || docView.Document.layout_hideOpenButton) ||
+ DocumentView.Selected().some(docView => docView.Document._dragOnlyWithinContainer || docView.Document.isGroup || docView.Document.layout_hideOpenButton) ||
this._isRounding ||
this._isRotating;
const hideDeleteButton =
@@ -685,13 +677,13 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
this._isRotating ||
seldocview._props.hideDeleteButton ||
seldocview.Document.hideDeleteButton ||
- SelectionManager.Views.some(docView => {
+ DocumentView.Selected().some(docView => {
const collectionAcl = docView.containerViewPath?.()?.lastElement() ? GetEffectiveAcl(docView.containerViewPath?.().lastElement().dataDoc) : AclEdit;
return collectionAcl !== AclAdmin && collectionAcl !== AclEdit && GetEffectiveAcl(docView.Document) !== AclAdmin;
});
const topBtn = (key: string, icon: string, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: any) => void), title: string) => (
<Tooltip key={key} title={<div className="dash-tooltip">{title}</div>} placement="top">
- <div className={`documentDecorations-${key}Button`} onContextMenu={e => e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => click!(e)))}>
+ <div className={`documentDecorations-${key}Button`} onContextMenu={e => e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => click!(clickEv)))}>
<FontAwesomeIcon icon={icon as any} />
</div>
</Tooltip>
@@ -699,8 +691,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
const bounds = this.ClippedBounds;
const useLock = bounds.r - bounds.x > 135;
- const useRotation = !hideResizers && seldocview.Document.type !== DocumentType.EQUATION && seldocview.CollectionFreeFormDocumentView; // when do we want an object to not rotate?
- const rotation = SelectionManager.Views.length == 1 ? seldocview.screenToContentsTransform().inverse().RotateDeg : 0;
+ const useRotation = !hideResizers && seldocview.Document.type !== DocumentType.EQUATION && CollectionFreeFormDocumentView.from(seldocview); // when do we want an object to not rotate?
+ const rotation = DocumentView.Selected().length === 1 ? seldocview.screenToContentsTransform().inverse().RotateDeg : 0;
// Radius constants
const useRounding = seldocview.ComponentView instanceof ImageBox || seldocview.ComponentView instanceof FormattedTextBox || seldocview.ComponentView instanceof CollectionFreeFormView;
@@ -731,21 +723,26 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
) : null;
const titleArea = this._editingTitle ? (
- <input
- ref={this._keyinput}
- className="documentDecorations-title"
- type="text"
- name="dynbox"
- autoComplete="on"
- value={hideTitle ? '' : this._accumulatedTitle}
- onBlur={action((e: React.FocusEvent) => {
- this._editingTitle = false;
- !hideTitle && this.titleBlur();
- })}
- onChange={action(e => !hideTitle && (this._accumulatedTitle = e.target.value))}
- onKeyDown={hideTitle ? emptyFunction : this.titleEntered}
- onPointerDown={e => e.stopPropagation()}
- />
+ <>
+ {r - x < 150 ? null : <span>{this._titleControlString + ':'}</span>}
+ <input
+ ref={this._keyinput}
+ className="documentDecorations-title"
+ type="text"
+ name="dynbox"
+ autoComplete="on"
+ value={hideTitle ? '' : this._accumulatedTitle}
+ onBlur={action(() => {
+ this._editingTitle = false;
+ this.titleBlur();
+ })}
+ onChange={action(e => {
+ !hideTitle && (this._accumulatedTitle = e.target.value);
+ })}
+ onKeyDown={hideTitle ? emptyFunction : this.titleEntered}
+ onPointerDown={e => e.stopPropagation()}
+ />
+ </>
) : (
<div className="documentDecorations-title" key="title">
{hideTitle ? null : (
@@ -765,7 +762,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
);
const centery = hideTitle ? 0 : this._titleHeight;
const transformOrigin = `${50}% calc(50% + ${centery / 2}px)`;
- const freeformDoc = SelectionManager.Views.some(v => v.CollectionFreeFormDocumentView);
+ const freeformDoc = DocumentView.Selected().some(v => CollectionFreeFormDocumentView.from(v));
return (
<div className="documentDecorations" style={{ display: this._showNothing && !freeformDoc ? 'none' : undefined }}>
<div
@@ -778,7 +775,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
transformOrigin,
background: SnappingManager.ShiftKey ? undefined : 'yellow',
pointerEvents: SnappingManager.ShiftKey || SnappingManager.IsResizing ? 'none' : 'all',
- display: SelectionManager.Views.length <= 1 || hideDecorations ? 'none' : undefined,
+ display: DocumentView.Selected().length <= 1 || hideDecorations ? 'none' : undefined,
transform: `rotate(${rotation}deg)`,
}}
onPointerDown={this.onBackgroundDown}
@@ -799,8 +796,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
display: hideDeleteButton && hideTitle && hideOpenButton ? 'none' : undefined,
}}
onPointerDown={this.onContainerDown}>
- {hideDeleteButton ? null : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
- {hideResizers || hideDeleteButton ? null : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
+ {hideDeleteButton ? null : topBtn('close', 'times', undefined, () => this.onCloseClick(true), 'Close')}
+ {hideResizers || hideDeleteButton ? null : topBtn('minimize', 'window-maximize', undefined, () => this.onCloseClick(undefined), 'Minimize')}
{titleArea}
{hideOpenButton ? <div /> : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Lightbox (ctrl: as alias, shift: in new collection)')}
</div>
@@ -835,7 +832,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
style={{
transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
}}>
- <DocumentButtonBar views={() => SelectionManager.Views} />
+ <DocumentButtonBar views={() => DocumentView.Selected()} />
</div>
)}
</div>
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 4508d00a7..684b948af 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -1,3 +1,5 @@
+/* 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';
@@ -70,7 +72,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
constructor(props: EditableProps) {
super(props);
makeObservable(this);
- this._editing = this._props.editing ? true : false;
+ this._editing = !!this._props.editing;
}
componentDidMount(): void {
@@ -121,6 +123,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
@action
onKeyDown = (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
+ if (e.nativeEvent.defaultPrevented) return; // hack .. DashFieldView grabs native events, but react ignores stoppedPropagation and preventDefault, so we need to check it here
switch (e.key) {
case 'Tab':
e.stopPropagation();
@@ -165,7 +168,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
this._props.menuCallback(e.currentTarget.getBoundingClientRect().x, e.currentTarget.getBoundingClientRect().y);
break;
}
-
+ // eslint-disable-next-line no-fallthrough
default:
if (this._props.textCallback?.(e.key)) {
e.stopPropagation();
@@ -185,7 +188,6 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
this._editing = true;
this._props.isEditingCallback?.(true);
}
- // e.stopPropagation();
}
};
@@ -222,6 +224,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
renderEditor() {
return this._props.autosuggestProps ? (
<Autosuggest
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props.autosuggestProps.autosuggestProps}
inputProps={{
className: 'editableView-input',
@@ -232,7 +235,6 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
onPointerDown: this.stopPropagation,
onClick: this.stopPropagation,
onPointerUp: this.stopPropagation,
- onKeyPress: this.stopPropagation,
value: this._props.autosuggestProps.value,
// @ts-ignore
onChange: this._props.autosuggestProps.onChange,
@@ -241,12 +243,13 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
) : this._props.oneLine !== false && this._props.GetValue()?.toString().indexOf('\n') === -1 ? (
<input
className="editableView-input"
- ref={r => (this._inputref = r)}
+ ref={r => { this._inputref = r; }} // prettier-ignore
style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minWidth: 20, background: this._props.background }}
placeholder={this._props.placeholder}
onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
defaultValue={this._props.GetValue()}
- autoFocus={true}
+ // eslint-disable-next-line jsx-a11y/no-autofocus
+ autoFocus
onChange={this.onChange}
onKeyDown={this.onKeyDown}
onPointerDown={this.stopPropagation}
@@ -256,12 +259,13 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
) : (
<textarea
className="editableView-input"
- ref={r => (this._inputref = r)}
+ ref={r => { this._inputref = r; }} // prettier-ignore
style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, background: this._props.background }}
placeholder={this._props.placeholder}
onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
defaultValue={this._props.GetValue()}
- autoFocus={true}
+ // eslint-disable-next-line jsx-a11y/no-autofocus
+ autoFocus
onChange={this.onChange}
onKeyDown={this.onKeyDown}
onPointerDown={this.stopPropagation}
@@ -304,7 +308,10 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
fontStyle: this._props.fontStyle,
fontSize: this._props.fontSize,
}}>
- {this._props.fieldContents ? <FieldView {...this._props.fieldContents} /> : this.props.contents ? this._props.contents?.valueOf() : ''}
+ {
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ this._props.fieldContents ? <FieldView {...this._props.fieldContents} /> : this.props.contents ? this._props.contents?.valueOf() : ''
+ }
</span>
</div>
);
diff --git a/src/client/views/ExtractColors.ts b/src/client/views/ExtractColors.ts
new file mode 100644
index 000000000..f6928c52a
--- /dev/null
+++ b/src/client/views/ExtractColors.ts
@@ -0,0 +1,168 @@
+import { extractColors } from 'extract-colors';
+import { FinalColor } from 'extract-colors/lib/types/Color';
+
+// Manages image color extraction
+export class ExtractColors {
+ // loads all images into img elements
+ static loadImages = async (imageFiles: File[]): Promise<HTMLImageElement[]> => {
+ try {
+ const imageElements = await Promise.all(imageFiles.map(file => this.loadImage(file)));
+ return imageElements;
+ } catch (error) {
+ console.error(error);
+ return [];
+ }
+ };
+
+ // loads a single img into an img element
+ static loadImage = (file: File): Promise<HTMLImageElement> => {
+ return new Promise((resolve, reject) => {
+ const img = new Image();
+
+ img.onload = () => resolve(img);
+ img.onerror = error => reject(error);
+
+ const url = URL.createObjectURL(file);
+ img.src = url;
+ });
+ };
+
+ // loads all images into img elements
+ static loadImagesUrl = async (imageUrls: string[]): Promise<HTMLImageElement[]> => {
+ try {
+ const imageElements = await Promise.all(imageUrls.map(url => this.loadImageUrl(url)));
+ return imageElements;
+ } catch (error) {
+ console.error(error);
+ return [];
+ }
+ };
+
+ // loads a single img into an img element
+ static loadImageUrl = (url: string): Promise<HTMLImageElement> => {
+ return new Promise((resolve, reject) => {
+ const img = new Image();
+
+ img.onload = () => resolve(img);
+ img.onerror = error => reject(error);
+
+ img.src = url;
+ });
+ };
+
+ // extracts a list of collors from an img element
+ static getImgColors = async (img: HTMLImageElement) => {
+ const colors = await extractColors(img, { distance: 0.35 });
+ return colors;
+ };
+
+ static simpleSort = (colors: FinalColor[]): FinalColor[] => {
+ colors.sort((a, b) => {
+ if (a.hue !== b.hue) {
+ return b.hue - a.hue;
+ } else {
+ return b.saturation - a.saturation;
+ }
+ });
+ return colors;
+ };
+
+ static sortColors(colors: FinalColor[]): FinalColor[] {
+ // Convert color from RGB to CIELAB format
+ const convertToLab = (color: FinalColor): number[] => {
+ const r = color.red / 255;
+ const g = color.green / 255;
+ const b = color.blue / 255;
+
+ const x = r * 0.4124564 + g * 0.3575761 + b * 0.1804375;
+ const y = r * 0.2126729 + g * 0.7151522 + b * 0.072175;
+ const z = r * 0.0193339 + g * 0.119192 + b * 0.9503041;
+
+ const pivot = 0.008856;
+ const factor = 903.3;
+
+ const fx = x > pivot ? Math.cbrt(x) : (factor * x + 16) / 116;
+ const fy = y > pivot ? Math.cbrt(y) : (factor * y + 16) / 116;
+ const fz = z > pivot ? Math.cbrt(z) : (factor * z + 16) / 116;
+
+ const L = 116 * fy - 16;
+ const a = (fx - fy) * 500;
+ const b1 = (fy - fz) * 200;
+
+ return [L, a, b1];
+ };
+
+ // Sort colors using CIELAB distance for smooth transitions
+ colors.sort((colorA, colorB) => {
+ const labA = convertToLab(colorA);
+ const labB = convertToLab(colorB);
+
+ // Calculate Euclidean distance in CIELAB space
+ const distanceA = Math.sqrt(Math.pow(labA[0] - labB[0], 2) + Math.pow(labA[1] - labB[1], 2) + Math.pow(labA[2] - labB[2], 2));
+
+ const distanceB = Math.sqrt(Math.pow(labB[0] - labA[0], 2) + Math.pow(labB[1] - labA[1], 2) + Math.pow(labB[2] - labA[2], 2));
+
+ return distanceA - distanceB; // Sort by CIELAB distance
+ });
+
+ return colors;
+ }
+
+ static hexToFinalColor = (hex: string): FinalColor => {
+ const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+
+ if (!rgb) {
+ throw new Error('Invalid hex color format.');
+ }
+
+ const red = parseInt(rgb[1], 16);
+ const green = parseInt(rgb[2], 16);
+ const blue = parseInt(rgb[3], 16);
+
+ const max = Math.max(red, green, blue);
+ const min = Math.min(red, green, blue);
+ const area = max - min;
+ const intensity = (max + min) / 2;
+
+ let hue = 0;
+ let saturation = 0;
+ let lightness = intensity;
+
+ if (area !== 0) {
+ saturation = area / (1 - Math.abs(2 * intensity - 1));
+ if (max === red) {
+ hue = (60 * ((green - blue) / area) + 360) % 360;
+ } else if (max === green) {
+ hue = (60 * ((blue - red) / area) + 120) % 360;
+ } else {
+ hue = (60 * ((red - green) / area) + 240) % 360;
+ }
+ }
+
+ return {
+ hex,
+ red,
+ green,
+ blue,
+ area,
+ hue,
+ saturation,
+ lightness,
+ intensity,
+ };
+ };
+}
+
+// for reference
+
+// type FinalColor = {
+// hex: string;
+// red: number;
+// green: number;
+// blue: number;
+// area: number;
+// hue: number;
+// saturation: number;
+// lightness: number;
+// intensity: number;
+// }
diff --git a/src/client/views/FieldsDropdown.tsx b/src/client/views/FieldsDropdown.tsx
index 5638d34c6..0ea0ebd83 100644
--- a/src/client/views/FieldsDropdown.tsx
+++ b/src/client/views/FieldsDropdown.tsx
@@ -13,7 +13,7 @@ import Select from 'react-select';
import { Doc } from '../../fields/Doc';
import { DocOptions, FInfo } from '../documents/Documents';
import { SearchUtil } from '../util/SearchUtil';
-import { SettingsManager } from '../util/SettingsManager';
+import { SnappingManager } from '../util/SnappingManager';
import './FilterPanel.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
@@ -61,44 +61,43 @@ export class FieldsDropdown extends ObservableReactComponent<fieldsDropdownProps
.forEach((pair: [string, FInfo]) => filteredOptions.push(pair[0]));
const options = filteredOptions.sort().map(facet => ({ value: facet, label: facet }));
- console.log(options);
return (
<Select
styles={{
- control: (baseStyles, state) => ({
+ control: (baseStyles /* , state */) => ({
...baseStyles,
minHeight: '5px',
maxHeight: '30px',
- color: SettingsManager.userColor,
- backgroundColor: SettingsManager.userBackgroundColor,
+ color: SnappingManager.userColor,
+ backgroundColor: SnappingManager.userBackgroundColor,
padding: 0,
margin: 0,
}),
- singleValue: (baseStyles, state) => ({
+ singleValue: (baseStyles /* , state */) => ({
...baseStyles,
- color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
+ color: SnappingManager.userColor,
+ background: SnappingManager.userBackgroundColor,
}),
- placeholder: (baseStyles, state) => ({
+ placeholder: (baseStyles /* , state */) => ({
...baseStyles,
- color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
+ color: SnappingManager.userColor,
+ background: SnappingManager.userBackgroundColor,
}),
- input: (baseStyles, state) => ({
+ input: (baseStyles /* , state */) => ({
...baseStyles,
padding: 0,
margin: 0,
- color: SettingsManager.userColor,
+ color: SnappingManager.userColor,
background: 'transparent',
}),
option: (baseStyles, state) => ({
...baseStyles,
- color: SettingsManager.userColor,
- background: !state.isFocused ? SettingsManager.userBackgroundColor : SettingsManager.userVariantColor,
+ color: SnappingManager.userColor,
+ background: !state.isFocused ? SnappingManager.userBackgroundColor : SnappingManager.userVariantColor,
}),
- menuList: (baseStyles, state) => ({
+ menuList: (baseStyles /* , state */) => ({
...baseStyles,
- backgroundColor: SettingsManager.userBackgroundColor,
+ backgroundColor: SnappingManager.userBackgroundColor,
}),
}}
placeholder={typeof this._props.placeholder === 'string' ? this._props.placeholder : this._props.placeholder?.()}
@@ -107,12 +106,14 @@ export class FieldsDropdown extends ObservableReactComponent<fieldsDropdownProps
onChange={val => this._props.selectFunc((val as any as { value: string; label: string }).value)}
onKeyDown={e => {
if (e.key === 'Enter') {
- runInAction(() => this._props.selectFunc((this._newField = (e.nativeEvent.target as any)?.value)));
+ runInAction(() => {
+ this._props.selectFunc((this._newField = (e.nativeEvent.target as any)?.value));
+ });
}
e.stopPropagation();
}}
onMenuClose={this._props.menuClose}
- closeMenuOnSelect={true}
+ closeMenuOnSelect
value={this._props.showPlaceholder ? null : undefined}
/>
);
diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx
index 0521c4a4b..c97edd7f0 100644
--- a/src/client/views/FilterPanel.tsx
+++ b/src/client/views/FilterPanel.tsx
@@ -1,19 +1,22 @@
+/* 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';
import { Handles, Rail, Slider, Ticks, Tracks } from 'react-compound-slider';
import { AiOutlineMinusSquare, AiOutlinePlusSquare } from 'react-icons/ai';
import { CiCircleRemove } from 'react-icons/ci';
-import { Doc, DocListCast, Field, LinkedTo, StrListCast } from '../../fields/Doc';
+import { Doc, DocListCast, Field, FieldType, LinkedTo, StrListCast } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
import { RichTextField } from '../../fields/RichTextField';
-import { DocumentManager } from '../util/DocumentManager';
import { SearchUtil } from '../util/SearchUtil';
-import { SettingsManager } from '../util/SettingsManager';
+import { SnappingManager } from '../util/SnappingManager';
import { undoable } from '../util/UndoManager';
import { FieldsDropdown } from './FieldsDropdown';
import './FilterPanel.scss';
+import { DocumentView } from './nodes/DocumentView';
import { Handle, Tick, TooltipRail, Track } from './nodes/SliderBox-components';
import { ObservableReactComponent } from './ObservableReactComponent';
@@ -37,7 +40,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
return this._props.Document;
}
@computed get targetDocChildKey() {
- const targetView = DocumentManager.Instance.getFirstDocumentView(this.Document);
+ const targetView = DocumentView.getFirstDocumentView(this.Document);
return targetView?.ComponentView?.annotationKey ?? targetView?.ComponentView?.fieldKey ?? 'data';
}
@computed get targetDocChildren() {
@@ -58,7 +61,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
@computed get mapActiveFiltersToFacets() {
const filters = new Map<string, string>();
- //this.targetDoc.docFilters
+ // this.targetDoc.docFilters
this.activeFilters.map(filter => filters.set(filter.split(Doc.FilterSep)[1], filter.split(Doc.FilterSep)[0]));
return filters;
}
@@ -73,7 +76,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
// ["#tags", "width", "height"]
//
@computed get activeFacetHeaders() {
- const activeHeaders = new Array();
+ const activeHeaders = [] as string[];
this.activeFilters.map(filter => activeHeaders.push(filter.split(Doc.FilterSep)[0]));
return activeHeaders;
@@ -83,19 +86,20 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
const valueSet = new Set<string>(childFilters.map(filter => filter.split(Doc.FilterSep)[1]));
let rtFields = 0;
let subDocs = childDocs;
- let gatheredDocs = [] as Doc[];
+ const gatheredDocs = [] as Doc[];
if (subDocs.length > 0) {
let newarray: Doc[] = [];
while (subDocs.length > 0) {
newarray = [];
+ // eslint-disable-next-line no-loop-func
subDocs.forEach(t => {
gatheredDocs.push(t);
const facetVal = t[facetKey];
if (facetVal instanceof RichTextField || typeof facetVal === 'string') rtFields++;
- facetVal !== undefined && valueSet.add(Field.toString(facetVal as Field));
- (facetVal === true || facetVal == false) && valueSet.add(Field.toString(!facetVal));
+ facetVal !== undefined && valueSet.add(Field.toString(facetVal as FieldType));
+ (facetVal === true || facetVal === false) && valueSet.add(Field.toString(!facetVal));
const fieldKey = Doc.LayoutFieldKey(t);
- const annos = !Field.toString(Doc.LayoutField(t) as Field).includes('CollectionView');
+ const annos = !Field.toString(Doc.LayoutField(t) as FieldType).includes('CollectionView');
DocListCast(t[annos ? fieldKey + '_annotations' : fieldKey]).forEach(newdoc => newarray.push(newdoc));
annos && DocListCast(t[fieldKey + '_sidebar']).forEach(newdoc => newarray.push(newdoc));
});
@@ -115,7 +119,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
// @observable _chosenFacets = new ObservableMap<string, 'text' | 'checkbox' | 'slider' | 'range'>();
@observable _chosenFacetsCollapse = new ObservableMap<string, boolean>();
- @observable _collapseReturnKeys = new Array();
+ @observable _collapseReturnKeys = [] as string[];
// this computed function gets the active filters and maps them to their headers
//
@@ -130,11 +134,11 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
const facetValues = FilterPanel.gatherFieldValues(this.targetDocChildren, facetHeader, StrListCast(this.Document.childFilters));
let nonNumbers = 0;
- let minVal = Number.MAX_VALUE,
- maxVal = -Number.MAX_VALUE;
- facetValues.strings.map(val => {
+ let minVal = Number.MAX_VALUE;
+ let maxVal = -Number.MAX_VALUE;
+ facetValues.strings.forEach(val => {
const num = val ? Number(val) : Number.NaN;
- if (Number.isNaN(num)) {
+ if (isNaN(num)) {
val && nonNumbers++;
} else {
minVal = Math.min(num, minVal);
@@ -144,14 +148,14 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
if (facetHeader === 'text') {
return { facetHeader, renderType: 'text' };
- } else if (facetHeader !== 'tags' && nonNumbers / facetValues.strings.length < 0.1) {
+ }
+ if (facetHeader !== 'tags' && nonNumbers / facetValues.strings.length < 0.1) {
const extendedMinVal = minVal - Math.min(1, Math.floor(Math.abs(maxVal - minVal) * 0.1));
const extendedMaxVal = Math.max(minVal + 1, maxVal + Math.min(1, Math.ceil(Math.abs(maxVal - minVal) * 0.05)));
- const ranged = Doc.readDocRangeFilter(this.Document, facetHeader); // not the filter range, but the zooomed in range on the filter
- return { facetHeader, renderType: 'range', domain: [extendedMinVal, extendedMaxVal], range: ranged ? ranged : [extendedMinVal, extendedMaxVal] };
- } else {
- return { facetHeader, renderType: 'checkbox' };
+ const ranged: number[] | undefined = Doc.readDocRangeFilter(this.Document, facetHeader); // not the filter range, but the zooomed in range on the filter
+ return { facetHeader, renderType: 'range', domain: [extendedMinVal, extendedMaxVal], range: ranged || [extendedMinVal, extendedMaxVal] };
}
+ return { facetHeader, renderType: 'checkbox' };
})
);
}
@@ -171,17 +175,17 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
sortingCurrentFacetValues = (facetHeader: string) => {
this._collapseReturnKeys.splice(0);
- Array.from(this.activeRenderedFacetInfos.keys()).map(renderInfo => {
+ Array.from(this.activeRenderedFacetInfos.keys()).forEach(renderInfo => {
if (renderInfo.renderType === 'range' && renderInfo.facetHeader === facetHeader && renderInfo.range) {
- this._collapseReturnKeys.push(renderInfo.range.map(number => number.toFixed(2)));
+ this._collapseReturnKeys.push(...renderInfo.range.map(number => number.toFixed(2)));
}
});
- for (var key of this.facetValues(facetHeader)) {
+ this.facetValues(facetHeader).forEach(key => {
if (this.mapActiveFiltersToFacets.get(key)) {
this._collapseReturnKeys.push(key);
}
- }
+ });
return <div className=" filterbox-collpasedAndActive">{this._collapseReturnKeys.join(', ')}</div>;
};
@@ -198,7 +202,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
);
else
allCollectionDocs.forEach(child => {
- const fieldVal = child[facetHeader] as Field;
+ const fieldVal = child[facetHeader] as FieldType;
if (!(fieldVal instanceof List)) {
// currently we have no good way of filtering based on a field that is a list
set.add(Field.toString(fieldVal));
@@ -209,7 +213,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
let nonNumbers = 0;
- facetValues.map(val => Number.isNaN(Number(val)) && nonNumbers++);
+ facetValues.map(val => isNaN(Number(val)) && nonNumbers++);
return nonNumbers / facetValues.length > 0.1 ? facetValues.sort() : facetValues.sort((n1: string, n2: string) => Number(n1) - Number(n2));
};
@@ -218,7 +222,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
<div className="filterBox-treeView">
<div className="filterBox-select">
<div style={{ width: '100%' }}>
- <FieldsDropdown Document={this.Document} selectFunc={this.facetClick} showPlaceholder={true} placeholder="add a filter" addedFields={['acl-Guest', LinkedTo]} />
+ <FieldsDropdown Document={this.Document} selectFunc={this.facetClick} showPlaceholder placeholder="add a filter" addedFields={['acl_Guest', LinkedTo]} />
</div>
{/* THE FOLLOWING CODE SHOULD BE DEVELOPER FOR BOOLEAN EXPRESSION (AND / OR) */}
{/* <div className="filterBox-select-bool">
@@ -234,34 +238,31 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
<div className="filterBox-tree" key="tree">
{Array.from(this.activeRenderedFacetInfos.keys()).map(
- (
- renderInfo // iterato over activeFacetRenderInfos ==> renderInfo which you can renderInfo.facetHeader
- ) => (
+ // iterate over activeFacetRenderInfos ==> renderInfo which you can renderInfo.facetHeader
+ renderInfo => (
<div>
<div className="filterBox-facetHeader">
<div className="filterBox-facetHeader-Header"> </div>
{renderInfo.facetHeader.charAt(0).toUpperCase() + renderInfo.facetHeader.slice(1)}
-
<div
className="filterBox-facetHeader-collapse"
- onClick={action(e => {
+ onClick={action(() => {
const collapseBoolValue = this._chosenFacetsCollapse.get(renderInfo.facetHeader);
this._chosenFacetsCollapse.set(renderInfo.facetHeader, !collapseBoolValue);
})}>
{this._chosenFacetsCollapse.get(renderInfo.facetHeader) ? <AiOutlinePlusSquare /> : <AiOutlineMinusSquare />}
</div>
-
<div
className="filterBox-facetHeader-remove"
- onClick={action(e => {
+ onClick={action(() => {
if (renderInfo.facetHeader === 'text') {
Doc.setDocFilter(this.Document, renderInfo.facetHeader, 'match', 'remove');
} else {
- for (var key of this.facetValues(renderInfo.facetHeader)) {
+ this.facetValues(renderInfo.facetHeader).forEach((key: string) => {
if (this.mapActiveFiltersToFacets.get(key)) {
Doc.setDocFilter(this.Document, renderInfo.facetHeader, key, 'remove');
}
- }
+ });
}
this._selectedFacetHeaders.delete(renderInfo.facetHeader);
this._chosenFacetsCollapse.delete(renderInfo.facetHeader);
@@ -292,15 +293,15 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
return (
<input
key={this.Document[Id]}
- placeholder={'enter text to match'}
+ placeholder="enter text to match"
defaultValue={
StrListCast(this.Document._childFilters)
.find(filter => filter.split(Doc.FilterSep)[0] === facetHeader)
?.split(Doc.FilterSep)[1]
}
- style={{ color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }}
+ style={{ color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}
onBlur={undoable(e => Doc.setDocFilter(this.Document, facetHeader, e.currentTarget.value, !e.currentTarget.value ? 'remove' : 'match'), 'set text filter')}
- onKeyDown={e => e.key === 'Enter' && undoable(e => Doc.setDocFilter(this.Document, facetHeader, e.currentTarget.value, !e.currentTarget.value ? 'remove' : 'match'), 'set text filter')(e)}
+ onKeyDown={e => e.key === 'Enter' && undoable(() => Doc.setDocFilter(this.Document, facetHeader, e.currentTarget.value, !e.currentTarget.value ? 'remove' : 'match'), 'set text filter')()}
/>
);
case 'checkbox':
@@ -312,7 +313,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
style={{ width: 20, marginLeft: 20 }}
checked={['check', 'exists'].includes(
StrListCast(this.Document._childFilters)
- .find(filter => filter.split(Doc.FilterSep)[0] === facetHeader && filter.split(Doc.FilterSep)[1] == facetValue)
+ .find(filter => filter.split(Doc.FilterSep)[0] === facetHeader && filter.split(Doc.FilterSep)[1] === facetValue)
?.split(Doc.FilterSep)[2] ?? ''
)}
type={type}
@@ -324,55 +325,56 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
});
case 'range':
- const domain = renderInfoDomain;
- const range = renderInfoRange;
- if (domain) {
- return (
- <div className="sliderBox-outerDiv" style={{ width: '95%', height: 45, float: 'right' }}>
- <Slider
- mode={2}
- step={Math.min(1, 0.1 * (domain[1] - domain[0]))}
- domain={[domain[0], domain[1]]} // -1000, 1000
- rootStyle={{ position: 'relative', width: '100%' }}
- onChange={values => Doc.setDocRangeFilter(this.Document, facetHeader, values)}
- values={renderInfoRange!}>
- <Rail>{railProps => <TooltipRail {...railProps} />}</Rail>
- <Handles>
- {({ handles, activeHandleID, getHandleProps }) => (
- <div className="slider-handles">
- {handles.map((handle, i) => {
- // const value = i === 0 ? defaultValues[0] : defaultValues[1];
- return (
+ {
+ const domain = renderInfoDomain;
+ if (domain) {
+ return (
+ <div className="sliderBox-outerDiv" style={{ width: '95%', height: 45, float: 'right' }}>
+ <Slider
+ mode={2}
+ step={Math.min(1, 0.1 * (domain[1] - domain[0]))}
+ domain={[domain[0], domain[1]]} // -1000, 1000
+ rootStyle={{ position: 'relative', width: '100%' }}
+ onChange={values => Doc.setDocRangeFilter(this.Document, facetHeader, values)}
+ values={renderInfoRange!}>
+ <Rail>{railProps => <TooltipRail {...railProps} />}</Rail>
+ <Handles>
+ {({ handles, activeHandleID, getHandleProps }) => (
+ <div className="slider-handles">
+ {handles.map(handle => (
+ // const value = i === 0 ? defaultValues[0] : defaultValues[1];
<div>
<Handle key={handle.id} handle={handle} domain={domain} isActive={handle.id === activeHandleID} getHandleProps={getHandleProps} />
</div>
- );
- })}
- </div>
- )}
- </Handles>
- <Tracks left={false} right={false}>
- {({ tracks, getTrackProps }) => (
- <div className="slider-tracks">
- {tracks.map(({ id, source, target }) => (
- <Track key={id} source={source} target={target} disabled={false} getTrackProps={getTrackProps} />
- ))}
- </div>
- )}
- </Tracks>
- <Ticks count={5}>
- {({ ticks }) => (
- <div className="slider-ticks">
- {ticks.map(tick => (
- <Tick key={tick.id} tick={tick} count={ticks.length} format={(val: number) => val.toString()} />
- ))}
- </div>
- )}
- </Ticks>
- </Slider>
- </div>
- );
+ ))}
+ </div>
+ )}
+ </Handles>
+ <Tracks left={false} right={false}>
+ {({ tracks, getTrackProps }) => (
+ <div className="slider-tracks">
+ {tracks.map(({ id, source, target }) => (
+ <Track key={id} source={source} target={target} disabled={false} getTrackProps={getTrackProps} />
+ ))}
+ </div>
+ )}
+ </Tracks>
+ <Ticks count={5}>
+ {({ ticks }) => (
+ <div className="slider-ticks">
+ {ticks.map(tick => (
+ <Tick key={tick.id} tick={tick} count={ticks.length} format={(val: number) => val.toString()} />
+ ))}
+ </div>
+ )}
+ </Ticks>
+ </Slider>
+ </div>
+ );
+ }
}
+ break;
+ default:
// case 'range'
// return <Slider ...
@@ -386,5 +388,6 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
// <dimain changing handles >
// <?div
}
+ return undefined;
}
}
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 86b9f5e40..2f26bdaef 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -2,17 +2,8 @@ import * as fitCurve from 'fit-curve';
import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../Utils';
-import { Doc, Opt } from '../../fields/Doc';
-import { InkData, InkTool } from '../../fields/InkField';
-import { BoolCast, NumCast } from '../../fields/Types';
-import MobileInkOverlay from '../../mobile/MobileInkOverlay';
-import { GestureUtils } from '../../pen-gestures/GestureUtils';
-import { MobileInkOverlayContent } from '../../server/Message';
-import { InteractionUtils } from '../util/InteractionUtils';
-import { ScriptingGlobals } from '../util/ScriptingGlobals';
-import { Transform } from '../util/Transform';
-import './GestureOverlay.scss';
+import { returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../ClientUtils';
+import { emptyFunction } from '../../Utils';
import {
ActiveArrowEnd,
ActiveArrowScale,
@@ -22,32 +13,44 @@ import {
ActiveInkBezierApprox,
ActiveInkColor,
ActiveInkWidth,
+ Doc,
+ Opt,
SetActiveArrowStart,
SetActiveDash,
SetActiveFillColor,
SetActiveInkColor,
SetActiveInkWidth,
-} from './InkingStroke';
+} from '../../fields/Doc';
+import { InkData, InkField, InkTool } from '../../fields/InkField';
+import { NumCast } from '../../fields/Types';
+// import MobileInkOverlay from '../../mobile/MobileInkOverlay';
+import { Gestures } from '../../pen-gestures/GestureTypes';
+import { GestureUtils } from '../../pen-gestures/GestureUtils';
+// import { MobileInkOverlayContent } from '../../server/Message';
+import { InteractionUtils } from '../util/InteractionUtils';
+import { ScriptingGlobals } from '../util/ScriptingGlobals';
+import { Transform } from '../util/Transform';
+import './GestureOverlay.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
-import { checkInksToGroup } from './global/globalScripts';
import { DocumentView } from './nodes/DocumentView';
+export enum ToolglassTools {
+ InkToText = 'inktotext',
+ IgnoreGesture = 'ignoregesture',
+ RadialMenu = 'radialmenu',
+ None = 'none',
+}
interface GestureOverlayProps {
isActive: boolean;
}
@observer
export class GestureOverlay extends ObservableReactComponent<React.PropsWithChildren<GestureOverlayProps>> {
+ // eslint-disable-next-line no-use-before-define
static Instance: GestureOverlay;
+ // eslint-disable-next-line no-use-before-define
static Instances: GestureOverlay[] = [];
- public static set RecognizeGestures(active) {
- Doc.UserDoc().recognizeGestures = active;
- }
- public static get RecognizeGestures() {
- return BoolCast(Doc.UserDoc().recognizeGestures);
- }
-
- @observable public InkShape: Opt<GestureUtils.Gestures> = undefined;
+ @observable public InkShape: Opt<Gestures> = undefined;
@observable public SavedColor?: string = undefined;
@observable public SavedWidth?: number = undefined;
@observable public Tool: ToolglassTools = ToolglassTools.None;
@@ -55,9 +58,6 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
@observable private _thumbX?: number = undefined;
@observable private _thumbY?: number = undefined;
- @observable private _selectedIndex: number = -1;
- @observable private _menuX: number = -300;
- @observable private _menuY: number = -300;
@observable private _pointerY?: number = undefined;
@observable private _points: { X: number; Y: number }[] = [];
@observable private _strokes: InkData[] = [];
@@ -65,8 +65,6 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
@observable private _clipboardDoc?: JSX.Element = undefined;
@observable private _possibilities: JSX.Element[] = [];
- public static DownDocView: DocumentView | undefined;
-
@computed private get height(): number {
return 2 * Math.max(this._pointerY && this._thumbY ? this._thumbY - this._pointerY : 100, 100);
}
@@ -74,7 +72,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
return this.Tool !== ToolglassTools.None;
}
- @observable private showMobileInkOverlay: boolean = false;
+ // @observable private showMobileInkOverlay: boolean = false;
private _overlayRef = React.createRef<HTMLDivElement>();
private _d1: Doc | undefined;
@@ -111,15 +109,14 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
this._points.push({ X: e.clientX, Y: e.clientY });
if (this._points.length > 1) {
- const B = this.svgBounds;
const initialPoint = this._points[0];
const xInGlass = initialPoint.X > (this._thumbX ?? Number.MAX_SAFE_INTEGER) && initialPoint.X < (this._thumbX ?? Number.MAX_SAFE_INTEGER) + this.height;
const yInGlass = initialPoint.Y > (this._thumbY ?? Number.MAX_SAFE_INTEGER) - this.height && initialPoint.Y < (this._thumbY ?? Number.MAX_SAFE_INTEGER);
if (this.Tool !== ToolglassTools.None && xInGlass && yInGlass) {
switch (this.Tool) {
- case ToolglassTools.RadialMenu:
- return true;
- }
+ case ToolglassTools.RadialMenu: return true;
+ default:
+ } // prettier-ignore
}
}
return false;
@@ -128,21 +125,21 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
@action primCreated() {
if (!this.KeepPrimitiveMode) {
this.InkShape = undefined;
- //get out of ink mode after each stroke=
- //if (Doc.ActiveTool === InkTool.Highlighter && GestureOverlay.Instance.SavedColor) SetActiveInkColor(GestureOverlay.Instance.SavedColor);
+ // get out of ink mode after each stroke=
+ // if (Doc.ActiveTool === InkTool.Highlighter && GestureOverlay.Instance.SavedColor) SetActiveInkColor(GestureOverlay.Instance.SavedColor);
Doc.ActiveTool = InkTool.None;
// SetActiveArrowStart('none');
// SetActiveArrowEnd('none');
}
}
@action
- onPointerUp = (e: PointerEvent) => {
- GestureOverlay.DownDocView = undefined;
+ onPointerUp = () => {
+ DocumentView.DownDocView = undefined;
if (this._points.length > 1) {
const B = this.svgBounds;
const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top }));
- //if any of the shape is activated in the CollectionFreeFormViewChrome
+ // if any of the shape is activated in the CollectionFreeFormViewChrome
if (this.InkShape) {
this.makeBezierPolygon(this.InkShape, false);
this.dispatchGesture(this.InkShape);
@@ -151,20 +148,21 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
// if we're not drawing in a toolglass try to recognize as gesture
else {
// need to decide when to turn gestures back on
- const result = points.length > 2 && GestureUtils.GestureRecognizer.Recognize(new Array(points));
+ const result = points.length > 2 && GestureUtils.GestureRecognizer.Recognize([points]);
let actionPerformed = false;
- if (GestureOverlay.RecognizeGestures && result && result.Score > 0.7) {
+ if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) {
switch (result.Name) {
- case GestureUtils.Gestures.Line:
- case GestureUtils.Gestures.Triangle:
- case GestureUtils.Gestures.Rectangle:
- case GestureUtils.Gestures.Circle:
+ case Gestures.Line:
+ case Gestures.Triangle:
+ case Gestures.Rectangle:
+ case Gestures.Circle:
this.makeBezierPolygon(result.Name, true);
actionPerformed = this.dispatchGesture(result.Name);
break;
- case GestureUtils.Gestures.Scribble:
+ case Gestures.Scribble:
console.log('scribble');
break;
+ default:
}
}
@@ -178,21 +176,20 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
const controlPoints: { X: number; Y: number }[] = [];
const bezierCurves = (fitCurve as any)(newPoints, 10);
- for (const curve of bezierCurves) {
+ Array.from(bezierCurves).forEach((curve: any) => {
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] });
controlPoints.push({ X: curve[3][0], Y: curve[3][1] });
- }
+ });
const dist = Math.sqrt(
(controlPoints[0].X - controlPoints.lastElement().X) * (controlPoints[0].X - controlPoints.lastElement().X) + (controlPoints[0].Y - controlPoints.lastElement().Y) * (controlPoints[0].Y - controlPoints.lastElement().Y)
);
+ // eslint-disable-next-line prefer-destructuring
if (controlPoints.length > 4 && dist < 10) controlPoints[controlPoints.length - 1] = controlPoints[0];
this._points.length = 0;
this._points.push(...controlPoints);
- this.dispatchGesture(GestureUtils.Gestures.Stroke);
- // TODO: nda - check inks to group here
- checkInksToGroup();
+ this.dispatchGesture(Gestures.Stroke);
}
}
}
@@ -202,34 +199,34 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
makeBezierPolygon = (shape: string, gesture: boolean) => {
const xs = this._points.map(p => p.X);
const ys = this._points.map(p => p.Y);
- var right = Math.max(...xs);
- var left = Math.min(...xs);
- var bottom = Math.max(...ys);
- var top = Math.min(...ys);
+ let right = Math.max(...xs);
+ let left = Math.min(...xs);
+ let bottom = Math.max(...ys);
+ let top = Math.min(...ys);
const firstx = this._points[0].X;
const firsty = this._points[0].Y;
- var lastx = this._points[this._points.length - 2].X;
- var lasty = this._points[this._points.length - 2].Y;
- var fourth = (lastx - firstx) / 4;
+ let lastx = this._points[this._points.length - 2].X;
+ let lasty = this._points[this._points.length - 2].Y;
+ let fourth = (lastx - firstx) / 4;
if (isNaN(fourth) || fourth === 0) {
fourth = 0.01;
}
- var m = (lasty - firsty) / (lastx - firstx);
+ let m = (lasty - firsty) / (lastx - firstx);
if (isNaN(m) || m === 0) {
m = 0.01;
}
- const b = firsty - m * firstx;
+ // const b = firsty - m * firstx;
if (shape === 'noRec') {
return false;
}
if (!gesture) {
- //if shape options is activated in inkOptionMenu
- //take second to last point because _point[length-1] is _points[0]
+ // if shape options is activated in inkOptionMenu
+ // take second to last point because _point[length-1] is _points[0]
right = this._points[this._points.length - 2].X;
left = this._points[0].X;
bottom = this._points[this._points.length - 2].Y;
top = this._points[0].Y;
- if (shape !== GestureUtils.Gestures.Arrow && shape !== GestureUtils.Gestures.Line && shape !== GestureUtils.Gestures.Circle) {
+ if (shape !== Gestures.Arrow && shape !== Gestures.Line && shape !== Gestures.Circle) {
if (left > right) {
const temp = right;
right = left;
@@ -244,7 +241,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
}
this._points.length = 0;
switch (shape) {
- case GestureUtils.Gestures.Rectangle:
+ case Gestures.Rectangle:
this._points.push({ X: left, Y: top });
this._points.push({ X: left, Y: top });
this._points.push({ X: right, Y: top });
@@ -267,7 +264,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
break;
- case GestureUtils.Gestures.Triangle:
+ case Gestures.Triangle:
this._points.push({ X: left, Y: bottom });
this._points.push({ X: left, Y: bottom });
@@ -285,39 +282,40 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
this._points.push({ X: left, Y: bottom });
break;
- case GestureUtils.Gestures.Circle:
- // Approximation of a circle using 4 Bézier curves in which the constant "c" reduces the maximum radial drift to 0.019608%,
- // making the curves indistinguishable from a circle.
- // Source: https://spencermortensen.com/articles/bezier-circle/
- const c = 0.551915024494;
- const centerX = (Math.max(left, right) + Math.min(left, right)) / 2;
- const centerY = (Math.max(top, bottom) + Math.min(top, bottom)) / 2;
- const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom));
-
- // Dividing the circle into four equal sections, and fitting each section to a cubic Bézier curve.
- this._points.push({ X: centerX, Y: centerY + radius });
- this._points.push({ X: centerX + c * radius, Y: centerY + radius });
- this._points.push({ X: centerX + radius, Y: centerY + c * radius });
- this._points.push({ X: centerX + radius, Y: centerY });
-
- this._points.push({ X: centerX + radius, Y: centerY });
- this._points.push({ X: centerX + radius, Y: centerY - c * radius });
- this._points.push({ X: centerX + c * radius, Y: centerY - radius });
- this._points.push({ X: centerX, Y: centerY - radius });
-
- this._points.push({ X: centerX, Y: centerY - radius });
- this._points.push({ X: centerX - c * radius, Y: centerY - radius });
- this._points.push({ X: centerX - radius, Y: centerY - c * radius });
- this._points.push({ X: centerX - radius, Y: centerY });
-
- this._points.push({ X: centerX - radius, Y: centerY });
- this._points.push({ X: centerX - radius, Y: centerY + c * radius });
- this._points.push({ X: centerX - c * radius, Y: centerY + radius });
- this._points.push({ X: centerX, Y: centerY + radius });
-
+ case Gestures.Circle:
+ {
+ // Approximation of a circle using 4 Bézier curves in which the constant "c" reduces the maximum radial drift to 0.019608%,
+ // making the curves indistinguishable from a circle.
+ // Source: https://spencermortensen.com/articles/bezier-circle/
+ const c = 0.551915024494;
+ const centerX = (Math.max(left, right) + Math.min(left, right)) / 2;
+ const centerY = (Math.max(top, bottom) + Math.min(top, bottom)) / 2;
+ const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom));
+
+ // Dividing the circle into four equal sections, and fitting each section to a cubic Bézier curve.
+ this._points.push({ X: centerX, Y: centerY + radius });
+ this._points.push({ X: centerX + c * radius, Y: centerY + radius });
+ this._points.push({ X: centerX + radius, Y: centerY + c * radius });
+ this._points.push({ X: centerX + radius, Y: centerY });
+
+ this._points.push({ X: centerX + radius, Y: centerY });
+ this._points.push({ X: centerX + radius, Y: centerY - c * radius });
+ this._points.push({ X: centerX + c * radius, Y: centerY - radius });
+ this._points.push({ X: centerX, Y: centerY - radius });
+
+ this._points.push({ X: centerX, Y: centerY - radius });
+ this._points.push({ X: centerX - c * radius, Y: centerY - radius });
+ this._points.push({ X: centerX - radius, Y: centerY - c * radius });
+ this._points.push({ X: centerX - radius, Y: centerY });
+
+ this._points.push({ X: centerX - radius, Y: centerY });
+ this._points.push({ X: centerX - radius, Y: centerY + c * radius });
+ this._points.push({ X: centerX - c * radius, Y: centerY + radius });
+ this._points.push({ X: centerX, Y: centerY + radius });
+ }
break;
- case GestureUtils.Gestures.Line:
+ case Gestures.Line:
if (Math.abs(firstx - lastx) < 10 && Math.abs(firsty - lasty) > 10) {
lastx = firstx;
}
@@ -330,28 +328,32 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
this._points.push({ X: lastx, Y: lasty });
this._points.push({ X: lastx, Y: lasty });
break;
- case GestureUtils.Gestures.Arrow:
- const x1 = left;
- const y1 = top;
- const x2 = right;
- const y2 = bottom;
- const L1 = Math.sqrt(Math.pow(Math.abs(x1 - x2), 2) + Math.pow(Math.abs(y1 - y2), 2));
- const L2 = L1 / 5;
- const angle = 0.785398;
- const x3 = x2 + (L2 / L1) * ((x1 - x2) * Math.cos(angle) + (y1 - y2) * Math.sin(angle));
- const y3 = y2 + (L2 / L1) * ((y1 - y2) * Math.cos(angle) - (x1 - x2) * Math.sin(angle));
- const x4 = x2 + (L2 / L1) * ((x1 - x2) * Math.cos(angle) - (y1 - y2) * Math.sin(angle));
- const y4 = y2 + (L2 / L1) * ((y1 - y2) * Math.cos(angle) + (x1 - x2) * Math.sin(angle));
- this._points.push({ X: x1, Y: y1 });
- this._points.push({ X: x2, Y: y2 });
- this._points.push({ X: x3, Y: y3 });
- this._points.push({ X: x4, Y: y4 });
- this._points.push({ X: x2, Y: y2 });
+ case Gestures.Arrow:
+ {
+ const x1 = left;
+ const y1 = top;
+ const x2 = right;
+ const y2 = bottom;
+ const L1 = Math.sqrt(Math.abs(x1 - x2) ** 2 + Math.abs(y1 - y2) ** 2);
+ const L2 = L1 / 5;
+ const angle = 0.785398;
+ const x3 = x2 + (L2 / L1) * ((x1 - x2) * Math.cos(angle) + (y1 - y2) * Math.sin(angle));
+ const y3 = y2 + (L2 / L1) * ((y1 - y2) * Math.cos(angle) - (x1 - x2) * Math.sin(angle));
+ const x4 = x2 + (L2 / L1) * ((x1 - x2) * Math.cos(angle) - (y1 - y2) * Math.sin(angle));
+ const y4 = y2 + (L2 / L1) * ((y1 - y2) * Math.cos(angle) + (x1 - x2) * Math.sin(angle));
+ this._points.push({ X: x1, Y: y1 });
+ this._points.push({ X: x2, Y: y2 });
+ this._points.push({ X: x3, Y: y3 });
+ this._points.push({ X: x4, Y: y4 });
+ this._points.push({ X: x2, Y: y2 });
+ }
+ break;
+ default:
}
return false;
};
- dispatchGesture = (gesture: GestureUtils.Gestures, stroke?: InkData, text?: any) => {
+ dispatchGesture = (gesture: Gestures, stroke?: InkData, text?: any) => {
const points = (stroke ?? this._points).slice();
return (
document.elementFromPoint(points[0].X, points[0].Y)?.dispatchEvent(
@@ -360,7 +362,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
detail: {
points,
gesture,
- bounds: GestureOverlay.getBounds(points),
+ bounds: InkField.getBounds(points),
text,
},
})
@@ -368,30 +370,19 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
);
};
- public static getBounds = (stroke: InkData, pad?: boolean) => {
- const padding = pad ? [-20000, 20000] : [];
- const xs = [...padding, ...stroke.map(p => p.X)];
- const ys = [...padding, ...stroke.map(p => p.Y)];
- const right = Math.max(...xs);
- const left = Math.min(...xs);
- const bottom = Math.max(...ys);
- const top = Math.min(...ys);
- return { right, left, bottom, top, width: right - left, height: bottom - top };
- };
-
@computed get svgBounds() {
- return GestureOverlay.getBounds(this._points);
+ return InkField.getBounds(this._points);
}
get elements() {
- const selView = GestureOverlay.DownDocView;
+ const selView = DocumentView.DownDocView;
const width = Number(ActiveInkWidth()) * NumCast(selView?.Document._freeform_scale, 1); // * (selView?.screenToViewTransform().Scale || 1);
const rect = this._overlayRef.current?.getBoundingClientRect();
- const B = { left: -20000, right: 20000, top: -20000, bottom: 20000, width: 40000, height: 40000 }; //this.getBounds(this._points, true);
- B.left = B.left - width / 2;
- B.right = B.right + width / 2;
+ const B = { left: -20000, right: 20000, top: -20000, bottom: 20000, width: 40000, height: 40000 }; // this.getBounds(this._points, true);
+ B.left -= width / 2;
+ B.right += width / 2;
B.top = B.top - width / 2 - (rect?.y || 0);
- B.bottom = B.bottom + width / 2;
+ B.bottom += width / 2;
B.width += width;
B.height += width;
const fillColor = ActiveFillColor();
@@ -401,8 +392,9 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
this._palette,
[
this._strokes.map((l, i) => {
- const b = { left: -20000, right: 20000, top: -20000, bottom: 20000, width: 40000, height: 40000 }; //this.getBounds(l, true);
+ const b = { left: -20000, right: 20000, top: -20000, bottom: 20000, width: 40000, height: 40000 }; // this.getBounds(l, true);
return (
+ // eslint-disable-next-line react/no-array-index-key
<svg key={i} width={b.width} height={b.height} style={{ top: 0, left: 0, transform: `translate(${b.left}px, ${b.top}px)`, pointerEvents: 'none', position: 'absolute', zIndex: 30000, overflow: 'visible' }}>
{InteractionUtils.CreatePolyline(
l,
@@ -414,7 +406,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
'miter',
'round',
ActiveInkBezierApprox(),
- 'none' /*ActiveFillColor()*/,
+ 'none' /* ActiveFillColor() */,
ActiveArrowStart(),
ActiveArrowEnd(),
ActiveArrowScale(),
@@ -441,7 +433,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
'miter',
'round',
'',
- 'none' /*ActiveFillColor()*/,
+ 'none' /* ActiveFillColor() */,
ActiveArrowStart(),
ActiveArrowEnd(),
ActiveArrowScale(),
@@ -491,15 +483,10 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
this._clipboardDoc = undefined;
};
- @action
- enableMobileInkOverlay = (content: MobileInkOverlayContent) => {
- this.showMobileInkOverlay = content.enableOverlay;
- };
-
render() {
return (
<div className="gestureOverlay-cont" style={{ pointerEvents: this._props.isActive ? 'all' : 'none' }} ref={this._overlayRef} onPointerDown={this.onPointerDown}>
- {this.showMobileInkOverlay ? <MobileInkOverlay /> : null}
+ {/* {this.showMobileInkOverlay ? <MobileInkOverlay /> : null} */}
{this.elements}
<div
@@ -529,19 +516,14 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
}
}
-// export class
-
-export enum ToolglassTools {
- InkToText = 'inktotext',
- IgnoreGesture = 'ignoregesture',
- RadialMenu = 'radialmenu',
- None = 'none',
-}
-
ScriptingGlobals.add('GestureOverlay', GestureOverlay);
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function setToolglass(tool: any) {
- runInAction(() => (GestureOverlay.Instance.Tool = tool));
+ runInAction(() => {
+ 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) {
runInAction(() => {
GestureOverlay.Instance.SavedColor = ActiveInkColor();
@@ -554,6 +536,7 @@ ScriptingGlobals.add(function setPen(width: any, color: any, fill: any, arrowSta
SetActiveDash(dash);
});
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function resetPen() {
runInAction(() => {
SetActiveInkColor(GestureOverlay.Instance.SavedColor ?? 'rgb(0, 0, 0)');
@@ -561,8 +544,9 @@ 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(GestureUtils.Gestures.Text, [{ X: x, Y: y }], text);
+ GestureOverlay.Instance.dispatchGesture(Gestures.Text, [{ X: x, Y: y }], text);
},
'creates a text document with inputted text and coordinates',
'(text: any, x: any, y: any)'
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index e800798ca..18ec0b6a9 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -8,37 +8,37 @@ import { Cast, PromiseValue } from '../../fields/Types';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
import { DragManager } from '../util/DragManager';
import { GroupManager } from '../util/GroupManager';
-import { SelectionManager } from '../util/SelectionManager';
import { SettingsManager } from '../util/SettingsManager';
import { SharingManager } from '../util/SharingManager';
import { SnappingManager } from '../util/SnappingManager';
-import { UndoManager } from '../util/UndoManager';
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { CollectionFreeFormView } from './collections/collectionFreeForm';
-import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
+import { UndoManager, undoable } from '../util/UndoManager';
import { ContextMenu } from './ContextMenu';
import { DocumentDecorations } from './DocumentDecorations';
import { InkStrokeProperties } from './InkStrokeProperties';
-import { LightboxView } from './LightboxView';
import { MainView } from './MainView';
+import { CollectionDockingView } from './collections/CollectionDockingView';
+import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
+import { CollectionFreeFormDocumentView } from './nodes/CollectionFreeFormDocumentView';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
-import { OpenWhereMod } from './nodes/DocumentView';
-import { AnchorMenu } from './pdf/AnchorMenu';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhereMod } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { AnchorMenu } from './pdf/AnchorMenu';
const modifiers = ['control', 'meta', 'shift', 'alt'];
-type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo;
type KeyControlInfo = {
preventDefault: boolean;
stopPropagation: boolean;
};
-
-export let CtrlKey = false;
+type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo;
export class KeyManager {
- public static Instance: KeyManager = new KeyManager();
+ // eslint-disable-next-line no-use-before-define
+ public static Instance: KeyManager;
private router = new Map<string, KeyHandler>();
constructor() {
+ KeyManager.Instance = this;
const isMac = navigator.platform.toLowerCase().indexOf('mac') >= 0;
// SHIFT CONTROL ALT META
@@ -47,27 +47,37 @@ export class KeyManager {
this.router.set(isMac ? '0100' : '0010', this.alt);
this.router.set(isMac ? '1001' : '1100', this.ctrl_shift);
this.router.set('1000', this.shift);
+
+ window.removeEventListener('keydown', KeyManager.Instance.handleModifiers, true);
+ window.addEventListener('keydown', KeyManager.Instance.handleModifiers, true);
+ window.removeEventListener('keyup', KeyManager.Instance.unhandleModifiers);
+ window.addEventListener('keyup', KeyManager.Instance.unhandleModifiers);
+ window.removeEventListener('keydown', KeyManager.Instance.handle);
+ 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);
}
- public unhandle = action((e: KeyboardEvent) => {
- e.key === 'Control' && (CtrlKey = false);
+ public unhandle = action((/* e: KeyboardEvent */) => {
+ /* empty */
});
public handleModifiers = action((e: KeyboardEvent) => {
if (e.shiftKey) SnappingManager.SetShiftKey(true);
if (e.ctrlKey) SnappingManager.SetCtrlKey(true);
+ if (e.metaKey) SnappingManager.SetMetaKey(true);
});
public unhandleModifiers = action((e: KeyboardEvent) => {
if (!e.shiftKey) SnappingManager.SetShiftKey(false);
if (!e.ctrlKey) SnappingManager.SetCtrlKey(false);
+ if (!e.metaKey) SnappingManager.SetMetaKey(false);
});
public handle = action((e: KeyboardEvent) => {
// accumulate buffer of characters to insert in a new text note. once the note is created, it will stop keyboard events from reaching this function.
- if (FormattedTextBox.SelectOnLoadChar) FormattedTextBox.SelectOnLoadChar = FormattedTextBox.SelectOnLoadChar + (e.key === 'Enter' ? '\n' : e.key);
- e.key === 'Control' && (CtrlKey = true);
- //if (!Doc.noviceMode && e.key.toLocaleLowerCase() === "shift") DocServer.UPDATE_SERVER_CACHE(true);
+ if (FormattedTextBox.SelectOnLoadChar) FormattedTextBox.SelectOnLoadChar += e.key === 'Enter' ? '\n' : e.key;
const keyname = e.key && e.key.toLowerCase();
- this.handleGreedy(keyname);
+ this.handleGreedy(/* keyname */);
if (modifiers.includes(keyname)) {
return;
@@ -87,14 +97,11 @@ export class KeyManager {
control.preventDefault && e.preventDefault();
});
- private handleGreedy = action((keyname: string) => {
- switch (keyname) {
- }
- });
+ private handleGreedy = action((/* keyname: string */) => {});
nudge = (x: number, y: number, label: string) => {
- const nudgeable = SelectionManager.Views.some(dv => dv.CollectionFreeFormDocumentView?.nudge);
- nudgeable && UndoManager.RunInBatch(() => SelectionManager.Views.map(dv => dv.CollectionFreeFormDocumentView?.nudge(x, y)), label);
+ const nudgeable = DocumentView.Selected().some(dv => CollectionFreeFormDocumentView.from(dv)?.nudge);
+ nudgeable && UndoManager.RunInBatch(() => DocumentView.Selected().map(dv => CollectionFreeFormDocumentView.from(dv)?.nudge(x, y)), label);
return { stopPropagation: nudgeable, preventDefault: nudgeable };
};
@@ -102,67 +109,62 @@ export class KeyManager {
switch (keyname) {
case 'u':
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
- const ungroupings = SelectionManager.Views;
- UndoManager.RunInBatch(() => ungroupings.map(dv => (dv.layoutDoc.group = undefined)), 'ungroup');
- SelectionManager.DeselectAll();
+ const ungroupings = DocumentView.Selected();
+ undoable(() => () => ungroupings.forEach(dv => { dv.layoutDoc.group = undefined; }), 'ungroup');
+ DocumentView.DeselectAll();
}
break;
case 'g':
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
- const selected = SelectionManager.Views;
- const collectionView = selected.reduce((col, dv) => (col === null || dv.CollectionFreeFormView === col ? dv.CollectionFreeFormView : undefined), null as null | undefined | CollectionFreeFormView);
- if (collectionView) {
- UndoManager.RunInBatch(() =>
- collectionView._marqueeViewRef.current?.collection(e, true, SelectionManager.Docs)
- , 'grouping');
- break;
- }
+ const selected = DocumentView.Selected();
+ const cv = selected.reduce((col, dv) => (!col || CollectionFreeFormView.from(dv) === col ? CollectionFreeFormView.from(dv) : undefined), undefined as undefined | CollectionFreeFormView);
+ cv && undoable(() => cv._marqueeViewRef.current?.collection(e, true, DocumentView.SelectedDocs()), 'grouping');
}
break;
case ' ':
// MarqueeView.DragMarquee = !MarqueeView.DragMarquee; // bcz: this needs a better disclosure UI
break;
- case 'escape':
- DocumentLinksButton.StartLink = undefined;
- DocumentLinksButton.StartLinkView = undefined;
- InkStrokeProperties.Instance._controlButton = false;
- Doc.ActiveTool = InkTool.None;
- DragManager.CompleteWindowDrag?.(true);
- var doDeselect = true;
- if (SnappingManager.IsDragging) {
- DragManager.AbortDrag();
- }
- if (CollectionDockingView.Instance?.HasFullScreen) {
- CollectionDockingView.Instance?.CloseFullScreen();
- }
- if (CollectionStackedTimeline.SelectingRegions.size) {
- CollectionStackedTimeline.StopSelecting();
- doDeselect = false;
- } else {
- doDeselect = !ContextMenu.Instance.closeMenu();
- }
- if (doDeselect) {
- SelectionManager.DeselectAll();
- LightboxView.Instance.SetLightboxDoc(undefined);
+ case 'escape': {
+ DocumentLinksButton.StartLink = undefined;
+ DocumentLinksButton.StartLinkView = undefined;
+ InkStrokeProperties.Instance._controlButton = false;
+ Doc.ActiveTool = InkTool.None;
+ DragManager.CompleteWindowDrag?.(true);
+ let doDeselect = true;
+ if (SnappingManager.IsDragging) {
+ DragManager.AbortDrag();
+ }
+ if (CollectionDockingView.Instance?.HasFullScreen) {
+ CollectionDockingView.Instance?.CloseFullScreen();
+ }
+ if (CollectionStackedTimeline.SelectingRegions.size) {
+ CollectionStackedTimeline.StopSelecting();
+ doDeselect = false;
+ } else {
+ doDeselect = !ContextMenu.Instance.closeMenu();
+ }
+ if (doDeselect) {
+ DocumentView.DeselectAll();
+ DocumentView.SetLightboxDoc(undefined);
+ }
+ // DictationManager.Controls.stop();
+ GoogleAuthenticationManager.Instance.cancel();
+ SharingManager.Instance.close();
+ if (!GroupManager.Instance.isOpen) SettingsManager.Instance.closeMgr();
+ GroupManager.Instance.close();
+ window.getSelection()?.empty();
+ document.body.focus();
}
- // DictationManager.Controls.stop();
- GoogleAuthenticationManager.Instance.cancel();
- SharingManager.Instance.close();
- if (!GroupManager.Instance.isOpen) SettingsManager.Instance.close();
- GroupManager.Instance.close();
- window.getSelection()?.empty();
- document.body.focus();
break;
- case 'enter': {
- //DocumentDecorations.Instance.onCloseClick(false);
+ case 'enter':
+ // DocumentDecorations.Instance.onCloseClick(false);
break;
- }
case 'delete':
case 'backspace':
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
- if (LightboxView.LightboxDoc) {
- LightboxView.Instance.SetLightboxDoc(undefined);
- SelectionManager.DeselectAll();
+ if (DocumentView.LightboxDoc()) {
+ DocumentView.SetLightboxDoc(undefined);
+ DocumentView.DeselectAll();
} else if (!window.getSelection()?.toString()) DocumentDecorations.Instance.onCloseClick(true);
return { stopPropagation: true, preventDefault: true };
}
@@ -171,6 +173,7 @@ export class KeyManager {
case 'arrowright': return this.nudge(1,0, 'nudge right');
case 'arrowup': return this.nudge(0, -1, 'nudge up');
case 'arrowdown': return this.nudge(0, 1, 'nudge down');
+ default:
} // prettier-ignore
return {
@@ -187,17 +190,18 @@ export class KeyManager {
case 'arrowdown': return this.nudge(0, 10, 'nudge down');
case 'u' :
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
- UndoManager.RunInBatch(() => SelectionManager.Docs.forEach(doc => (doc.group = undefined)), 'unggroup');
- SelectionManager.DeselectAll();
+ UndoManager.RunInBatch(() => DocumentView.Selected().map(dv => dv.Document).forEach(doc => {doc.group = undefined}), 'unggroup');
+ DocumentView.DeselectAll();
}
break;
case 'g':
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
const randomGroup = random(0, 1000);
- UndoManager.RunInBatch(() => SelectionManager.Docs.forEach(doc => (doc.group = randomGroup)), 'group');
- SelectionManager.DeselectAll();
+ UndoManager.RunInBatch(() => DocumentView.Selected().forEach(dv => {dv.Document.group = randomGroup}), 'group');
+ DocumentView.DeselectAll();
}
break;
+ default:
} // prettier-ignore
return {
@@ -213,8 +217,9 @@ export class KeyManager {
switch (keyname) {
case 'ƒ':
case 'f':
- const dv = SelectionManager.Views?.[0];
- UndoManager.RunInBatch(() => dv.CollectionFreeFormDocumentView?.float(), 'float');
+ UndoManager.RunInBatch(() => CollectionFreeFormDocumentView.from(DocumentView.Selected()?.[0])?.float(), 'float');
+ break;
+ default:
}
return {
@@ -249,20 +254,24 @@ export class KeyManager {
PromiseValue(Cast(Doc.UserDoc()['tabs-button-tools'], Doc)).then(pv => pv && (pv.onClick as ScriptField).script.run({ this: pv }));
break;
case 'i':
- const importBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyImports);
- if (importBtn) {
- MainView.Instance.selectMenu(importBtn);
+ {
+ const importBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyImports);
+ if (importBtn) {
+ MainView.Instance.selectMenu(importBtn);
+ }
}
break;
case 's':
- const trailsBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyTrails);
- if (trailsBtn) {
- MainView.Instance.selectMenu(trailsBtn);
+ {
+ const trailsBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyTrails);
+ if (trailsBtn) {
+ MainView.Instance.selectMenu(trailsBtn);
+ }
}
break;
case 'f':
- if (SelectionManager.Views.length === 1 && SelectionManager.Views[0].ComponentView?.search) {
- SelectionManager.Views[0].ComponentView?.search?.('', false, false);
+ if (DocumentView.Selected().length === 1 && DocumentView.Selected()[0].ComponentView?.search) {
+ DocumentView.Selected()[0].ComponentView?.search?.('', false, false);
} else {
const searchBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MySearcher);
if (searchBtn) {
@@ -281,14 +290,14 @@ export class KeyManager {
break;
case 'y':
if (Doc.ActivePage !== 'home') {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
UndoManager.Redo();
}
stopPropagation = false;
break;
case 'z':
if (Doc.ActivePage !== 'home') {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
UndoManager.Undo();
}
stopPropagation = false;
@@ -304,11 +313,17 @@ export class KeyManager {
preventDefault = false;
break;
case 'x':
- if (SelectionManager.Views.length) {
+ if (DocumentView.Selected().length) {
const bds = DocumentDecorations.Instance.Bounds;
- const pt = SelectionManager.Views[0].screenToViewTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2);
- const text = `__DashDocId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.Views.map(dv => dv.Document[Id]).join(':');
- SelectionManager.Views.length && navigator.clipboard.writeText(text);
+ const pt = DocumentView.Selected()[0] //
+ .screenToViewTransform()
+ .transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2);
+ const text =
+ `__DashDocId(${pt?.[0] || 0},${pt?.[1] || 0}):` + //
+ DocumentView.Selected()
+ .map(dv => dv.Document[Id])
+ .join(':'); // prettier-ignore
+ DocumentView.Selected().length && navigator.clipboard.writeText(text);
DocumentDecorations.Instance.onCloseClick(true);
stopPropagation = false;
preventDefault = false;
@@ -317,13 +332,20 @@ export class KeyManager {
case 'c':
if ((document.activeElement as any)?.type !== 'text' && !AnchorMenu.Instance.Active && DocumentDecorations.Instance.Bounds.r - DocumentDecorations.Instance.Bounds.x > 2) {
const bds = DocumentDecorations.Instance.Bounds;
- const pt = SelectionManager.Views[0].screenToViewTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2);
- const text = `__DashCloneId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.Views.map(dv => dv.Document[Id]).join(':');
- SelectionManager.Views.length && navigator.clipboard.writeText(text);
+ const pt = DocumentView.Selected()[0]
+ .screenToViewTransform()
+ .transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2); // prettier-ignore
+ const text =
+ `__DashCloneId(${pt?.[0] || 0},${pt?.[1] || 0}):` +
+ DocumentView.SelectedDocs()
+ .map(doc => doc[Id])
+ .join(':'); // prettier-ignore
+ DocumentView.Selected().length && navigator.clipboard.writeText(text);
stopPropagation = false;
}
preventDefault = false;
break;
+ default:
}
return {
@@ -337,7 +359,7 @@ export class KeyManager {
if (!plain) return;
const clone = plain.startsWith('__DashCloneId(');
const docids = plain.split(':'); // hack! docids[0] is the top left of the selection rectangle
- const addDocument = SelectionManager.Views.lastElement()?.ComponentView?.addDocument;
+ const addDocument = DocumentView.Selected().lastElement()?.ComponentView?.addDocument;
if (addDocument && (plain.startsWith('__DashDocId(') || clone)) {
Doc.Paste(docids.slice(1), clone, addDocument);
}
@@ -358,6 +380,7 @@ export class KeyManager {
case 'p':
Doc.ActiveTool = InkTool.Write;
break;
+ default:
}
return {
diff --git a/src/client/views/InkControlPtHandles.tsx b/src/client/views/InkControlPtHandles.tsx
index 31b13d2c8..a49923ffb 100644
--- a/src/client/views/InkControlPtHandles.tsx
+++ b/src/client/views/InkControlPtHandles.tsx
@@ -1,18 +1,20 @@
import * as React from 'react';
-import { action, observable } from 'mobx';
+import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import { Doc } from '../../fields/Doc';
-import { ControlPoint, InkData, PointData } from '../../fields/InkField';
+import { ControlPoint, InkData } from '../../fields/InkField';
import { List } from '../../fields/List';
import { listSpec } from '../../fields/Schema';
import { Cast } from '../../fields/Types';
-import { returnFalse, setupMoveUpEvents } from '../../Utils';
-import { SelectionManager } from '../util/SelectionManager';
+import { returnFalse, setupMoveUpEvents } from '../../ClientUtils';
import { UndoManager } from '../util/UndoManager';
import { Colors } from './global/globalEnums';
import { InkingStroke } from './InkingStroke';
import { InkStrokeProperties } from './InkStrokeProperties';
import { SnappingManager } from '../util/SnappingManager';
+import { ObservableReactComponent } from './ObservableReactComponent';
+import { PointData } from '../../pen-gestures/GestureTypes';
+import { DocumentView } from './nodes/DocumentView';
export interface InkControlProps {
inkDoc: Doc;
@@ -24,10 +26,15 @@ export interface InkControlProps {
}
@observer
-export class InkControlPtHandles extends React.Component<InkControlProps> {
+export class InkControlPtHandles extends ObservableReactComponent<InkControlProps> {
@observable private _overControl = -1;
get docView() {
- return this.props.inkView.DocumentView?.();
+ return this._props.inkView.DocumentView?.();
+ }
+
+ constructor(props: InkControlProps) {
+ super(props);
+ makeObservable(this);
}
componentDidMount() {
@@ -42,51 +49,51 @@ export class InkControlPtHandles extends React.Component<InkControlProps> {
*/
@action
onControlDown = (e: React.PointerEvent, controlIndex: number): void => {
- const ptFromScreen = this.props.inkView.ptFromScreen;
+ const { ptFromScreen } = this._props.inkView;
if (ptFromScreen) {
const order = controlIndex % 4;
- const handleIndexA = ((order === 3 ? controlIndex - 1 : controlIndex - 2) + this.props.inkCtrlPoints.length) % this.props.inkCtrlPoints.length;
- const handleIndexB = (order === 3 ? controlIndex + 2 : controlIndex + 1) % this.props.inkCtrlPoints.length;
- const brokenIndices = Cast(this.props.inkDoc.brokenInkIndices, listSpec('number'));
+ const handleIndexA = ((order === 3 ? controlIndex - 1 : controlIndex - 2) + this._props.inkCtrlPoints.length) % this._props.inkCtrlPoints.length;
+ const handleIndexB = (order === 3 ? controlIndex + 2 : controlIndex + 1) % this._props.inkCtrlPoints.length;
+ const brokenIndices = Cast(this._props.inkDoc.brokenInkIndices, listSpec('number'));
const wasSelected = InkStrokeProperties.Instance._currentPoint === controlIndex;
if (!wasSelected) InkStrokeProperties.Instance._currentPoint = -1;
- const origInk = this.props.inkCtrlPoints.slice();
+ const origInk = this._props.inkCtrlPoints.slice();
setupMoveUpEvents(
this,
e,
- action((e: PointerEvent, down: number[], delta: number[]) => {
- if (!this.props.inkView.controlUndo) this.props.inkView.controlUndo = UndoManager.StartBatch('drag ink ctrl pt');
+ action((moveEv: PointerEvent, down: number[], delta: number[]) => {
+ if (!this._props.inkView.controlUndo) this._props.inkView.controlUndo = UndoManager.StartBatch('drag ink ctrl pt');
const inkMoveEnd = ptFromScreen({ X: delta[0], Y: delta[1] });
const inkMoveStart = ptFromScreen({ X: 0, Y: 0 });
this.docView && InkStrokeProperties.Instance.moveControlPtHandle(this.docView, inkMoveEnd.X - inkMoveStart.X, inkMoveEnd.Y - inkMoveStart.Y, controlIndex, origInk);
return false;
}),
action(() => {
- if (this.props.inkView.controlUndo && this.docView) {
+ if (this._props.inkView.controlUndo && this.docView) {
InkStrokeProperties.Instance.snapControl(this.docView, controlIndex);
}
- this.props.inkView.controlUndo?.end();
- this.props.inkView.controlUndo = undefined;
+ this._props.inkView.controlUndo?.end();
+ this._props.inkView.controlUndo = undefined;
UndoManager.FilterBatches(['data', 'x', 'y', 'width', 'height']);
}),
- action((e: PointerEvent, doubleTap: boolean | undefined) => {
- const equivIndex = controlIndex === 0 ? this.props.inkCtrlPoints.length - 1 : controlIndex === this.props.inkCtrlPoints.length - 1 ? 0 : controlIndex;
- if (doubleTap || e.button === 2) {
+ action((moveEv: PointerEvent, doubleTap: boolean | undefined) => {
+ const equivIndex = controlIndex === 0 ? this._props.inkCtrlPoints.length - 1 : controlIndex === this._props.inkCtrlPoints.length - 1 ? 0 : controlIndex;
+ if (doubleTap || moveEv.button === 2) {
if (!brokenIndices?.includes(equivIndex) && !brokenIndices?.includes(controlIndex)) {
if (brokenIndices) brokenIndices.push(controlIndex);
- else this.props.inkDoc.brokenInkIndices = new List<number>([controlIndex]);
+ else this._props.inkDoc.brokenInkIndices = new List<number>([controlIndex]);
} else {
if (brokenIndices?.includes(equivIndex)) {
- if (!this.props.inkView.controlUndo) this.props.inkView.controlUndo = UndoManager.StartBatch('make smooth');
+ if (!this._props.inkView.controlUndo) this._props.inkView.controlUndo = UndoManager.StartBatch('make smooth');
this.docView && InkStrokeProperties.Instance.snapHandleTangent(this.docView, equivIndex, handleIndexA, handleIndexB);
}
if (equivIndex !== controlIndex && brokenIndices?.includes(controlIndex)) {
- if (!this.props.inkView.controlUndo) this.props.inkView.controlUndo = UndoManager.StartBatch('make smooth');
+ if (!this._props.inkView.controlUndo) this._props.inkView.controlUndo = UndoManager.StartBatch('make smooth');
this.docView && InkStrokeProperties.Instance.snapHandleTangent(this.docView, controlIndex, handleIndexA, handleIndexB);
}
}
- this.props.inkView.controlUndo?.end();
- this.props.inkView.controlUndo = undefined;
+ this._props.inkView.controlUndo?.end();
+ this._props.inkView.controlUndo = undefined;
}
this.changeCurrPoint(controlIndex);
}),
@@ -122,18 +129,20 @@ export class InkControlPtHandles extends React.Component<InkControlProps> {
* Changes the current selected control point.
*/
@action
- changeCurrPoint = (i: number) => (InkStrokeProperties.Instance._currentPoint = i);
+ changeCurrPoint = (i: number) => {
+ InkStrokeProperties.Instance._currentPoint = i;
+ };
render() {
// Accessing the current ink's data and extracting all control points.
- const scrData = this.props.screenCtrlPoints;
+ const scrData = this._props.screenCtrlPoints;
const sreenCtrlPoints: ControlPoint[] = [];
for (let i = 0; i <= scrData.length - 4; i += 4) {
sreenCtrlPoints.push({ ...scrData[i], I: i });
sreenCtrlPoints.push({ ...scrData[i + 3], I: i + 3 });
}
- const inkData = this.props.inkCtrlPoints;
+ const inkData = this._props.inkCtrlPoints;
const inkCtrlPts: ControlPoint[] = [];
for (let i = 0; i <= inkData.length - 4; i += 4) {
inkCtrlPts.push({ ...inkData[i], I: i });
@@ -141,23 +150,23 @@ export class InkControlPtHandles extends React.Component<InkControlProps> {
}
const closed = InkingStroke.IsClosed(inkData);
- const nearestScreenPt = this.props.nearestScreenPt();
+ const nearestScreenPt = this._props.nearestScreenPt();
const TagType = (broken?: boolean) => (broken ? 'rect' : 'circle');
const hdl = (control: { X: number; Y: number; I: number }, scale: number, color: string) => {
- const broken = Cast(this.props.inkDoc.brokenInkIndices, listSpec('number'))?.includes(control.I);
+ const broken = Cast(this._props.inkDoc.brokenInkIndices, listSpec('number'))?.includes(control.I);
const Tag = TagType((control.I === 0 || control.I === inkData.length - 1) && !closed) as keyof JSX.IntrinsicElements;
return (
<Tag
key={control.I.toString() + scale}
- x={control.X - this.props.screenSpaceLineWidth * 2 * scale}
- y={control.Y - this.props.screenSpaceLineWidth * 2 * scale}
+ x={control.X - this._props.screenSpaceLineWidth * 2 * scale}
+ y={control.Y - this._props.screenSpaceLineWidth * 2 * scale}
cx={control.X}
cy={control.Y}
- r={this.props.screenSpaceLineWidth * 2 * scale}
- opacity={this.props.inkView.controlUndo ? 0.35 : 1}
- height={this.props.screenSpaceLineWidth * 4 * scale}
- width={this.props.screenSpaceLineWidth * 4 * scale}
- strokeWidth={this.props.screenSpaceLineWidth / 2}
+ r={this._props.screenSpaceLineWidth * 2 * scale}
+ opacity={this._props.inkView.controlUndo ? 0.35 : 1}
+ height={this._props.screenSpaceLineWidth * 4 * scale}
+ width={this._props.screenSpaceLineWidth * 4 * scale}
+ strokeWidth={this._props.screenSpaceLineWidth / 2}
stroke={Colors.MEDIUM_BLUE}
fill={broken ? Colors.MEDIUM_BLUE : color}
onPointerDown={(e: React.PointerEvent) => this.onControlDown(e, control.I)}
@@ -170,7 +179,7 @@ export class InkControlPtHandles extends React.Component<InkControlProps> {
};
return (
<svg>
- {!nearestScreenPt ? null : <circle key={'npt'} cx={nearestScreenPt.X} cy={nearestScreenPt.Y} r={this.props.screenSpaceLineWidth * 2} fill={'#00007777'} stroke={'#00007777'} strokeWidth={0} pointerEvents="none" />}
+ {!nearestScreenPt ? null : <circle key="npt" cx={nearestScreenPt.X} cy={nearestScreenPt.Y} r={this._props.screenSpaceLineWidth * 2} fill="#00007777" stroke="#00007777" strokeWidth={0} pointerEvents="none" />}
{sreenCtrlPoints.map(control => hdl(control, this._overControl !== control.I ? 1 : 3 / 2, Colors.WHITE))}
</svg>
);
@@ -185,10 +194,15 @@ export interface InkEndProps {
endPt: () => PointData;
}
@observer
-export class InkEndPtHandles extends React.Component<InkEndProps> {
+export class InkEndPtHandles extends ObservableReactComponent<InkEndProps> {
@observable _overStart: boolean = false;
@observable _overEnd: boolean = false;
+ constructor(props: InkEndProps) {
+ super(props);
+ makeObservable(this);
+ }
+
_throttle = 0; // need to throttle dragging since the position may change when the control points change. this allows the stroke to settle so that we don't get increasingly bad jitter
@action
dragRotate = (e: React.PointerEvent, pt1: () => { X: number; Y: number }, pt2: () => { X: number; Y: number }) => {
@@ -196,28 +210,28 @@ export class InkEndPtHandles extends React.Component<InkEndProps> {
setupMoveUpEvents(
this,
e,
- action(e => {
+ action(moveEv => {
if (this._throttle++ % 2 !== 0) return false;
- if (!this.props.inkView.controlUndo) this.props.inkView.controlUndo = UndoManager.StartBatch('stretch ink');
+ if (!this._props.inkView.controlUndo) this._props.inkView.controlUndo = UndoManager.StartBatch('stretch ink');
// compute stretch factor by finding scaling along axis between start and end points
const p1 = pt1();
const p2 = pt2();
const v1 = { X: p1.X - p2.X, Y: p1.Y - p2.Y };
- const v2 = { X: e.clientX - p2.X, Y: e.clientY - p2.Y };
+ const v2 = { X: moveEv.clientX - p2.X, Y: moveEv.clientY - p2.Y };
const v1len = Math.sqrt(v1.X * v1.X + v1.Y * v1.Y);
const v2len = Math.sqrt(v2.X * v2.X + v2.Y * v2.Y);
const scaling = v2len / v1len;
const v1n = { X: v1.X / v1len, Y: v1.Y / v1len };
const v2n = { X: v2.X / v2len, Y: v2.Y / v2len };
const angle = Math.acos(v1n.X * v2n.X + v1n.Y * v2n.Y) * Math.sign(v1.X * v2.Y - v2.X * v1.Y);
- InkStrokeProperties.Instance.stretchInk(SelectionManager.Views, scaling, p2, v1n, e.shiftKey);
- InkStrokeProperties.Instance.rotateInk(SelectionManager.Views, angle, pt2()); // bcz: call pt2() func here because pt2 will have changed from previous stretchInk call
+ InkStrokeProperties.Instance.stretchInk(DocumentView.Selected(), scaling, p2, v1n, moveEv.shiftKey);
+ InkStrokeProperties.Instance.rotateInk(DocumentView.Selected(), angle, pt2()); // bcz: call pt2() func here because pt2 will have changed from previous stretchInk call
return false;
}),
action(() => {
SnappingManager.SetIsDragging(false);
- this.props.inkView.controlUndo?.end();
- this.props.inkView.controlUndo = undefined;
+ this._props.inkView.controlUndo?.end();
+ this._props.inkView.controlUndo = undefined;
UndoManager.FilterBatches(['stroke', 'x', 'y', 'width', 'height']);
}),
returnFalse
@@ -228,22 +242,26 @@ export class InkEndPtHandles extends React.Component<InkEndProps> {
const hdl = (key: string, pt: PointData, dragFunc: (e: React.PointerEvent) => void) => (
<circle
key={key}
- cx={pt.X}
- cy={pt.Y}
- r={this.props.screenSpaceLineWidth * 2}
+ cx={pt?.X}
+ cy={pt?.Y}
+ r={this._props.screenSpaceLineWidth * 2}
fill={this._overStart ? '#aaaaaa' : '#99999977'}
- stroke={'#00007777'}
+ stroke="#00007777"
strokeWidth={0}
- onPointerLeave={action(() => (this._overStart = false))}
- onPointerEnter={action(() => (this._overStart = true))}
+ onPointerLeave={action(() => {
+ this._overStart = false;
+ })}
+ onPointerEnter={action(() => {
+ this._overStart = true;
+ })}
onPointerDown={dragFunc}
pointerEvents="all"
/>
);
return (
<svg>
- {hdl('start', this.props.startPt(), e => this.dragRotate(e, this.props.startPt, this.props.endPt))}
- {hdl('end', this.props.endPt(), e => this.dragRotate(e, this.props.endPt, this.props.startPt))}
+ {hdl('start', this._props.startPt(), e => this.dragRotate(e, this._props.startPt, this._props.endPt))}
+ {hdl('end', this._props.endPt(), e => this.dragRotate(e, this._props.endPt, this._props.startPt))}
</svg>
);
}
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index 52ea89cde..3920ecc2a 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -1,20 +1,22 @@
import { Bezier } from 'bezier-js';
+import * as _ from 'lodash';
import { action, makeObservable, observable, reaction, runInAction } from 'mobx';
import { Doc, NumListCast, Opt } from '../../fields/Doc';
-import { InkData, InkField, InkTool, PointData } from '../../fields/InkField';
+import { InkData, InkField, InkTool } from '../../fields/InkField';
import { List } from '../../fields/List';
import { listSpec } from '../../fields/Schema';
import { Cast, NumCast } from '../../fields/Types';
+import { PointData } from '../../pen-gestures/GestureTypes';
import { Point } from '../../pen-gestures/ndollar';
import { DocumentType } from '../documents/DocumentTypes';
-import { FitOneCurve } from '../util/bezierFit';
-import { DocumentManager } from '../util/DocumentManager';
import { undoBatch } from '../util/UndoManager';
+import { FitOneCurve } from '../util/bezierFit';
import { InkingStroke } from './InkingStroke';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { DocumentView } from './nodes/DocumentView';
-import * as _ from 'lodash';
export class InkStrokeProperties {
+ // eslint-disable-next-line no-use-before-define
static _Instance: InkStrokeProperties | undefined;
public static get Instance() {
return this._Instance || new InkStrokeProperties();
@@ -28,11 +30,15 @@ export class InkStrokeProperties {
makeObservable(this);
reaction(
() => this._controlButton,
- button => button && (Doc.ActiveTool = InkTool.None)
+ button => {
+ button && (Doc.ActiveTool = InkTool.None);
+ }
);
reaction(
() => Doc.ActiveTool,
- tool => tool !== InkTool.None && (this._controlButton = false)
+ tool => {
+ tool !== InkTool.None && (this._controlButton = false);
+ }
);
}
@@ -46,7 +52,7 @@ export class InkStrokeProperties {
func: (view: DocumentView, ink: InkData, ptsXscale: number, ptsYscale: number, inkStrokeWidth: number) => { X: number; Y: number }[] | undefined,
requireCurrPoint: boolean = false
) => {
- var appliedFunc = false;
+ let appliedFunc = false;
(strokes instanceof DocumentView ? [strokes] : strokes)?.forEach(
action(inkView => {
if (!requireCurrPoint || this._currentPoint !== -1) {
@@ -85,7 +91,7 @@ export class InkStrokeProperties {
*/
@undoBatch
addPoints = (inkView: DocumentView, t: number, i: number, controls: { X: number; Y: number }[]) => {
- this.applyFunction(inkView, (view: DocumentView, ink: InkData) => {
+ this.applyFunction(inkView, (view: DocumentView /* , ink: InkData */) => {
const doc = view.Document;
const array = [controls[i], controls[i + 1], controls[i + 2], controls[i + 3]];
const newsegs = new Bezier(array.map(p => ({ x: p.X, y: p.Y }))).split(t);
@@ -94,7 +100,9 @@ export class InkStrokeProperties {
// Updating the indices of the control points whose handle tangency has been broken.
doc.brokenInkIndices = new List(Cast(doc.brokenInkIndices, listSpec('number'), []).map(control => (control > i ? control + 4 : control)));
- runInAction(() => (this._currentPoint = -1));
+ runInAction(() => {
+ this._currentPoint = -1;
+ });
return controls;
});
@@ -126,8 +134,8 @@ export class InkStrokeProperties {
*/
getNewHandlePoints = (C: PointData[], D: PointData[], newControl: PointData) => {
const [m, n] = [C.length, D.length];
- let handleSizeA = Math.sqrt(Math.pow(newControl.X - C[0].X, 2) + Math.pow(newControl.Y - C[0].Y, 2));
- let handleSizeB = Math.sqrt(Math.pow(D[n - 1].X - newControl.X, 2) + Math.pow(D[n - 1].Y - newControl.Y, 2));
+ let handleSizeA = Math.sqrt((newControl.X - C[0].X) ** 2 + (newControl.Y - C[0].Y) ** 2);
+ let handleSizeB = Math.sqrt((D[n - 1].X - newControl.X) ** 2 + (D[n - 1].Y - newControl.Y) ** 2);
// Scaling adjustments to improve the ratio between the magnitudes of the two handle lines.
// (Ensures that the new point added doesn't augment the inital shape of the curve much).
if (handleSizeA < 75 && handleSizeB < 75) {
@@ -167,13 +175,13 @@ export class InkStrokeProperties {
const start = this._currentPoint === 0 ? 0 : this._currentPoint - 4;
const splicedPoints = ink.slice(start, start + (this._currentPoint === 0 || this._currentPoint === ink.length - 1 ? 4 : 8));
const samples: Point[] = [];
- var startDir = { x: 0, y: 0 };
- var endDir = { x: 0, y: 0 };
- for (var i = 0; i < splicedPoints.length / 4; i++) {
+ let startDir = { x: 0, y: 0 };
+ let endDir = { x: 0, y: 0 };
+ for (let i = 0; i < splicedPoints.length / 4; i++) {
const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y })));
if (i === 0) startDir = bez.derivative(0);
if (i === splicedPoints.length / 4 - 1) endDir = bez.derivative(1);
- for (var t = 0; t < (i === splicedPoints.length / 4 - 1 ? 1 + 1e-7 : 1); t += 0.05) {
+ for (let t = 0; t < (i === splicedPoints.length / 4 - 1 ? 1 + 1e-7 : 1); t += 0.05) {
const pt = bez.compute(t);
samples.push(new Point(pt.x, pt.y));
}
@@ -186,7 +194,9 @@ export class InkStrokeProperties {
}
}
doc.brokenInkIndices = new List(brokenIndices.map(control => (control >= this._currentPoint ? control - 4 : control)));
- runInAction(() => (this._currentPoint = -1));
+ runInAction(() => {
+ this._currentPoint = -1;
+ });
return newPoints.length < 4 ? undefined : newPoints;
},
true
@@ -200,7 +210,7 @@ export class InkStrokeProperties {
*/
@undoBatch
rotateInk = (inkStrokes: DocumentView[], angle: number, scrpt: PointData) => {
- this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData, xScale: number, yScale: number, inkStrokeWidth: number) => {
+ this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData, xScale: number, yScale: number /* , inkStrokeWidth: number */) => {
const inkCenterPt = view.ComponentView?.ptFromScreen?.(scrpt);
return !inkCenterPt
? ink
@@ -247,37 +257,37 @@ export class InkStrokeProperties {
const closed = InkingStroke.IsClosed(ink);
const brokenIndices = Cast(inkView.Document.brokenInkIndices, listSpec('number'), []);
if (origInk && this._currentPoint > 0 && this._currentPoint < ink.length - 1 && brokenIndices.findIndex(value => value === controlIndex) === -1) {
- const cpt_before = ink[controlIndex];
- const cpt = { X: cpt_before.X + deltaX, Y: cpt_before.Y + deltaY };
+ const cptBefore = ink[controlIndex];
+ const cpt = { X: cptBefore.X + deltaX, Y: cptBefore.Y + deltaY };
const newink = origInk.slice();
const start = this._currentPoint === 0 ? 0 : this._currentPoint - 4;
const splicedPoints = origInk.slice(start, start + (this._currentPoint === 0 || this._currentPoint === ink.length - 1 ? 4 : 8));
const { nearestT, nearestSeg } = InkStrokeProperties.nearestPtToStroke(splicedPoints, cpt);
- if ((nearestSeg === 0 && nearestT < 1e-1) || (nearestSeg === 4 && 1 - nearestT < 1e-1)) return ink.slice();
+ if ((nearestSeg === 0 && nearestT < 1e-1) || (nearestSeg === 4 && 1 - nearestT < 1e-1) || nearestSeg < 0) return ink.slice();
const samplesLeft: Point[] = [];
const samplesRight: Point[] = [];
- var startDir = { x: 0, y: 0 };
- var endDir = { x: 0, y: 0 };
- for (var i = 0; i < nearestSeg / 4 + 1; i++) {
+ let startDir = { x: 0, y: 0 };
+ let endDir = { x: 0, y: 0 };
+ for (let i = 0; i < nearestSeg / 4 + 1; i++) {
const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y })));
if (i === 0) startDir = bez.derivative(_.isEqual(bez.derivative(0), { x: 0, y: 0, t: 0 }) ? 1e-8 : 0);
if (i === nearestSeg / 4) endDir = bez.derivative(nearestT);
- for (var t = 0; t < (i === nearestSeg / 4 ? nearestT + 0.05 : 1); t += 0.05) {
+ for (let t = 0; t < (i === nearestSeg / 4 ? nearestT + 0.05 : 1); t += 0.05) {
const pt = bez.compute(i !== nearestSeg / 4 ? t : Math.min(nearestT, t));
samplesLeft.push(new Point(pt.x, pt.y));
}
}
- var { finalCtrls } = FitOneCurve(samplesLeft, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y });
- for (var i = nearestSeg / 4; i < splicedPoints.length / 4; i++) {
+ let { finalCtrls } = FitOneCurve(samplesLeft, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y });
+ for (let i = nearestSeg / 4; i < splicedPoints.length / 4; i++) {
const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y })));
if (i === nearestSeg / 4) startDir = bez.derivative(nearestT);
if (i === splicedPoints.length / 4 - 1) endDir = bez.derivative(_.isEqual(bez.derivative(1), { x: 0, y: 0, t: 1 }) ? 1 - 1e-8 : 1);
- for (var t = i === nearestSeg / 4 ? nearestT : 0; t < (i === nearestSeg / 4 ? 1 + 0.05 + 1e-7 : 1 + 1e-7); t += 0.05) {
+ for (let t = i === nearestSeg / 4 ? nearestT : 0; t < (i === nearestSeg / 4 ? 1 + 0.05 + 1e-7 : 1 + 1e-7); t += 0.05) {
const pt = bez.compute(Math.min(1, t));
samplesRight.push(new Point(pt.x, pt.y));
}
}
- const { finalCtrls: rightCtrls, error: errorRight } = FitOneCurve(samplesRight, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y });
+ const { finalCtrls: rightCtrls /* , error: errorRight */ } = FitOneCurve(samplesRight, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y });
finalCtrls = finalCtrls.concat(rightCtrls);
newink.splice(this._currentPoint - 4, 8, ...finalCtrls);
return newink;
@@ -307,11 +317,12 @@ export class InkStrokeProperties {
});
public static nearestPtToStroke(ctrlPoints: { X: number; Y: number }[], refInkSpacePt: { X: number; Y: number }, excludeSegs?: number[]) {
- var distance = Number.MAX_SAFE_INTEGER;
- var nearestT = -1;
- var nearestSeg = -1;
- var nearestPt = { X: 0, Y: 0 };
- for (var i = 0; i < ctrlPoints.length - 3; i += 4) {
+ let distance = Number.MAX_SAFE_INTEGER;
+ let nearestT = -1;
+ let nearestSeg = -1;
+ let nearestPt = { X: 0, Y: 0 };
+ for (let i = 0; i < ctrlPoints.length - 3; i += 4) {
+ // eslint-disable-next-line no-continue
if (excludeSegs?.includes(i)) continue;
const array = [ctrlPoints[i], ctrlPoints[i + 1], ctrlPoints[i + 2], ctrlPoints[i + 3]];
const point = new Bezier(array.map(p => ({ x: p.X, y: p.Y }))).project({ x: refInkSpacePt.X, y: refInkSpacePt.Y });
@@ -369,17 +380,18 @@ export class InkStrokeProperties {
};
snapToAllCurves = (screenDragPt: { X: number; Y: number }, inkView: DocumentView, snapData: { nearestPt: { X: number; Y: number }; distance: number }, ink: InkData, controlIndex: number) => {
- const containingCollection = inkView.CollectionFreeFormView;
+ const containingCollection = CollectionFreeFormView.from(inkView);
const containingDocView = containingCollection?.DocumentView?.();
containingCollection?.childDocs
.filter(doc => doc.type === DocumentType.INK)
.forEach(doc => {
- const testInkView = DocumentManager.Instance.getDocumentView(doc, containingDocView);
+ const testInkView = DocumentView.getDocumentView(doc, containingDocView);
const snapped = testInkView?.ComponentView?.snapPt?.(screenDragPt, doc === inkView.Document ? this.excludeSelfSnapSegs(ink, controlIndex) : []);
if (snapped && snapped.distance < snapData.distance) {
const snappedInkPt = doc === inkView.Document ? snapped.nearestPt : inkView.ComponentView?.ptFromScreen?.(testInkView?.ComponentView?.ptToScreen?.(snapped.nearestPt) ?? { X: 0, Y: 0 }); // convert from snapped ink coordinate system to dragged ink coordinate system by converting to/from screen space
if (snappedInkPt) {
+ // eslint-disable-next-line no-param-reassign
snapData = { nearestPt: snappedInkPt, distance: snapped.distance };
}
}
@@ -406,6 +418,7 @@ export class InkStrokeProperties {
inkCopy[handleIndexB] = this.rotatePoint(handleB, controlPoint, angleDifference);
return inkCopy;
}
+ return undefined;
});
};
@@ -430,7 +443,9 @@ export class InkStrokeProperties {
const magnitudeB = Math.sqrt(vectorB.X * vectorB.X + vectorB.Y * vectorB.Y);
if (magnitudeA === 0 || magnitudeB === 0) return 0;
// Normalizing the vectors.
+ // eslint-disable-next-line no-param-reassign
vectorA = { X: vectorA.X / magnitudeA, Y: vectorA.Y / magnitudeA };
+ // eslint-disable-next-line no-param-reassign
vectorB = { X: vectorB.X / magnitudeB, Y: vectorB.Y / magnitudeB };
return Math.acos(vectorB.X * vectorA.X + vectorB.Y * vectorA.Y);
}
diff --git a/src/client/views/InkTangentHandles.tsx b/src/client/views/InkTangentHandles.tsx
index c20399698..577acc4d1 100644
--- a/src/client/views/InkTangentHandles.tsx
+++ b/src/client/views/InkTangentHandles.tsx
@@ -6,18 +6,18 @@ import { HandleLine, HandlePoint, InkData } from '../../fields/InkField';
import { List } from '../../fields/List';
import { listSpec } from '../../fields/Schema';
import { Cast } from '../../fields/Types';
-import { emptyFunction, setupMoveUpEvents } from '../../Utils';
-import { Transform } from '../util/Transform';
+import { emptyFunction } from '../../Utils';
+import { setupMoveUpEvents } from '../../ClientUtils';
import { UndoManager } from '../util/UndoManager';
import { Colors } from './global/globalEnums';
import { InkingStroke } from './InkingStroke';
import { InkStrokeProperties } from './InkStrokeProperties';
+
export interface InkHandlesProps {
inkDoc: Doc;
inkView: InkingStroke;
screenCtrlPoints: InkData;
screenSpaceLineWidth: number;
- ScreenToLocalTransform: () => Transform;
}
@observer
@@ -37,9 +37,9 @@ export class InkTangentHandles extends React.Component<InkHandlesProps> {
setupMoveUpEvents(
this,
e,
- action((e: PointerEvent, down: number[], delta: number[]) => {
+ action((moveEv: PointerEvent, down: number[], delta: number[]) => {
if (!this.props.inkView.controlUndo) this.props.inkView.controlUndo = UndoManager.StartBatch('DocDecs move tangent');
- if (e.altKey) this.onBreakTangent(controlIndex);
+ if (moveEv.altKey) this.onBreakTangent(controlIndex);
const inkMoveEnd = this.props.inkView.ptFromScreen({ X: delta[0], Y: delta[1] });
const inkMoveStart = this.props.inkView.ptFromScreen({ X: 0, Y: 0 });
this.docView && InkStrokeProperties.Instance.moveTangentHandle(this.docView, -(inkMoveEnd.X - inkMoveStart.X), -(inkMoveEnd.Y - inkMoveStart.Y), handleIndex, oppositeHandleIndex, controlIndex);
@@ -100,11 +100,12 @@ export class InkTangentHandles extends React.Component<InkHandlesProps> {
tangentLines.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 1].X, Y2: data[i + 1].Y, X3: data[i + 3].X, Y3: data[i + 3].Y, dot1: i + 1, dot2: i + 2 });
}
}
- const screenSpaceLineWidth = this.props.screenSpaceLineWidth;
+ const { screenSpaceLineWidth } = this.props;
return (
<>
{tangentHandles.map((pts, i) => (
+ // eslint-disable-next-line react/no-array-index-key
<svg height="10" width="10" key={`hdl${i}`}>
<circle
cx={pts.X}
@@ -128,12 +129,13 @@ export class InkTangentHandles extends React.Component<InkHandlesProps> {
x2={x2}
y2={y2}
stroke={Colors.MEDIUM_BLUE}
- strokeDasharray={'1 1'}
+ strokeDasharray="1 1"
strokeWidth={1}
display={pts.dot1 === InkStrokeProperties.Instance._currentPoint || pts.dot2 === InkStrokeProperties.Instance._currentPoint ? 'inherit' : 'none'}
/>
);
return (
+ // eslint-disable-next-line react/no-array-index-key
<svg height="100" width="100" key={`line${i}`}>
{tangentLine(pts.X1, pts.Y1, pts.X2, pts.Y2)}
{tangentLine(pts.X2, pts.Y2, pts.X3, pts.Y3)}
diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx
index 7e2b334af..1ed8de1be 100644
--- a/src/client/views/InkTranscription.tsx
+++ b/src/client/views/InkTranscription.tsx
@@ -6,7 +6,6 @@
// import { Cast, DateCast, NumCast } from '../../fields/Types';
// import { aggregateBounds } from '../../Utils';
// import { DocumentType } from '../documents/DocumentTypes';
-// import { DocumentManager } from '../util/DocumentManager';
// import { CollectionFreeFormView } from './collections/collectionFreeForm';
// import { InkingStroke } from './InkingStroke';
// import './InkTranscription.scss';
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 122e5c4c3..55f28f415 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -23,30 +23,34 @@
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { DashColor, returnFalse, setupMoveUpEvents } from '../../ClientUtils';
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 { DashColor, returnFalse, setupMoveUpEvents } from '../../Utils';
import { CognitiveServices } from '../cognitive_services/CognitiveServices';
import { Docs } from '../documents/Documents';
+import { DocumentType } from '../documents/DocumentTypes';
import { InteractionUtils } from '../util/InteractionUtils';
import { SnappingManager } from '../util/SnappingManager';
import { UndoManager } from '../util/UndoManager';
import { ContextMenu } from './ContextMenu';
-import { ViewBoxBaseComponent, ViewBoxInterface } from './DocComponent';
+import { ViewBoxInterface } from './ViewBoxInterface';
+import { ViewBoxAnnotatableComponent } from './DocComponent';
import { Colors } from './global/globalEnums';
import { InkControlPtHandles, InkEndPtHandles } from './InkControlPtHandles';
import './InkStroke.scss';
import { InkStrokeProperties } from './InkStrokeProperties';
import { InkTangentHandles } from './InkTangentHandles';
import { FieldView, FieldViewProps } from './nodes/FieldView';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
-import { PinProps, PresBox } from './nodes/trails';
-import { StyleProp } from './StyleProvider';
-const { default: { INK_MASK_SIZE } } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
+import { FormattedTextBox, FormattedTextBoxProps } from './nodes/formattedText/FormattedTextBox';
+import { PinDocView, PinProps } from './PinFuncs';
+import { StyleProp } from './StyleProp';
+
+const { INK_MASK_SIZE } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
+
@observer
-export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() implements ViewBoxInterface {
+export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>() {
static readonly MaskDim = INK_MASK_SIZE; // choose a really big number to make sure mask fits over container (which in theory can be arbitrarily big)
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(InkingStroke, fieldStr);
@@ -65,7 +69,9 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
this._props.setContentViewBox?.(this);
this._disposers.selfDisper = reaction(
() => this._props.isSelected(), // react to stroke being deselected by turning off ink handles
- selected => !selected && (InkStrokeProperties.Instance._controlButton = false)
+ selected => {
+ !selected && (InkStrokeProperties.Instance._controlButton = false);
+ }
);
}
componentWillUnmount() {
@@ -87,8 +93,8 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
});
if (anchor) {
anchor.backgroundColor = 'transparent';
- // /* addAsAnnotation &&*/ this.addDocument(anchor);
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), inkable: true } }, this.Document);
+ addAsAnnotation && this.addDocument(anchor);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), inkable: true } }, this.Document);
return anchor;
}
return this.Document;
@@ -140,7 +146,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
e,
!isEditing
? returnFalse
- : action((e: PointerEvent, down: number[], delta: number[]) => {
+ : action((moveEv: PointerEvent, down: number[], delta: number[]) => {
if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch('drag ink ctrl pt');
const inkMoveEnd = this.ptFromScreen({ X: delta[0], Y: delta[1] });
const inkMoveStart = this.ptFromScreen({ X: 0, Y: 0 });
@@ -155,7 +161,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
this.controlUndo = undefined;
UndoManager.FilterBatches(['data', 'x', 'y', 'width', 'height']);
}),
- action((e: PointerEvent, doubleTap: boolean | undefined) => {
+ action((moveEv: PointerEvent, doubleTap: boolean | undefined) => {
if (doubleTap) {
InkStrokeProperties.Instance._controlButton = true;
InkStrokeProperties.Instance._currentPoint = -1;
@@ -167,7 +173,9 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
}),
isEditing,
isEditing,
- action(() => wasSelected && (InkStrokeProperties.Instance._currentPoint = -1))
+ action(() => {
+ wasSelected && (InkStrokeProperties.Instance._currentPoint = -1);
+ })
);
};
@@ -217,7 +225,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
* factor for converting between ink and screen space.
*/
inkScaledData = () => {
- const inkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
+ const inkData = Cast(this.dataDoc[this.fieldKey], InkField, Cast(this.layoutDoc[this.fieldKey], InkField, null))?.inkData ?? [];
const inkStrokeWidth = NumCast(this.layoutDoc.stroke_width, 1);
const inkTop = Math.min(...inkData.map(p => p.Y)) - inkStrokeWidth / 2;
const inkBottom = Math.max(...inkData.map(p => p.Y)) + inkStrokeWidth / 2;
@@ -325,32 +333,34 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
false
)}
<InkControlPtHandles inkView={this} inkDoc={inkDoc} inkCtrlPoints={inkData} screenCtrlPoints={this.screenCtrlPts} nearestScreenPt={this.nearestScreenPt} screenSpaceLineWidth={screenSpaceCenterlineStrokeWidth} />
- <InkTangentHandles inkView={this} inkDoc={inkDoc} screenCtrlPoints={this.screenCtrlPts} screenSpaceLineWidth={screenSpaceCenterlineStrokeWidth} ScreenToLocalTransform={this.ScreenToLocalBoxXf} />
+ <InkTangentHandles inkView={this} inkDoc={inkDoc} screenCtrlPoints={this.screenCtrlPts} screenSpaceLineWidth={screenSpaceCenterlineStrokeWidth} />
</div>
);
};
- _subContentView: ViewBoxInterface | undefined;
- setSubContentView = (doc: ViewBoxInterface) => (this._subContentView = doc);
- @computed get fillColor() {
+ _subContentView: ViewBoxInterface<FormattedTextBoxProps> | undefined;
+ setSubContentView = (box: ViewBoxInterface<FormattedTextBoxProps>) => {
+ this._subContentView = box;
+ };
+ @computed get fillColor(): string {
const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask);
return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) ?? 'transparent';
}
@computed get strokeColor() {
const { inkData } = this.inkScaledData();
- const fillColor = this.fillColor;
+ const { fillColor } = this;
return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) ?? StrCast(this.layoutDoc.color);
}
render() {
TraceMobx();
- const { inkData, inkStrokeWidth, inkLeft, inkTop, inkScaleX, inkScaleY, inkWidth, inkHeight } = this.inkScaledData();
+ const { inkData, inkStrokeWidth, inkLeft, inkTop, inkScaleX, inkScaleY } = this.inkScaledData();
const startMarker = StrCast(this.layoutDoc.stroke_startMarker);
const endMarker = StrCast(this.layoutDoc.stroke_endMarker);
const markerScale = NumCast(this.layoutDoc.stroke_markerScale, 1);
const closed = InkingStroke.IsClosed(inkData);
const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask);
- const fillColor = this.fillColor;
+ const { fillColor } = this;
// bcz: Hack!! Not really sure why, but having fractional values for width/height of mask ink strokes causes the dragging clone (see DragManager) to be offset from where it should be.
if (isInkMask && (this.layoutDoc._width !== Math.round(NumCast(this.layoutDoc._width)) || this.layoutDoc._height !== Math.round(NumCast(this.layoutDoc._height)))) {
@@ -387,12 +397,11 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
1.0,
false,
undefined,
- undefined,
- color === 'transparent' ? highlightColor : undefined
+ undefined
);
const higlightMargin = Math.min(12, Math.max(2, 0.3 * inkStrokeWidth));
// Invisible polygonal line that enables the ink to be selected by the user.
- const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, mask: boolean = false) =>
+ const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, mask: boolean = false): any =>
InteractionUtils.CreatePolyline(
inkData,
inkLeft,
@@ -415,22 +424,29 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
0.0,
false,
downHdlr,
- mask,
- highlightColor
+ mask
);
// bootsrap 3 style sheet sets line height to be 20px for default 14 point font size.
// this attempts to figure out the lineHeight ratio by inquiring the body's lineHeight and dividing by the fontsize which should yield 1.428571429
// see: https://bibwild.wordpress.com/2019/06/10/bootstrap-3-to-4-changes-in-how-font-size-line-height-and-spacing-is-done-or-what-happened-to-line-height-computed/
- const lineHeightGuess = +getComputedStyle(document.body).lineHeight.replace('px', '') / +getComputedStyle(document.body).fontSize.replace('px', '');
+ // const lineHeightGuess = +getComputedStyle(document.body).lineHeight.replace('px', '') / +getComputedStyle(document.body).fontSize.replace('px', '');
const interactions = {
- onPointerLeave: action(() => (this._nearestScrPt = undefined)),
+ onPointerLeave: action(() => {
+ this._nearestScrPt = undefined;
+ }),
onPointerMove: this._props.isSelected() ? this.onPointerMove : undefined,
onClick: (e: React.MouseEvent) => this._handledClick && e.stopPropagation(),
onContextMenu: () => {
const cm = ContextMenu.Instance;
!Doc.noviceMode && cm?.addItem({ description: 'Recognize Writing', event: this.analyzeStrokes, icon: 'paint-brush' });
cm?.addItem({ description: 'Toggle Mask', event: () => InkingStroke.toggleMask(this.dataDoc), icon: 'paint-brush' });
- cm?.addItem({ description: 'Edit Points', event: action(() => (InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton)), icon: 'paint-brush' });
+ cm?.addItem({
+ description: 'Edit Points',
+ event: action(() => {
+ InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton;
+ }),
+ icon: 'paint-brush',
+ });
},
};
return (
@@ -438,15 +454,16 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
<svg
className="inkStroke"
style={{
- transform: isInkMask ? `rotate(-${NumCast(this._props.CollectionFreeFormDocumentView?.()._props.rotation ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
+ transform: isInkMask ? `rotate(-${NumCast(this._props.LocalRotation?.() ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
// mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? 'multiply' : 'unset',
cursor: this._props.isSelected() ? 'default' : undefined,
}}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...interactions}>
{clickableLine(this.onPointerDown, isInkMask)}
{isInkMask ? null : inkLine}
</svg>
- {!closed || (!RTFCast(this.dataDoc.text)?.Text && (!this._props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : (
+ {!closed || this.dataDoc[this.fieldKey + '_showLabel'] === false || (!RTFCast(this.dataDoc.text)?.Text && !this.dataDoc[this.fieldKey + '_showLabel'] && (!this._props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : (
<div
className="inkStroke-text"
style={{
@@ -455,18 +472,19 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
width: NumCast(this.layoutDoc._width),
transform: `scale(${this._props.NativeDimScaling?.() || 1})`,
transformOrigin: 'top left',
- //top: (this._props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this._props.NativeDimScaling?.() || 1)) / 2,
+ // top: (this._props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this._props.NativeDimScaling?.() || 1)) / 2,
}}>
<FormattedTextBox
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setHeight={undefined}
setContentViewBox={this.setSubContentView} // this makes the inkingStroke the "dominant" component - ie, it will show the inking UI when selected (not text)
yPadding={10}
xPadding={10}
fieldKey="text"
- dontRegisterView={true}
- noSidebar={true}
- dontScale={true}
+ // dontRegisterView={true}
+ noSidebar
+ dontScale
isContentActive={this._props.isContentActive}
/>
</div>
@@ -475,61 +493,17 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
);
}
}
-
-export function SetActiveInkWidth(width: string): void {
- !isNaN(parseInt(width)) && ActiveInkPen() && (ActiveInkPen().activeInkWidth = width);
-}
-export function SetActiveBezierApprox(bezier: string): void {
- ActiveInkPen() && (ActiveInkPen().activeInkBezier = isNaN(parseInt(bezier)) ? '' : bezier);
-}
-export function SetActiveInkColor(value: string) {
- ActiveInkPen() && (ActiveInkPen().activeInkColor = value);
-}
-export function SetActiveIsInkMask(value: boolean) {
- ActiveInkPen() && (ActiveInkPen().activeIsInkMask = value);
-}
-export function SetActiveFillColor(value: string) {
- ActiveInkPen() && (ActiveInkPen().activeFillColor = value);
-}
-export function SetActiveArrowStart(value: string) {
- ActiveInkPen() && (ActiveInkPen().activeArrowStart = value);
-}
-export function SetActiveArrowEnd(value: string) {
- ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value);
-}
-export function SetActiveArrowScale(value: number) {
- ActiveInkPen() && (ActiveInkPen().activeArrowScale = value);
-}
-export function SetActiveDash(dash: string): void {
- !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash);
-}
-export function ActiveInkPen(): Doc {
- return Doc.UserDoc();
-}
-export function ActiveInkColor(): string {
- return StrCast(ActiveInkPen()?.activeInkColor, 'black');
-}
-export function ActiveFillColor(): string {
- return StrCast(ActiveInkPen()?.activeFillColor, '');
-}
-export function ActiveIsInkMask(): boolean {
- return BoolCast(ActiveInkPen()?.activeIsInkMask, false);
-}
-export function ActiveArrowStart(): string {
- return StrCast(ActiveInkPen()?.activeArrowStart, '');
-}
-export function ActiveArrowEnd(): string {
- return StrCast(ActiveInkPen()?.activeArrowEnd, '');
-}
-export function ActiveArrowScale(): number {
- return NumCast(ActiveInkPen()?.activeArrowScale, 1);
-}
-export function ActiveDash(): string {
- return StrCast(ActiveInkPen()?.activeDash, '0');
-}
-export function ActiveInkWidth(): number {
- return Number(ActiveInkPen()?.activeInkWidth);
-}
-export function ActiveInkBezierApprox(): string {
- return StrCast(ActiveInkPen()?.activeInkBezier);
-}
+Docs.Prototypes.TemplateMap.set(DocumentType.INK, {
+ // NOTE: this is unused!! ink fields are filled in directly within the InkDocument() method
+ layout: { view: InkingStroke, dataField: 'stroke' },
+ options: {
+ acl: '',
+ systemIcon: 'BsFillPencilFill', //
+ _layout_nativeDimEditable: true,
+ _layout_reflowVertical: true,
+ _layout_reflowHorizontal: true,
+ layout_hideDecorationTitle: true, // don't show title when selected
+ _layout_fitWidth: false,
+ layout_isSvg: true,
+ },
+});
diff --git a/src/client/views/KeyphraseQueryView.tsx b/src/client/views/KeyphraseQueryView.tsx
index e996fc946..81f004010 100644
--- a/src/client/views/KeyphraseQueryView.tsx
+++ b/src/client/views/KeyphraseQueryView.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable jsx-a11y/label-has-associated-control */
import { observer } from 'mobx-react';
import * as React from 'react';
import './KeyphraseQueryView.scss';
@@ -9,28 +10,21 @@ export interface KP_Props {
@observer
export class KeyphraseQueryView extends React.Component<KP_Props> {
- constructor(props: KP_Props) {
- super(props);
- }
-
render() {
- const kps = this.props.keyphrases.toString();
const keyterms = this.props.keyphrases.split(',');
return (
<div>
<h5>Select queries to send:</h5>
<form>
- {keyterms.map((kp: string) => {
- //return (<p>{"-" + kp}</p>);
- return (
- <p>
- <label>
- <input name="query" type="radio" />
- <span>{kp}</span>
- </label>
- </p>
- );
- })}
+ {keyterms.map((kp: string) => (
+ // return (<p>{"-" + kp}</p>);
+ <p>
+ <label>
+ <input name="query" type="radio" />
+ <span>{kp}</span>
+ </label>
+ </p>
+ ))}
</form>
</div>
);
diff --git a/src/client/views/LightboxView.scss b/src/client/views/LightboxView.scss
index 9a9b8a437..6da5c0338 100644
--- a/src/client/views/LightboxView.scss
+++ b/src/client/views/LightboxView.scss
@@ -67,6 +67,7 @@
z-index: 1000;
.lightboxView-contents {
position: absolute;
+ color: black;
}
.lightboxView-navBtn-frame {
position: absolute;
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index c7ff7ce47..7198c7f05 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -1,41 +1,48 @@
+/* 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';
import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, FieldResult, Opt } from '../../fields/Doc';
+import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../ClientUtils';
+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 } from '../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, Utils } from '../../Utils';
-import { DocUtils } from '../documents/Documents';
-import { DocumentManager } from '../util/DocumentManager';
-import { LinkManager } from '../util/LinkManager';
-import { SelectionManager } from '../util/SelectionManager';
-import { SettingsManager } from '../util/SettingsManager';
+import { Cast, NumCast, toList } from '../../fields/Types';
+import { SnappingManager } from '../util/SnappingManager';
import { Transform } from '../util/Transform';
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
-import { TabDocView } from './collections/TabDocView';
import { GestureOverlay } from './GestureOverlay';
import './LightboxView.scss';
-import { DocumentView, OpenWhere, OpenWhereMod } from './nodes/DocumentView';
-import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
import { ObservableReactComponent } from './ObservableReactComponent';
-import { SnappingManager } from '../util/SnappingManager';
+import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere';
+import { ScriptingGlobals } from '../util/ScriptingGlobals';
+import { OverlayView } from './OverlayView';
interface LightboxViewProps {
PanelWidth: number;
PanelHeight: number;
maxBorder: number[];
+ addSplit: (document: Doc, pullSide: OpenWhereMod, stack?: any, panelName?: string | undefined, keyValue?: boolean | undefined) => boolean;
}
const savedKeys = ['freeform_panX', 'freeform_panY', 'freeform_scale', 'layout_scrollTop', 'layout_fieldKey'];
type LightboxSavedState = { [key: string]: FieldResult; }; // prettier-ignore
@observer
export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
- public static Contains(view?:DocumentView) { return view && LightboxView.Instance?._docView&& (view.containerViewPath?.() ?? []).concat(view).includes(LightboxView.Instance?._docView); } // prettier-ignore
- public static get LightboxDoc() { return LightboxView.Instance?._doc; } // prettier-ignore
+ /**
+ * Determines whether a DocumentView is descendant of the lightbox view
+ * @param view
+ * @returns true if a DocumentView is descendant of the lightbox view
+ */
+ public static Contains(view?:DocumentView) { return view && LightboxView.Instance?._docView && (view.containerViewPath?.() ?? []).concat(view).includes(LightboxView.Instance?._docView); } // prettier-ignore
+ public static LightboxDoc = () => LightboxView.Instance?._doc;
+ // eslint-disable-next-line no-use-before-define
static Instance: LightboxView;
private _path: {
doc: Opt<Doc>; //
@@ -60,19 +67,36 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
super(props);
makeObservable(this);
LightboxView.Instance = this;
+ DocumentView._setLightboxDoc = this.SetLightboxDoc;
+ DocumentView._lightboxContains = LightboxView.Contains;
+ DocumentView._lightboxDoc = LightboxView.LightboxDoc;
}
-
+ /**
+ * Sets the root Doc to render in the lightbox view.
+ * @param doc
+ * @param target a Doc within 'doc' to focus on (useful for freeform collections)
+ * @param future a list of Docs to step through with the arrow buttons of the lightbox
+ * @param layoutTemplate a template to apply to 'doc' to render it.
+ * @returns success flag which is currently always true
+ */
@action
- public SetLightboxDoc(doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) {
+ public SetLightboxDoc = (doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) => {
const lightDoc = this._doc;
- lightDoc && lightDoc !== doc && savedKeys.forEach(key => (lightDoc[key] = this._savedState[key]));
+ lightDoc &&
+ lightDoc !== doc &&
+ savedKeys.forEach(key => {
+ lightDoc[key] = this._savedState[key];
+ });
this._savedState = {};
if (doc) {
- lightDoc !== doc && savedKeys.map(key => (this._savedState[key] = Doc.Get(doc, key, true)));
- const l = DocUtils.MakeLinkToActiveAudio(() => doc).lastElement();
+ lightDoc !== doc &&
+ savedKeys.forEach(key => {
+ this._savedState[key] = Doc.Get(doc, key, true);
+ });
+ const l = CreateLinkToActiveAudio(() => doc).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
- CollectionStackedTimeline.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
+ DocumentView.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
this._history.push({ doc, target });
} else {
this._future = [];
@@ -80,14 +104,14 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
Doc.ActiveTool = InkTool.None;
SnappingManager.SetExploreMode(false);
}
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
if (future) {
this._future.push(
...(this._doc ? [this._doc] : []),
...future
.slice()
.sort((a, b) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow))
- .sort((a, b) => LinkManager.Links(a).length - LinkManager.Links(b).length)
+ .sort((a, b) => Doc.Links(a).length - Doc.Links(b).length)
);
}
this._doc = doc;
@@ -98,10 +122,11 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
this._docTarget = target ?? doc;
return true;
- }
+ };
- public AddDocTab = (doc: Doc, location: OpenWhere, layoutTemplate?: Doc | string) =>
- this.SetLightboxDoc(
+ public AddDocTab = (docs: Doc | Doc[], location: OpenWhere, layoutTemplate?: Doc | string) => {
+ const doc = toList(docs).lastElement();
+ return this.SetLightboxDoc(
doc,
undefined,
[...DocListCast(doc[Doc.LayoutFieldKey(doc)]), ...DocListCast(doc[Doc.LayoutFieldKey(doc) + '_annotations']).filter(anno => anno.annotationOn !== doc), ...this._future].sort(
@@ -109,19 +134,22 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
),
layoutTemplate
);
+ };
@action
next = () => {
const lightDoc = this._doc;
if (!lightDoc) return;
const target = (this._docTarget = this._future.pop());
- const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target);
+ const targetDocView = target && DocumentView.getLightboxDocumentView(target);
if (targetDocView && target) {
- const l = DocUtils.MakeLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
+ const l = CreateLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
- DocumentManager.Instance.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
+ DocumentView.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
if (this._history.lastElement().target !== target) this._history.push({ doc: lightDoc, target });
} else if (!target && this._path.length) {
- savedKeys.forEach(key => (lightDoc[key] = this._savedState[key]));
+ savedKeys.forEach(key => {
+ lightDoc[key] = this._savedState[key];
+ });
this._path.pop();
} else {
this.SetLightboxDoc(target);
@@ -135,10 +163,10 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
return;
}
const { doc, target } = this._history.lastElement();
- const docView = DocumentManager.Instance.getLightboxDocumentView(target || doc);
+ const docView = DocumentView.getLightboxDocumentView(target || doc);
if (docView) {
this._docTarget = target;
- target && DocumentManager.Instance.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
+ target && DocumentView.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
} else {
this.SetLightboxDoc(doc, target);
}
@@ -156,8 +184,8 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
if (this._docTarget) {
const fieldKey = Doc.LayoutFieldKey(this._docTarget);
const contents = [...DocListCast(this._docTarget[fieldKey]), ...DocListCast(this._docTarget[fieldKey + '_annotations'])];
- const links = LinkManager.Links(this._docTarget)
- .map(link => LinkManager.getOppositeAnchor(link, this._docTarget!)!)
+ const links = Doc.Links(this._docTarget)
+ .map(link => Doc.getOppositeAnchor(link, this._docTarget!)!)
.filter(doc => doc);
this.SetLightboxDoc(this._docTarget, undefined, contents.length ? contents : links);
}
@@ -167,12 +195,16 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
const lightDoc = this._docTarget ?? this._doc;
if (lightDoc) {
Doc.RemoveDocFromList(Doc.MyRecentlyClosed, 'data', lightDoc);
- CollectionDockingView.AddSplit(lightDoc, OpenWhereMod.none);
+ this._props.addSplit(lightDoc, OpenWhereMod.none);
this.SetLightboxDoc(undefined);
}
};
- toggleFitWidth = () => this._doc && (this._doc._layout_fitWidth = !this._doc._layout_fitWidth);
- togglePen = () => (Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen);
+ toggleFitWidth = () => {
+ this._doc && (this._doc._layout_fitWidth = !this._doc._layout_fitWidth);
+ };
+ togglePen = () => {
+ Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen;
+ };
toggleExplore = () => SnappingManager.SetExploreMode(!SnappingManager.ExploreMode);
lightboxDoc = () => this._doc;
@@ -182,39 +214,37 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
lightboxDocTemplate = () => this._layoutTemplate;
future = () => this._future;
- renderNavBtn = (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: IconProp, display: any, click: () => void, color?: string) => {
- return (
+ renderNavBtn = (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: IconProp, display: any, click: () => void, color?: string) => (
+ <div
+ className="lightboxView-navBtn-frame"
+ style={{
+ display: display ? '' : 'none',
+ left,
+ width: bottom !== undefined ? undefined : Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]),
+ bottom,
+ }}>
<div
- className="lightboxView-navBtn-frame"
- style={{
- display: display ? '' : 'none',
- left,
- width: bottom !== undefined ? undefined : Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]),
- bottom,
+ className="lightboxView-navBtn"
+ title={color}
+ style={{ top, color: SnappingManager.userColor, background: undefined }}
+ onClick={e => {
+ e.stopPropagation();
+ click();
}}>
- <div
- className="lightboxView-navBtn"
- title={color}
- style={{ top, color: SettingsManager.userColor, background: undefined }}
- onClick={e => {
- e.stopPropagation();
- click();
- }}>
- <div style={{ height: 10 }}>{color}</div>
- <FontAwesomeIcon icon={icon} size="3x" />
- </div>
+ <div style={{ height: 10 }}>{color}</div>
+ <FontAwesomeIcon icon={icon} size="3x" />
</div>
- );
- };
+ </div>
+ );
render() {
- let downx = 0,
- downy = 0;
+ let downx = 0;
+ let downy = 0;
const toggleBtn = (classname: string, tooltip: string, toggleBackground: any, icon: IconProp, icon2: IconProp | string, onClick: () => void) => (
<div className={classname}>
<Toggle
tooltip={tooltip}
- color={SettingsManager.userColor}
- background={toggleBackground ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor}
+ color={SnappingManager.userColor}
+ background={toggleBackground ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
toggleType={ToggleType.BUTTON}
type={Type.TERT}
icon={<FontAwesomeIcon icon={toggleBackground ? icon : (icon2 as IconProp) || icon} size="sm" />}
@@ -225,15 +255,17 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
/>
</div>
);
- return !this._doc ? null : (
+ return !this._doc ? (
+ <OverlayView />
+ ) : (
<div
className="lightboxView-frame"
- style={{ background: SettingsManager.userBackgroundColor }}
+ style={{ background: SnappingManager.userBackgroundColor }}
onPointerDown={e => {
downx = e.clientX;
downy = e.clientY;
}}
- onClick={e => Utils.isClick(e.clientX, e.clientY, downx, downy, Date.now()) && this.SetLightboxDoc(undefined)}>
+ onClick={e => ClientUtils.isClick(e.clientX, e.clientY, downx, downy, Date.now()) && this.SetLightboxDoc(undefined)}>
<div
className="lightboxView-contents"
style={{
@@ -242,12 +274,14 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
width: this.lightboxWidth(),
height: this.lightboxHeight(),
clipPath: `path('${Doc.UserDoc().renderStyle === 'comic' ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')`,
- background: SettingsManager.userBackgroundColor,
- color: SettingsManager.userColor,
+ background: SnappingManager.userBackgroundColor,
}}>
- <GestureOverlay isActive={true}>
+ <GestureOverlay isActive>
<DocumentView
- ref={action((r: DocumentView | null) => (this._docView = r !== null ? r : undefined))}
+ key={this._doc.title + this._doc[Id]} // this makes a new DocumentView when the document changes which makes link following work, otherwise no DocView is registered for the new Doc
+ ref={action((r: DocumentView | null) => {
+ this._docView = r !== null ? r : undefined;
+ })}
Document={this._doc}
PanelWidth={this.lightboxWidth}
PanelHeight={this.lightboxHeight}
@@ -257,6 +291,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
styleProvider={DefaultStyleProvider}
ScreenToLocalTransform={this.lightboxScreenToLocal}
renderDepth={0}
+ suppressSetHeight={!!this._doc._layout_fitWidth}
containerViewPath={returnEmptyDoclist}
childFilters={returnEmptyFilter}
childFiltersByRanges={returnEmptyFilter}
@@ -265,8 +300,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
removeDocument={undefined}
whenChildContentsActiveChanged={emptyFunction}
addDocTab={this.AddDocTab}
- pinToPres={TabDocView.PinDoc}
- onBrowseClickScript={DocumentView.exploreMode}
+ pinToPres={DocumentView.PinDoc}
focus={emptyFunction}
/>
</GestureOverlay>
@@ -293,6 +327,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
}
interface LightboxTourBtnProps {
navBtn: (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: IconProp, display: any, click: () => void, color?: string) => JSX.Element;
+ // eslint-disable-next-line react/no-unused-prop-types
future: () => Opt<Doc[]>;
stepInto: () => void;
lightboxDoc: () => Opt<Doc>;
@@ -303,3 +338,8 @@ export class LightboxTourBtn extends React.Component<LightboxTourBtnProps> {
return this.props.navBtn('50%', 0, 0, 'chevron-down', this.props.lightboxDoc(), this.props.stepInto, '');
}
}
+
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function deiconifyViewToLightbox(documentView: DocumentView) {
+ LightboxView.Instance.AddDocTab(documentView.Document, OpenWhere.lightboxAlways, 'layout'); // , 0);
+});
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 17c21326d..43b9a6b39 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable no-new */
// if ((module as any).hot) {
// (module as any).hot.accept();
// }
@@ -5,16 +6,61 @@
import * as dotenv from 'dotenv'; // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
-import { AssignAllExtensions } from '../../extensions/General/Extensions';
+import { AssignAllExtensions } from '../../extensions/Extensions';
import { FieldLoader } from '../../fields/FieldLoader';
+import { BranchingTrailManager } from '../util/BranchingTrailManager';
import { CurrentUserUtils } from '../util/CurrentUserUtils';
+import { LinkFollower } from '../util/LinkFollower';
import { PingManager } from '../util/PingManager';
import { ReplayMovements } from '../util/ReplayMovements';
import { TrackMovements } from '../util/TrackMovements';
+import { KeyManager } from './GlobalKeyHandler';
+import { InkingStroke } from './InkingStroke';
+import { MainView } from './MainView';
+import { CollectionCalendarView } from './collections/CollectionCalendarView';
+import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionView } from './collections/CollectionView';
+import { TabDocView } from './collections/TabDocView';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
+import { CollectionFreeFormInfoUI } from './collections/collectionFreeForm/CollectionFreeFormInfoUI';
+import { CollectionSchemaView } from './collections/collectionSchema/CollectionSchemaView';
+import { SchemaRowBox } from './collections/collectionSchema/SchemaRowBox';
import './global/globalScripts';
-import { MainView } from './MainView';
-import { BranchingTrailManager } from '../util/BranchingTrailManager';
+import { AudioBox } from './nodes/AudioBox';
+import { ChatBox } from './nodes/ChatBox/ChatBox';
+import { ComparisonBox } from './nodes/ComparisonBox';
+import { DataVizBox } from './nodes/DataVizBox/DataVizBox';
+import { DiagramBox } from './nodes/DiagramBox';
+import { DocumentContentsView, HTMLtag } from './nodes/DocumentContentsView';
+import { EquationBox } from './nodes/EquationBox';
+import { FieldView } from './nodes/FieldView';
+import { FontIconBox } from './nodes/FontIconBox/FontIconBox';
+import { FunctionPlotBox } from './nodes/FunctionPlotBox';
+import { ImageBox } from './nodes/ImageBox';
+import { KeyValueBox } from './nodes/KeyValueBox';
+import { LabelBox } from './nodes/LabelBox';
+import { LinkBox } from './nodes/LinkBox';
+import { LoadingBox } from './nodes/LoadingBox';
+import { MapBox } from './nodes/MapBox/MapBox';
+import { MapPushpinBox } from './nodes/MapBox/MapPushpinBox';
+import { PDFBox } from './nodes/PDFBox';
+import { PhysicsSimulationBox } from './nodes/PhysicsBox/PhysicsSimulationBox';
+import { RecordingBox } from './nodes/RecordingBox';
+import { ScreenshotBox } from './nodes/ScreenshotBox';
+import { ScriptingBox } from './nodes/ScriptingBox';
+import { VideoBox } from './nodes/VideoBox';
+import { WebBox } from './nodes/WebBox';
+import { DashDocCommentView } from './nodes/formattedText/DashDocCommentView';
+import { DashDocView } from './nodes/formattedText/DashDocView';
+import { DashFieldView } from './nodes/formattedText/DashFieldView';
+import { EquationView } from './nodes/formattedText/EquationView';
+import { FootnoteView } from './nodes/formattedText/FootnoteView';
+import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { SummaryView } from './nodes/formattedText/SummaryView';
+import { ImportElementBox } from './nodes/importBox/ImportElementBox';
+import { PresBox, PresElementBox } from './nodes/trails';
+import { SearchBox } from './search/SearchBox';
+
dotenv.config();
AssignAllExtensions();
@@ -29,22 +75,14 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
root.render(<FieldLoader />);
window.location.search.includes('safe') && CollectionView.SetSafeMode(true);
const info = await CurrentUserUtils.loadCurrentUser();
- // if (info.email === 'guest') DocServer.Control.makeReadOnly();
if (!info.userDocumentId) {
alert('Fatal Error: user not found in database');
return;
}
await CurrentUserUtils.loadUserDocument(info);
setTimeout(() => {
- document.getElementById('root')!.addEventListener(
- 'wheel',
- event => {
- if (event.ctrlKey) {
- event.preventDefault();
- }
- },
- true
- );
+ // prevent zooming browser
+ document.getElementById('root')!.addEventListener('wheel', event => event.ctrlKey && event.preventDefault(), true);
const startload = (document as any).startLoad;
const loading = Date.now() - (startload ? Number(startload) : Date.now() - 3000);
console.log('Loading Time = ' + loading);
@@ -56,6 +94,60 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
new ReplayMovements();
new BranchingTrailManager({});
new PingManager();
+ new KeyManager();
+
+ // 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
+ }));
+ CollectionFreeFormInfoUI.Init();
+ LinkFollower.Init();
+ KeyValueBox.Init();
+ PresBox.Init(TabDocView.AllTabDocs);
+ DocumentContentsView.Init(KeyValueBox.LayoutString(), {
+ FormattedTextBox,
+ ImageBox,
+ FontIconBox,
+ LabelBox,
+ EquationBox,
+ FieldView,
+ CollectionFreeFormView,
+ CollectionDockingView,
+ CollectionSchemaView,
+ CollectionCalendarView,
+ CollectionView,
+ WebBox,
+ KeyValueBox,
+ PDFBox,
+ VideoBox,
+ AudioBox,
+ RecordingBox,
+ PresBox,
+ PresElementBox,
+ SearchBox,
+ FunctionPlotBox,
+ InkingStroke,
+ LinkBox,
+ ScriptingBox,
+ MapBox,
+ ScreenshotBox,
+ DataVizBox,
+ ChatBox,
+ DiagramBox,
+ HTMLtag,
+ ComparisonBox,
+ LoadingBox,
+ PhysicsSimulationBox,
+ SchemaRowBox,
+ ImportElementBox,
+ MapPushpinBox,
+ });
root.render(<MainView />);
}, 0);
})();
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 28a0f7750..e204759ab 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -7,12 +7,6 @@ body {
overscroll-behavior-x: none;
}
-h1,
-.h1 {
- // reverts change to h1 made by normalize.css
- font-size: 36px;
-}
-
.dash-tooltip {
font-size: 11px;
padding: 2px;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 56d28ee5d..33c343176 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,3 +1,4 @@
+/* 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';
@@ -5,13 +6,15 @@ import * as fa from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, configure, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
-import 'normalize.css';
import * as React from 'react';
+// eslint-disable-next-line import/no-relative-packages
import '../../../node_modules/browndash-components/dist/styles/global.min.css';
-import { Utils, emptyFunction, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../Utils';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { ClientUtils, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils';
+import { emptyFunction } from '../../Utils';
+import { Doc, DocListCast, GetDocFromUrl, Opt } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
-import { DocCast, StrCast } from '../../fields/Types';
+import { Id } from '../../fields/FieldSymbols';
+import { DocCast, StrCast, toList } from '../../fields/Types';
import { DocServer } from '../DocServer';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
@@ -19,13 +22,14 @@ import { Docs } from '../documents/Documents';
import { CalendarManager } from '../util/CalendarManager';
import { CaptureManager } from '../util/CaptureManager';
import { DocumentManager } from '../util/DocumentManager';
-import { DragManager, dropActionType } from '../util/DragManager';
+import { DragManager } from '../util/DragManager';
+import { dropActionType } from '../util/DropActionTypes';
import { GroupManager } from '../util/GroupManager';
import { HistoryUtil } from '../util/History';
import { Hypothesis } from '../util/HypothesisUtils';
+import { UPDATE_SERVER_CACHE } from '../util/LinkManager';
import { RTFMarkup } from '../util/RTFMarkup';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
-import { SelectionManager } from '../util/SelectionManager';
import { ServerStats } from '../util/ServerStats';
import { SettingsManager } from '../util/SettingsManager';
import { SharingManager } from '../util/SharingManager';
@@ -38,45 +42,46 @@ import { DashboardView } from './DashboardView';
import { DictationOverlay } from './DictationOverlay';
import { DocumentDecorations } from './DocumentDecorations';
import { GestureOverlay } from './GestureOverlay';
-import { KeyManager } from './GlobalKeyHandler';
import { LightboxView } from './LightboxView';
import './MainView.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
-import { OverlayView } from './OverlayView';
import { PreviewCursor } from './PreviewCursor';
import { PropertiesView } from './PropertiesView';
-import { DashboardStyleProvider, DefaultStyleProvider } from './StyleProvider';
+import { DashboardStyleProvider, DefaultStyleProvider, returnEmptyDocViewList } from './StyleProvider';
import { TimelineMenu } from './animationtimeline/TimelineMenu';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionMenu } from './collections/CollectionMenu';
import { TabDocView } from './collections/TabDocView';
import './collections/TreeView.scss';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
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, OpenWhere, OpenWhereMod, returnEmptyDocViewList } from './nodes/DocumentView';
-import { ImageBox } from './nodes/ImageBox';
+import { DocumentView, DocumentViewInternal } from './nodes/DocumentView';
+import { ImageEditorData as ImageEditor } from './nodes/ImageBox';
import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
import { LinkDocPreview, LinkInfo } from './nodes/LinkDocPreview';
import { DirectionsAnchorMenu } from './nodes/MapBox/DirectionsAnchorMenu';
import { MapAnchorMenu } from './nodes/MapBox/MapAnchorMenu';
+import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere';
import { TaskCompletionBox } from './nodes/TaskCompletedBox';
import { DashFieldViewMenu } from './nodes/formattedText/DashFieldView';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { RichTextMenu } from './nodes/formattedText/RichTextMenu';
import GenerativeFill from './nodes/generativeFill/GenerativeFill';
import { PresBox } from './nodes/trails';
import { AnchorMenu } from './pdf/AnchorMenu';
import { GPTPopup } from './pdf/GPTPopup/GPTPopup';
import { TopBar } from './topbar/TopBar';
-const { default: { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
+
const _global = (window /* browser */ || global) /* node */ as any;
+const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
@observer
export class MainView extends ObservableReactComponent<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: MainView;
public static Live: boolean = false;
private _docBtnRef = React.createRef<HTMLDivElement>();
@@ -96,7 +101,7 @@ export class MainView extends ObservableReactComponent<{}> {
return this._hideUI ? 0 : 27;
} // 27 comes form lm.config.defaultConfig.dimensions.headerHeight in goldenlayout.js
@computed private get topOfDashUI() {
- return this._hideUI || LightboxView.LightboxDoc ? 0 : Number(TOPBAR_HEIGHT.replace('px', ''));
+ return this._hideUI || DocumentView.LightboxDoc() ? 0 : Number(TOPBAR_HEIGHT.replace('px', ''));
}
@computed private get topOfHeaderBarDoc() {
return this.topOfDashUI;
@@ -118,8 +123,12 @@ export class MainView extends ObservableReactComponent<{}> {
}
@observable mainDoc: Opt<Doc> = undefined;
@computed private get mainContainer() {
- if (window.location.pathname.startsWith('/doc/') && Doc.CurrentUserEmail === 'guest') {
- DocServer.GetRefField(window.location.pathname.substring('/doc/'.length)).then(main => runInAction(() => (this.mainDoc = main as Doc)));
+ if (window.location.pathname.startsWith('/doc/') && ClientUtils.CurrentUserEmail() === 'guest') {
+ DocServer.GetRefField(window.location.pathname.substring('/doc/'.length)).then(main =>
+ runInAction(() => {
+ this.mainDoc = main as Doc;
+ })
+ );
return this.mainDoc;
}
return this.userDoc ? Doc.ActiveDashboard : Doc.GuestDashboard;
@@ -149,24 +158,33 @@ export class MainView extends ObservableReactComponent<{}> {
leftMenuHeight = () => this._dashUIHeight;
leftMenuFlyoutWidth = () => this._leftMenuFlyoutWidth;
leftMenuFlyoutHeight = () => this._dashUIHeight;
- propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, SettingsManager.Instance?.propertiesWidth || 0));
+ propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, SnappingManager.PropertiesWidth || 0));
propertiesHeight = () => this._dashUIHeight;
mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth() - this.leftMenuFlyoutWidth();
mainDocViewHeight = () => this._dashUIHeight - this.headerBarDocHeight();
componentDidMount() {
+ // Utils.TraceConsoleLog();
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
- () => SelectionManager.Views.slice(),
+ () => DocumentView.Selected().slice(),
views => views.length > 1 && (document.activeElement as any)?.blur !== undefined && (document.activeElement as any)!.blur()
);
+ reaction(
+ () => Doc.MyDockedBtns.linearView_IsOpen,
+ open => SnappingManager.SetPrintToConsole(!!open)
+ );
const scriptTag = document.createElement('script');
scriptTag.setAttribute('type', 'text/javascript');
scriptTag.setAttribute('src', 'https://www.bing.com/api/maps/mapcontrol?callback=makeMap');
scriptTag.async = true;
scriptTag.defer = true;
document.body.appendChild(scriptTag);
- document.getElementById('root')?.addEventListener('scroll', e => (ele => (ele.scrollLeft = ele.scrollTop = 0))(document.getElementById('root')!));
+ document.getElementById('root')?.addEventListener('scroll', () =>
+ (ele => {
+ ele.scrollLeft = ele.scrollTop = 0;
+ })(document.getElementById('root')!)
+ );
const ele = document.getElementById('loader');
const prog = document.getElementById('dash-progress');
if (ele && prog) {
@@ -175,7 +193,9 @@ export class MainView extends ObservableReactComponent<{}> {
prog.style.transition = '1s';
prog.style.width = '100%';
}, 0);
- setTimeout(() => (ele.outerHTML = ''), 1000);
+ setTimeout(() => {
+ ele.outerHTML = '';
+ }, 1000);
}
this._sidebarContent.proto = undefined;
if (!MainView.Live) {
@@ -203,7 +223,7 @@ export class MainView extends ObservableReactComponent<{}> {
'text_scrollHeight',
'text_height',
'hidden',
- //'type_collection',
+ // 'type_collection',
'chromeHidden',
'currentFrame',
]); // can play with these fields on someone else's
@@ -213,32 +233,23 @@ export class MainView extends ObservableReactComponent<{}> {
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);
- window.removeEventListener('keydown', KeyManager.Instance.handleModifiers, true);
- window.addEventListener('keydown', KeyManager.Instance.handleModifiers, true);
- window.removeEventListener('keyup', KeyManager.Instance.unhandleModifiers);
- window.addEventListener('keyup', KeyManager.Instance.unhandleModifiers);
- window.removeEventListener('keydown', KeyManager.Instance.handle);
- 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);
document.addEventListener('dash', (e: any) => {
// event used by chrome plugin to tell Dash which document to focus on
- const id = FormattedTextBox.GetDocFromUrl(e.detail);
- DocServer.GetRefField(id).then(doc => (doc instanceof Doc ? DocumentManager.Instance.showDocument(doc, { willPan: false }) : null));
+ const id = GetDocFromUrl(e.detail);
+ DocServer.GetRefField(id).then(doc => (doc instanceof Doc ? DocumentView.showDocument(doc, { willPan: false }) : null));
});
document.addEventListener('linkAnnotationToDash', Hypothesis.linkListener);
this.initEventListeners();
}
componentWillUnMount() {
- window.removeEventListener('keyup', KeyManager.Instance.unhandle);
- window.removeEventListener('keydown', KeyManager.Instance.handle);
- window.removeEventListener('pointerdown', this.globalPointerDown, true);
- window.removeEventListener('pointermove', this.globalPointerMove, true);
- window.removeEventListener('pointerup', this.globalPointerClick, true);
- window.removeEventListener('paste', KeyManager.Instance.paste as any);
- document.removeEventListener('linkAnnotationToDash', Hypothesis.linkListener);
+ // window.removeEventListener('keyup', KeyManager.Instance.unhandle);
+ // window.removeEventListener('keydown', KeyManager.Instance.handle);
+ // window.removeEventListener('pointerdown', this.globalPointerDown, true);
+ // window.removeEventListener('pointermove', this.globalPointerMove, true);
+ // window.removeEventListener('pointerup', this.globalPointerClick, true);
+ // window.removeEventListener('paste', KeyManager.Instance.paste as any);
+ // document.removeEventListener('linkAnnotationToDash', Hypothesis.linkListener);
}
constructor(props: any) {
@@ -306,6 +317,7 @@ export class MainView extends ObservableReactComponent<{}> {
fa.faSnowflake,
fa.faStar,
fa.faMicrophone,
+ fa.faCircleHalfStroke,
fa.faKeyboard,
fa.faQuestion,
fa.faTasks,
@@ -526,12 +538,17 @@ export class MainView extends ObservableReactComponent<{}> {
fa.faZ,
fa.faArrowsUpToLine,
fa.faArrowsDownToLine,
+ fa.faPalette,
+ fa.faHourglassHalf,
+ fa.faRobot,
+ fa.faSatellite,
+ fa.faStar
]
);
}
private longPressTimer: NodeJS.Timeout | undefined;
- globalPointerClick = action((e: any) => {
+ globalPointerClick = action(() => {
this.longPressTimer && clearTimeout(this.longPressTimer);
DocumentView.LongPress = false;
});
@@ -541,7 +558,9 @@ export class MainView extends ObservableReactComponent<{}> {
globalPointerDown = action((e: PointerEvent) => {
DocumentView.LongPress = false;
this.longPressTimer = setTimeout(
- action(() => (DocumentView.LongPress = true)),
+ action(() => {
+ DocumentView.LongPress = true;
+ }),
1000
);
DocumentManager.removeOverlayViews();
@@ -560,7 +579,7 @@ export class MainView extends ObservableReactComponent<{}> {
});
initEventListeners = () => {
- window.addEventListener('beforeunload', DocServer.UPDATE_SERVER_CACHE);
+ window.addEventListener('beforeunload', UPDATE_SERVER_CACHE);
window.addEventListener('drop', e => e.preventDefault(), false); // prevent default behavior of navigating to a new web page
window.addEventListener('dragover', e => e.preventDefault(), false);
document.addEventListener('pointerdown', this.globalPointerDown, true);
@@ -572,7 +591,7 @@ export class MainView extends ObservableReactComponent<{}> {
if (!e.cancelBubble) {
const pathstr = (e as any)?.path?.map((p: any) => p.classList?.toString()).join();
if (pathstr?.includes('libraryFlyout')) {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
}
}
},
@@ -608,8 +627,8 @@ export class MainView extends ObservableReactComponent<{}> {
waitForDoubleClick = () => (SnappingManager.ExploreMode ? 'never' : undefined);
headerBarScreenXf = () => new Transform(-this.leftScreenOffsetOfMainDocView - this.leftMenuFlyoutWidth(), -this.headerBarDocHeight(), 1);
mainScreenToLocalXf = () => new Transform(-this.leftScreenOffsetOfMainDocView - this.leftMenuFlyoutWidth(), -this.topOfMainDocContent, 1);
- addHeaderDoc = (doc: Doc | Doc[], annotationKey?: string) => (doc instanceof Doc ? [doc] : doc).reduce((done, doc) => Doc.AddDocToList(this.headerBarDoc, 'data', doc), true);
- removeHeaderDoc = (doc: Doc | Doc[], annotationKey?: string) => (doc instanceof Doc ? [doc] : doc).reduce((done, doc) => Doc.RemoveDocFromList(this.headerBarDoc, 'data', doc), true);
+ addHeaderDoc = (docs: Doc | Doc[]) => toList(docs).reduce((done, doc) => Doc.AddDocToList(this.headerBarDoc, 'data', doc), true);
+ removeHeaderDoc = (docs: Doc | Doc[]) => toList(docs).reduce((done, doc) => Doc.RemoveDocFromList(this.headerBarDoc, 'data', doc), true);
@computed get headerBarDocView() {
return (
<div className="mainView-headerBar" style={{ height: this.headerBarDocHeight() }}>
@@ -626,10 +645,10 @@ export class MainView extends ObservableReactComponent<{}> {
isDocumentActive={returnTrue} // headerBar is always documentActive (ie, the docView gets pointer events)
isContentActive={returnTrue} // headerBar is awlays contentActive which means its items are always documentActive
ScreenToLocalTransform={this.headerBarScreenXf}
- childHideResizeHandles={true}
+ childHideResizeHandles
childDragAction={dropActionType.move}
- dontRegisterView={true}
- hideResizeHandles={true}
+ dontRegisterView
+ hideResizeHandles
PanelWidth={this.headerBarDocWidth}
PanelHeight={this.headerBarDocHeight}
renderDepth={0}
@@ -665,7 +684,7 @@ export class MainView extends ObservableReactComponent<{}> {
childFilters={returnEmptyFilter}
childFiltersByRanges={returnEmptyFilter}
searchFilterDocs={returnEmptyDoclist}
- suppressSetHeight={true}
+ suppressSetHeight
renderDepth={this._hideUI ? 0 : -1}
/>
</>
@@ -674,7 +693,7 @@ export class MainView extends ObservableReactComponent<{}> {
@computed get dockingContent() {
return (
- <GestureOverlay isActive={LightboxView.LightboxDoc ? false : true}>
+ <GestureOverlay isActive={!DocumentView.LightboxDoc()}>
<div
key="docking"
className={`mainView-dockingContent${this._leftMenuFlyoutWidth ? '-flyout' : ''}`}
@@ -685,7 +704,7 @@ export class MainView extends ObservableReactComponent<{}> {
style={{
width: `calc(100% - ${this._leftMenuFlyoutWidth + this.leftMenuWidth() + this.propertiesWidth()}px)`,
minWidth: `calc(100% - ${this._leftMenuFlyoutWidth + this.leftMenuWidth() + this.propertiesWidth()}px)`,
- transform: LightboxView.LightboxDoc ? 'scale(0.0001)' : undefined,
+ transform: DocumentView.LightboxDoc() ? 'scale(0.0001)' : undefined,
}}>
{!this.mainContainer ? null : this.mainDocView}
</div>
@@ -698,9 +717,16 @@ export class MainView extends ObservableReactComponent<{}> {
setupMoveUpEvents(
this,
e,
- action(e => ((SettingsManager.Instance.propertiesWidth = Math.max(0, this._dashUIWidth - e.clientX)) ? false : false)),
- action(() => SettingsManager.Instance.propertiesWidth < 5 && (SettingsManager.Instance.propertiesWidth = 0)),
- action(() => (SettingsManager.Instance.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0)),
+ action(() => {
+ SnappingManager.SetPropertiesWidth(Math.max(0, this._dashUIWidth - e.clientX));
+ return !SnappingManager.PropertiesWidth;
+ }),
+ action(() => {
+ SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0);
+ }),
+ action(() => {
+ SnappingManager.SetPropertiesWidth(this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0);
+ }),
false
);
};
@@ -710,7 +736,10 @@ export class MainView extends ObservableReactComponent<{}> {
setupMoveUpEvents(
this,
e,
- action(e => ((this._leftMenuFlyoutWidth = Math.max(e.clientX - 58, 0)) ? false : false)),
+ action(ev => {
+ this._leftMenuFlyoutWidth = Math.max(ev.clientX - 58, 0);
+ return false;
+ }),
() => this._leftMenuFlyoutWidth < 5 && this.closeFlyout(),
this.closeFlyout
);
@@ -718,7 +747,8 @@ export class MainView extends ObservableReactComponent<{}> {
sidebarScreenToLocal = () => new Transform(0, -this.topOfSidebarDoc, 1);
mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftScreenOffsetOfMainDocView, 0);
- static addDocTabFunc_impl = (doc: Doc, location: OpenWhere): boolean => {
+ static addDocTabFunc_impl = (docs: Doc | Doc[], location: OpenWhere): boolean => {
+ const doc = toList(docs).lastElement();
const whereFields = location.split(':');
const keyValue = whereFields.includes(OpenWhereMod.keyvalue);
const whereMods = whereFields.length > 1 ? (whereFields[1] as OpenWhereMod) : OpenWhereMod.none;
@@ -735,7 +765,7 @@ export class MainView extends ObservableReactComponent<{}> {
@computed get flyout() {
return !this._leftMenuFlyoutWidth ? (
- <div key="flyout" className={`mainView-libraryFlyout-out`}>
+ <div key="flyout" className="mainView-libraryFlyout-out">
{this.docButtons}
</div>
) : (
@@ -745,7 +775,7 @@ export class MainView extends ObservableReactComponent<{}> {
Document={this._sidebarContent.proto || this._sidebarContent}
addDocument={undefined}
addDocTab={DocumentViewInternal.addDocTabFunc}
- pinToPres={TabDocView.PinDoc}
+ pinToPres={DocumentView.PinDoc}
containerViewPath={returnEmptyDoclist}
styleProvider={this._sidebarContent.proto === Doc.MyDashboards || this._sidebarContent.proto === Doc.MyFilesystem || this._sidebarContent.proto === Doc.MyTrails ? DashboardStyleProvider : DefaultStyleProvider}
removeDocument={returnFalse}
@@ -768,7 +798,7 @@ export class MainView extends ObservableReactComponent<{}> {
@computed get leftMenuPanel() {
return (
- <div key="menu" className="mainView-leftMenuPanel" style={{ background: SettingsManager.userBackgroundColor, display: LightboxView.LightboxDoc ? 'none' : undefined }}>
+ <div key="menu" className="mainView-leftMenuPanel" style={{ background: SnappingManager.userBackgroundColor, display: DocumentView.LightboxDoc() ? 'none' : undefined }}>
<DocumentView
Document={Doc.MyLeftSidebarMenu}
addDocument={undefined}
@@ -800,7 +830,7 @@ export class MainView extends ObservableReactComponent<{}> {
if (willOpen) {
switch ((this._panelContent = title)) {
case 'Settings':
- SettingsManager.Instance.open();
+ SettingsManager.Instance.openMgr();
break;
case 'Help':
break;
@@ -821,9 +851,9 @@ export class MainView extends ObservableReactComponent<{}> {
{this.flyout}
<div
className="mainView-libraryHandle"
- style={{ background: SettingsManager.userBackgroundColor, left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }}
+ style={{ background: SnappingManager.userBackgroundColor, left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }}
onPointerDown={this.onFlyoutPointerDown}>
- <FontAwesomeIcon icon="chevron-left" color={SettingsManager.userColor} style={{ opacity: '50%' }} size="sm" />
+ <FontAwesomeIcon icon="chevron-left" color={SnappingManager.userColor} style={{ opacity: '50%' }} size="sm" />
</div>
<div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)` }}>
{this.dockingContent}
@@ -833,16 +863,14 @@ export class MainView extends ObservableReactComponent<{}> {
className={`mainView-propertiesDragger${this.propertiesWidth() < 10 ? '-minified' : ''}`}
key="props"
onPointerDown={this.onPropertiesPointerDown}
- style={{ background: SettingsManager.userVariantColor, right: this.propertiesWidth() - 1 }}>
- <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? 'chevron-left' : 'chevron-right'} color={SettingsManager.userColor} size="sm" />
+ style={{ background: SnappingManager.userVariantColor, right: this.propertiesWidth() - 1 }}>
+ <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? 'chevron-left' : 'chevron-right'} color={SnappingManager.userColor} size="sm" />
</div>
)}
- <div className="properties-container" style={{ width: this.propertiesWidth(), color: SettingsManager.userColor }}>
- {
- <div style={{ display: this.propertiesWidth() < 10 ? 'none' : undefined }}>
- <PropertiesView styleProvider={DefaultStyleProvider} addDocTab={DocumentViewInternal.addDocTabFunc} width={this.propertiesWidth()} height={this.propertiesHeight()} />
- </div>
- }
+ <div className="properties-container" style={{ width: this.propertiesWidth(), color: SnappingManager.userColor }}>
+ <div style={{ display: this.propertiesWidth() < 10 ? 'none' : undefined }}>
+ <PropertiesView styleProvider={DefaultStyleProvider} addDocTab={DocumentViewInternal.addDocTabFunc} width={this.propertiesWidth()} height={this.propertiesHeight()} />
+ </div>
</div>
</div>
</div>
@@ -879,32 +907,32 @@ export class MainView extends ObservableReactComponent<{}> {
// generate the wrong value from getClientRectangle() -- specifically they return an 'x' that is the flyout's width greater than it should be.
// interactively adjusting the flyout fixes the problem. So does programmatically changing the value after a timeout to something *fractionally* different (ie, 1.5, not 1);)
this._leftMenuFlyoutWidth = this._leftMenuFlyoutWidth || 250;
- //setTimeout(action(() => (this._leftMenuFlyoutWidth += 0.5)));
+ // setTimeout(action(() => (this._leftMenuFlyoutWidth += 0.5)));
this._sidebarContent.proto = DocCast(button.target);
- SettingsManager.Instance.SetLastPressedBtn(button);
+ SnappingManager.SetLastPressedBtn(button[Id]);
});
closeFlyout = action(() => {
- SettingsManager.Instance.SetLastPressedBtn(undefined);
+ SnappingManager.SetLastPressedBtn('');
this._panelContent = 'none';
this._sidebarContent.proto = undefined;
this._leftMenuFlyoutWidth = 0;
});
- remButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && !doc.dragOnlyWithinContainer && Doc.RemoveDocFromList(Doc.MyDockedBtns, 'data', doc), true);
- moveButtonDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => this.remButtonDoc(doc) && addDocument(doc);
- addButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.AddDocToList(Doc.MyDockedBtns, 'data', doc), true);
+ remButtonDoc = (docs: Doc | Doc[]) => toList(docs).reduce((flg: boolean, doc) => flg && !doc.dragOnlyWithinContainer && Doc.RemoveDocFromList(Doc.MyDockedBtns, 'data', doc), true);
+ moveButtonDoc = (docs: Doc | Doc[], targetCol: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => this.remButtonDoc(docs) && addDocument(docs);
+ addButtonDoc = (docs: Doc | Doc[]) => toList(docs).reduce((flg: boolean, doc) => flg && Doc.AddDocToList(Doc.MyDockedBtns, 'data', doc), true);
buttonBarXf = () => {
if (!this._docBtnRef.current) return Transform.Identity();
- const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
+ const { scale, translateX, translateY } = ClientUtils.GetScreenTransform(this._docBtnRef.current);
return new Transform(-translateX, -translateY, 1 / scale);
};
@computed get docButtons() {
return !Doc.MyDockedBtns ? null : (
- <div className="mainView-docButtons" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }} ref={this._docBtnRef}>
+ <div className="mainView-docButtons" style={{ background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor }} ref={this._docBtnRef}>
<CollectionLinearView
Document={Doc.MyDockedBtns}
docViewPath={returnEmptyDocViewList}
@@ -930,22 +958,26 @@ export class MainView extends ObservableReactComponent<{}> {
childFiltersByRanges={returnEmptyFilter}
searchFilterDocs={returnEmptyDoclist}
/>
- {['watching', 'recording'].includes(StrCast(this.userDoc?.presentationMode)) ? <div style={{ border: '.5rem solid green', padding: '5px' }}>{StrCast(this.userDoc?.presentationMode)}</div> : <></>}
+ {['watching', 'recording'].includes(StrCast(this.userDoc?.presentationMode)) ? <div style={{ border: '.5rem solid green', padding: '5px' }}>{StrCast(this.userDoc?.presentationMode)}</div> : null}
</div>
);
}
@computed get snapLines() {
- const dragged = DragManager.docsBeingDragged.lastElement() ?? SelectionManager.Docs.lastElement();
- const dragPar = dragged ? DocumentManager.Instance.getDocumentView(dragged)?.CollectionFreeFormView : undefined;
+ const dragged = DragManager.docsBeingDragged.lastElement() ?? DocumentView.SelectedDocs().lastElement();
+ const dragPar = dragged ? CollectionFreeFormView.from(DocumentView.getViews(dragged).lastElement()) : undefined;
return !dragPar?.layoutDoc.freeform_snapLines ? null : (
<div className="mainView-snapLines">
<svg style={{ width: '100%', height: '100%' }}>
- {SnappingManager.HorizSnapLines.map((l, i) => (
- <line key={i} x1="0" y1={l} x2="2000" y2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray={'2 2'} />
- ))}
- {SnappingManager.VertSnapLines.map((l, i) => (
- <line key={i} y1={this.topOfMainDocContent.toString()} x1={l} y2="2000" x2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray={'2 2'} />
- ))}
+ {[
+ ...SnappingManager.HorizSnapLines.map((l, i) => (
+ // eslint-disable-next-line react/no-array-index-key
+ <line key={'horiz' + i} x1="0" y1={l} x2="2000" y2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray="2 2" />
+ )),
+ ...SnappingManager.VertSnapLines.map((l, i) => (
+ // eslint-disable-next-line react/no-array-index-key
+ <line key={'vert' + i} y1={this.topOfMainDocContent.toString()} x1={l} y2="2000" x2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray="2 2" />
+ )),
+ ]}
</svg>
</div>
);
@@ -962,13 +994,14 @@ export class MainView extends ObservableReactComponent<{}> {
values="1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
- 0 0 0 1 0"></feColorMatrix>
- <feGaussianBlur in="color" stdDeviation="4" result="blur"></feGaussianBlur>
- <feOffset in="blur" dx="0" dy="0" result="offset"></feOffset>
+ 0 0 0 1 0"
+ />
+ <feGaussianBlur in="color" stdDeviation="4" result="blur" />
+ <feOffset in="blur" dx="0" dy="0" result="offset" />
<feMerge>
- <feMergeNode in="bg"></feMergeNode>
- <feMergeNode in="offset"></feMergeNode>
- <feMergeNode in="SourceGraphic"></feMergeNode>
+ <feMergeNode in="bg" />
+ <feMergeNode in="offset" />
+ <feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
@@ -976,15 +1009,28 @@ export class MainView extends ObservableReactComponent<{}> {
);
}
+ togglePropertiesFlyout = () => {
+ if (MainView.Instance.propertiesWidth() > 0) {
+ SnappingManager.SetPropertiesWidth(0);
+ } else {
+ SnappingManager.SetPropertiesWidth(300);
+ }
+ };
+
+ lightboxMaxBorder = [200, 50];
render() {
return (
<div
className="mainView-container"
style={{
- color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
+ color: SnappingManager.userColor,
+ background: SnappingManager.userBackgroundColor,
}}
- onScroll={() => (ele => (ele.scrollTop = ele.scrollLeft = 0))(document.getElementById('root')!)}
+ onScroll={() =>
+ (ele => {
+ ele.scrollTop = ele.scrollLeft = 0;
+ })(document.getElementById('root')!)
+ }
ref={r => {
r &&
new _global.ResizeObserver(
@@ -1009,23 +1055,31 @@ export class MainView extends ObservableReactComponent<{}> {
<ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
{this._hideUI ? null : <TopBar />}
<LinkDescriptionPopup />
- {DocButtonState.Instance.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => (DocButtonState.Instance.LinkEditorDocView = undefined))} docView={DocButtonState.Instance.LinkEditorDocView} /> : null}
- {LinkInfo.Instance?.LinkInfo ? <LinkDocPreview {...LinkInfo.Instance.LinkInfo} /> : null}
-
+ {DocButtonState.Instance.LinkEditorDocView ? (
+ <LinkMenu
+ clearLinkEditor={action(() => {
+ DocButtonState.Instance.LinkEditorDocView = undefined;
+ })}
+ docView={DocButtonState.Instance.LinkEditorDocView}
+ />
+ ) : null}
+ {LinkInfo.Instance?.LinkInfo ? (
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ <LinkDocPreview {...LinkInfo.Instance.LinkInfo} />
+ ) : null}
{((page: string) => {
// prettier-ignore
switch (page) {
- default:
- case 'dashboard': return (<>
- <div key="dashdiv" style={{ position: 'relative', display: this._hideUI || LightboxView.LightboxDoc ? 'none' : undefined, zIndex: 2001 }}>
- <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} toggleTopBar={this.toggleTopBar} topBarHeight={this.headerBarHeightFunc}/>
+ case 'home': return <DashboardView />;
+ case 'dashboard':
+ default: return (<>
+ <div key="dashdiv" style={{ position: 'relative', display: this._hideUI || DocumentView.LightboxDoc() ? 'none' : undefined, zIndex: 2001 }}>
+ <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} togglePropertiesFlyout={this.togglePropertiesFlyout} toggleTopBar={this.toggleTopBar} topBarHeight={this.headerBarHeightFunc}/>
</div>
{this.mainDashboardArea}
</> );
- case 'home': return <DashboardView />;
}
})(Doc.ActivePage)}
-
<PreviewCursor />
<TaskCompletionBox />
<ContextMenu />
@@ -1036,28 +1090,29 @@ export class MainView extends ObservableReactComponent<{}> {
<MarqueeOptionsMenu />
<TimelineMenu />
<RichTextMenu />
- {/* <InkTranscription /> */}
{this.snapLines}
- <LightboxView key="lightbox" PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} maxBorder={[200, 50]} />
- <OverlayView />
+ <LightboxView key="lightbox" PanelWidth={this._windowWidth} addSplit={CollectionDockingView.AddSplit} PanelHeight={this._windowHeight} maxBorder={this.lightboxMaxBorder} />
<GPTPopup key="gptpopup" />
<SchemaCSVPopUp key="schemacsvpopup" />
- <GenerativeFill imageEditorOpen={ImageBox.imageEditorOpen} imageEditorSource={ImageBox.imageEditorSource} imageRootDoc={ImageBox.imageRootDoc} addDoc={ImageBox.addDoc} />
- {/* <NewLightboxView key="newLightbox" PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} maxBorder={[200, 50]} /> */}
+ <GenerativeFill imageEditorOpen={ImageEditor.Open} imageEditorSource={ImageEditor.Source} imageRootDoc={ImageEditor.RootDoc} addDoc={ImageEditor.AddDoc} />
</div>
);
}
}
-ScriptingGlobals.add(function selectMainMenu(doc: Doc, title: string) {
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function selectMainMenu(doc: Doc) {
MainView.Instance.selectMenu(doc);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function createNewPresentation() {
return MainView.Instance.createNewPresentation();
}, 'creates a new presentation when called');
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function openPresentation(pres: Doc) {
return MainView.Instance.openPresentation(pres);
}, 'creates a new presentation when called');
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function createNewFolder() {
return MainView.Instance.createNewFolder();
}, 'creates a new folder in myFiles when called');
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index af7f38937..a6dc5c62b 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -1,7 +1,10 @@
+/* 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';
import * as React from 'react';
-import { SettingsManager } from '../util/SettingsManager';
+import { SnappingManager } from '../util/SnappingManager';
import './MainViewModal.scss';
export interface MainViewOverlayProps {
@@ -11,7 +14,6 @@ export interface MainViewOverlayProps {
dialogueBoxStyle?: React.CSSProperties;
overlayStyle?: React.CSSProperties;
dialogueBoxDisplayedOpacity?: number;
- overlayDisplayedOpacity?: number;
closeOnExternalClick?: () => void; // the close method of a MainViewModal, triggered if there is a click on the overlay (closing the modal)
}
@@ -20,7 +22,6 @@ export class MainViewModal extends React.Component<MainViewOverlayProps> {
render() {
const p = this.props;
const dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1;
- const overlayOpacity = p.overlayDisplayedOpacity || 0.4;
return !p.isDisplayed ? null : (
<div
className="mainViewModal-cont"
@@ -43,7 +44,7 @@ export class MainViewModal extends React.Component<MainViewOverlayProps> {
className="overlay"
onClick={this.props?.closeOnExternalClick}
style={{
- backgroundColor: isDark(SettingsManager.userColor) ? '#DFDFDF30' : '#32323230',
+ backgroundColor: isDark(SnappingManager.userColor) ? '#DFDFDF30' : '#32323230',
...(p.overlayStyle || {}),
}}
/>
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index f59042b04..c18ac6738 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -7,16 +7,14 @@ import { List } from '../../fields/List';
import { NumCast } from '../../fields/Types';
import { GetEffectiveAcl } from '../../fields/util';
import { unimplementedFunction, Utils } from '../../Utils';
-import { Docs, DocUtils } from '../documents/Documents';
+import { Docs } from '../documents/Documents';
+import { DocUtils, FollowLinkScript } from '../documents/DocUtils';
import { DragManager } from '../util/DragManager';
-import { FollowLinkScript } from '../util/LinkFollower';
import { undoable, undoBatch, UndoManager } from '../util/UndoManager';
import './MarqueeAnnotator.scss';
import { DocumentView } from './nodes/DocumentView';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
-import { AnchorMenu } from './pdf/AnchorMenu';
import { ObservableReactComponent } from './ObservableReactComponent';
-const _global = (window /* browser */ || global) /* node */ as any;
+import { AnchorMenu } from './pdf/AnchorMenu';
export interface MarqueeAnnotatorProps {
Document: Doc;
@@ -34,7 +32,7 @@ export interface MarqueeAnnotatorProps {
annotationLayer: HTMLDivElement;
addDocument: (doc: Doc) => boolean;
getPageFromScroll?: (top: number) => number;
- finishMarquee: (x?: number, y?: number, PointerEvent?: PointerEvent) => void;
+ finishMarquee: (x?: number, y?: number) => void;
anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
anchorMenuCrop?: (anchor: Doc | undefined, addCrop: boolean) => Doc | undefined;
highlightDragSrcColor?: string;
@@ -86,51 +84,51 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
return marqueeAnno;
}
- const textRegionAnno = Docs.Create.HTMLMarkerDocument([], {
+ const textRegionAnno = Docs.Create.ConfigDocument({
annotationOn: this.props.Document,
text: this.props.selectionText() as any, // text want an RTFfield, but strings are acceptable, too.
+ text_html: this.props.selectionText() as any,
backgroundColor: 'transparent',
presentation_duration: 2100,
presentation_transition: 500,
presentation_zoomText: true,
- title: 'Selection on ' + this.props.Document.title,
+ title: '>' + this.props.Document.title,
});
+ const textRegionAnnoProto = textRegionAnno[DocData];
let minX = Number.MAX_VALUE;
let maxX = -Number.MAX_VALUE;
let minY = Number.MAX_VALUE;
let maxY = -Number.MIN_VALUE;
- const annoDocs: Doc[] = [];
- savedAnnoMap.forEach((value: HTMLDivElement[], key: number) =>
- value.map(anno => {
- const textRegion = new Doc();
- textRegion.x = parseInt(anno.style.left ?? '0');
- textRegion.y = parseInt(anno.style.top ?? '0');
- textRegion._height = parseInt(anno.style.height ?? '0');
- textRegion._width = parseInt(anno.style.width ?? '0');
- textRegion.annoTextRegion = textRegionAnno;
- textRegion.backgroundColor = color;
- annoDocs.push(textRegion);
+ const annoRects: string[] = [];
+ savedAnnoMap.forEach((value: HTMLDivElement[]) =>
+ value.forEach(anno => {
+ const x = parseInt(anno.style.left ?? '0');
+ const y = parseInt(anno.style.top ?? '0');
+ const height = parseInt(anno.style.height ?? '0');
+ const width = parseInt(anno.style.width ?? '0');
+ annoRects.push(`${x}:${y}:${width}:${height}`);
anno.remove();
- minY = Math.min(NumCast(textRegion.y), minY);
- minX = Math.min(NumCast(textRegion.x), minX);
- maxY = Math.max(NumCast(textRegion.y) + NumCast(textRegion._height), maxY);
- maxX = Math.max(NumCast(textRegion.x) + NumCast(textRegion._width), maxX);
+ minY = Math.min(NumCast(y), minY);
+ minX = Math.min(NumCast(x), minX);
+ maxY = Math.max(NumCast(y) + NumCast(height), maxY);
+ maxX = Math.max(NumCast(x) + NumCast(width), maxX);
})
);
- const textRegionAnnoProto = textRegionAnno[DocData];
textRegionAnnoProto.y = Math.max(minY, 0);
textRegionAnnoProto.x = Math.max(minX, 0);
textRegionAnnoProto.height = Math.max(maxY, 0) - Math.max(minY, 0);
textRegionAnnoProto.width = Math.max(maxX, 0) - Math.max(minX, 0);
+ textRegionAnnoProto.backgroundColor = color;
// mainAnnoDocProto.text = this._selectionText;
- textRegionAnnoProto.text_inlineAnnotations = new List<Doc>(annoDocs);
+ textRegionAnnoProto.text_inlineAnnotations = new List<string>(annoRects);
+ textRegionAnnoProto.opacity = 0;
textRegionAnnoProto.layout_unrendered = true;
savedAnnoMap.clear();
return textRegionAnno;
};
@action
- highlight = (color: string, isLinkButton: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean, summarize?: boolean) => {
+ highlight = (color: string, isLinkButton: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => {
// creates annotation documents for current highlights
const effectiveAcl = GetEffectiveAcl(this.props.Document[DocData]);
const annotationDoc = [AclAugment, AclSelfEdit, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color, isLinkButton, savedAnnotations);
@@ -156,7 +154,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
// 3) localize the unrotated vector by scaling into the marquee container's coordinates
// 4) reattach the vector to the center of the bounding box
getTransformedScreenPt = (down: number[]) => {
- const marqueeContainer = this.props.marqueeContainer;
+ const { marqueeContainer } = this.props;
const containerXf = this.props.isNativeScaled ? this.props.docView().screenToContentsTransform() : this.props.docView().screenToViewTransform();
const boundingRect = marqueeContainer.getBoundingClientRect();
const center = { x: boundingRect.x + boundingRect.width / 2, y: boundingRect.y + boundingRect.height / 2 };
@@ -168,7 +166,6 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
@action
public onInitiateSelection(down: number[]) {
- console.log('DOWN = ' + down[0] + ' ' + down[1]);
this._width = this._height = 0;
this._start = this.getTransformedScreenPt(down);
@@ -177,15 +174,15 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
document.addEventListener('pointermove', this.onSelectMove);
document.addEventListener('pointerup', this.onSelectEnd);
- AnchorMenu.Instance.OnCrop = (e: PointerEvent) => {
+ AnchorMenu.Instance.OnCrop = () => {
if (this.props.anchorMenuCrop) {
UndoManager.RunInBatch(() => this.props.anchorMenuCrop?.(this.highlight('', true, undefined, false), true), 'cropping');
}
};
- AnchorMenu.Instance.OnClick = undoable((e: PointerEvent) => this.props.anchorMenuClick?.()?.(this.highlight(this.props.highlightDragSrcColor ?? 'rgba(173, 216, 230, 0.75)', true, undefined, true)), 'make sidebar annotation');
+ AnchorMenu.Instance.OnClick = undoable(() => this.props.anchorMenuClick?.()?.(this.highlight(this.props.highlightDragSrcColor ?? 'rgba(173, 216, 230, 0.75)', true, undefined, true)), 'make sidebar annotation');
AnchorMenu.Instance.OnAudio = unimplementedFunction;
- AnchorMenu.Instance.Highlight = this.highlight;
- AnchorMenu.Instance.GetAnchor = (savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => this.highlight('rgba(173, 216, 230, 0.75)', true, savedAnnotations, true);
+ AnchorMenu.Instance.Highlight = (color: string) => this.highlight(color, false, undefined, true);
+ AnchorMenu.Instance.GetAnchor = (savedAnnotations?: ObservableMap<number, HTMLDivElement[]> /* , addAsAnnotation?: boolean */) => this.highlight('rgba(173, 216, 230, 0.75)', true, savedAnnotations, true);
AnchorMenu.Instance.onMakeAnchor = () => AnchorMenu.Instance.GetAnchor(undefined, true);
/**
@@ -199,14 +196,14 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
const targetCreator = (annotationOn: Doc | undefined) => {
const target = DocUtils.GetNewTextDoc('Note linked to ' + this.props.Document.title, 0, 0, 100, 100, annotationOn, 'yellow');
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
return target;
};
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docView(), sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
- dragComplete: e => {
- if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
- e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.props.Document;
- e.annoDragData.linkSourceDoc.followLinkZoom = false;
+ dragComplete: dragEv => {
+ if (!dragEv.aborted && dragEv.annoDragData && dragEv.annoDragData.linkSourceDoc && dragEv.annoDragData.dropDocument && dragEv.linkDocument) {
+ dragEv.annoDragData.linkSourceDoc.followLinkToggle = dragEv.annoDragData.dropDocument.annotationOn === this.props.Document;
+ dragEv.annoDragData.linkSourceDoc.followLinkZoom = false;
}
},
});
@@ -220,16 +217,16 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
: action((e: PointerEvent, ele: HTMLElement) => {
e.preventDefault();
e.stopPropagation();
- var cropRegion: Doc | undefined;
+ let cropRegion: Doc | undefined;
+ // eslint-disable-next-line no-return-assign
const sourceAnchorCreator = () => (cropRegion = this.highlight('', true, undefined, true)); // hyperlink color
- const targetCreator = (annotationOn: Doc | undefined) => this.props.anchorMenuCrop!(cropRegion, false)!;
+ const targetCreator = (/* annotationOn: Doc | undefined */) => this.props.anchorMenuCrop!(cropRegion, false)!;
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docView(), sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
- dragComplete: e => {
- if (!e.aborted && e.linkDocument) {
- const linkDocData = e.linkDocument[DocData];
+ dragComplete: dragEx => {
+ if (!dragEx.aborted && dragEx.linkDocument) {
+ const linkDocData = dragEx.linkDocument[DocData];
linkDocData.link_relationship = 'cropped image';
linkDocData.title = 'crop: ' + this.props.Document.title;
- linkDocData.link_displayLine = false;
}
},
});
@@ -241,16 +238,27 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
}
@action
+ onMove = (pt: number[]) => {
+ const movLoc = this.getTransformedScreenPt(pt);
+ this._width = movLoc.x - this._start.x;
+ this._height = movLoc.y - this._start.y;
+ };
+
+ @action
onSelectMove = (e: PointerEvent) => {
const movLoc = this.getTransformedScreenPt([e.clientX, e.clientY]);
this._width = movLoc.x - this._start.x;
this._height = movLoc.y - this._start.y;
- //e.stopPropagation(); // overlay documents are all 'active', yet they can be dragged. if we stop propagation, then they can be marqueed but not dragged. if we don't stop, then they will be marqueed and dragged, but the marquee will be zero width since the doc will move along with the cursor.
+ // e.stopPropagation(); // overlay documents are all 'active', yet they can be dragged. if we stop propagation, then they can be marqueed but not dragged. if we don't stop, then they will be marqueed and dragged, but the marquee will be zero width since the doc will move along with the cursor.
};
- @action
onSelectEnd = (e: PointerEvent) => {
e.stopPropagation();
+ this.onEnd(e.clientX, e.clientY);
+ };
+ @action
+ onEnd = (x: number, y: number) => {
+ AnchorMenu.Instance.setSelectedText('');
const marquees = this.props.marqueeContainer.getElementsByClassName('marqueeAnnotator-dragBox');
const marqueeStyle = (Array.from(marquees).lastElement() as HTMLDivElement)?.style;
if (!this.isEmpty && marqueeStyle) {
@@ -258,7 +266,9 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
// copy the temporary marquee to allow for multiple selections (not currently available though).
const copy = document.createElement('div');
const scale = (this.props.scaling?.() || 1) * NumCast(this.props.Document._freeform_scale, 1);
- ['border', 'opacity', 'top', 'left', 'width', 'height'].forEach(prop => (copy.style[prop as any] = marqueeStyle[prop as any]));
+ ['border', 'opacity', 'top', 'left', 'width', 'height'].forEach(prop => {
+ copy.style[prop as any] = marqueeStyle[prop as any];
+ });
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';
@@ -266,9 +276,9 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
copy.style.height = parseInt(marqueeStyle.height.toString().replace('px', '')) / scale + 'px';
(copy as any).marqueeing = true;
MarqueeAnnotator.previewNewAnnotation(this.props.savedAnnotations(), this.props.annotationLayer, copy, this.props.getPageFromScroll?.(this.top) || 0);
- AnchorMenu.Instance.jumpTo(e.clientX, e.clientY);
+ AnchorMenu.Instance.jumpTo(x, y);
}
- this.props.finishMarquee(this.isEmpty ? e.clientX : undefined, this.isEmpty ? e.clientY : undefined, e);
+ this.props.finishMarquee(this.isEmpty ? x : undefined, this.isEmpty ? y : undefined);
this._width = this._height = 0;
};
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
deleted file mode 100644
index 89c3c41f8..000000000
--- a/src/client/views/MetadataEntryMenu.tsx
+++ /dev/null
@@ -1,197 +0,0 @@
-import { IReactionDisposer, action, observable, reaction, runInAction } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import * as Autosuggest from 'react-autosuggest';
-import { emptyFunction, emptyPath } from '../../Utils';
-import { Doc, DocListCast, Field } from '../../fields/Doc';
-import { undoBatch } from '../util/UndoManager';
-import './MetadataEntryMenu.scss';
-import { KeyValueBox } from './nodes/KeyValueBox';
-
-export type DocLike = Doc | Doc[] | Promise<Doc> | Promise<Doc[]>;
-export interface MetadataEntryProps {
- docs: Doc[];
- onError?: () => boolean;
- suggestWithFunction?: boolean;
-}
-
-@observer
-export class MetadataEntryMenu extends React.Component<MetadataEntryProps> {
- @observable private _currentKey: string = '';
- @observable private _currentValue: string = '';
- private _addChildren: boolean = false;
- @observable _allSuggestions: string[] = [];
- _suggestionDispser: IReactionDisposer | undefined;
- private userModified = false;
-
- private autosuggestRef = React.createRef<Autosuggest>();
-
- @action
- onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
- this._currentKey = newValue;
- if (!this.userModified) {
- this.previewValue();
- }
- };
-
- previewValue = async () => {
- let field: Field | undefined | null = null;
- let onProto: boolean = false;
- let value: string | undefined = undefined;
- const docs = this.props.docs;
- for (const doc of docs) {
- const v = await doc[this._currentKey];
- onProto = onProto || !Object.keys(doc).includes(this._currentKey);
- if (field === null) {
- field = v;
- } else if (v !== field) {
- value = 'multiple values';
- }
- }
- if (value === undefined) {
- if (field !== null && field !== undefined) {
- value = (onProto ? '' : '= ') + Field.toScriptString(field);
- } else {
- value = '';
- }
- }
- const s = value;
- runInAction(() => (this._currentValue = s));
- };
-
- @action
- onValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {
- this._currentValue = e.target.value;
- this.userModified = e.target.value.trim() !== '';
- };
-
- @undoBatch
- @action
- onValueKeyDown = async (e: React.KeyboardEvent) => {
- if (e.key === 'Enter') {
- e.stopPropagation();
- const script = KeyValueBox.CompileKVPScript(this._currentValue);
- if (!script) return;
-
- let childSuccess = true;
- if (this._addChildren) {
- for (const document of this.props.docs) {
- const collectionChildren = DocListCast(document.data);
- if (collectionChildren) {
- childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script));
- }
- }
- }
- const success = this.props.docs.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)) && childSuccess;
- if (!success) {
- if (this.props.onError) {
- if (this.props.onError()) {
- this.clearInputs();
- }
- } else {
- this.clearInputs();
- }
- } else {
- this.clearInputs();
- }
- }
- };
-
- @action
- clearInputs = () => {
- this._currentKey = '';
- this._currentValue = '';
- this.userModified = false;
- if (this.autosuggestRef.current) {
- const input: HTMLInputElement = (this.autosuggestRef.current as any).input;
- input && input.focus();
- }
- };
-
- getKeySuggestions = (value: string) => {
- value = value.toLowerCase();
- const docs = this.props.docs;
- const keys = new Set<string>();
- docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
- return Array.from(keys).filter(key => key.toLowerCase().startsWith(value));
- };
- getSuggestionValue = (suggestion: string) => suggestion;
-
- renderSuggestion = (suggestion: string) => {
- return null;
- };
- componentDidMount() {
- this._suggestionDispser = reaction(
- () => this._currentKey,
- () => (this._allSuggestions = this.getKeySuggestions(this._currentKey)),
- { fireImmediately: true }
- );
- }
- componentWillUnmount() {
- this._suggestionDispser && this._suggestionDispser();
- }
-
- onClick = (e: React.ChangeEvent<HTMLInputElement>) => {
- this._addChildren = !this._addChildren;
- };
-
- private get considerChildOptions() {
- if (!this.props.docs.every(doc => doc._type_collection !== undefined)) {
- return null;
- }
- return (
- <div style={{ display: 'flex' }}>
- Children:
- <input type="checkbox" onChange={this.onClick}></input>
- </div>
- );
- }
-
- _ref = React.createRef<HTMLInputElement>();
- render() {
- return (
- <div className="metadataEntry-outerDiv" id="metadataEntry-outer" onPointerDown={e => e.stopPropagation()}>
- <div className="metadataEntry-inputArea">
- <div style={{ display: 'flex', flexDirection: 'row' }}>
- <span>Key:</span>
- <div className="metadataEntry-autoSuggester" onClick={e => this.autosuggestRef.current!.input?.focus()}>
- <Autosuggest
- // @ts-ignore
- inputProps={{ value: this._currentKey, onChange: this.onKeyChange }}
- getSuggestionValue={this.getSuggestionValue}
- suggestions={emptyPath}
- alwaysRenderSuggestions={false}
- renderSuggestion={this.renderSuggestion}
- onSuggestionsFetchRequested={emptyFunction}
- onSuggestionsClearRequested={emptyFunction}
- ref={this.autosuggestRef}
- />
- </div>
- </div>
- <div style={{ display: 'flex', flexDirection: 'row' }}>
- <span>Value:</span>
- <input className="metadataEntry-input" ref={this._ref} value={this._currentValue} onClick={e => this._ref.current!.focus()} onChange={this.onValueChange} onKeyDown={this.onValueKeyDown} />
- </div>
- {this.considerChildOptions}
- </div>
- <div className="metadataEntry-keys">
- <ul>
- {this._allSuggestions
- .slice()
- .sort()
- .map(s => (
- <li
- key={s}
- onClick={action(() => {
- this._currentKey = s;
- this.previewValue();
- })}>
- {s}
- </li>
- ))}
- </ul>
- </div>
- </div>
- );
- }
-}
diff --git a/src/client/views/ObservableReactComponent.tsx b/src/client/views/ObservableReactComponent.tsx
index 9b2b00903..34da82b6c 100644
--- a/src/client/views/ObservableReactComponent.tsx
+++ b/src/client/views/ObservableReactComponent.tsx
@@ -1,6 +1,8 @@
import { action, makeObservable, observable } from 'mobx';
import * as React from 'react';
import './AntimodeMenu.scss';
+import { observer } from 'mobx-react';
+import JsxParser from 'react-jsx-parser';
/**
* This is an abstract class that serves as the base for a PDF-style or Marquee-style
@@ -14,8 +16,19 @@ export abstract class ObservableReactComponent<T> extends React.Component<T, {}>
makeObservable(this);
}
componentDidUpdate(prevProps: Readonly<T>): void {
- Object.keys(prevProps).forEach(action(pkey =>
- (prevProps as any)[pkey] !== (this.props as any)[pkey] &&
- ((this._props as any)[pkey] = (this.props as any)[pkey]))); // prettier-ignore
+ Object.keys(prevProps)
+ .filter(pkey => (prevProps as any)[pkey] !== (this.props as any)[pkey])
+ .forEach(action(pkey => {
+ (this._props as any)[pkey] = (this.props as any)[pkey];
+ })); // prettier-ignore
}
}
+
+class ObserverJsxParser1 extends JsxParser {
+ constructor(props: any) {
+ super(props);
+ observer(this as any);
+ }
+}
+
+export const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any;
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 15b1f0275..a7907a565 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -3,19 +3,21 @@ import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
import ReactLoading from 'react-loading';
-import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue, setupMoveUpEvents } from '../../Utils';
+import { returnEmptyDoclist, returnEmptyFilter, returnTrue, setupMoveUpEvents } from '../../ClientUtils';
+import { Utils, emptyFunction } from '../../Utils';
import { Doc } from '../../fields/Doc';
import { Height, Width } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
-import { NumCast } from '../../fields/Types';
+import { NumCast, toList } from '../../fields/Types';
import { DocumentType } from '../documents/DocumentTypes';
-import { DragManager, dropActionType } from '../util/DragManager';
+import { DragManager } from '../util/DragManager';
+import { dropActionType } from '../util/DropActionTypes';
import { Transform } from '../util/Transform';
-import { LightboxView } from './LightboxView';
import { ObservableReactComponent } from './ObservableReactComponent';
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;
@@ -50,14 +52,14 @@ export class OverlayWindow extends ObservableReactComponent<OverlayWindowProps>
this.height = opts.height || 200;
}
- onPointerDown = (_: React.PointerEvent) => {
+ onPointerDown = () => {
document.removeEventListener('pointermove', this.onPointerMove);
document.removeEventListener('pointerup', this.onPointerUp);
document.addEventListener('pointermove', this.onPointerMove);
document.addEventListener('pointerup', this.onPointerUp);
};
- onResizerPointerDown = (_: React.PointerEvent) => {
+ onResizerPointerDown = () => {
document.removeEventListener('pointermove', this.onResizerPointerMove);
document.removeEventListener('pointerup', this.onResizerPointerUp);
document.addEventListener('pointermove', this.onResizerPointerMove);
@@ -80,27 +82,27 @@ export class OverlayWindow extends ObservableReactComponent<OverlayWindowProps>
this.height = Math.max(this.height, 30);
};
- onPointerUp = (e: PointerEvent) => {
+ onPointerUp = () => {
document.removeEventListener('pointermove', this.onPointerMove);
document.removeEventListener('pointerup', this.onPointerUp);
};
- onResizerPointerUp = (e: PointerEvent) => {
+ onResizerPointerUp = () => {
document.removeEventListener('pointermove', this.onResizerPointerMove);
document.removeEventListener('pointerup', this.onResizerPointerUp);
};
render() {
- return LightboxView.LightboxDoc ? null : (
+ return (
<div className="overlayWindow-outerDiv" style={{ transform: `translate(${this.x}px, ${this.y}px)`, width: this.width, height: this.height }}>
<div className="overlayWindow-titleBar" onPointerDown={this.onPointerDown}>
{this._props.overlayOptions.title || 'Untitled'}
- <button onClick={this._props.onClick} className="overlayWindow-closeButton">
+ <button type="button" onClick={this._props.onClick} className="overlayWindow-closeButton">
X
</button>
</div>
<div className="overlayWindow-content">{this.props.children}</div>
- <div className="overlayWindow-resizeDragger" onPointerDown={this.onResizerPointerDown}></div>
+ <div className="overlayWindow-resizeDragger" onPointerDown={this.onResizerPointerDown} />
</div>
);
}
@@ -108,6 +110,7 @@ export class OverlayWindow extends ObservableReactComponent<OverlayWindowProps>
@observer
export class OverlayView extends ObservableReactComponent<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: OverlayView;
@observable.shallow _elements: JSX.Element[] = [];
@@ -118,8 +121,9 @@ export class OverlayView extends ObservableReactComponent<{}> {
OverlayView.Instance = this;
new _global.ResizeObserver(
action((entries: any) => {
- for (const entry of entries) {
- Doc.MyOverlayDocs.forEach(doc => {
+ Array.from(entries).forEach((entry: any) => {
+ Doc.MyOverlayDocs.forEach(docIn => {
+ const doc = docIn;
if (NumCast(doc.overlayX) > entry.contentRect.width - 10) {
doc.overlayX = entry.contentRect.width - 10;
}
@@ -127,7 +131,7 @@ export class OverlayView extends ObservableReactComponent<{}> {
doc.overlayY = entry.contentRect.height - 10;
}
});
- }
+ });
})
).observe(window.document.body);
}
@@ -162,30 +166,22 @@ export class OverlayView extends ObservableReactComponent<{}> {
const index = this._elements.indexOf(contents);
if (index !== -1) this._elements.splice(index, 1);
});
- contents = (
+ const wincontents = (
<OverlayWindow onClick={remove} key={Utils.GenerateGuid()} overlayOptions={options}>
{contents}
</OverlayWindow>
);
- this._elements.push(contents);
+ this._elements.push(wincontents);
return remove;
}
- removeOverlayDoc = (doc: Doc | Doc[]) => {
- (doc instanceof Doc ? [doc] : doc).forEach(Doc.RemFromMyOverlay);
- return true;
- };
+ removeOverlayDoc = (docs: Doc | Doc[]) => toList(docs).every(Doc.RemFromMyOverlay);
- docScreenToLocalXf = computedFn(
- function docScreenToLocalXf(this: any, doc: Doc) {
- return () => new Transform(-NumCast(doc.overlayX), -NumCast(doc.overlayY), 1);
- }.bind(this)
- );
+ docScreenToLocalXf = computedFn((doc: Doc) => () => new Transform(-NumCast(doc.overlayX), -NumCast(doc.overlayY), 1));
@computed get overlayDocs() {
- return Doc.MyOverlayDocs.filter(d => !LightboxView.LightboxDoc || d.type === DocumentType.PRES).map(d => {
- let offsetx = 0,
- offsety = 0;
+ return Doc.MyOverlayDocs.map(d => {
+ let [offsetx, offsety] = [0, 0];
const dref = React.createRef<HTMLDivElement>();
const onPointerMove = action((e: PointerEvent, down: number[]) => {
if (e.cancelBubble) return false; // if the overlay doc processed the move event (e.g., to pan its contents), then the event should be marked as canceled since propagation can't be stopped
@@ -198,9 +194,7 @@ export class OverlayView extends ObservableReactComponent<{}> {
dragData.offset = [-offsetx, -offsety];
dragData.dropAction = dropActionType.move;
dragData.removeDocument = this.removeOverlayDoc;
- dragData.moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => {
- return dragData.removeDocument!(doc) ? addDocument(doc) : false;
- };
+ dragData.moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => (dragData.removeDocument?.(doc) ? addDocument(doc) : false);
DragManager.StartDocumentDrag([dref.current!], dragData, down[0], down[1]);
return true;
}
@@ -227,7 +221,7 @@ export class OverlayView extends ObservableReactComponent<{}> {
PanelHeight={d[Height]}
ScreenToLocalTransform={this.docScreenToLocalXf(d)}
renderDepth={1}
- hideDecorations={true}
+ hideDecorations
isDocumentActive={returnTrue}
isContentActive={returnTrue}
whenChildContentsActiveChanged={emptyFunction}
diff --git a/src/client/views/PinFuncs.ts b/src/client/views/PinFuncs.ts
new file mode 100644
index 000000000..430455644
--- /dev/null
+++ b/src/client/views/PinFuncs.ts
@@ -0,0 +1,139 @@
+import { Doc, DocListCast } from '../../fields/Doc';
+import { DocData } from '../../fields/DocSymbols';
+import { Copy, Id } from '../../fields/FieldSymbols';
+import { List } from '../../fields/List';
+import { ObjectField } from '../../fields/ObjectField';
+import { NumCast, StrCast } from '../../fields/Types';
+import { SerializationHelper } from '../util/SerializationHelper';
+
+export interface MarqueeViewBounds {
+ left: number;
+ top: number;
+ width: number;
+ height: number;
+}
+export interface pinDataTypes {
+ scrollable?: boolean;
+ dataviz?: number[];
+ pannable?: boolean;
+ type_collection?: boolean;
+ inkable?: boolean;
+ filters?: boolean;
+ pivot?: boolean;
+ temporal?: boolean;
+ clippable?: boolean;
+ datarange?: boolean;
+ dataview?: boolean;
+ poslayoutview?: boolean;
+ dataannos?: boolean;
+ map?: boolean;
+}
+export interface PinProps {
+ audioRange?: boolean;
+ activeFrame?: number;
+ currentFrame?: number;
+ hidePresBox?: boolean;
+ pinViewport?: MarqueeViewBounds; // pin a specific viewport on a freeform view (use MarqueeView.CurViewBounds to compute if no region has been selected)
+ pinDocLayout?: boolean; // pin layout info (width/height/x/y)
+ pinAudioPlay?: boolean; // pin audio annotation
+ pinData?: pinDataTypes;
+}
+
+/// copies values from the targetDoc (which is the prototype of the pinDoc) to
+/// reserved fields on the pinDoc so that those values can be restored to the
+/// target doc when navigating to it.
+export function PinDocView(pinDocIn: Doc, pinProps: PinProps, targetDoc: Doc) {
+ const pinDoc = pinDocIn;
+ pinDoc.presentation = true;
+ pinDoc.config = '';
+ if (pinProps.pinDocLayout) {
+ pinDoc.config_pinLayout = true;
+ pinDoc.config_x = NumCast(targetDoc.x);
+ pinDoc.config_y = NumCast(targetDoc.y);
+ pinDoc.config_rotation = NumCast(targetDoc.rotation);
+ pinDoc.config_width = NumCast(targetDoc.width);
+ pinDoc.config_height = NumCast(targetDoc.height);
+ }
+ if (pinProps.pinAudioPlay) pinDoc.presentation_playAudio = true;
+ if (pinProps.pinData) {
+ pinDoc.config_pinData =
+ pinProps.pinData.scrollable ||
+ pinProps.pinData.temporal ||
+ pinProps.pinData.pannable ||
+ pinProps.pinData.type_collection ||
+ pinProps.pinData.clippable ||
+ pinProps.pinData.datarange ||
+ pinProps.pinData.dataview ||
+ pinProps.pinData.poslayoutview ||
+ pinProps?.activeFrame !== undefined;
+ const fkey = Doc.LayoutFieldKey(targetDoc);
+ if (pinProps.pinData.dataview) {
+ pinDoc.config_usePath = targetDoc[fkey + '_usePath'];
+ pinDoc.config_data = targetDoc[fkey] instanceof ObjectField ? (targetDoc[fkey] as ObjectField)[Copy]() : targetDoc.data;
+ }
+ if (pinProps.pinData.dataannos) {
+ const fieldKey = Doc.LayoutFieldKey(targetDoc);
+ pinDoc.config_annotations = new List<Doc>(DocListCast(targetDoc[DocData][fieldKey + '_annotations']).filter(doc => !doc.layout_unrendered));
+ }
+ if (pinProps.pinData.inkable) {
+ pinDoc.config_fillColor = targetDoc.fillColor;
+ pinDoc.config_color = targetDoc.color;
+ pinDoc.config_width = targetDoc._width;
+ pinDoc.config_height = targetDoc._height;
+ }
+ if (pinProps.pinData.scrollable) pinDoc.config_scrollTop = targetDoc._layout_scrollTop;
+ if (pinProps.pinData.clippable) {
+ const fieldKey = Doc.LayoutFieldKey(targetDoc);
+ pinDoc.config_clipWidth = targetDoc[fieldKey + '_clipWidth'];
+ }
+ if (pinProps.pinData.datarange) {
+ pinDoc.config_xRange = undefined; // targetDoc?.xrange;
+ pinDoc.config_yRange = undefined; // targetDoc?.yrange;
+ }
+ if (pinProps.pinData.map) {
+ // pinDoc.config_latitude = targetDoc?.latitude;
+ // pinDoc.config_longitude = targetDoc?.longitude;
+ pinDoc.config_map_zoom = targetDoc?.map_zoom;
+ pinDoc.config_map_type = targetDoc?.map_type;
+ // ...
+ }
+ if (pinProps.pinData.poslayoutview)
+ pinDoc.config_pinLayoutData = new List<string>(
+ DocListCast(targetDoc[fkey] as ObjectField).map(d =>
+ JSON.stringify({
+ id: d[Id],
+ x: NumCast(d.x),
+ y: NumCast(d.y),
+ w: NumCast(d._width),
+ h: NumCast(d._height),
+ fill: StrCast(d._fillColor),
+ back: StrCast(d._backgroundColor),
+ data: SerializationHelper.Serialize(d.data instanceof ObjectField ? d.data[Copy]() : ''),
+ text: SerializationHelper.Serialize(d.text instanceof ObjectField ? d.text[Copy]() : ''),
+ })
+ )
+ );
+ if (pinProps.pinData.type_collection) pinDoc.config_viewType = targetDoc._type_collection;
+ if (pinProps.pinData.filters) pinDoc.config_docFilters = ObjectField.MakeCopy(targetDoc.childFilters as ObjectField);
+ if (pinProps.pinData.pivot) pinDoc.config_pivotField = targetDoc._pivotField;
+ if (pinProps.pinData.pannable) {
+ pinDoc.config_panX = NumCast(targetDoc._freeform_panX);
+ pinDoc.config_panY = NumCast(targetDoc._freeform_panY);
+ pinDoc.config_viewScale = NumCast(targetDoc._freeform_scale, 1);
+ }
+ if (pinProps.pinData.temporal) {
+ pinDoc.config_clipStart = targetDoc._layout_currentTimecode;
+ const duration = NumCast(pinDoc[`${Doc.LayoutFieldKey(pinDoc)}_duration`], NumCast(targetDoc.config_clipStart) + 0.1);
+ pinDoc.config_clipEnd = NumCast(pinDoc.config_clipStart) + NumCast(targetDoc.clipEnd, duration);
+ }
+ }
+ if (pinProps?.pinViewport) {
+ // If pinWithView option set then update scale and x / y props of slide
+ const bounds = pinProps.pinViewport;
+ pinDoc.config_pinView = true;
+ pinDoc.config_viewScale = NumCast(targetDoc._freeform_scale, 1);
+ pinDoc.config_panX = bounds.left + bounds.width / 2;
+ pinDoc.config_panY = bounds.top + bounds.height / 2;
+ pinDoc.config_viewBounds = new List<number>([bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + bounds.height]);
+ }
+}
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index a94c18295..034ade50b 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -1,9 +1,10 @@
import { action, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { lightOrDark, returnFalse } from '../../Utils';
+import { lightOrDark, returnFalse } from '../../ClientUtils';
import { Doc, Opt } from '../../fields/Doc';
-import { DocUtils, Docs, DocumentOptions } from '../documents/Documents';
+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';
@@ -13,12 +14,13 @@ import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
@observer
export class PreviewCursor extends ObservableReactComponent<{}> {
+ // eslint-disable-next-line no-use-before-define
static _instance: PreviewCursor;
public static get Instance() {
return PreviewCursor._instance;
}
- _onKeyPress?: (e: KeyboardEvent) => void;
+ _onKeyDown?: (e: KeyboardEvent) => void;
_getTransform?: () => Transform;
_addDocument?: (doc: Doc | Doc[]) => boolean;
_addLiveTextDoc?: (doc: Doc) => void;
@@ -32,14 +34,16 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
makeObservable(this);
PreviewCursor._instance = this;
this._clickPoint = observable([0, 0]);
- document.addEventListener('keydown', this.onKeyPress);
+ document.addEventListener('keydown', this.onKeyDown);
document.addEventListener('paste', this.paste, true);
}
paste = async (e: ClipboardEvent) => {
if (this.Visible && e.clipboardData) {
const newPoint = this._getTransform?.().transformPoint(this._clickPoint[0], this._clickPoint[1]);
- runInAction(() => (this.Visible = false));
+ runInAction(() => {
+ this.Visible = false;
+ });
// tests for URL and makes web document
const re: any = /^https?:\/\//g;
@@ -88,10 +92,10 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
UndoManager.RunInBatch(() => this._addLiveTextDoc?.(DocUtils.GetNewTextDoc('', newPoint[0], newPoint[1], 500, undefined, undefined)), 'paste');
}
}
- //pasting in images
+ // pasting in images
else if (e.clipboardData.getData('text/html') !== '' && e.clipboardData.getData('text/html').includes('<img src=')) {
- const re: any = /<img src="(.*?)"/g;
- const arr: any[] = re.exec(e.clipboardData.getData('text/html'));
+ const regEx: any = /<img src="(.*?)"/g;
+ const arr: any[] = regEx.exec(e.clipboardData.getData('text/html'));
if (newPoint) {
undoBatch(() => {
@@ -120,9 +124,9 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
};
@action
- onKeyPress = (e: KeyboardEvent) => {
+ onKeyDown = (e: KeyboardEvent) => {
// Mixing events between React and Native is finicky.
- //if not these keys, make a textbox if preview cursor is active!
+ // if not these keys, make a textbox if preview cursor is active!
if (
e.key !== 'Escape' &&
e.key !== 'Backspace' &&
@@ -146,7 +150,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
) {
if ((!e.metaKey && !e.ctrlKey) || (e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 65 && e.keyCode <= 90)) {
// /^[a-zA-Z0-9$*^%#@+-=_|}{[]"':;?/><.,}]$/.test(e.key)) {
- this.Visible && this._onKeyPress?.(e);
+ this.Visible && this._onKeyDown?.(e);
((!e.ctrlKey && !e.metaKey) || e.key !== 'v') && (this.Visible = false);
}
} else if (this.Visible) {
@@ -162,7 +166,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
}
};
- //when focus is lost, this will remove the preview cursor
+ // when focus is lost, this will remove the preview cursor
@action onBlur = (): void => {
this.Visible = false;
};
@@ -171,7 +175,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
public static Show(
x: number,
y: number,
- onKeyPress: (e: KeyboardEvent) => void,
+ onKeyDown: (e: KeyboardEvent) => void,
addLiveText: (doc: Doc) => void,
getTransform: () => Transform,
addDocument: undefined | ((doc: Doc | Doc[]) => boolean),
@@ -181,7 +185,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
const self = PreviewCursor.Instance;
if (self) {
self._clickPoint = [x, y];
- self._onKeyPress = onKeyPress;
+ self._onKeyDown = onKeyDown;
self._addLiveTextDoc = addLiveText;
self._getTransform = getTransform;
self._addDocument = addDocument || returnFalse;
@@ -192,6 +196,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
}
render() {
return !this._clickPoint || !this.Visible ? null : (
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
<div className="previewCursor" onBlur={this.onBlur} tabIndex={0} ref={e => e?.focus()} style={{ color: lightOrDark(this.Doc?.backgroundColor ?? 'white'), transform: `translate(${this._clickPoint[0]}px, ${this._clickPoint[1]}px)` }}>
I
</div>
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 02f288a68..edf6df2b9 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -1,3 +1,6 @@
+/* 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';
import { action, computed, observable } from 'mobx';
@@ -12,98 +15,47 @@ import { MdClosedCaption, MdClosedCaptionDisabled, MdGridOff, MdGridOn, MdSubtit
import { RxWidth } from 'react-icons/rx';
import { TbEditCircle, TbEditCircleOff, TbHandOff, TbHandStop, TbHighlight, TbHighlightOff } from 'react-icons/tb';
import { TfiBarChart } from 'react-icons/tfi';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { Doc, Opt } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, ScriptCast } from '../../fields/Types';
import { ImageField } from '../../fields/URLField';
+import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
-import { DocUtils } from '../documents/Documents';
-import { IsFollowLinkScript } from '../util/LinkFollower';
-import { LinkManager } from '../util/LinkManager';
-import { SelectionManager } from '../util/SelectionManager';
import { SettingsManager } from '../util/SettingsManager';
import { undoBatch, undoable } from '../util/UndoManager';
import { InkingStroke } from './InkingStroke';
import './PropertiesButtons.scss';
import { Colors } from './global/globalEnums';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
@observer
export class PropertiesButtons extends React.Component<{}, {}> {
+ // eslint-disable-next-line no-use-before-define
@observable public static Instance: PropertiesButtons;
@computed get selectedDoc() {
- return SelectionManager.SelectedSchemaDoc || SelectionManager.Views.lastElement()?.Document;
+ return DocumentView.SelectedSchemaDoc() || DocumentView.Selected().lastElement()?.Document;
}
@computed get selectedLayoutDoc() {
- return SelectionManager.SelectedSchemaDoc || SelectionManager.Views.lastElement()?.layoutDoc;
+ return DocumentView.SelectedSchemaDoc() || DocumentView.Selected().lastElement()?.layoutDoc;
}
@computed get selectedTabView() {
- return !SelectionManager.SelectedSchemaDoc && SelectionManager.Views.lastElement()?.topMost;
- }
-
- propertyToggleBtn = (label: (on?: any) => string, property: string, tooltip: (on?: any) => string, icon: (on?: any) => any, onClick?: (dv: Opt<DocumentView>, doc: Doc, property: string) => void, useUserDoc?: boolean) => {
- const targetDoc = useUserDoc ? Doc.UserDoc() : this.selectedLayoutDoc;
- const onPropToggle = (dv: Opt<DocumentView>, doc: Doc, prop: string) => ((dv?.layoutDoc || doc)[prop] = (dv?.layoutDoc || doc)[prop] ? false : true);
- return !targetDoc ? null : (
- <Toggle
- toggleStatus={BoolCast(targetDoc[property])}
- tooltip={tooltip(BoolCast(targetDoc[property]))}
- text={label(targetDoc?.[property])}
- color={SettingsManager.userColor}
- icon={icon(targetDoc?.[property] as any)}
- iconPlacement="left"
- align="flex-start"
- fillWidth={true}
- toggleType={ToggleType.BUTTON}
- onClick={undoable(() => {
- if (SelectionManager.Views.length > 1) {
- SelectionManager.Views.forEach(dv => (onClick ?? onPropToggle)(dv, dv.Document, property));
- } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property);
- }, property)}
- />
- );
- };
-
- // this implments a container pattern by marking the targetDoc (collection) as a lightbox
- // that always fits its contents to its container and that hides all other documents when
- // a link is followed that targets a 'lightbox' destination
- @computed get isLightboxButton() {
- return this.propertyToggleBtn(
- on => 'Lightbox',
- 'isLightbox',
- on => `${on ? 'Set' : 'Remove'} lightbox flag`,
- on => 'window-restore',
- onClick => {
- SelectionManager.Views.forEach(dv => {
- const containerDoc = dv.Document;
- //containerDoc.followAllLinks =
- // containerDoc.noShadow =
- // containerDoc.layout_disableBrushing =
- // containerDoc._forceActive =
- //containerDoc._freeform_fitContentsToBox =
- containerDoc._isLightbox = !containerDoc._isLightbox;
- //containerDoc._xPadding = containerDoc._yPadding = containerDoc._isLightbox ? 10 : undefined;
- const containerContents = DocListCast(dv.dataDoc[Doc.LayoutFieldKey(containerDoc)]);
- //dv.Docuemnt.onClick = ScriptField.MakeScript('{self.data = undefined; documentView.select(false)}', { documentView: 'any' });
- containerContents.forEach(doc => LinkManager.Links(doc).forEach(link => (link.link_displayLine = false)));
- });
- }
- );
+ return !DocumentView.SelectedSchemaDoc() && DocumentView.Selected().lastElement()?.topMost;
}
@computed get titleButton() {
return this.propertyToggleBtn(
- on => (!on ? 'SHOW TITLE' : this.selectedDoc?.['_layout_showTitle'] === 'title:hover' ? 'HIDE TITLE' : 'HOVER TITLE'),
+ on => (!on ? 'SHOW TITLE' : this.selectedDoc?._layout_showTitle === 'title:hover' ? 'HIDE TITLE' : 'HOVER TITLE'),
'_layout_showTitle',
- on => 'Switch between title styles',
+ () => 'Switch between title styles',
on => (on ? <MdSubtitlesOff /> : <MdSubtitles />), // {currentIcon}, //(on ? <MdSubtitles/> :) , //,'text-width', on ? <MdSubtitles/> : <MdSubtitlesOff/>,
(dv, doc) => {
const tdoc = dv?.Document || doc;
const newtitle = !tdoc._layout_showTitle ? 'title' : tdoc._layout_showTitle === 'title' ? 'title:hover' : '';
- tdoc._layout_showTitle = newtitle ? newtitle : undefined;
+ tdoc._layout_showTitle = newtitle || undefined;
}
);
}
@@ -119,7 +71,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
}
@computed get maskButton() {
- //highlight text while going down and reading through
+ // highlight text while going down and reading through
return this.propertyToggleBtn(
on => (on ? 'PLAIN INK' : 'HIGHLIGHTER MASK'),
'stroke_isInkMask',
@@ -132,10 +84,10 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed get hideImageButton() {
// put in developer -- can trace on top of object and drawing is still there
return this.propertyToggleBtn(
- on => (on ? 'SHOW BACKGROUND IMAGE' : 'HIDE BACKGROUND IMAGE'), //'Background',
+ on => (on ? 'SHOW BACKGROUND IMAGE' : 'HIDE BACKGROUND IMAGE'), // 'Background',
'_hideImage',
on => (on ? 'Show Image' : 'Show Background'),
- on => (on ? <BiShow /> : <BiHide />) //'portrait'
+ on => (on ? <BiShow /> : <BiHide />) // 'portrait'
);
}
@@ -144,35 +96,35 @@ export class PropertiesButtons extends React.Component<{}, {}> {
on => (on ? 'DISABLE CLUSTERS' : 'HIGHLIGHT CLUSTERS'),
'_freeform_useClusters',
on => `${on ? 'Hide' : 'Show'} clusters`,
- on => <FaBraille />
+ () => <FaBraille />
);
}
@computed get panButton() {
return this.propertyToggleBtn(
- on => (on ? 'ENABLE PANNING' : 'DISABLE PANNING'), //'Lock\xA0View',
+ on => (on ? 'ENABLE PANNING' : 'DISABLE PANNING'), // 'Lock\xA0View',
'_lockedTransform',
on => `${on ? 'Unlock' : 'Lock'} panning of view`,
- on => (on ? <TbHandStop /> : <TbHandOff />) //'lock'
+ on => (on ? <TbHandStop /> : <TbHandOff />) // 'lock'
);
}
@computed get forceActiveButton() {
- //select text
+ // select text
return this.propertyToggleBtn(
on => (on ? 'SELECT TO INTERACT' : 'ALWAYS INTERACTIVE'),
'_forceActive',
on => `${on ? 'Document must be selected to interact with its contents' : 'Contents always active (respond to click/drag events)'} `,
- on => <MdTouchApp /> // 'eye'
+ () => <MdTouchApp /> // 'eye'
);
}
@computed get verticalAlignButton() {
- //select text
+ // select text
return this.propertyToggleBtn(
on => (on ? 'ALIGN TOP' : 'ALIGN CENTER'),
'_layout_centered',
on => `${on ? 'Text is aligned with top of document' : 'Text is aligned with center of document'} `,
- on => <MdTouchApp /> // 'eye'
+ () => <MdTouchApp /> // 'eye'
);
}
@@ -181,9 +133,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
on => (on ? 'DISABLE FLASHCARD' : 'ENABLE FLASHCARD'),
'layout_textPainted',
on => `${on ? 'Flashcard enabled' : 'Flashcard disabled'} `,
- on => <MdTouchApp />,
+ () => <MdTouchApp />,
(dv, doc) => {
- const on = doc.onPaint ? true : false;
+ const on = !!doc.onPaint;
doc[DocData].onPaint = on ? undefined : ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, { documentView: 'any' });
doc[DocData].layout_textPainted = on ? undefined : `<ComparisonBox {...props} fieldKey={'${dv?.LayoutFieldKey ?? 'text'}'}/>`;
}
@@ -192,10 +144,10 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed get fitContentButton() {
return this.propertyToggleBtn(
- on => (on ? 'PREVIOUS VIEW' : 'VIEW ALL'), //'View All',
+ on => (on ? 'PREVIOUS VIEW' : 'VIEW ALL'), // 'View All',
'_freeform_fitContentsToBox',
on => `${on ? "Don't" : 'Do'} fit content to container visible area`,
- on => (on ? <CiGrid31 /> : <BsGrid3X3GapFill />) //'object-group'
+ on => (on ? <CiGrid31 /> : <BsGrid3X3GapFill />) // 'object-group'
);
}
@@ -209,7 +161,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
// on => `${on ? 'Set' : 'Remove'} lightbox flag`,
// on => 'window-restore',
// onClick => {
- // SelectionManager.Views.forEach(dv => {
+ // DocumentView.Selected().forEach(dv => {
// const containerDoc = dv.Document;
// //containerDoc.followAllLinks =
// // containerDoc.noShadow =
@@ -219,7 +171,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
// containerDoc._isLightbox = !containerDoc._isLightbox;
// //containerDoc._xPadding = containerDoc._yPadding = containerDoc._isLightbox ? 10 : undefined;
// const containerContents = DocListCast(dv.dataDoc[dv.props.fieldKey ?? Doc.LayoutFieldKey(containerDoc)]);
- // //dv.Document.onClick = ScriptField.MakeScript('{self.data = undefined; documentView.select(false)}', { documentView: 'any' });
+ // //dv.Document.onClick = ScriptField.MakeScript('{this.data = undefined; documentView.select(false)}', { documentView: 'any' });
// containerContents.forEach(doc => LinkManager.Links(doc).forEach(link => (link.layout_linkDisplay = false)));
// });
// }
@@ -228,7 +180,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed get layout_fitWidthButton() {
return this.propertyToggleBtn(
- on => (on ? 'SCALED VIEW' : 'READING VIEW'), //'Fit\xA0Width',
+ on => (on ? 'SCALED VIEW' : 'READING VIEW'), // 'Fit\xA0Width',
'_layout_fitWidth',
on =>
on
@@ -240,12 +192,14 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed get captionButton() {
return this.propertyToggleBtn(
- //DEVELOPER
- on => (on ? 'HIDE CAPTION' : 'SHOW CAPTION'), //'Caption',
+ // DEVELOPER
+ on => (on ? 'HIDE CAPTION' : 'SHOW CAPTION'), // 'Caption',
'_layout_showCaption',
on => `${on ? 'Hide' : 'Show'} caption footer`,
- on => (on ? <MdClosedCaptionDisabled /> : <MdClosedCaption />), //'closed-captioning',
- (dv, doc) => ((dv?.Document || doc)._layout_showCaption = (dv?.Document || doc)._layout_showCaption === undefined ? 'caption' : undefined)
+ on => (on ? <MdClosedCaptionDisabled /> : <MdClosedCaption />), // 'closed-captioning',
+ (dv, doc) => {
+ (dv?.Document || doc)._layout_showCaption = (dv?.Document || doc)._layout_showCaption === undefined ? 'caption' : undefined;
+ }
);
}
@@ -256,7 +210,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
'_chromeHidden',
on => `${on ? 'Show' : 'Hide'} editing UI`,
on => (on ? <TbEditCircle /> : <TbEditCircleOff />), // 'edit',
- (dv, doc) => ((dv?.Document || doc)._chromeHidden = !(dv?.Document || doc)._chromeHidden)
+ (dv, doc) => {
+ (dv?.Document || doc)._chromeHidden = !(dv?.Document || doc)._chromeHidden;
+ }
);
}
@@ -265,8 +221,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
return this.propertyToggleBtn(
on => (on ? 'AUTO\xA0SIZE' : 'FIXED SIZE'),
'_layout_autoHeight',
- on => `Automatical vertical sizing to show all content`,
- on => <FontAwesomeIcon icon="arrows-alt-v" size="lg" />
+ () => `Automatical vertical sizing to show all content`,
+ () => <FontAwesomeIcon icon="arrows-alt-v" size="lg" />
);
}
@@ -274,8 +230,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
return this.propertyToggleBtn(
on => (on ? 'HIDE GRID' : 'DISPLAY GRID'),
'_freeform_backgroundGrid',
- on => `Display background grid in collection`,
- on => (on ? <MdGridOff /> : <MdGridOn />) //'border-all'
+ () => `Display background grid in collection`,
+ on => (on ? <MdGridOff /> : <MdGridOn />) // 'border-all'
);
}
@@ -317,8 +273,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
return this.propertyToggleBtn(
on => (on ? 'HIDE SNAP LINES' : 'SHOW SNAP LINES'),
'freeform_snapLines',
- on => `Display snapping lines when objects are dragged`,
- on => <TfiBarChart />, //'th',
+ () => `Display snapping lines when objects are dragged`,
+ () => <TfiBarChart />, // 'th',
undefined
);
}
@@ -361,18 +317,20 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@undoBatch
handlePerspectiveChange = (e: any) => {
this.selectedDoc && (this.selectedDoc._type_collection = e.target.value);
- SelectionManager.Views.forEach(docView => (docView.layoutDoc._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;
- const linkedToLightboxView = () => LinkManager.Links(this.selectedDoc).some(link => LinkManager.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
+ const linkedToLightboxView = () => Doc.Links(this.selectedDoc).some(link => Doc.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
if (followLoc === OpenWhere.lightbox && !linkedToLightboxView()) return 'linkInPlace';
- else if (linkButton && followLoc === OpenWhere.addRight) return 'linkOnRight';
- else if (linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView()) return 'enterPortal';
- else if (ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail')) return 'toggleDetail';
- else return 'nothing';
+ if (linkButton && followLoc === OpenWhere.addRight) return 'linkOnRight';
+ if (linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView()) return 'enterPortal';
+ if (ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail')) return 'toggleDetail';
+ return 'nothing';
}
@computed
@@ -385,20 +343,18 @@ export class PropertiesButtons extends React.Component<{}, {}> {
['linkOnRight', 'Open Link on Right'],
];
- const items: IListItemProps[] = buttonList.map(value => {
- return {
- text: value[1],
- val: value[1],
- };
- });
+ const items: IListItemProps[] = buttonList.map(value => ({
+ text: value[1],
+ val: value[1],
+ }));
return !this.selectedDoc ? null : (
<Dropdown
- tooltip={'Choose onClick behavior'}
+ tooltip="Choose onClick behavior"
items={items}
- closeOnSelect={true}
+ closeOnSelect
selectedVal={this.onClickVal}
setSelectedVal={val => this.handleOptionChange(val as string)}
- title={'Choose onClick behaviour'}
+ title="Choose onClick behaviour"
color={SettingsManager.userColor}
dropdownType={DropdownType.SELECT}
type={Type.SEC}
@@ -422,7 +378,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@undoBatch
@action
handleOptionChange = (onClick: string) => {
- SelectionManager.Views.forEach(docView => {
+ DocumentView.Selected().forEach(docView => {
const linkButton = IsFollowLinkScript(docView.Document.onClick);
docView.noOnClick();
switch (onClick) {
@@ -440,16 +396,11 @@ export class PropertiesButtons extends React.Component<{}, {}> {
docView.toggleFollowLink(false, false);
docView.Document.followLinkLocation = linkButton ? OpenWhere.addRight : undefined;
break;
+ default:
}
});
};
- @undoBatch
- editOnClickScript = () => {
- if (SelectionManager.Views.length) SelectionManager.Views.forEach(dv => DocUtils.makeCustomViewClicked(dv.Document, undefined, 'onClick'));
- else this.selectedDoc && DocUtils.makeCustomViewClicked(this.selectedDoc, undefined, 'onClick');
- };
-
@computed
get onClickFlyout() {
const buttonList = [
@@ -463,7 +414,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
const click = () => this.handleOptionChange(value[0]);
const linkButton = IsFollowLinkScript(this.selectedDoc.onClick);
const followLoc = this.selectedDoc._followLinkLocation;
- const linkedToLightboxView = () => LinkManager.Links(this.selectedDoc).some(link => LinkManager.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
+ const linkedToLightboxView = () => Doc.Links(this.selectedDoc).some(link => Doc.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
let active = false;
// prettier-ignore
@@ -473,6 +424,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
case 'enterPortal': active = linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView(); break;
case 'toggleDetail':active = ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail'); break;
case 'nothing': active = !linkButton && this.selectedDoc.onClick === undefined;break;
+ default:
}
return (
<div className="list-item" key={`${value}`} style={{ backgroundColor: active ? Colors.LIGHT_BLUE : undefined }} onClick={click}>
@@ -494,10 +446,40 @@ export class PropertiesButtons extends React.Component<{}, {}> {
</div>
);
}
+ @undoBatch
+ editOnClickScript = () => {
+ if (DocumentView.Selected().length) DocumentView.Selected().forEach(dv => DocUtils.makeCustomViewClicked(dv.Document, undefined, 'onClick'));
+ 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<DocumentView>, doc: Doc, property: string) => void, useUserDoc?: boolean) => {
+ const targetDoc = useUserDoc ? Doc.UserDoc() : this.selectedLayoutDoc;
+ const onPropToggle = (dv: Opt<DocumentView>, doc: Doc, prop: string) => {
+ (dv?.layoutDoc || doc)[prop] = !(dv?.layoutDoc || doc)[prop];
+ };
+ return !targetDoc ? null : (
+ <Toggle
+ toggleStatus={BoolCast(targetDoc[property])}
+ tooltip={tooltip(BoolCast(targetDoc[property]))}
+ text={label(targetDoc?.[property])}
+ color={SettingsManager.userColor}
+ icon={icon(targetDoc?.[property] as any)}
+ iconPlacement="left"
+ align="flex-start"
+ fillWidth
+ toggleType={ToggleType.BUTTON}
+ onClick={undoable(() => {
+ if (DocumentView.Selected().length > 1) {
+ DocumentView.Selected().forEach(dv => (onClick ?? onPropToggle)(dv, dv.Document, property));
+ } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property);
+ }, property)}
+ />
+ );
+ };
render() {
const layoutField = this.selectedDoc?.[Doc.LayoutFieldKey(this.selectedDoc)];
- const isText = SelectionManager.Views.lastElement()?.ComponentView instanceof FormattedTextBox;
+ const isText = DocumentView.Selected().lastElement()?.ComponentView instanceof FormattedTextBox;
const isInk = this.selectedDoc?.layout_isSvg;
const isImage = layoutField instanceof ImageField;
const isMap = this.selectedDoc?.type === DocumentType.MAP;
@@ -505,11 +487,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
const isStacking = [CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.NoteTaking].includes(this.selectedDoc?._type_collection as any);
const isFreeForm = this.selectedDoc?._type_collection === CollectionViewType.Freeform;
const isTree = this.selectedDoc?._type_collection === CollectionViewType.Tree;
- const isTabView = this.selectedTabView;
const toggle = (ele: JSX.Element | null, style?: React.CSSProperties) => (
<div className="propertiesButtons-button" style={style}>
- {' '}
- {ele}{' '}
+ {ele}
</div>
);
const isNovice = Doc.noviceMode;
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx
index cf5105efc..edb55f341 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.tsx
+++ b/src/client/views/PropertiesDocBacklinksSelector.tsx
@@ -1,3 +1,5 @@
+/* eslint-disable react/require-default-props */
+/* eslint-disable react/no-unused-prop-types */
import { action } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -5,12 +7,12 @@ import { Doc } from '../../fields/Doc';
import { Cast } from '../../fields/Types';
import { DocumentType } from '../documents/DocumentTypes';
import { LinkManager } from '../util/LinkManager';
-import { SelectionManager } from '../util/SelectionManager';
import { SettingsManager } from '../util/SettingsManager';
import './PropertiesDocBacklinksSelector.scss';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { LinkMenu } from './linking/LinkMenu';
-import { OpenWhere } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
+import { DocumentView } from './nodes/DocumentView';
type PropertiesDocBacklinksSelectorProps = {
Document: Doc;
@@ -23,7 +25,7 @@ type PropertiesDocBacklinksSelectorProps = {
export class PropertiesDocBacklinksSelector extends React.Component<PropertiesDocBacklinksSelectorProps> {
getOnClick = action((link: Doc) => {
const linkAnchor = this.props.Document;
- const other = LinkManager.getOppositeAnchor(link, linkAnchor);
+ const other = Doc.getOppositeAnchor(link, linkAnchor);
const otherdoc = !other ? undefined : other.annotationOn && other.type !== DocumentType.RTF ? Cast(other.annotationOn, Doc, null) : other;
LinkManager.Instance.currentLink = link;
if (otherdoc) {
@@ -34,10 +36,10 @@ export class PropertiesDocBacklinksSelector extends React.Component<PropertiesDo
});
render() {
- return !SelectionManager.Views.length ? null : (
+ return !DocumentView.Selected().length ? null : (
<div className="propertiesDocBacklinksSelector" style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}>
{this.props.hideTitle ? null : <p key="contexts">Contexts:</p>}
- <LinkMenu docView={SelectionManager.Views.lastElement()} clearLinkEditor={undefined} itemHandler={this.getOnClick} style={{ left: 0, top: 0 }} />
+ <LinkMenu docView={DocumentView.Selected().lastElement()} clearLinkEditor={undefined} itemHandler={this.getOnClick} style={{ left: 0, top: 0 }} />
</div>
);
}
diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx
index b8bbde9de..1fea36d16 100644
--- a/src/client/views/PropertiesDocContextSelector.tsx
+++ b/src/client/views/PropertiesDocContextSelector.tsx
@@ -1,14 +1,17 @@
+/* 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';
-import { Doc, DocListCast } from '../../fields/Doc';
+import { Doc } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { Cast, StrCast } from '../../fields/Types';
-import { DocFocusOrOpen } from '../util/DocumentManager';
import { ObservableReactComponent } from './ObservableReactComponent';
import './PropertiesDocContextSelector.scss';
import { CollectionDockingView } from './collections/CollectionDockingView';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
type PropertiesDocContextSelectorProps = {
DocView?: DocumentView;
@@ -52,10 +55,10 @@ export class PropertiesDocContextSelector extends ObservableReactComponent<Prope
.map(doc => ({ col: doc, target }));
}
- getOnClick = (col: Doc, target: Doc) => {
+ getOnClick = (clickCol: Doc) => {
if (!this._props.DocView) return;
- col = Doc.IsDataProto(col) ? Doc.MakeDelegate(col) : col;
- DocFocusOrOpen(Doc.GetProto(this._props.DocView.Document), undefined, col);
+ const col = Doc.IsDataProto(clickCol) ? Doc.MakeDelegate(clickCol) : clickCol;
+ DocumentView.FocusOrOpen(Doc.GetProto(this._props.DocView.Document), undefined, col);
};
render() {
@@ -65,7 +68,7 @@ export class PropertiesDocContextSelector extends ObservableReactComponent<Prope
{this._props.hideTitle ? null : <p key="contexts">Contexts:</p>}
{this._docs.map(doc => (
<p key={doc.col[Id] + doc.target[Id]}>
- <a onClick={() => this.getOnClick(doc.col, doc.target)}>{StrCast(doc.col.title)}</a>
+ <a onClick={() => this.getOnClick(doc.col)}>{StrCast(doc.col.title)}</a>
</p>
))}
</div>
diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx
index 3c9fa1123..b9a587719 100644
--- a/src/client/views/PropertiesSection.tsx
+++ b/src/client/views/PropertiesSection.tsx
@@ -1,5 +1,8 @@
+/* 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, observable } from 'mobx';
+import { action, computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { SettingsManager } from '../util/SettingsManager';
@@ -10,8 +13,6 @@ export interface PropertiesSectionProps {
children?: JSX.Element | string | null;
isOpen: boolean;
setIsOpen: (bool: boolean) => any;
- inSection?: boolean;
- setInSection?: (bool: boolean) => any;
onDoubleClick?: () => void;
}
@@ -21,44 +22,35 @@ export class PropertiesSection extends React.Component<PropertiesSectionProps> {
return SettingsManager.userColor;
}
- @computed get backgroundColor() {
- return SettingsManager.userBackgroundColor;
- }
-
@computed get variantColor() {
return SettingsManager.userVariantColor;
}
- @observable isDouble: boolean = false;
-
render() {
if (this.props.children === undefined || this.props.children === null) return null;
- else
- return (
- <div className="propertiesView-section" onPointerEnter={action(() => this.props.setInSection && this.props.setInSection(true))} onPointerLeave={action(() => this.props.setInSection && this.props.setInSection(false))}>
- <div
- className="propertiesView-sectionTitle"
- onDoubleClick={action(e => {
- this.isDouble = true;
- this.props.onDoubleClick && this.props.onDoubleClick();
- this.props.setIsOpen(true);
- setTimeout(() => (this.isDouble = false), 300);
- })}
- onClick={action(e => {
- this.props.setIsOpen(!this.props.isOpen);
- })}
- style={{
- background: this.variantColor,
- // this.props.isOpen ? this.variantColor : this.backgroundColor,
- color: this.color,
- }}>
- {this.props.title}
- <div className="propertiesView-sectionTitle-icon">
- <FontAwesomeIcon icon={this.props.isOpen ? 'caret-down' : 'caret-right'} size="lg" />
- </div>
+ return (
+ <div className="propertiesView-section">
+ <div
+ className="propertiesView-sectionTitle"
+ onDoubleClick={action(() => {
+ this.props.onDoubleClick && this.props.onDoubleClick();
+ this.props.setIsOpen(true);
+ })}
+ onClick={action(() => {
+ this.props.setIsOpen(!this.props.isOpen);
+ })}
+ style={{
+ background: this.variantColor,
+ // this.props.isOpen ? this.variantColor : this.backgroundColor,
+ color: this.color,
+ }}>
+ {this.props.title}
+ <div className="propertiesView-sectionTitle-icon">
+ <FontAwesomeIcon icon={this.props.isOpen ? 'caret-down' : 'caret-right'} size="lg" />
</div>
- {!this.props.isOpen ? null : <div className="propertiesView-content">{this.props.children}</div>}
</div>
- );
+ {!this.props.isOpen ? null : <div className="propertiesView-content">{this.props.children}</div>}
+ </div>
+ );
}
}
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index 8581bdf73..840df41e7 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -7,6 +7,21 @@
position: absolute;
right: 4;
}
+.propertiesView-palette {
+ cursor: pointer;
+ padding: 8px;
+ border-radius: 4px;
+ transition: all 0.2s ease;
+ &:hover {
+ background-color: #3b3c3e;
+ }
+}
+.styling-chatbox {
+ color: #000000;
+ width: 100%;
+ outline: none;
+ border: none;
+}
.propertiesView {
height: 100%;
width: 250;
@@ -227,14 +242,15 @@
font-weight: bold;
width: 95px;
overflow-x: hidden;
- display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
+ display: flex;
+ align-items: center;
}
.propertiesView-sharingTable-item-permission {
display: flex;
- align-items: flex-end;
+ align-items: center;
text-align: right;
margin-left: auto;
margin-right: -12px;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index cbd3ff358..024db82a4 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -1,3 +1,6 @@
+/* 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 { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -8,9 +11,10 @@ import { IReactionDisposer, action, computed, makeObservable, observable, reacti
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 { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
-import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
+import * as Icons from 'react-icons/bs'; // {BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs"
+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';
import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { InkField } from '../../fields/InkField';
@@ -19,12 +23,10 @@ import { ComputedField } from '../../fields/ScriptField';
import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { GetEffectiveAcl, SharingPermissions, normalizeEmail } from '../../fields/util';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
-import { DocumentManager } from '../util/DocumentManager';
import { GroupManager } from '../util/GroupManager';
import { LinkManager } from '../util/LinkManager';
-import { SelectionManager } from '../util/SelectionManager';
-import { SettingsManager } from '../util/SettingsManager';
import { SharingManager } from '../util/SharingManager';
+import { SnappingManager } from '../util/SnappingManager';
import { Transform } from '../util/Transform';
import { UndoManager, undoBatch, undoable } from '../util/UndoManager';
import { EditableView } from './EditableView';
@@ -36,12 +38,12 @@ import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector
import { PropertiesDocContextSelector } from './PropertiesDocContextSelector';
import { PropertiesSection } from './PropertiesSection';
import './PropertiesView.scss';
-import { DefaultStyleProvider } from './StyleProvider';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
+import { DefaultStyleProvider, SetFilterOpener as SetPropertiesFilterOpener } from './StyleProvider';
+import { DocumentView } from './nodes/DocumentView';
import { StyleProviderFuncType } from './nodes/FieldView';
-import { KeyValueBox } from './nodes/KeyValueBox';
+import { OpenWhere } from './nodes/OpenWhere';
import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
-import { LinkBox } from './nodes/LinkBox';
+
const _global = (window /* browser */ || global) /* node */ as any;
interface PropertiesViewProps {
@@ -55,11 +57,18 @@ interface PropertiesViewProps {
export class PropertiesView extends ObservableReactComponent<PropertiesViewProps> {
private _widthUndo?: UndoManager.Batch;
+ // eslint-disable-next-line no-use-before-define
public static Instance: PropertiesView | undefined;
constructor(props: any) {
super(props);
makeObservable(this);
PropertiesView.Instance = this;
+ SetPropertiesFilterOpener(
+ action(() => {
+ this.CloseAll();
+ this.openFilters = true;
+ })
+ );
}
@computed get MAX_EMBED_HEIGHT() {
@@ -67,20 +76,18 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
}
@computed get selectedDoc() {
- return SelectionManager.SelectedSchemaDoc || this.selectedDocumentView?.Document || Doc.ActiveDashboard;
+ return DocumentView.SelectedSchemaDoc() || this.selectedDocumentView?.Document || Doc.ActiveDashboard;
}
@computed get selectedLink() {
- return this.selectedDocumentView?.ComponentView instanceof LinkBox ? this.selectedDocumentView.Document : LinkManager.Instance.currentLink;
+ return LinkManager.Instance.currentLink;
}
@computed get selectedLayoutDoc() {
- return SelectionManager.SelectedSchemaDoc || this.selectedDocumentView?.layoutDoc || Doc.ActiveDashboard;
+ return DocumentView.SelectedSchemaDoc() || this.selectedDocumentView?.layoutDoc || Doc.ActiveDashboard;
}
@computed get selectedDocumentView() {
- if (SelectionManager.Views.length) return SelectionManager.Views[0];
- if (PresBox.Instance?.selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.Document);
- return undefined;
+ return DocumentView.Selected().lastElement();
}
@computed get isPres(): boolean {
return this.selectedDoc?.type === DocumentType.PRES;
@@ -101,15 +108,15 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@observable openAppearance: boolean = true;
@observable openTransform: boolean = true;
@observable openFilters: boolean = false;
+ @observable openStyling: boolean = true;
- //Pres Trails booleans:
+ // Pres Trails booleans:
@observable openPresTransitions: boolean = true;
@observable openPresProgressivize: boolean = false;
@observable openPresVisibilityAndDuration: boolean = false;
@observable openAddSlide: boolean = false;
@observable openSlideOptions: boolean = false;
- @observable inOptions: boolean = false;
@observable _controlButton: boolean = false;
private _disposers: { [name: string]: IReactionDisposer } = {};
@@ -177,42 +184,47 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
const rows: JSX.Element[] = [];
if (this.dataDoc && this.selectedDoc) {
const ids = new Set<string>(reqdKeys);
- const docs: Doc[] = SelectionManager.Views.length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : SelectionManager.Views.map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc));
+ const docs: Doc[] =
+ DocumentView.Selected().length < 2 //
+ ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc]
+ : DocumentView.Selected().map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc));
docs.forEach(doc =>
Object.keys(doc)
.filter(filter)
.forEach(key => doc[key] !== ComputedField.undefined && key && ids.add(key))
);
- // prettier-ignore
- Array.from(ids).sort().map(key => {
- const multiple = Array.from(docs.reduce((set,doc) => set.add(doc[key]), new Set<FieldResult>()).keys()).length > 1;
- const editableContents = multiple ? '-multiple-' : Field.toKeyValueString(docs[0], key);
- const displayContents = multiple ? '-multiple-' : Field.toString(docs[0][key] as Field);
- const contentElement = (
- <EditableView
- key="editableView"
- contents={displayContents}
- height={13}
- fontSize={10}
- GetValue={() => editableContents}
- SetValue={(value: string) => {
- value !== '-multiple-' && docs.map(doc => KeyValueBox.SetField(doc, key, value, true));
- return true;
- }}
- />);
- rows.push(
- <div style={{ display: 'flex', overflowY: 'visible', marginBottom: '-1px' }} key={key}>
- <span style={{ fontWeight: 'bold', whiteSpace: 'nowrap' }}>{key + ':'}</span>
- &nbsp;
- {contentElement}
- </div>
- );
- });
+ Array.from(ids)
+ .sort()
+ .forEach(key => {
+ const multiple = Array.from(docs.reduce((set, doc) => set.add(doc[key]), new Set<FieldResult>()).keys()).length > 1;
+ const editableContents = multiple ? '-multiple-' : Field.toKeyValueString(docs[0], key);
+ const displayContents = multiple ? '-multiple-' : Field.toString(docs[0][key] as FieldType);
+ const contentElement = (
+ <EditableView
+ key="editableView"
+ contents={displayContents}
+ height={13}
+ fontSize={10}
+ GetValue={() => editableContents}
+ SetValue={(value: string) => {
+ value !== '-multiple-' && docs.map(doc => Doc.SetField(doc, key, value, true));
+ return true;
+ }}
+ />
+ );
+ rows.push(
+ <div style={{ display: 'flex', overflowY: 'visible', marginBottom: '-1px' }} key={key}>
+ <span style={{ fontWeight: 'bold', whiteSpace: 'nowrap' }}>{key + ':'}</span>
+ &nbsp;
+ {contentElement}
+ </div>
+ );
+ });
rows.push(
- <div className="propertiesView-field" key="newKeyValue" style={{ marginTop: '3px', backgroundColor: SettingsManager.userBackgroundColor, textAlign: 'center' }}>
- <EditableView key="editableView" oneLine contents={'add key:value or #tags'} height={13} fontSize={10} GetValue={() => ''} SetValue={this.setKeyValue} />
+ <div className="propertiesView-field" key="newKeyValue" style={{ marginTop: '3px', backgroundColor: SnappingManager.userBackgroundColor, textAlign: 'center' }}>
+ <EditableView key="editableView" oneLine contents="add key:value or #tags" height={13} fontSize={10} GetValue={returnEmptyString} SetValue={this.setKeyValue} />
</div>
);
}
@@ -225,23 +237,29 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get noviceFields() {
const noviceReqFields = ['author', 'author_date', 'tags', '_layout_curPage'];
- return this.editableFields(key => key.indexOf('modificationDate') !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith('acl')), noviceReqFields);
+ return this.editableFields(key => key.indexOf('modificationDate') !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith('acl_')), noviceReqFields);
}
@undoBatch
setKeyValue = (value: string) => {
- const docs = SelectionManager.Views.length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc!] : SelectionManager.Views.map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc));
+ const docs =
+ DocumentView.Selected().length < 2 && this.selectedDoc
+ ? [this.layoutFields
+ ? Doc.Layout(this.selectedDoc) //
+ : this.dataDoc!]
+ : DocumentView.Selected().map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc)); // prettier-ignore
docs.forEach(doc => {
if (value.indexOf(':') !== -1) {
const newVal = value[0].toUpperCase() + value.substring(1, value.length);
const splits = newVal.split(':');
- KeyValueBox.SetField(doc, splits[0], splits[1], true);
+ Doc.SetField(doc, splits[0], splits[1], true);
const tags = StrCast(doc.tags, ':');
if (tags.includes(`${splits[0]}:`) && splits[1] === 'undefined') {
- KeyValueBox.SetField(doc, 'tags', `"${tags.replace(splits[0] + ':', '')}"`, true);
+ Doc.SetField(doc, 'tags', `"${tags.replace(splits[0] + ':', '')}"`, true);
}
return true;
- } else if (value[0] === '#') {
+ }
+ if (value[0] === '#') {
const tags = StrListCast(doc.tags);
if (!tags.includes(value)) {
tags.push(value);
@@ -249,6 +267,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
}
return true;
}
+ return undefined;
});
return false;
};
@@ -256,44 +275,43 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@observable transform: Transform = Transform.Identity();
getTransform = () => this.transform;
propertiesDocViewRef = (ref: HTMLDivElement) => {
- const observer = new _global.ResizeObserver(
- action((entries: any) => {
+ const resizeObserver = new _global.ResizeObserver(
+ action(() => {
const cliRect = ref.getBoundingClientRect();
this.transform = new Transform(-cliRect.x, -cliRect.y, 1);
})
);
- ref && observer.observe(ref);
+ ref && resizeObserver.observe(ref);
};
@computed get contexts() {
- return !this.selectedDoc ? null : <PropertiesDocContextSelector DocView={this.selectedDocumentView} hideTitle={true} addDocTab={this._props.addDocTab} />;
+ return !this.selectedDoc ? null : <PropertiesDocContextSelector DocView={this.selectedDocumentView} hideTitle addDocTab={this._props.addDocTab} />;
}
@computed get contextCount() {
if (this.selectedDocumentView) {
const target = this.selectedDocumentView.Document;
return Doc.GetEmbeddings(target).length - 1;
- } else {
- return 0;
}
+ return 0;
}
@computed get links() {
const selAnchor = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.Instance.currentLinkAnchor ?? this.selectedDoc;
- return !selAnchor ? null : <PropertiesDocBacklinksSelector Document={selAnchor} hideTitle={true} addDocTab={this._props.addDocTab} />;
+ return !selAnchor ? null : <PropertiesDocBacklinksSelector Document={selAnchor} hideTitle addDocTab={this._props.addDocTab} />;
}
@computed get linkCount() {
const selAnchor = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.Instance.currentLinkAnchor ?? this.selectedDoc;
- var counter = 0;
+ let counter = 0;
- LinkManager.Links(selAnchor).forEach((l, i) => counter++);
+ Doc.Links(selAnchor).forEach(() => counter++);
return counter;
}
@computed get layoutPreview() {
- if (SelectionManager.Views.length > 1) {
+ if (DocumentView.Selected().length > 1) {
return '-- multiple selected --';
}
if (this.selectedDoc) {
@@ -309,7 +327,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
fitContentsToBox={returnTrue}
styleProvider={DefaultStyleProvider}
containerViewPath={returnEmptyDoclist}
- dontCenter={'y'}
+ dontCenter="y"
isDocumentActive={returnFalse}
isContentActive={emptyFunction}
NativeWidth={layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined}
@@ -327,13 +345,12 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
whenChildContentsActiveChanged={emptyFunction}
addDocTab={returnFalse}
pinToPres={emptyFunction}
- dontRegisterView={true}
+ dontRegisterView
/>
</div>
);
- } else {
- return null;
}
+ return null;
}
/**
@@ -341,7 +358,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
*/
@undoBatch
changePermissions = (e: any, user: string) => {
- const docs = SelectionManager.Views.length < 2 ? [this.selectedDoc] : SelectionManager.Views.map(dv => (this.layoutDocAcls ? dv.layoutDoc : dv.dataDoc));
+ 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);
};
@@ -353,9 +370,9 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
if (permission === '-multiple-') dropdownValues.unshift(permission);
return (
<select className="propertiesView-permissions-select" value={permission} onChange={e => this.changePermissions(e, user)}>
- {dropdownValues.map(permission => (
- <option className="propertiesView-permisssions-select" key={permission} value={permission}>
- {concat(ReverseHierarchyMap.get(permission)?.image, ' ', permission)}
+ {dropdownValues.map(permissionVal => (
+ <option className="propertiesView-permisssions-select" key={permissionVal} value={permissionVal}>
+ {concat(ReverseHierarchyMap.get(permissionVal)?.image, ' ', permissionVal)}
</option>
))}
</select>
@@ -382,9 +399,9 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
return (
<div className="expansion-button">
<IconButton
- icon={<FontAwesomeIcon icon={'ellipsis-h'} />}
+ icon={<FontAwesomeIcon icon="ellipsis-h" />}
size={Size.XSMALL}
- color={SettingsManager.userColor}
+ color={SnappingManager.userColor}
onClick={action(() => {
if (this.selectedDocumentView || this.selectedDoc) {
SharingManager.Instance.open(this.selectedDocumentView?.Document === this.selectedDoc ? this.selectedDocumentView : undefined, this.selectedDoc);
@@ -398,10 +415,8 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
/**
* @returns a row of the permissions panel
*/
- sharingItem(name: string, admin: boolean, permission: string, showExpansionIcon?: boolean) {
- if (name == Doc.CurrentUserEmail) {
- name = 'Me';
- }
+ sharingItem(nameIn: string, admin: boolean, permission: string, showExpansionIcon?: boolean) {
+ const name = nameIn === ClientUtils.CurrentUserEmail() ? 'Me' : nameIn;
return (
<div
className="propertiesView-sharingTable-item"
@@ -416,7 +431,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
{/* {name !== "Me" ? this.notifyIcon : null} */}
<div className="propertiesView-sharingTable-item-permission">
{this.colorACLDropDown(name, admin, permission, false)}
- {(permission === 'Owner' && name == 'Me') || showExpansionIcon ? this.expansionIcon : null}
+ {(permission === 'Owner' && name === 'Me') || showExpansionIcon ? this.expansionIcon : null}
</div>
</div>
);
@@ -426,10 +441,10 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
* @returns a colored dropdown bar reflective of the permission
*/
colorACLDropDown(name: string, admin: boolean, permission: string, showGuestOptions: boolean) {
- var shareImage = ReverseHierarchyMap.get(permission)?.image;
+ const shareImage = ReverseHierarchyMap.get(permission)?.image;
return (
<div>
- <div className={'propertiesView-shareDropDown'}>
+ <div className="propertiesView-shareDropDown">
<div className={`propertiesView-shareDropDown${permission}`}>
<div>{admin && permission !== 'Owner' ? this.getPermissionsSelect(name, permission, showGuestOptions) : concat(shareImage, ' ', permission)}</div>
</div>
@@ -441,9 +456,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
/**
* Sorting algorithm to sort users.
*/
- sortUsers = (u1: String, u2: String) => {
- return u1 > u2 ? -1 : u1 === u2 ? 0 : 1;
- };
+ sortUsers = (u1: String, u2: String) => (u1 > u2 ? -1 : u1 === u2 ? 0 : 1);
/**
* Sorting algorithm to sort groups.
@@ -459,45 +472,45 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
*/
@computed get sharingTable() {
// all selected docs
- const docs = SelectionManager.Views.length < 2 && this.selectedDoc ? [this.selectedDoc] : SelectionManager.Views.map(docView => docView.Document);
+ const docs = DocumentView.Selected().length < 2 && this.selectedDoc ? [this.selectedDoc] : DocumentView.SelectedDocs();
const target = docs[0];
- const showAdmin = GetEffectiveAcl(target) == AclAdmin;
+ const showAdmin = GetEffectiveAcl(target) === AclAdmin;
const individualTableEntries = [];
const usersAdded: string[] = []; // all shared users being added - organized by denormalized email
const seldoc = this.layoutDocAcls ? this.selectedLayoutDoc : this.selectedDoc?.[DocData];
// adds each user to usersAdded
SharingManager.Instance.users.forEach(eachUser => {
- var userOnDoc = true;
+ let userOnDoc = true;
if (seldoc) {
- if (Doc.GetT(seldoc, 'acl-' + normalizeEmail(eachUser.user.email), 'string', true) === '' || Doc.GetT(seldoc, 'acl-' + normalizeEmail(eachUser.user.email), 'string', true) === undefined) {
+ if (Doc.GetT(seldoc, 'acl_' + normalizeEmail(eachUser.user.email), 'string', true) === '' || Doc.GetT(seldoc, 'acl_' + normalizeEmail(eachUser.user.email), 'string', true) === undefined) {
userOnDoc = false;
}
}
- if (userOnDoc && !usersAdded.includes(eachUser.user.email) && eachUser.user.email !== 'guest' && eachUser.user.email != target.author) {
+ if (userOnDoc && !usersAdded.includes(eachUser.user.email) && eachUser.user.email !== 'guest' && eachUser.user.email !== target.author) {
usersAdded.push(eachUser.user.email);
}
});
// sorts and then adds each user to the table
usersAdded.sort(this.sortUsers);
- usersAdded.map(userEmail => {
- const userKey = `acl-${normalizeEmail(userEmail)}`;
- var aclField = Doc.GetT(this.layoutDocAcls ? target : Doc.GetProto(target), userKey, 'string', true);
- var permission = StrCast(aclField);
+ usersAdded.forEach(userEmail => {
+ const userKey = `acl_${normalizeEmail(userEmail)}`;
+ const aclField = Doc.GetT(this.layoutDocAcls ? target : Doc.GetProto(target), userKey, 'string', true);
+ const permission = StrCast(aclField);
individualTableEntries.unshift(this.sharingItem(userEmail, showAdmin, permission!, false)); // adds each user
});
// adds current user
- var userEmail = Doc.CurrentUserEmail;
- if (userEmail == 'guest') userEmail = 'Guest';
- const userKey = `acl-${normalizeEmail(userEmail)}`;
- if (!usersAdded.includes(userEmail) && userEmail !== 'Guest' && userEmail != target.author) {
- var permission;
+ let userEmail = ClientUtils.CurrentUserEmail();
+ if (userEmail === 'guest') userEmail = 'Guest';
+ const userKey = `acl_${normalizeEmail(userEmail)}`;
+ if (!usersAdded.includes(userEmail) && userEmail !== 'Guest' && userEmail !== target.author) {
+ let permission;
if (this.layoutDocAcls) {
if (target[DocAcl][userKey]) permission = HierarchyMapping.get(target[DocAcl][userKey])?.name;
- else if (target['embedContainer']) permission = StrCast(Doc.GetProto(DocCast(target['embedContainer']))[userKey]);
+ else if (target.embedContainer) permission = StrCast(Doc.GetProto(DocCast(target.embedContainer))[userKey]);
else permission = StrCast(Doc.GetProto(target)?.[userKey]);
} else permission = StrCast(target[userKey]);
individualTableEntries.unshift(this.sharingItem(userEmail, showAdmin, permission!, false)); // adds each user
@@ -510,15 +523,15 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
const groupTableEntries: JSX.Element[] = [];
const groupList = GroupManager.Instance?.allGroups || [];
groupList.sort(this.sortGroups);
- groupList.map(group => {
- if (group.title != 'Guest' && this.selectedDoc) {
- const groupKey = 'acl-' + normalizeEmail(StrCast(group.title));
- if (this.selectedDoc[groupKey] != '' && this.selectedDoc[groupKey] != undefined) {
- var permission;
+ groupList.forEach(group => {
+ if (group.title !== 'Guest' && this.selectedDoc) {
+ const groupKey = 'acl_' + normalizeEmail(StrCast(group.title));
+ if (this.selectedDoc[groupKey] !== '' && this.selectedDoc[groupKey] !== undefined) {
+ let permission;
if (this.layoutDocAcls) {
if (target[DocAcl][groupKey]) {
permission = HierarchyMapping.get(target[DocAcl][groupKey])?.name;
- } else if (target['embedContainer']) permission = StrCast(Doc.GetProto(DocCast(target['embedContainer']))[groupKey]);
+ } else if (target.embedContainer) permission = StrCast(Doc.GetProto(DocCast(target.embedContainer))[groupKey]);
else permission = StrCast(Doc.GetProto(target)?.[groupKey]);
} else permission = StrCast(target[groupKey]);
groupTableEntries.unshift(this.sharingItem(StrCast(group.title), showAdmin, permission!, false));
@@ -527,27 +540,27 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
});
// guest permission
- const guestPermission = StrCast((this.layoutDocAcls ? target : Doc.GetProto(target))['acl-Guest']);
+ const guestPermission = StrCast((this.layoutDocAcls ? target : Doc.GetProto(target)).acl_Guest);
return (
<div>
<div>
- <br></br> Individuals with Access to this Document
+ <br /> Individuals with Access to this Document
</div>
- <div className="propertiesView-sharingTable" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}>
- {<div> {individualTableEntries}</div>}
+ <div className="propertiesView-sharingTable" style={{ background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor }}>
+ <div> {individualTableEntries}</div>
</div>
{groupTableEntries.length > 0 ? (
<div>
<div>
- <br></br> Groups with Access to this Document
+ <br /> Groups with Access to this Document
</div>
- <div className="propertiesView-sharingTable" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}>
- {<div> {groupTableEntries}</div>}
+ <div className="propertiesView-sharingTable" style={{ background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor }}>
+ <div> {groupTableEntries}</div>
</div>
</div>
) : null}
- <br></br> Guest
+ <br /> Guest
<div>{this.colorACLDropDown('Guest', showAdmin, guestPermission!, true)}</div>
</div>
);
@@ -559,41 +572,39 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
}
@action
- toggleCheckbox = () => (this.layoutFields = !this.layoutFields);
+ toggleCheckbox = () => {
+ this.layoutFields = !this.layoutFields;
+ };
@computed get color() {
- return SettingsManager.userColor;
+ return SnappingManager.userColor;
}
@computed get backgroundColor() {
- return SettingsManager.userBackgroundColor;
+ return SnappingManager.userBackgroundColor;
}
@computed get variantColor() {
- return SettingsManager.userVariantColor;
+ return SnappingManager.userVariantColor;
}
@computed get editableTitle() {
const titles = new Set<string>();
- SelectionManager.Views.forEach(dv => titles.add(StrCast(dv.Document.title)));
+ DocumentView.Selected().forEach(dv => titles.add(StrCast(dv.Document.title)));
const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title);
return (
<div>
- <EditableText val={title} setVal={this.setTitle} color={this.color} type={Type.SEC} formLabel={'Title'} fillWidth />
+ <EditableText val={title} setVal={this.setTitle} color={this.color} type={Type.SEC} formLabel="Title" fillWidth />
{LinkManager.Instance.currentLinkAnchor ? (
<p className="propertiesView-titleExtender">
- <>
- <b>Anchor:</b>
- {LinkManager.Instance.currentLinkAnchor.title}
- </>
+ <b>Anchor:</b>
+ {StrCast(LinkManager.Instance.currentLinkAnchor.title)}
</p>
) : null}
{this.selectedLink?.title ? (
<p className="propertiesView-titleExtender">
- <>
- <b>Link:</b>
- {this.selectedLink.title}
- </>
+ <b>Link:</b>
+ {StrCast(this.selectedLink.title)}
</p>
) : null}
</div>
@@ -601,9 +612,9 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
}
@computed get currentType() {
- const documentType = StrCast(this.selectedDoc?.type);
- var currentType: string = documentType;
- var capitalizedDocType = Utils.cleanDocumentType(currentType as DocumentType);
+ const docType = StrCast(this.selectedDoc?.type) as DocumentType;
+ const colType = StrCast(this.selectedDoc?.type_collection) as CollectionViewType;
+ const capitalizedDocType = ClientUtils.cleanDocumentType(docType, colType);
return (
<div>
@@ -619,7 +630,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
}
@computed get currentComponent() {
- var iconName = StrCast(this.selectedDoc?.systemIcon);
+ const iconName = StrCast(this.selectedDoc?.systemIcon);
if (iconName) {
const Icon = Icons[iconName as keyof typeof Icons];
@@ -630,11 +641,11 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@undoBatch
setTitle = (value: string | number) => {
- if (SelectionManager.Views.length > 1) {
- SelectionManager.Views.map(dv => Doc.SetInPlace(dv.Document, 'title', value, true));
+ if (DocumentView.Selected().length > 1) {
+ DocumentView.Selected().map(dv => Doc.SetInPlace(dv.Document, 'title', value, true));
} else if (this.dataDoc) {
if (this.selectedDoc) Doc.SetInPlace(this.selectedDoc, 'title', value, true);
- else KeyValueBox.SetField(this.dataDoc, 'title', value as string, true);
+ else Doc.SetField(this.dataDoc, 'title', value as string, true);
}
};
@@ -651,13 +662,11 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
const ys = ink.map(p => p.Y);
const left = Math.min(...xs);
const top = Math.min(...ys);
- const right = Math.max(...xs);
- const bottom = Math.max(...ys);
_centerPoints.push({ X: left, Y: top });
}
}
- var index = 0;
+ let index = 0;
if (doc.type === DocumentType.INK && doc.x && doc.y && layout._width && layout._height && doc.data) {
layout.rotation = NumCast(layout.rotation) + angle;
const inks = Cast(doc.stroke, InkField)?.inkData;
@@ -688,11 +697,13 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
get controlPointsButton() {
return (
<div className="inking-button">
- <Tooltip title={<div className="dash-tooltip">{'Edit points'}</div>}>
+ <Tooltip title={<div className="dash-tooltip">Edit points</div>}>
<div
className="inking-button-points"
style={{ backgroundColor: InkStrokeProperties.Instance._controlButton ? 'black' : '' }}
- onPointerDown={action(() => (InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton))}>
+ onPointerDown={action(() => {
+ InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton;
+ })}>
<FontAwesomeIcon icon="bezier-curve" size="lg" />
</div>
</Tooltip>
@@ -700,152 +711,129 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
);
}
- inputBox = (key: string, value: any, setter: (val: string) => {}, title: string) => {
- return (
- <div
- className="inputBox"
- style={{
- marginRight: title === 'X:' ? '19px' : '',
- marginLeft: title === '∠:' ? '39px' : '',
- }}>
- <div className="inputBox-title"> {title} </div>
- <input
- className="inputBox-input"
- type="text"
- value={value}
- style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}
- onChange={e => setter(e.target.value)}
- onKeyPress={e => e.stopPropagation()}
- />
- <div className="inputBox-button">
- <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}>
- <FontAwesomeIcon icon="caret-up" size="sm" />
- </div>
- <div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}>
- <FontAwesomeIcon icon="caret-down" size="sm" />
- </div>
+ inputBox = (key: string, value: any, setter: (val: string) => {}, title: string) => (
+ <div
+ className="inputBox"
+ style={{
+ marginRight: title === 'X:' ? '19px' : '',
+ marginLeft: title === '∠:' ? '39px' : '',
+ }}>
+ <div className="inputBox-title"> {title} </div>
+ <input className="inputBox-input" type="text" value={value} style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }} onChange={e => setter(e.target.value)} onKeyDown={e => e.stopPropagation()} />
+ <div className="inputBox-button">
+ <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}>
+ <FontAwesomeIcon icon="caret-up" size="sm" />
+ </div>
+ <div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}>
+ <FontAwesomeIcon icon="caret-down" size="sm" />
</div>
</div>
- );
- };
+ </div>
+ );
- inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => {
- return (
- <div className="inputBox-duo">
- {this.inputBox(key, value, setter, title1)}
- {title2 === '' ? null : this.inputBox(key2, value2, setter2, title2)}
- </div>
- );
- };
+ inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => (
+ <div className="inputBox-duo">
+ {this.inputBox(key, value, setter, title1)}
+ {title2 === '' ? null : this.inputBox(key2, value2, setter2, title2)}
+ </div>
+ );
@action
upDownButtons = (dirs: string, field: string) => {
const selDoc = this.selectedDoc;
if (!selDoc) return;
- //prettier-ignore
+ // prettier-ignore
switch (field) {
case 'Xps': selDoc.x = NumCast(this.selectedDoc?.x) + (dirs === 'up' ? 10 : -10); break;
case 'Yps': selDoc.y = NumCast(this.selectedDoc?.y) + (dirs === 'up' ? 10 : -10); break;
case 'stk': selDoc.stroke_width = NumCast(this.selectedDoc?.[DocData].stroke_width) + (dirs === 'up' ? 0.1 : -0.1); break;
- case 'wid':
- const oldWidth = NumCast(selDoc._width);
- const oldHeight = NumCast(selDoc._height);
- const oldX = NumCast(selDoc.x);
- const oldY = NumCast(selDoc.y);
- selDoc._width = oldWidth + (dirs === 'up' ? 10 : -10);
- if (selDoc.type === DocumentType.INK && selDoc.x && selDoc.y && selDoc._height && selDoc._width) {
- const ink = Cast(selDoc.data, InkField)?.inkData;
- if (ink) {
- const newPoints: { X: number; Y: number }[] = [];
- for (var j = 0; j < ink.length; j++) {
- // (new x — oldx) + (oldxpoint * newWidt)/oldWidth
- const newX = NumCast(selDoc.x) - oldX + (ink[j].X * NumCast(selDoc._width)) / oldWidth;
- const newY = NumCast(selDoc.y) - oldY + (ink[j].Y * NumCast(selDoc._height)) / oldHeight;
- newPoints.push({ X: newX, Y: newY });
+ case 'wid': {
+ const oldWidth = NumCast(selDoc._width);
+ const oldHeight = NumCast(selDoc._height);
+ const oldX = NumCast(selDoc.x);
+ const oldY = NumCast(selDoc.y);
+ selDoc._width = oldWidth + (dirs === 'up' ? 10 : -10);
+ if (selDoc.type === DocumentType.INK && selDoc.x && selDoc.y && selDoc._height && selDoc._width) {
+ const ink = Cast(selDoc.data, InkField)?.inkData;
+ if (ink) {
+ const newPoints: { X: number; Y: number }[] = [];
+ for (let j = 0; j < ink.length; j++) {
+ // (new x — oldx) + (oldxpoint * newWidt)/oldWidth
+ const newX = NumCast(selDoc.x) - oldX + (ink[j].X * NumCast(selDoc._width)) / oldWidth;
+ const newY = NumCast(selDoc.y) - oldY + (ink[j].Y * NumCast(selDoc._height)) / oldHeight;
+ newPoints.push({ X: newX, Y: newY });
+ }
+ selDoc.data = new InkField(newPoints);
}
- selDoc.data = new InkField(newPoints);
}
}
break;
- case 'hgt':
- const oWidth = NumCast(selDoc._width);
- const oHeight = NumCast(selDoc._height);
- const oX = NumCast(selDoc.x);
- const oY = NumCast(selDoc.y);
- selDoc._height = oHeight + (dirs === 'up' ? 10 : -10);
- if (selDoc.type === DocumentType.INK && selDoc.x && selDoc.y && selDoc._height && selDoc._width) {
- const ink = Cast(selDoc.data, InkField)?.inkData;
- if (ink) {
- const newPoints: { X: number; Y: number }[] = [];
- for (var j = 0; j < ink.length; j++) {
- // (new x — oldx) + (oldxpoint * newWidt)/oldWidth
- const newX = NumCast(selDoc.x) - oX + (ink[j].X * NumCast(selDoc._width)) / oWidth;
- const newY = NumCast(selDoc.y) - oY + (ink[j].Y * NumCast(selDoc._height)) / oHeight;
- newPoints.push({ X: newX, Y: newY });
+ case 'hgt': {
+ const oWidth = NumCast(selDoc._width);
+ const oHeight = NumCast(selDoc._height);
+ const oX = NumCast(selDoc.x);
+ const oY = NumCast(selDoc.y);
+ selDoc._height = oHeight + (dirs === 'up' ? 10 : -10);
+ if (selDoc.type === DocumentType.INK && selDoc.x && selDoc.y && selDoc._height && selDoc._width) {
+ const ink = Cast(selDoc.data, InkField)?.inkData;
+ if (ink) {
+ const newPoints: { X: number; Y: number }[] = [];
+ for (let j = 0; j < ink.length; j++) {
+ // (new x — oldx) + (oldxpoint * newWidt)/oldWidth
+ const newX = NumCast(selDoc.x) - oX + (ink[j].X * NumCast(selDoc._width)) / oWidth;
+ const newY = NumCast(selDoc.y) - oY + (ink[j].Y * NumCast(selDoc._height)) / oHeight;
+ newPoints.push({ X: newX, Y: newY });
+ }
+ selDoc.data = new InkField(newPoints);
}
- selDoc.data = new InkField(newPoints);
}
}
break;
+ default: { /* empty */ }
}
};
getField(key: string) {
- return Field.toString(this.selectedDoc?.[DocData][key] as Field);
+ return Field.toString(this.selectedDoc?.[DocData][key] as FieldType);
}
- @computed get shapeXps() {
- return NumCast(this.selectedDoc?.x);
- }
- @computed get shapeYps() {
- return NumCast(this.selectedDoc?.y);
- }
- @computed get shapeHgt() {
- return NumCast(this.selectedDoc?._height);
- }
- @computed get shapeWid() {
- return NumCast(this.selectedDoc?._width);
- }
- @computed get strokeThk() {
- return NumCast(this.selectedDoc?.[DocData].stroke_width);
- }
- set shapeXps(value) {
- this.selectedDoc && (this.selectedDoc.x = Math.round(value * 100) / 100);
- }
- set shapeYps(value) {
- this.selectedDoc && (this.selectedDoc.y = Math.round(value * 100) / 100);
- }
- set shapeWid(value) {
- this.selectedDoc && (this.selectedDoc._width = Math.round(value * 100) / 100);
- }
- set shapeHgt(value) {
- this.selectedDoc && (this.selectedDoc._height = Math.round(value * 100) / 100);
- }
- set strokeThk(value) {
- this.selectedDoc && (this.selectedDoc[DocData].stroke_width = Math.round(value * 100) / 100);
- }
+ @computed get shapeXps() { return NumCast(this.selectedDoc?.x); } // prettier-ignore
+ set shapeXps(value) { this.selectedDoc && (this.selectedDoc.x = Math.round(value * 100) / 100); } // prettier-ignore
+ @computed get shapeYps() { return NumCast(this.selectedDoc?.y); } // prettier-ignore
+ set shapeYps(value) { this.selectedDoc && (this.selectedDoc.y = Math.round(value * 100) / 100); } // prettier-ignore
+ @computed get shapeWid() { return NumCast(this.selectedDoc?._width); } // prettier-ignore
+ set shapeWid(value) { this.selectedDoc && (this.selectedDoc._width = Math.round(value * 100) / 100); } // prettier-ignore
+ @computed get shapeHgt() { return NumCast(this.selectedDoc?._height); } // prettier-ignore
+ set shapeHgt(value) { this.selectedDoc && (this.selectedDoc._height = Math.round(value * 100) / 100); } // prettier-ignore
+ @computed get strokeThk(){ return NumCast(this.selectedDoc?.[DocData].stroke_width); } // prettier-ignore
+ set strokeThk(value) { this.selectedDoc && (this.selectedDoc[DocData].stroke_width = Math.round(value * 100) / 100); } // prettier-ignore
@computed get hgtInput() {
return this.inputBoxDuo(
'hgt',
this.shapeHgt,
- undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = +val), 'set height'),
+ undoable((val: string) => {
+ !Number(val) && (this.shapeHgt = +val);
+ }, 'set height'),
'H:',
'wid',
this.shapeWid,
- undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = +val), 'set width'),
+ undoable((val: string) => {
+ !isNaN(Number(val)) && (this.shapeWid = +val);
+ }, 'set width'),
'W:'
);
}
@computed get XpsInput() {
+ // prettier-ignore
return this.inputBoxDuo(
'Xps',
this.shapeXps,
- undoable((val: string) => val !== '0' && !isNaN(Number(val)) && (this.shapeXps = +val), 'set x coord'),
+ undoable((val: string) => { val !== '0' && !isNaN(Number(val)) && (this.shapeXps = +val); }, 'set x coord'),
'X:',
'Yps',
this.shapeYps,
- undoable((val: string) => val !== '0' && !isNaN(Number(val)) && (this.shapeYps = +val), 'set y coord'),
+ undoable((val: string) => { val !== '0' && !isNaN(Number(val)) && (this.shapeYps = +val); }, 'set y coord'),
'Y:'
);
}
@@ -855,22 +843,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
private _lastDash: any = '2';
- @computed get colorFil() {
- return StrCast(this.selectedDoc?.[DocData].fillColor);
- }
- @computed get colorStk() {
- return StrCast(this.selectedDoc?.[DocData].color);
- }
- set colorFil(value) {
- this.selectedDoc && (this.selectedDoc[DocData].fillColor = value ? value : undefined);
- }
- set colorStk(value) {
- this.selectedDoc && (this.selectedDoc[DocData].color = value ? value : undefined);
- }
+ @computed get colorFil() { return StrCast(this.selectedDoc?.[DocData].fillColor); } // prettier-ignore
+ set colorFil(value) { this.selectedDoc && (this.selectedDoc[DocData].fillColor = value || undefined); } // prettier-ignore
+ @computed get colorStk() { return StrCast(this.selectedDoc?.[DocData].color); } // prettier-ignore
+ set colorStk(value) { this.selectedDoc && (this.selectedDoc[DocData].color = value || undefined); } // prettier-ignore
colorButton(value: string, type: string, setter: () => void) {
return (
- <div className="color-button" key="color" onPointerDown={action(e => setter())}>
+ <div className="color-button" key="color" onPointerDown={action(() => setter())}>
<div
className="color-button-preview"
style={{
@@ -889,7 +869,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
return (
<SketchPicker
onChange={undoable(
- action((color: ColorResult) => setter(color.hex)),
+ action((col: ColorResult) => setter(col.hex)),
'set stroke color property'
)}
presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
@@ -912,10 +892,10 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
}
@computed get fillPicker() {
- return this.colorPicker(this.colorFil, (color: string) => (this.colorFil = color));
+ return this.colorPicker(this.colorFil, (color: string) => { this.colorFil = color; }); // prettier-ignore
}
@computed get linePicker() {
- return this.colorPicker(this.colorStk, (color: string) => (this.colorStk = color));
+ return this.colorPicker(this.colorStk, (color: string) => { this.colorStk = color; }); // prettier-ignore
}
@computed get strokeAndFill() {
@@ -937,60 +917,41 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
);
}
- @computed get dashdStk() {
- return this.selectedDoc?.stroke_dash || '';
- }
- @computed get widthStk() {
- return this.getField('stroke_width') || '1';
- }
- @computed get markScal() {
- return Number(this.getField('stroke_markerScale') || '1');
- }
- @computed get markHead() {
- return this.getField('stroke_startMarker') || '';
- }
- @computed get markTail() {
- return this.getField('stroke_endMarker') || '';
- }
+ @computed get dashdStk() { return this.selectedDoc?.stroke_dash || ''; } // prettier-ignore
set dashdStk(value) {
value && (this._lastDash = value);
this.selectedDoc && (this.selectedDoc[DocData].stroke_dash = value ? this._lastDash : undefined);
}
- set markScal(value) {
- this.selectedDoc && (this.selectedDoc[DocData].stroke_markerScale = Number(value));
- }
+ @computed get widthStk() { return this.getField('stroke_width') || '1'; } // prettier-ignore
set widthStk(value) {
this.selectedDoc && (this.selectedDoc[DocData].stroke_width = Number(value));
}
+ @computed get markScal() { return Number(this.getField('stroke_markerScale') || '1'); } // prettier-ignore
+ set markScal(value) {
+ this.selectedDoc && (this.selectedDoc[DocData].stroke_markerScale = Number(value));
+ }
+ @computed get markHead() { return this.getField('stroke_startMarker') || ''; } // prettier-ignore
set markHead(value) {
this.selectedDoc && (this.selectedDoc[DocData].stroke_startMarker = value);
}
+ @computed get markTail() { return this.getField('stroke_endMarker') || ''; } // prettier-ignore
set markTail(value) {
this.selectedDoc && (this.selectedDoc[DocData].stroke_endMarker = value);
}
- @computed get stkInput() {
- return this.regInput('stk', this.widthStk, (val: string) => (this.widthStk = val));
- }
- @computed get markScaleInput() {
- return this.regInput('scale', this.markScal.toString(), (val: string) => (this.markScal = Number(val)));
- }
-
- regInput = (key: string, value: any, setter: (val: string) => {}) => {
- return (
- <div className="inputBox">
- <input className="inputBox-input" type="text" value={value} style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} onChange={e => setter(e.target.value)} />
- <div className="inputBox-button">
- <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}>
- <FontAwesomeIcon icon="caret-up" size="sm" />
- </div>
- <div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}>
- <FontAwesomeIcon icon="caret-down" size="sm" />
- </div>
+ regInput = (key: string, value: any, setter: (val: string) => {}) => (
+ <div className="inputBox">
+ <input className="inputBox-input" type="text" value={value} style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }} onChange={e => setter(e.target.value)} />
+ <div className="inputBox-button">
+ <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}>
+ <FontAwesomeIcon icon="caret-up" size="sm" />
+ </div>
+ <div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}>
+ <FontAwesomeIcon icon="caret-down" size="sm" />
</div>
</div>
- );
- };
+ </div>
+ );
@action
CloseAll = () => {
@@ -1006,18 +967,55 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get widthAndDash() {
return (
+ // prettier-ignore
<div className="widthAndDash">
- <div className="width">{this.getNumber('Thickness', '', 0, Math.max(50, this.strokeThk), this.strokeThk, (val: number) => !isNaN(val) && (this.strokeThk = val), 50, 1)}</div>
- <div className="width">{this.getNumber('Arrow Scale', '', 0, Math.max(10, this.markScal), this.markScal, (val: number) => !isNaN(val) && (this.markScal = val), 10, 1)}</div>
+ <div className="width">
+ {this.getNumber(
+ 'Thickness',
+ '',
+ 0,
+ Math.max(50, this.strokeThk),
+ this.strokeThk,
+ (val: number) => { !isNaN(val) && (this.strokeThk = val); },
+ 50,
+ 1
+ )}
+ </div>
+ <div className="width">
+ {this.getNumber(
+ 'Arrow Scale',
+ '',
+ 0,
+ Math.max(10, this.markScal),
+ this.markScal,
+ (val: number) => { !isNaN(val) && (this.markScal = val); },
+ 10,
+ 1
+ )}
+ </div>
<div className="arrows">
<div className="arrows-head">
<div className="arrows-head-title">Arrow Head: </div>
- <input key="markHead" className="arrows-head-input" type="checkbox" checked={this.markHead !== ''} onChange={undoBatch(action(() => (this.markHead = this.markHead ? '' : 'arrow')))} />
+ <input
+ key="markHead"
+ className="arrows-head-input"
+ type="checkbox"
+ checked={this.markHead !== ''}
+ onChange={undoBatch(action(() => { this.markHead = this.markHead ? '' : 'arrow'; }))}
+ />
</div>
<div className="arrows-tail">
<div className="arrows-tail-title">Arrow End: </div>
- <input key="markTail" className="arrows-tail-input" type="checkbox" checked={this.markTail !== ''} onChange={undoBatch(action(() => (this.markTail = this.markTail ? '' : 'arrow')))} />
+ <input
+ key="markTail"
+ className="arrows-tail-input"
+ type="checkbox"
+ checked={this.markTail !== ''}
+ onChange={undoBatch(
+ action(() => { this.markTail = this.markTail ? '' : 'arrow'; })
+ )}
+ />
</div>
</div>
<div className="dashed">
@@ -1046,50 +1044,53 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
setFinalNumber = () => {
this._sliderBatch?.end();
};
- getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any, autorange?: number, autorangeMinVal?: number) => {
- return (
- <div key={label + this.selectedDoc?.title}>
- <NumberInput formLabel={label} formLabelPlacement={'left'} type={Type.SEC} unit={unit} fillWidth color={this.color} number={number} setNumber={setNumber} min={min} max={max} />
- <Slider
- key={label}
- onPointerDown={e => (this._sliderBatch = UndoManager.StartBatch('slider ' + label))}
- multithumb={false}
- color={this.color}
- size={Size.XSMALL}
- min={min}
- max={max}
- autorangeMinVal={autorangeMinVal}
- autorange={autorange}
- number={number}
- unit={unit}
- decimals={1}
- setFinalNumber={this.setFinalNumber}
- setNumber={setNumber}
- fillWidth
- />
- </div>
- );
- };
+ getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any, autorange?: number, autorangeMinVal?: number) => (
+ <div key={label + (this.selectedDoc?.title ?? '')}>
+ <NumberInput formLabel={label} formLabelPlacement="left" type={Type.SEC} unit={unit} fillWidth color={this.color} number={number} setNumber={setNumber} min={min} max={max} />
+ <Slider
+ key={label}
+ onPointerDown={() => {
+ this._sliderBatch = UndoManager.StartBatch('slider ' + label);
+ }}
+ multithumb={false}
+ color={this.color}
+ size={Size.XSMALL}
+ min={min}
+ max={max}
+ autorangeMinVal={autorangeMinVal}
+ autorange={autorange}
+ number={number}
+ unit={unit}
+ decimals={1}
+ setFinalNumber={this.setFinalNumber}
+ setNumber={setNumber}
+ fillWidth
+ />
+ </div>
+ );
+ setVal = (func: (doc: Doc, val: number) => void) => (val: number) => this.selectedDoc && !isNaN(val) && func(this.selectedDoc, val);
@computed get transformEditor() {
return (
+ // prettier-ignore
<div className="transform-editor">
- {!this.isStack ? null : this.getNumber('Gap', ' px', 0, 200, NumCast(this.selectedDoc!.gridGap), (val: number) => !isNaN(val) && (this.selectedDoc!.gridGap = val))}
- {!this.isStack ? null : this.getNumber('xMargin', ' px', 0, 500, NumCast(this.selectedDoc!.xMargin), (val: number) => !isNaN(val) && (this.selectedDoc!.xMargin = val))}
- {!this.isStack ? null : this.getNumber('yMargin', ' px', 0, 500, NumCast(this.selectedDoc!.yMargin), (val: number) => !isNaN(val) && (this.selectedDoc!.yMargin = val))}
- {!this.isGroup ? null : this.getNumber('Padding', ' px', 0, 500, NumCast(this.selectedDoc!.xPadding), (val: number) => !isNaN(val) && (this.selectedDoc!.xPadding = this.selectedDoc!.yPadding = val))}
+ {!this.isStack ? null : this.getNumber('Gap', ' px', 0, 200, NumCast(this.selectedDoc!.gridGap), this.setVal((doc: Doc, val: number) => { doc.gridGap = val; })) }
+ {!this.isStack ? null : this.getNumber('xMargin', ' px', 0, 500, NumCast(this.selectedDoc!.xMargin), this.setVal((doc: Doc, val: number) => { doc.xMargin = val; })) }
+ {!this.isStack ? null : this.getNumber('yMargin', ' px', 0, 500, NumCast(this.selectedDoc!.yMargin), this.setVal((doc: Doc, val: number) => { doc.yMargin = val; })) }
+ {!this.isGroup ? null : this.getNumber('Padding', ' px', 0, 500, NumCast(this.selectedDoc!.xPadding), this.setVal((doc: Doc, val: number) => { doc.xPadding = doc.yPadding = val; })) }
{this.isInk ? this.controlPointsButton : null}
- {this.getNumber('Width', ' px', 0, Math.max(1000, this.shapeWid), this.shapeWid, (val: number) => !isNaN(val) && (this.shapeWid = val), 1000, 1)}
- {this.getNumber('Height', ' px', 0, Math.max(1000, this.shapeHgt), this.shapeHgt, (val: number) => !isNaN(val) && (this.shapeHgt = val), 1000, 1)}
- {this.getNumber('X', ' px', this.shapeXps - 500, this.shapeXps + 500, this.shapeXps, (val: number) => !isNaN(val) && (this.shapeXps = val), 1000)}
- {this.getNumber('Y', ' px', this.shapeYps - 500, this.shapeYps + 500, this.shapeYps, (val: number) => !isNaN(val) && (this.shapeYps = val), 1000)}
+ {this.getNumber('Width', ' px', 0, Math.max(1000, this.shapeWid), this.shapeWid, this.setVal((doc: Doc, val:number) => {this.shapeWid = val}), 1000, 1)}
+ {this.getNumber('Height', ' px', 0, Math.max(1000, this.shapeHgt), this.shapeHgt, this.setVal((doc: Doc, val:number) => {this.shapeHgt = val}), 1000, 1)}
+ {this.getNumber('X', ' px', this.shapeXps - 500, this.shapeXps + 500, this.shapeXps, this.setVal((doc: Doc, val:number) => {this.shapeXps = val}), 1000)}
+ {this.getNumber('Y', ' px', this.shapeYps - 500, this.shapeYps + 500, this.shapeYps, this.setVal((doc: Doc, val:number) => {this.shapeYps = val}), 1000)}
</div>
);
}
@computed get optionsSubMenu() {
return (
- <PropertiesSection title="Options" inSection={this.inOptions} isOpen={this.openOptions} setInSection={bool => (this.inOptions = bool)} setIsOpen={bool => (this.openOptions = bool)} onDoubleClick={this.CloseAll}>
+ // prettier-ignore
+ <PropertiesSection title="Options" isOpen={this.openOptions} setIsOpen={bool => { this.openOptions = bool; }} onDoubleClick={this.CloseAll}>
<PropertiesButtons />
</PropertiesSection>
);
@@ -1097,12 +1098,23 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get sharingSubMenu() {
return (
- <PropertiesSection title="Sharing and Permissions" isOpen={this.openSharing} setIsOpen={bool => (this.openSharing = bool)} onDoubleClick={() => this.CloseAll()}>
+ // prettier-ignore
+ <PropertiesSection
+ title="Sharing and Permissions"
+ isOpen={this.openSharing}
+ setIsOpen={bool => { this.openSharing = bool; }}
+ onDoubleClick={this.CloseAll}>
<>
{/* <div className="propertiesView-buttonContainer"> */}
<div className="propertiesView-acls-checkbox">
Layout Permissions
- <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} />
+ <Checkbox
+ color="primary"
+ onChange={action(() => {
+ this.layoutDocAcls = !this.layoutDocAcls;
+ })}
+ checked={this.layoutDocAcls}
+ />
</div>
{/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}>
<button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}>
@@ -1142,7 +1154,8 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get filtersSubMenu() {
return (
- <PropertiesSection title="Filters" isOpen={this.openFilters} setIsOpen={bool => (this.openFilters = bool)} onDoubleClick={() => this.CloseAll()}>
+ // prettier-ignore
+ <PropertiesSection title="Filters" isOpen={this.openFilters} setIsOpen={bool => { this.openFilters = bool; }} onDoubleClick={this.CloseAll}>
<div className="propertiesView-content filters" style={{ position: 'relative', height: 'auto' }}>
<FilterPanel Document={this.selectedDoc ?? Doc.ActiveDashboard!} />
</div>
@@ -1152,11 +1165,12 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get inkSubMenu() {
return (
+ // prettier-ignore
<>
- <PropertiesSection title="Appearance" isOpen={this.openAppearance} setIsOpen={bool => (this.openAppearance = bool)} onDoubleClick={() => this.CloseAll()}>
+ <PropertiesSection title="Appearance" isOpen={this.openAppearance} setIsOpen={bool => { this.openAppearance = bool; }} onDoubleClick={this.CloseAll}>
{this.selectedLayoutDoc?.layout_isSvg ? this.appearanceEditor : null}
</PropertiesSection>
- <PropertiesSection title="Transform" isOpen={this.openTransform} setIsOpen={bool => (this.openTransform = bool)} onDoubleClick={() => this.CloseAll()}>
+ <PropertiesSection title="Transform" isOpen={this.openTransform} setIsOpen={bool => { this.openTransform = bool; }} onDoubleClick={this.CloseAll}>
{this.transformEditor}
</PropertiesSection>
</>
@@ -1165,7 +1179,13 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get fieldsSubMenu() {
return (
- <PropertiesSection title="Fields & Tags" isOpen={this.openFields} setIsOpen={bool => (this.openFields = bool)} onDoubleClick={() => this.CloseAll()}>
+ <PropertiesSection
+ title="Fields & Tags"
+ isOpen={this.openFields}
+ setIsOpen={bool => {
+ this.openFields = bool;
+ }}
+ onDoubleClick={this.CloseAll}>
<div className="propertiesView-content fields">{Doc.noviceMode ? this.noviceFields : this.expandedField}</div>
</PropertiesSection>
);
@@ -1173,7 +1193,13 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get contextsSubMenu() {
return (
- <PropertiesSection title="Other Contexts" isOpen={this.openContexts} setIsOpen={bool => (this.openContexts = bool)} onDoubleClick={() => this.CloseAll()}>
+ <PropertiesSection
+ title="Other Contexts"
+ isOpen={this.openContexts}
+ setIsOpen={bool => {
+ this.openContexts = bool;
+ }}
+ onDoubleClick={this.CloseAll}>
{this.contextCount > 0 ? this.contexts : 'There are no other contexts.'}
</PropertiesSection>
);
@@ -1181,7 +1207,13 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get linksSubMenu() {
return (
- <PropertiesSection title="Linked To" isOpen={this.openLinks} setIsOpen={bool => (this.openLinks = bool)} onDoubleClick={this.CloseAll}>
+ <PropertiesSection
+ title="Linked To"
+ isOpen={this.openLinks}
+ setIsOpen={bool => {
+ this.openLinks = bool;
+ }}
+ onDoubleClick={this.CloseAll}>
{this.linkCount > 0 ? this.links : 'There are no current links.'}
</PropertiesSection>
);
@@ -1189,14 +1221,20 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
@computed get layoutSubMenu() {
return (
- <PropertiesSection title="Layout" isOpen={this.openLayout} setIsOpen={bool => (this.openLayout = bool)} onDoubleClick={this.CloseAll}>
+ <PropertiesSection
+ title="Layout"
+ isOpen={this.openLayout}
+ setIsOpen={bool => {
+ this.openLayout = bool;
+ }}
+ onDoubleClick={this.CloseAll}>
{this.layoutPreview}
</PropertiesSection>
);
}
@computed get description() {
- return Field.toString(this.selectedLink?.link_description as any as Field);
+ return Field.toString(this.selectedLink?.link_description as any as FieldType);
}
@computed get relationship() {
return StrCast(this.selectedLink?.link_relationship);
@@ -1251,12 +1289,12 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
// if the relationship is already in the list AND the new rel is different from the prev rel, update the rel sizes
} else if (linkRelationshipList && value !== prevRelationship) {
const index = linkRelationshipList.indexOf(value);
- //increment size of new relationship size
+ // increment size of new relationship size
if (index !== -1 && index < linkRelationshipSizes.length) {
const pvalue = linkRelationshipSizes[index];
linkRelationshipSizes[index] = pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue + 1;
}
- //decrement the size of the previous relationship if it already exists (i.e. not default 'link' relationship upon link creation)
+ // decrement the size of the previous relationship if it already exists (i.e. not default 'link' relationship upon link creation)
if (linkRelationshipList.includes(prevRelationship)) {
const pindex = linkRelationshipList.indexOf(prevRelationship);
if (pindex !== -1 && pindex < linkRelationshipSizes.length) {
@@ -1266,21 +1304,25 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
}
}
this.relationshipButtonColor = 'rgb(62, 133, 55)';
- setTimeout(
- action(() => (this.relationshipButtonColor = '')),
- 750
- );
+ setTimeout(action(() => { this.relationshipButtonColor = ''; }), 750); // prettier-ignore
return true;
}
+ return undefined;
});
- changeFollowBehavior = undoable((loc: Opt<string>) => this.sourceAnchor && (this.sourceAnchor.followLinkLocation = loc), 'change follow behavior');
+ changeFollowBehavior = undoable((loc: Opt<string>) => {
+ this.sourceAnchor && (this.sourceAnchor.followLinkLocation = loc);
+ }, 'change follow behavior');
@undoBatch
- changeAnimationBehavior = action((behavior: string) => this.sourceAnchor && (this.sourceAnchor.followLinkAnimEffect = behavior));
+ changeAnimationBehavior = action((behavior: string) => {
+ this.sourceAnchor && (this.sourceAnchor.followLinkAnimEffect = behavior);
+ });
@undoBatch
- changeEffectDirection = action((effect: PresEffectDirection) => this.sourceAnchor && (this.sourceAnchor.followLinkAnimDirection = effect));
+ changeEffectDirection = action((effect: PresEffectDirection) => {
+ this.sourceAnchor && (this.sourceAnchor.followLinkAnimDirection = effect);
+ });
animationDirection = (direction: PresEffectDirection, icon: string, gridColumn: number, gridRow: number, opts: object) => {
const lanch = this.sourceAnchor;
@@ -1301,7 +1343,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
document.getElementById('link_description_input')?.blur();
};
- onDescriptionKey = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
+ onDescriptionKey = () => {
// if (e.key === 'Enter') {
// this.setDescripValue(this.description);
// document.getElementById('link_description_input')?.blur();
@@ -1321,20 +1363,26 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
};
toggleLinkProp = (e: React.PointerEvent, prop: string) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedLink && (this.selectedLink[prop] = !this.selectedLink[prop]))));
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ undoBatch(action(() => { this.selectedLink && (this.selectedLink[prop] = !this.selectedLink[prop]); })) // prettier-ignore
+ );
};
@computed get destinationAnchor() {
const ldoc = this.selectedLink;
const lanch = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.Instance.currentLinkAnchor;
- if (ldoc && lanch) return LinkManager.getOppositeAnchor(ldoc, lanch) ?? lanch;
+ if (ldoc && lanch) return Doc.getOppositeAnchor(ldoc, lanch) ?? lanch;
return ldoc ? DocCast(ldoc.link_anchor_2) : ldoc;
}
@computed get sourceAnchor() {
const selAnchor = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.Instance.currentLinkAnchor;
- return selAnchor ?? (this.selectedLink && this.destinationAnchor ? LinkManager.getOppositeAnchor(this.selectedLink, this.destinationAnchor) : this.selectedLink);
+ return selAnchor ?? (this.selectedLink && this.destinationAnchor ? Doc.getOppositeAnchor(this.selectedLink, this.destinationAnchor) : this.selectedLink);
}
toggleAnchorProp = (e: React.PointerEvent, prop: string, anchor?: Doc, value: any = true, ovalue: any = false, cb: (val: any) => any = val => val) => {
@@ -1344,12 +1392,10 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
e,
returnFalse,
emptyFunction,
- undoBatch(
- action(() => {
- anchor[prop] = anchor[prop] === value ? ovalue : value;
- this.selectedDoc && cb(anchor[prop]);
- })
- )
+ undoBatch(action(() => {
+ anchor[prop] = anchor[prop] === value ? ovalue : value;
+ this.selectedDoc && cb(anchor[prop]);
+ })) // prettier-ignore
);
};
@@ -1357,8 +1403,8 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
get editRelationship() {
return (
<input
- style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}
- autoComplete={'off'}
+ style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }}
+ autoComplete="off"
id="link_relationship_input"
value={StrCast(this.selectedLink?.link_relationship)}
onKeyDown={this.onRelationshipKey}
@@ -1375,7 +1421,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
return (
<textarea
autoComplete="off"
- style={{ textAlign: 'left', color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}
+ style={{ textAlign: 'left', color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }}
id="link_description_input"
value={StrCast(this.selectedLink?.link_description)}
onKeyDown={this.onDescriptionKey}
@@ -1399,7 +1445,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
const zoom = Number((NumCast(this.sourceAnchor?.followLinkZoomScale, 1) * 100).toPrecision(3));
const targZoom = this.sourceAnchor?.followLinkZoom;
const indent = 30;
- const hasSelectedAnchor = LinkManager.Links(this.sourceAnchor).includes(this.selectedLink!);
+ const hasSelectedAnchor = this.selectedLink !== this.selectedDoc && Doc.Links(this.sourceAnchor).includes(this.selectedLink!);
return (
<>
@@ -1418,7 +1464,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
<div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 84px)' }}>
<p>Follow by</p>
<select
- style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}
+ style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }}
onChange={e => this.changeFollowBehavior(e.currentTarget.value === 'Default' ? undefined : e.currentTarget.value)}
value={Cast(this.sourceAnchor?.followLinkLocation, 'string', null)}>
<option value={undefined}>Default</option>
@@ -1426,7 +1472,8 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
<option value={OpenWhere.addRight}>Opening in new right pane</option>
<option value={OpenWhere.replaceLeft}>Replacing left tab</option>
<option value={OpenWhere.replaceRight}>Replacing right tab</option>
- <option value={OpenWhere.lightbox}>Opening in lightbox</option>
+ <option value={OpenWhere.lightboxAlways}>Opening in lightbox always</option>
+ <option value={OpenWhere.lightbox}>Opening in lightbox if not visible</option>
<option value={OpenWhere.add}>Opening in new tab</option>
<option value={OpenWhere.replace}>Replacing current tab</option>
<option value={OpenWhere.inParent}>Opening in same collection</option>
@@ -1436,11 +1483,11 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
<div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 134px) 50px' }}>
<p>Animation</p>
<select
- style={{ width: '100%', gridColumn: 2, color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}
+ style={{ width: '100%', gridColumn: 2, color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }}
onChange={e => this.changeAnimationBehavior(e.currentTarget.value)}
value={StrCast(this.sourceAnchor?.followLinkAnimEffect, 'default')}>
<option value="default">Default</option>
- {[PresEffect.None, PresEffect.Zoom, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
+ {[PresEffect.None, PresEffect.Expand, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
<option key={effect.toString()} value={effect.toString()}>
{effect.toString()}
</option>
@@ -1460,11 +1507,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
'10',
NumCast(this.sourceAnchor?.followLinkTransitionTime) / 1000,
true,
- (val: string) => PresBox.SetTransitionTime(val, (timeInMS: number) => this.sourceAnchor && (this.sourceAnchor.followLinkTransitionTime = timeInMS)),
+ (val: string) =>
+ PresBox.SetTransitionTime(val, (timeInMS: number) => {
+ this.sourceAnchor && (this.sourceAnchor.followLinkTransitionTime = timeInMS);
+ }),
indent
)}{' '}
<div
- className={'slider-headers'}
+ className="slider-headers"
style={{
display: 'grid',
justifyContent: 'space-between',
@@ -1479,111 +1529,147 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
</div>{' '}
<div className="propertiesView-input inline">
<p>Play Target Audio</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkAudio ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkAudio', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: !this.sourceAnchor?.followLinkAudio ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkAudio', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ }
</div>
<div className="propertiesView-input inline">
<p>Play Target Video</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkVideo ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkVideo', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: !this.sourceAnchor?.followLinkVideo ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkVideo', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ }
</div>
<div className="propertiesView-input inline">
<p>Zoom Text Selections</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkZoomText ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoomText', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: !this.sourceAnchor?.followLinkZoomText ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoomText', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ }
</div>
<div className="propertiesView-input inline">
<p>Toggle Follow to Outer Context</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkToOuterContext ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToOuterContext', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faWindowMaximize as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: !this.sourceAnchor?.followLinkToOuterContext ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToOuterContext', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faWindowMaximize as IconLookup} size="lg" />
+ </button>
+ }
</div>
<div className="propertiesView-input inline">
<p>Toggle Target (Show/Hide)</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkToggle ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToggle', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: !this.sourceAnchor?.followLinkToggle ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToggle', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ }
</div>
<div className="propertiesView-input inline">
<p>Ease Transitions</p>
- <button
- style={{ background: this.sourceAnchor?.followLinkEase === 'linear' ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkEase', this.sourceAnchor, 'ease', 'linear')}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: this.sourceAnchor?.followLinkEase === 'linear' ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkEase', this.sourceAnchor, 'ease', 'linear')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ }
</div>
<div className="propertiesView-input inline">
<p>Capture Offset to Target</p>
- <button
- style={{ background: this.sourceAnchor?.followLinkXoffset === undefined ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => {
- this.toggleAnchorProp(e, 'followLinkXoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.x) - NumCast(this.sourceAnchor?.x), undefined);
- this.toggleAnchorProp(e, 'followLinkYoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.y) - NumCast(this.sourceAnchor?.y), undefined);
- }}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: this.sourceAnchor?.followLinkXoffset === undefined ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => {
+ this.toggleAnchorProp(e, 'followLinkXoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.x) - NumCast(this.sourceAnchor?.x), undefined);
+ this.toggleAnchorProp(e, 'followLinkYoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.y) - NumCast(this.sourceAnchor?.y), undefined);
+ }}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ }
</div>
<div className="propertiesView-input inline">
<p>Center Target (no zoom)</p>
- <button
- style={{ background: this.sourceAnchor?.followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: this.sourceAnchor?.followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ }
</div>
<div className="propertiesView-input inline" style={{ display: 'grid', gridTemplateColumns: '78px calc(100% - 108px) 50px' }}>
<p>Zoom %</p>
<div className="ribbon-property" style={{ display: !targZoom ? 'none' : 'inline-flex' }}>
- <input className="presBox-input" style={{ width: '100%', color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} readOnly={true} type="number" value={zoom} />
+ <input className="presBox-input" style={{ width: '100%', color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }} readOnly type="number" value={zoom} />
<div className="ribbon-propertyUpDown" style={{ display: 'flex', flexDirection: 'column' }}>
<div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}>
- <FontAwesomeIcon icon={'caret-up'} />
+ <FontAwesomeIcon icon="caret-up" />
</div>
<div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}>
- <FontAwesomeIcon icon={'caret-down'} />
+ <FontAwesomeIcon icon="caret-down" />
</div>
</div>
</div>
- <button
- style={{ background: !targZoom || this.sourceAnchor?.followLinkZoomScale === 0 ? '' : '#4476f7', borderRadius: 3, gridColumn: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button
+ type="button"
+ style={{ background: !targZoom || this.sourceAnchor?.followLinkZoomScale === 0 ? '' : '#4476f7', borderRadius: 3, gridColumn: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+ </button>
+ }
</div>
{!targZoom ? null : PresBox.inputter('0', '1', '100', zoom, true, this.setZoom, 30)}
<div
- className={'slider-headers'}
+ className="slider-headers"
style={{
display: !targZoom ? 'none' : 'grid',
justifyContent: 'space-between',
@@ -1595,7 +1681,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
}}>
<div className="slider-text">0%</div>
<div className="slider-text">100%</div>
- </div>{' '}
+ </div>
</div>
)}
</>
@@ -1615,7 +1701,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
render() {
const isNovice = Doc.noviceMode;
- const hasSelectedAnchor = LinkManager.Links(this.sourceAnchor).includes(this.selectedLink!);
if (!this.selectedDoc && !this.isPres) {
return (
<div className="propertiesView" style={{ width: this._props.width }}>
@@ -1624,128 +1709,140 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
</div>
</div>
);
- } else {
- if (this.selectedDoc && !this.isPres) {
- return (
- <div
- className="propertiesView"
- style={{
- background: SettingsManager.userBackgroundColor,
- color: SettingsManager.userColor,
- width: this._props.width,
- minWidth: this._props.width,
- }}>
- <div className="propertiesView-propAndInfoGrouping">
- <div className="propertiesView-sectionTitle" style={{ width: this._props.width }}>
- Properties
- <div className="propertiesView-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/properties')}>
- <IconButton icon={<FontAwesomeIcon icon="info-circle" />} color={SettingsManager.userColor} />
- </div>
+ }
+ if (this.selectedDoc && !this.isPres) {
+ return (
+ <div
+ className="propertiesView"
+ style={{
+ background: SnappingManager.userBackgroundColor,
+ color: SnappingManager.userColor,
+ width: this._props.width,
+ minWidth: this._props.width,
+ }}>
+ <div className="propertiesView-propAndInfoGrouping">
+ <div className="propertiesView-sectionTitle" style={{ width: this._props.width }}>
+ Properties
+ <div className="propertiesView-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/properties')}>
+ <IconButton icon={<FontAwesomeIcon icon="info-circle" />} color={SnappingManager.userColor} />
</div>
</div>
-
- <div className="propertiesView-name">{this.editableTitle}</div>
- <div className="propertiesView-type"> {this.currentType} </div>
- {this.fieldsSubMenu}
- {this.optionsSubMenu}
- {this.linksSubMenu}
- {!this.selectedLink || !this.openLinks ? null : this.linkProperties}
- {this.inkSubMenu}
- {this.contextsSubMenu}
- {isNovice ? null : this.sharingSubMenu}
- {this.filtersSubMenu}
- {isNovice ? null : this.layoutSubMenu}
</div>
- );
- }
- if (this.isPres && PresBox.Instance) {
- const selectedItem: boolean = PresBox.Instance.selectedArray.size > 0;
- const type = [DocumentType.AUDIO, DocumentType.VID].includes(DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType)
- ? (DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType)
- : PresBox.targetRenderedDoc(PresBox.Instance.activeItem)?.type;
- return (
- <div className="propertiesView" style={{ width: this._props.width }}>
- <div className="propertiesView-sectionTitle" style={{ width: this._props.width }}>
- Presentation
+
+ <div className="propertiesView-name">{this.editableTitle}</div>
+ <div className="propertiesView-type"> {this.currentType} </div>
+ {/* {this.stylingSubMenu} */}
+ {this.fieldsSubMenu}
+ {this.optionsSubMenu}
+ {this.linksSubMenu}
+ {!this.selectedLink || !this.openLinks ? null : this.linkProperties}
+ {this.inkSubMenu}
+ {this.contextsSubMenu}
+ {isNovice ? null : this.sharingSubMenu}
+ {this.filtersSubMenu}
+ {isNovice ? null : this.layoutSubMenu}
+ </div>
+ );
+ }
+ if (this.isPres && PresBox.Instance) {
+ const selectedItem: boolean = PresBox.Instance.selectedArray.size > 0;
+ const type = [DocumentType.AUDIO, DocumentType.VID].includes(DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType)
+ ? (DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType)
+ : PresBox.targetRenderedDoc(PresBox.Instance.activeItem)?.type;
+ return (
+ <div className="propertiesView" style={{ width: this._props.width }}>
+ <div className="propertiesView-sectionTitle" style={{ width: this._props.width }}>
+ Presentation
+ <div className="propertiesView-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/trails/')}>
+ <IconButton icon={<FontAwesomeIcon icon="info-circle" />} color={SnappingManager.userColor} />
</div>
- <div className="propertiesView-name" style={{ borderBottom: 0 }}>
- {this.editableTitle}
- <div className="propertiesView-presSelected">
- <div className="propertiesView-selectedCount">{PresBox.Instance.selectedArray.size} selected</div>
- <div className="propertiesView-selectedList">{PresBox.Instance.listOfSelected}</div>
- </div>
+ </div>
+ <div className="propertiesView-name" style={{ borderBottom: 0 }}>
+ {this.editableTitle}
+ <div className="propertiesView-presSelected">
+ <div className="propertiesView-selectedCount">{PresBox.Instance.selectedArray.size} selected</div>
+ <div className="propertiesView-selectedList">{PresBox.Instance.listOfSelected}</div>
</div>
- {!selectedItem ? null : (
- <div className="propertiesView-presentationTrails">
- <div
- className="propertiesView-presentationTrails-title"
- onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))}
- style={{
- color: SettingsManager.userColor,
- backgroundColor: this.openPresTransitions ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor,
- }}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Transitions
- <div className="propertiesView-presentationTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" />
- </div>
+ </div>
+ {!selectedItem ? null : (
+ <div className="propertiesView-presentationTrails">
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => {
+ this.openPresTransitions = !this.openPresTransitions;
+ })}
+ style={{
+ color: SnappingManager.userColor,
+ backgroundColor: this.openPresTransitions ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}>
+ &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> &nbsp; Transitions
+ <div className="propertiesView-presentationTrails-title-icon">
+ <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" />
</div>
- {this.openPresTransitions ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.transitionDropdown}</div> : null}
</div>
- )}
- {!selectedItem ? null : (
- <div className="propertiesView-presentationTrails">
- <div
- className="propertiesView-presentationTrails-title"
- onPointerDown={action(() => (this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration))}
- style={{
- color: SettingsManager.userColor,
- backgroundColor: this.openPresVisibilityAndDuration ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor,
- }}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Visibility
- <div className="propertiesView-presentationTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" />
- </div>
+ {this.openPresTransitions ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.transitionDropdown}</div> : null}
+ </div>
+ )}
+ {!selectedItem ? null : (
+ <div className="propertiesView-presentationTrails">
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => {
+ this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration;
+ })}
+ style={{
+ color: SnappingManager.userColor,
+ backgroundColor: this.openPresVisibilityAndDuration ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}>
+ &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> &nbsp; Visibility
+ <div className="propertiesView-presentationTrails-title-icon">
+ <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" />
</div>
- {this.openPresVisibilityAndDuration ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.visibilityDurationDropdown}</div> : null}
</div>
- )}
- {!selectedItem ? null : (
- <div className="propertiesView-presentationTrails">
- <div
- className="propertiesView-presentationTrails-title"
- onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))}
- style={{
- color: SettingsManager.userColor,
- backgroundColor: this.openPresProgressivize ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor,
- }}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Progressivize
- <div className="propertiesView-presentationTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" />
- </div>
+ {this.openPresVisibilityAndDuration ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.visibilityDurationDropdown}</div> : null}
+ </div>
+ )}
+ {!selectedItem ? null : (
+ <div className="propertiesView-presentationTrails">
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => {
+ this.openPresProgressivize = !this.openPresProgressivize;
+ })}
+ style={{
+ color: SnappingManager.userColor,
+ backgroundColor: this.openPresProgressivize ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}>
+ &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> &nbsp; Progressivize
+ <div className="propertiesView-presentationTrails-title-icon">
+ <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" />
</div>
- {this.openPresProgressivize ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.progressivizeDropdown}</div> : null}
</div>
- )}
- {!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? null : (
- <div className="propertiesView-presentationTrails">
- <div
- className="propertiesView-presentationTrails-title"
- onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))}
- style={{
- color: SettingsManager.userColor,
- backgroundColor: this.openSlideOptions ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor,
- }}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> &nbsp; {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'}
- <div className="propertiesView-presentationTrails-title-icon">
- <FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" />
- </div>
+ {this.openPresProgressivize ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.progressivizeDropdown}</div> : null}
+ </div>
+ )}
+ {!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? null : (
+ <div className="propertiesView-presentationTrails">
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => {
+ this.openSlideOptions = !this.openSlideOptions;
+ })}
+ style={{
+ color: SnappingManager.userColor,
+ backgroundColor: this.openSlideOptions ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}>
+ &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> &nbsp; {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'}
+ <div className="propertiesView-presentationTrails-title-icon">
+ <FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" />
</div>
- {this.openSlideOptions ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.mediaOptionsDropdown}</div> : null}
</div>
- )}
- </div>
- );
- }
+ {this.openSlideOptions ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.mediaOptionsDropdown}</div> : null}
+ </div>
+ )}
+ </div>
+ );
}
+ return null;
}
}
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index 623201ed1..9c36e6d26 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -1,17 +1,18 @@
+/* eslint-disable react/require-default-props */
import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { emptyFunction } from '../../Utils';
import { Doc, Opt } from '../../fields/Doc';
+import { DocData } from '../../fields/DocSymbols';
import { ScriptField } from '../../fields/ScriptField';
import { ScriptCast } from '../../fields/Types';
-import { emptyFunction } from '../../Utils';
import { DragManager } from '../util/DragManager';
import { CompileScript } from '../util/Scripting';
import { EditableView } from './EditableView';
-import { DocumentIconContainer } from './nodes/DocumentIcon';
import { OverlayView } from './OverlayView';
import './ScriptBox.scss';
-import { DocData } from '../../fields/DocSymbols';
+import { DocumentIconContainer } from './nodes/DocumentIcon';
export interface ScriptBoxProps {
onSave: (text: string, onError: (error: string) => void) => void;
@@ -25,6 +26,7 @@ export interface ScriptBoxProps {
export class ScriptBox extends React.Component<ScriptBoxProps> {
@observable
private _scriptText: string;
+ overlayDisposer?: () => void;
constructor(props: ScriptBoxProps) {
super(props);
@@ -42,7 +44,6 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
console.log('ScriptBox: ' + error);
};
- overlayDisposer?: () => void;
onFocus = () => {
this.overlayDisposer?.();
this.overlayDisposer = OverlayView.Instance.addElement(<DocumentIconContainer />, { x: 0, y: 0 });
@@ -53,21 +54,35 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
};
render() {
- let onFocus: Opt<() => void> = undefined,
- onBlur: Opt<() => void> = undefined;
+ let onFocus: Opt<() => void>;
+ let onBlur: Opt<() => void>;
if (this.props.showDocumentIcons) {
onFocus = this.onFocus;
onBlur = this.onBlur;
}
- const params = <EditableView contents={''} display={'block'} maxHeight={72} height={35} fontSize={28} GetValue={() => ''} SetValue={(value: string) => (this.props.setParams?.(value.split(' ').filter(s => s !== ' ')) ? true : true)} />;
+ const params = (
+ <EditableView
+ contents=""
+ display="block"
+ maxHeight={72}
+ height={35}
+ fontSize={28}
+ GetValue={() => ''}
+ SetValue={(value: string) => {
+ this.props.setParams?.(value.split(' ').filter(s => s !== ' '));
+ return true;
+ }}
+ />
+ );
return (
<div className="scriptBox-outerDiv">
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
- <textarea className="scriptBox-textarea" onChange={this.onChange} value={this._scriptText} onFocus={onFocus} onBlur={onBlur}></textarea>
+ <textarea className="scriptBox-textarea" onChange={this.onChange} value={this._scriptText} onFocus={onFocus} onBlur={onBlur} />
<div style={{ background: 'beige' }}>{params}</div>
</div>
<div className="scriptBox-toolbar">
<button
+ type="button"
onClick={e => {
this.props.onSave(this._scriptText, this.onError);
e.stopPropagation();
@@ -75,6 +90,7 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
Save
</button>
<button
+ type="button"
onClick={e => {
this.props.onCancel && this.props.onCancel();
e.stopPropagation();
@@ -85,11 +101,12 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
</div>
);
}
- //let l = docList(this.source[0].data).length; if (l) { let ind = this.target[0].index !== undefined ? (this.target[0].index+1) % l : 0; this.target[0].index = ind; this.target[0].proto = getProto(docList(this.source[0].data)[ind]);}
+ // let l = docList(this.source[0].data).length; if (l) { let ind = this.target[0].index !== undefined ? (this.target[0].index+1) % l : 0; this.target[0].index = ind; this.target[0].proto = getProto(docList(this.source[0].data)[ind]);}
+ // eslint-disable-next-line react/sort-comp
public static EditButtonScript(title: string, doc: Doc, fieldKey: string, clientX: number, clientY: number, contextParams?: { [name: string]: string }, defaultScript?: ScriptField) {
let overlayDisposer: () => void = emptyFunction;
const script = ScriptCast(doc[fieldKey]) || defaultScript;
- let originalText: string | undefined = undefined;
+ let originalText: string | undefined;
if (script) {
originalText = script.script.originalScript;
}
@@ -105,14 +122,14 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
if (!text) {
doc[DocData][fieldKey] = undefined;
} else {
- const script = CompileScript(text, {
+ const compScript = CompileScript(text, {
params: { this: Doc.name, ...contextParams },
typecheck: false,
editable: true,
transformer: DocumentIconContainer.getTransformer(),
});
- if (!script.compiled) {
- onError(script.errors.map(error => error.messageText).join('\n'));
+ if (!compScript.compiled) {
+ onError(compScript.errors.map(error => error.messageText).join('\n'));
return;
}
@@ -124,9 +141,9 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
div.style.display = 'inline-block';
div.style.transform = `translate(${clientX}px, ${clientY}px)`;
div.innerHTML = 'button';
- params.length && DragManager.StartButtonDrag([div], text, doc.title + '-instance', {}, params, (button: Doc) => {}, clientX, clientY);
+ params.length && DragManager.StartButtonDrag([div], text, doc.title + '-instance', {}, params, () => {}, clientX, clientY);
- doc[DocData][fieldKey] = new ScriptField(script);
+ doc[DocData][fieldKey] = new ScriptField(compScript);
overlayDisposer();
}
}}
diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx
index acf0ecff4..1a2eb460f 100644
--- a/src/client/views/ScriptingRepl.tsx
+++ b/src/client/views/ScriptingRepl.tsx
@@ -1,17 +1,50 @@
+/* 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';
import * as React from 'react';
-import { DocumentManager } from '../util/DocumentManager';
import { CompileScript, Transformer, ts } from '../util/Scripting';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
-import { SettingsManager } from '../util/SettingsManager';
+import { SnappingManager } from '../util/SnappingManager';
import { undoable } from '../util/UndoManager';
import { ObservableReactComponent } from './ObservableReactComponent';
import { OverlayView } from './OverlayView';
import './ScriptingRepl.scss';
import { DocumentIconContainer } from './nodes/DocumentIcon';
+import { DocumentView } from './nodes/DocumentView';
+interface replValueProps {
+ scrollToBottom: () => void;
+ value: any;
+ name?: string;
+}
+@observer
+export class ScriptingValueDisplay extends ObservableReactComponent<replValueProps> {
+ constructor(props: any) {
+ super(props);
+ makeObservable(this);
+ }
+
+ render() {
+ const val = this._props.name ? this._props.value[this._props.name] : this._props.value;
+ const title = (name: string) => (
+ <>
+ {this._props.name ? <b>{this._props.name} : </b> : <> </>}
+ {name}
+ </>
+ );
+ if (typeof val === 'object') {
+ // eslint-disable-next-line no-use-before-define
+ return <ScriptingObjectDisplay scrollToBottom={this._props.scrollToBottom} value={val} name={this._props.name} />;
+ }
+ if (typeof val === 'function') {
+ return <div className="scriptingObject-leaf">{title('[Function]')}</div>;
+ }
+ return <div className="scriptingObject-leaf">{title(String(val))}</div>;
+ }
+}
interface ReplProps {
scrollToBottom: () => void;
value: { [key: string]: any };
@@ -37,7 +70,7 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps>
const name = (proto && proto.constructor && proto.constructor.name) || String(val);
const title = (
<>
- {this.props.name ? <b>{this._props.name} : </b> : <></>}
+ {this.props.name ? <b>{this._props.name} : </b> : null}
{name}
</>
);
@@ -50,53 +83,23 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps>
{title} (+{Object.keys(val).length})
</div>
);
- } else {
- return (
- <div className="scriptingObject-open">
- <div>
- <span onClick={this.toggle} className="scriptingObject-icon">
- <FontAwesomeIcon icon="caret-down" size="sm" />
- </span>
- {title}
- </div>
- <div className="scriptingObject-fields">
- {Object.keys(val).map(key => (
- <ScriptingValueDisplay {...this._props} name={key} />
- ))}
- </div>
- </div>
- );
}
- }
-}
-
-interface replValueProps {
- scrollToBottom: () => void;
- value: any;
- name?: string;
-}
-@observer
-export class ScriptingValueDisplay extends ObservableReactComponent<replValueProps> {
- constructor(props: any) {
- super(props);
- makeObservable(this);
- }
-
- render() {
- const val = this._props.name ? this._props.value[this._props.name] : this._props.value;
- const title = (name: string) => (
- <>
- {this._props.name ? <b>{this._props.name} : </b> : <> </>}
- {name}
- </>
+ return (
+ <div className="scriptingObject-open">
+ <div>
+ <span onClick={this.toggle} className="scriptingObject-icon">
+ <FontAwesomeIcon icon="caret-down" size="sm" />
+ </span>
+ {title}
+ </div>
+ <div className="scriptingObject-fields">
+ {Object.keys(val).map(key => (
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ <ScriptingValueDisplay {...this._props} name={key} />
+ ))}
+ </div>
+ </div>
);
- if (typeof val === 'object') {
- return <ScriptingObjectDisplay scrollToBottom={this._props.scrollToBottom} value={val} name={this._props.name} />;
- } else if (typeof val === 'function') {
- const name = '[Function]';
- return <div className="scriptingObject-leaf">{title('[Function]')}</div>;
- }
- return <div className="scriptingObject-leaf">{title(String(val))}</div>;
}
}
@@ -119,47 +122,45 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
private args: any = {};
- getTransformer = (): Transformer => {
- return {
- transformer: context => {
- const knownVars: { [name: string]: number } = {};
- const usedDocuments: number[] = [];
- ScriptingGlobals.getGlobals().forEach((global: any) => (knownVars[global] = 1));
- return root => {
- function visit(node: ts.Node) {
- let skip = false;
- if (ts.isIdentifier(node)) {
- if (ts.isParameter(node.parent)) {
- skip = true;
- knownVars[node.text] = 1;
- }
+ getTransformer = (): Transformer => ({
+ transformer: context => {
+ const knownVars: { [name: string]: number } = {};
+ const usedDocuments: number[] = [];
+ ScriptingGlobals.getGlobals().forEach((global: any) => {
+ knownVars[global] = 1;
+ });
+ return root => {
+ function visit(nodeIn: ts.Node) {
+ if (ts.isIdentifier(nodeIn)) {
+ if (ts.isParameter(nodeIn.parent)) {
+ knownVars[nodeIn.text] = 1;
}
- node = ts.visitEachChild(node, visit, context);
+ }
+ const node = ts.visitEachChild(nodeIn, visit, context);
- if (ts.isIdentifier(node)) {
- const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node;
- const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node;
- if (ts.isParameter(node.parent)) {
- // delete knownVars[node.text];
- } else if (isntPropAccess && isntPropAssign && !(node.text in knownVars) && !(node.text in globalThis)) {
- const match = node.text.match(/d([0-9]+)/);
- if (match) {
- const m = parseInt(match[1]);
- usedDocuments.push(m);
- } else {
- return ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('args'), node);
- // ts.createPropertyAccess(ts.createIdentifier('args'), node);
- }
+ if (ts.isIdentifier(node)) {
+ const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node;
+ const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node;
+ if (ts.isParameter(node.parent)) {
+ // delete knownVars[node.text];
+ } else if (isntPropAccess && isntPropAssign && !(node.text in knownVars) && !(node.text in globalThis)) {
+ const match = node.text.match(/d([0-9]+)/);
+ if (match) {
+ const m = parseInt(match[1]);
+ usedDocuments.push(m);
+ } else {
+ return ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('args'), node);
+ // ts.createPropertyAccess(ts.createIdentifier('args'), node);
}
}
-
- return node;
}
- return ts.visitNode(root, visit);
- };
- },
- };
- };
+
+ return node;
+ }
+ return ts.visitNode(root, visit);
+ };
+ },
+ });
@action
onKeyDown = (e: React.KeyboardEvent) => {
@@ -168,14 +169,16 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
case 'Enter': {
e.stopPropagation();
const docGlobals: { [name: string]: any } = {};
- DocumentManager.Instance.DocumentViews.forEach((dv, i) => (docGlobals[`d${i}`] = dv.Document));
+ DocumentView.allViews().forEach((dv, i) => {
+ docGlobals[`d${i}`] = dv.Document;
+ });
const globals = ScriptingGlobals.makeMutableGlobalsCopy(docGlobals);
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 });
return;
}
- const result = undoable(() => script.run({ args: this.args }, e => this.commands.push({ command: this.commandString, result: e.toString() })), 'run:' + this.commandString)();
+ const result = undoable(() => script.run({ args: this.args }, () => this.commands.push({ command: this.commandString, result: e.toString() })), 'run:' + this.commandString)();
if (result.success) {
this.commands.push({ command: this.commandString, result: result.result });
this.commandsHistory.push(this.commandString);
@@ -259,23 +262,21 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
render() {
return (
<div className="scriptingRepl-outerContainer">
- <div className="scriptingRepl-commandsContainer" style={{ background: SettingsManager.userBackgroundColor }} ref={this.commandsRef}>
- {this.commands.map(({ command, result }, i) => {
- return (
- <div className="scriptingRepl-resultContainer" style={{ background: SettingsManager.userBackgroundColor }} key={i}>
- <div className="scriptingRepl-commandString" style={{ background: SettingsManager.userBackgroundColor }}>
- {command || <br />}
- </div>
- <div className="scriptingRepl-commandResult" style={{ background: SettingsManager.userBackgroundColor }}>
- {<ScriptingValueDisplay scrollToBottom={this.maybeScrollToBottom} value={result} />}
- </div>
+ <div className="scriptingRepl-commandsContainer" style={{ background: SnappingManager.userBackgroundColor }} ref={this.commandsRef}>
+ {this.commands.map(({ command, result }, i) => (
+ <div className="scriptingRepl-resultContainer" style={{ background: SnappingManager.userBackgroundColor }} key={i}>
+ <div className="scriptingRepl-commandString" style={{ background: SnappingManager.userBackgroundColor }}>
+ {command || <br />}
+ </div>
+ <div className="scriptingRepl-commandResult" style={{ background: SnappingManager.userBackgroundColor }}>
+ <ScriptingValueDisplay scrollToBottom={this.maybeScrollToBottom} value={result} />
</div>
- );
- })}
+ </div>
+ ))}
</div>
<input
className="scriptingRepl-commandInput"
- style={{ background: SettingsManager.userBackgroundColor }} //
+ style={{ background: SnappingManager.userBackgroundColor }} //
onFocus={this.onFocus}
onBlur={this.onBlur}
value={this.commandString}
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 1e9272e93..9b70f1ca7 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -1,24 +1,27 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnAll, returnFalse, returnOne, returnZero } from '../../Utils';
-import { Doc, DocListCast, Field, FieldResult, StrListCast } from '../../fields/Doc';
+import { ClientUtils, returnAll, returnFalse, returnOne, returnZero } from '../../ClientUtils';
+import { emptyFunction } from '../../Utils';
+import { Doc, DocListCast, Field, FieldType, FieldResult, StrListCast } from '../../fields/Doc';
+import { DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
import { RichTextField } from '../../fields/RichTextField';
import { DocCast, NumCast, StrCast } from '../../fields/Types';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
-import { DocUtils, Docs } from '../documents/Documents';
-import { LinkManager } from '../util/LinkManager';
+import { Docs } from '../documents/Documents';
+import { DocUtils } from '../documents/DocUtils';
import { SearchUtil } from '../util/SearchUtil';
import { Transform } from '../util/Transform';
import { ObservableReactComponent } from './ObservableReactComponent';
import './SidebarAnnos.scss';
-import { StyleProp } from './StyleProvider';
+import { StyleProp } from './StyleProp';
import { CollectionStackingView } from './collections/CollectionStackingView';
import { FieldViewProps } from './nodes/FieldView';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
-import { DocData } from '../../fields/DocSymbols';
interface ExtraProps {
fieldKey: string;
@@ -44,7 +47,7 @@ export class SidebarAnnos extends ObservableReactComponent<FieldViewProps & Extr
_stackRef = React.createRef<CollectionStackingView>();
@computed get allMetadata() {
- const keys = new Map<string, FieldResult<Field>>();
+ const keys = new Map<string, FieldResult<FieldType>>();
DocListCast(this._props.Document[this.sidebarKey]).forEach(doc =>
SearchUtil.documentKeys(doc)
.filter(key => key[0] && key[0] !== '_' && key[0] === key[0].toUpperCase())
@@ -80,10 +83,9 @@ export class SidebarAnnos extends ObservableReactComponent<FieldViewProps & Extr
_text_fontSize: StrCast(Doc.UserDoc().fontSize),
_text_fontFamily: StrCast(Doc.UserDoc().fontFamily),
});
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
FormattedTextBox.DontSelectInitialText = true;
const link = DocUtils.MakeLink(anchor, target, { link_relationship: 'inline comment:comment on' });
- link && (link.link_displayLine = false);
const taggedContent = this.childFilters()
.filter(data => data.split(':')[0])
@@ -94,8 +96,8 @@ export class SidebarAnnos extends ObservableReactComponent<FieldViewProps & Extr
target[DocData][key] = val;
return {
type: 'dashField',
- attrs: { fieldKey: key, docId: '', hideKey: false, editable: true },
- marks: [{ type: 'pFontSize', attrs: { fontSize: '12px' } }, { type: 'strong' }, { type: 'user_mark', attrs: { userid: Doc.CurrentUserEmail, modified: 0 } }],
+ attrs: { fieldKey: key, docId: '', hideKey: false, hideValue: false, editable: true },
+ marks: [{ type: 'pFontSize', attrs: { fontSize: '12px' } }, { type: 'strong' }, { type: 'user_mark', attrs: { userid: ClientUtils.CurrentUserEmail(), modified: 0 } }],
};
});
@@ -121,7 +123,7 @@ export class SidebarAnnos extends ObservableReactComponent<FieldViewProps & Extr
{ type: 'pFontSize', attrs: { fontSize: '8px' } },
{ type: 'em' },
],
- attrs: { fieldKey: 'text', docId: anchor[Id], hideKey: true, editable: false },
+ attrs: { fieldKey: 'text', docId: anchor[Id], hideKey: true, hideValue: false, editable: false },
},
],
},
@@ -183,8 +185,8 @@ export class SidebarAnnos extends ObservableReactComponent<FieldViewProps & Extr
layout_showTitle = () => 'title';
setHeightCallback = (height: number) => this._props.setHeight?.(height + this.filtersHeight());
sortByLinkAnchorY = (a: Doc, b: Doc) => {
- const ay = LinkManager.Links(a).length && DocCast(LinkManager.Links(a)[0].link_anchor_1).y;
- const by = LinkManager.Links(b).length && DocCast(LinkManager.Links(b)[0].link_anchor_1).y;
+ const ay = Doc.Links(a).length && DocCast(Doc.Links(a)[0].link_anchor_1).y;
+ const by = Doc.Links(b).length && DocCast(Doc.Links(b)[0].link_anchor_1).y;
return NumCast(ay) - NumCast(by);
};
render() {
@@ -196,7 +198,7 @@ export class SidebarAnnos extends ObservableReactComponent<FieldViewProps & Extr
</div>
);
};
- const renderMeta = (tag: string, dflt: FieldResult<Field>) => {
+ const renderMeta = (tag: string) => {
const active = this.childFilters().includes(`${tag}${Doc.FilterSep}${Doc.FilterAny}${Doc.FilterSep}exists`);
return (
<div key={tag} className={`sidebarAnnos-filterTag${active ? '-active' : ''}`} onClick={e => Doc.setDocFilter(this._props.Document, tag, Doc.FilterAny, 'exists', true, undefined, e.shiftKey)}>
@@ -227,13 +229,12 @@ export class SidebarAnnos extends ObservableReactComponent<FieldViewProps & Extr
<div className="sidebarAnnos-tagList" style={{ height: this.filtersHeight() }} onWheel={e => e.stopPropagation()}>
{this.allUsers.length > 1 ? this.allUsers.map(renderUsers) : null}
{this.allHashtags.map(renderTag)}
- {Array.from(this.allMetadata.keys())
- .sort()
- .map(key => renderMeta(key, this.allMetadata.get(key)))}
+ {Array.from(this.allMetadata.keys()).sort().map(renderMeta)}
</div>
<div style={{ width: '100%', height: `calc(100% - 38px)`, position: 'relative' }}>
<CollectionStackingView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setContentViewBox={emptyFunction}
NativeWidth={returnZero}
@@ -247,11 +248,11 @@ export class SidebarAnnos extends ObservableReactComponent<FieldViewProps & Extr
isAnnotationOverlay={false}
select={emptyFunction}
NativeDimScaling={returnOne}
- //childlayout_showTitle={this.layout_showTitle}
+ // childlayout_showTitle={this.layout_showTitle}
isAnyChildContentActive={returnFalse}
childDocumentsActive={this._props.isContentActive}
whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
- childHideDecorationTitle={true}
+ childHideDecorationTitle
removeDocument={this.removeDocument}
moveDocument={this.moveDocument}
addDocument={this.addDocument}
diff --git a/src/client/views/StyleProp.ts b/src/client/views/StyleProp.ts
new file mode 100644
index 000000000..dd5b98cfe
--- /dev/null
+++ b/src/client/views/StyleProp.ts
@@ -0,0 +1,24 @@
+export enum StyleProp {
+ TreeViewIcon = 'treeView_Icon',
+ TreeViewSortings = 'treeView_Sortings', // options for how to sort tree view items
+ DocContents = 'docContents', // when specified, the JSX returned will replace the normal rendering of the document view
+ Opacity = 'opacity', // opacity of the document view
+ BoxShadow = 'boxShadow', // box shadow - used for making collections standout and for showing clusters in free form views
+ BorderRounding = 'borderRounding', // border radius of the document view
+ Color = 'color', // foreground color of Document view items
+ BackgroundColor = 'backgroundColor', // background color of a document view
+ FillColor = 'fillColor', // fill color of an ink stroke or shape
+ WidgetColor = 'widgetColor', // color to display UI widgets on a document view -- used for the sidebar divider dragger on a text note
+ PointerEvents = 'pointerEvents', // pointer events for DocumentView -- inherits pointer events if not specified
+ Decorations = 'decorations', // additional decoration to display above a DocumentView -- currently only used to display a Lock for making things background
+ HeaderMargin = 'headerMargin', // margin at top of documentview, typically for displaying a title -- doc contents will start below that
+ ShowCaption = 'layout_showCaption',
+ TitleHeight = 'titleHeight', // Height of Title area
+ ShowTitle = 'layout_showTitle', // whether to display a title on a Document (optional :hover suffix)
+ BorderPath = 'customBorder', // border path for document view
+ FontColor = 'fontColor', // color o tet
+ FontSize = 'fontSize', // size of text font
+ FontFamily = 'fontFamily', // font family of text
+ FontWeight = 'fontWeight', // font weight of text
+ Highlighting = 'highlighting', // border highlighting
+}
diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss
index 30a026dbc..ce00f6101 100644
--- a/src/client/views/StyleProvider.scss
+++ b/src/client/views/StyleProvider.scss
@@ -3,6 +3,7 @@
.styleProvider-paint,
.styleProvider-paint-selected,
.styleProvider-lock {
+ z-index: 2; // has to be above title which is z-index 1
font-size: 10;
width: 15;
height: 15;
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index ab811858a..b7f8a3170 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -1,3 +1,6 @@
+/* eslint-disable jsx-a11y/alt-text */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
@@ -7,49 +10,24 @@ import { extname } from 'path';
import * as React from 'react';
import { BsArrowDown, BsArrowDownUp, BsArrowUp } from 'react-icons/bs';
import { FaFilter } from 'react-icons/fa';
+import { ClientUtils, DashColor, lightOrDark } from '../../ClientUtils';
import { Doc, Opt, StrListCast } from '../../fields/Doc';
-import { DocViews } from '../../fields/DocSymbols';
+import { Id } from '../../fields/FieldSymbols';
+import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, Cast, DocCast, ImageCast, NumCast, ScriptCast, StrCast } from '../../fields/Types';
-import { DashColor, lightOrDark, Utils } from '../../Utils';
+import { AudioAnnoState } from '../../server/SharedMediaTypes';
+import { emptyPath } from '../../Utils';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
-import { DocFocusOrOpen, DocumentManager } from '../util/DocumentManager';
-import { IsFollowLinkScript } from '../util/LinkFollower';
-import { LinkManager } from '../util/LinkManager';
-import { SettingsManager } from '../util/SettingsManager';
+import { IsFollowLinkScript } from '../documents/DocUtils';
import { SnappingManager } from '../util/SnappingManager';
import { undoBatch, UndoManager } from '../util/UndoManager';
import { TreeSort } from './collections/TreeSort';
import { Colors } from './global/globalEnums';
-import { DocumentViewProps } from './nodes/DocumentView';
+import { DocumentView, DocumentViewProps } from './nodes/DocumentView';
import { FieldViewProps } from './nodes/FieldView';
-import { KeyValueBox } from './nodes/KeyValueBox';
-import { PropertiesView } from './PropertiesView';
+import { StyleProp } from './StyleProp';
import './StyleProvider.scss';
-export enum StyleProp {
- TreeViewIcon = 'treeView_Icon',
- TreeViewSortings = 'treeView_Sortings', // options for how to sort tree view items
- DocContents = 'docContents', // when specified, the JSX returned will replace the normal rendering of the document view
- Opacity = 'opacity', // opacity of the document view
- BoxShadow = 'boxShadow', // box shadow - used for making collections standout and for showing clusters in free form views
- BorderRounding = 'borderRounding', // border radius of the document view
- Color = 'color', // foreground color of Document view items
- BackgroundColor = 'backgroundColor', // background color of a document view
- FillColor = 'fillColor', // fill color of an ink stroke or shape
- WidgetColor = 'widgetColor', // color to display UI widgets on a document view -- used for the sidebar divider dragger on a text note
- PointerEvents = 'pointerEvents', // pointer events for DocumentView -- inherits pointer events if not specified
- Decorations = 'decorations', // additional decoration to display above a DocumentView -- currently only used to display a Lock for making things background
- HeaderMargin = 'headerMargin', // margin at top of documentview, typically for displaying a title -- doc contents will start below that
- ShowCaption = 'layout_showCaption',
- TitleHeight = 'titleHeight', // Height of Title area
- ShowTitle = 'layout_showTitle', // whether to display a title on a Document (optional :hover suffix)
- BorderPath = 'customBorder', // border path for document view
- FontSize = 'fontSize', // size of text font
- FontFamily = 'fontFamily', // font family of text
- FontWeight = 'fontWeight', // font weight of text
- Highlighting = 'highlighting', // border highlighting
-}
-
function toggleLockedPosition(doc: Doc) {
UndoManager.RunInBatch(() => Doc.toggleLockedPosition(doc), 'toggleBackground');
}
@@ -64,6 +42,19 @@ function togglePaintView(e: React.MouseEvent, doc: Opt<Doc>, props: Opt<FieldVie
ScriptCast(doc?.onPaint)?.script.run(scriptProps);
}
+export function styleFromLayoutString(doc: Doc, props: FieldViewProps, scale: number) {
+ const style: { [key: string]: any } = {};
+ const divKeys = ['width', 'height', 'fontSize', 'transform', 'left', 'backgroundColor', 'left', 'right', 'top', 'bottom', 'pointerEvents', 'position'];
+ const replacer = (match: any, expr: string) =>
+ // bcz: this executes a script to convert a property expression string: { script } into a value
+ ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: doc, scale }).result?.toString() ?? '';
+ divKeys.forEach((prop: string) => {
+ const p = (props as any)[prop];
+ typeof p === 'string' && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
+ });
+ return style;
+}
+
export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
return `M ${pw * 0.5} ${ph * inset} C ${pw * 0.6} ${ph * inset} ${pw * (1 - 2 * inset)} 0 ${pw * (1 - inset)} ${ph * inset} C ${pw} ${ph * (2 * inset)} ${pw * (1 - inset)} ${ph * 0.25} ${pw * (1 - inset)} ${ph * 0.3} C ${
pw * (1 - inset)
@@ -74,6 +65,11 @@ export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
} ${ph * inset}`;
}
+let _filterOpener: () => void;
+export function SetFilterOpener(func: () => void) {
+ _filterOpener = func;
+}
+
// a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
//
export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string): any {
@@ -83,38 +79,63 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
const isNonTransparent = property.includes(':nonTransparent');
const isNonTransparentLevel = isNonTransparent ? Number(property.replace(/.*:nonTransparent([0-9]+).*/, '$1')) : 0; // property.includes(':nonTransparent');
const isAnnotated = property.includes(':annotated');
- const isInk = () => doc?._layout_isSvg && !props?.LayoutTemplateString;
- const isOpen = property.includes(':open');
- const isEmpty = property.includes(':empty');
- const boxBackground = property.includes(':box');
- const fieldKey = props?.fieldKey ? props.fieldKey + '_' : isCaption ? 'caption_' : '';
+ const layoutDoc = doc ? Doc.Layout(doc) : doc;
+ const isOpen = property.includes(':treeOpen');
+ const boxBackground = property.includes(':docView'); // background color of docView's bounds can be different than the background of contents -- eg FontIconBox
+ const {
+ DocumentView: docView,
+ fieldKey: fieldKeyProp,
+ styleProvider,
+ pointerEvents,
+ isGroupActive,
+ isDocumentActive,
+ containerViewPath,
+ childFilters,
+ hideCaptions,
+ showTitle,
+ childFiltersByRanges,
+ renderDepth,
+ docViewPath,
+ LayoutTemplateString,
+ disableBrushing,
+ NativeDimScaling,
+ PanelWidth,
+ PanelHeight,
+ isSelected,
+ isHovering,
+ } = props || {}; // extract props that are not shared between fieldView and documentView props.
+ const componentView = docView?.()?.ComponentView;
+ const fieldKey = fieldKeyProp ? fieldKeyProp + '_' : isCaption ? 'caption_' : '';
+ const isInk = () => layoutDoc?._layout_isSvg && !LayoutTemplateString;
const lockedPosition = () => doc && BoolCast(doc._lockedPosition);
- const titleHeight = () => props?.styleProvider?.(doc, props, StyleProp.TitleHeight);
- const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
- const color = () => props?.styleProvider?.(doc, props, StyleProp.Color);
- const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity);
- const layout_showTitle = () => props?.styleProvider?.(doc, props, StyleProp.ShowTitle);
+ const titleHeight = () => styleProvider?.(doc, props, StyleProp.TitleHeight);
+ const backgroundCol = () => styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
+ const color = () => styleProvider?.(doc, props, StyleProp.Color);
+ const opacity = () => styleProvider?.(doc, props, StyleProp.Opacity);
+ const layoutShowTitle = () => styleProvider?.(doc, props, StyleProp.ShowTitle);
// prettier-ignore
switch (property.split(':')[0]) {
- case StyleProp.TreeViewIcon:
- const img = ImageCast(doc?.icon, ImageCast(doc?.data));
+ case StyleProp.TreeViewIcon: {
+ const img = ImageCast(doc?.icon ?? doc?.[doc ? Doc.LayoutFieldKey(doc) : ""]);
if (img) {
const ext = extname(img.url.href);
const url = doc?.icon ? img.url.href : img.url.href.replace(ext, '_s' + ext);
return <img src={url} width={20} height={15} style={{ margin: 'auto', display: 'block', objectFit: 'contain' }} />;
}
return Doc.toIcon(doc, isOpen);
- case StyleProp.TreeViewSortings:
+ }
+ case StyleProp.TreeViewSortings: {
const allSorts: { [key: string]: { color: string; icon: JSX.Element | string } | undefined } = {};
allSorts[TreeSort.AlphaDown] = { color: Colors.MEDIUM_BLUE, icon: <BsArrowDown/> };
allSorts[TreeSort.AlphaUp] = { color: 'crimson', icon: <BsArrowUp/> };
if (doc?._type_collection === CollectionViewType.Freeform) allSorts[TreeSort.Zindex] = { color: 'green', icon: 'Z' };
allSorts[TreeSort.WhenAdded] = { color: 'darkgray', icon: <BsArrowDownUp/> };
return allSorts;
+ }
case StyleProp.Highlighting:
if (doc && (Doc.IsSystem(doc) || doc.type === DocumentType.FONTICON)) return undefined;
- if (doc && !doc.layout_disableBrushing && !props?.disableBrushing) {
- const selected = Array.from(doc?.[DocViews]??[]).filter(dv => dv.IsSelected).length;
+ if (doc && !doc.layout_disableBrushing && !disableBrushing) {
+ const selected = DocumentView.getViews(doc).filter(dv => dv.IsSelected).length;
const highlightIndex = Doc.GetBrushHighlightStatus(doc) || (selected ? Doc.DocBrushStatus.selfBrushed : 0);
const highlightColor = ['transparent', 'rgb(68, 118, 247)', selected ? "black" : 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex];
const highlightStyle = ['solid', 'dashed', 'solid', 'solid', 'solid'][highlightIndex];
@@ -123,77 +144,85 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
highlightStyle: doc.isGroup ? "dotted": highlightStyle,
highlightColor,
highlightIndex,
- highlightStroke: doc.layout_isSvg,
+ highlightStroke: layoutDoc?.layout_isSvg,
};
}
}
return undefined;
- case StyleProp.DocContents:return undefined;
- case StyleProp.WidgetColor:return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
- case StyleProp.Opacity: return props?.LayoutTemplateString?.includes(KeyValueBox.name) ? 1 : doc?.text_inlineAnnotations ? 0 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
- case StyleProp.FontSize: return StrCast(doc?.[fieldKey + 'fontSize'], StrCast(Doc.UserDoc().fontSize));
- case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily));
- case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(Doc.UserDoc().fontWeight));
- case StyleProp.FillColor: return StrCast(doc?._fillColor, StrCast(doc?.fillColor, StrCast(doc?.backgroundColor, 'transparent')));
- case StyleProp.ShowCaption:return props?.hideCaptions || doc?._type_collection === CollectionViewType.Carousel ? undefined: StrCast(doc?._layout_showCaption);
- case StyleProp.TitleHeight:return (props?.ScreenToLocalTransform().Scale ?? 1) * NumCast(Doc.UserDoc().headerHeight,30);
- case StyleProp.ShowTitle:
- return (
+ case StyleProp.DocContents: return undefined;
+ case StyleProp.WidgetColor: return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
+ case StyleProp.Opacity: return componentView?.isUnstyledView?.() ? 1 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
+ case StyleProp.FontColor: return StrCast(doc?.[fieldKey + 'fontColor'], StrCast(Doc.UserDoc().fontColor, color()));
+ case StyleProp.FontSize: return StrCast(doc?.[fieldKey + 'fontSize'], StrCast(Doc.UserDoc().fontSize));
+ case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily));
+ case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(Doc.UserDoc().fontWeight));
+ case StyleProp.FillColor: return StrCast(doc?._fillColor, StrCast(doc?.fillColor, StrCast(doc?.backgroundColor, 'transparent')));
+ case StyleProp.ShowCaption: return hideCaptions || doc?._type_collection === CollectionViewType.Carousel ? undefined: StrCast(doc?._layout_showCaption);
+ case StyleProp.TitleHeight: return Math.min(4,(docView?.().screenToViewTransform().Scale ?? 1)) * NumCast(Doc.UserDoc().headerHeight,30);
+ case StyleProp.ShowTitle: return (
(doc &&
- !props?.LayoutTemplateString &&
+ !componentView?.isUnstyledView?.() &&
+ !LayoutTemplateString &&
!doc.presentation_targetDoc &&
- !props?.LayoutTemplateString?.includes(KeyValueBox.name) &&
- props?.layout_showTitle?.() !== '' &&
+ showTitle?.() !== '' &&
StrCast(
doc._layout_showTitle,
- props?.layout_showTitle?.() ||
+ showTitle?.() ||
(!Doc.IsSystem(doc) && [DocumentType.COL, DocumentType.FUNCPLOT, DocumentType.LABEL, DocumentType.RTF, DocumentType.IMG, DocumentType.VID].includes(doc.type as any)
- ? doc.author === Doc.CurrentUserEmail
+ ? doc.author === ClientUtils.CurrentUserEmail()
? StrCast(Doc.UserDoc().layout_showTitle)
: remoteDocHeader
: '')
)) ||
''
);
- case StyleProp.Color:
- if (SettingsManager.Instance.LastPressedBtn === doc) return SettingsManager.userBackgroundColor;
- if (Doc.IsSystem(doc!)) return SettingsManager.userColor;
- if (doc?.type === DocumentType.FONTICON) return SettingsManager.userColor;
+ case StyleProp.Color: {
+ if (SnappingManager.LastPressedBtn === doc?.[Id]) return SnappingManager.userBackgroundColor;
+ if (Doc.IsSystem(doc!)) return SnappingManager.userColor;
+ if (doc?.type === DocumentType.FONTICON) return SnappingManager.userColor;
const docColor: Opt<string> = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color));
if (docColor) return docColor;
const backColor = backgroundCol();
return backColor ? lightOrDark(backColor) : undefined;
- case StyleProp.BorderRounding:
- return StrCast(doc?.[fieldKey + 'borderRounding'], StrCast(doc?.layout_borderRounding, doc?._type_collection === CollectionViewType.Pile ? '50%' : ''));
- case StyleProp.BorderPath:
+ }
+ case StyleProp.BorderRounding: {
+ const rounding = StrCast(doc?.[fieldKey + 'borderRounding'], StrCast(doc?.layout_borderRounding, doc?._type_collection === CollectionViewType.Pile ? '50%' : ''));
+ return (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc || doc?.isTemplateDoc) ? StrCast(doc._layout_borderRounding,rounding) : rounding;
+ }
+ case StyleProp.BorderPath: {
const borderPath = Doc.IsComicStyle(doc) &&
- props?.renderDepth &&
- !doc?.layout_isSvg && { path: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0), fill: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0, 0.08), width: 3 };
- return !borderPath
- ? null
- : {
- clipPath: `path('${borderPath.path}')`,
- jsx: (
- <div key="border2" className="documentView-customBorder" style={{ pointerEvents: 'none' }}>
- <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${props.PanelWidth()} ${props.PanelHeight()}`}>
- <path d={borderPath.path} style={{ stroke: 'black', fill: 'transparent', strokeWidth: borderPath.width }} />
- </svg>
- </div>
- ),
- };
+ renderDepth &&
+ !doc?.layout_isSvg && { path: wavyBorderPath(PanelWidth?.() || 0, PanelHeight?.() || 0), fill: wavyBorderPath(PanelWidth?.() || 0, PanelHeight?.() || 0, 0.08), width: 3 };
+ return !borderPath
+ ? null
+ : {
+ clipPath: `path('${borderPath.path}')`,
+ jsx: (
+ <div key="border2" className="documentView-customBorder" style={{ pointerEvents: 'none' }}>
+ <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${PanelWidth?.()} ${PanelHeight?.()}`}>
+ <path d={borderPath.path} style={{ stroke: 'black', fill: 'transparent', strokeWidth: borderPath.width }} />
+ </svg>
+ </div>
+ ),
+ };
+ }
case StyleProp.HeaderMargin:
return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._type_collection as any) ||
- (doc?.type === DocumentType.RTF && !layout_showTitle()?.includes('noMargin')) ||
+ (doc?.type === DocumentType.RTF && !layoutShowTitle()?.includes('noMargin')) ||
doc?.type === DocumentType.LABEL) &&
- layout_showTitle() &&
+ layoutShowTitle() &&
!StrCast(doc?.layout_showTitle).includes(':hover')
? titleHeight()
: 0;
case StyleProp.BackgroundColor: {
- if (SettingsManager.Instance.LastPressedBtn === doc) return SettingsManager.userColor; // hack to indicate active menu panel item
- let docColor: Opt<string> = StrCast(doc?.[fieldKey + 'backgroundColor'], StrCast(doc?.backgroundColor, isCaption ? 'rgba(0,0,0,0.4)' : ''));
+ if (SnappingManager.LastPressedBtn === doc?.[Id]) return SnappingManager.userColor; // hack to indicate active menu panel item
+ const dataKey = doc ? Doc.LayoutFieldKey(doc) : "";
+ const usePath = StrCast(doc?.[dataKey + "_usePath"]);
+ const alternate = usePath.includes(":hover") ? ( isHovering?.() ? '_' + usePath.replace(":hover","") : "") : usePath ? "_" +usePath:usePath;
+ let docColor: Opt<string> = StrCast(doc?.[fieldKey+alternate], StrCast(doc?.['backgroundColor' +alternate], isCaption ? 'rgba(0,0,0,0.4)' : ''));
+ if (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc) docColor = StrCast(doc._backgroundColor,docColor)
// prettier-ignore
- switch (doc?.type) {
+ switch (layoutDoc?.type) {
case DocumentType.PRESELEMENT: docColor = docColor || ""; break;
case DocumentType.PRES: docColor = docColor || 'transparent'; break;
case DocumentType.FONTICON: docColor = boxBackground ? undefined : docColor || Colors.DARK_GRAY; break;
@@ -210,85 +239,86 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
case DocumentType.SCREENSHOT:
case DocumentType.VID: docColor = docColor || (Colors.LIGHT_GRAY); break;
case DocumentType.COL:
- docColor = docColor || (Doc.IsSystem(doc)
- ? SettingsManager.userBackgroundColor
- : doc.annotationOn
+ docColor = docColor || (doc && Doc.IsSystem(doc)
+ ? SnappingManager.userBackgroundColor
+ : doc?.annotationOn
? '#00000010' // faint interior for collections on PDFs, images, etc
: doc?.isGroup
? undefined
- : doc._type_collection === CollectionViewType.Stacking ?
+ : doc?._type_collection === CollectionViewType.Stacking ?
(Colors.DARK_GRAY)
- : Cast((props?.renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY));
+ : Cast((renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY));
break;
- //if (doc._type_collection !== CollectionViewType.Freeform && doc._type_collection !== CollectionViewType.Time) return "rgb(62,62,62)";
+ // if (doc._type_collection !== CollectionViewType.Freeform && doc._type_collection !== CollectionViewType.Time) return "rgb(62,62,62)";
default: docColor = docColor || (Colors.WHITE);
}
- if (isNonTransparent && isNonTransparentLevel < 9 && (!docColor || docColor === 'transparent') && doc?.embedContainer && props?.styleProvider) {
- return props.styleProvider(DocCast(doc.embedContainer), props, StyleProp.BackgroundColor+":nonTransparent"+(isNonTransparentLevel+1));
+ if (isNonTransparent && isNonTransparentLevel < 9 && (!docColor || docColor === 'transparent') && doc?.embedContainer && styleProvider) {
+ return styleProvider(DocCast(doc.embedContainer), props, StyleProp.BackgroundColor+":nonTransparent"+(isNonTransparentLevel+1));
}
return (docColor && !doc) ? DashColor(docColor).fade(0.5).toString() : docColor;
}
case StyleProp.BoxShadow: {
if (!doc || opacity() === 0 || doc.noShadow) return undefined; // if it's not visible, then no shadow)
if (doc.layout_boxShadow === 'standard') return Shadows.STANDARD_SHADOW;
- if (IsFollowLinkScript(doc?.onClick) && LinkManager.Links(doc).length && !doc.layout_isSvg) return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
+ if (IsFollowLinkScript(doc?.onClick) && Doc.Links(doc).length && !layoutDoc?.layout_isSvg) return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
switch (doc?.type) {
case DocumentType.COL:
return StrCast(
doc?.layout_boxShadow,
doc?._type_collection === CollectionViewType.Pile
? '4px 4px 10px 2px'
- : lockedPosition() || doc?.isGroup || props?.LayoutTemplateString
+ : lockedPosition() || doc?.isGroup || LayoutTemplateString
? undefined // groups have no drop shadow -- they're supposed to be "invisible". LayoutString's imply collection is being rendered as something else (e.g., title of a Slide)
: `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}`
);
case DocumentType.LABEL:
if (doc?.annotationOn !== undefined) return 'black 2px 2px 1px';
+ // eslint-disable-next-line no-fallthrough
default:
return doc.z
? `#9c9396 ${StrCast(doc?.layout_boxShadow, '10px 10px 0.9vw')}` // if it's a floating doc, give it a big shadow
- : props?.containerViewPath?.().lastElement()?.Document._freeform_useClusters
- ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (props?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
+ : containerViewPath?.().lastElement()?.Document._freeform_useClusters
+ ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
: NumCast(doc.group, -1) !== -1
- ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (props?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
+ ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
: lockedPosition()
? undefined // if it's a background & has a cluster color, make the shadow spread really big
: fieldKey.includes('_inline') // if doc is an inline document in a text box
? `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0vw 0vw 0.1vw')}`
- : DocCast(doc.embedContainer)?.type=== DocumentType.RTF // if doc is embedded in a text document (but not an inline)
+ : DocCast(doc.embedContainer)?.type === DocumentType.RTF && !isInk() // if doc is embedded in a text document (but not an inline)
? `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}`
: StrCast(doc.layout_boxShadow, '');
}
}
case StyleProp.PointerEvents:
- if (StrCast(doc?.pointerEvents) && !props?.LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
- if (props?.LayoutTemplateString?.includes(KeyValueBox.name)) return 'all';
+ if (componentView?.dontRegisterView?.()) return 'all';
+ if (StrCast(doc?.pointerEvents)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
if (SnappingManager.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all';
- if (props?.pointerEvents?.() === 'none') return 'none';
+ if (pointerEvents?.() === 'none') return 'none';
if (opacity() === 0) return 'none';
- if (props?.isGroupActive?.() ) return isInk() ? 'visiblePainted': (doc?.
+ if (isGroupActive?.() ) return isInk() ? 'visiblePainted': (doc?.
isGroup )? undefined: 'all'
- if (props?.isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all';
+ if (isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all';
return undefined; // fixes problem with tree view elements getting pointer events when the tree view is not active
- case StyleProp.Decorations:
+ case StyleProp.Decorations: {
const lock = () => doc?.pointerEvents !== 'none' ? null : (
<div className="styleProvider-lock" onClick={() => toggleLockedPosition(doc)}>
<FontAwesomeIcon icon='lock' size="lg" />
</div>
);
const paint = () => !doc?.onPaint ? null : (
- <div className={`styleProvider-paint${props?.DocumentView?.().IsSelected ? "-selected":""}`} onClick={e => togglePaintView(e, doc, props)}>
+ <div className={`styleProvider-paint${isSelected?.() ? "-selected":""}`} onClick={e => togglePaintView(e, doc, props)}>
<FontAwesomeIcon icon='pen' size="lg" />
</div>
);
const filter = () => {
- const dashView = untracked(() => DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard));
+ const dashView = untracked(() => DocumentView.getDocumentView(Doc.ActiveDashboard));
const showFilterIcon =
StrListCast(doc?._childFilters).length || StrListCast(doc?._childFiltersByRanges).length
? 'green' // #18c718bd' //'hasFilter'
- : props?.childFilters?.().filter(f => Utils.IsRecursiveFilter(f) && f !== Utils.noDragDocsFilter).length || props?.childFiltersByRanges().length
- ? 'orange' //'inheritsFilter'
+ : childFilters?.().filter(f => ClientUtils.IsRecursiveFilter(f) && f !== ClientUtils.noDragDocsFilter).length || childFiltersByRanges?.().length
+ ? 'orange' // 'inheritsFilter'
: undefined;
return !showFilterIcon ? null : (
<div className="styleProvider-filter">
@@ -296,19 +326,14 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
type={Type.TERT}
dropdownType={DropdownType.CLICK}
fillWidth
- iconProvider={(active:boolean) => <div className='styleProvider-filterShift'><FaFilter/></div>}
- closeOnSelect={true}
- setSelectedVal={
- action((dv) => {
- (dv as any).select(false);
- (SettingsManager.Instance.propertiesWidth = 250);
- setTimeout(action(() => {
- if (PropertiesView.Instance) {
- PropertiesView.Instance.CloseAll();
- PropertiesView.Instance.openFilters = true;
- }
- }));
- })
+ // eslint-disable-next-line react/no-unstable-nested-components
+ iconProvider={() => <div className='styleProvider-filterShift'><FaFilter/></div>}
+ closeOnSelect
+ setSelectedVal={((dv: DocumentView) => {
+ dv.select(false);
+ SnappingManager.SetPropertiesWidth(250);
+ _filterOpener?.();
+ }) as any // Dropdown assumes values are strings or numbers..
}
size={Size.XSMALL}
width={15}
@@ -316,28 +341,28 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
title={showFilterIcon === 'green' ?
"This view is filtered. Click to view/change filters":
"this view inherits filters from one of its parents"}
- color={SettingsManager.userColor}
+ color={SnappingManager.userColor}
background={showFilterIcon}
- items={[ ...(dashView ? [dashView]: []), ...(props?.docViewPath?.()??[])]
+ items={[ ...(dashView ? [dashView]: []), ...(docViewPath?.()??[])]
.filter(dv => StrListCast(dv?.Document.childFilters).length || StrListCast(dv?.Document.childRangeFilters).length)
.map(dv => ({
text: StrCast(dv?.Document.title),
val: dv as any,
- style: {color:SettingsManager.userColor, background:SettingsManager.userBackgroundColor},
+ style: {color:SnappingManager.userColor, background:SnappingManager.userBackgroundColor},
} as IListItemProps)) }
/>
</div>
);
};
const audio = () => {
- const audioAnnoState = (doc: Doc) => StrCast(doc.audioAnnoState, 'stopped');
- const audioAnnosCount = (doc: Doc) => StrListCast(doc[fieldKey + 'audioAnnotations']).length;
- if (!doc || props?.renderDepth === -1 || !audioAnnosCount(doc)) return null;
- const audioIconColors: { [key: string]: string } = { recording: 'red', playing: 'green', stopped: 'blue' };
+ const audioAnnoState = (audioDoc: Doc) => StrCast(audioDoc.audioAnnoState, AudioAnnoState.stopped);
+ const audioAnnosCount = (audioDoc: Doc) => StrListCast(audioDoc[fieldKey + 'audioAnnotations']).length;
+ if (!doc || renderDepth === -1 || !audioAnnosCount(doc)) return null;
+ const audioIconColors: { [key: string]: string } = { playing: 'green', stopped: 'blue' };
return (
<Tooltip title={<div>{StrListCast(doc[fieldKey + 'audioAnnotations_text']).lastElement()}</div>}>
- <div className="styleProvider-audio" onPointerDown={() => DocumentManager.Instance.getFirstDocumentView(doc)?.playAnnotation()}>
- <FontAwesomeIcon className="documentView-audioFont" style={{ color: audioIconColors[audioAnnoState(doc)] }} icon={'file-audio'} size="sm" />
+ <div className="styleProvider-audio" onPointerDown={() => DocumentView.getFirstDocumentView(doc)?.playAnnotation()}>
+ <FontAwesomeIcon className="documentView-audioFont" style={{ color: audioIconColors[audioAnnoState(doc)] }} icon='file-audio' size="sm" />
</div>
</Tooltip>
);
@@ -350,11 +375,13 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
{audio()}
</>
);
+ }
+ default:
}
}
export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, offIcon: IconProp, clickFunc?: () => void) {
- const color = SettingsManager.userColor;
+ const color = SnappingManager.userColor;
return (
<IconButton
size={Size.XSMALL}
@@ -376,7 +403,11 @@ export function DashboardStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>
if (doc && property.split(':')[0] === StyleProp.Decorations) {
return doc._type_collection === CollectionViewType.Docking || Doc.IsSystem(doc)
? null
- : DashboardToggleButton(doc, 'hidden', 'eye-slash', 'eye', () => DocFocusOrOpen(doc, { toggleTarget: true, willZoomCentered: true, zoomScale: 0 }, DocCast(doc?.embedContainer ?? doc?.annotationOn)));
+ : DashboardToggleButton(doc, 'hidden', 'eye-slash', 'eye', () => DocumentView.FocusOrOpen(doc, { toggleTarget: true, willZoomCentered: true, zoomScale: 0 }, DocCast(doc?.embedContainer ?? doc?.annotationOn)));
}
return DefaultStyleProvider(doc, props, property);
}
+
+export function returnEmptyDocViewList() {
+ return emptyPath;
+}
diff --git a/src/client/views/TemplateMenu.scss b/src/client/views/TemplateMenu.scss
index 4d0f1bf00..36a9ce6d0 100644
--- a/src/client/views/TemplateMenu.scss
+++ b/src/client/views/TemplateMenu.scss
@@ -39,6 +39,7 @@
display: inline-block;
height: 100%;
width: 100%;
+ max-height: 250px;
.templateToggle,
.chromeToggle {
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index eed197b0b..cff32a557 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -1,37 +1,23 @@
-import { action, computed, observable, ObservableSet, runInAction } from 'mobx';
+import { computed, ObservableSet, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../ClientUtils';
import { Doc, DocListCast } from '../../fields/Doc';
+import { DocData } from '../../fields/DocSymbols';
import { ScriptField } from '../../fields/ScriptField';
import { Cast, DocCast, StrCast } from '../../fields/Types';
import { TraceMobx } from '../../fields/util';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../Utils';
-import { Docs, DocUtils } from '../documents/Documents';
+import { emptyFunction } from '../../Utils';
+import { Docs } from '../documents/Documents';
+import { DocUtils } from '../documents/DocUtils';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
import { Transform } from '../util/Transform';
-import { undoBatch } from '../util/UndoManager';
import { CollectionTreeView } from './collections/CollectionTreeView';
-import { DocumentView, returnEmptyDocViewList } from './nodes/DocumentView';
-import { DefaultStyleProvider } from './StyleProvider';
+import { DocumentView } from './nodes/DocumentView';
+import { DefaultStyleProvider, returnEmptyDocViewList } from './StyleProvider';
import './TemplateMenu.scss';
-import { DocData } from '../../fields/DocSymbols';
@observer
-class TemplateToggle extends React.Component<{ template: string; checked: boolean; toggle: (event: React.ChangeEvent<HTMLInputElement>, template: string) => void }> {
- render() {
- if (this.props.template) {
- return (
- <li className="templateToggle">
- <input type="checkbox" checked={this.props.checked} onChange={event => this.props.toggle(event, this.props.template)} />
- {this.props.template}
- </li>
- );
- } else {
- return null;
- }
- }
-}
-@observer
class OtherToggle extends React.Component<{ checked: boolean; name: string; toggle: (event: React.ChangeEvent<HTMLInputElement>) => void }> {
render() {
return (
@@ -51,12 +37,25 @@ export interface TemplateMenuProps {
export class TemplateMenu extends React.Component<TemplateMenuProps> {
_addedKeys = new ObservableSet();
_customRef = React.createRef<HTMLInputElement>();
- @observable private _hidden: boolean = true;
+
+ componentDidMount() {
+ !this._addedKeys && (this._addedKeys = new ObservableSet());
+ [...Array.from(Object.keys(this.props.docViews[0].Document[DocData])), ...Array.from(Object.keys(this.props.docViews[0].Document))]
+ .filter(key => key.startsWith('layout_') && (
+ StrCast(this.props.docViews[0].Document[key]).startsWith("<") ||
+ DocCast(this.props.docViews[0].Document[key])?.isTemplateDoc
+ ))
+ .forEach(key => runInAction(() => this._addedKeys.add(key.replace('layout_', '')))); // prettier-ignore
+ }
+ @computed get scriptField() {
+ const script = ScriptField.MakeScript('docs.map(d => switchView(d, this))', { this: Doc.name }, { docs: this.props.docViews.map(dv => dv.Document) as any });
+ return script ? () => script : undefined;
+ }
toggleLayout = (e: React.ChangeEvent<HTMLInputElement>, layout: string): void => {
this.props.docViews.map(dv => dv.switchViews(e.target.checked, layout, undefined, true));
};
- toggleDefault = (e: React.ChangeEvent<HTMLInputElement>): void => {
+ toggleDefault = (): void => {
this.props.docViews.map(dv => dv.switchViews(false, 'layout'));
};
@@ -66,21 +65,8 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
runInAction(() => this._addedKeys.add(this._customRef.current!.value));
}
};
- componentDidMount() {
- !this._addedKeys && (this._addedKeys = new ObservableSet());
- [...Array.from(Object.keys(this.props.docViews[0].Document[DocData])), ...Array.from(Object.keys(this.props.docViews[0].Document))]
- .filter(key => key.startsWith('layout_') && (
- StrCast(this.props.docViews[0].Document[key]).startsWith("<") ||
- DocCast(this.props.docViews[0].Document[key])?.isTemplateDoc
- ))
- .map(key => runInAction(() => this._addedKeys.add(key.replace('layout_', '')))); // prettier-ignore
- }
return100 = () => 300;
- @computed get scriptField() {
- const script = ScriptField.MakeScript('docs.map(d => switchView(d, this))', { this: Doc.name }, { docs: this.props.docViews.map(dv => dv.Document) as any });
- return script ? () => script : undefined;
- }
templateIsUsed = (selDoc: Doc, templateDoc: Doc) => {
const template = StrCast(templateDoc.dragFactory ? Cast(templateDoc.dragFactory, Doc, null)?.title : templateDoc.title);
return StrCast(selDoc.layout_fieldKey) === 'layout_' + template ? 'check' : 'unchecked';
@@ -89,18 +75,19 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
TraceMobx();
const firstDoc = this.props.docViews[0].Document;
const templateName = StrCast(firstDoc.layout_fieldKey, 'layout').replace('layout_', '');
- const noteTypes = DocListCast(Cast(Doc.UserDoc()['template_notes'], Doc, null)?.data);
- const addedTypes = DocListCast(Cast(Doc.UserDoc()['template_clickFuncs'], Doc, null)?.data);
+ const noteTypes = DocListCast(Cast(Doc.UserDoc().template_notes, Doc, null)?.data);
+ const addedTypes = DocListCast(Cast(Doc.UserDoc().template_clickFuncs, Doc, null)?.data);
const templateMenu: Array<JSX.Element> = [];
templateMenu.push(<OtherToggle key="default" name={firstDoc.layout instanceof Doc ? StrCast(firstDoc.layout.title) : 'Default'} checked={templateName === 'layout'} toggle={this.toggleDefault} />);
+ // eslint-disable-next-line no-return-assign
addedTypes.concat(noteTypes).map(template => (template.treeView_Checked = this.templateIsUsed(firstDoc, template)));
this._addedKeys &&
Array.from(this._addedKeys)
.filter(key => !noteTypes.some(nt => nt.title === key))
.forEach(template => templateMenu.push(<OtherToggle key={template} name={template} checked={templateName === template} toggle={e => this.toggleLayout(e, template)} />));
return (
- <ul className="template-list" style={{ display: 'block' }}>
- {Doc.noviceMode ? null : <input placeholder="+ layout" ref={this._customRef} onKeyPress={this.onCustomKeypress} />}
+ <ul className="template-list">
+ {Doc.noviceMode ? null : <input placeholder="+ layout" ref={this._customRef} onKeyDown={this.onCustomKeypress} />}
{templateMenu}
<CollectionTreeView
Document={Doc.MyTemplates}
@@ -123,10 +110,10 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
addDocTab={returnFalse}
PanelWidth={this.return100}
PanelHeight={this.return100}
- treeViewHideHeaderFields={true}
- treeViewHideTitle={true}
- dontRegisterView={true}
- fieldKey={'data'}
+ treeViewHideHeaderFields
+ treeViewHideTitle
+ dontRegisterView
+ fieldKey="data"
moveDocument={returnFalse}
removeDocument={returnFalse}
addDocument={returnFalse}
@@ -136,10 +123,9 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
}
}
-ScriptingGlobals.add(function switchView(doc: Doc, template: Doc | undefined) {
- if (template?.dragFactory) {
- template = Cast(template.dragFactory, Doc, null);
- }
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function switchView(doc: Doc, templateIn: Doc | undefined) {
+ const template = templateIn?.dragFactory ? Cast(templateIn.dragFactory, Doc, null) : templateIn;
const templateTitle = StrCast(template?.title);
return templateTitle && DocUtils.makeCustomViewClicked(doc, Docs.Create.FreeformDocument, templateTitle, template);
});
diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
deleted file mode 100644
index 436cb688f..000000000
--- a/src/client/views/Touchable.tsx
+++ /dev/null
@@ -1,213 +0,0 @@
-import * as React from 'react';
-import { action } from 'mobx';
-import { InteractionUtils } from '../util/InteractionUtils';
-
-const HOLD_DURATION = 1000;
-
-export abstract class Touchable<T = {}> extends React.Component<React.PropsWithChildren<T>> {
- //private holdTimer: NodeJS.Timeout | undefined;
- private moveDisposer?: InteractionUtils.MultiTouchEventDisposer;
- private endDisposer?: InteractionUtils.MultiTouchEventDisposer;
- private holdMoveDisposer?: InteractionUtils.MultiTouchEventDisposer;
- private holdEndDisposer?: InteractionUtils.MultiTouchEventDisposer;
-
- protected abstract _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
- protected _touchDrag: boolean = false;
- protected prevPoints: Map<number, React.Touch> = new Map<number, React.Touch>();
-
- public FirstX: number = 0;
- public FirstY: number = 0;
- public SecondX: number = 0;
- public SecondY: number = 0;
-
- /**
- * When a touch even starts, we keep track of each touch that is associated with that event
- */
- @action
- protected onTouchStart = (e: Event, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): void => {
- const actualPts: React.Touch[] = [];
- const te = me.touchEvent;
- // loop through all touches on screen
- for (const pt of me.touches) {
- actualPts.push(pt);
- if (this.prevPoints.has(pt.identifier)) {
- this.prevPoints.set(pt.identifier, pt);
- }
- // only add the ones that are targeted on "this" element, but with the identifier that the screen touch gives
- for (const tPt of me.changedTouches) {
- if (pt.clientX === tPt.clientX && pt.clientY === tPt.clientY) {
- // pen is also a touch, but with a radius of 0.5 (at least with the surface pens)
- // and this seems to be the only way of differentiating pen and touch on touch events
- if ((pt as any).radiusX > 1 && (pt as any).radiusY > 1) {
- this.prevPoints.set(pt.identifier, pt);
- }
- }
- }
- }
-
- const ptsToDelete: number[] = [];
- this.prevPoints.forEach(pt => {
- if (!actualPts.includes(pt)) {
- ptsToDelete.push(pt.identifier);
- }
- });
-
- ptsToDelete.forEach(pt => this.prevPoints.delete(pt));
-
- if (this.prevPoints.size) {
- switch (this.prevPoints.size) {
- case 1:
- this.handle1PointerDown(te, me);
- te.persist();
- // -- code for radial menu --
- // if (this.holdTimer) {
- // clearTimeout(this.holdTimer)
- // this.holdTimer = undefined;
- // }
- break;
- case 2:
- this.handle2PointersDown(te, me);
- break;
- }
- }
- };
-
- /**
- * Handle touch move event
- */
- @action
- protected onTouch = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
- const te = me.touchEvent;
- const myTouches = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true);
-
- // if we're not actually moving a lot, don't consider it as dragging yet
- if (!InteractionUtils.IsDragging(this.prevPoints, myTouches, 5) && !this._touchDrag) return;
- this._touchDrag = true;
- switch (myTouches.length) {
- case 1:
- this.handle1PointerMove(te, me);
- break;
- case 2:
- this.handle2PointersMove(te, me);
- break;
- }
-
- for (const pt of me.touches) {
- if (pt && this.prevPoints.has(pt.identifier)) {
- this.prevPoints.set(pt.identifier, pt);
- }
- }
- };
-
- @action
- protected onTouchEnd = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
- // remove all the touches associated with the event
- const te = me.touchEvent;
- for (const pt of me.changedTouches) {
- if (pt) {
- if (this.prevPoints.has(pt.identifier)) {
- this.prevPoints.delete(pt.identifier);
- }
- }
- }
- this._touchDrag = false;
- te.stopPropagation();
-
- // if (e.targetTouches.length === 0) {
- // this.prevPoints.clear();
- // }
-
- if (this.prevPoints.size === 0) {
- this.cleanUpInteractions();
- }
- e.stopPropagation();
- };
-
- cleanUpInteractions = (): void => {
- this.removeMoveListeners();
- this.removeEndListeners();
- };
-
- handle1PointerMove = (e: TouchEvent, me: InteractionUtils.MultiTouchEvent<TouchEvent>): any => {
- e.stopPropagation();
- e.preventDefault();
- };
-
- handle2PointersMove = (e: TouchEvent, me: InteractionUtils.MultiTouchEvent<TouchEvent>): any => {
- e.stopPropagation();
- e.preventDefault();
- };
-
- handle1PointerDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): any => {
- this.removeMoveListeners();
- this.addMoveListeners();
- this.removeEndListeners();
- this.addEndListeners();
- };
-
- handle2PointersDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): any => {
- this.removeMoveListeners();
- this.addMoveListeners();
- this.removeEndListeners();
- this.addEndListeners();
- };
-
- handle1PointerHoldStart = (e: Event, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): any => {
- e.stopPropagation();
- me.touchEvent.stopPropagation();
- this.removeMoveListeners();
- this.removeEndListeners();
- this.removeHoldMoveListeners();
- this.removeHoldEndListeners();
- this.addHoldMoveListeners();
- this.addHoldEndListeners();
- };
-
- addMoveListeners = () => {
- const handler = (e: Event) => this.onTouch(e, (e as CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>).detail);
- document.addEventListener('dashOnTouchMove', handler);
- this.moveDisposer = () => document.removeEventListener('dashOnTouchMove', handler);
- };
- addEndListeners = () => {
- const handler = (e: Event) => this.onTouchEnd(e, (e as CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>).detail);
- document.addEventListener('dashOnTouchEnd', handler);
- this.endDisposer = () => document.removeEventListener('dashOnTouchEnd', handler);
- };
-
- addHoldMoveListeners = () => {
- const handler = (e: Event) => this.handle1PointerHoldMove(e, (e as CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>).detail);
- document.addEventListener('dashOnTouchHoldMove', handler);
- this.holdMoveDisposer = () => document.removeEventListener('dashOnTouchHoldMove', handler);
- };
-
- addHoldEndListeners = () => {
- const handler = (e: Event) => this.handle1PointerHoldEnd(e, (e as CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>).detail);
- document.addEventListener('dashOnTouchHoldEnd', handler);
- this.holdEndDisposer = () => document.removeEventListener('dashOnTouchHoldEnd', handler);
- };
-
- removeMoveListeners = () => this.moveDisposer?.();
- removeEndListeners = () => this.endDisposer?.();
- removeHoldMoveListeners = () => this.holdMoveDisposer?.();
- removeHoldEndListeners = () => this.holdEndDisposer?.();
-
- handle1PointerHoldMove = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
- // e.stopPropagation();
- // me.touchEvent.stopPropagation();
- };
-
- handle1PointerHoldEnd = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
- e.stopPropagation();
- me.touchEvent.stopPropagation();
- this.removeHoldMoveListeners();
- this.removeHoldEndListeners();
-
- me.touchEvent.stopPropagation();
- me.touchEvent.preventDefault();
- };
-
- handleHandDown = (e: React.TouchEvent) => {
- // e.stopPropagation();
- // e.preventDefault();
- };
-}
diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx
index 068143225..2d461c0ab 100644
--- a/src/client/views/UndoStack.tsx
+++ b/src/client/views/UndoStack.tsx
@@ -1,6 +1,7 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { Tooltip } from '@mui/material';
import { Popup, Type } from 'browndash-components';
-import { observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { StrCast } from '../../fields/Types';
@@ -15,19 +16,19 @@ export class UndoStack extends React.Component<UndoStackProps> {
const background = UndoManager.batchCounter.get() ? 'yellow' : SettingsManager.userVariantColor;
const color = UndoManager.batchCounter.get() ? 'black' : SettingsManager.userColor;
return (
- <Tooltip title={'undo stack (if it stays yellow, undo is broken - you should reload Dash)'}>
+ <Tooltip title="undo stack (if it stays yellow, undo is broken - you should reload Dash)">
<div>
<div className="undoStack-outerContainer">
<Popup
text="stack"
color={color}
background={background}
- placement={`top-start`}
+ placement="top-start"
type={Type.TERT}
popup={
<div
className="undoStack-commandsContainer"
- ref={r => r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })}
+ ref={r => r?.scroll({ behavior: 'auto', top: (r?.scrollHeight ?? 0) + 20 })}
style={{
background,
color,
@@ -35,12 +36,13 @@ export class UndoStack extends React.Component<UndoStackProps> {
{Array.from(UndoManager.undoStackNames).map((name, i) => (
<div
className="undoStack-resultContainer"
+ // eslint-disable-next-line react/no-array-index-key
key={i}
- onClick={e => {
+ onClick={() => {
const size = UndoManager.undoStackNames.length;
for (let n = 0; n < size - i; n++) UndoManager.Undo();
}}>
- <div className="undoStack-commandString">{StrCast(name).replace(/[^\.]*\./, '')}</div>
+ <div className="undoStack-commandString">{StrCast(name).replace(/[^.]*\./, '')}</div>
</div>
))}
{Array.from(UndoManager.redoStackNames)
@@ -48,12 +50,13 @@ export class UndoStack extends React.Component<UndoStackProps> {
.map((name, i) => (
<div
className="undoStack-resultContainer"
+ // eslint-disable-next-line react/no-array-index-key
key={i}
- onClick={e => {
+ onClick={() => {
for (let n = 0; n <= i; n++) UndoManager.Redo();
}}>
<div className="undoStack-commandString" style={{ fontWeight: 'bold', background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}>
- {StrCast(name).replace(/[^\.]*\./, '')}
+ {StrCast(name).replace(/[^.]*\./, '')}
</div>
</div>
))}
diff --git a/src/client/views/ViewBoxInterface.ts b/src/client/views/ViewBoxInterface.ts
new file mode 100644
index 000000000..c633f34fb
--- /dev/null
+++ b/src/client/views/ViewBoxInterface.ts
@@ -0,0 +1,60 @@
+import * as React from 'react';
+import { Doc, FieldType, Opt } from '../../fields/Doc';
+import { RefField } from '../../fields/RefField';
+import { DragManager } from '../util/DragManager';
+import { ObservableReactComponent } from './ObservableReactComponent';
+import { PinProps } from './PinFuncs';
+import { DocumentView } from './nodes/DocumentView';
+import { FocusViewOptions } from './nodes/FocusViewOptions';
+import { OpenWhere } from './nodes/OpenWhere';
+// import { DocUtils } from '../documents/Documents';
+
+/**
+ * Shared interface among all viewBox'es (ie, react classes that render the contents of a Doc)
+ * Many of these methods only make sense for specific viewBox'es, but they should be written to
+ * be as general as possible
+ */
+export abstract class ViewBoxInterface<P> extends ObservableReactComponent<React.PropsWithChildren<P>> {
+ abstract get Document(): Doc;
+ abstract get dataDoc(): Doc;
+ abstract get fieldKey(): string;
+ promoteCollection?: () => 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)
+ restoreView?: (viewSpec: Doc) => boolean;
+ scrollPreview?: (docView: DocumentView, doc: Doc, focusSpeed: number, options: FocusViewOptions) => Opt<number>; // returns the duration of the focus
+ brushView?: (view: { width: number; height: number; panX: number; panY: number }, transTime: number, holdTime: number) => void; // highlight a region of a view (used by freeforms)
+ getView?: (doc: Doc, options: FocusViewOptions) => Promise<Opt<DocumentView>>; // returns a nested DocumentView for the specified doc or undefined
+ addDocTab?: (doc: Doc, where: OpenWhere) => boolean; // determines how to add a document - used in following links to open the target ina local lightbox
+ addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean; // add a document (used only by collections)
+ removeDocument?: (doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean, dontAddToRemoved?: boolean) => boolean; // add a document (used only by collections)
+ select?: (ctrlKey: boolean, shiftKey: boolean) => void;
+ focus?: (textAnchor: Doc, options: FocusViewOptions) => Opt<number>;
+ viewTransition?: () => Opt<string>; // duration of a view transition animation
+ isAnyChildContentActive?: () => boolean; // is any child content of the document active
+ onClickScriptDisable?: () => 'never' | 'always'; // disable click scripts : never, always, or undefined = only when selected
+ getKeyFrameEditing?: () => boolean; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
+ setKeyFrameEditing?: (set: boolean) => void; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
+ playTrail?: (docs: Doc[]) => void;
+ playFrom?: (time: number, endTime?: number, fullPlay?: boolean) => void; // play a range of a media document
+ Play?: () => void; // play a media documents
+ Pause?: () => void; // pause a media document (eg, audio/video)
+ IsPlaying?: () => boolean; // is a media document playing
+ PlayerTime?: () => number | undefined; // current timecode of player
+ TogglePause?: (keep?: boolean) => void; // toggle media document playing state
+ setFocus?: () => void; // sets input focus to the componentView
+ setData?: (data: FieldType | Promise<RefField | undefined>) => boolean;
+ componentUI?: (boundsLeft: number, boundsTop: number) => JSX.Element | null;
+ dragStarting?: (snapToDraggedDoc: boolean, showGroupDragTarget: boolean, visited: Set<Doc>) => void;
+ dragConfig?: (dragData: DragManager.DocumentDragData) => void; // function to setup dragData in custom way (see TreeViews which add a tree view flag)
+ incrementalRendering?: () => void;
+ infoUI?: () => JSX.Element | null;
+ contentBounds?: () => undefined | { bounds: { x: number; y: number; r: number; b: number }; cx: number; cy: number; width: number; height: number }; // bounds of contents in collection coordinate space (used by TabDocViewThumb)
+ screenBounds?: () => Opt<{ left: number; top: number; right: number; bottom: number; transition?: string }>;
+ ptToScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
+ ptFromScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
+ snapPt?: (pt: { X: number; Y: number }, excludeSegs?: number[]) => { nearestPt: { X: number; Y: number }; distance: number };
+ search?: (str: string, bwd?: boolean, clear?: boolean) => boolean;
+ dontRegisterView?: () => boolean; // KeyValueBox's don't want to register their views
+ isUnstyledView?: () => boolean; // SchemaView and KeyValue are unstyled -- not titles, no opacity, no animations
+}
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index cc4da1694..d9ff21035 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -4,7 +4,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Utils, emptyFunction, setupMoveUpEvents } from '../../../Utils';
+import { setupMoveUpEvents } from '../../../ClientUtils';
+import { Utils, emptyFunction } from '../../../Utils';
import { Doc, DocListCast } from '../../../fields/Doc';
import { BoolCast, NumCast, StrCast } from '../../../fields/Types';
import { DocumentType } from '../../documents/DocumentTypes';
@@ -45,13 +46,13 @@ import { Track } from './Track';
@observer
export class Timeline extends ObservableReactComponent<FieldViewProps> {
- //readonly constants
+ // readonly constants
private readonly DEFAULT_TICK_SPACING: number = 50;
private readonly MAX_TITLE_HEIGHT = 75;
private readonly MAX_CONTAINER_HEIGHT: number = 800;
private readonly DEFAULT_TICK_INCREMENT: number = 1000;
- //height variables
+ // height variables
private DEFAULT_CONTAINER_HEIGHT: number = 330;
private MIN_CONTAINER_HEIGHT: number = 205;
@@ -60,7 +61,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
makeObservable(this);
}
- //react refs
+ // react refs
@observable private _trackbox = React.createRef<HTMLDivElement>();
@observable private _titleContainer = React.createRef<HTMLDivElement>();
@observable private _timelineContainer = React.createRef<HTMLDivElement>();
@@ -68,7 +69,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
@observable private _roundToggleRef = React.createRef<HTMLDivElement>();
@observable private _roundToggleContainerRef = React.createRef<HTMLDivElement>();
- //boolean vars and instance vars
+ // boolean vars and instance vars
@observable private _currentBarX: number = 0;
@observable private _windSpeed: number = 1;
@observable private _totalLength: number = 0;
@@ -77,11 +78,11 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
@observable private _containerHeight: number = this.DEFAULT_CONTAINER_HEIGHT;
@observable private _tickSpacing = this.DEFAULT_TICK_SPACING;
@observable private _tickIncrement = this.DEFAULT_TICK_INCREMENT;
- @observable private _time = 100000; //DEFAULT
+ @observable private _time = 100000; // DEFAULT
@observable private _playButton = faPlayCircle;
@observable private _titleHeight = 0;
- @observable public IsPlaying: boolean = false; //scrubber playing
+ @observable public IsPlaying: boolean = false; // scrubber playing
/**
* collection get method. Basically defines what defines collection's children. These will be tracked in the timeline. Do not edit.
@@ -95,30 +96,30 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
return DocListCast(this._props.Document[this._props.fieldKey]);
}
- /////////lifecycle functions////////////
+ /// //////lifecycle functions////////////
@action
componentDidMount() {
- const relativeHeight = window.innerHeight / 20; //sets height to arbitrary size, relative to innerHeight
- this._titleHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; //check if relHeight is less than Maxheight. Else, just set relheight to max
- this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; //offset
- this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; //twice the titleheight + offset
+ const relativeHeight = window.innerHeight / 20; // sets height to arbitrary size, relative to innerHeight
+ this._titleHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; // check if relHeight is less than Maxheight. Else, just set relheight to max
+ this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; // offset
+ this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; // twice the titleheight + offset
if (!this._props.Document.AnimationLength) {
- //if animation length did not exist
- this._props.Document.AnimationLength = this._time; //set it to default time
+ // if animation length did not exist
+ this._props.Document.AnimationLength = this._time; // set it to default time
} else {
- this._time = NumCast(this._props.Document.AnimationLength); //else, set time to animationlength stored from before
+ this._time = NumCast(this._props.Document.AnimationLength); // else, set time to animationlength stored from before
}
- this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); //the entire length of the timeline div (actual div part itself)
- this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; //the visible length of the timeline (the length that you current see)
- this._visibleStart = this._infoContainer.current!.scrollLeft; //where the div starts
- this._props.Document.isATOn = !this._props.Document.isATOn; //turns the boolean on, saying AT (animation timeline) is on
+ this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); // the entire length of the timeline div (actual div part itself)
+ this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; // the visible length of the timeline (the length that you current see)
+ this._visibleStart = this._infoContainer.current!.scrollLeft; // where the div starts
+ this._props.Document.isATOn = !this._props.Document.isATOn; // turns the boolean on, saying AT (animation timeline) is on
this.toggleHandle();
}
componentWillUnmount() {
- this._props.Document.AnimationLength = this._time; //save animation length
+ this._props.Document.AnimationLength = this._time; // save animation length
}
- /////////////////////////////////////////////////
+ /// //////////////////////////////////////////////
/**
* React Functional Component
@@ -146,7 +147,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
pixel <= 0 ? (this._currentBarX = 0) : pixel >= this._totalLength ? (this._currentBarX = this._totalLength) : (this._currentBarX = pixel);
};
- //for playing
+ // for playing
onPlay = (e: React.MouseEvent) => {
e.stopPropagation();
this.play();
@@ -179,7 +180,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
e.preventDefault();
e.stopPropagation();
if (this._windSpeed < 64) {
- //max speed is 32
+ // max speed is 32
this._windSpeed = this._windSpeed * 2;
}
};
@@ -213,7 +214,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
const scrubberbox = this._infoContainer.current!;
const left = scrubberbox.getBoundingClientRect().left;
const offsetX = Math.round(e.clientX - left) * this._props.ScreenToLocalTransform().Scale;
- this.changeCurrentBarX(offsetX + this._visibleStart); //changes scrubber to clicked scrubber position
+ this.changeCurrentBarX(offsetX + this._visibleStart); // changes scrubber to clicked scrubber position
return false;
};
@@ -353,12 +354,12 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
* tool box includes the toggle buttons at the top of the timeline (both editing mode and play mode)
*/
private timelineToolBox = (scale: number, totalTime: number) => {
- const size = 40 * scale; //50 is default
+ const size = 40 * scale; // 50 is default
const iconSize = 25;
const width: number = this._props.PanelWidth();
const modeType = this._props.Document.isATOn ? 'Author' : 'Play';
- //decides if information should be omitted because the timeline is very small
+ // decides if information should be omitted because the timeline is very small
// if its less than 950 pixels then it's going to be overlapping
let modeString = modeType,
overviewString = '',
@@ -467,7 +468,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
this._props.Document.isATOn = !this._props.Document.isATOn;
if (!BoolCast(this._props.Document.isATOn)) {
- //turning on playmode...
+ // turning on playmode...
roundToggle.style.transform = 'translate(0px, 0px)';
roundToggle.style.animationName = 'turnoff';
roundToggleContainer.style.animationName = 'turnoff';
@@ -475,7 +476,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
timelineContainer.style.top = `${-this._containerHeight}px`;
this.toPlay();
} else {
- //turning on authoring mode...
+ // turning on authoring mode...
roundToggle.style.transform = 'translate(20px, 0px)';
roundToggle.style.animationName = 'turnon';
roundToggleContainer.style.animationName = 'turnon';
@@ -488,8 +489,8 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
@action.bound
changeLengths() {
if (this._infoContainer.current) {
- this._visibleLength = this._infoContainer.current.getBoundingClientRect().width; //the visible length of the timeline (the length that you current see)
- this._visibleStart = this._infoContainer.current.scrollLeft; //where the div starts
+ this._visibleLength = this._infoContainer.current.getBoundingClientRect().width; // the visible length of the timeline (the length that you current see)
+ this._visibleStart = this._infoContainer.current.scrollLeft; // where the div starts
}
}
@@ -513,7 +514,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
}
}
} else {
- //TODO: remove undefineds and duplicates
+ // TODO: remove undefineds and duplicates
}
});
return longestTime;
@@ -546,7 +547,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
<div key="timeline_info" className="info-container" onPointerDown={this.onPanDown} ref={this._infoContainer} onWheel={this.onWheelZoom}>
{this.drawTicks()}
<div key="timeline_scrubber" className="scrubber" style={{ transform: `translate(${this._currentBarX}px)` }}>
- <div key="timeline_scrubberhead" className="scrubberhead" onPointerDown={this.onScrubberDown}></div>
+ <div key="timeline_scrubberhead" className="scrubberhead" onPointerDown={this.onScrubberDown} />
</div>
<div key="timeline_trackbox" className="trackbox" ref={this._trackbox} style={{ width: `${this._totalLength}px` }}>
{[...this.children, this._props.Document].map(doc => (
diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx
index 97a571dc4..0d7873931 100644
--- a/src/client/views/animationtimeline/TimelineMenu.tsx
+++ b/src/client/views/animationtimeline/TimelineMenu.tsx
@@ -1,3 +1,5 @@
+/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { IconLookup } from '@fortawesome/fontawesome-svg-core';
import { faChartLine, faClipboard } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -9,6 +11,7 @@ import './TimelineMenu.scss';
@observer
export class TimelineMenu extends React.Component {
+ // eslint-disable-next-line no-use-before-define
public static Instance: TimelineMenu;
@observable private _opacity = 0;
diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx
index 489c4dcde..7bf685c9e 100644
--- a/src/client/views/animationtimeline/TimelineOverview.tsx
+++ b/src/client/views/animationtimeline/TimelineOverview.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/no-unused-prop-types */
import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -32,7 +33,6 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
@observable private visibleTime: number = 0;
@observable private currentX: number = 0;
@observable private visibleStart: number = 0;
- private readonly DEFAULT_HEIGHT = 50;
private readonly DEFAULT_WIDTH = 300;
componentDidMount() {
@@ -50,9 +50,9 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
);
}
- componentWillUnmount = () => {
+ componentWillUnmount() {
this._authoringReaction && this._authoringReaction();
- };
+ }
@action
setOverviewWidth() {
@@ -109,7 +109,7 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
e.preventDefault();
e.stopPropagation();
const scrubberRef = this._scrubberRef.current!;
- const left = scrubberRef.getBoundingClientRect().left;
+ const { left } = scrubberRef.getBoundingClientRect();
const offsetX = Math.round(e.clientX - left);
this.props.changeCurrentBarX((offsetX / this.activeOverviewWidth) * this.props.totalLength + this.props.currentBarX);
};
@@ -152,17 +152,17 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
const timeline = this.props.isAuthoring
? [
<div key="timeline-overview-container" className="timeline-overview-container overviewBar" id="timelineOverview" ref={this.authoringContainer}>
- <div ref={this._visibleRef} key="1" className="timeline-overview-visible" style={{ left: `${barStart}px`, width: `${visibleBarWidth}px` }} onPointerDown={this.onPointerDown}></div>,
+ <div ref={this._visibleRef} key="1" className="timeline-overview-visible" style={{ left: `${barStart}px`, width: `${visibleBarWidth}px` }} onPointerDown={this.onPointerDown} />,
<div ref={this._scrubberRef} key="2" className="timeline-overview-scrubber-container" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown}>
- <div key="timeline-overview-scrubber-head" className="timeline-overview-scrubber-head"></div>
+ <div key="timeline-overview-scrubber-head" className="timeline-overview-scrubber-head" />
</div>
</div>,
]
: [
<div key="1" className="timeline-play-bar overviewBar" id="timelinePlay" ref={this.playbackContainer}>
- <div ref={this._scrubberRef} className="timeline-play-head" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown}></div>
+ <div ref={this._scrubberRef} className="timeline-play-head" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown} />
</div>,
- <div key="2" className="timeline-play-tail" style={{ width: `${playWidth}px` }}></div>,
+ <div key="2" className="timeline-play-tail" style={{ width: `${playWidth}px` }} />,
];
return (
<div className="timeline-flex">
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index 490a14be5..1e4ed74be 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -73,7 +73,7 @@ export class Track extends ObservableReactComponent<IProps> {
this._timelineVisibleReaction?.();
this._autoKfReaction?.();
}
- ////////////////////////////////
+ // //////////////////////////////
getLastRegionTime = () => {
let lastTime: number = 0;
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
index cbcc980a9..a08a7c7c1 100644
--- a/src/client/views/collections/CollectionCalendarView.tsx
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -1,7 +1,8 @@
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { dateRangeStrToDates, emptyFunction, returnTrue } from '../../../Utils';
+import { emptyFunction } from '../../../Utils';
+import { dateRangeStrToDates, returnTrue } from '../../../ClientUtils';
import { Doc, DocListCast } from '../../../fields/Doc';
import { StrCast } from '../../../fields/Types';
import { CollectionStackingView } from './CollectionStackingView';
@@ -24,16 +25,13 @@ export class CollectionCalendarView extends CollectionSubView() {
removeCalendar = () => {};
- addCalendar = (doc: Doc | Doc[], annotationKey?: string | undefined): boolean => {
+ addCalendar = (/* doc: Doc | Doc[], annotationKey?: string | undefined */): boolean =>
// bring up calendar modal with option to create a calendar
- return true;
- };
+ true;
_stackRef = React.createRef<CollectionStackingView>();
- panelHeight = () => {
- return this._props.PanelHeight() - 40; // this should be the height of the stacking view. For now, it's the hieight of the calendar view minus 40 to allow for a title
- };
+ panelHeight = () => this._props.PanelHeight() - 40; // this should be the height of the stacking view. For now, it's the hieight of the calendar view minus 40 to allow for a title
// most recent calendar should come first
sortByMostRecentDate = (calendarA: Doc, calendarB: Doc) => {
@@ -45,18 +43,18 @@ export class CollectionCalendarView extends CollectionSubView() {
if (aFromDate > bFromDate) {
return -1; // a comes first
- } else if (aFromDate < bFromDate) {
+ }
+ if (aFromDate < bFromDate) {
+ return 1; // b comes first
+ }
+ // start dates are the same
+ if (aToDate > bToDate) {
+ return -1; // a comes first
+ }
+ if (aToDate < bToDate) {
return 1; // b comes first
- } else {
- // start dates are the same
- if (aToDate > bToDate) {
- return -1; // a comes first
- } else if (aToDate < bToDate) {
- return 1; // b comes first
- } else {
- return 0; // same start and end dates
- }
}
+ return 0; // same start and end dates
};
screenToLocalTransform = () =>
@@ -73,12 +71,12 @@ export class CollectionCalendarView extends CollectionSubView() {
return (
<div className="collectionCalendarView">
<CollectionStackingView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setContentViewBox={emptyFunction}
ref={this._stackRef}
PanelHeight={this.panelHeight}
PanelWidth={this._props.PanelWidth}
- // childFilters={this.childFilters} DO I NEED THIS?
sortFunc={this.sortByMostRecentDate}
setHeight={undefined}
isAnnotationOverlay={false}
diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss
new file mode 100644
index 000000000..a089b248d
--- /dev/null
+++ b/src/client/views/collections/CollectionCardDeckView.scss
@@ -0,0 +1,84 @@
+@import '../global/globalCssVariables.module.scss';
+
+.collectionCardView-outer {
+ height: 100%;
+ width: 100%;
+ position: relative;
+ background-color: white;
+ overflow: hidden;
+}
+
+.card-wrapper {
+ display: grid;
+ grid-template-columns: repeat(10, 1fr);
+ // width: 100%;
+ transform-origin: top left;
+
+ position: absolute;
+ align-items: center;
+ justify-items: center;
+ justify-content: center;
+
+ transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955);
+}
+
+.card-button-container {
+ display: flex;
+ padding: 3px;
+ // width: 300px;
+ background-color: rgb(218, 218, 218); /* Background color of the container */
+ border-radius: 50px; /* Rounds the corners of the container */
+ transform: translateY(75px);
+ // box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Optional: Adds shadow for depth */
+ align-items: center; /* Centers buttons vertically */
+ justify-content: start; /* Centers buttons horizontally */
+}
+
+button {
+ width: 35px;
+ height: 35px;
+ border-radius: 50%;
+ background-color: $dark-gray;
+ // border-color: $medium-blue;
+ margin: 5px; // transform: translateY(-50px);
+}
+
+// button:hover {
+// transform: translateY(-50px);
+// }
+
+// .card-wrapper::after {
+// content: "";
+// width: 100%; /* Forces wrapping */
+// }
+
+// .card-wrapper > .card-item:nth-child(10n)::after {
+// content: "";
+// width: 100%; /* Forces wrapping after every 10th item */
+// }
+
+// .card-row{
+// display: flex;
+// position: absolute;
+// align-items: center;
+// transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955);
+
+// }
+
+.card-item-inactive,
+.card-item-active,
+.card-item {
+ position: relative;
+ transition: transform 0.5s ease-in-out;
+ display: flex;
+ flex-direction: column;
+}
+
+.card-item-inactive {
+ opacity: 0.5;
+}
+
+.card-item-active {
+ position: absolute;
+ z-index: 100;
+}
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
new file mode 100644
index 000000000..34800040c
--- /dev/null
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -0,0 +1,513 @@
+import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { ClientUtils, DashColor, returnFalse, returnZero } from '../../../ClientUtils';
+import { numberRange } from '../../../Utils';
+import { Doc, NumListCast } from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
+import { Id } from '../../../fields/FieldSymbols';
+import { BoolCast, Cast, DateCast, NumCast, RTFCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { URLField } from '../../../fields/URLField';
+import { gptImageLabel } from '../../apis/gpt/GPT';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { DragManager } from '../../util/DragManager';
+import { SnappingManager } from '../../util/SnappingManager';
+import { Transform } from '../../util/Transform';
+import { undoable } from '../../util/UndoManager';
+import { StyleProp } from '../StyleProp';
+import { DocumentView } from '../nodes/DocumentView';
+import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup';
+import './CollectionCardDeckView.scss';
+import { CollectionSubView } from './CollectionSubView';
+
+enum cardSortings {
+ Time = 'time',
+ Type = 'type',
+ Color = 'color',
+ Custom = 'custom',
+ None = '',
+}
+@observer
+export class CollectionCardView extends CollectionSubView() {
+ private _dropDisposer?: DragManager.DragDropDisposer;
+ private _childDocumentWidth = 600; // target width of a Doc...
+ private _disposers: { [key: string]: IReactionDisposer } = {};
+ private _textToDoc = new Map<string, Doc>();
+
+ @observable _forceChildXf = false;
+ @observable _isLoading = false;
+ @observable _hoveredNodeIndex = -1;
+ @observable _docRefs = new ObservableMap<Doc, DocumentView>();
+ @observable _maxRowCount = 10;
+
+ static getButtonGroup(groupFieldKey: 'chat' | 'star' | 'idea' | 'like', doc: Doc): number | undefined {
+ return Cast(doc[groupFieldKey], 'number', null);
+ }
+
+ static imageUrlToBase64 = async (imageUrl: string): Promise<string> => {
+ try {
+ const response = await fetch(imageUrl);
+ const blob = await response.blob();
+
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.readAsDataURL(blob);
+ reader.onloadend = () => resolve(reader.result as string);
+ reader.onerror = error => reject(error);
+ });
+ } catch (error) {
+ console.error('Error:', error);
+ throw error;
+ }
+ };
+
+ protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
+ this._dropDisposer?.();
+ if (ele) {
+ this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc);
+ }
+ };
+
+ constructor(props: any) {
+ super(props);
+ makeObservable(this);
+ }
+
+ componentDidMount(): void {
+ this._disposers.sort = reaction(
+ () => ({ cardSort: this.cardSort, field: this.cardSort_customField }),
+ ({ cardSort, field }) => (cardSort === cardSortings.Custom && field === 'chat' ? this.openChatPopup() : GPTPopup.Instance.setVisible(false))
+ );
+ }
+
+ componentWillUnmount() {
+ Object.keys(this._disposers).forEach(key => this._disposers[key]?.());
+ this._dropDisposer?.();
+ }
+
+ @computed get cardSort_customField() {
+ return StrCast(this.Document.cardSort_customField) as any as 'chat' | 'star' | 'idea' | 'like';
+ }
+
+ @computed get cardSort() {
+ return StrCast(this.Document.cardSort) as any as cardSortings;
+ }
+ /**
+ * how much to scale down the contents of the view so that everything will fit
+ */
+ @computed get fitContentScale() {
+ const length = Math.min(this.childDocsWithoutLinks.length, this._maxRowCount);
+ return (this._childDocumentWidth * length) / this._props.PanelWidth();
+ }
+
+ @computed get translateWrapperX() {
+ let translate = 0;
+
+ if (this.inactiveDocs().length !== this.childDocsWithoutLinks.length && this.inactiveDocs().length < 10) {
+ translate += this.panelWidth() / 2;
+ }
+ return translate;
+ }
+
+ /**
+ * The child documents to be rendered-- either all of them except the Links or the docs in the currently active
+ * custom group
+ */
+ @computed get childDocsWithoutLinks() {
+ const regularDocs = this.childDocs.filter(l => l.type !== DocumentType.LINK);
+ const activeGroups = NumListCast(this.Document.cardSort_visibleSortGroups);
+
+ if (activeGroups.length > 0 && this.cardSort === cardSortings.Custom) {
+ return regularDocs.filter(doc => {
+ // Get the group number for the current index
+ const groupNumber = CollectionCardView.getButtonGroup(this.cardSort_customField, doc);
+ // Check if the group number is in the active groups
+ return groupNumber !== undefined && activeGroups.includes(groupNumber);
+ });
+ }
+
+ // Default return for non-custom cardSort or other cases, filtering out links
+ return regularDocs;
+ }
+
+ /**
+ * Determines the order in which the cards will be rendered depending on the current sort type
+ */
+ @computed get sortedDocs() {
+ return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.layoutDoc.sortDesc));
+ }
+
+ @action
+ setHoveredNodeIndex = (index: number) => {
+ if (!DocumentView.SelectedDocs().includes(this.childDocs[index])) {
+ this._hoveredNodeIndex = index;
+ }
+ };
+ /**
+ * Translates the hovered node to the center of the screen
+ * @param index
+ * @returns
+ */
+ translateHover = (index: number) => (this._hoveredNodeIndex === index && !DocumentView.SelectedDocs().includes(this.childDocs[index]) ? -50 : 0);
+
+ isSelected = (index: number) => DocumentView.SelectedDocs().includes(this.childDocs[index]);
+
+ /**
+ * Returns all the documents except the one that's currently selected
+ */
+ inactiveDocs = () => this.childDocsWithoutLinks.filter(d => !DocumentView.SelectedDocs().includes(d));
+
+ panelWidth = () => this._childDocumentWidth;
+ panelHeight = (layout: Doc) => () => (this.panelWidth() * NumCast(layout._height)) / NumCast(layout._width);
+ onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick);
+ isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive();
+ isChildContentActive = () => (this.isContentActive() ? true : false);
+
+ /**
+ * Returns the degree to rotate a card dependind on the amount of cards in their row and their index in said row
+ * @param amCards
+ * @param index
+ * @returns
+ */
+ rotate = (amCards: number, index: number) => {
+ const possRotate = -30 + index * (30 / ((amCards - (amCards % 2)) / 2));
+ const stepMag = Math.abs(-30 + (amCards / 2 - 1) * (30 / ((amCards - (amCards % 2)) / 2)));
+
+ if (amCards % 2 == 0 && possRotate == 0) {
+ return possRotate + Math.abs(-30 + (index - 1) * (30 / (amCards / 2)));
+ }
+ if (amCards % 2 == 0 && index > (amCards + 1) / 2) {
+ return possRotate + stepMag;
+ }
+
+ return possRotate;
+ };
+ /**
+ * Returns the degree to which a card should be translated in the y direction for the arch effect
+ */
+ translateY = (amCards: number, index: number, realIndex: number) => {
+ const evenOdd = amCards % 2;
+ const apex = (amCards - evenOdd) / 2;
+ const stepMag = 200 / ((amCards - evenOdd) / 2) + Math.abs((apex - index) * 25);
+
+ let rowOffset = 0;
+ if (realIndex > this._maxRowCount - 1) {
+ rowOffset = 400 * ((realIndex - (realIndex % this._maxRowCount)) / this._maxRowCount);
+ }
+ if (evenOdd == 1 || index < apex - 1) {
+ return Math.abs(stepMag * (apex - index)) - rowOffset;
+ }
+ if (index == apex || index == apex - 1) {
+ return 0 - rowOffset;
+ }
+
+ return Math.abs(stepMag * (apex - index - 1)) - rowOffset;
+ };
+
+ /**
+ * Translates the selected node to the middle fo the screen
+ * @param index
+ * @returns
+ */
+ translateSelected = (index: number): number => {
+ // if (this.isSelected(index)) {
+ const middleOfPanel = this._props.PanelWidth() / 2;
+ const scaledNodeWidth = this.panelWidth() * 1.25;
+
+ // Calculate the position of the node's left edge before scaling
+ const nodeLeftEdge = index * this.panelWidth();
+ // Find the center of the node after scaling
+ const scaledNodeCenter = nodeLeftEdge + scaledNodeWidth / 2;
+
+ // Calculate the translation needed to align the scaled node's center with the panel's center
+ const translation = middleOfPanel - scaledNodeCenter - scaledNodeWidth - scaledNodeWidth / 4;
+
+ return translation;
+ };
+
+ /**
+ * Called in the sortedDocsType method. Compares the cards' value in regards to the desired sort type-- earlier cards are move to the
+ * front, latter cards to the back
+ * @param docs
+ * @param sortType
+ * @param isDesc
+ * @returns
+ */
+ sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean) => {
+ if (sortType === cardSortings.None) return docs;
+ docs.sort((docA, docB) => {
+ const [typeA, typeB] = (() => {
+ switch (sortType) {
+ case cardSortings.Time:
+ return [DateCast(docA.author_date)?.date ?? Date.now(),
+ DateCast(docB.author_date)?.date ?? Date.now()];
+ case cardSortings.Color:
+ return [DashColor(StrCast(docA.backgroundColor)).hsv().toString(), // If docA.type is undefined, use an empty string
+ DashColor(StrCast(docB.backgroundColor)).hsv().toString()]; // If docB.type is undefined, use an empty string
+ case cardSortings.Custom:
+ return [CollectionCardView.getButtonGroup(this.cardSort_customField, docA)??0,
+ CollectionCardView.getButtonGroup(this.cardSort_customField, docB)??0];
+ default: return [StrCast(docA.type), // If docA.type is undefined, use an empty string
+ StrCast(docB.type)]; // If docB.type is undefined, use an empty string
+ } // prettier-ignore
+ })();
+
+ const out = typeA < typeB ? -1 : typeA > typeB ? 1 : 0;
+ return isDesc ? -out : out; // Reverse the sort order if descending is true
+ });
+
+ return docs;
+ };
+
+ displayDoc = (doc: Doc, screenToLocalTransform: () => Transform) => {
+ return (
+ <DocumentView
+ {...this._props}
+ ref={action((r: DocumentView) => r?.ContentDiv && this._docRefs.set(doc, r))}
+ Document={doc}
+ NativeWidth={returnZero}
+ NativeHeight={returnZero}
+ fitWidth={returnFalse}
+ onDoubleClickScript={this.onChildDoubleClick}
+ renderDepth={this._props.renderDepth + 1}
+ LayoutTemplate={this._props.childLayoutTemplate}
+ LayoutTemplateString={this._props.childLayoutString}
+ ScreenToLocalTransform={screenToLocalTransform} //makes sure the box wrapper thing is in the right spot
+ isContentActive={this.isChildContentActive}
+ isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
+ PanelWidth={this.panelWidth}
+ PanelHeight={this.panelHeight(doc)}
+ />
+ );
+ };
+
+ /**
+ * Determines how many cards are in the row of a card at a specific index
+ * @param index
+ * @returns
+ */
+ overflowAmCardsCalc = (index: number) => {
+ if (this.inactiveDocs().length < this._maxRowCount) {
+ return this.inactiveDocs().length;
+ }
+ // 13 - 3 = 10
+ const totalCards = this.inactiveDocs().length;
+ // if 9 or less
+ if (index < totalCards - (totalCards % 10)) {
+ return this._maxRowCount;
+ }
+ //(3)
+ return totalCards % 10;
+ };
+ /**
+ * Determines the index a card is in in a row
+ * @param realIndex
+ * @returns
+ */
+ overflowIndexCalc = (realIndex: number) => realIndex % 10;
+ /**
+ * Translates the cards in the second rows and beyond over to the right
+ * @param realIndex
+ * @param calcIndex
+ * @param calcRowCards
+ * @returns
+ */
+ translateOverflowX = (realIndex: number, calcRowCards: number) => (realIndex < this._maxRowCount ? 0 : (10 - calcRowCards) * (this.panelWidth() / 2));
+
+ /**
+ * Determines how far to translate a card in the y direction depending on its index, whether or not its being hovered, or if it's selected
+ * @param isHovered
+ * @param isSelected
+ * @param realIndex
+ * @param amCards
+ * @param calcRowIndex
+ * @returns
+ */
+ calculateTranslateY = (isHovered: boolean, isSelected: boolean, realIndex: number, amCards: number, calcRowIndex: number) => {
+ if (isSelected) return 50 * this.fitContentScale;
+ const trans = isHovered ? this.translateHover(realIndex) : 0;
+ return trans + this.translateY(amCards, calcRowIndex, realIndex);
+ };
+
+ /**
+ * Toggles the buttons between on and off when creating custom sort groupings/changing those created by gpt
+ * @param childPairIndex
+ * @param buttonID
+ * @param doc
+ */
+ toggleButton = undoable((buttonID: number, doc: Doc) => this.cardSort_customField && (doc[this.cardSort_customField] = buttonID), 'toggle custom button');
+
+ /**
+ * A list of the text content of all the child docs. RTF documents will have just their text and pdf documents will have the first 50 words.
+ * Image documents are converted to bse64 and gpt generates a description for them. all other documents use their title. This string is
+ * inputted into the gpt prompt to sort everything together
+ * @returns
+ */
+ childPairStringList = () => {
+ const docToText = (doc: Doc) => {
+ switch (doc.type) {
+ case DocumentType.PDF: const words = StrCast(doc.text).split(/\s+/);
+ return words.slice(0, 50).join(' '); // first 50 words of pdf text
+ case DocumentType.IMG: return this.getImageDesc(doc);
+ case DocumentType.RTF: return StrCast(RTFCast(doc.text).Text);
+ default: return StrCast(doc.title);
+ } // prettier-ignore
+ };
+ const docTextPromises = this.childDocsWithoutLinks.map(async doc => {
+ const docText = (await docToText(doc)) ?? '';
+ this._textToDoc.set(docText.trim(), doc);
+ return `======${docText.replace(/\n/g, ' ').trim()}======`;
+ });
+ return Promise.all<string>(docTextPromises);
+ };
+
+ /**
+ * Calls the gpt API to generate descriptions for the images in the view
+ * @param image
+ * @returns
+ */
+ getImageDesc = async (image: Doc) => {
+ if (StrCast(image.description)) return StrCast(image.description); // Return existing description
+ const href = (image.data as URLField).url.href;
+ const hrefParts = href.split('.');
+ const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`;
+ try {
+ const hrefBase64 = await CollectionCardView.imageUrlToBase64(hrefComplete);
+ const response = await gptImageLabel(hrefBase64);
+ image[DocData].description = response.trim();
+ return response; // Return the response from gptImageLabel
+ } catch (error) {
+ console.log('bad things have happened');
+ }
+ return '';
+ };
+
+ /**
+ * Converts the gpt output into a hashmap that can be used for sorting. lists are seperated by ==== while elements within the list are seperated by ~~~~~~
+ * @param gptOutput
+ */
+ processGptOutput = (gptOutput: string) => {
+ // Split the string into individual list items
+ const listItems = gptOutput.split('======').filter(item => item.trim() !== '');
+ listItems.forEach((item, index) => {
+ // Split the item by '~~~~~~' to get all descriptors
+ const parts = item.split('~~~~~~').map(part => part.trim());
+
+ parts.forEach(part => {
+ // Find the corresponding Doc in the textToDoc map
+ const doc = this._textToDoc.get(part);
+ if (doc) {
+ doc.chat = index;
+ }
+ });
+ });
+ };
+ /**
+ * Opens up the chat popup and starts the process for smart sorting.
+ */
+ openChatPopup = async () => {
+ GPTPopup.Instance.setVisible(true);
+ GPTPopup.Instance.setMode(GPTPopupMode.SORT);
+ const sortDesc = await this.childPairStringList(); // Await the promise to get the string result
+ GPTPopup.Instance.setCardsDoneLoading(true); // Set dataDoneLoading to true after data is loaded
+ GPTPopup.Instance.setSortDesc(sortDesc.join());
+ GPTPopup.Instance.onSortComplete = (sortResult: string) => this.processGptOutput(sortResult);
+ };
+
+ /**
+ * Renders the buttons to customize sorting depending on which group the card belongs to and the amount of total groups
+ * @param childPairIndex
+ * @param doc
+ * @returns
+ */
+ renderButtons = (doc: Doc, cardSort: cardSortings) => {
+ if (cardSort !== cardSortings.Custom) return '';
+ const amButtons = Math.max(4, this.childDocs?.reduce((set, doc) => this.cardSort_customField && set.add(NumCast(doc[this.cardSort_customField])), new Set<number>()).size ?? 0);
+ const activeButtonIndex = CollectionCardView.getButtonGroup(this.cardSort_customField, doc);
+ const totalWidth = amButtons * 35 + amButtons * 2 * 5 + 6;
+ return (
+ <div className="card-button-container" style={{ width: `${totalWidth}px` }}>
+ {numberRange(amButtons).map(i => (
+ <button
+ key={i}
+ type="button"
+ style={{ backgroundColor: activeButtonIndex === i ? '#4476f7' : '#323232' }} //
+ onClick={() => this.toggleButton(i, doc)}
+ />
+ ))}
+ </div>
+ );
+ };
+ /**
+ * Actually renders all the cards
+ */
+ renderCards = () => {
+ const anySelected = this.childDocs.some(doc => DocumentView.SelectedDocs().includes(doc));
+ // Map sorted documents to their rendered components
+ return this.sortedDocs.map((doc, index) => {
+ const realIndex = this.sortedDocs.filter(sortDoc => !DocumentView.SelectedDocs().includes(sortDoc)).indexOf(doc);
+ const calcRowIndex = this.overflowIndexCalc(realIndex);
+ const amCards = this.overflowAmCardsCalc(realIndex);
+ const isSelected = DocumentView.SelectedDocs().includes(doc);
+
+ const childScreenToLocal = () => {
+ this._forceChildXf;
+ const dref = this._docRefs.get(doc);
+ const { translateX, translateY, scale } = ClientUtils.GetScreenTransform(dref?.ContentDiv);
+ return new Transform(-translateX + (dref?.centeringX || 0) * scale,
+ -translateY + (dref?.centeringY || 0) * scale, 1)
+ .scale(1 / scale).rotate(!isSelected ? -this.rotate(amCards, calcRowIndex) : 0); // prettier-ignore
+ };
+
+ return (
+ <div
+ key={doc[Id]}
+ className={`card-item${isSelected ? '-active' : anySelected ? '-inactive' : ''}`}
+ onPointerUp={() => {
+ // this turns off documentDecorations during a transition, then turns them back on afterward.
+ SnappingManager.SetIsResizing(this.Document[Id]);
+ setTimeout(
+ action(() => {
+ SnappingManager.SetIsResizing(undefined);
+ this._forceChildXf = !this._forceChildXf;
+ }),
+ 700
+ );
+ }}
+ style={{
+ width: this.panelWidth(),
+ height: 'max-content', // this.panelHeight(childPair.layout)(),
+ transform: `translateY(${this.calculateTranslateY(this._hoveredNodeIndex === index, isSelected, realIndex, amCards, calcRowIndex)}px)
+ translateX(${isSelected ? this.translateSelected(calcRowIndex) : this.translateOverflowX(realIndex, amCards)}px)
+ rotate(${!isSelected ? this.rotate(amCards, calcRowIndex) : 0}deg)
+ scale(${isSelected ? 1.25 : 1})`,
+ }}
+ onMouseEnter={() => this.setHoveredNodeIndex(index)}>
+ {this.displayDoc(doc, childScreenToLocal)}
+ {this.renderButtons(doc, this.cardSort)}
+ </div>
+ );
+ });
+ };
+ render() {
+ return (
+ <div
+ className="collectionCardView-outer"
+ ref={this.createDashEventsTarget}
+ style={{
+ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
+ color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
+ }}>
+ <div
+ className="card-wrapper"
+ style={{
+ transform: ` scale(${1 / this.fitContentScale}) translateX(${this.translateWrapperX}px)`,
+ height: `${100 * this.fitContentScale}%`,
+ }}
+ onMouseLeave={() => this.setHoveredNodeIndex(-1)}>
+ {this.renderCards()}
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 7e484f3df..27c85533f 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -1,24 +1,28 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Utils, emptyFunction, returnFalse, returnZero } from '../../../Utils';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { returnZero } from '../../../ClientUtils';
+import { Utils } from '../../../Utils';
+import { Doc, DocListCast, Opt } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { DocumentType } from '../../documents/DocumentTypes';
import { DragManager } from '../../util/DragManager';
-import { SelectionManager } from '../../util/SelectionManager';
-import { StyleProp } from '../StyleProvider';
+import { StyleProp } from '../StyleProp';
import { DocumentView } from '../nodes/DocumentView';
-import { FocusViewOptions } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
import './CollectionCarousel3DView.scss';
import { CollectionSubView } from './CollectionSubView';
-const { default: { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } } = require('../global/globalCssVariables.module.scss'); // prettier-ignore
+
+const { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } = require('../global/globalCssVariables.module.scss');
+
@observer
export class CollectionCarousel3DView extends CollectionSubView() {
@computed get scrollSpeed() {
- return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; //default scroll speed
+ return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; // default scroll speed
}
constructor(props: any) {
super(props);
@@ -38,21 +42,25 @@ export class CollectionCarousel3DView extends CollectionSubView() {
}
};
+ @computed get carouselItems() {
+ return this.childLayoutPairs.filter(pair => pair.layout.type !== DocumentType.LINK);
+ }
+
centerScale = Number(CAROUSEL3D_CENTER_SCALE);
panelWidth = () => this._props.PanelWidth() / 3;
panelHeight = () => this._props.PanelHeight() * Number(CAROUSEL3D_SIDE_SCALE);
onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick);
isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive();
- isChildContentActive = () => (this.isContentActive() ? true : false);
+ isChildContentActive = () => !!this.isContentActive();
childScreenToLocal = () =>
this._props // document's left is the panel shifted by the doc's index * panelWidth/#docs. But it scales by centerScale around its center, so it's left moves left by the distance of the left from the center (panelwidth/2) * the scale delta (centerScale-1)
.ScreenToLocalTransform() // the top behaves the same way ecept it's shifted by the 'top' amount specified for the panel in css and then by the scale factor.
.translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2, -((Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2)
.scale(1 / this.centerScale);
- focus = (anchor: Doc, options: FocusViewOptions) => {
+ focus = (anchor: Doc, options: FocusViewOptions): Opt<number> => {
const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]);
- if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return;
+ if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return undefined;
options.didMove = true;
const target = DocCast(anchor.annotationOn) ?? anchor;
const index = docs.indexOf(target);
@@ -61,42 +69,39 @@ export class CollectionCarousel3DView extends CollectionSubView() {
};
@computed get content() {
const currentIndex = NumCast(this.layoutDoc._carousel_index);
- const displayDoc = (childPair: { layout: Doc; data: Doc }) => {
- return (
- <DocumentView
- {...this._props}
- Document={childPair.layout}
- TemplateDataDocument={childPair.data}
- //suppressSetHeight={true}
- NativeWidth={returnZero}
- NativeHeight={returnZero}
- layout_fitWidth={undefined}
- onDoubleClickScript={this.onChildDoubleClick}
- renderDepth={this._props.renderDepth + 1}
- LayoutTemplate={this._props.childLayoutTemplate}
- LayoutTemplateString={this._props.childLayoutString}
- focus={this.focus}
- ScreenToLocalTransform={this.childScreenToLocal}
- isContentActive={this.isChildContentActive}
- isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
- PanelWidth={this.panelWidth}
- PanelHeight={this.panelHeight}
- />
- );
- };
-
- return this.childLayoutPairs.map((childPair, index) => {
- return (
- <div key={childPair.layout[Id]} className={`collectionCarousel3DView-item${index === currentIndex ? '-active' : ''} ${index}`} style={{ width: this.panelWidth() }}>
- {displayDoc(childPair)}
- </div>
- );
- });
+ const displayDoc = (childPair: { layout: Doc; data: Doc }) => (
+ <DocumentView
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ {...this._props}
+ Document={childPair.layout}
+ TemplateDataDocument={childPair.data}
+ // suppressSetHeight={true}
+ NativeWidth={returnZero}
+ NativeHeight={returnZero}
+ fitWidth={undefined}
+ onDoubleClickScript={this.onChildDoubleClick}
+ renderDepth={this._props.renderDepth + 1}
+ LayoutTemplate={this._props.childLayoutTemplate}
+ LayoutTemplateString={this._props.childLayoutString}
+ focus={this.focus}
+ ScreenToLocalTransform={this.childScreenToLocal}
+ isContentActive={this.isChildContentActive}
+ isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
+ PanelWidth={this.panelWidth}
+ PanelHeight={this.panelHeight}
+ />
+ );
+
+ return this.carouselItems.map((childPair, index) => (
+ <div key={childPair.layout[Id]} className={`collectionCarousel3DView-item${index === currentIndex ? '-active' : ''} ${index}`} style={{ width: this.panelWidth() }}>
+ {displayDoc(childPair)}
+ </div>
+ ));
}
changeSlide = (direction: number) => {
- SelectionManager.DeselectAll();
- this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) + direction + this.childLayoutPairs.length) % this.childLayoutPairs.length;
+ DocumentView.DeselectAll();
+ this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) + direction + this.carouselItems.length) % this.carouselItems.length;
};
onArrowClick = (direction: number) => {
@@ -119,21 +124,21 @@ export class CollectionCarousel3DView extends CollectionSubView() {
};
toggleAutoScroll = (direction: number) => {
- this.layoutDoc.autoScrollOn = this.layoutDoc.autoScrollOn ? false : true;
+ this.layoutDoc.autoScrollOn = !this.layoutDoc.autoScrollOn;
this.layoutDoc.autoScrollOn ? this.startAutoScroll(direction) : this.stopAutoScroll();
};
fadeScrollButton = () => {
window.setTimeout(() => {
- !this.layoutDoc.autoScrollOn && (this.layoutDoc.showScrollButton = 'none'); //fade away after 1.5s if it's not clicked.
+ !this.layoutDoc.autoScrollOn && (this.layoutDoc.showScrollButton = 'none'); // fade away after 1.5s if it's not clicked.
}, 1500);
};
@computed get buttons() {
return (
<div className="arrow-buttons">
- <div title="click to go back" key="back" className="carousel3DView-back" onClick={e => this.onArrowClick(-1)} />
- <div title="click to advance" key="fwd" className="carousel3DView-fwd" onClick={e => this.onArrowClick(1)} />
+ <div title="click to go back" key="back" className="carousel3DView-back" onClick={() => this.onArrowClick(-1)} />
+ <div title="click to advance" key="fwd" className="carousel3DView-fwd" onClick={() => this.onArrowClick(1)} />
{/* {this.autoScrollButton} */}
</div>
);
@@ -144,17 +149,25 @@ export class CollectionCarousel3DView extends CollectionSubView() {
return (
<>
<div className={`carousel3DView-back-scroll${whichButton === 'back' ? '' : '-hidden'}`} style={{ background: `${StrCast(this.Document.backgroundColor)}` }} onClick={() => this.toggleAutoScroll(-1)}>
- {this.layoutDoc.autoScrollOn ? <FontAwesomeIcon icon={'pause'} size={'1x'} /> : <FontAwesomeIcon icon={'angle-double-left'} size={'1x'} />}
+ {this.layoutDoc.autoScrollOn ? <FontAwesomeIcon icon="pause" size="1x" /> : <FontAwesomeIcon icon="angle-double-left" size="1x" />}
</div>
<div className={`carousel3DView-fwd-scroll${whichButton === 'fwd' ? '' : '-hidden'}`} style={{ background: `${StrCast(this.Document.backgroundColor)}` }} onClick={() => this.toggleAutoScroll(1)}>
- {this.layoutDoc.autoScrollOn ? <FontAwesomeIcon icon={'pause'} size={'1x'} /> : <FontAwesomeIcon icon={'angle-double-right'} size={'1x'} />}
+ {this.layoutDoc.autoScrollOn ? <FontAwesomeIcon icon="pause" size="1x" /> : <FontAwesomeIcon icon="angle-double-right" size="1x" />}
</div>
</>
);
}
@computed get dots() {
- return this.childLayoutPairs.map((_child, index) => <div key={Utils.GenerateGuid()} className={`dot${index === NumCast(this.layoutDoc._carousel_index) ? '-active' : ''}`} onClick={() => (this.layoutDoc._carousel_index = index)} />);
+ return this.carouselItems.map((_child, index) => (
+ <div
+ key={Utils.GenerateGuid()}
+ className={`dot${index === NumCast(this.layoutDoc._carousel_index) ? '-active' : ''}`}
+ onClick={() => {
+ this.layoutDoc._carousel_index = index;
+ }}
+ />
+ ));
}
@computed get translateX() {
const index = NumCast(this.layoutDoc._carousel_index);
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index d45b0822b..b736c7ced 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -1,12 +1,17 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable react/jsx-props-no-spreading */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { StopEvent, emptyFunction, returnFalse, returnOne, returnZero } from '../../../Utils';
+import { emptyFunction } from '../../../Utils';
+import { StopEvent, returnFalse, returnOne, returnZero } from '../../../ClientUtils';
import { Doc, Opt } from '../../../fields/Doc';
import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { DocumentType } from '../../documents/DocumentTypes';
import { DragManager } from '../../util/DragManager';
-import { StyleProp } from '../StyleProvider';
+import { StyleProp } from '../StyleProp';
import { DocumentView } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
@@ -33,6 +38,10 @@ export class CollectionCarouselView extends CollectionSubView() {
}
};
+ @computed get carouselItems() {
+ return this.childLayoutPairs.filter(pair => pair.layout.type !== DocumentType.LINK);
+ }
+
/**
* Goes to the next flashcard in the stack and filters
* based on the the currently selected option.
@@ -143,7 +152,7 @@ export class CollectionCarouselView extends CollectionSubView() {
captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<FieldViewProps>, property: string): any => {
// first look for properties on the document in the carousel, then fallback to properties on the container
- const childValue = doc?.['caption-' + property] ? this._props.styleProvider?.(doc, captionProps, property) : undefined;
+ const childValue = doc?.['caption_' + property] ? this._props.styleProvider?.(doc, captionProps, property) : undefined;
return childValue ?? this._props.styleProvider?.(this.layoutDoc, captionProps, property);
};
panelHeight = () => this._props.PanelHeight() - (StrCast(this.layoutDoc._layout_showCaption) ? 50 : 0);
@@ -155,7 +164,7 @@ export class CollectionCarouselView extends CollectionSubView() {
captionWidth = () => this._props.PanelWidth() - 2 * this.marginX;
@computed get content() {
const index = NumCast(this.layoutDoc._carousel_index);
- const curDoc = this.childLayoutPairs?.[index];
+ const curDoc = this.carouselItems?.[index];
const captionProps = { ...this._props, NativeScaling: returnOne, PanelWidth: this.captionWidth, fieldKey: 'caption', setHeight: undefined, setContentView: undefined };
const carouselShowsCaptions = StrCast(this.layoutDoc._layout_showCaption);
return !(curDoc?.layout instanceof Doc) ? null : (
@@ -165,7 +174,7 @@ export class CollectionCarouselView extends CollectionSubView() {
{...this._props}
NativeWidth={returnZero}
NativeHeight={returnZero}
- layout_fitWidth={undefined}
+ fitWidth={undefined}
setContentViewBox={undefined}
onDoubleClickScript={this.onContentDoubleClick}
onClickScript={this.onContentClick}
@@ -202,10 +211,10 @@ export class CollectionCarouselView extends CollectionSubView() {
return (
<>
<div key="back" className="carouselView-back" onClick={this.goback}>
- <FontAwesomeIcon icon={'chevron-left'} size={'2x'} />
+ <FontAwesomeIcon icon="chevron-left" size="2x" />
</div>
<div key="fwd" className="carouselView-fwd" onClick={this.advance}>
- <FontAwesomeIcon icon={'chevron-right'} size={'2x'} />
+ <FontAwesomeIcon icon="chevron-right" size="2x" />
</div>
<div key="star" className="carouselView-star" onClick={this.star}>
<FontAwesomeIcon icon={'star'} color={this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)].layout[`${this.fieldKey}_star`] ? 'yellow' : 'gray'} size={'1x'} />
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 8f1633122..73179a266 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -2,59 +2,56 @@ import { action, IReactionDisposer, makeObservable, observable, reaction } from
import { observer } from 'mobx-react';
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
-import * as GoldenLayout from '../../../client/goldenLayout';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, DivWidth, incrementTitleCopy, returnTrue, UpdateIcon } from '../../../ClientUtils';
+import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
import { AclAdmin, AclEdit, DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { ImageCast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
-import { GetEffectiveAcl, inheritParentAcls } from '../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, DivWidth, emptyFunction, incrementTitleCopy } from '../../../Utils';
+import { GetEffectiveAcl, inheritParentAcls, SetPropSetterCb } from '../../../fields/util';
+import { emptyFunction } from '../../../Utils';
import { DocServer } from '../../DocServer';
import { Docs } from '../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
-import { DocumentManager } from '../../util/DocumentManager';
+import * as GoldenLayout from '../../goldenLayout';
import { DragManager } from '../../util/DragManager';
import { InteractionUtils } from '../../util/InteractionUtils';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
-import { SelectionManager } from '../../util/SelectionManager';
-import { SettingsManager } from '../../util/SettingsManager';
+import { SnappingManager } from '../../util/SnappingManager';
import { undoable, undoBatch, UndoManager } from '../../util/UndoManager';
import { DashboardView } from '../DashboardView';
-import { LightboxView } from '../LightboxView';
-import { OpenWhere, OpenWhereMod } from '../nodes/DocumentView';
+import { DocumentView } from '../nodes/DocumentView';
+import { OpenWhere, OpenWhereMod } from '../nodes/OpenWhere';
import { OverlayView } from '../OverlayView';
import { ScriptingRepl } from '../ScriptingRepl';
import { UndoStack } from '../UndoStack';
import './CollectionDockingView.scss';
-import { CollectionFreeFormView } from './collectionFreeForm';
import { CollectionSubView } from './CollectionSubView';
-import { TabDocView } from './TabDocView';
+
const _global = (window /* browser */ || global) /* node */ as any;
@observer
export class CollectionDockingView extends CollectionSubView() {
- @observable public static Instance: CollectionDockingView | undefined = undefined;
- public static makeDocumentConfig(document: Doc, panelName?: string, width?: number, keyValue?: boolean) {
- return {
- type: 'react-component',
- component: 'DocumentFrameRenderer',
- title: document.title,
- width: width,
- props: {
- documentId: document[Id],
- keyValue,
- panelName, // name of tab that can be used to close or replace its contents
- },
- };
+ static tabClass: JSX.Element | null = null;
+ /**
+ * Initialize by assigning the add split method to DocumentView and by
+ * configuring golden layout to render its documents using the specified React component
+ * @param ele - typically would be set to TabDocView
+ */
+ public static Init(ele: any) {
+ this.tabClass = ele;
+ DocumentView.addSplit = CollectionDockingView.AddSplit;
}
+ // eslint-disable-next-line no-use-before-define
+ @observable public static Instance: CollectionDockingView | undefined = undefined;
private _reactionDisposer?: IReactionDisposer;
private _lightboxReactionDisposer?: IReactionDisposer;
private _containerRef = React.createRef<HTMLDivElement>();
- public _flush: UndoManager.Batch | undefined;
+ private _flush: UndoManager.Batch | undefined;
+ private _unmounting = false;
private _ignoreStateChange = '';
public tabMap: Set<any> = new Set();
public get HasFullScreen() {
@@ -67,7 +64,7 @@ export class CollectionDockingView extends CollectionSubView() {
super(props);
makeObservable(this);
if (this._props.renderDepth < 0) CollectionDockingView.Instance = this;
- //Why is this here?
+ // Why is this here?
(window as any).React = React;
(window as any).ReactDOM = ReactDOM;
DragManager.StartWindowDrag = this.StartOtherDrag;
@@ -83,7 +80,7 @@ export class CollectionDockingView extends CollectionSubView() {
*/
public StartOtherDrag = (e: { pageX: number; pageY: number }, dragDocs: Doc[], finishDrag?: (aborted: boolean) => void) => {
this._flush = this._flush ?? UndoManager.StartBatch('golden layout drag');
- const config = dragDocs.length === 1 ? CollectionDockingView.makeDocumentConfig(dragDocs[0]) : { type: 'row', content: dragDocs.map(doc => CollectionDockingView.makeDocumentConfig(doc)) };
+ const config = dragDocs.length === 1 ? DashboardView.makeDocumentConfig(dragDocs[0]) : { type: 'row', content: dragDocs.map(doc => DashboardView.makeDocumentConfig(doc)) };
const dragSource = CollectionDockingView.Instance?._goldenLayout.createDragSource(document.createElement('div'), config);
this.tabDragStart(dragSource, finishDrag);
dragSource._dragListener.onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 });
@@ -117,7 +114,7 @@ export class CollectionDockingView extends CollectionSubView() {
@undoBatch
public static CloseSplit(document: Opt<Doc>, panelName?: string): boolean {
if (CollectionDockingView.Instance) {
- const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tab => (panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document));
+ const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tabView => (panelName ? tabView.contentItem.config.props.panelName === panelName : tabView.DashDoc === document));
if (tab) {
const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
if (j !== -1) {
@@ -132,11 +129,10 @@ export class CollectionDockingView extends CollectionSubView() {
}
@undoBatch
- @action
public static ReplaceTab(document: Doc, mods: OpenWhereMod, stack: any, panelName: string, addToSplit?: boolean, keyValue?: boolean): boolean {
const instance = CollectionDockingView.Instance;
if (!instance) return false;
- const newConfig = CollectionDockingView.makeDocumentConfig(document, panelName, undefined, keyValue);
+ const newConfig = DashboardView.makeDocumentConfig(document, panelName, undefined, keyValue);
if (!panelName && stack) {
const activeContentItemIndex = stack.contentItems.findIndex((item: any) => item.config === stack._activeContentItem.config);
const newContentItem = stack.layoutManager.createContentItem(newConfig, instance._goldenLayout);
@@ -144,7 +140,7 @@ export class CollectionDockingView extends CollectionSubView() {
stack.contentItems[activeContentItemIndex].remove();
return instance.layoutChanged();
}
- const tab = Array.from(instance.tabMap.keys()).find(tab => tab.contentItem.config.props.panelName === panelName);
+ const tab = Array.from(instance.tabMap.keys()).find(tabView => tabView.contentItem.config.props.panelName === panelName);
if (tab) {
const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
if (newConfig.props.documentId !== tab.header.parent.contentItems[j].config.props.documentId) {
@@ -169,7 +165,7 @@ export class CollectionDockingView extends CollectionSubView() {
public static AddSplit(document: Doc, pullSide: OpenWhereMod, stack?: any, panelName?: string, keyValue?: boolean) {
if (document?._type_collection === CollectionViewType.Docking && !keyValue) return DashboardView.openDashboard(document);
if (!CollectionDockingView.Instance) return false;
- const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === document && !tab.contentItem.config.props.keyValue && !keyValue);
+ const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tabView => tabView.DashDoc === document && !tabView.contentItem.config.props.keyValue && !keyValue);
if (tab) {
tab.header.parent.setActiveContentItem(tab.contentItem);
return true;
@@ -177,7 +173,7 @@ export class CollectionDockingView extends CollectionSubView() {
const instance = CollectionDockingView.Instance;
const glayRoot = instance._goldenLayout.root;
if (!instance) return false;
- const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName, undefined, keyValue);
+ const docContentConfig = DashboardView.makeDocumentConfig(document, panelName, undefined, keyValue);
CollectionDockingView.Instance._flush = CollectionDockingView.Instance._flush ?? UndoManager.StartBatch('Add Split');
setTimeout(CollectionDockingView.Instance.endUndoBatch, 100);
@@ -200,6 +196,7 @@ export class CollectionDockingView extends CollectionSubView() {
} else if (instance._goldenLayout.root.contentItems[0].isRow) {
// if row
switch (pullSide) {
+ // eslint-disable-next-line default-case-last
default:
case OpenWhereMod.none:
case OpenWhereMod.right:
@@ -209,7 +206,7 @@ export class CollectionDockingView extends CollectionSubView() {
glayRoot.contentItems[0].addChild(newContentItem(), 0);
break;
case OpenWhereMod.top:
- case OpenWhereMod.bottom:
+ case OpenWhereMod.bottom: {
// if not going in a row layout, must add already existing content into column
const rowlayout = glayRoot.contentItems[0];
const newColumn = rowlayout.layoutManager.createContentItem({ type: 'column' }, instance._goldenLayout);
@@ -228,6 +225,7 @@ export class CollectionDockingView extends CollectionSubView() {
rowlayout.config.height = 50;
newItem.config.height = 50;
+ }
}
} else {
// if (instance._goldenLayout.root.contentItems[0].isColumn) { // if column
@@ -240,7 +238,7 @@ export class CollectionDockingView extends CollectionSubView() {
break;
case 'left':
case 'right':
- default:
+ default: {
// if not going in a row layout, must add already existing content into column
const collayout = glayRoot.contentItems[0];
const newRow = collayout.layoutManager.createContentItem({ type: 'row' }, instance._goldenLayout);
@@ -259,6 +257,7 @@ export class CollectionDockingView extends CollectionSubView() {
collayout.config.width = 50;
newItem.config.width = 50;
+ }
}
}
instance._ignoreStateChange = JSON.stringify(instance._goldenLayout.toConfig());
@@ -277,10 +276,10 @@ export class CollectionDockingView extends CollectionSubView() {
}
setupGoldenLayout = async () => {
if (this._unmounting) return;
- //const config = StrCast(this.Document.dockingConfig, JSON.stringify(DashboardView.resetDashboard(this.Document)));
+ // const config = StrCast(this.Document.dockingConfig, JSON.stringify(DashboardView.resetDashboard(this.Document)));
const config = StrCast(this.Document.dockingConfig);
if (config) {
- const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const matches = config.match(/"documentId":"[a-z0-9-]+"/g);
const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) ?? [];
await Promise.all(docids.map(id => DocServer.GetRefField(id)));
@@ -288,12 +287,13 @@ export class CollectionDockingView extends CollectionSubView() {
if (this._goldenLayout) {
if (config === JSON.stringify(this._goldenLayout.toConfig())) {
return;
- } else {
- try {
- this._goldenLayout.unbind('tabCreated', this.tabCreated);
- this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
- this._goldenLayout.unbind('stackCreated', this.stackCreated);
- } catch (e) {}
+ }
+ try {
+ this._goldenLayout.unbind('tabCreated', this.tabCreated);
+ this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
+ this._goldenLayout.unbind('stackCreated', this.stackCreated);
+ } catch (e) {
+ /* empty */
}
this.tabMap.clear();
this._goldenLayout.destroy();
@@ -302,7 +302,7 @@ export class CollectionDockingView extends CollectionSubView() {
glay.on('tabCreated', this.tabCreated);
glay.on('tabDestroyed', this.tabDestroyed);
glay.on('stackCreated', this.stackCreated);
- glay.registerComponent('DocumentFrameRenderer', TabDocView);
+ glay.registerComponent('DocumentFrameRenderer', CollectionDockingView.tabClass);
glay.container = this._containerRef.current;
glay.init();
glay.root.layoutManager.on('itemDropped', this.tabItemDropped);
@@ -313,12 +313,31 @@ export class CollectionDockingView extends CollectionSubView() {
}
};
+ /**
+ * This publishes Docs having titles starting with '@' to Doc.myPublishedDocs
+ * Once published, any text that uses the 'title' in its body will automatically
+ * be linked to this published document.
+ * @param target
+ * @param title
+ */
+ titleChanged = (target: any, value: any) => {
+ const title = Field.toString(value);
+ if (title.startsWith('@') && !title.substring(1).match(/[()[\]@]/) && title.length > 1) {
+ const embedding = DocListCast(target.proto_embeddings).lastElement();
+ embedding && Doc.AddToMyPublished(embedding);
+ } else if (!title.startsWith('@')) {
+ DocListCast(target.proto_embeddings).forEach(doc => Doc.RemFromMyPublished(doc));
+ }
+ };
+
componentDidMount: () => void = async () => {
+ this._props.setContentViewBox?.(this);
this._unmounting = false;
+ SetPropSetterCb('title', this.titleChanged); // this overrides any previously assigned callback for the property
if (this._containerRef.current) {
this._lightboxReactionDisposer = reaction(
- () => LightboxView.LightboxDoc,
- doc => setTimeout(() => !doc && this.onResize(undefined))
+ () => DocumentView.LightboxDoc(),
+ doc => setTimeout(() => !doc && this.onResize())
);
new _global.ResizeObserver(this.onResize).observe(this._containerRef.current);
this._reactionDisposer = reaction(
@@ -337,25 +356,26 @@ export class CollectionDockingView extends CollectionSubView() {
{ fireImmediately: true }
);
reaction(
- () => [SettingsManager.userBackgroundColor, SettingsManager.userBackgroundColor],
+ () => [SnappingManager.userBackgroundColor, SnappingManager.userBackgroundColor],
() => {
clearStyleSheetRules(CollectionDockingView._highlightStyleSheet);
- addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { background: `${SettingsManager.userBackgroundColor} !important` });
- addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { color: `${SettingsManager.userColor} !important` });
- addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${SettingsManager.userBackgroundColor} !important` });
+ addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { background: `${SnappingManager.userBackgroundColor} !important` });
+ addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { color: `${SnappingManager.userColor} !important` });
+ addStyleSheetRule(SnappingManager.SettingsStyle, 'lm_header', { background: `${SnappingManager.userBackgroundColor} !important` });
},
{ fireImmediately: true }
);
}
};
- _unmounting = false;
componentWillUnmount: () => void = () => {
this._unmounting = true;
try {
this._goldenLayout.unbind('stackCreated', this.stackCreated);
this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
- } catch (e) {}
+ } catch (e) {
+ /* empty */
+ }
this._goldenLayout?.destroy();
window.removeEventListener('resize', this.onResize);
window.removeEventListener('mouseup', this.onPointerUp);
@@ -364,16 +384,19 @@ export class CollectionDockingView extends CollectionSubView() {
this._lightboxReactionDisposer?.();
};
+ // ViewBoxInterface overrides
+ override isUnstyledView = returnTrue;
+
@action
- onResize = (event: any) => {
+ onResize = () => {
const cur = this._containerRef.current;
// bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed
- !LightboxView.LightboxDoc && cur && this._goldenLayout?.updateSize(cur.getBoundingClientRect().width, cur.getBoundingClientRect().height);
+ !DocumentView.LightboxDoc() && cur && this._goldenLayout?.updateSize(cur.getBoundingClientRect().width, cur.getBoundingClientRect().height);
};
endUndoBatch = () => {
const json = JSON.stringify(this._goldenLayout.toConfig());
- const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const matches = json.match(/"documentId":"[a-z0-9-]+"/g);
const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', ''));
const docs = !docids
? []
@@ -396,7 +419,7 @@ export class CollectionDockingView extends CollectionSubView() {
};
@action
- onPointerUp = (e: MouseEvent): void => {
+ onPointerUp = (): void => {
window.removeEventListener('pointerup', this.onPointerUp);
DragManager.CompleteWindowDrag = undefined;
setTimeout(this.endUndoBatch, 100);
@@ -418,8 +441,8 @@ export class CollectionDockingView extends CollectionSubView() {
} else {
const tabTarget = (e.target as HTMLElement)?.parentElement?.className.includes('lm_tab') ? (e.target as HTMLElement).parentElement : (e.target as HTMLElement);
const map = Array.from(this.tabMap).find(tab => tab.element[0] === tabTarget);
- if (map?.DashDoc && DocumentManager.Instance.getFirstDocumentView(map.DashDoc)) {
- SelectionManager.SelectView(DocumentManager.Instance.getFirstDocumentView(map.DashDoc), false);
+ if (map?.DashDoc && DocumentView.getDocumentView(map.DashDoc, this.DocumentView?.())) {
+ DocumentView.SelectView(DocumentView.getDocumentView(map.DashDoc, this.DocumentView?.()), false);
}
}
}
@@ -434,24 +457,27 @@ export class CollectionDockingView extends CollectionSubView() {
if (content) {
const _width = DivWidth(content);
const _height = DivHeight(content);
- return CollectionFreeFormView.UpdateIcon(this.layoutDoc[Id] + '-icon' + new Date().getTime(), content, _width, _height, _width, _height, 0, 1, true, this.layoutDoc[Id] + '-icon', (iconFile, _nativeWidth, _nativeHeight) => {
+ return UpdateIcon(this.layoutDoc[Id] + '-icon' + new Date().getTime(), content, _width, _height, _width, _height, 0, 1, true, this.layoutDoc[Id] + '-icon', iconFile => {
const proto = this.dataDoc; // Cast(img.proto, Doc, null)!;
- proto['thumb_nativeWidth'] = _width;
- proto['thumb_nativeHeight'] = _height;
+ proto.thumb_nativeWidth = _width;
+ proto.thumb_nativeHeight = _height;
proto.thumb = new ImageField(iconFile);
});
}
+ return undefined;
}
public static async TakeSnapshot(doc: Doc | undefined, clone = false) {
if (!doc) return undefined;
let json = StrCast(doc.dockingConfig);
if (clone) {
const cloned = await Doc.MakeClone(doc);
- Array.from(cloned.map.entries()).map(entry => (json = json.replace(entry[0], entry[1][Id])));
+ Array.from(cloned.map.entries()).forEach(entry => {
+ json = json.replace(entry[0], entry[1][Id]);
+ });
cloned.clone[DocData].dockingConfig = json;
return DashboardView.openDashboard(cloned.clone);
}
- const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const matches = json.match(/"documentId":"[a-z0-9-]+"/g);
const origtabids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) || [];
const origtabs = origtabids
.map(id => DocServer.GetCachedRefField(id))
@@ -468,10 +494,15 @@ export class CollectionDockingView extends CollectionSubView() {
json = json.replace(origtab[Id], newtab[Id]);
return newtab;
});
- const copy = Docs.Create.DockDocument(newtabs, json, { title: incrementTitleCopy(StrCast(doc.title)) });
- DashboardView.SetupDashboardTrails(copy);
- DashboardView.SetupDashboardCalendars(copy); // Zaul TODO: needed?
- return DashboardView.openDashboard(copy);
+ const dashboardDoc = Docs.Create.DockDocument(newtabs, json, { title: incrementTitleCopy(StrCast(doc.title)) });
+
+ dashboardDoc.pane_count = 1;
+ dashboardDoc.myOverlayDocs = new List<Doc>();
+ dashboardDoc.myPublishedDocs = new List<Doc>();
+
+ DashboardView.SetupDashboardTrails(dashboardDoc);
+ DashboardView.SetupDashboardCalendars(dashboardDoc); // Zaul TODO: needed?
+ return DashboardView.openDashboard(dashboardDoc);
}
@action
@@ -484,19 +515,20 @@ export class CollectionDockingView extends CollectionSubView() {
tabDestroyed = (tab: any) => {
this._flush = this._flush ?? UndoManager.StartBatch('tab movement');
- if (tab.DashDoc && ![DocumentType.PRES].includes(tab.DashDoc?.type) && !tab.contentItem.config.props.keyValue) {
- Doc.AddDocToList(Doc.MyHeaderBar, 'data', tab.DashDoc, undefined, undefined, true);
+ const dashDoc = tab.DashDoc;
+ if (dashDoc && ![DocumentType.PRES].includes(dashDoc.type) && !tab.contentItem.config.props.keyValue) {
+ Doc.AddDocToList(Doc.MyHeaderBar, 'data', dashDoc, undefined, undefined, true);
// if you close a tab that is not embedded somewhere else (an embedded Doc can be opened simultaneously in a tab), then add the tab to recently closed
- if (tab.DashDoc.embedContainer === this.Document) tab.DashDoc.embedContainer = undefined;
- if (!tab.DashDoc.embedContainer) {
- Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', tab.DashDoc, undefined, true, true);
- Doc.RemoveEmbedding(tab.DashDoc, tab.DashDoc);
+ if (dashDoc.embedContainer === this.Document) dashDoc.embedContainer = undefined;
+ if (!dashDoc.embedContainer) {
+ Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', dashDoc, undefined, true, true);
+ Doc.RemoveEmbedding(dashDoc, dashDoc);
}
}
if (CollectionDockingView.Instance) {
const dview = CollectionDockingView.Instance.Document;
- const fieldKey = CollectionDockingView.Instance.props.fieldKey;
- Doc.RemoveDocFromList(dview, fieldKey, tab.DashDoc);
+ const { fieldKey } = CollectionDockingView.Instance.props;
+ Doc.RemoveDocFromList(dview, fieldKey, dashDoc);
this.tabMap.delete(tab);
tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
this.stateChanged();
@@ -507,18 +539,18 @@ export class CollectionDockingView extends CollectionSubView() {
tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
};
- stackCreated = (stack: any) => {
- stack = stack.header ? stack : stack.origin;
+ stackCreated = (stackIn: any) => {
+ const stack = stackIn.header ? stackIn : stackIn.origin;
stack.header?.element.on('mousedown', (e: any) => {
const dashboard = Doc.ActiveDashboard;
if (dashboard && e.target === stack.header?.element[0] && e.button === 2) {
- dashboard['pane-count'] = NumCast(dashboard['pane-count']) + 1;
+ dashboard.pane_count = NumCast(dashboard.pane_count) + 1;
const docToAdd = Docs.Create.FreeformDocument([], {
_width: this._props.PanelWidth(),
_height: this._props.PanelHeight(),
_freeform_backgroundGrid: true,
_layout_fitWidth: true,
- title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`,
+ title: `Untitled Tab ${NumCast(dashboard.pane_count)}`,
});
Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd, undefined, undefined, true);
inheritParentAcls(this.Document, docToAdd, false);
@@ -526,32 +558,29 @@ export class CollectionDockingView extends CollectionSubView() {
}
});
- let addNewDoc = undoable(
- action(() => {
- const dashboard = Doc.ActiveDashboard;
- if (dashboard) {
- dashboard['pane-count'] = NumCast(dashboard['pane-count']) + 1;
- const docToAdd = Docs.Create.FreeformDocument([], {
- _width: this._props.PanelWidth(),
- _height: this._props.PanelHeight(),
- _layout_fitWidth: true,
- _freeform_backgroundGrid: true,
- title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`,
- });
- Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd, undefined, undefined, true);
- inheritParentAcls(this.dataDoc, docToAdd, false);
- CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack);
- }
- }),
- 'add new tab'
- );
+ const addNewDoc = undoable(() => {
+ const dashboard = Doc.ActiveDashboard;
+ if (dashboard) {
+ dashboard.pane_count = NumCast(dashboard.pane_count) + 1;
+ const docToAdd = Docs.Create.FreeformDocument([], {
+ _width: this._props.PanelWidth(),
+ _height: this._props.PanelHeight(),
+ _layout_fitWidth: true,
+ _freeform_backgroundGrid: true,
+ title: `Untitled Tab ${NumCast(dashboard.pane_count)}`,
+ });
+ Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd, undefined, undefined, true);
+ inheritParentAcls(this.dataDoc, docToAdd, false);
+ CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack);
+ }
+ }, 'add new tab');
stack.header?.controlsContainer
- .find('.lm_close') //get the close icon
- .off('click') //unbind the current click handler
+ .find('.lm_close') // get the close icon
+ .off('click') // unbind the current click handler
.click(
action(() => {
- //if (confirm('really close this?')) {
+ // if (confirm('really close this?')) {
if ((!stack.parent.isRoot && !stack.parent.parent.isRoot) || stack.parent.contentItems.length > 1) {
const batch = UndoManager.StartBatch('close stack');
stack.remove();
@@ -571,11 +600,11 @@ export class CollectionDockingView extends CollectionSubView() {
}
});
stack.header?.controlsContainer
- .find('.lm_maximise') //get the close icon
+ .find('.lm_maximise') // get the close icon
.click(() => setTimeout(this.stateChanged));
stack.header?.controlsContainer
- .find('.lm_popout') //get the popout icon
- .off('click') //unbind the current click handler
+ .find('.lm_popout') // get the popout icon
+ .off('click') // unbind the current click handler
.click(addNewDoc);
};
@@ -585,13 +614,14 @@ export class CollectionDockingView extends CollectionSubView() {
<div>
{href ? (
<img
+ alt="thumbnail of nested dashboard"
style={{ background: 'white', top: 0, position: 'absolute' }}
src={href} // + '?d=' + (new Date()).getTime()}
width={this._props.PanelWidth()}
height={this._props.PanelHeight()}
/>
) : (
- <p>nested dashboards has no thumbnail</p>
+ <p>nested dashboard has no thumbnail</p>
)}
</div>
) : (
@@ -601,33 +631,45 @@ export class CollectionDockingView extends CollectionSubView() {
}
ScriptingGlobals.add(
+ // eslint-disable-next-line prefer-arrow-callback
function openInLightbox(doc: any) {
- LightboxView.Instance.AddDocTab(doc, OpenWhere.lightbox);
+ CollectionDockingView.Instance?._props.addDocTab(doc, OpenWhere.lightboxAlways);
},
'opens up document in a lightbox',
'(doc: any)'
);
ScriptingGlobals.add(
+ // eslint-disable-next-line prefer-arrow-callback
function openDoc(doc: any, where: OpenWhere) {
switch (where) {
case OpenWhere.addRight:
return CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
case OpenWhere.overlay:
+ default:
// prettier-ignore
switch (doc) {
case '<ScriptingRepl />': return OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: 'Scripting REPL' });
case "<UndoStack />": return OverlayView.Instance.addWindow(<UndoStack />, { x: 300, y: 100, width: 200, height: 200, title: 'Undo stack' });
+ default:
}
Doc.AddToMyOverlay(doc);
+ return true;
}
},
'opens up document in location specified',
'(doc: any)'
);
ScriptingGlobals.add(
+ // eslint-disable-next-line prefer-arrow-callback
function openRepl() {
return 'openRepl';
},
'opens up document in screen overlay layer',
'(doc: any)'
);
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(async function snapshotDashboard() {
+ const batch = UndoManager.StartBatch('snapshot');
+ await CollectionDockingView.TakeSnapshot(Doc.ActiveDashboard);
+ batch.end();
+}, 'creates a snapshot copy of a dashboard');
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 763d2e3a6..9a6f1e2eb 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -1,9 +1,13 @@
+/* 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 { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, numberRange, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../Utils';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction, numberRange } from '../../../Utils';
+import { Doc } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { ScriptField } from '../../../fields/ScriptField';
@@ -51,13 +55,19 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
@observable private collapsed: boolean = false;
@observable private _paletteOn = false;
private set _heading(value: string) {
- runInAction(() => this._props.headingObject && (this._props.headingObject.heading = this.heading = value));
+ runInAction(() => {
+ this._props.headingObject && (this._props.headingObject.heading = this.heading = value);
+ });
}
private set _color(value: string) {
- runInAction(() => this._props.headingObject && (this._props.headingObject.color = this.color = value));
+ runInAction(() => {
+ this._props.headingObject && (this._props.headingObject.color = this.color = value);
+ });
}
private set _collapsed(value: boolean) {
- runInAction(() => this._props.headingObject && (this._props.headingObject.collapsed = this.collapsed = value));
+ runInAction(() => {
+ this._props.headingObject && (this._props.headingObject.collapsed = this.collapsed = value);
+ });
}
private _dropDisposer?: DragManager.DragDropDisposer;
@@ -87,7 +97,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
if (this.collapsed) {
this._props.setDocHeight(this.heading, 20);
} else {
- const rawHeight = this._contRef.current!.getBoundingClientRect().height + 15; //+ 15 accounts for the group header
+ const rawHeight = this._contRef.current!.getBoundingClientRect().height + 15; // +15 accounts for the group header
const transformScale = this._props.screenToLocalTransform().Scale;
const trueHeight = rawHeight * transformScale;
this._props.setDocHeight(this.heading, trueHeight);
@@ -100,9 +110,8 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
if (de.complete.docDragData) {
const key = this._props.pivotField;
const castedValue = this.getValue(this.heading);
- const onLayoutDoc = this.onLayoutDoc(key);
if (this._props.parent.onInternalDrop(e, de)) {
- de.complete.docDragData.droppedDocuments.forEach(d => Doc.SetInPlace(d, key, castedValue, !onLayoutDoc));
+ key && de.complete.docDragData.droppedDocuments.forEach(d => Doc.SetInPlace(d, key, castedValue, true));
}
return true;
}
@@ -118,7 +127,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
};
@action
- headingChanged = (value: string, shiftDown?: boolean) => {
+ headingChanged = (value: string /* , shiftDown?: boolean */) => {
this._createEmbeddingSelected = false;
const key = this._props.pivotField;
const castedValue = this.getValue(value);
@@ -128,7 +137,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
return false;
}
}
- this._props.docList.forEach(d => Doc.SetInPlace(d, key, castedValue, true));
+ key && this._props.docList.forEach(d => Doc.SetInPlace(d, key, castedValue, true));
this._heading = castedValue.toString();
return true;
}
@@ -141,7 +150,9 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
this._color = color;
};
- pointerEnteredRow = action(() => SnappingManager.IsDragging && (this._background = '#b4b4b4'));
+ pointerEnteredRow = action(() => {
+ SnappingManager.IsDragging && (this._background = '#b4b4b4');
+ });
@action
pointerLeaveRow = () => {
@@ -153,21 +164,20 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
addDocument = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
if (!value && !forceEmptyNote) return false;
this._createEmbeddingSelected = false;
- const key = this._props.pivotField;
+ const { pivotField } = this._props;
const newDoc = Docs.Create.TextDocument('', { _layout_autoHeight: true, _width: 200, _layout_fitWidth: true, title: value });
- const onLayoutDoc = this.onLayoutDoc(key);
- FormattedTextBox.SetSelectOnLoad(newDoc);
+ Doc.SetSelectOnLoad(newDoc);
FormattedTextBox.SelectOnLoadChar = value;
- (onLayoutDoc ? newDoc : newDoc[DocData])[key] = this.getValue(this._props.heading);
+ pivotField && (newDoc[DocData][pivotField] = this.getValue(this._props.heading));
const docs = this._props.parent.childDocList;
- return docs ? (docs.splice(0, 0, newDoc) ? true : false) : this._props.parent._props.addDocument?.(newDoc) || false; // should really extend addDocument to specify insertion point (at beginning of list)
+ return docs ? !!docs.splice(0, 0, newDoc) : this._props.parent._props.addDocument?.(newDoc) || false; // should really extend addDocument to specify insertion point (at beginning of list)
};
deleteRow = undoBatch(
action(() => {
this._createEmbeddingSelected = false;
const key = this._props.pivotField;
- this._props.docList.forEach(d => Doc.SetInPlace(d, key, undefined, true));
+ key && this._props.docList.forEach(d => Doc.SetInPlace(d, key, undefined, true));
if (this._props.parent.colHeaderData && this._props.headingObject) {
const index = this._props.parent.colHeaderData.indexOf(this._props.headingObject);
this._props.parent.colHeaderData.splice(index, 1);
@@ -199,21 +209,11 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
@action
headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
if (e.button === 0 && !e.ctrlKey) {
- setupMoveUpEvents(this, e, this.headerMove, emptyFunction, e => !this._props.chromeHidden && this.collapseSection(e));
+ setupMoveUpEvents(this, e, this.headerMove, emptyFunction, clickEv => !this._props.chromeHidden && this.collapseSection(clickEv));
this._createEmbeddingSelected = false;
}
};
- /**
- * Returns true if a key is on the layout doc of the documents in the collection.
- */
- onLayoutDoc = (key: string): boolean => {
- DocListCast(this._props.parent.Document.data).forEach(doc => {
- if (Doc.Get(doc, key, true)) return true;
- });
- return false;
- };
-
renderColorPicker = () => {
const selected = this.color;
@@ -230,27 +230,29 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
return (
<div className="collectionStackingView-colorPicker">
<div className="colorOptions">
- <div className={'colorPicker' + (selected === pink ? ' active' : '')} style={{ backgroundColor: pink }} onClick={() => this.changeColumnColor(pink!)}></div>
- <div className={'colorPicker' + (selected === purple ? ' active' : '')} style={{ backgroundColor: purple }} onClick={() => this.changeColumnColor(purple!)}></div>
- <div className={'colorPicker' + (selected === blue ? ' active' : '')} style={{ backgroundColor: blue }} onClick={() => this.changeColumnColor(blue!)}></div>
- <div className={'colorPicker' + (selected === yellow ? ' active' : '')} style={{ backgroundColor: yellow }} onClick={() => this.changeColumnColor(yellow!)}></div>
- <div className={'colorPicker' + (selected === red ? ' active' : '')} style={{ backgroundColor: red }} onClick={() => this.changeColumnColor(red!)}></div>
- <div className={'colorPicker' + (selected === gray ? ' active' : '')} style={{ backgroundColor: gray }} onClick={() => this.changeColumnColor(gray)}></div>
- <div className={'colorPicker' + (selected === green ? ' active' : '')} style={{ backgroundColor: green }} onClick={() => this.changeColumnColor(green!)}></div>
- <div className={'colorPicker' + (selected === cyan ? ' active' : '')} style={{ backgroundColor: cyan }} onClick={() => this.changeColumnColor(cyan!)}></div>
- <div className={'colorPicker' + (selected === orange ? ' active' : '')} style={{ backgroundColor: orange }} onClick={() => this.changeColumnColor(orange!)}></div>
+ <div className={'colorPicker' + (selected === pink ? ' active' : '')} style={{ backgroundColor: pink }} onClick={() => this.changeColumnColor(pink!)} />
+ <div className={'colorPicker' + (selected === purple ? ' active' : '')} style={{ backgroundColor: purple }} onClick={() => this.changeColumnColor(purple!)} />
+ <div className={'colorPicker' + (selected === blue ? ' active' : '')} style={{ backgroundColor: blue }} onClick={() => this.changeColumnColor(blue!)} />
+ <div className={'colorPicker' + (selected === yellow ? ' active' : '')} style={{ backgroundColor: yellow }} onClick={() => this.changeColumnColor(yellow!)} />
+ <div className={'colorPicker' + (selected === red ? ' active' : '')} style={{ backgroundColor: red }} onClick={() => this.changeColumnColor(red!)} />
+ <div className={'colorPicker' + (selected === gray ? ' active' : '')} style={{ backgroundColor: gray }} onClick={() => this.changeColumnColor(gray)} />
+ <div className={'colorPicker' + (selected === green ? ' active' : '')} style={{ backgroundColor: green }} onClick={() => this.changeColumnColor(green!)} />
+ <div className={'colorPicker' + (selected === cyan ? ' active' : '')} style={{ backgroundColor: cyan }} onClick={() => this.changeColumnColor(cyan!)} />
+ <div className={'colorPicker' + (selected === orange ? ' active' : '')} style={{ backgroundColor: orange }} onClick={() => this.changeColumnColor(orange!)} />
</div>
</div>
);
};
- toggleEmbedding = action(() => (this._createEmbeddingSelected = true));
- toggleVisibility = () => (this._collapsed = !this.collapsed);
+ toggleEmbedding = action(() => {
+ this._createEmbeddingSelected = true;
+ });
+ toggleVisibility = () => {
+ this._collapsed = !this.collapsed;
+ };
@action
- textCallback = (char: string) => {
- return this.addDocument('', false);
- };
+ textCallback = (/* char: string */) => this.addDocument('', false);
@computed get contentLayout() {
const rows = Math.max(1, Math.min(this._props.docList.length, Math.floor((this._props.parent._props.PanelWidth() - 2 * this._props.parent.xMargin) / (this._props.parent.columnWidth + this._props.parent.gridGap))));
@@ -264,22 +266,22 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
className="collectionStackingView-addDocumentButton"
style={
{
- //width: style.columnWidth / style.numGroupColumns,
- //padding: `${NumCast(this._props.parent.layoutDoc._yPadding, this._props.parent.yMargin)}px 0px 0px 0px`,
+ // width: style.columnWidth / style.numGroupColumns,
+ // padding: `${NumCast(this._props.parent.layoutDoc._yPadding, this._props.parent.yMargin)}px 0px 0px 0px`,
}
}>
- <EditableView GetValue={returnEmptyString} SetValue={this.addDocument} textCallback={this.textCallback} contents={'+ NEW'} />
+ <EditableView GetValue={returnEmptyString} SetValue={this.addDocument} textCallback={this.textCallback} contents="+ NEW" />
</div>
) : null}
<div
- className={`collectionStackingView-masonryGrid`}
+ className="collectionStackingView-masonryGrid"
ref={this._contRef}
style={{
padding: stackPad,
minHeight: this._props.showHandle && this._props.parent._props.isContentActive() ? '10px' : undefined,
width: this._props.parent.NodeWidth,
gridGap: this._props.parent.gridGap,
- gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this._props.parent.columnWidth}px`, ''),
+ gridTemplateColumns: numberRange(rows).reduce(list => list + ` ${this._props.parent.columnWidth}px`, ''),
}}>
{this._props.parent.children(this._props.docList)}
</div>
@@ -291,7 +293,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
const noChrome = this._props.chromeHidden;
const key = this._props.pivotField;
const evContents = this.heading ? this.heading : this._props.type && this._props.type === 'number' ? '0' : `NO ${key.toUpperCase()} VALUE`;
- const editableHeaderView = <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine={true} />;
+ const editableHeaderView = <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine />;
return this._props.Document.miniHeaders ? (
<div className="collectionStackingView-miniHeader">{editableHeaderView}</div>
) : !this._props.headingObject ? null : (
@@ -305,6 +307,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
{noChrome || evContents === `NO ${key.toUpperCase()} VALUE` ? null : (
<div className="collectionStackingView-sectionColor">
<button
+ type="button"
className="collectionStackingView-sectionColorButton"
onPointerDown={e =>
setupMoveUpEvents(
@@ -312,7 +315,9 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
e,
returnFalse,
emptyFunction,
- action(e => (this._paletteOn = !this._paletteOn))
+ action(() => {
+ this._paletteOn = !this._paletteOn;
+ })
)
}>
<FontAwesomeIcon icon="palette" size="lg" />
@@ -321,13 +326,13 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
</div>
)}
{noChrome ? null : (
- <button className="collectionStackingView-sectionDelete" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, noChrome ? emptyFunction : this.collapseSection)}>
+ <button type="button" className="collectionStackingView-sectionDelete" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, noChrome ? emptyFunction : this.collapseSection)}>
<FontAwesomeIcon icon={this.collapsed ? 'chevron-down' : 'chevron-up'} size="lg" />
</button>
)}
{noChrome || evContents === `NO ${key.toUpperCase()} VALUE` ? null : (
<div className="collectionStackingView-sectionOptions" onPointerDown={e => e.stopPropagation()}>
- <button className="collectionStackingView-sectionOptionButton" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.deleteRow)}>
+ <button type="button" className="collectionStackingView-sectionOptionButton" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.deleteRow)}>
<FontAwesomeIcon icon="trash" size="lg" />
</button>
</div>
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 5d46649b2..3ec875df4 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -10,7 +10,7 @@
border-bottom: $standard-border;
padding: 0 10px;
align-items: center;
- overflow-x: scroll;
+ overflow-x: auto;
&::-webkit-scrollbar {
display: none;
}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 8729ef549..3eb3008c4 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,39 +1,47 @@
-import * as React from 'react';
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* 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 */
+/* eslint-disable react/no-unused-class-component-methods */
+/* eslint-disable react/sort-comp */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { Toggle, ToggleType, Type } from 'browndash-components';
-import { action, computed, Lambda, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { Lambda, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
+import * as React from 'react';
+import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { RichTextField } from '../../../fields/RichTextField';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
-import { DragManager, dropActionType } from '../../util/DragManager';
-import { SelectionManager } from '../../util/SelectionManager';
-import { SettingsManager } from '../../util/SettingsManager';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
+import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
import { AntimodeMenu } from '../AntimodeMenu';
import { EditableView } from '../EditableView';
-import { MainView } from '../MainView';
-import { DocumentView, DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
-import { DefaultStyleProvider } from '../StyleProvider';
-import { CollectionLinearView } from './collectionLinear';
+import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider';
+import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
import './CollectionMenu.scss';
-import { DocData } from '../../../fields/DocSymbols';
+import { CollectionLinearView } from './collectionLinear';
interface CollectionMenuProps {
panelHeight: () => number;
panelWidth: () => number;
toggleTopBar: () => void;
topBarHeight: () => number;
+ togglePropertiesFlyout: () => void;
}
@observer
export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
+ // eslint-disable-next-line no-use-before-define
@observable static Instance: CollectionMenu;
@observable SelectedCollection: DocumentView | undefined = undefined;
@@ -44,13 +52,13 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
makeObservable(this);
CollectionMenu.Instance = this;
this._canFade = false; // don't let the inking menu fade away
- this.Pinned = Cast(Doc.UserDoc()['menuCollections-pinned'], 'boolean', true);
+ this.Pinned = Cast(Doc.UserDoc().menuCollections_pinned, 'boolean', true);
this.jumpTo(300, 300);
}
componentDidMount() {
reaction(
- () => SelectionManager.Views.lastElement(),
+ () => DocumentView.Selected().lastElement(),
view => view && this.SetSelection(view)
);
}
@@ -61,25 +69,16 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
}
@action
- toggleMenuPin = (e: React.MouseEvent) => {
- Doc.UserDoc()['menuCollections-pinned'] = this.Pinned = !this.Pinned;
+ toggleMenuPin = () => {
+ Doc.UserDoc().menuCollections_pinned = this.Pinned = !this.Pinned;
if (!this.Pinned && this._left < 0) {
this.jumpTo(300, 300);
}
};
- @action
- toggleProperties = () => {
- if (MainView.Instance.propertiesWidth() > 0) {
- SettingsManager.Instance.propertiesWidth = 0;
- } else {
- SettingsManager.Instance.propertiesWidth = 300;
- }
- };
-
buttonBarXf = () => {
if (!this._docBtnRef.current) return Transform.Identity();
- const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
+ const { scale, translateX, translateY } = ClientUtils.GetScreenTransform(this._docBtnRef.current);
return new Transform(-translateX, -translateY, 1 / scale);
};
@@ -119,15 +118,15 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
render() {
const headerIcon = this.props.topBarHeight() > 0 ? 'angle-double-up' : 'angle-double-down';
const headerTitle = this.props.topBarHeight() > 0 ? 'Close Header Bar' : 'Open Header Bar';
- const propIcon = SettingsManager.Instance.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left';
- const propTitle = SettingsManager.Instance.propertiesWidth > 0 ? 'Close Properties' : 'Open Properties';
+ const propIcon = SnappingManager.PropertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left';
+ const propTitle = SnappingManager.PropertiesWidth > 0 ? 'Close Properties' : 'Open Properties';
const hardCodedButtons = (
- <div className={`hardCodedButtons`}>
+ <div className="hardCodedButtons">
<Toggle
toggleType={ToggleType.BUTTON}
type={Type.PRIM}
- color={SettingsManager.userColor}
+ color={SnappingManager.userColor}
onClick={this.props.toggleTopBar}
toggleStatus={this.props.topBarHeight() > 0}
icon={<FontAwesomeIcon icon={headerIcon} size="lg" />}
@@ -136,21 +135,21 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
<Toggle
toggleType={ToggleType.BUTTON}
type={Type.PRIM}
- color={SettingsManager.userColor}
- onClick={this.toggleProperties}
- toggleStatus={SettingsManager.Instance.propertiesWidth > 0}
+ color={SnappingManager.userColor}
+ onClick={this._props.togglePropertiesFlyout}
+ toggleStatus={SnappingManager.PropertiesWidth > 0}
icon={<FontAwesomeIcon icon={propIcon} size="lg" />}
tooltip={propTitle}
/>
</div>
);
- //dash col linear view buttons
+ // dash col linear view buttons
const contMenuButtons = (
<div
className="collectionMenu-container"
style={{
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
// borderColor: SettingsManager.userColor
}}>
{this.contMenuButtons}
@@ -163,7 +162,9 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
}
interface CollectionViewMenuProps {
+ // eslint-disable-next-line react/no-unused-prop-types
type: CollectionViewType;
+ // eslint-disable-next-line react/no-unused-prop-types
fieldKey: string;
docView: DocumentView;
}
@@ -172,7 +173,7 @@ const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
@observer
export class CollectionViewBaseChrome extends React.Component<CollectionViewMenuProps> {
- //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\)
+ // (!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\)
get document() {
return this.props.docView?.Document;
@@ -206,14 +207,18 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
params: ['target', 'source'],
title: 'child click view',
script: 'this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])',
- immediate: undoBatch((source: Doc[]) => source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]))),
+ immediate: undoBatch((source: Doc[]) => {
+ source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]));
+ }),
initialize: emptyFunction,
};
_contentCommand = {
params: ['target', 'source'],
title: 'set content',
script: 'getProto(this.target).data = copyField(this.source);',
- immediate: undoBatch((source: Doc[]) => (this.target[DocData].data = new List<Doc>(source))),
+ immediate: undoBatch((source: Doc[]) => {
+ this.target[DocData].data = new List<Doc>(source);
+ }),
initialize: emptyFunction,
};
_onClickCommand = {
@@ -224,14 +229,14 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
getProto(this.proxy[0]).target = this.target.target;
getProto(this.proxy[0]).source = copyField(this.target.source);
}}`,
- immediate: undoBatch((source: Doc[]) => {}),
+ immediate: undoBatch(() => {}),
initialize: emptyFunction,
};
_viewCommand = {
params: ['target'],
title: 'bookmark view',
- script: "this.target._freeform_panX = self['target-freeform_panX']; this.target._freeform_panY = this['target-freeform_panY']; this.target._freeform_scale = this['target_freeform_scale']; gotoFrame(this.target, this['target-currentFrame']);",
- immediate: undoBatch((source: Doc[]) => {
+ script: "this.target._freeform_panX = this.target_freeform_panX; this.target._freeform_panY = this['target-freeform_panY']; this.target._freeform_scale = this['target_freeform_scale']; gotoFrame(this.target, this['target-currentFrame']);",
+ immediate: undoBatch(() => {
this.target._freeform_panX = 0;
this.target._freeform_panY = 0;
this.target._freeform_scale = 1;
@@ -248,30 +253,34 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
params: ['target'],
title: 'fit content',
script: 'this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox;',
- immediate: undoBatch((source: Doc[]) => (this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox)),
+ immediate: undoBatch(() => {
+ this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox;
+ }),
initialize: emptyFunction,
};
_fitContentCommand = {
params: ['target'],
title: 'toggle clusters',
script: 'this.target._freeform_useClusters = !this.target._freeform_useClusters;',
- immediate: undoBatch((source: Doc[]) => (this.target._freeform_useClusters = !this.target._freeform_useClusters)),
+ immediate: undoBatch(() => {
+ this.target._freeform_useClusters = !this.target._freeform_useClusters;
+ }),
initialize: emptyFunction,
};
_saveFilterCommand = {
params: ['target'],
title: 'save filter',
- script: `this.target._childFilters = compareLists(this['target-childFilters'],this.target._childFilters) ? undefined : copyField(this['target-childFilters']);
- this.target._searchFilterDocs = compareLists(this['target-searchFilterDocs'],this.target._searchFilterDocs) ? undefined: copyField(this['target-searchFilterDocs']);`,
- immediate: undoBatch((source: Doc[]) => {
+ script: `this.target._childFilters = compareLists(this.target_childFilters,this.target._childFilters) ? undefined : copyField(this.target_childFilters);
+ this.target._searchFilterDocs = compareLists(this.target_searchFilterDocs,this.target._searchFilterDocs) ? undefined: copyField(this.target_searchFilterDocs);`,
+ immediate: undoBatch(() => {
this.target._childFilters = undefined;
this.target._searchFilterDocs = undefined;
}),
initialize: (button: Doc) => {
const activeDash = Doc.ActiveDashboard;
if (activeDash) {
- button['target-childFilters'] = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as any as ObjectField) : undefined;
- button['target-searchFilterDocs'] = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs as any as ObjectField) : undefined;
+ button.target_childFilters = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as any as ObjectField) : undefined;
+ button.target_searchFilterDocs = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs as any as ObjectField) : undefined;
}
},
};
@@ -299,8 +308,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
}
private get _buttonizableCommands() {
switch (this.props.type) {
- default:
- return this._doc_commands;
case CollectionViewType.Freeform:
return this._freeform_commands;
case CollectionViewType.Tree:
@@ -319,6 +326,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
return this._freeform_commands;
case CollectionViewType.Carousel3D:
return this._freeform_commands;
+ default:
+ return this._doc_commands;
}
}
private _commandRef = React.createRef<HTMLInputElement>();
@@ -332,13 +341,13 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
@undoBatch
viewChanged = (e: React.ChangeEvent) => {
const target = this.document !== Doc.MyLeftSidebarPanel ? this.document : DocCast(this.document.proto);
- //@ts-ignore
- target._type_collection = e.target.selectedOptions[0].value;
+ target._type_collection = (e.target as any).selectedOptions[0].value;
};
commandChanged = (e: React.ChangeEvent) => {
- //@ts-ignore
- runInAction(() => (this._currentKey = e.target.selectedOptions[0].value));
+ runInAction(() => {
+ this._currentKey = (e.target as any).selectedOptions[0].value;
+ });
};
@action closeViewSpecs = () => {
@@ -356,7 +365,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
@undoBatch
@action
protected drop(e: Event, de: DragManager.DropEvent): boolean {
- const docDragData = de.complete.docDragData;
+ const { docDragData } = de.complete;
if (docDragData?.draggedDocuments.length) {
this._buttonizableCommands?.filter(c => c.title === this._currentKey).map(c => c.immediate(docDragData.draggedDocuments || []));
e.stopPropagation();
@@ -369,16 +378,18 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
setupMoveUpEvents(
this,
e,
- (e, down, delta) => {
+ moveEv => {
const vtype = this.props.type;
const c = {
params: ['target'],
title: vtype,
script: `this.target._type_collection = '${StrCast(this.props.type)}'`,
- immediate: (source: Doc[]) => (this.document._type_collection = Doc.getDocTemplate(source?.[0])),
+ immediate: (source: Doc[]) => {
+ this.document._type_collection = Doc.getDocTemplate(source?.[0]);
+ },
initialize: emptyFunction,
};
- DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title), { target: this.document }, c.params, c.initialize, e.clientX, e.clientY);
+ DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title), { target: this.document }, c.params, c.initialize, moveEv.clientX, moveEv.clientY);
return true;
},
emptyFunction,
@@ -389,8 +400,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
setupMoveUpEvents(
this,
e,
- (e, down, delta) => {
- this._buttonizableCommands?.filter(c => c.title === this._currentKey).map(c => DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, { target: this.document }, c.params, c.initialize, e.clientX, e.clientY));
+ moveEv => {
+ this._buttonizableCommands
+ ?.filter(c => c.title === this._currentKey)
+ .map(c => DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, { target: this.document }, c.params, c.initialize, moveEv.clientX, moveEv.clientY));
return true;
},
emptyFunction,
@@ -405,11 +418,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
<div className="collectionViewBaseChrome-template" ref={this.createDropTarget}>
<Tooltip title={<div className="dash-tooltip">drop document to apply or drag to create button</div>} placement="bottom">
<div className="commandEntry-outerDiv" ref={this._commandRef} onPointerDown={this.dragCommandDown}>
- <button className={'antimodeMenu-button'}>
+ <button type="button" className="antimodeMenu-button">
<FontAwesomeIcon icon="bullseye" size="lg" />
</button>
<select className="collectionViewBaseChrome-cmdPicker" onPointerDown={stopPropagation} onChange={this.commandChanged} value={this._currentKey}>
- <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={'empty'} value={''} />
+ <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key="empty" value="" />
{this._buttonizableCommands?.map(cmd => (
<option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={cmd.title} value={cmd.title}>
{cmd.title}
@@ -456,23 +469,19 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
if (docs instanceof Doc) {
const keys = Object.keys(docs).filter(key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('author_date') >= 0 || key.indexOf('modificationDate') >= 0 || (key[0].toUpperCase() === key[0] && key[0] !== '_'));
return keys.filter(key => key.toLowerCase().indexOf(val) > -1);
- } else {
- const keys = new Set<string>();
- docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
- const noviceKeys = Array.from(keys).filter(
- key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('author_date') >= 0 || key.indexOf('modificationDate') >= 0 || (key[0]?.toUpperCase() === key[0] && key[0] !== '_')
- );
- return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1);
}
+ const keys = new Set<string>();
+ docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
+ const noviceKeys = Array.from(keys).filter(key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('author_date') >= 0 || key.indexOf('modificationDate') >= 0 || (key[0]?.toUpperCase() === key[0] && key[0] !== '_'));
+ return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1);
}
if (docs instanceof Doc) {
return Object.keys(docs).filter(key => key.toLowerCase().indexOf(val) > -1);
- } else {
- const keys = new Set<string>();
- docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
- return Array.from(keys).filter(key => key.toLowerCase().indexOf(val) > -1);
}
+ const keys = new Set<string>();
+ docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
+ return Array.from(keys).filter(key => key.toLowerCase().indexOf(val) > -1);
};
@action
@@ -482,9 +491,7 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
getSuggestionValue = (suggestion: string) => suggestion;
- renderSuggestion = (suggestion: string) => {
- return <p>{suggestion}</p>;
- };
+ renderSuggestion = (suggestion: string) => <p>{suggestion}</p>;
onSuggestionFetch = async ({ value }: { value: string }) => {
const sugg = await this.getKeySuggestions(value);
@@ -572,12 +579,16 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
}
componentDidMount() {
- runInAction(() => (this.resize = this.props.docView.props.PanelWidth() < 700));
+ runInAction(() => {
+ this.resize = this.props.docView.props.PanelWidth() < 700;
+ });
// listener to reduce text on chrome resize (panel resize)
this.resizeListenerDisposer = reaction(
() => this.panelWidth,
- newValue => (this.resize = newValue < 700)
+ newValue => {
+ this.resize = newValue < 700;
+ }
);
}
@@ -593,7 +604,10 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
* Sets the value of `numCols` on the grid's Document to the value entered.
*/
onNumColsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
- if (e.currentTarget.valueAsNumber > 0) undoBatch(() => (this.document.gridNumCols = e.currentTarget.valueAsNumber))();
+ if (e.currentTarget.valueAsNumber > 0)
+ undoBatch(() => {
+ this.document.gridNumCols = e.currentTarget.valueAsNumber;
+ })();
};
/**
@@ -622,7 +636,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
onIncrementButtonClick = () => {
this.clicked = true;
this.entered && (this.document.gridNumCols as number)--;
- undoBatch(() => (this.document.gridNumCols = this.numCols + 1))();
+ undoBatch(() => {
+ this.document.gridNumCols = this.numCols + 1;
+ })();
this.entered = false;
};
@@ -633,7 +649,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
this.clicked = true;
if (this.numCols > 1 && !this.decrementLimitReached) {
this.entered && (this.document.gridNumCols as number)++;
- undoBatch(() => (this.document.gridNumCols = this.numCols - 1))();
+ undoBatch(() => {
+ this.document.gridNumCols = this.numCols - 1;
+ })();
if (this.numCols === 1) this.decrementLimitReached = true;
}
this.entered = false;
@@ -726,7 +744,13 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
<label className="flexLabel">{this.resize ? 'Flex' : 'Flexible'}</label>
</span>
- <button onClick={() => (this.document.gridResetLayout = true)}>{!this.resize ? 'Reset' : <FontAwesomeIcon icon="redo-alt" size="1x" />}</button>
+ <button
+ type="button"
+ onClick={() => {
+ this.document.gridResetLayout = true;
+ }}>
+ {!this.resize ? 'Reset' : <FontAwesomeIcon icon="redo-alt" size="1x" />}
+ </button>
</div>
);
}
diff --git a/src/client/views/collections/CollectionNoteTakingView.scss b/src/client/views/collections/CollectionNoteTakingView.scss
index 4c2dcf9ab..95fda7b0a 100644
--- a/src/client/views/collections/CollectionNoteTakingView.scss
+++ b/src/client/views/collections/CollectionNoteTakingView.scss
@@ -1,7 +1,7 @@
@import '../global/globalCssVariables.module.scss';
.collectionNoteTakingView-DocumentButtons {
- display: none;
+ opacity: 0;
justify-content: space-between;
margin: auto;
}
@@ -15,7 +15,6 @@
.editableView-container-editing-oneLine,
.editableView-container-editing {
- color: grey;
padding: 10px;
width: 100%;
}
@@ -29,7 +28,6 @@
.editableView-input {
outline-color: black;
letter-spacing: 2px;
- color: grey;
border: 0px;
padding: 12px 10px 11px 10px;
}
@@ -41,7 +39,6 @@
.editableView-input {
outline-color: black;
letter-spacing: 2px;
- color: grey;
border: 0px;
padding: 12px 10px 11px 10px;
}
@@ -51,9 +48,9 @@
display: flex;
}
-.collectionNoteTakingViewFieldColumn:hover {
+.collectionNoteTakingViewFieldColumnHover:hover {
.collectionNoteTakingView-DocumentButtons {
- display: flex;
+ opacity: 1;
}
}
@@ -100,6 +97,9 @@
flex-direction: column;
height: max-content;
}
+ .collectionNoteTakingViewFieldColumnHover {
+ min-height: 100%; // if we use this, then we can't have autoHeight
+ }
.collectionSchemaView-previewDoc {
height: 100%;
@@ -250,7 +250,6 @@
overflow: visible;
width: 100%;
display: flex;
- color: gray;
align-items: center;
}
}
@@ -262,10 +261,6 @@
background: $medium-gray;
// overflow: hidden; overflow is visible so the color menu isn't hidden -ftong
- .editableView-input {
- color: $dark-gray;
- }
-
.editableView-input:hover,
.editableView-container-editing:hover,
.editableView-container-editing-oneLine:hover {
@@ -288,7 +283,6 @@
.editableView-container-editing-oneLine,
.editableView-container-editing {
- color: grey;
padding: 10px;
}
@@ -301,7 +295,6 @@
.editableView-input {
padding: 12px 10px 11px 10px;
border: 0px;
- color: grey;
text-align: center;
letter-spacing: 2px;
outline-color: black;
@@ -409,7 +402,6 @@
.editableView-container-editing-oneLine,
.editableView-container-editing {
- color: grey;
padding: 10px;
width: 100%;
}
@@ -423,13 +415,16 @@
.editableView-input {
outline-color: black;
letter-spacing: 2px;
- color: grey;
border: 0px;
padding: 12px 10px 11px 10px;
+ &::placeholder {
+ color: black;
+ }
}
}
.collectionNoteTakingView-addDocumentButton {
+ opacity: 0.5;
font-size: 75%;
letter-spacing: 2px;
cursor: pointer;
@@ -437,10 +432,12 @@
.editableView-input {
outline-color: black;
letter-spacing: 2px;
- color: grey;
border: 0px;
padding: 12px 10px 11px 10px;
}
+ &:hover {
+ opacity: unset;
+ }
}
.collectionNoteTakingView-addGroupButton {
@@ -497,6 +494,24 @@
.rc-switch-checked .rc-switch-inner {
left: 8px;
}
+
+ .collectionNoteTaking-pivotField {
+ display: none;
+ }
+ &:hover {
+ .collectionNoteTaking-pivotField {
+ display: unset;
+ }
+ }
+}
+
+.collectionNoteTakingViewLight {
+ .collectionNoteTakingView-addDocumentButton,
+ .collectionNoteTakingView-addGroupButton {
+ .editableView-input::placeholder {
+ color: white;
+ }
+ }
}
@media only screen and (max-device-width: 480px) {
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 6318620e0..16c474996 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,7 +1,8 @@
-import { action, computed, IReactionDisposer, makeObservable, observable, observe, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, Field, Opt } from '../../../fields/Doc';
+import { ClientUtils, DivHeight, lightOrDark, returnZero, smoothScroll } from '../../../ClientUtils';
+import { Doc, Field, FieldType, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Copy, Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
@@ -9,24 +10,28 @@ import { listSpec } from '../../../fields/Schema';
import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { DivHeight, emptyFunction, returnFalse, returnZero, smoothScroll, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
-import { DragManager, dropActionType } from '../../util/DragManager';
+import { emptyFunction } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
+import { undoable, undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { LightboxView } from '../LightboxView';
+import { FieldsDropdown } from '../FieldsDropdown';
+import { Colors } from '../global/globalEnums';
+import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocumentView } from '../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
-import { StyleProp } from '../StyleProvider';
+import { FieldViewProps } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
+import { StyleProp } from '../StyleProp';
import './CollectionNoteTakingView.scss';
import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
import { CollectionSubView } from './CollectionSubView';
-import { JsxElement } from 'typescript';
+
const _global = (window /* browser */ || global) /* node */ as any;
/**
@@ -41,7 +46,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
_disposers: { [key: string]: IReactionDisposer } = {};
_masonryGridRef: HTMLDivElement | null = null;
_draggerRef = React.createRef<HTMLDivElement>();
- notetakingCategoryField = 'NotetakingCategory';
+ @computed get notetakingCategoryField() {
+ return StrCast(this.dataDoc.notetaking_column, StrCast(this.layoutDoc.pivotField, 'notetaking_column'));
+ }
public DividerWidth = 16;
@observable docsDraggedRowCol: number[] = [];
@observable _scroll = 0;
@@ -53,7 +60,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
}
@computed get chromeHidden() {
- return BoolCast(this.layoutDoc.chromeHidden) || this._props.onBrowseClickScript?.() ? true : false;
+ return BoolCast(this.layoutDoc.chromeHidden) || SnappingManager.ExploreMode;
}
// columnHeaders returns the list of SchemaHeaderFields currently being used by the layout doc to render the columns
@computed get colHeaderData() {
@@ -62,7 +69,6 @@ export class CollectionNoteTakingView extends CollectionSubView() {
if (needsUnsetCategory || colHeaderData === undefined || colHeaderData.length === 0) {
setTimeout(() => {
const columnHeaders = Array.from(Cast(this.dataDoc[this.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null) ?? []);
- const needsUnsetCategory = this.childDocs.some(d => !d[this.notetakingCategoryField] && !columnHeaders?.find(sh => sh.heading === 'unset'));
if (needsUnsetCategory || columnHeaders.length === 0) {
columnHeaders.push(new SchemaHeaderField('unset', undefined, undefined, 1));
this.resizeColumns(columnHeaders);
@@ -106,12 +112,12 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// to render the docs you see within an individual column.
children = (docs: Doc[]) => {
TraceMobx();
- return docs.map((d, i) => {
+ return docs.map(d => {
const height = () => this.getDocHeight(d);
const width = () => this.getDocWidth(d);
const style = { width: width(), marginTop: this.gridGap, height: height() };
return (
- <div className={`collectionNoteTakingView-columnDoc`} key={d[Id]} style={style}>
+ <div className="collectionNoteTakingView-columnDoc" key={d[Id]} style={style}>
{this.getDisplayDoc(d, width)}
</div>
);
@@ -130,7 +136,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
const sections = new Map<SchemaHeaderField, Doc[]>(columnHeaders.map(sh => [sh, []] as [SchemaHeaderField, []]));
const rowCol = this.docsDraggedRowCol;
// this will sort the docs into the correct columns (minus the ones you're currently dragging)
- docs.map(d => {
+ docs.forEach(d => {
const sectionValue = (d[this.notetakingCategoryField] as object) ?? `unset`;
// look for if header exists already
const existingHeader = columnHeaders.find(sh => sh.heading === sectionValue.toString());
@@ -148,42 +154,51 @@ export class CollectionNoteTakingView extends CollectionSubView() {
removeDocDragHighlight = () => {
setTimeout(
- action(() => (this.docsDraggedRowCol.length = 0)),
+ action(() => {
+ this.docsDraggedRowCol.length = 0;
+ }),
100
);
};
+ @computed get allFieldValues() {
+ return new Set(this.childDocs.map(doc => StrCast(doc[this.notetakingCategoryField])));
+ }
+
componentDidMount() {
super.componentDidMount?.();
document.addEventListener('pointerup', this.removeDocDragHighlight, true);
- this._disposers.layout_autoHeight = reaction(
- () => this.layoutDoc._layout_autoHeight,
- layout_autoHeight => layout_autoHeight && this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight)))
+
+ this._disposers.autoColumns = reaction(
+ () => (this.layoutDoc._notetaking_columns_autoCreate ? Array.from(this.allFieldValues) : undefined),
+ columns => undoable(() => columns?.filter(col => !this.colHeaderData.some(h => h.heading === col)).forEach(col => this.addColumn(col)), 'adding columns')(),
+ { fireImmediately: true }
);
this._disposers.refList = reaction(
- () => ({ refList: this._refList.slice(), autoHeight: this.layoutDoc._layout_autoHeight && !LightboxView.Contains(this.DocumentView?.()) }),
+ () => ({ refList: this._refList.slice(), autoHeight: this.layoutDoc._layout_autoHeight && !DocumentView.LightboxContains(this.DocumentView?.()) }),
({ refList, autoHeight }) => {
- if (autoHeight) refList.forEach(r => this.observer.observe(r));
- else this.observer.disconnect();
+ if (autoHeight) {
+ refList.forEach(r => this.observer.observe(r));
+ this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight)));
+ } else this.observer.disconnect();
},
{ fireImmediately: true }
);
}
componentWillUnmount() {
+ this.observer.disconnect();
document.removeEventListener('pointerup', this.removeDocDragHighlight, true);
super.componentWillUnmount();
Object.keys(this._disposers).forEach(key => this._disposers[key]());
}
- moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string): boolean => {
- return this._props.removeDocument?.(doc) && addDocument?.(doc) ? true : false;
- };
+ moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean) => !!(this._props.removeDocument?.(doc) && addDocument?.(doc));
createRef = (ele: HTMLDivElement | null) => {
this._masonryGridRef = ele;
- this.createDashEventsTarget(ele!); //so the whole grid is the drop target?
+ this.createDashEventsTarget(ele!);
};
@computed get onChildClickHandler() {
@@ -203,14 +218,15 @@ export class CollectionNoteTakingView extends CollectionSubView() {
Doc.BrushDoc(doc);
const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
if (found) {
- const top = found.getBoundingClientRect().top;
+ const { top } = found.getBoundingClientRect();
const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top);
if (Math.floor(localTop[1]) !== 0 && Math.ceil(this._props.PanelHeight()) < (this._mainCont?.scrollHeight || 0)) {
- let focusSpeed = options.zoomTime ?? 500;
+ const focusSpeed = options.zoomTime ?? 500;
smoothScroll(focusSpeed, this._mainCont!, localTop[1] + this._mainCont!.scrollTop, options.easeFunc);
return focusSpeed;
}
}
+ return undefined;
};
styleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
@@ -225,6 +241,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
return this._props.childOpacity();
}
break;
+ default:
}
return this._props.styleProvider?.(doc, props, property);
};
@@ -240,7 +257,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
const noteTakingDocTransform = () => this.getDocTransform(doc, dref);
return (
<DocumentView
- ref={r => (dref = r || undefined)}
+ ref={r => {
+ dref = r || undefined;
+ }}
Document={doc}
TemplateDataDocument={dataDoc ?? (!Doc.AreProtosEqual(doc[DocData], doc) ? doc[DocData] : undefined)}
pointerEvents={this.blockPointerEventsWhenDragging}
@@ -249,11 +268,11 @@ export class CollectionNoteTakingView extends CollectionSubView() {
PanelHeight={height}
styleProvider={this.styleProvider}
containerViewPath={this.childContainerViewPath}
- layout_fitWidth={this._props.childLayoutFitWidth}
+ fitWidth={this._props.childLayoutFitWidth}
isContentActive={emptyFunction}
onKey={this.onKeyDown}
- //TODO: change this from a prop to a parameter passed into a function
- dontHideOnDrag={true}
+ // TODO: change this from a prop to a parameter passed into a function
+ dontHideOnDrag
isDocumentActive={this.isContentActive}
LayoutTemplate={this._props.childLayoutTemplate}
LayoutTemplateString={this._props.childLayoutString}
@@ -262,10 +281,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
dontCenter={this._props.childIgnoreNativeSize ? 'xy' : undefined}
dontRegisterView={dataDoc ? true : BoolCast(this.layoutDoc.childDontRegisterViews, this._props.dontRegisterView)}
rootSelected={this.rootSelected}
- layout_showTitle={this._props.childlayout_showTitle}
+ showTitle={this._props.childlayout_showTitle}
dragAction={StrCast(this.layoutDoc.childDragAction) as dropActionType}
onClickScript={this.onChildClickHandler}
- onBrowseClickScript={this._props.onBrowseClickScript}
onDoubleClickScript={this.onChildDoubleClickHandler}
ScreenToLocalTransform={noteTakingDocTransform}
focus={this.focusDocument}
@@ -287,8 +305,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// getDocTransform is used to get the coordinates of a document when we go from a view like freeform to columns
getDocTransform(doc: Doc, dref?: DocumentView) {
- const y = this._scroll; // required for document decorations to update when the text box container is scrolled
- const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv || undefined);
+ this._scroll; // required for document decorations to update when the text box container is scrolled
+ const { translateX, translateY } = ClientUtils.GetScreenTransform(dref?.ContentDiv || undefined);
// the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off
return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(this.ScreenToLocalBoxXf().Scale);
}
@@ -296,9 +314,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// how to get the width of a document. Currently returns the width of the column (minus margins)
// if a note doc. Otherwise, returns the normal width (for graphs, images, etc...)
getDocWidth(d: Doc) {
- const heading = !d[this.notetakingCategoryField] ? 'unset' : Field.toString(d[this.notetakingCategoryField] as Field);
+ const heading = !d[this.notetakingCategoryField] ? 'unset' : Field.toString(d[this.notetakingCategoryField] as FieldType);
const existingHeader = this.colHeaderData.find(sh => sh.heading === heading);
- const existingWidth = existingHeader?.width ? existingHeader.width : 0;
+ const existingWidth = this.layoutDoc._notetaking_columns_autoSize ? 1 / (this.colHeaderData.length ?? 1) : existingHeader?.width ? existingHeader.width : 0;
const maxWidth = existingWidth > 0 ? existingWidth * this.availableWidth : this.maxColWidth;
const width = d.layout_fitWidth ? maxWidth : NumCast(d._width);
return Math.min(maxWidth - CollectionNoteTakingViewColumn.ColumnMargin, width < maxWidth ? width : maxWidth);
@@ -332,7 +350,6 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// Adding example: column widths are [0.6, 0.4] --> user adds column at end --> column widths are [0.4, 0.267, 0.33]
@action
resizeColumns = (headers: SchemaHeaderField[]) => {
- const n = headers.length;
const curWidths = headers.reduce((sum, hdr) => sum + Math.abs(hdr.width), 0);
const scaleFactor = 1 / curWidths;
this.dataDoc[this.fieldKey + '_columnHeaders'] = new List<SchemaHeaderField>(
@@ -370,7 +387,11 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// we alter the pivot fields of the docs in case they are moved to a new column.
const colIndex = this.getColumnFromXCoord(xCoord);
const colHeader = colIndex === undefined ? 'unset' : StrCast(this.colHeaderData[colIndex].heading);
- DragManager.docsBeingDragged.forEach(d => (d[this.notetakingCategoryField] = colHeader));
+ DragManager.docsBeingDragged
+ .map(doc => doc[DocData])
+ .forEach(d => {
+ d[this.notetakingCategoryField] = colHeader;
+ });
// used to notify sections to re-render
this.docsDraggedRowCol.length = 0;
const columnFromCoord = this.getColumnFromXCoord(xCoord);
@@ -381,7 +402,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// getColumnFromXCoord returns the column index for a given x-coordinate (currently always the client's mouse coordinate).
// This function is used to know which document a column SHOULD be in while it is being dragged.
getColumnFromXCoord = (xCoord: number): number | undefined => {
- let colIndex: number | undefined = undefined;
+ let colIndex: number | undefined;
const numColumns = this.colHeaderData.length;
const coords = [];
let colStartXCoord = 0;
@@ -404,10 +425,10 @@ export class CollectionNoteTakingView extends CollectionSubView() {
const docsMatchingHeader: Doc[] = [];
const colIndex = this.getColumnFromXCoord(xCoord);
const colHeader = colIndex === undefined ? 'unset' : StrCast(this.colHeaderData[colIndex].heading);
- this.childDocs?.map(d => {
+ this.childDocs?.forEach(d => {
if (d instanceof Promise) return;
const sectionValue = (d[this.notetakingCategoryField] as object) ?? 'unset';
- if (sectionValue.toString() == colHeader) {
+ if (sectionValue.toString() === colHeader) {
docsMatchingHeader.push(d);
}
});
@@ -420,9 +441,10 @@ export class CollectionNoteTakingView extends CollectionSubView() {
e.stopPropagation?.();
const newDoc = Doc.MakeCopy(fieldProps.Document, true);
newDoc[DocData].text = undefined;
- FormattedTextBox.SetSelectOnLoad(newDoc);
+ Doc.SetSelectOnLoad(newDoc);
return this.addDocument?.(newDoc);
}
+ return undefined;
};
// onInternalDrop is used when dragging and dropping a document within the view, such as dragging
@@ -451,7 +473,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
}
return true;
}
- } else if (de.complete.linkDragData?.dragDocument.embedContainer === this.Document && de.complete.linkDragData?.linkDragView?.CollectionFreeFormDocumentView) {
+ } else if (de.complete.linkDragData?.dragDocument.embedContainer === this.Document && CollectionFreeFormDocumentView.from(de.complete.linkDragData?.linkDragView)) {
const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, _layout_fitWidth: true, title: 'dropped annotation' });
if (!this._props.addDocument?.(source)) e.preventDefault();
de.complete.linkDocument = DocUtils.MakeLink(source, de.complete.linkDragData.linkSourceGetAnchor(), { link_relationship: 'doc annotation' }); // TODODO this is where in text links get passed
@@ -500,11 +522,12 @@ export class CollectionNoteTakingView extends CollectionSubView() {
editableViewProps = () => ({
GetValue: () => '',
- SetValue: this.addGroup,
- contents: '+ New Column',
+ SetValue: this.addColumn,
+ contents: '+ Column',
});
refList = () => this._refList;
+ backgroundColor = () => this.DocumentView?.()?.backgroundColor();
// sectionNoteTaking returns a CollectionNoteTakingViewColumn (which is an individual column)
sectionNoteTaking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => (
@@ -512,7 +535,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
key={heading?.heading ?? 'unset'}
PanelWidth={this._props.PanelWidth}
refList={this._refList}
+ backgroundColor={this.backgroundColor}
select={this._props.select}
+ isContentActive={this.isContentActive}
addDocument={this.addDocument}
chromeHidden={this.chromeHidden}
colHeaderData={this.colHeaderData}
@@ -538,18 +563,27 @@ export class CollectionNoteTakingView extends CollectionSubView() {
/>
);
+ @undoBatch
+ remColumn = (value: SchemaHeaderField) => {
+ const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
+ if (value) {
+ const index = colHdrData.indexOf(value);
+ index !== -1 && colHdrData.splice(index, 1);
+ this.resizeColumns(colHdrData);
+ }
+ };
+
// addGroup is called when adding a new columnHeader, adding a SchemaHeaderField to our list of
// columnHeaders and resizing the existing columns to make room for our new one.
@undoBatch
- addGroup = (value: string) => {
- if (this.colHeaderData) {
- for (const header of this.colHeaderData) {
- if (header.heading === value) {
- alert('You cannot use an existing column name. Please try a new column name');
- return value;
- }
+ addColumn = (value: string) => {
+ this.colHeaderData.forEach(header => {
+ if (header.heading === value) {
+ alert('You cannot use an existing column name. Please try a new column name');
+ return value;
}
- }
+ return undefined;
+ });
const columnHeaders = Array.from(Cast(this.dataDoc[this.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
const newColWidth = 1 / (this.numGroupColumns + 1);
columnHeaders.push(new SchemaHeaderField(value, undefined, undefined, newColWidth));
@@ -557,13 +591,43 @@ export class CollectionNoteTakingView extends CollectionSubView() {
return true;
};
+ removeEmptyColumns = undoable(() => {
+ this.colHeaderData.filter(h => !this.allFieldValues.has(h.heading)).forEach(this.remColumn);
+ }, 'remove empty Columns');
+
onContextMenu = (e: React.MouseEvent): void => {
// need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
if (!e.isPropagationStopped()) {
const subItems: ContextMenuProps[] = [];
- subItems.push({ description: `${this.layoutDoc._columnsFill ? 'Variable Size' : 'Autosize'} Column`, event: () => (this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill), icon: 'plus' });
- subItems.push({ description: `${this.layoutDoc._layout_autoHeight ? 'Variable Height' : 'Auto Height'}`, event: () => (this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight), icon: 'plus' });
- subItems.push({ description: 'Clear All', event: () => (this.dataDoc.data = new List([])), icon: 'times' });
+ subItems.push({
+ description: `${this.layoutDoc._notetaking_columns_autoCreate ? 'Manually' : 'Automatically'} Create columns`,
+ event: () => {
+ this.layoutDoc._notetaking_columns_autoCreate = !this.layoutDoc._notetaking_columns_autoCreate;
+ },
+ icon: 'computer',
+ });
+ subItems.push({ description: 'Remove Empty Columns', event: this.removeEmptyColumns, icon: 'computer' });
+ subItems.push({
+ description: `${this.layoutDoc._notetaking_columns_autoSize ? 'Variable Size' : 'Autosize'} Columns`,
+ event: () => {
+ this.layoutDoc._notetaking_columns_autoSize = !this.layoutDoc._notetaking_columns_autoSize;
+ },
+ icon: 'plus',
+ });
+ subItems.push({
+ description: `${this.layoutDoc._layout_autoHeight ? 'Variable Height' : 'Auto Height'}`,
+ event: () => {
+ this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight;
+ },
+ icon: 'plus',
+ });
+ subItems.push({
+ description: 'Clear All',
+ event: () => {
+ this.dataDoc.data = new List([]);
+ },
+ icon: 'times',
+ });
ContextMenu.Instance.addItem({ description: 'Options...', subitems: subItems, icon: 'eye' });
}
};
@@ -588,6 +652,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
const sections = Array.from(this.Sections.entries());
return sections.reduce((list, sec, i) => {
list.push(this.sectionNoteTaking(sec[0], sec[1]));
+ // eslint-disable-next-line react/no-array-index-key
i !== sections.length - 1 && list.push(<CollectionNoteTakingViewDivider key={`divider${i}`} isContentActive={this.isContentActive} index={i} setColumnStartXCoords={this.setColumnStartXCoords} xMargin={this.xMargin} />);
return list;
}, [] as JSX.Element[]);
@@ -614,22 +679,35 @@ export class CollectionNoteTakingView extends CollectionSubView() {
TraceMobx();
return (
<div
- className="collectionNoteTakingView"
+ className={`collectionNoteTakingView ${lightOrDark(this.backgroundColor()) === Colors.WHITE ? 'collectionNoteTakingViewLight' : ''}`}
ref={this.createRef}
- key="notes"
style={{
- overflowY: this._props.isContentActive() ? 'auto' : 'hidden',
- background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor),
+ overflowY: this.isContentActive() ? 'auto' : 'hidden',
+ background: this.backgroundColor(),
pointerEvents: this.backgroundEvents,
}}
- onScroll={action(e => (this._scroll = e.currentTarget.scrollTop))}
- onPointerLeave={action(e => (this.docsDraggedRowCol.length = 0))}
+ onScroll={action(e => {
+ this._scroll = e.currentTarget.scrollTop;
+ })}
+ onPointerLeave={action(() => {
+ this.docsDraggedRowCol.length = 0;
+ })}
onPointerMove={e => e.buttons && this.onPointerMove(false, e.clientX, e.clientY)}
onDragOver={e => this.onPointerMove(true, e.clientX, e.clientY)}
onDrop={this.onExternalDrop.bind(this)}
onContextMenu={this.onContextMenu}
onWheel={e => this._props.isContentActive() && e.stopPropagation()}>
- <>{this.renderedSections}</>
+ {this.renderedSections}
+ <div className="collectionNotetaking-pivotField" style={{ right: 0, top: 0, position: 'absolute' }}>
+ <FieldsDropdown
+ Document={this.Document}
+ selectFunc={undoable(fieldKey => {
+ this.layoutDoc._pivotField = fieldKey;
+ this.removeEmptyColumns();
+ }, 'change pivot field')}
+ placeholder={StrCast(this.layoutDoc._pivotField)}
+ />
+ </div>
</div>
);
}
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index db178d500..44ab1968d 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -1,23 +1,21 @@
+/* eslint-disable jsx-a11y/control-has-associated-label */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable } from 'mobx';
+import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { returnEmptyString } from '../../../Utils';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Id } from '../../../fields/FieldSymbols';
-import { RichTextField } from '../../../fields/RichTextField';
+import { lightOrDark, returnEmptyString } from '../../../ClientUtils';
+import { Doc, Opt } from '../../../fields/Doc';
import { listSpec } from '../../../fields/Schema';
import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { Cast, NumCast } from '../../../fields/Types';
-import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { DocUtils, Docs } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
+import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
+import { undoBatch, undoable } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
-import { ContextMenuProps } from '../ContextMenuItem';
import { EditableView } from '../EditableView';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
@@ -26,6 +24,7 @@ import './CollectionNoteTakingView.scss';
interface CSVFieldColumnProps {
Document: Doc;
TemplateDataDocument: Opt<Doc>;
+ backgroundColor?: (() => string) | undefined;
docList: Doc[];
heading: string;
pivotField: string;
@@ -38,6 +37,7 @@ interface CSVFieldColumnProps {
gridGap: number;
headings: () => object[];
select: (ctrlPressed: boolean) => void;
+ isContentActive: () => boolean | undefined;
renderChildren: (docs: Doc[]) => JSX.Element[];
addDocument: (doc: Doc | Doc[]) => boolean;
createDropTarget: (ele: HTMLDivElement) => void;
@@ -57,10 +57,16 @@ interface CSVFieldColumnProps {
*/
@observer
export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSVFieldColumnProps> {
- @observable private _background = 'inherit';
+ @observable private _hover = false;
+
+ constructor(props: CSVFieldColumnProps) {
+ super(props);
+ makeObservable(this);
+ }
// columnWidth returns the width of a column in absolute pixels
@computed get columnWidth() {
+ if (this._props.Document._notetaking_columns_autoSize) return this._props.availableWidth / (this._props.colHeaderData?.length || 1);
if (!this._props.colHeaderData || !this._props.headingObject || this._props.colHeaderData.length === 1) return `${(this._props.availableWidth / this._props.PanelWidth()) * 100}%`;
const i = this._props.colHeaderData.findIndex(hd => hd.heading === this._props.headingObject?.heading && hd.color === this._props.headingObject.color);
return ((this._props.colHeaderData[i].width * this._props.availableWidth) / this._props.PanelWidth()) * 100 + '%';
@@ -106,13 +112,15 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
};
@action
- headingChanged = (value: string, shiftDown?: boolean) => {
+ headingChanged = (value: string /* , shiftDown?: boolean */) => {
const castedValue = this.getValue(value);
if (castedValue) {
if (this._props.colHeaderData?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) {
return false;
}
- this._props.docList.forEach(d => (d[this._props.pivotField] = castedValue));
+ this._props.docList.forEach(d => {
+ d[this._props.pivotField] = castedValue;
+ });
if (this._props.headingObject) {
this._props.headingObject.setHeading(castedValue.toString());
this._heading = this._props.headingObject.heading;
@@ -122,10 +130,14 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
return false;
};
- @action pointerEntered = () => SnappingManager.IsDragging && (this._background = '#b4b4b4');
- @action pointerLeave = () => (this._background = 'inherit');
- @undoBatch
- addTextNote = (char: string) => this.addNewTextDoc('-typed text-', false, true);
+ @action pointerEntered = () => {
+ this._hover = true;
+ };
+ @action pointerLeave = () => {
+ this._hover = false;
+ };
+
+ addTextNote = undoable(() => this.addNewTextDoc('-typed text-', false, true), 'add text note');
// addNewTextDoc is called when a user starts typing in a column to create a new node
@action
@@ -135,7 +147,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _layout_fitWidth: true, title: value, _layout_autoHeight: true });
const colValue = this.getValue(this._props.heading);
newDoc[key] = colValue;
- FormattedTextBox.SetSelectOnLoad(newDoc);
+ Doc.SetSelectOnLoad(newDoc);
FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
return this._props.addDocument?.(newDoc) || false;
};
@@ -147,7 +159,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
deleteColumn = () => {
const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
if (this._props.headingObject) {
- this._props.docList.forEach(d => (d[this._props.pivotField] = undefined));
+ // this._props.docList.forEach(d => (d[DocData][this._props.pivotField] = undefined));
colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1);
this._props.resizeColumns(colHdrData);
}
@@ -155,64 +167,24 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
menuCallback = (x: number, y: number) => {
ContextMenu.Instance.clearItems();
- const layoutItems: ContextMenuProps[] = [];
- const docItems: ContextMenuProps[] = [];
- const dataDoc = this._props.TemplateDataDocument || this._props.Document;
+ const { pivotField } = this._props;
const pivotValue = this.getValue(this._props.heading);
DocUtils.addDocumentCreatorMenuItems(
doc => {
const key = this._props.pivotField;
doc[key] = this.getValue(this._props.heading);
- FormattedTextBox.SetSelectOnLoad(doc);
+ Doc.SetSelectOnLoad(doc);
return this._props.addDocument?.(doc);
},
this._props.addDocument,
x,
y,
true,
- this._props.pivotField,
+ pivotField, // when created, the new doc's pivotField will be set to pivotValue
pivotValue
);
- Array.from(Object.keys(Doc.GetProto(dataDoc)))
- .filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof dataDoc[fieldKey] === 'string')
- .map(fieldKey =>
- docItems.push({
- description: ':' + fieldKey,
- event: () => {
- const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document));
- if (created) {
- if (this._props.Document.isTemplateDoc) {
- Doc.MakeMetadataFieldTemplate(created, this._props.Document);
- }
- return this._props.addDocument?.(created);
- }
- },
- icon: 'compress-arrows-alt',
- })
- );
- Array.from(Object.keys(Doc.GetProto(dataDoc)))
- .filter(fieldKey => DocListCast(dataDoc[fieldKey]).length)
- .map(fieldKey =>
- docItems.push({
- description: ':' + fieldKey,
- event: () => {
- const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
- if (created) {
- const container = this._props.Document.resolvedDataDoc ? Doc.GetProto(this._props.Document) : this._props.Document;
- if (container.isTemplateDoc) {
- Doc.MakeMetadataFieldTemplate(created, container);
- return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created);
- }
- return this._props.addDocument?.(created) || false;
- }
- },
- icon: 'compress-arrows-alt',
- })
- );
- !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' });
- !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: 'Containers ...', subitems: layoutItems, icon: 'eye' });
ContextMenu.Instance.setDefaultItem('::', (name: string): void => {
Doc.GetProto(this._props.Document)[name] = '';
const created = Docs.Create.TextDocument('', { title: name, _width: 250, _layout_autoHeight: true });
@@ -231,7 +203,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
const key = this._props.pivotField;
const heading = this._heading;
const columnYMargin = this._props.headingObject ? 0 : this._props.yMargin;
- const evContents = heading ? heading : '25';
+ const evContents = heading || '25';
const headingView = this._props.headingObject ? (
<div
key={heading}
@@ -245,17 +217,16 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
className="collectionNoteTakingView-sectionHeader-subCont"
title={evContents === `No Value` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''}
style={{ background: evContents !== `No Value` ? this._color : 'inherit' }}>
- <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this._props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine={true} />
+ <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this._props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine />
</div>
{(this._props.colHeaderData?.length ?? 0) > 1 && (
- <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
+ <button type="button" className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
<FontAwesomeIcon icon="trash" size="lg" />
</button>
)}
</div>
) : null;
const templatecols = this.columnWidth;
- const type = this._props.Document.type;
return (
<>
{headingView}
@@ -263,7 +234,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
<div className="collectionNoteTakingView-columnStack">
<div
key={`${heading}-stack`}
- className={`collectionNoteTakingView-Nodes`}
+ className="collectionNoteTakingView-Nodes"
style={{
padding: `${columnYMargin}px ${0}px ${this._props.yMargin}px ${0}px`,
gridGap: this._props.gridGap,
@@ -273,12 +244,15 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
</div>
{!this._props.chromeHidden ? (
- <div className="collectionNoteTakingView-DocumentButtons" style={{ marginBottom: 10 }}>
- <div key={`${heading}-add-document`} className="collectionNoteTakingView-addDocumentButton">
- <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} placeholder={"Type ':' for commands"} contents={'+ New Node'} menuCallback={this.menuCallback} />
+ <div className="collectionNoteTakingView-DocumentButtons" style={{ display: this._props.isContentActive() ? 'flex' : 'none', marginBottom: 10 }}>
+ <div className="collectionNoteTakingView-addDocumentButton" style={{ color: lightOrDark(this._props.backgroundColor?.()) }}>
+ <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} placeholder={"Type ':' for commands"} contents="+ Node" menuCallback={this.menuCallback} />
</div>
- <div key={`${this._props.Document[Id]}-addGroup`} className="collectionNoteTakingView-addDocumentButton">
- <EditableView {...this._props.editableViewProps()} />
+ <div className="collectionNoteTakingView-addDocumentButton" style={{ color: lightOrDark(this._props.backgroundColor?.()) }}>
+ {
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ <EditableView {...this._props.editableViewProps()} />
+ }
</div>
</div>
) : null}
@@ -292,17 +266,17 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
TraceMobx();
return (
<div
- className="collectionNoteTakingViewFieldColumn"
- key={this._heading}
+ className="collectionNoteTakingViewFieldColumnHover"
+ onPointerEnter={this.pointerEntered}
+ onPointerLeave={this.pointerLeave}
style={{
width: this.columnWidth,
- background: this._background,
+ background: this._hover && SnappingManager.IsDragging ? '#b4b4b4' : 'inherit',
marginLeft: this._props.headings().findIndex((h: any) => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0,
- }}
- ref={this.createColumnDropRef}
- onPointerEnter={this.pointerEntered}
- onPointerLeave={this.pointerLeave}>
- {this.innards}
+ }}>
+ <div className="collectionNoteTakingViewFieldColumn" key={this._heading} ref={this.createColumnDropRef}>
+ {this.innards}
+ </div>
</div>
);
}
diff --git a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
index 5e4bce19d..ddd4b8137 100644
--- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
@@ -1,7 +1,8 @@
import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, setupMoveUpEvents } from '../../../Utils';
+import { emptyFunction } from '../../../Utils';
+import { setupMoveUpEvents } from '../../../ClientUtils';
import { UndoManager } from '../../util/UndoManager';
import { ObservableReactComponent } from '../ObservableReactComponent';
@@ -27,7 +28,7 @@ export class CollectionNoteTakingViewDivider extends ObservableReactComponent<Di
setupMoveUpEvents(
this,
e,
- (e, down, delta) => {
+ (moveEv, down, delta) => {
if (!batch) batch = UndoManager.StartBatch('resizing');
this._props.setColumnStartXCoords(delta[0], this._props.index);
return false;
@@ -59,6 +60,18 @@ export class CollectionNoteTakingViewDivider extends ObservableReactComponent<Di
width: 12,
borderRight: '4px solid #282828',
borderLeft: '4px solid #282828',
+ position: 'fixed',
+ pointerEvents: 'none',
+ }}
+ />
+ <div
+ className="columnResizer-handler"
+ onPointerDown={e => this.registerResizing(e)}
+ style={{
+ height: '95%',
+ width: 12,
+ borderRight: '4px solid #282828',
+ borderLeft: '4px solid #282828',
}}
/>
</div>
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 7d7f0bb61..5b3f625db 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -1,19 +1,22 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action, computed, IReactionDisposer, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
import { Doc, DocListCast } from '../../../fields/Doc';
import { ScriptField } from '../../../fields/ScriptField';
-import { NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils';
-import { DocUtils } from '../../documents/Documents';
-import { SelectionManager } from '../../util/SelectionManager';
+import { NumCast, StrCast, toList } from '../../../fields/Types';
+import { emptyFunction } from '../../../Utils';
+import { DocUtils } from '../../documents/DocUtils';
+import { dropActionType } from '../../util/DropActionTypes';
import { undoBatch, UndoManager } from '../../util/UndoManager';
-import { OpenWhere } from '../nodes/DocumentView';
+import { OpenWhere } from '../nodes/OpenWhere';
import { computePassLayout, computeStarburstLayout } from './collectionFreeForm';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
import './CollectionPileView.scss';
import { CollectionSubView } from './CollectionSubView';
-import { dropActionType } from '../../util/DragManager';
+import { DocumentView } from '../nodes/DocumentView';
@observer
export class CollectionPileView extends CollectionSubView() {
@@ -40,15 +43,15 @@ export class CollectionPileView extends CollectionSubView() {
layoutEngine = () => StrCast(this.Document._freeform_pileEngine);
@undoBatch
- addPileDoc = (doc: Doc | Doc[]) => {
- (doc instanceof Doc ? [doc] : doc).map(d => DocUtils.iconify(d));
- return this._props.addDocument?.(doc) || false;
+ addPileDoc = (docs: Doc | Doc[]) => {
+ toList(docs).map(doc => DocUtils.iconify(doc));
+ return this._props.addDocument?.(docs) || false;
};
@undoBatch
- removePileDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
- (doc instanceof Doc ? [doc] : doc).forEach(d => Doc.deiconifyView(d));
- const ret = this._props.moveDocument?.(doc, targetCollection, addDoc) || false;
+ removePileDoc = (docs: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
+ toList(docs).forEach(doc => Doc.deiconifyView(doc));
+ const ret = this._props.moveDocument?.(docs, targetCollection, addDoc) || false;
if (ret && !DocListCast(this.dataDoc[this.fieldKey ?? 'data']).length) this.DocumentView?.()._props.removeDocument?.(this.Document);
return ret;
};
@@ -66,6 +69,7 @@ export class CollectionPileView extends CollectionSubView() {
return (
<div className="collectionPileView-innards" style={{ pointerEvents: this.contentEvents }}>
<CollectionFreeFormView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props} //
layoutEngine={this.layoutEngine}
addDocument={this.addPileDoc}
@@ -116,16 +120,16 @@ export class CollectionPileView extends CollectionSubView() {
setupMoveUpEvents(
this,
e,
- (e: PointerEvent, down: number[], delta: number[]) => {
- if (this.layoutEngine() === 'pass' && this.childDocs.length && e.shiftKey) {
+ (moveEv: PointerEvent, down: number[], delta: number[]) => {
+ if (this.layoutEngine() === 'pass' && this.childDocs.length && moveEv.shiftKey) {
dist += Math.sqrt(delta[0] * delta[0] + delta[1] * delta[1]);
if (dist > 100) {
if (!this._undoBatch) {
this._undoBatch = UndoManager.StartBatch('layout pile');
}
const doc = this.childDocs[0];
- doc.x = e.clientX;
- doc.y = e.clientY;
+ doc.x = moveEv.clientX;
+ doc.y = moveEv.clientY;
this._props.addDocTab(doc, OpenWhere.inParentFromScreen) && (this._props.removeDocument?.(doc) || false);
dist = 0;
}
@@ -146,7 +150,7 @@ export class CollectionPileView extends CollectionSubView() {
@undoBatch
onClick = (e: React.MouseEvent) => {
if (e.button === 0) {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
this.toggleStarburst();
e.stopPropagation();
}
@@ -154,7 +158,7 @@ export class CollectionPileView extends CollectionSubView() {
render() {
return (
- <div className={`collectionPileView`} onClick={this.onClick} onPointerDown={this.pointerDown} style={{ width: this._props.PanelWidth(), height: '100%' }}>
+ <div className="collectionPileView" onClick={this.onClick} onPointerDown={this.pointerDown} style={{ width: this._props.PanelWidth(), height: '100%' }}>
{this.contents}
</div>
);
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 5c47d4b9e..fac885300 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -1,7 +1,13 @@
+/* eslint-disable react/jsx-props-no-spreading */
+/* eslint-disable jsx-a11y/alt-text */
+/* eslint-disable no-use-before-define */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnTrue, returnZero, setupMoveUpEvents, smoothScrollHorizontal, StopEvent } from '../../../ClientUtils';
import { Doc, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
@@ -10,26 +16,25 @@ import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { Cast, NumCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
-import { emptyFunction, formatTime, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnTrue, returnZero, setupMoveUpEvents, smoothScrollHorizontal, StopEvent } from '../../../Utils';
+import { emptyFunction, formatTime } from '../../../Utils';
import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
-import { DocumentManager } from '../../util/DocumentManager';
+import { FollowLinkScript, IsFollowLinkScript } from '../../documents/DocUtils';
import { DragManager } from '../../util/DragManager';
-import { FollowLinkScript, IsFollowLinkScript, LinkFollower } from '../../util/LinkFollower';
-import { LinkManager } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch, UndoManager } from '../../util/UndoManager';
-import { CollectionSubView } from '../collections/CollectionSubView';
-import { LightboxView } from '../LightboxView';
+import { VideoThumbnails } from '../global/globalEnums';
import { AudioWaveform } from '../nodes/audio/AudioWaveform';
-import { DocumentView, OpenWhere } from '../nodes/DocumentView';
-import { FocusFuncType, FocusViewOptions, StyleProviderFuncType } from '../nodes/FieldView';
+import { DocumentView } from '../nodes/DocumentView';
+import { FocusFuncType, StyleProviderFuncType } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
import { LabelBox } from '../nodes/LabelBox';
-import { VideoBox } from '../nodes/VideoBox';
+import { OpenWhere } from '../nodes/OpenWhere';
import { ObservableReactComponent } from '../ObservableReactComponent';
import './CollectionStackedTimeline.scss';
+import { CollectionSubView } from './CollectionSubView';
export type CollectionStackedTimelineProps = {
Play: () => void;
@@ -57,9 +62,14 @@ export enum TrimScope {
@observer
export class CollectionStackedTimeline extends CollectionSubView<CollectionStackedTimelineProps>() {
+ // eslint-disable-next-line no-use-before-define
public static SelectingRegions: Set<CollectionStackedTimeline> = new Set();
public static StopSelecting() {
- this.SelectingRegions.forEach(action(region => (region._selectingRegion = false)));
+ this.SelectingRegions.forEach(
+ action(region => {
+ region._selectingRegion = false;
+ })
+ );
this.SelectingRegions.clear();
}
constructor(props: any) {
@@ -73,7 +83,6 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
private _timeline: HTMLDivElement | null = null; // ref to actual timeline div
private _timelineWrapper: HTMLDivElement | null = null; // ref to timeline wrapper div for zooming and scrolling
private _markerStart: number = 0;
- @observable public static CurrentlyPlaying: DocumentView[] = [];
@observable _selectingRegion = false;
@observable _markerEnd: number | undefined = undefined;
@observable _trimming: number = TrimScope.None;
@@ -130,7 +139,9 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
componentWillUnmount() {
document.removeEventListener('keydown', this.keyEvents, true);
if (this._selectingRegion) {
- runInAction(() => (this._selectingRegion = false));
+ runInAction(() => {
+ this._selectingRegion = false;
+ });
CollectionStackedTimeline.SelectingRegions.delete(this);
}
}
@@ -166,7 +177,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
getView = async (doc: Doc, options: FocusViewOptions): Promise<Opt<DocumentView>> =>
new Promise<Opt<DocumentView>>(res => {
if (doc.hidden) options.didMove = !(doc.hidden = false);
- const findDoc = (finish: (dv: DocumentView) => void) => DocumentManager.Instance.AddViewRenderedCb(doc, dv => finish(dv));
+ const findDoc = (finish: (dv: DocumentView) => void) => DocumentView.addViewRenderedCb(doc, dv => finish(dv));
findDoc(dv => res(dv));
});
@@ -174,9 +185,9 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
anchorEnd = (anchor: Doc, val: any = null) => NumCast(anchor._timecodeToHide, NumCast(anchor[this._props.endTag], val) ?? null);
// converts screen pixel offset to time
- toTimeline = (screen_delta: number, width: number) => {
- return Math.max(this.clipStart, Math.min(this.clipEnd, (screen_delta / width) * this.clipDuration + this.clipStart));
- };
+ // prettier-ignore
+ toTimeline = (screenDelta: number, width: number) => //
+ Math.max(this.clipStart, Math.min(this.clipEnd, (screenDelta / width) * this.clipDuration + this.clipStart));
@computed get rangeClick() {
// prettier-ignore
@@ -234,6 +245,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
this._props.setTime(Math.min(Math.max(this.clipStart, this.currentTime + jump), this.clipEnd));
e.stopPropagation();
break;
+ default:
}
}
};
@@ -253,17 +265,15 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
@action
onPointerDownTimeline = (e: React.PointerEvent): void => {
const rect = this._timeline?.getBoundingClientRect();
- const clientX = e.clientX;
- const diff = rect ? clientX - rect?.x : null;
- const shiftKey = e.shiftKey;
+ const { clientX, shiftKey } = e;
if (rect && this._props.isContentActive()) {
const wasPlaying = this._props.playing();
if (wasPlaying) this._props.Pause();
- var wasSelecting = this._markerEnd !== undefined;
+ let wasSelecting = this._markerEnd !== undefined;
setupMoveUpEvents(
this,
e,
- action(e => {
+ action(() => {
if (!wasSelecting) {
this._markerStart = this._markerEnd = this.toTimeline(clientX - rect.x, rect.width);
wasSelecting = true;
@@ -272,8 +282,8 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
this._markerEnd = this.toTimeline(e.clientX - rect.x, rect.width);
return false;
}),
- action((e, movement, isClick) => {
- this._markerEnd = this.toTimeline(e.clientX - rect.x, rect.width);
+ action((upEvent, movement, isClick) => {
+ this._markerEnd = this.toTimeline(upEvent.clientX - rect.x, rect.width);
if (this._markerEnd < this._markerStart) {
const tmp = this._markerStart;
this._markerStart = this._markerEnd;
@@ -281,13 +291,13 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
}
if (!isClick && Math.abs(movement[0]) > 15 && !this.IsTrimming) {
const anchor = CollectionStackedTimeline.createAnchor(this.Document, this.dataDoc, this._props.fieldKey, this._markerStart, this._markerEnd, undefined, true);
- setTimeout(() => DocumentManager.Instance.getDocumentView(anchor)?.select(false));
+ setTimeout(() => DocumentView.getDocumentView(anchor)?.select(false));
}
(!isClick || !wasSelecting) && (this._markerEnd = undefined);
this._timelineWrapper && (this._timelineWrapper.style.cursor = '');
}),
- (e, doubleTap) => {
- if (e.button !== 2) {
+ (clickEv, doubleTap) => {
+ if (clickEv.button !== 2) {
this._props.select(false);
!wasPlaying && doubleTap && this._props.Play();
}
@@ -309,11 +319,11 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
onHover = (e: React.MouseEvent): void => {
e.stopPropagation();
const rect = this._timeline?.getBoundingClientRect();
- const clientX = e.clientX;
+ const { clientX } = e;
if (rect) {
this._hoverTime = this.toTimeline(clientX - rect.x, rect.width);
if (this.thumbnails) {
- const nearest = Math.floor((this._hoverTime / this._props.rawDuration) * VideoBox.numThumbnails);
+ const nearest = Math.floor((this._hoverTime / this._props.rawDuration) * VideoThumbnails.DENSE);
const imgField = this.thumbnails.length > 0 ? new ImageField(this.thumbnails[nearest]) : undefined;
this._thumbnail = imgField?.url?.href ? imgField.url.href.replace('.png', '_m.png') : undefined;
}
@@ -327,14 +337,14 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
setupMoveUpEvents(
this,
e,
- action((e, [], []) => {
+ action(moveEv => {
if (rect && this._props.isContentActive()) {
- this._trimStart = Math.min(Math.max(this.trimStart + (e.movementX / rect.width) * this.clipDuration, this.clipStart), this.trimEnd - this.minTrimLength);
+ this._trimStart = Math.min(Math.max(this.trimStart + (moveEv.movementX / rect.width) * this.clipDuration, this.clipStart), this.trimEnd - this.minTrimLength);
}
return false;
}),
emptyFunction,
- action((e, doubleTap) => {
+ action((clickEv, doubleTap) => {
doubleTap && (this._trimStart = this.clipStart);
})
);
@@ -347,14 +357,14 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
setupMoveUpEvents(
this,
e,
- action((e, [], []) => {
+ action(moveEv => {
if (rect && this._props.isContentActive()) {
- this._trimEnd = Math.max(Math.min(this.trimEnd + (e.movementX / rect.width) * this.clipDuration, this.clipEnd), this.trimStart + this.minTrimLength);
+ this._trimEnd = Math.max(Math.min(this.trimEnd + (moveEv.movementX / rect.width) * this.clipDuration, this.clipEnd), this.trimStart + this.minTrimLength);
}
return false;
}),
emptyFunction,
- action((e, doubleTap) => {
+ action((clickEv, doubleTap) => {
doubleTap && (this._trimEnd = this.clipEnd);
})
);
@@ -383,7 +393,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
// handles dragging and dropping markers in timeline
@action
- internalDocDrop(e: Event, de: DragManager.DropEvent, docDragData: DragManager.DocumentDragData, xp: number) {
+ internalDocDrop(e: Event, de: DragManager.DropEvent, docDragData: DragManager.DocumentDragData) {
if (super.onInternalDrop(e, de)) {
// determine x coordinate of drop and assign it to the documents being dragged --- see internalDocDrop of collectionFreeFormView.tsx for how it's done when dropping onto a 2D freeform view
const localPt = this.ScreenToLocalBoxXf().transformPoint(de.x, de.y);
@@ -403,7 +413,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
}
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
- if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData, 0);
+ if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData);
return false;
};
@@ -441,7 +451,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
}
@action
- playOnClick = (anchorDoc: Doc, clientX: number) => {
+ playOnClick = (anchorDoc: Doc /* , clientX: number */) => {
const seekTimeInSeconds = this.anchorStart(anchorDoc) - 0.05;
const endTime = this.anchorEnd(anchorDoc);
if (this.layoutDoc.autoPlayAnchors) {
@@ -450,17 +460,15 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
this._props.playFrom(seekTimeInSeconds, endTime);
this.scrollToTime(seekTimeInSeconds);
}
- } else {
- if (seekTimeInSeconds < NumCast(this.layoutDoc._layout_currentTimecode) && endTime > NumCast(this.layoutDoc._layout_currentTimecode)) {
- if (!this.layoutDoc.autoPlayAnchors && this._props.playing()) {
- this._props.Pause();
- } else {
- this._props.Play();
- }
+ } else if (seekTimeInSeconds < NumCast(this.layoutDoc._layout_currentTimecode) && endTime > NumCast(this.layoutDoc._layout_currentTimecode)) {
+ if (!this.layoutDoc.autoPlayAnchors && this._props.playing()) {
+ this._props.Pause();
} else {
- this._props.playFrom(seekTimeInSeconds, endTime);
- this.scrollToTime(seekTimeInSeconds);
+ this._props.Play();
}
+ } else {
+ this._props.playFrom(seekTimeInSeconds, endTime);
+ this.scrollToTime(seekTimeInSeconds);
}
return { select: true };
};
@@ -468,7 +476,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
@action
clickAnchor = (anchorDoc: Doc, clientX: number) => {
if (IsFollowLinkScript(anchorDoc.onClick)) {
- LinkFollower.FollowLink(undefined, anchorDoc, false);
+ DocumentView.FollowLink(undefined, anchorDoc, false);
}
const seekTimeInSeconds = this.anchorStart(anchorDoc) - 0.05;
const endTime = this.anchorEnd(anchorDoc);
@@ -479,19 +487,17 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
const rect = this._timeline?.getBoundingClientRect();
rect && this._props.setTime(this.toTimeline(clientX - rect.x, rect.width));
}
+ } else if (this.layoutDoc.autoPlayAnchors) {
+ this._props.playFrom(seekTimeInSeconds, endTime);
} else {
- if (this.layoutDoc.autoPlayAnchors) {
- this._props.playFrom(seekTimeInSeconds, endTime);
- } else {
- this._props.setTime(seekTimeInSeconds);
- }
+ this._props.setTime(seekTimeInSeconds);
}
return { select: true };
};
// makes sure no anchors overlaps each other by setting the correct position and width
getLevel = (m: Doc, placed: { anchorStartTime: number; anchorEndTime: number; level: number }[]) => {
- const timelineContentWidth = this.timelineContentWidth;
+ const { timelineContentWidth } = this;
const x1 = this.anchorStart(m);
const x2 = this.anchorEnd(m, x1 + (10 / timelineContentWidth) * this.clipDuration);
let max = 0;
@@ -503,6 +509,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
max = Math.max(max, p.level);
return p.level;
}
+ return undefined;
})
);
let level = max + 1;
@@ -564,10 +571,14 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
onWheel={e => this.isContentActive() && e.stopPropagation()}
onScroll={this.setScroll}
onMouseMove={e => this.isContentActive() && this.onHover(e)}
- ref={wrapper => (this._timelineWrapper = wrapper)}>
+ ref={wrapper => {
+ this._timelineWrapper = wrapper;
+ }}>
<div
className="collectionStackedTimeline"
- ref={(timeline: HTMLDivElement | null) => (this._timeline = timeline)}
+ ref={(timeline: HTMLDivElement | null) => {
+ this._timeline = timeline;
+ }}
onClick={e => this.isContentActive() && StopEvent(e)}
onPointerDown={e => this.isContentActive() && this.onPointerDownTimeline(e)}
style={{ width: this.timelineContentWidth }}>
@@ -582,7 +593,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
const height = this._props.PanelHeight() / maxLevel;
return this.Document.hideAnchors ? null : (
<div
- className={'collectionStackedTimeline-marker-timeline'}
+ className="collectionStackedTimeline-marker-timeline"
key={d.anchor[Id]}
style={{
left,
@@ -592,8 +603,10 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
pointerEvents: 'none',
}}>
<StackedTimelineAnchor
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
mark={d.anchor}
+ containerViewPath={this._props.containerViewPath}
rangeClickScript={this.rangeClickScript}
rangePlayScript={this.rangePlayScript}
left={left - this._scroll}
@@ -645,7 +658,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
{this.IsTrimming !== TrimScope.None && (
<>
- <div className="collectionStackedTimeline-trim-shade" style={{ width: `${((this.trimStart - this.clipStart) / this.clipDuration) * 100}%` }}></div>
+ <div className="collectionStackedTimeline-trim-shade" style={{ width: `${((this.trimStart - this.clipStart) / this.clipDuration) * 100}%` }} />
<div
className="collectionStackedTimeline-trim-controls"
@@ -653,8 +666,8 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
left: `${((this.trimStart - this.clipStart) / this.clipDuration) * 100}%`,
width: `${((this.trimEnd - this.trimStart) / this.clipDuration) * 100}%`,
}}>
- <div className="collectionStackedTimeline-trim-handle" onPointerDown={this.trimLeft}></div>
- <div className="collectionStackedTimeline-trim-handle" onPointerDown={this.trimRight}></div>
+ <div className="collectionStackedTimeline-trim-handle" onPointerDown={this.trimLeft} />
+ <div className="collectionStackedTimeline-trim-handle" onPointerDown={this.trimRight} />
</div>
<div
@@ -662,7 +675,8 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
style={{
left: `${((this.trimEnd - this.clipStart) / this.clipDuration) * 100}%`,
width: `${((this.clipEnd - this.trimEnd) / this.clipDuration) * 100}%`,
- }}></div>
+ }}
+ />
</>
)}
</div>
@@ -684,7 +698,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
interface StackedTimelineAnchorProps {
mark: Doc;
whenChildContentsActiveChanged: (isActive: boolean) => void;
- addDocTab: (doc: Doc, where: OpenWhere) => boolean;
+ addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean;
rangeClickScript: () => ScriptField;
rangePlayScript: () => ScriptField;
left: number;
@@ -701,6 +715,7 @@ interface StackedTimelineAnchorProps {
layoutDoc: Doc;
isDocumentActive?: () => boolean | undefined;
ScreenToLocalTransform: () => Transform;
+ containerViewPath?: () => DocumentView[];
_timeline: HTMLDivElement | null;
focus: FocusFuncType;
currentTimecode: () => number;
@@ -733,20 +748,20 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
this._disposer = reaction(
() => this._props.currentTimecode(),
time => {
- const dictationDoc = Cast(this._props.layoutDoc.data_dictation, Doc, null);
- const isDictation = dictationDoc && LinkManager.Links(this._props.mark).some(link => Cast(link.link_anchor_1, Doc, null)?.annotationOn === dictationDoc);
+ // const dictationDoc = Cast(this._props.layoutDoc.data_dictation, Doc, null);
+ // const isDictation = dictationDoc && LinkManager.Links(this._props.mark).some(link => Cast(link.link_anchor_1, Doc, null)?.annotationOn === dictationDoc);
if (
- !LightboxView.LightboxDoc &&
+ !DocumentView.LightboxDoc() &&
// bcz: when should links be followed? we don't want to move away from the video to follow a link but we can open it in a sidebar/etc. But we don't know that upfront.
// for now, we won't follow any links when the lightbox is oepn to avoid "losing" the video.
- /*(isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this._props.layoutDoc))*/
+ /* (isDictation || !Doc.AreProtosEqual(DocumentView.LightboxDoc(), this._props.layoutDoc)) */
!this._props.layoutDoc.dontAutoFollowLinks &&
- LinkManager.Links(this._props.mark).length &&
+ Doc.Links(this._props.mark).length &&
time > NumCast(this._props.mark[this._props.startTag]) &&
time < NumCast(this._props.mark[this._props.endTag]) &&
this._lastTimecode < NumCast(this._props.mark[this._props.startTag]) - 1e-5
) {
- LinkFollower.FollowLink(undefined, this._props.mark, false);
+ DocumentView.FollowLink(undefined, this._props.mark, false);
}
this._lastTimecode = time;
}
@@ -761,34 +776,33 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
// starting the drag event for anchor resizing
@action
onAnchorDown = (e: React.PointerEvent, anchor: Doc, left: boolean): void => {
- //this._props._timeline?.setPointerCapture(e.pointerId);
- const newTime = (e: PointerEvent) => {
- const rect = (e.target as any).getBoundingClientRect();
- return this._props.toTimeline(e.clientX - rect.x, rect.width);
+ const newTime = (timeDownEv: PointerEvent) => {
+ const rect = (timeDownEv.target as any).getBoundingClientRect();
+ return this._props.toTimeline(timeDownEv.clientX - rect.x, rect.width);
};
- const changeAnchor = (anchor: Doc, left: boolean, time: number | undefined) => {
+ const changeAnchor = (time: number | undefined) => {
const timelineOnly = Cast(anchor[this._props.startTag], 'number', null) !== undefined;
if (timelineOnly) {
- if (!left && time !== undefined && time <= NumCast(anchor[this._props.startTag])) time = undefined;
- Doc.SetInPlace(anchor, left ? this._props.startTag : this._props.endTag, time, true);
- if (!left) Doc.SetInPlace(anchor, 'layout_borderRounding', time !== undefined ? undefined : '100%', true);
+ const timeMod = !left && time !== undefined && time <= NumCast(anchor[this._props.startTag]) ? undefined : time;
+ Doc.SetInPlace(anchor, left ? this._props.startTag : this._props.endTag, timeMod, true);
+ if (!left) Doc.SetInPlace(anchor, 'layout_borderRounding', timeMod !== undefined ? undefined : '100%', true);
} else {
anchor[left ? '_timecodeToShow' : '_timecodeToHide'] = time;
}
return false;
};
this.noEvents = true;
- var undo: UndoManager.Batch | undefined;
+ let undo: UndoManager.Batch | undefined;
setupMoveUpEvents(
this,
e,
- e => {
+ moveEv => {
if (!undo) undo = UndoManager.StartBatch('drag anchor');
- this._props.setTime(newTime(e));
- return changeAnchor(anchor, left, newTime(e));
+ this._props.setTime(newTime(moveEv));
+ return changeAnchor(newTime(moveEv));
},
- action(e => {
- this._props.setTime(newTime(e));
+ action(upEv => {
+ this._props.setTime(newTime(upEv));
undo?.end();
this.noEvents = false;
}),
@@ -796,12 +810,15 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
);
};
+ resetTitle = () => {
+ this._props.mark[DocData].title = ComputedField.MakeFunction(
+ `["${this._props.endTag}"] ? "#" + formatToTime(this["${this._props.startTag}"]) + "-" + formatToTime(this["${this._props.endTag}"]) : "#" + formatToTime(this["${this._props.startTag}"]`
+ );
+ };
// context menu
contextMenuItems = () => {
const resetTitle = {
- script: ScriptField.MakeFunction(
- `this.title = this["${this._props.endTag}"] ? "#" + formatToTime(this["${this._props.startTag}"]) + "-" + formatToTime(this["${this._props.endTag}"]) : "#" + formatToTime(this["${this._props.startTag}"])`
- )!,
+ method: this.resetTitle,
icon: 'folder-plus',
label: 'Reset Title',
};
@@ -823,10 +840,12 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
{...this._props}
NativeWidth={returnZero}
NativeHeight={returnZero}
- ref={action((r: DocumentView | null) => (anchor.view = r))}
+ ref={action((r: DocumentView | null) => {
+ anchor.view = r;
+ })}
Document={mark}
TemplateDataDocument={undefined}
- containerViewPath={returnEmptyDoclist}
+ containerViewPath={this._props.containerViewPath}
pointerEvents={this.noEvents ? returnNone : undefined}
styleProvider={this._props.styleProvider}
renderDepth={this._props.renderDepth + 1}
@@ -835,7 +854,7 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
isDocumentActive={this._props.isDocumentActive}
PanelWidth={width}
PanelHeight={height}
- layout_fitWidth={returnTrue}
+ fitWidth={returnTrue}
ScreenToLocalTransform={screenXf}
pinToPres={emptyFunction}
focus={focusFunc}
@@ -846,7 +865,7 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
onClickScript={script}
onDoubleClickScript={this._props.layoutDoc.autoPlayAnchors ? undefined : doublescript}
ignoreAutoHeight={false}
- hideResizeHandles={true}
+ hideResizeHandles
contextMenuItems={this.contextMenuItems}
/>
),
@@ -862,7 +881,7 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
return (
<div style={{ pointerEvents: this.noEvents ? 'none' : undefined }}>
{inner.view}
- {!inner.anchor.view || !inner.anchor.view.IsSelected ? null : (
+ {!inner.anchor.view?.IsSelected ? null : (
<>
<div key="left" className="collectionStackedTimeline-left-resizer" style={{ pointerEvents: this.noEvents ? 'none' : undefined }} onPointerDown={e => this.onAnchorDown(e, this._props.mark, true)} />
<div key="right" className="collectionStackedTimeline-resizer" style={{ pointerEvents: this.noEvents ? 'none' : undefined }} onPointerDown={e => this.onAnchorDown(e, this._props.mark, false)} />
@@ -872,12 +891,15 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
);
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function formatToTime(time: number): any {
return formatTime(time);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function min(num1: number, num2: number): number {
return Math.min(num1, num2);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function max(num1: number, num2: number): number {
return Math.max(num1, num2);
});
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ea1caf58f..56d2a6c9c 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -1,8 +1,11 @@
+/* eslint-disable react/jsx-props-no-spreading */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+// eslint-disable-next-line import/no-extraneous-dependencies
import * as CSS from 'csstype';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { ClientUtils, DivHeight, returnEmptyDoclist, returnNone, returnZero, setupMoveUpEvents, smoothScroll } from '../../../ClientUtils';
import { Doc, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
@@ -11,26 +14,28 @@ import { listSpec } from '../../../fields/Schema';
import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { DivHeight, emptyFunction, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { emptyFunction } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
import { CollectionViewType } from '../../documents/DocumentTypes';
-import { DragManager, dropActionType } from '../../util/DragManager';
+import { DocUtils } from '../../documents/DocUtils';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
import { SettingsManager } from '../../util/SettingsManager';
import { Transform } from '../../util/Transform';
import { undoBatch, UndoManager } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { EditableView } from '../EditableView';
-import { LightboxView } from '../LightboxView';
import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocumentView } from '../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
-import { StyleProp } from '../StyleProvider';
+import { FieldViewProps } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
+import { StyleProp } from '../StyleProp';
import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow';
import './CollectionStackingView.scss';
import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn';
import { CollectionSubView } from './CollectionSubView';
+
const _global = (window /* browser */ || global) /* node */ as any;
export type collectionStackingViewProps = {
@@ -125,11 +130,16 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// TODO: plj - these are the children
children = (docs: Doc[]) => {
- //TODO: can somebody explain me to what exactly TraceMobX is?
+ // TODO: can somebody explain me to what exactly TraceMobX is?
TraceMobx();
// appears that we are going to reset the _docXfs. TODO: what is Xfs?
this._docXfs.length = 0;
- this._renderCount < docs.length && setTimeout(action(() => (this._renderCount = Math.min(docs.length, this._renderCount + 5))));
+ this._renderCount < docs.length &&
+ setTimeout(
+ action(() => {
+ this._renderCount = Math.min(docs.length, this._renderCount + 5);
+ })
+ );
return docs.map((d, i) => {
const height = () => this.getDocHeight(d);
const width = () => this.getDocWidth(d);
@@ -152,19 +162,21 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
};
// is sections that all collections inherit? I think this is how we show the masonry/columns
- //TODO: this seems important
+ // TODO: this seems important
get Sections() {
// appears that pivot field IS actually for sorting
if (!this.pivotField || this.colHeaderData instanceof Promise) return new Map<SchemaHeaderField, Doc[]>();
if (this.colHeaderData === undefined) {
- setTimeout(() => (this.dataDoc['_' + this.fieldKey + '_columnHeaders'] = new List<SchemaHeaderField>()), 0);
+ setTimeout(() => {
+ this.dataDoc['_' + this.fieldKey + '_columnHeaders'] = new List<SchemaHeaderField>();
+ });
return new Map<SchemaHeaderField, Doc[]>();
}
const colHeaderData = Array.from(this.colHeaderData);
const fields = new Map<SchemaHeaderField, Doc[]>(colHeaderData.map(sh => [sh, []] as [SchemaHeaderField, []]));
let changed = false;
- this.filteredChildren.map(d => {
+ this.filteredChildren.forEach(d => {
const sectionValue = (d[this.pivotField] ? d[this.pivotField] : `NO ${this.pivotField.toUpperCase()} VALUE`) as object;
// the next five lines ensures that floating point rounding errors don't create more than one section -syip
const parsed = parseInt(sectionValue.toString());
@@ -186,7 +198,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
if (this.layoutDoc._columnsHideIfEmpty) {
Array.from(fields.keys())
.filter(key => !fields.get(key)!.length)
- .map(header => {
+ .forEach(header => {
fields.delete(header);
colHeaderData.splice(colHeaderData.indexOf(header), 1);
changed = true;
@@ -207,14 +219,16 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// reset section headers when a new filter is inputted
this._disposers.pivotField = reaction(
() => this.pivotField,
- () => (this.dataDoc['_' + this.fieldKey + '_columnHeaders'] = new List())
+ () => {
+ this.dataDoc['_' + this.fieldKey + '_columnHeaders'] = new List();
+ }
);
this._disposers.autoHeight = reaction(
() => this.layoutDoc._layout_autoHeight,
- layout_autoHeight => layout_autoHeight && this._props.setHeight?.(this.headerMargin + (this.isStackingView ? Math.max(...this._refList.map(DivHeight)) : this._refList.reduce((p, r) => p + DivHeight(r), 0)))
+ layoutAutoHeight => layoutAutoHeight && this._props.setHeight?.(this.headerMargin + (this.isStackingView ? Math.max(...this._refList.map(DivHeight)) : this._refList.reduce((p, r) => p + DivHeight(r), 0)))
);
this._disposers.refList = reaction(
- () => ({ refList: this._refList.slice(), autoHeight: this.layoutDoc._layout_autoHeight && !LightboxView.Contains(this.DocumentView?.()) }),
+ () => ({ refList: this._refList.slice(), autoHeight: this.layoutDoc._layout_autoHeight && !DocumentView.LightboxContains(this.DocumentView?.()) }),
({ refList, autoHeight }) => {
this.observer.disconnect();
if (autoHeight) refList.forEach(r => this.observer.observe(r));
@@ -225,14 +239,13 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
componentWillUnmount() {
super.componentWillUnmount();
+ this.observer.disconnect();
Object.keys(this._disposers).forEach(key => this._disposers[key]());
}
isAnyChildContentActive = () => this._props.isAnyChildContentActive();
- moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => {
- return this._props.removeDocument?.(doc) && addDocument?.(doc) ? true : false;
- };
+ moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => !!(this._props.removeDocument?.(doc) && addDocument?.(doc));
onChildClickHandler = () => this._props.childClickScript || ScriptCast(this.Document.onChildClick);
@computed get onChildDoubleClickHandler() {
@@ -249,10 +262,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
if (found) {
- const top = found.getBoundingClientRect().top;
+ const { top } = found.getBoundingClientRect();
const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top);
if (Math.floor(localTop[1]) !== 0) {
- let focusSpeed = options.zoomTime ?? 500;
+ const focusSpeed = options.zoomTime ?? 500;
smoothScroll(focusSpeed, this._mainCont!, localTop[1] + this._mainCont!.scrollTop, options.easeFunc);
return focusSpeed;
}
@@ -275,18 +288,18 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
if (['Enter'].includes(e.key) && e.ctrlKey) {
e.stopPropagation?.();
- const below = !e.altKey && e.key !== 'Tab';
- const layout_fieldKey = StrCast(fieldProps.fieldKey);
+ const layoutFieldKey = StrCast(fieldProps.fieldKey);
const newDoc = Doc.MakeCopy(fieldProps.Document, true);
const dataField = fieldProps.Document[Doc.LayoutFieldKey(newDoc)];
newDoc[DocData][Doc.LayoutFieldKey(newDoc)] = dataField === undefined || Cast(dataField, listSpec(Doc), null)?.length !== undefined ? new List<Doc>([]) : undefined;
- if (layout_fieldKey !== 'layout' && fieldProps.Document[layout_fieldKey] instanceof Doc) {
- newDoc[layout_fieldKey] = fieldProps.Document[layout_fieldKey];
+ if (layoutFieldKey !== 'layout' && fieldProps.Document[layoutFieldKey] instanceof Doc) {
+ newDoc[layoutFieldKey] = fieldProps.Document[layoutFieldKey];
}
newDoc[DocData].text = undefined;
- FormattedTextBox.SetSelectOnLoad(newDoc);
+ Doc.SetSelectOnLoad(newDoc);
return this.addDocument?.(newDoc);
}
+ return false;
};
isContentActive = () => (this._props.isContentActive() ? true : this._props.isSelected() === false || this._props.isContentActive() === false ? false : undefined);
@@ -315,18 +328,17 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
<DocumentView
ref={action((r: DocumentView) => r?.ContentDiv && this.docRefs.set(doc, r))}
Document={doc}
- TemplateDataDocument={dataDoc ?? (Doc.AreProtosEqual(doc[DocData], doc) ? undefined : doc[DocData])}
+ TemplateDataDocument={dataDoc}
renderDepth={this._props.renderDepth + 1}
PanelWidth={panelWidth}
PanelHeight={panelHeight}
pointerEvents={this.DocumentView?.()._props.onClickScript?.() ? returnNone : undefined} // if the stack has an onClick, then we don't want the contents to be interactive (see CollectionPileView)
styleProvider={this.styleProvider}
containerViewPath={this.childContainerViewPath}
- layout_fitWidth={this.childFitWidth}
+ fitWidth={this.childFitWidth}
isContentActive={doc.onClick ? this.isChildButtonContentActive : this.isChildContentActive}
onKey={this.onKeyDown}
DataTransition={trans}
- onBrowseClickScript={this._props.onBrowseClickScript}
isDocumentActive={this.isContentActive}
LayoutTemplate={this._props.childLayoutTemplate}
LayoutTemplateString={this._props.childLayoutString}
@@ -335,7 +347,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
dontCenter={this._props.childIgnoreNativeSize ? 'xy' : (StrCast(this.layoutDoc.layout_dontCenter) as any)}
dontRegisterView={BoolCast(this.layoutDoc.childDontRegisterViews, this._props.dontRegisterView)} // used to be true if DataDoc existed, but template textboxes won't layout_autoHeight resize if dontRegisterView is set, but they need to.
rootSelected={this.rootSelected}
- layout_showTitle={this._props.childlayout_showTitle}
+ showTitle={this._props.childlayout_showTitle}
dragAction={(this.layoutDoc.childDragAction ?? this._props.childDragAction) as dropActionType}
onClickScript={this.onChildClickHandler}
onDoubleClickScript={this.onChildDoubleClickHandler}
@@ -362,7 +374,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
getDocTransform(doc: Doc) {
const dref = this.docRefs.get(doc);
this._scroll; // must be referenced for document decorations to update when the text box container is scrolled
- const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv);
+ const { translateX, translateY } = ClientUtils.GetScreenTransform(dref?.ContentDiv);
// the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off
return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(this.ScreenToLocalBoxXf().Scale);
}
@@ -398,7 +410,9 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// This following three functions must be from the view Mehek showed
columnDividerDown = (e: React.PointerEvent) => {
- runInAction(() => (this._cursor = 'grabbing'));
+ runInAction(() => {
+ this._cursor = 'grabbing';
+ });
const batch = UndoManager.StartBatch('stacking width');
setupMoveUpEvents(
this,
@@ -424,7 +438,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
onPointerDown={this.columnDividerDown}
ref={this._draggerRef}
style={{ cursor: this._cursor, color: SettingsManager.userColor, left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.yMargin - 9)}px` }}>
- <FontAwesomeIcon icon={'arrows-alt-h'} />
+ <FontAwesomeIcon icon="arrows-alt-h" />
</div>
);
}
@@ -438,7 +452,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
let dropAfter = 0;
if (de.complete.docDragData) {
// going to re-add the docs to the _docXFs based on position of where we just dropped
- this._docXfs.map((cd, i) => {
+ this._docXfs.forEach((cd, i) => {
const pos = cd
.stackedDocTransform()
.inverse()
@@ -467,7 +481,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
}
return true;
}
- } else if (de.complete.linkDragData?.dragDocument.embedContainer === this.Document && de.complete.linkDragData?.linkDragView?.CollectionFreeFormDocumentView) {
+ } else if (de.complete.linkDragData?.dragDocument.embedContainer === this.Document && CollectionFreeFormDocumentView.from(de.complete.linkDragData?.linkDragView)) {
const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, _layout_fitWidth: true, title: 'dropped annotation' });
if (!this._props.addDocument?.(source)) e.preventDefault();
de.complete.linkDocument = DocUtils.MakeLink(source, de.complete.linkDragData.linkSourceGetAnchor(), { link_relationship: 'doc annotation' }); // TODODO this is where in text links get passed
@@ -495,7 +509,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
onExternalDrop = async (e: React.DragEvent): Promise<void> => {
const where = [e.clientX, e.clientY];
let targInd = -1;
- this._docXfs.map((cd, i) => {
+ this._docXfs.forEach((cd, i) => {
const pos = cd
.stackedDocTransform()
.inverse()
@@ -520,10 +534,11 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// what a section looks like if we're in stacking view
sectionStacking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
const key = this.pivotField;
- let type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined = undefined;
+ let type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined;
if (this.pivotField) {
const types = docList.length ? docList.map(d => typeof d[key]) : this.filteredChildren.map(d => typeof d[key]);
if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
+ // eslint-disable-next-line prefer-destructuring
type = types[0];
}
}
@@ -556,9 +571,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// what a section looks like if we're in masonry. Shouldn't actually need to use this.
sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[], first: boolean) => {
const key = this.pivotField;
- let type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined = undefined;
+ let type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined;
const types = docList.length ? docList.map(d => typeof d[key]) : this.filteredChildren.map(d => typeof d[key]);
if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
+ // eslint-disable-next-line prefer-destructuring
type = types[0];
}
const rows = () => (!this.isStackingView ? 1 : Math.max(1, Math.min(docList.length, Math.floor((this._props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap)))));
@@ -608,9 +624,9 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
const cm = ContextMenu.Instance;
const options = cm.findByDescription('Options...');
const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : [];
- optionItems.push({ description: `${this.layoutDoc._columnsFill ? 'Variable Size' : 'Autosize'} Column`, event: () => (this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill), icon: 'plus' });
- optionItems.push({ description: `${this.layoutDoc._layout_autoHeight ? 'Variable Height' : 'Auto Height'}`, event: () => (this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight), icon: 'plus' });
- optionItems.push({ description: 'Clear All', event: () => (this.dataDoc[this.fieldKey ?? 'data'] = new List([])), icon: 'times' });
+ optionItems.push({ description: `${this.layoutDoc._columnsFill ? 'Variable Size' : 'Autosize'} Column`, event: () => { this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill; }, icon: 'plus' }); // prettier-ignore
+ optionItems.push({ description: `${this.layoutDoc._layout_autoHeight ? 'Variable Height' : 'Auto Height'}`, event: () => { this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight; }, icon: 'plus' }); // prettier-ignore
+ optionItems.push({ description: 'Clear All', event: () => { this.dataDoc[this.fieldKey ?? 'data'] = new List([]); } , icon: 'times' }); // prettier-ignore
!options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'compass' });
}
};
@@ -638,7 +654,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
addDocument={this._props.addDocument}
moveDocument={this._props.moveDocument}
addDocTab={this._props.addDocTab}
- onBrowseClickScript={this._props.onBrowseClickScript}
pinToPres={emptyFunction}
rootSelected={this.rootSelected}
removeDocument={this._props.removeDocument}
@@ -699,7 +714,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
className={this.isStackingView ? 'collectionStackingView' : 'collectionMasonryView'}
ref={ele => {
this._masonryGridRef = ele;
- this.createDashEventsTarget(ele); //so the whole grid is the drop target?
+ this.createDashEventsTarget(ele); // so the whole grid is the drop target?
this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel);
this._oldWheel = ele;
// prevent wheel events from passively propagating up through containers and prevents containers from preventDefault which would block scrolling
@@ -710,7 +725,9 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor),
pointerEvents: (this._props.pointerEvents?.() as any) ?? this.backgroundEvents,
}}
- onScroll={action(e => (this._scroll = e.currentTarget.scrollTop))}
+ onScroll={action(e => {
+ this._scroll = e.currentTarget.scrollTop;
+ })}
onDrop={this.onExternalDrop.bind(this)}
onContextMenu={this.onContextMenu}
onWheel={e => this.isContentActive() && e.stopPropagation()}>
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 6a3cb759e..e2ad5b31d 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -1,7 +1,11 @@
+/* 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 { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { DivHeight, DivWidth, returnEmptyString, setupMoveUpEvents } from '../../../ClientUtils';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
import { RichTextField } from '../../../fields/RichTextField';
import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField';
@@ -9,10 +13,13 @@ import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, NumCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { DivHeight, DivWidth, emptyFunction, returnEmptyString, setupMoveUpEvents } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { emptyFunction } from '../../../Utils';
+import { DocumentFromField } from '../../documents/DocFromField';
+import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
@@ -66,11 +73,26 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
_ele: HTMLElement | null = null;
+ protected onInternalPreDrop = (e: Event, de: DragManager.DropEvent, targetDropAction: dropActionType) => {
+ const dragData = de.complete.docDragData;
+ if (dragData) {
+ const sourceDragAction = dragData.dropAction;
+ const sameCollection = !dragData.draggedDocuments.some(d => !this._props.docList.includes(d));
+ dragData.dropAction = !sameCollection // if doc from another tree
+ ? sourceDragAction || targetDropAction // then use the source's dragAction otherwise the target's
+ : sourceDragAction === dropActionType.inPlace // if source drag is inPlace
+ ? sourceDragAction // keep the doc in place
+ : dropActionType.same; // otherwise use same tree semantics to move within tree
+
+ e.stopPropagation();
+ }
+ };
+
// This is likely similar to what we will be doing. Why do we need to make these refs?
// is that the only way to have drop targets?
createColumnDropRef = (ele: HTMLDivElement | null) => {
this.dropDisposer?.();
- if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document);
+ if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document, this.onInternalPreDrop.bind(this));
else if (this._ele) this.props.refList.splice(this.props.refList.indexOf(this._ele), 1);
this._ele = ele;
};
@@ -80,7 +102,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
this._ele && this.props.refList.push(this._ele);
this._disposers.collapser = reaction(
() => this._props.headingObject?.collapsed,
- collapsed => (this.collapsed = collapsed !== undefined ? BoolCast(collapsed) : false),
+ collapsed => { this.collapsed = collapsed !== undefined ? BoolCast(collapsed) : false; }, // prettier-ignore
{ fireImmediately: true }
);
}
@@ -90,7 +112,6 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
this._ele = null;
}
- //TODO: what is scripting? I found it in SetInPlace def but don't know what that is
@undoBatch
columnDrop = action((e: Event, de: DragManager.DropEvent) => {
const drop = { docs: de.complete.docDragData?.droppedDocuments, val: this.getValue(this._heading) };
@@ -106,13 +127,13 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
};
@action
- headingChanged = (value: string, shiftDown?: boolean) => {
+ headingChanged = (value: string /* , shiftDown?: boolean */) => {
const castedValue = this.getValue(value);
if (castedValue) {
if (this._props.colHeaderData?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) {
return false;
}
- this._props.docList.forEach(d => (d[this._props.pivotField] = castedValue));
+ this._props.pivotField && this._props.docList.forEach(d => { d[this._props.pivotField] = castedValue; }) // prettier-ignore
if (this._props.headingObject) {
this._props.headingObject.setHeading(castedValue.toString());
this._heading = this._props.headingObject.heading;
@@ -128,27 +149,30 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
this._color = color;
};
- @action pointerEntered = () => SnappingManager.IsDragging && (this._background = '#b4b4b4');
- @action pointerLeave = () => (this._background = 'inherit');
- @undoBatch typedNote = (char: string) => this.addNewTextDoc('-typed text-', false, true);
+ @action pointerEntered = () => { SnappingManager.IsDragging && (this._background = '#b4b4b4'); } // prettier-ignore
+ @action pointerLeave = () => { this._background = 'inherit'}; // prettier-ignore
+ @undoBatch typedNote = () => this.addNewTextDoc('-typed text-', false, true);
@action
addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
if (!value && !forceEmptyNote) return false;
const key = this._props.pivotField;
const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _layout_fitWidth: true, title: value, _layout_autoHeight: true });
- newDoc[key] = this.getValue(this._props.heading);
- const maxHeading = this._props.docList.reduce((maxHeading, doc) => (NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading), 0);
+ key && (newDoc[key] = this.getValue(this._props.heading));
+ const maxHeading = this._props.docList.reduce((prevHeading, doc) => (NumCast(doc.heading) > prevHeading ? NumCast(doc.heading) : prevHeading), 0);
const heading = maxHeading === 0 || this._props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
newDoc.heading = heading;
- FormattedTextBox.SetSelectOnLoad(newDoc);
+ Doc.SetSelectOnLoad(newDoc);
FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
return this._props.addDocument?.(newDoc) || false;
};
@action
deleteColumn = () => {
- this._props.docList.forEach(d => (d[this._props.pivotField] = undefined));
+ this._props.pivotField &&
+ this._props.docList.forEach(d => {
+ d[this._props.pivotField] = undefined;
+ });
if (this._props.colHeaderData && this._props.headingObject) {
const index = this._props.colHeaderData.indexOf(this._props.headingObject);
this._props.colHeaderData.splice(index, 1);
@@ -163,8 +187,8 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
headerDown = (e: React.PointerEvent<HTMLDivElement>) => setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
- //TODO: I think this is where I'm supposed to edit stuff
- startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
+ // TODO: I think this is where I'm supposed to edit stuff
+ startDrag = (e: PointerEvent) => {
// is MakeEmbedding a way to make a copy of a doc without rendering it?
const embedding = Doc.MakeEmbedding(this._props.Document);
embedding._width = this._props.columnWidth / (this._props.colHeaderData?.length || 1);
@@ -195,23 +219,21 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
);
};
- renderMenu = () => {
- return (
- <div className="collectionStackingView-optionPicker">
- <div className="optionOptions">
- <div className={'optionPicker' + (true ? ' active' : '')} onClick={action(() => {})}>
- Add options here
- </div>
- </div>
+ renderMenu = () => (
+ <div className="collectionStackingView-optionPicker">
+ <div className="optionOptions">
+ <div className="optionPicker active">Add options here</div>
</div>
- );
- };
+ </div>
+ );
@observable private collapsed: boolean = false;
- private toggleVisibility = action(() => (this.collapsed = !this.collapsed));
+ private toggleVisibility = action(() => {
+ this.collapsed = !this.collapsed;
+ });
- menuCallback = (x: number, y: number) => {
+ menuCallback = () => {
ContextMenu.Instance.clearItems();
const layoutItems: ContextMenuProps[] = [];
const docItems: ContextMenuProps[] = [];
@@ -220,7 +242,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
const height = this._ele ? DivHeight(this._ele) : 0;
DocUtils.addDocumentCreatorMenuItems(
doc => {
- FormattedTextBox.SetSelectOnLoad(doc);
+ Doc.SetSelectOnLoad(doc);
return this._props.addDocument?.(doc);
},
this._props.addDocument,
@@ -235,13 +257,14 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
docItems.push({
description: ':' + fieldKey,
event: () => {
- const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document));
+ const created = DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document));
if (created) {
if (this._props.Document.isTemplateDoc) {
Doc.MakeMetadataFieldTemplate(created, this._props.Document);
}
return this._props.addDocument?.(created);
}
+ return false;
},
icon: 'compress-arrows-alt',
})
@@ -261,6 +284,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
}
return this._props.addDocument?.(created) || false;
}
+ return false;
},
icon: 'compress-arrows-alt',
})
@@ -292,7 +316,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
const columnYMargin = this._props.headingObject ? 0 : this._props.yMargin;
const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
const noValueHeader = `NO ${key.toUpperCase()} VALUE`;
- const evContents = heading ? heading : this._props?.type === 'number' ? '0' : noValueHeader;
+ const evContents = heading || (this._props?.type === 'number' ? '0' : noValueHeader);
const headingView = this._props.headingObject ? (
<div
key={heading}
@@ -309,14 +333,19 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
onPointerDown={this.headerDown}
title={evContents === noValueHeader ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''}
style={{ background: evContents !== noValueHeader ? this._color : 'inherit' }}>
- <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine={true} />
+ <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine />
<div className="collectionStackingView-sectionColor" style={{ display: evContents === noValueHeader ? 'none' : undefined }}>
- <button className="collectionStackingView-sectionColorButton" onClick={action(e => (this._paletteOn = !this._paletteOn))}>
+ <button
+ type="button"
+ className="collectionStackingView-sectionColorButton"
+ onClick={action(() => {
+ this._paletteOn = !this._paletteOn;
+ })}>
<FontAwesomeIcon icon="palette" size="lg" />
</button>
{this._paletteOn ? this.renderColorPicker() : null}
</div>
- <button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
+ <button type="button" className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
<FontAwesomeIcon icon="trash" size="lg" />
</button>
{/* {evContents === noValueHeader ? null : (
@@ -337,7 +366,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
</div>
) : null;
const templatecols = `${this._props.columnWidth / this._props.numGroupColumns}px `;
- const type = this._props.Document.type;
+ const { type } = this._props.Document;
return (
<>
{this._props.Document._columnsHideIfEmpty ? null : headingView}
@@ -345,11 +374,11 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
<div>
<div
key={`${heading}-stack`}
- className={`collectionStackingView-masonrySingle`}
+ className="collectionStackingView-masonrySingle"
style={{
padding: `${columnYMargin}px ${0}px ${this._props.yMargin}px ${0}px`,
margin: 'auto',
- width: 'max-content', //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
+ width: 'max-content', // singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
height: 'max-content',
position: 'relative',
gridGap: this._props.gridGap,
@@ -361,10 +390,10 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
{!this._props.chromeHidden && type !== DocumentType.PRES ? (
// TODO: this is the "new" button: see what you can work with here
// change cursor to pointer for this, and update dragging cursor
- //TODO: there is a bug that occurs when adding a freeform document and trying to move it around
- //TODO: would be great if there was additional space beyond the frame, so that you can actually see your
+ // TODO: there is a bug that occurs when adding a freeform document and trying to move it around
+ // TODO: would be great if there was additional space beyond the frame, so that you can actually see your
// bottom note
- //TODO: ok, so we are using a single column, and this is it!
+ // TODO: ok, so we are using a single column, and this is it!
<div
key={`${heading}-add-document`}
onKeyDown={e => e.stopPropagation()}
@@ -375,7 +404,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
SetValue={this.addNewTextDoc}
textCallback={this.typedNote}
placeholder={"Type ':' for commands"}
- contents={<FontAwesomeIcon icon={'plus'} />}
+ contents={<FontAwesomeIcon icon="plus" />}
menuCallback={this.menuCallback}
/>
</div>
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 59a695a3d..e250d7a90 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -1,37 +1,68 @@
import { action, computed, makeObservable, observable } from 'mobx';
import * as React from 'react';
import * as rp from 'request-promise';
-import { Utils, returnFalse } from '../../../Utils';
+import { ClientUtils, returnFalse } from '../../../ClientUtils';
import CursorField from '../../../fields/CursorField';
-import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc';
-import { AclPrivate } from '../../../fields/DocSymbols';
+import { Doc, DocListCast, GetDocFromUrl, GetHrefFromHTML, Opt, RTFIsFragment, StrListCast } from '../../../fields/Doc';
+import { AclPrivate, DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
+import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types';
import { WebField } from '../../../fields/URLField';
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
import { GestureUtils } from '../../../pen-gestures/GestureUtils';
import { DocServer } from '../../DocServer';
import { Networking } from '../../Network';
+import { DocUtils } from '../../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
-import { DocUtils, Docs, DocumentOptions } from '../../documents/Documents';
-import { DragManager, dropActionType } from '../../util/DragManager';
+import { Docs, DocumentOptions } from '../../documents/Documents';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
import { ImageUtils } from '../../util/Import & Export/ImageUtils';
-import { SelectionManager } from '../../util/SelectionManager';
import { SnappingManager } from '../../util/SnappingManager';
import { UndoManager, undoBatch } from '../../util/UndoManager';
import { ViewBoxBaseComponent } from '../DocComponent';
-import { LoadingBox } from '../nodes/LoadingBox';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
-import { CollectionView, CollectionViewProps } from './CollectionView';
+import { FieldViewProps } from '../nodes/FieldView';
+import { DocumentView } from '../nodes/DocumentView';
+
+export interface CollectionViewProps extends React.PropsWithChildren<FieldViewProps> {
+ isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc)
+ isAnnotationOverlayScrollable?: boolean; // whether the annotation overlay can be vertically scrolled (just for tree views, currently)
+ layoutEngine?: () => string;
+ setPreviewCursor?: (func: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => void;
+ ignoreUnrendered?: boolean;
+
+ // property overrides for child documents
+ childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox)
+ childDocumentsActive?: () => boolean | undefined; // whether child documents can be dragged if collection can be dragged (eg., in a when a Pile document is in startburst mode)
+ childContentsActive?: () => boolean | undefined;
+ childLayoutFitWidth?: (child: Doc) => boolean;
+ childlayout_showTitle?: () => string;
+ childOpacity?: () => number;
+ childContextMenuItems?: () => { script: ScriptField; label: string }[];
+ childLayoutTemplate?: () => Doc | undefined; // specify a layout Doc template to use for children of the collection
+ childHideDecorationTitle?: boolean;
+ childHideResizeHandles?: boolean;
+ childDragAction?: dropActionType;
+ childXPadding?: number;
+ childYPadding?: number;
+ childLayoutString?: string;
+ childIgnoreNativeSize?: boolean;
+ childClickScript?: ScriptField;
+ childDoubleClickScript?: ScriptField;
+ AddToMap?: (treeViewDoc: Doc, index: number[]) => void;
+ RemFromMap?: (treeViewDoc: Doc, index: number[]) => void;
+ hierarchyIndex?: number[]; // hierarchical index of a document up to the rendering root (primarily used for tree views)
+}
export interface SubCollectionViewProps extends CollectionViewProps {
isAnyChildContentActive: () => boolean;
}
-export function CollectionSubView<X>(moreProps?: X) {
- class CollectionSubView extends ViewBoxBaseComponent<X & SubCollectionViewProps>() {
+export function CollectionSubView<X>() {
+ class CollectionSubViewInternal extends ViewBoxBaseComponent<X & SubCollectionViewProps>() {
private dropDisposer?: DragManager.DragDropDisposer;
private gestureDisposer?: GestureUtils.GestureEventDisposer;
protected _mainCont?: HTMLDivElement;
@@ -53,7 +84,7 @@ export function CollectionSubView<X>(moreProps?: X) {
}
};
protected CreateDropTarget(ele: HTMLDivElement) {
- //used in schema view
+ // used in schema view
this.createDashEventsTarget(ele);
}
@@ -62,7 +93,7 @@ export function CollectionSubView<X>(moreProps?: X) {
}
get dataDoc() {
- return this._props.TemplateDataDocument instanceof Doc && this.Document.isTemplateForField ? Doc.GetProto(this._props.TemplateDataDocument) : this.Document.resolvedDataDoc ? this.Document : Doc.GetProto(this.Document); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template
+ return this._props.TemplateDataDocument instanceof Doc && this.Document.isTemplateForField ? Doc.GetProto(this._props.TemplateDataDocument) : this.Document.resolvedDataDoc ? this.Document : this.Document[DocData]; // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template
}
get childContainerViewPath() {
@@ -83,10 +114,11 @@ export function CollectionSubView<X>(moreProps?: X) {
const { Document, TemplateDataDocument } = this._props;
const validPairs = this.childDocs
.map(doc => Doc.GetLayoutDataDocPair(Document, !this._props.isAnnotationOverlay ? TemplateDataDocument : undefined, doc))
- .filter(pair => {
- // filter out any documents that have a proto that we don't have permissions to
- return !pair.layout?.hidden && pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));
- });
+ .filter(
+ pair =>
+ // filter out any documents that have a proto that we don't have permissions to
+ !pair.layout?.hidden && pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate))
+ );
return validPairs.map(({ data, layout }) => ({ data: data as Doc, layout: layout! })); // this mapping is a bit of a hack to coerce types
}
@computed get childDocList() {
@@ -95,9 +127,9 @@ export function CollectionSubView<X>(moreProps?: X) {
collectionFilters = () => this._focusFilters ?? StrListCast(this.Document._childFilters);
collectionRangeDocFilters = () => this._focusRangeFilters ?? Cast(this.Document._childFiltersByRanges, listSpec('string'), []);
// child filters apply to the descendants of the documents in this collection
- childDocFilters = () => [...(this._props.childFilters?.().filter(f => Utils.IsRecursiveFilter(f)) || []), ...this.collectionFilters()];
+ childDocFilters = () => [...(this._props.childFilters?.().filter(f => ClientUtils.IsRecursiveFilter(f)) || []), ...this.collectionFilters()];
// unrecursive filters apply to the documents in the collection, but no their children. See Utils.noRecursionHack
- unrecursiveDocFilters = () => [...(this._props.childFilters?.().filter(f => !Utils.IsRecursiveFilter(f)) || [])];
+ unrecursiveDocFilters = () => [...(this._props.childFilters?.().filter(f => !ClientUtils.IsRecursiveFilter(f)) || [])];
childDocRangeFilters = () => [...(this._props.childFiltersByRanges?.() || []), ...this.collectionRangeDocFilters()];
searchFilterDocs = () => this._props.searchFilterDocs?.() ?? DocListCast(this.Document._searchFilterDocs);
@computed.struct get childDocs() {
@@ -129,29 +161,30 @@ export function CollectionSubView<X>(moreProps?: X) {
const docsforFilter: Doc[] = [];
childDocs.forEach(d => {
// dragging facets
- const dragged = this._props.childFilters?.().some(f => f.includes(Utils.noDragDocsFilter));
- if (dragged && SnappingManager.CanEmbed && DragManager.docsBeingDragged.includes(d)) return false;
+ const dragged = this._props.childFilters?.().some(f => f.includes(ClientUtils.noDragDocsFilter));
+ if (dragged && SnappingManager.CanEmbed && DragManager.docsBeingDragged.includes(d)) return;
let notFiltered = d.z || Doc.IsSystem(d) || DocUtils.FilterDocs([d], this.unrecursiveDocFilters(), childFiltersByRanges, this.Document).length > 0;
if (notFiltered) {
notFiltered = (!searchDocs.length || searchDocs.includes(d)) && DocUtils.FilterDocs([d], childDocFilters, childFiltersByRanges, this.Document).length > 0;
const fieldKey = Doc.LayoutFieldKey(d);
- const annos = !Field.toString(Doc.LayoutField(d) as Field).includes(CollectionView.name);
- const data = d[annos ? fieldKey + '_annotations' : fieldKey];
- const side = annos && d[fieldKey + '_sidebar'];
- if (data !== undefined || side !== undefined) {
- let subDocs = [...DocListCast(data), ...DocListCast(side)];
+ const isAnnotatableDoc = d[fieldKey] instanceof List && !(d[fieldKey] as List<Doc>)?.some(ele => !(ele instanceof Doc));
+ const docChildDocs = d[isAnnotatableDoc ? fieldKey + '_annotations' : fieldKey];
+ const sidebarDocs = isAnnotatableDoc && d[fieldKey + '_sidebar'];
+ if (docChildDocs !== undefined || sidebarDocs !== undefined) {
+ let subDocs = [...DocListCast(docChildDocs), ...DocListCast(sidebarDocs)];
if (subDocs.length > 0) {
let newarray: Doc[] = [];
notFiltered = notFiltered || (!searchDocs.length && DocUtils.FilterDocs(subDocs, childDocFilters, childFiltersByRanges, d).length);
while (subDocs.length > 0 && !notFiltered) {
newarray = [];
+ // eslint-disable-next-line no-loop-func
subDocs.forEach(t => {
- const fieldKey = Doc.LayoutFieldKey(t);
- const annos = !Field.toString(Doc.LayoutField(t) as Field).includes(CollectionView.name);
+ const docFieldKey = Doc.LayoutFieldKey(t);
+ const isSubDocAnnotatable = t[docFieldKey] instanceof List && !(t[docFieldKey] as List<Doc>)?.some(ele => !(ele instanceof Doc));
notFiltered =
notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!childDocFilters.length && !childFiltersByRanges.length) || DocUtils.FilterDocs([t], childDocFilters, childFiltersByRanges, d).length));
- DocListCast(t[annos ? fieldKey + '_annotations' : fieldKey]).forEach(newdoc => newarray.push(newdoc));
- annos && DocListCast(t[fieldKey + '_sidebar']).forEach(newdoc => newarray.push(newdoc));
+ DocListCast(t[isSubDocAnnotatable ? docFieldKey + '_annotations' : docFieldKey]).forEach(newdoc => newarray.push(newdoc));
+ isSubDocAnnotatable && DocListCast(t[docFieldKey + '_sidebar']).forEach(newdoc => newarray.push(newdoc));
});
subDocs = newarray;
}
@@ -168,7 +201,7 @@ export function CollectionSubView<X>(moreProps?: X) {
let ind;
const doc = this.Document;
const id = Doc.UserDoc()[Id];
- const email = Doc.CurrentUserEmail;
+ const email = ClientUtils.CurrentUserEmail();
const pos = { x: position[0], y: position[1] };
if (id && email) {
const proto = Doc.GetProto(doc);
@@ -184,6 +217,7 @@ export function CollectionSubView<X>(moreProps?: X) {
if (!cursors) {
proto.cursors = cursors = new List<CursorField>();
}
+ // eslint-disable-next-line no-cond-assign
if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.data.metadata.id === id)) > -1) {
cursors[ind].setPosition(pos);
} else {
@@ -194,27 +228,31 @@ export function CollectionSubView<X>(moreProps?: X) {
}
@undoBatch
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
protected onGesture(e: Event, ge: GestureUtils.GestureEvent) {}
- protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, dropAction: dropActionType) {
- if (de.complete.docDragData) {
- // if the dropEvent's dragAction is, say 'embed', but we're just dragging within a collection, we may not actually want to make an embedding.
- // so we check if our collection has a dropAction set on it and if so, we use that instead.
- if (dropAction && !de.complete.docDragData.draggedDocuments.some(d => d.embedContainer === this.Document && this.childDocs.includes(d))) {
- de.complete.docDragData.dropAction = dropAction;
- }
+ protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, targetDropAction: dropActionType) {
+ const dragData = de.complete.docDragData;
+ if (dragData) {
+ const sourceDragAction = dragData.dropAction;
+ const sameCollection = !dragData.draggedDocuments.some(d => d.embedContainer !== this._props.Document);
+ dragData.dropAction = !sameCollection // if doc from another tree
+ ? sourceDragAction || targetDropAction // then use the source's dragAction otherwise the target's
+ : sourceDragAction === dropActionType.inPlace // if source drag is inPlace
+ ? sourceDragAction // keep the doc in place
+ : dropActionType.same; // otherwise use same tree semantics to move within tree
e.stopPropagation();
}
}
addDocument = (doc: Doc | Doc[], annotationKey?: string) => this._props.addDocument?.(doc, annotationKey) || false;
removeDocument = (doc: Doc | Doc[], annotationKey?: string) => this._props.removeDocument?.(doc, annotationKey) || false;
- moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string) => this._props.moveDocument?.(doc, targetCollection, addDocument) || false;
+ moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean) => this._props.moveDocument?.(doc, targetCollection, addDocument) || false;
protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
- const docDragData = de.complete.docDragData;
+ const { docDragData } = de.complete;
if (docDragData) {
- let added = undefined;
+ let added;
const dropAction = docDragData.dropAction || docDragData.userDropAction;
const targetDocments = DocListCast(this.dataDoc[this._props.fieldKey]);
const someMoved = !dropAction && docDragData.draggedDocuments.some(drag => targetDocments.includes(drag));
@@ -242,8 +280,9 @@ export function CollectionSubView<X>(moreProps?: X) {
}
added === false && !this._props.isAnnotationOverlay && e.preventDefault();
added === true && e.stopPropagation();
- return added ? true : false;
- } else if (de.complete.annoDragData) {
+ return !!added;
+ }
+ if (de.complete.annoDragData) {
const dropCreator = de.complete.annoDragData.dropDocCreator;
de.complete.annoDragData.dropDocCreator = () => {
const dropped = dropCreator(this._props.isAnnotationOverlay ? this.Document : undefined);
@@ -277,10 +316,10 @@ export function CollectionSubView<X>(moreProps?: X) {
const addDocument = (doc: Doc | Doc[]) => this.addDocument(doc);
if (html) {
- if (FormattedTextBox.IsFragment(html)) {
- const href = FormattedTextBox.GetHref(html);
+ if (RTFIsFragment(html)) {
+ const href = GetHrefFromHTML(html);
if (href) {
- const docId = FormattedTextBox.GetDocFromUrl(href);
+ const docId = GetDocFromUrl(href);
if (docId) {
// prosemirror text containing link to dash document
DocServer.GetRefField(docId).then(f => {
@@ -313,7 +352,7 @@ export function CollectionSubView<X>(moreProps?: X) {
const result = (await Networking.PostToServer('/uploadRemoteImage', { sources: [imgSrc] })).lastElement();
const newImgSrc =
result.accessPaths.agnostic.client.indexOf('dashblobstore') === -1 //
- ? Utils.prepend(result.accessPaths.agnostic.client)
+ ? ClientUtils.prepend(result.accessPaths.agnostic.client)
: result.accessPaths.agnostic.client;
addDocument(ImageUtils.AssignImgInfo(Docs.Create.ImageDocument(newImgSrc, imgOpts), result));
@@ -322,39 +361,39 @@ export function CollectionSubView<X>(moreProps?: X) {
addDocument(ImageUtils.AssignImgInfo(doc, await ImageUtils.ExtractImgInfo(doc)));
}
return;
+ }
+ const path = window.location.origin + '/doc/';
+ if (text.startsWith(path)) {
+ const docId = text.replace(Doc.globalServerPath(), '').split('?')[0];
+ DocServer.GetRefField(docId).then(f => {
+ const fDoc = f;
+ if (fDoc instanceof Doc) {
+ if (options.x || options.y) {
+ fDoc.x = options.x as number;
+ fDoc.y = options.y as number;
+ } // should be in CollectionFreeFormView
+ addDocument(fDoc);
+ }
+ });
} else {
- const path = window.location.origin + '/doc/';
- if (text.startsWith(path)) {
- const docId = text.replace(Doc.globalServerPath(), '').split('?')[0];
- DocServer.GetRefField(docId).then(f => {
- if (f instanceof Doc) {
- if (options.x || options.y) {
- f.x = options.x as number;
- f.y = options.y as number;
- } // should be in CollectionFreeFormView
- f instanceof Doc && addDocument(f);
- }
- });
- } else {
- const srcWeb = SelectionManager.Views.lastElement();
- const srcUrl = (srcWeb?.Document.data as WebField)?.url?.href?.match(/https?:\/\/[^/]*/)?.[0];
- const reg = new RegExp(Utils.prepend(''), 'g');
- const modHtml = srcUrl ? html.replace(reg, srcUrl) : html;
- const backgroundColor = tags.map(tag => tag.match(/.*(background-color: ?[^;]*)/)?.[1]?.replace(/background-color: ?(.*)/, '$1')).filter(t => t)?.[0];
- const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: srcUrl ? 'from:' + srcUrl : '-web clip-', _width: 300, _height: 300, backgroundColor });
- Doc.GetProto(htmlDoc)['data-text'] = Doc.GetProto(htmlDoc).text = text;
- addDocument(htmlDoc);
- if (srcWeb) {
- const iframe = SelectionManager.Views[0].ContentDiv?.getElementsByTagName('iframe')?.[0];
- const focusNode = iframe?.contentDocument?.getSelection()?.focusNode as any;
- if (focusNode) {
- const anchor = srcWeb?.ComponentView?.getAnchor?.(true);
- anchor && DocUtils.MakeLink(htmlDoc, anchor, {});
- }
+ const srcWeb = DocumentView.Selected().lastElement();
+ const srcUrl = (srcWeb?.Document.data as WebField)?.url?.href?.match(/https?:\/\/[^/]*/)?.[0];
+ const reg = new RegExp(ClientUtils.prepend(''), 'g');
+ const modHtml = srcUrl ? html.replace(reg, srcUrl) : html;
+ const backgroundColor = tags.map(tag => tag.match(/.*(background-color: ?[^;]*)/)?.[1]?.replace(/background-color: ?(.*)/, '$1')).filter(t => t)?.[0];
+ const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: srcUrl ? 'from:' + srcUrl : '-web clip-', _width: 300, _height: 300, backgroundColor });
+ Doc.GetProto(htmlDoc)['data-text'] = Doc.GetProto(htmlDoc).text = text;
+ addDocument(htmlDoc);
+ if (srcWeb) {
+ const iframe = DocumentView.Selected()[0].ContentDiv?.getElementsByTagName('iframe')?.[0];
+ const focusNode = iframe?.contentDocument?.getSelection()?.focusNode as any;
+ if (focusNode) {
+ const anchor = srcWeb?.ComponentView?.getAnchor?.(true);
+ anchor && DocUtils.MakeLink(htmlDoc, anchor, {});
}
}
- return;
}
+ return;
}
}
@@ -411,10 +450,15 @@ export function CollectionSubView<X>(moreProps?: X) {
for (let i = 0; i < length; i++) {
const item = e.dataTransfer.items[i];
if (item.kind === 'string' && item.type.includes('uri')) {
- const stringContents = await new Promise<string>(resolve => item.getAsString(resolve));
- const type = (await rp.head(Utils.CorsProxy(stringContents)))['content-type'];
+ // eslint-disable-next-line no-await-in-loop
+ const stringContents = await new Promise<string>(resolve => {
+ item.getAsString(resolve);
+ });
+ // eslint-disable-next-line no-await-in-loop
+ const type = (await rp.head(ClientUtils.CorsProxy(stringContents)))['content-type'];
if (type) {
- const doc = await DocUtils.DocumentFromType(type, Utils.CorsProxy(stringContents), options);
+ // eslint-disable-next-line no-await-in-loop
+ const doc = await DocUtils.DocumentFromType(type, ClientUtils.CorsProxy(stringContents), options);
doc && generatedDocuments.push(doc);
}
}
@@ -423,7 +467,7 @@ export function CollectionSubView<X>(moreProps?: X) {
file?.type && files.push(file);
file?.type === 'application/json' &&
- Utils.readUploadedFileAsText(file).then(result => {
+ ClientUtils.readUploadedFileAsText(file).then(result => {
const json = JSON.parse(result as string);
addDocument(
Docs.Create.TreeDocument(
@@ -447,17 +491,17 @@ export function CollectionSubView<X>(moreProps?: X) {
// create placeholder docs
// inside placeholder docs have some func that
- let pileUpDoc = undefined;
+ let pileUpDoc;
if (typeof files === 'string') {
const loading = Docs.Create.LoadingDocument(files, options);
generatedDocuments.push(loading);
- LoadingBox.addCurrentlyLoading(loading);
+ Doc.addCurrentlyLoading(loading);
DocUtils.uploadYoutubeVideoLoading(files, {}, loading);
} else {
generatedDocuments.push(
...files.map(file => {
const loading = Docs.Create.LoadingDocument(file, options);
- LoadingBox.addCurrentlyLoading(loading);
+ Doc.addCurrentlyLoading(loading);
DocUtils.uploadFileToDoc(file, {}, loading);
return loading;
})
@@ -475,23 +519,19 @@ export function CollectionSubView<X>(moreProps?: X) {
})
: [];
if (completed) completed(set);
- else {
- if (isFreeformView && generatedDocuments.length > 1) {
- pileUpDoc = DocUtils.pileup(generatedDocuments, options.x as number, options.y as number)!;
- addDocument(pileUpDoc);
- } else {
- generatedDocuments.forEach(addDocument);
- }
- }
- } else {
- if (text && !text.includes('https://')) {
- addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 }));
+ else if (isFreeformView && generatedDocuments.length > 1) {
+ pileUpDoc = DocUtils.pileup(generatedDocuments, options.x as number, options.y as number)!;
+ addDocument(pileUpDoc);
} else {
- alert('Document upload failed - possibly an unsupported file type.');
+ generatedDocuments.forEach(addDocument);
}
+ } else if (text && !text.includes('https://')) {
+ addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 }));
+ } else {
+ alert('Document upload failed - possibly an unsupported file type.');
}
};
}
- return CollectionSubView;
+ return CollectionSubViewInternal;
}
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index b92edd165..0369e4a2a 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -1,7 +1,10 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils';
+import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { Doc, Opt, StrListCast } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
@@ -9,14 +12,12 @@ import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { Docs } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { FieldsDropdown } from '../FieldsDropdown';
+import { PinDocView } from '../PinFuncs';
import { DocumentView } from '../nodes/DocumentView';
-import { FocusViewOptions } from '../nodes/FieldView';
-import { PresBox } from '../nodes/trails';
import { CollectionSubView } from './CollectionSubView';
import './CollectionTimeView.scss';
import { ViewDefBounds, computePivotLayout, computeTimelineLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
@@ -49,11 +50,11 @@ export class CollectionTimeView extends CollectionSubView() {
}
getAnchor = (addAsAnnotation: boolean) => {
- const anchor = Docs.Create.HTMLMarkerDocument([], {
+ const anchor = Docs.Create.ConfigDocument({
title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as any,
annotationOn: this.Document,
});
- PresBox.pinDocView(anchor, { pinData: { type_collection: true, pivot: true, filters: true } }, this.Document);
+ PinDocView(anchor, { pinData: { type_collection: true, pivot: true, filters: true } }, this.Document);
if (addAsAnnotation) {
// when added as an annotation, links to anchors can be found as links to the document even if the anchors are not rendered
@@ -67,7 +68,7 @@ export class CollectionTimeView extends CollectionSubView() {
};
@action
- scrollPreview = (docView: DocumentView, anchor: Doc, focusSpeed: number, options: FocusViewOptions) => {
+ scrollPreview = (docView: DocumentView, anchor: Doc /* , focusSpeed: number, options: FocusViewOptions */) => {
// if in preview, then override document's fields with view spec
this._focusFilters = StrListCast(anchor.config_docFilters);
this._focusRangeFilters = StrListCast(anchor.config_docRangeFilters);
@@ -76,13 +77,15 @@ export class CollectionTimeView extends CollectionSubView() {
};
layoutEngine = () => this._layoutEngine;
- toggleVisibility = action(() => (this._collapsed = !this._collapsed));
+ toggleVisibility = action(() => {
+ this._collapsed = !this._collapsed;
+ });
onMinDown = (e: React.PointerEvent) => {
setupMoveUpEvents(
this,
e,
- action((e: PointerEvent, down: number[], delta: number[]) => {
+ action((moveEv: PointerEvent, down: number[], delta: number[]) => {
const minReq = NumCast(this.Document[this._props.fieldKey + '-timelineMinReq'], NumCast(this.Document[this._props.fieldKey + '-timelineMin'], 0));
const maxReq = NumCast(this.Document[this._props.fieldKey + '-timelineMaxReq'], NumCast(this.Document[this._props.fieldKey + '-timelineMax'], 10));
this.Document[this._props.fieldKey + '-timelineMinReq'] = minReq + ((maxReq - minReq) * delta[0]) / this._props.PanelWidth();
@@ -98,7 +101,7 @@ export class CollectionTimeView extends CollectionSubView() {
setupMoveUpEvents(
this,
e,
- action((e: PointerEvent, down: number[], delta: number[]) => {
+ action((moveEv, down: number[], delta: number[]) => {
const minReq = NumCast(this.Document[this._props.fieldKey + '-timelineMinReq'], NumCast(this.Document[this._props.fieldKey + '-timelineMin'], 0));
const maxReq = NumCast(this.Document[this._props.fieldKey + '-timelineMaxReq'], NumCast(this.Document[this._props.fieldKey + '-timelineMax'], 10));
this.Document[this._props.fieldKey + '-timelineMaxReq'] = maxReq + ((maxReq - minReq) * delta[0]) / this._props.PanelWidth();
@@ -113,7 +116,7 @@ export class CollectionTimeView extends CollectionSubView() {
setupMoveUpEvents(
this,
e,
- action((e: PointerEvent, down: number[], delta: number[]) => {
+ action((moveEv: PointerEvent, down: number[], delta: number[]) => {
const minReq = NumCast(this.Document[this._props.fieldKey + '-timelineMinReq'], NumCast(this.Document[this._props.fieldKey + '-timelineMin'], 0));
const maxReq = NumCast(this.Document[this._props.fieldKey + '-timelineMaxReq'], NumCast(this.Document[this._props.fieldKey + '-timelineMax'], 10));
this.Document[this._props.fieldKey + '-timelineMinReq'] = minReq - ((maxReq - minReq) * delta[0]) / this._props.PanelWidth();
@@ -133,7 +136,7 @@ export class CollectionTimeView extends CollectionSubView() {
};
@action
- contentsDown = (e: React.MouseEvent) => {
+ contentsDown = () => {
const prevFilterIndex = NumCast(this.layoutDoc._prevFilterIndex);
if (prevFilterIndex > 0) {
this.goTo(prevFilterIndex - 1);
@@ -146,6 +149,7 @@ export class CollectionTimeView extends CollectionSubView() {
return (
<div className="collectionTimeView-innards" key="timeline" style={{ pointerEvents: this._props.isContentActive() ? undefined : 'none' }} onClick={this.contentsDown}>
<CollectionFreeFormView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
engineProps={{ pivotField: this.pivotField, childFilters: this.childDocFilters, childFiltersByRanges: this.childDocRangeFilters }}
fitContentsToBox={returnTrue}
@@ -161,7 +165,7 @@ export class CollectionTimeView extends CollectionSubView() {
const fieldKey = Doc.LayoutFieldKey(doc);
doc[fieldKey + '-timelineCur'] = ComputedField.MakeFunction("(activePresentationItem()[this._pivotField || 'year'] || 0)");
}
- specificMenu = (e: React.MouseEvent) => {
+ specificMenu = () => {
const layoutItems: ContextMenuProps[] = [];
const doc = this.layoutDoc;
@@ -193,9 +197,9 @@ export class CollectionTimeView extends CollectionSubView() {
render() {
let nonNumbers = 0;
- this.childDocs.map(doc => {
+ this.childDocs.forEach(doc => {
const num = NumCast(doc[this.pivotField], Number(StrCast(doc[this.pivotField])));
- if (Number.isNaN(num)) {
+ if (isNaN(num)) {
nonNumbers++;
}
});
@@ -225,13 +229,20 @@ export class CollectionTimeView extends CollectionSubView() {
</>
)}
<div style={{ right: 0, top: 0, position: 'absolute' }}>
- <FieldsDropdown Document={this.Document} selectFunc={fieldKey => (this.layoutDoc._pivotField = fieldKey)} placeholder={StrCast(this.layoutDoc._pivotField)} />
+ <FieldsDropdown
+ Document={this.Document}
+ selectFunc={fieldKey => {
+ this.layoutDoc._pivotField = fieldKey;
+ }}
+ placeholder={StrCast(this.layoutDoc._pivotField)}
+ />
</div>
</div>
);
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function pivotColumnClick(pivotDoc: Doc, bounds: ViewDefBounds) {
const pivotField = StrCast(pivotDoc._pivotField, 'author');
let prevFilterIndex = NumCast(pivotDoc._prevFilterIndex);
@@ -245,9 +256,10 @@ ScriptingGlobals.add(function pivotColumnClick(pivotDoc: Doc, bounds: ViewDefBou
action(() => {
const filterVals = bounds.payload as string[];
filterVals.map(filterVal => Doc.setDocFilter(pivotDoc, pivotField, filterVal, 'check'));
- const pivotView = DocumentManager.Instance.getDocumentView(pivotDoc);
+ const pivotView = DocumentView.getDocumentView(pivotDoc);
if (pivotDoc && pivotView?.ComponentView instanceof CollectionTimeView && filterVals.length === 1) {
if (pivotView?.ComponentView.childDocs.length && pivotView.ComponentView.childDocs[0][filterVals[0]]) {
+ // eslint-disable-next-line prefer-destructuring
pivotDoc._pivotField = filterVals[0];
}
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 3b37bdcfa..c39df2c76 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,18 +1,22 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { DivHeight, returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero } from '../../../ClientUtils';
import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { listSpec } from '../../../fields/Schema';
import { ScriptField } from '../../../fields/ScriptField';
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast, toList } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { DivHeight, emptyFunction, returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../util/DragManager';
-import { SelectionManager } from '../../util/SelectionManager';
+import { emptyFunction, Utils } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
+import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch, UndoManager } from '../../util/UndoManager';
@@ -20,14 +24,14 @@ import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { EditableView } from '../EditableView';
import { DocumentView } from '../nodes/DocumentView';
-import { FieldViewProps } from '../nodes/FieldView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
-import { StyleProp } from '../StyleProvider';
+import { StyleProp } from '../StyleProp';
import { CollectionFreeFormView } from './collectionFreeForm';
import { CollectionSubView } from './CollectionSubView';
import './CollectionTreeView.scss';
+import { TreeViewType } from './CollectionTreeViewType';
import { TreeView } from './TreeView';
-import { ScriptingGlobals } from '../../util/ScriptingGlobals';
+
const _global = (window /* browser */ || global) /* node */ as any;
export type collectionTreeViewProps = {
@@ -44,12 +48,6 @@ export type collectionTreeViewProps = {
hierarchyIndex?: number[];
};
-export enum TreeViewType {
- outline = 'outline',
- fileSystem = 'fileSystem',
- default = 'default',
-}
-
@observer
export class CollectionTreeView extends CollectionSubView<Partial<collectionTreeViewProps>>() {
public static AddTreeFunc = 'addTreeFolder(this.embedContainer)';
@@ -66,9 +64,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
makeObservable(this);
}
- get dataDoc() {
- return this._props.TemplateDataDocument || this.Document;
- }
@computed get treeViewtruncateTitleWidth() {
return NumCast(this.Document.treeView_TruncateTitleWidth, this.panelWidth());
}
@@ -92,8 +87,10 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
// these should stay in synch with counterparts in DocComponent.ts ViewBoxAnnotatableComponent
@observable _isAnyChildContentActive = false;
- whenChildContentsActiveChanged = action((isActive: boolean) => this._props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive)));
- isContentActive = (outsideReaction?: boolean) => (this._isAnyChildContentActive ? true : this._props.isContentActive() ? true : false);
+ whenChildContentsActiveChanged = action((isActive: boolean) => {
+ this._props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive));
+ });
+ isContentActive = () => (this._isAnyChildContentActive ? true : !!this._props.isContentActive());
componentWillUnmount() {
this._isDisposing = true;
@@ -103,7 +100,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
}
componentDidMount() {
- //this._props.setContentView?.(this);
+ // this._props.setContentView?.(this);
this._disposers.autoheight = reaction(
() => this.layoutDoc.layout_autoHeight,
auto => auto && this.computeHeight(),
@@ -126,20 +123,19 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
observeHeight = (ref: any) => {
if (ref) {
this.refList.add(ref);
- this.observer = new _global.ResizeObserver(
- action((entries: any) => {
- if (this.layoutDoc.layout_autoHeight && ref && this.refList.size && !SnappingManager.IsDragging) {
- this.computeHeight();
- }
- })
- );
+ this.observer = new _global.ResizeObserver(() => {
+ if (this.layoutDoc.layout_autoHeight && ref && this.refList.size && !SnappingManager.IsDragging) {
+ this.computeHeight();
+ }
+ });
this.layoutDoc.layout_autoHeight && this.computeHeight();
this.observer.observe(ref);
}
};
protected createTreeDropTarget = (ele: HTMLDivElement) => {
this._treedropDisposer?.();
- if ((this._mainEle = ele)) this._treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.Document, this.onInternalPreDrop.bind(this));
+ this._mainEle = ele;
+ if (ele) this._treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.Document, this.onInternalPreDrop.bind(this));
};
protected onInternalDrop(e: Event, de: DragManager.DropEvent) {
@@ -157,51 +153,49 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
const dragData = de.complete.docDragData;
if (dragData) {
const sourceDragAction = dragData.dropAction;
- const sameTree = () => Doc.AreProtosEqual(dragData.treeViewDoc, this.Document);
- const isAlreadyInTree = () => sameTree || dragData.draggedDocuments.some(d => d.embedContainer === this.Document && this.childDocs.includes(d));
- dragData.dropAction =
- targetDropAction && !isAlreadyInTree() // if dropped document is not in the tree
- ? targetDropAction // then use the target's drop action if it's specified
- : !sameTree() || sourceDragAction === dropActionType.inPlace // if doc from another tree, or a non inPlace source drag action is specified
- ? sourceDragAction // use the source dragAction
- : dropActionType.same; // otherwise use same tree semantics to move within tree
+ const sameTree = dragData.treeViewDoc?.[DocData] === this.dataDoc;
+ dragData.dropAction = !sameTree // if doc from another tree
+ ? sourceDragAction || targetDropAction // then use the source's dragAction otherwise the target's
+ : sourceDragAction === dropActionType.inPlace // if source drag is inPlace
+ ? sourceDragAction // keep the doc in place
+ : dropActionType.same; // otherwise use same tree semantics to move within tree
e.stopPropagation();
}
};
- dragConfig = (dragData: DragManager.DocumentDragData) => (dragData.treeViewDoc = this.Document);
+ dragConfig = (dragData: DragManager.DocumentDragData) => { dragData.treeViewDoc = this.Document; }; // prettier-ignore
screenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, -this._headerHeight);
@action
- remove = (doc: Doc | Doc[]): boolean => {
- const docs = doc instanceof Doc ? [doc] : doc;
+ remove = (docIn: Doc | Doc[]): boolean => {
+ const docs = toList(docIn);
const targetDataDoc = this.Document[DocData];
const value = DocListCast(targetDataDoc[this._props.fieldKey]);
const result = value.filter(v => !docs.includes(v));
- if ((doc instanceof Doc ? [doc] : doc).some(doc => SelectionManager.Views.some(dv => Doc.AreProtosEqual(dv.Document, doc)))) SelectionManager.DeselectAll();
+ if (docs.some(doc => DocumentView.Selected().some(dv => Doc.AreProtosEqual(dv.Document, doc)))) DocumentView.DeselectAll();
if (result.length !== value.length) {
- if (doc instanceof Doc) {
- const ind = DocListCast(targetDataDoc[this._props.fieldKey]).indexOf(doc);
+ if (docIn instanceof Doc) {
+ const ind = DocListCast(targetDataDoc[this._props.fieldKey]).indexOf(docIn);
const prev = ind && DocListCast(targetDataDoc[this._props.fieldKey])[ind - 1];
- this._props.removeDocument?.(doc);
+ this._props.removeDocument?.(docIn);
if (ind > 0 && prev) {
- FormattedTextBox.SetSelectOnLoad(prev);
- DocumentManager.Instance.getDocumentView(prev, this.DocumentView?.())?.select(false);
+ Doc.SetSelectOnLoad(prev);
+ DocumentView.getDocumentView(prev, this.DocumentView?.())?.select(false);
}
return true;
}
- return this._props.removeDocument?.(doc) ?? false;
+ return this._props.removeDocument?.(docIn) ?? false;
}
return false;
};
@action
addDoc = (docs: Doc | Doc[], relativeTo: Opt<Doc>, before?: boolean): boolean => {
- const doclist = docs instanceof Doc ? [docs] : docs;
- const addDocRelativeTo = (doc: Doc | Doc[]) => doclist.reduce((flg, doc) => flg && Doc.AddDocToList(this.Document[DocData], this._props.fieldKey, doc, relativeTo, before), true);
+ const addDocRelativeTo = (adocs: Doc | Doc[]) => (adocs as Doc[]).reduce((flg, doc) => flg && Doc.AddDocToList(this.Document[DocData], this._props.fieldKey, doc, relativeTo, before), true);
if (this.Document.resolvedDataDoc instanceof Promise) return false;
- const res = relativeTo === undefined ? this._props.addDocument?.(docs) || false : addDocRelativeTo(docs);
+ const doclist = toList(docs);
+ const res = relativeTo === undefined ? this._props.addDocument?.(doclist) || false : addDocRelativeTo(doclist);
res &&
doclist.forEach(doc => {
Doc.SetContainer(doc, this.Document);
@@ -209,19 +203,19 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
});
return res;
};
- onContextMenu = (e: React.MouseEvent): void => {
+ onContextMenu = (): void => {
// need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
const layoutItems: ContextMenuProps[] = [];
- const menuDoc = ScriptCast(Cast(this.layoutDoc.layout_headerButton, Doc, null)?.onClick).script.originalScript === CollectionTreeView.AddTreeFunc;
+ const menuDoc = ScriptCast(Cast(this.layoutDoc.layout_headerButton, Doc, null)?.onClick)?.script.originalScript === CollectionTreeView.AddTreeFunc;
menuDoc && layoutItems.push({ description: 'Create new folder', event: () => CollectionTreeView.addTreeFolder(this.Document), icon: 'paint-brush' });
if (!Doc.noviceMode) {
layoutItems.push({
description: 'Make tree state ' + (this.Document.treeView_OpenIsTransient ? 'persistent' : 'transient'),
- event: () => (this.Document.treeView_OpenIsTransient = !this.Document.treeView_OpenIsTransient),
+ event: () => { this.Document.treeView_OpenIsTransient = !this.Document.treeView_OpenIsTransient; }, // prettier-ignore
icon: 'paint-brush',
});
- layoutItems.push({ description: (this.Document.treeView_HideHeaderFields ? 'Show' : 'Hide') + ' Header Fields', event: () => (this.Document.treeView_HideHeaderFields = !this.Document.treeView_HideHeaderFields), icon: 'paint-brush' });
- layoutItems.push({ description: (this.Document.treeView_HideTitle ? 'Show' : 'Hide') + ' Title', event: () => (this.Document.treeView_HideTitle = !this.Document.treeView_HideTitle), icon: 'paint-brush' });
+ layoutItems.push({ description: (this.Document.treeView_HideHeaderFields ? 'Show' : 'Hide') + ' Header Fields', event: () => { this.Document.treeView_HideHeaderFields = !this.Document.treeView_HideHeaderFields; }, icon: 'paint-brush' }); // prettier-ignore
+ layoutItems.push({ description: (this.Document.treeView_HideTitle ? 'Show' : 'Hide') + ' Title', event: () => { this.Document.treeView_HideTitle = !this.Document.treeView_HideTitle; }, icon: 'paint-brush' }); // prettier-ignore
}
ContextMenu.Instance.addItem({ description: 'Options...', subitems: layoutItems, icon: 'eye' });
if (!Doc.noviceMode) {
@@ -240,9 +234,9 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
return (
<EditableView
contents={this.dataDoc.title}
- display={'block'}
+ display="block"
maxHeight={72}
- height={'auto'}
+ height="auto"
GetValue={() => StrCast(this.dataDoc.title)}
SetValue={undoBatch((value: string, shift: boolean, enter: boolean) => {
if (enter && this.Document.treeView_Type === TreeViewType.outline) this.makeTextCollection(this.treeChildren);
@@ -253,22 +247,24 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
);
}
- onKey = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
+ onKey = (e: React.KeyboardEvent /* , fieldProps: FieldViewProps */) => {
if (this.outlineMode && e.key === 'Enter') {
e.stopPropagation();
this.makeTextCollection(this.treeChildren);
return true;
}
+ return undefined;
};
get documentTitle() {
return (
<FormattedTextBox
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
fieldKey="text"
renderDepth={this._props.renderDepth + 1}
isContentActive={this.isContentActive}
isDocumentActive={this.isContentActive}
- forceAutoHeight={true} // needed to make the title resize even if the rest of the tree view is not layout_autoHeight
+ forceAutoHeight // needed to make the title resize even if the rest of the tree view is not layout_autoHeight
PanelWidth={this.documentTitleWidth}
PanelHeight={this.documentTitleHeight}
NativeDimScaling={returnOne}
@@ -294,9 +290,14 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
@computed get treeViewElements() {
TraceMobx();
const dragAction = StrCast(this.Document.childDragAction) as any as dropActionType;
- const addDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before);
+ const treeAddDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before);
const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this._props.moveDocument?.(d, target, addDoc) || false;
- if (this._renderCount < this.treeChildren.length) setTimeout(action(() => (this._renderCount = Math.min(this.treeChildren.length, this._renderCount + 20))));
+ if (this._renderCount < this.treeChildren.length)
+ setTimeout(
+ action(() => {
+ this._renderCount = Math.min(this.treeChildren.length, this._renderCount + 20);
+ })
+ );
return TreeView.GetChildElements(
this.treeChildren,
this,
@@ -305,7 +306,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
this._props.TemplateDataDocument,
undefined,
undefined,
- addDoc,
+ treeAddDoc,
this.remove,
moveDoc,
dragAction,
@@ -326,7 +327,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
this.observeHeight,
this.unobserveHeight,
this.childContextMenuItems(),
- //TODO: [AL] add these
this._props.AddToMap,
this._props.RemFromMap,
this._props.hierarchyIndex,
@@ -337,7 +337,9 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
return this.dataDoc === null ? null : (
<div
className="collectionTreeView-titleBar"
- ref={action((r: any) => (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this.ScreenToLocalBoxXf().Scale))}
+ ref={action((r: any) => {
+ (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this.ScreenToLocalBoxXf().Scale);
+ })}
key={this.Document[Id]}
style={!this.outlineMode ? { marginLeft: this.marginX(), paddingTop: this.marginTop() } : {}}>
{this.outlineMode ? this.documentTitle : this.editableTitle}
@@ -408,8 +410,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
addAnnotationDocument = (doc: Doc | Doc[]) => this.addDocument(doc, `${this._props.fieldKey}_annotations`) || false;
remAnnotationDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, `${this._props.fieldKey}_annotations`) || false;
- moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) =>
- this.moveDocument(doc, targetCollection, addDocument, `${this._props.fieldKey}_annotations`) || false;
+ moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => this.moveDocument(doc, targetCollection, addDocument) || false;
@observable _headerHeight = 0;
@computed get content() {
@@ -420,7 +421,11 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
return (
<div style={{ display: 'flex', flexDirection: 'column', height: '100%', pointerEvents: 'all' }}>
{!this.buttonMenu && !this.noviceExplainer ? null : (
- <div className="documentButtonMenu" ref={action((r: HTMLDivElement | null) => r && (this._headerHeight = DivHeight(r)))}>
+ <div
+ className="documentButtonMenu"
+ ref={action((r: HTMLDivElement | null) => {
+ r && (this._headerHeight = DivHeight(r));
+ })}>
{this.buttonMenu}
{this.noviceExplainer}
</div>
@@ -453,7 +458,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
minHeight: '100%',
}}
onWheel={e => e.stopPropagation()}
- onClick={e => (!this.layoutDoc.forceActive ? this._props.select(false) : SelectionManager.DeselectAll())}
+ onClick={() => (!this.layoutDoc.forceActive ? this._props.select(false) : DocumentView.DeselectAll())}
onDrop={this.onTreeDrop}>
<ul className={`no-indent${this.outlineMode ? '-outline' : ''}`}>{this.treeViewElements}</ul>
</div>
@@ -470,13 +475,14 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
<div style={{ transform: `scale(${scale})`, transformOrigin: 'top left', width: `${100 / scale}%`, height: `${100 / scale}%` }}>
{!(this.Document instanceof Doc) || !this.treeChildren ? null : this.Document.treeView_HasOverlay ? (
<CollectionFreeFormView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setContentViewBox={emptyFunction}
NativeWidth={returnZero}
NativeHeight={returnZero}
pointerEvents={this._props.isContentActive() && SnappingManager.IsDragging ? returnAll : returnNone}
- isAnnotationOverlay={true}
- isAnnotationOverlayScrollable={true}
+ isAnnotationOverlay
+ isAnnotationOverlayScrollable
childDocumentsActive={this._props.isContentActive}
fieldKey={this._props.fieldKey + '_annotations'}
dropAction={dropActionType.move}
@@ -500,6 +506,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function addTreeFolder(doc: Doc) {
CollectionTreeView.addTreeFolder(doc);
});
diff --git a/src/client/views/collections/CollectionTreeViewType.ts b/src/client/views/collections/CollectionTreeViewType.ts
new file mode 100644
index 000000000..53b88160e
--- /dev/null
+++ b/src/client/views/collections/CollectionTreeViewType.ts
@@ -0,0 +1,5 @@
+export enum TreeViewType {
+ outline = 'outline',
+ fileSystem = 'fileSystem',
+ default = 'default',
+}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 2f0f2a773..d084a2aec 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -1,21 +1,21 @@
+/* eslint-disable react/jsx-props-no-spreading */
import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { returnEmptyString } from '../../../Utils';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { returnEmptyString } from '../../../ClientUtils';
+import { Doc, DocListCast } from '../../../fields/Doc';
import { ObjectField } from '../../../fields/ObjectField';
-import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { CollectionViewType } from '../../documents/DocumentTypes';
-import { DocUtils } from '../../documents/Documents';
-import { dropActionType } from '../../util/DragManager';
+import { DocUtils } from '../../documents/DocUtils';
+import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
import { ImageUtils } from '../../util/Import & Export/ImageUtils';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
-import { OpenWhere } from '../nodes/DocumentView';
-import { FieldView, FieldViewProps } from '../nodes/FieldView';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { FieldView } from '../nodes/FieldView';
+import { OpenWhere } from '../nodes/OpenWhere';
import { CollectionCalendarView } from './CollectionCalendarView';
import { CollectionCarousel3DView } from './CollectionCarousel3DView';
import { CollectionCarouselView } from './CollectionCarouselView';
@@ -23,7 +23,7 @@ import { CollectionDockingView } from './CollectionDockingView';
import { CollectionNoteTakingView } from './CollectionNoteTakingView';
import { CollectionPileView } from './CollectionPileView';
import { CollectionStackingView } from './CollectionStackingView';
-import { SubCollectionViewProps } from './CollectionSubView';
+import { CollectionViewProps, SubCollectionViewProps } from './CollectionSubView';
import { CollectionTimeView } from './CollectionTimeView';
import { CollectionTreeView } from './CollectionTreeView';
import './CollectionView.scss';
@@ -33,38 +33,10 @@ import { CollectionLinearView } from './collectionLinear';
import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView';
import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView';
import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView';
-export interface CollectionViewProps extends React.PropsWithChildren<FieldViewProps> {
- isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc)
- isAnnotationOverlayScrollable?: boolean; // whether the annotation overlay can be vertically scrolled (just for tree views, currently)
- layoutEngine?: () => string;
- setPreviewCursor?: (func: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => void;
- ignoreUnrendered?: boolean;
+import { CollectionCardView } from './CollectionCardDeckView';
- // property overrides for child documents
- childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox)
- childDocumentsActive?: () => boolean | undefined; // whether child documents can be dragged if collection can be dragged (eg., in a when a Pile document is in startburst mode)
- childContentsActive?: () => boolean | undefined;
- childLayoutFitWidth?: (child: Doc) => boolean;
- childlayout_showTitle?: () => string;
- childOpacity?: () => number;
- childContextMenuItems?: () => { script: ScriptField; label: string }[];
- childLayoutTemplate?: () => Doc | undefined; // specify a layout Doc template to use for children of the collection
- childHideDecorationTitle?: boolean;
- childHideResizeHandles?: boolean;
- childDragAction?: dropActionType;
- childXPadding?: number;
- childYPadding?: number;
- childLayoutString?: string;
- childIgnoreNativeSize?: boolean;
- childClickScript?: ScriptField;
- childDoubleClickScript?: ScriptField;
- //TODO: [AL] add these fields
- AddToMap?: (treeViewDoc: Doc, index: number[]) => void;
- RemFromMap?: (treeViewDoc: Doc, index: number[]) => void;
- hierarchyIndex?: number[]; // hierarchical index of a document up to the rendering root (primarily used for tree views)
-}
@observer
-export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewProps>() implements ViewBoxInterface {
+export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewProps>() {
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(CollectionView, fieldStr);
}
@@ -90,7 +62,9 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
// this a reaction, downstream invalidations only occur when the reaction value actually changes.
this.reactionDisposer = reaction(
() => (this.isAnyChildContentActive() ? true : this._props.isContentActive()),
- active => (this._isContentActive = active),
+ active => {
+ this._isContentActive = active;
+ },
{ fireImmediately: true }
);
}
@@ -99,17 +73,16 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
}
get collectionViewType(): CollectionViewType | undefined {
- const viewField = StrCast(this.layoutDoc._type_collection);
+ const viewField = StrCast(this.layoutDoc._type_collection) as any as CollectionViewType;
if (CollectionView._safeMode) {
- switch (viewField) {
+ switch (viewField) {
case CollectionViewType.Freeform:
- case CollectionViewType.Schema:
- return CollectionViewType.Tree;
- case CollectionViewType.Invalid:
- return CollectionViewType.Freeform;
- }
+ case CollectionViewType.Schema: return CollectionViewType.Tree;
+ case CollectionViewType.Invalid: return CollectionViewType.Freeform;
+ default:
+ } // prettier-ignore
}
- return viewField as any as CollectionViewType;
+ return viewField;
}
screenToLocalTransform = () => (this._props.renderDepth ? this.ScreenToLocalBoxXf() : this.ScreenToLocalBoxXf().scale(this._props.PanelWidth() / this.bodyPanelWidth()));
@@ -118,8 +91,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
TraceMobx();
if (type === undefined) return null;
switch (type) {
- default:
- case CollectionViewType.Freeform: return <CollectionFreeFormView key="collview" {...props} />;
case CollectionViewType.Schema: return <CollectionSchemaView key="collview" {...props} />;
case CollectionViewType.Calendar: return <CollectionCalendarView key="collview" {...props} />;
case CollectionViewType.Docking: return <CollectionDockingView key="collview" {...props} />;
@@ -135,6 +106,9 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
case CollectionViewType.Masonry: return <CollectionStackingView key="collview" {...props} />;
case CollectionViewType.Time: return <CollectionTimeView key="collview" {...props} />;
case CollectionViewType.Grid: return <CollectionGridView key="collview" {...props} />;
+ case CollectionViewType.Card: return <CollectionCardView key="collview" {...props} />;
+ case CollectionViewType.Freeform:
+ default: return <CollectionFreeFormView key="collview" {...props} />;
}
};
@@ -145,9 +119,9 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
{ description: 'Freeform', event: () => func(CollectionViewType.Freeform), icon: 'signature' },
{ description: 'Schema', event: () => func(CollectionViewType.Schema), icon: 'th-list' },
{ description: 'Tree', event: () => func(CollectionViewType.Tree), icon: 'tree' },
- { description: 'Stacking', event: () => (func(CollectionViewType.Stacking)._layout_autoHeight = true), icon: 'ellipsis-v' },
+ { description: 'Stacking', event: () => {func(CollectionViewType.Stacking)._layout_autoHeight = true}, icon: 'ellipsis-v' },
{ description: 'Calendar', event: () => func(CollectionViewType.Calendar), icon: 'columns'},
- { description: 'Notetaking', event: () => (func(CollectionViewType.NoteTaking)._layout_autoHeight = true), icon: 'ellipsis-v' },
+ { description: 'Notetaking', event: () => {func(CollectionViewType.NoteTaking)._layout_autoHeight = true}, icon: 'ellipsis-v' },
{ description: 'Multicolumn', event: () => func(CollectionViewType.Multicolumn), icon: 'columns' },
{ description: 'Multirow', event: () => func(CollectionViewType.Multirow), icon: 'columns' },
{ description: 'Masonry', event: () => func(CollectionViewType.Masonry), icon: 'columns' },
@@ -192,14 +166,14 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
const options = cm.findByDescription('Options...');
const optionItems = options && 'subitems' in options ? options.subitems : [];
- !Doc.noviceMode ? optionItems.splice(0, 0, { description: `${this.Document.forceActive ? 'Select' : 'Force'} Contents Active`, event: () => (this.Document.forceActive = !this.Document.forceActive), icon: 'project-diagram' }) : null;
+ !Doc.noviceMode ? optionItems.splice(0, 0, { description: `${this.Document.forceActive ? 'Select' : 'Force'} Contents Active`, event: () => {this.Document.forceActive = !this.Document.forceActive}, icon: 'project-diagram' }) : null; // prettier-ignore
if (this.Document.childLayout instanceof Doc) {
optionItems.push({ description: 'View Child Layout', event: () => this._props.addDocTab(this.Document.childLayout as Doc, OpenWhere.addRight), icon: 'project-diagram' });
}
if (this.Document.childClickedOpenTemplateView instanceof Doc) {
optionItems.push({ description: 'View Child Detailed Layout', event: () => this._props.addDocTab(this.Document.childClickedOpenTemplateView as Doc, OpenWhere.addRight), icon: 'project-diagram' });
}
- !Doc.noviceMode && optionItems.push({ description: `${this.layoutDoc._isLightbox ? 'Unset' : 'Set'} is Lightbox`, event: () => (this.layoutDoc._isLightbox = !this.layoutDoc._isLightbox), icon: 'project-diagram' });
+ !Doc.noviceMode && optionItems.push({ description: `${this.layoutDoc._isLightbox ? 'Unset' : 'Set'} is Lightbox`, event: () => { this.layoutDoc._isLightbox = !this.layoutDoc._isLightbox; }, icon: 'project-diagram' }); // prettier-ignore
!options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'hand-point-right' });
@@ -214,7 +188,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
onClicks.push({
description: `Edit ${func.name} script`,
icon: 'edit',
- event: (obj: any) => {
+ event: () => {
const embedding = Doc.MakeEmbedding(this.Document);
DocUtils.makeCustomViewClicked(embedding, undefined, func.key);
this._props.addDocTab(embedding, OpenWhere.addRight);
@@ -225,7 +199,9 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
onClicks.push({
description: `Set child ${childClick.title}`,
icon: 'edit',
- event: () => (this.dataDoc[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data))),
+ event: () => {
+ this.dataDoc[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data));
+ },
})
);
!Doc.IsSystem(this.Document) && !existingOnClick && cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
@@ -243,7 +219,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
bodyPanelWidth = () => this._props.PanelWidth();
childLayoutTemplate = () => this._props.childLayoutTemplate?.() || Cast(this.Document.childLayoutTemplate, Doc, null);
- isContentActive = (outsideReaction?: boolean) => this._isContentActive;
+ isContentActive = () => this._isContentActive;
pointerEvents = () =>
this.layoutDoc._lockedPosition && //
@@ -275,3 +251,19 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.COL, {
+ layout: { view: CollectionView, dataField: 'data' },
+ options: {
+ acl: '',
+ _layout_fitWidth: true,
+ freeform: '',
+ _freeform_panX: 0,
+ _freeform_panY: 0,
+ _freeform_scale: 1,
+ _layout_nativeDimEditable: true,
+ _layout_reflowHorizontal: true,
+ _layout_reflowVertical: true,
+ systemIcon: 'BsFillCollectionFill',
+ },
+});
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index 4523a4f1e..7dc08389b 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/button-has-type */
import { observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -35,11 +36,36 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
return (
<div className="collectionViewBaseChrome-viewSpecsMenu-row">
- <input className="collectionViewBaseChrome-viewSpecsMenu-rowLeft" value={this._key} onChange={e => runInAction(() => (this._key = e.target.value))} placeholder="KEY" />
- <button className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle" style={{ background: this._contains ? '#77dd77' : '#ff6961' }} onClick={() => runInAction(() => (this._contains = !this._contains))}>
+ <input
+ className="collectionViewBaseChrome-viewSpecsMenu-rowLeft"
+ value={this._key}
+ onChange={e =>
+ runInAction(() => {
+ this._key = e.target.value;
+ })
+ }
+ placeholder="KEY"
+ />
+ <button
+ className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
+ style={{ background: this._contains ? '#77dd77' : '#ff6961' }}
+ onClick={() =>
+ runInAction(() => {
+ this._contains = !this._contains;
+ })
+ }>
{this._contains ? 'CONTAINS' : 'DOES NOT CONTAIN'}
</button>
- <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight" value={this._value} onChange={e => runInAction(() => (this._value = e.target.value))} placeholder="VALUE" />
+ <input
+ className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
+ value={this._value}
+ onChange={e =>
+ runInAction(() => {
+ this._value = e.target.value;
+ })
+ }
+ placeholder="VALUE"
+ />
</div>
);
}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 699ec3b95..46f61290e 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -6,40 +6,180 @@ import { IReactionDisposer, ObservableSet, action, computed, makeObservable, obs
import { observer } from 'mobx-react';
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
-import { DashColor, Utils, emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../../Utils';
+import { ClientUtils, DashColor, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { FieldId } from '../../../fields/RefField';
import { ComputedField } from '../../../fields/ScriptField';
-import { Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, DocCast, NumCast, StrCast, toList } from '../../../fields/Types';
import { DocServer } from '../../DocServer';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../util/DragManager';
-import { SelectionManager } from '../../util/SelectionManager';
-import { SettingsManager } from '../../util/SettingsManager';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { UndoManager, undoable } from '../../util/UndoManager';
import { DashboardView } from '../DashboardView';
import { LightboxView } from '../LightboxView';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { DefaultStyleProvider, StyleProp } from '../StyleProvider';
+import { PinDocView, PinProps } from '../PinFuncs';
+import { StyleProp } from '../StyleProp';
+import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider';
import { Colors } from '../global/globalEnums';
-import { DocumentView, OpenWhere, OpenWhereMod, returnEmptyDocViewList } from '../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
+import { DocumentView } from '../nodes/DocumentView';
+import { FieldViewProps } from '../nodes/FieldView';
import { KeyValueBox } from '../nodes/KeyValueBox';
-import { DashFieldView } from '../nodes/formattedText/DashFieldView';
-import { PinProps, PresBox, PresMovement } from '../nodes/trails';
+import { OpenWhere, OpenWhereMod } from '../nodes/OpenWhere';
+import { PresBox } from '../nodes/trails';
+import { PresMovement } from '../nodes/trails/PresEnums';
import { CollectionDockingView } from './CollectionDockingView';
import { CollectionView } from './CollectionView';
import './TabDocView.scss';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
+
const _global = (window /* browser */ || global) /* node */ as any;
+interface TabMinimapViewProps {
+ document: Doc;
+ tabView: () => DocumentView | undefined;
+ addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean;
+ PanelWidth: () => number;
+ PanelHeight: () => number;
+ background: () => string;
+}
+interface TabMiniThumbProps {
+ miniWidth: () => number;
+ miniHeight: () => number;
+ miniTop: () => number;
+ miniLeft: () => number;
+}
+
+@observer
+class TabMiniThumb extends React.Component<TabMiniThumbProps> {
+ render() {
+ const { miniWidth, miniHeight, miniLeft, miniTop } = this.props;
+ return <div className="miniThumb" style={{ width: `${miniWidth()}%`, height: `${miniHeight()}%`, left: `${miniLeft()}%`, top: `${miniTop()}%` }} />;
+ }
+}
+@observer
+export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps> {
+ static miniStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
+ if (doc) {
+ switch (property.split(':')[0]) {
+ case StyleProp.PointerEvents: return 'none';
+ case StyleProp.DocContents: {
+ const background = (() => {
+ switch (doc.type as DocumentType) {
+ case DocumentType.PDF: return 'pink';
+ case DocumentType.AUDIO: return 'lightgreen';
+ case DocumentType.WEB: return 'brown';
+ case DocumentType.IMG: return 'blue';
+ case DocumentType.MAP: return 'orange';
+ case DocumentType.VID: return 'purple';
+ case DocumentType.RTF: return 'yellow';
+ case DocumentType.COL: return undefined;
+ default: return 'gray';
+ } // prettier-ignore
+ })();
+ return !background ? undefined : <div style={{ width: NumCast(doc._width), height: NumCast(doc._height), position: 'absolute', display: 'block', background }} />;
+ }
+ default: return DefaultStyleProvider(doc, props, property);
+ } // prettier-ignore
+ }
+ return undefined;
+ };
+
+ @computed get renderBounds() {
+ const cbounds = this._props.tabView()?.ComponentView?.contentBounds?.();
+ const { width, height, bounds, cx, cy } = cbounds ?? { bounds: undefined, width: 0, height: 0 };
+ const dim = Math.max(width, height);
+ return bounds === undefined ? bounds : { l: bounds.x + width / 2 - dim / 2, t: bounds.y + height / 2 - dim / 2, cx, cy, dim };
+ }
+ @computed get xPadding() {
+ return !this.renderBounds ? 0 : Math.max(0, this._props.PanelWidth() / NumCast(this._props.document._freeform_scale, 1) - 2 * (this.renderBounds.cx - this.renderBounds.l));
+ }
+ @computed get yPadding() {
+ return !this.renderBounds ? 0 : Math.max(0, this._props.PanelHeight() / NumCast(this._props.document._freeform_scale, 1) - 2 * (this.renderBounds.cy - this.renderBounds.l));
+ }
+ childLayoutTemplate = () => Cast(this._props.document.childLayoutTemplate, Doc, null);
+ returnMiniSize = () => NumCast(this._props.document._miniMapSize, 150);
+ miniDown = (e: React.PointerEvent) => {
+ const doc = this._props.document;
+ const miniSize = this.returnMiniSize();
+ doc &&
+ setupMoveUpEvents(
+ this,
+ e,
+ action((moveEv, down: number[], delta: number[]) => {
+ const renderBounds = this.renderBounds ?? { l: 0, r: 0, t: 0, b: 0, dim: 1 };
+ doc._freeform_panX = clamp(NumCast(doc._freeform_panX) + (delta[0] / miniSize) * renderBounds.dim, renderBounds.l, renderBounds.l + renderBounds.dim);
+ doc._freeform_panY = clamp(NumCast(doc._freeform_panY) + (delta[1] / miniSize) * renderBounds.dim, renderBounds.t, renderBounds.t + renderBounds.dim);
+ return false;
+ }),
+ emptyFunction,
+ emptyFunction
+ );
+ };
+ popup = () => {
+ const { renderBounds } = this;
+ if (!renderBounds) return <div />;
+ const miniWidth = () => (this._props.PanelWidth() / NumCast(this._props.document._freeform_scale, 1) / renderBounds.dim) * 100;
+ const miniHeight = () => (this._props.PanelHeight() / NumCast(this._props.document._freeform_scale, 1) / renderBounds.dim) * 100;
+ const miniLeft = () => 50 + ((NumCast(this._props.document._freeform_panX) - renderBounds.cx) / renderBounds.dim) * 100 - miniWidth() / 2;
+ const miniTop = () => 50 + ((NumCast(this._props.document._freeform_panY) - renderBounds.cy) / renderBounds.dim) * 100 - miniHeight() / 2;
+ const miniSize = this.returnMiniSize();
+ return (
+ <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this._props.background() }}>
+ <CollectionFreeFormView
+ Document={this._props.document}
+ docViewPath={returnEmptyDocViewList}
+ childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
+ noOverlay // don't render overlay Docs since they won't scale
+ isContentActive={emptyFunction}
+ isAnyChildContentActive={returnFalse}
+ select={emptyFunction}
+ isSelected={returnFalse}
+ dontRegisterView
+ fieldKey={Doc.LayoutFieldKey(this._props.document)}
+ addDocument={returnFalse}
+ moveDocument={returnFalse}
+ removeDocument={returnFalse}
+ PanelWidth={this.returnMiniSize}
+ PanelHeight={this.returnMiniSize}
+ ScreenToLocalTransform={Transform.Identity}
+ renderDepth={0}
+ whenChildContentsActiveChanged={emptyFunction}
+ focus={emptyFunction}
+ styleProvider={TabMinimapView.miniStyleProvider}
+ addDocTab={this._props.addDocTab}
+ // eslint-disable-next-line no-use-before-define
+ pinToPres={TabDocView.PinDoc}
+ childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
+ childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
+ searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
+ fitContentsToBox={returnTrue}
+ xPadding={this.xPadding}
+ yPadding={this.yPadding}
+ />
+ <div className="miniOverlay" onPointerDown={this.miniDown}>
+ <TabMiniThumb miniLeft={miniLeft} miniTop={miniTop} miniWidth={miniWidth} miniHeight={miniHeight} />
+ </div>
+ </div>
+ );
+ };
+ render() {
+ return this._props.document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._props.document)) || this._props.document?._type_collection !== CollectionViewType.Freeform ? null : (
+ <div className="miniMap-hidden">
+ <Popup icon={<FontAwesomeIcon icon="globe-asia" size="lg" />} color={SnappingManager.userVariantColor} type={Type.TERT} onPointerDown={e => e.stopPropagation()} placement="top-end" popup={this.popup} />
+ </div>
+ );
+ }
+}
+
interface TabDocViewProps {
documentId: FieldId;
keyValue?: boolean;
@@ -48,12 +188,109 @@ interface TabDocViewProps {
@observer
export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
static _allTabs = new ObservableSet<TabDocView>();
+ public static AllTabDocs() {
+ return Array.from(TabDocView._allTabs)
+ .filter(tv => tv._document)
+ .map(tv => tv._document!);
+ }
_mainCont: HTMLDivElement | null = null;
_tabReaction: IReactionDisposer | undefined;
+ /**
+ * Adds a document to the presentation view
+ * */
+ @action
+ public static PinDoc(docIn: Doc | Doc[], pinProps: PinProps) {
+ const docs = toList(docIn);
+
+ const batch = UndoManager.StartBatch('Pin doc to pres trail');
+ const curPres = Doc.ActivePresentation ?? Doc.MakeCopy(Doc.UserDoc().emptyTrail as Doc, true);
+
+ if (!Doc.ActivePresentation) {
+ Doc.AddDocToList(Doc.MyTrails, 'data', curPres);
+ Doc.ActivePresentation = curPres;
+ }
+
+ docs.forEach(doc => {
+ // Edge Case 1: Cannot pin document to itself
+ if (doc === curPres) {
+ alert('Cannot pin presentation document to itself');
+ return;
+ }
+ const anchorDoc = DocumentView.getDocumentView(doc)?.ComponentView?.getAnchor?.(false, pinProps);
+ const pinDoc = anchorDoc?.type === DocumentType.CONFIG ? anchorDoc : Docs.Create.ConfigDocument({});
+ const targDoc = (pinDoc.presentation_targetDoc = anchorDoc ?? doc);
+ pinDoc.title = doc.title + ' - Slide';
+ pinDoc.data = targDoc.type === DocumentType.PRES ? ComputedField.MakeFunction('copyField(this.presentation_targetDoc.data') : new List<Doc>(); // the children of the embedding's layout are the presentation slide children. the embedding's data field might be children of a collection, PDF data, etc -- in any case we don't want the tree view to "see" this data
+ pinDoc.presentation_movement = doc.type === DocumentType.SCRIPTING || pinProps?.pinDocLayout ? PresMovement.None : PresMovement.Zoom;
+ pinDoc.presentation_duration = pinDoc.presentation_duration ?? 1000;
+ pinDoc.presentation_groupWithUp = false;
+ Doc.SetContainer(pinDoc, curPres);
+ // these should potentially all be props passed down by the CollectionTreeView to the TreeView elements. That way the PresBox could configure all of its children at render time
+ pinDoc.treeView = ''; // not really needed, but makes key value pane look better
+ pinDoc.treeView_RenderAsBulletHeader = true; // forces a tree view to render the document next to the bullet in the header area
+ pinDoc.treeView_HeaderWidth = '100%'; // forces the header to grow to be the same size as its largest sibling.
+ pinDoc.treeView_FieldKey = 'data'; // tree view will treat the 'data' field as the field where the hierarchical children are located instead of using the document's layout string field
+ pinDoc.treeView_ExpandedView = 'data'; // in case the data doc has an expandedView set, this will mask that field and use the 'data' field when expanding the tree view
+ pinDoc.treeView_HideHeaderIfTemplate = true; // this will force the document to render itself as the tree view header
+ const duration = NumCast(doc[`${Doc.LayoutFieldKey(pinDoc)}_duration`], null);
+
+ if (pinProps.pinViewport) PinDocView(pinDoc, pinProps, anchorDoc ?? doc);
+ if (!pinProps?.audioRange && duration !== undefined) {
+ pinDoc.presentation_mediaStart = 'manual';
+ pinDoc.presentation_mediaStop = 'manual';
+ }
+ if (pinProps?.activeFrame !== undefined) {
+ pinDoc.config_activeFrame = pinProps?.activeFrame;
+ pinDoc.title = doc.title + ' (move)';
+ pinDoc.presentation_movement = PresMovement.Pan;
+ }
+ if (pinProps?.currentFrame !== undefined) {
+ pinDoc.config_currentFrame = pinProps?.currentFrame;
+ pinDoc.title = doc.title + ' (move)';
+ pinDoc.presentation_movement = PresMovement.Pan;
+ }
+ if (pinDoc.stroke_isInkMask) {
+ pinDoc.presentation_hideAfter = true;
+ pinDoc.presentation_hideBefore = true;
+ pinDoc.presentation_movement = PresMovement.None;
+ }
+ if (curPres.expandBoolean) pinDoc.presentation_expandInlineButton = true;
+ Doc.AddDocToList(curPres, 'data', pinDoc, PresBox.Instance?.sortArray()?.lastElement());
+ PresBox.Instance?.clearSelectedArray();
+ pinDoc && PresBox.Instance?.addToSelectedArray(pinDoc); // Update selected array
+ });
+ if (
+ // open the presentation trail if it's not already opened
+ !Array.from(CollectionDockingView.Instance?.tabMap ?? [])
+ .map(d => d.DashDoc)
+ .includes(curPres)
+ ) {
+ if (Doc.IsInMyOverlay(curPres)) Doc.RemFromMyOverlay(curPres);
+ CollectionDockingView.AddSplit(curPres, OpenWhereMod.right);
+ setTimeout(() => DocumentView.showDocument(docs.lastElement(), { willPan: true }), 100); // keeps the pinned doc in view since the sidebar shifts things
+ }
+ setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
+ }
+
+ static Activate = (tabDoc: Doc) => {
+ const tab = Array.from(CollectionDockingView.Instance?.tabMap!).find(findTab => findTab.DashDoc === tabDoc && !findTab.contentItem.config.props.keyValue);
+ tab?.header.parent.setActiveContentItem(tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost)
+ return tab !== undefined;
+ };
+ // static ActivateTabView(doc: Doc) {
+ // const tabView = Array.from(TabDocView._allTabs).find(view => view._document === doc);
+ // if (!tabView?._activated && tabView?._document) {
+ // TabDocView.Activate(tabView?._document);
+ // return tabView;
+ // }
+ // return undefined;
+ // }
constructor(props: any) {
super(props);
makeObservable(this);
+ DocumentView.activateTabView = TabDocView.Activate;
+ DocumentView.PinDoc = TabDocView.PinDoc;
}
@observable _activated: boolean = false;
@@ -62,8 +299,14 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
@observable _hovering = false;
@observable _isActive: boolean = false;
@observable _isAnyChildContentActive = false;
+ public static IsSelected = (doc?: Doc) => {
+ if (DocumentView.getViews(doc).some(dv => dv?.IsSelected)) {
+ return true;
+ }
+ return false;
+ };
@computed get _isUserActivated() {
- return SelectionManager.IsSelected(this._document) || this._isAnyChildContentActive;
+ return TabDocView.IsSelected(this._document) || this._isAnyChildContentActive;
}
get _isContentActive() {
return this._isUserActivated || this._hovering;
@@ -90,7 +333,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
@action
init = (tab: any, doc: Opt<Doc>) => {
if (tab.contentItem === tab.header.parent.getActiveContentItem()) this._activated = true;
- if (tab.DashDoc !== doc && doc && tab.hasOwnProperty('contentItem') && tab.contentItem.config.type !== 'stack') {
+ if (tab.DashDoc !== doc && doc && tab.contentItem?.config.type !== 'stack') {
tab._disposers = {} as { [name: string]: IReactionDisposer };
tab.contentItem.config.fixed && (tab.contentItem.parent.config.fixed = true);
tab.DashDoc = doc;
@@ -105,7 +348,6 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
while (child?.children.length) {
const next = Array.from(child.children).find(c => c.className?.toString().includes('SVGAnimatedString') || typeof c.className === 'string');
if (next?.className?.toString().includes(DocumentView.ROOT_DIV)) break;
- if (next?.className?.toString().includes(DashFieldView.name)) break;
if (next) child = next;
else break;
}
@@ -129,37 +371,37 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
setupMoveUpEvents(
this,
e,
- e =>
- !e.defaultPrevented &&
- DragManager.StartDocumentDrag([iconWrap], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY, undefined, () => {
+ moveEv =>
+ !moveEv.defaultPrevented &&
+ DragManager.StartDocumentDrag([iconWrap], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), moveEv.clientX, moveEv.clientY, undefined, () => {
CollectionDockingView.CloseSplit(doc);
}),
returnFalse,
- action(e => {
+ action(clickEv => {
if (this.view) {
- SelectionManager.SelectView(this.view, false);
+ DocumentView.SelectView(this.view, false);
const child = getChild();
- simulateMouseClick(child, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
+ simulateMouseClick(child, clickEv.clientX, clickEv.clientY + 30, clickEv.screenX, clickEv.screenY + 30);
} else {
this._activated = true;
- setTimeout(() => this.view && SelectionManager.SelectView(this.view, false));
+ setTimeout(() => this.view && DocumentView.SelectView(this.view, false));
}
})
);
};
const docIcon = <FontAwesomeIcon onPointerDown={dragBtnDown} icon={iconType} />;
- const closeIcon = <FontAwesomeIcon icon={'eye'} />;
+ const closeIcon = <FontAwesomeIcon icon="eye" />;
ReactDOM.createRoot(iconWrap).render(docIcon);
ReactDOM.createRoot(closeWrap).render(closeIcon);
tab.reactComponents = [iconWrap, closeWrap];
tab.element[0].prepend(iconWrap);
tab._disposers.color = reaction(
- () => ({ variant: SettingsManager.userVariantColor, degree: Doc.GetBrushStatus(doc), highlight: DefaultStyleProvider(this._document, undefined, StyleProp.Highlighting) }),
+ () => ({ variant: SnappingManager.userVariantColor, degree: Doc.GetBrushStatus(doc), highlight: DefaultStyleProvider(this._document, undefined, StyleProp.Highlighting) }),
({ variant, degree, highlight }) => {
const color = highlight?.highlightIndex === Doc.DocBrushStatus.highlighted ? highlight.highlightColor : degree ? ['transparent', variant, variant, 'orange'][degree] : variant;
- const textColor = color === variant ? SettingsManager.userColor : lightOrDark(color);
+ const textColor = color === variant ? SnappingManager.userColor ?? '' : lightOrDark(color);
titleEle.style.color = textColor;
iconWrap.style.color = textColor;
closeWrap.style.color = textColor;
@@ -185,19 +427,19 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
);
}
// shifts the focus to this tab when another tab is dragged over it
- tab.element[0].onmouseenter = (e: MouseEvent) => {
+ tab.element[0].onmouseenter = () => {
if (SnappingManager.IsDragging && tab.contentItem !== tab.header.parent.getActiveContentItem()) {
tab.header.parent.setActiveContentItem(tab.contentItem);
tab.setActive(true);
}
this._document && Doc.BrushDoc(this._document);
};
- tab.element[0].onmouseleave = (e: MouseEvent) => {
+ tab.element[0].onmouseleave = () => {
this._document && Doc.UnBrushDoc(this._document);
};
tab.element[0].oncontextmenu = (e: MouseEvent) => {
- let child = getChild();
+ const child = getChild();
if (child) {
simulateMouseClick(child, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
e.stopPropagation();
@@ -208,7 +450,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
// select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected
titleEle.onpointerdown = action((e: any) => {
if (e.target.className !== 'lm_iconWrap') {
- if (this.view) SelectionManager.SelectView(this.view, false);
+ if (this.view) DocumentView.SelectView(this.view, false);
else this._activated = true;
if (Date.now() - titleEle.lastClick < 1000) titleEle.select();
titleEle.lastClick = Date.now();
@@ -216,15 +458,12 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
}
});
tab._disposers.selectionDisposer = reaction(
- () => SelectionManager.IsSelected(this._document),
+ () => TabDocView.IsSelected(this._document),
action(selected => {
if (selected) this._activated = true;
- const toggle = tab.element[0].children[2].children[0] as HTMLInputElement;
if (selected && tab.contentItem !== tab.header.parent.getActiveContentItem()) {
undoable(() => tab.header.parent.setActiveContentItem(tab.contentItem), 'tab switch')();
}
- //toggle.style.fontWeight = selected ? 'bold' : '';
- // toggle.style.textTransform = selected ? "uppercase" : "";
}),
{ fireImmediately: true }
);
@@ -232,101 +471,27 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
// highlight the tab when the tab document is brushed in any part of the UI
tab._disposers.reactionDisposer = reaction(
() => doc?.title,
- title => (titleEle.value = title),
+ title => {
+ titleEle.value = title;
+ },
{ fireImmediately: true }
);
// clean up the tab when it is closed
tab.closeElement
- .off('click') //unbind the current click handler
- .click(function () {
+ .off('click') // unbind the current click handler
+ .click(() => {
Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
UndoManager.RunInBatch(() => tab.contentItem.remove(), 'delete tab');
});
}
};
- /**
- * Adds a document to the presentation view
- **/
- @action
- public static PinDoc(docs: Doc | Doc[], pinProps: PinProps) {
- const docList = docs instanceof Doc ? [docs] : docs;
-
- const batch = UndoManager.StartBatch('Pin doc to pres trail');
- const curPres = Doc.ActivePresentation ?? Doc.MakeCopy(Doc.UserDoc().emptyTrail as Doc, true);
-
- if (!Doc.ActivePresentation) {
- Doc.AddDocToList(Doc.MyTrails, 'data', curPres);
- Doc.ActivePresentation = curPres;
- }
-
- docList.forEach(doc => {
- // Edge Case 1: Cannot pin document to itself
- if (doc === curPres) {
- alert('Cannot pin presentation document to itself');
- return;
- }
- const anchorDoc = DocumentManager.Instance.getDocumentView(doc)?.ComponentView?.getAnchor?.(false, pinProps);
- const pinDoc = anchorDoc?.type === DocumentType.CONFIG ? anchorDoc : Docs.Create.ConfigDocument({});
- const targDoc = (pinDoc.presentation_targetDoc = anchorDoc ?? doc);
- pinDoc.title = doc.title + ' - Slide';
- pinDoc.data = targDoc.type === DocumentType.PRES ? ComputedField.MakeFunction('copyField(this.presentation_targetDoc.data') : new List<Doc>(); // the children of the embedding's layout are the presentation slide children. the embedding's data field might be children of a collection, PDF data, etc -- in any case we don't want the tree view to "see" this data
- pinDoc.presentation_movement = doc.type === DocumentType.SCRIPTING || pinProps?.pinDocLayout ? PresMovement.None : PresMovement.Zoom;
- pinDoc.presentation_duration = pinDoc.presentation_duration ?? 1000;
- pinDoc.presentation_groupWithUp = false;
- Doc.SetContainer(pinDoc, curPres);
- // these should potentially all be props passed down by the CollectionTreeView to the TreeView elements. That way the PresBox could configure all of its children at render time
- pinDoc.treeView = ''; // not really needed, but makes key value pane look better
- pinDoc.treeView_RenderAsBulletHeader = true; // forces a tree view to render the document next to the bullet in the header area
- pinDoc.treeView_HeaderWidth = '100%'; // forces the header to grow to be the same size as its largest sibling.
- pinDoc.treeView_FieldKey = 'data'; // tree view will treat the 'data' field as the field where the hierarchical children are located instead of using the document's layout string field
- pinDoc.treeView_ExpandedView = 'data'; // in case the data doc has an expandedView set, this will mask that field and use the 'data' field when expanding the tree view
- pinDoc.treeView_HideHeaderIfTemplate = true; // this will force the document to render itself as the tree view header
- const duration = NumCast(doc[`${Doc.LayoutFieldKey(pinDoc)}_duration`], null);
-
- if (pinProps.pinViewport) PresBox.pinDocView(pinDoc, pinProps, anchorDoc ?? doc);
- if (!pinProps?.audioRange && duration !== undefined) {
- pinDoc.presentation_mediaStart = 'manual';
- pinDoc.presentation_mediaStop = 'manual';
- }
- if (pinProps?.activeFrame !== undefined) {
- pinDoc.config_activeFrame = pinProps?.activeFrame;
- pinDoc.title = doc.title + ' (move)';
- pinDoc.presentation_movement = PresMovement.Pan;
- }
- if (pinProps?.currentFrame !== undefined) {
- pinDoc.config_currentFrame = pinProps?.currentFrame;
- pinDoc.title = doc.title + ' (move)';
- pinDoc.presentation_movement = PresMovement.Pan;
- }
- if (pinDoc.stroke_isInkMask) {
- pinDoc.presentation_hideAfter = true;
- pinDoc.presentation_hideBefore = true;
- pinDoc.presentation_movement = PresMovement.None;
- }
- if (curPres.expandBoolean) pinDoc.presentation_expandInlineButton = true;
- Doc.AddDocToList(curPres, 'data', pinDoc, PresBox.Instance?.sortArray()?.lastElement());
- PresBox.Instance?.clearSelectedArray();
- pinDoc && PresBox.Instance?.addToSelectedArray(pinDoc); //Update selected array
- });
- if (
- // open the presentation trail if it's not already opened
- !Array.from(CollectionDockingView.Instance?.tabMap ?? [])
- .map(d => d.DashDoc)
- .includes(curPres)
- ) {
- if (Doc.IsInMyOverlay(curPres)) Doc.RemFromMyOverlay(curPres);
- CollectionDockingView.AddSplit(curPres, OpenWhereMod.right);
- setTimeout(() => DocumentManager.Instance.showDocument(docList.lastElement(), { willPan: true }), 100); // keeps the pinned doc in view since the sidebar shifts things
- }
- setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
- }
-
componentDidMount() {
new _global.ResizeObserver(
action((entries: any) => {
+ // eslint-disable-next-line no-restricted-syntax
for (const entry of entries) {
this._panelWidth = entry.contentRect.width;
this._panelHeight = entry.contentRect.height;
@@ -342,12 +507,12 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
}
componentDidUpdate(prevProps: Readonly<TabDocViewProps>) {
super.componentDidUpdate(prevProps);
- this._view && DocumentManager.Instance.AddView(this._view);
+ this._view && DocumentView.addView(this._view);
}
componentWillUnmount() {
this._tabReaction?.();
- this._view && DocumentManager.Instance.RemoveView(this._view);
+ this._view && DocumentView.removeView(this._view);
runInAction(() => TabDocView._allTabs.delete(this));
this._props.glContainer.layoutManager.off('activeContentItemChanged', this.onActiveContentItemChanged);
@@ -361,7 +526,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
private onActiveContentItemChanged(contentItem: any) {
if (!contentItem || (this.stack === contentItem.parent && ((contentItem?.tab === this.tab && !this._isActive) || (contentItem?.tab !== this.tab && this._isActive)))) {
this._activated = this._isActive = !contentItem || contentItem?.tab === this.tab;
- if (!this._view && this.tab?.contentItem?.config?.props?.panelName !== TabDocView.DontSelectOnActivate) setTimeout(() => SelectionManager.SelectView(this._view, false));
+ if (!this._view && this.tab?.contentItem?.config?.props?.panelName !== TabDocView.DontSelectOnActivate) setTimeout(() => DocumentView.SelectView(this._view, false));
!this._isActive && this._document && Doc.UnBrushDoc(this._document); // bcz: bad -- trying to simulate a pointer leave event when a new tab is opened up on top of an existing one.
}
}
@@ -373,50 +538,37 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
// "replace:right" - will replace the stack on the right named "right" if it exists, or create a stack on the right with that name,
// "replace:monkeys" - will replace any tab that has the label 'monkeys', or a tab with that label will be created by default on the right
// lightbox - will add the document to any collection along the path from the document to the docking view that has a field isLightbox. if none is found, it adds to the full screen lightbox
- addDocTab = (doc: Doc, location: OpenWhere) => {
- SelectionManager.DeselectAll();
+ addDocTab = (docsIn: Doc | Doc[], location: OpenWhere) => {
+ const docs = toList(docsIn);
+ DocumentView.DeselectAll();
const whereFields = location.split(':');
const keyValue = whereFields.includes(OpenWhereMod.keyvalue);
const whereMods = whereFields.length > 1 ? (whereFields[1] as OpenWhereMod) : OpenWhereMod.none;
const panelName = whereFields.length > 1 ? whereFields.lastElement() : '';
- if (doc.dockingConfig && !keyValue) return DashboardView.openDashboard(doc);
+ if (docs[0]?.dockingConfig && !keyValue) return DashboardView.openDashboard(docs[0]);
// prettier-ignore
switch (whereFields[0]) {
case undefined:
- case OpenWhere.lightbox: if (this.layoutDoc?._isLightbox) {
- const lightboxView = !doc.annotationOn && DocCast(doc.embedContainer) ? DocumentManager.Instance.getFirstDocumentView(DocCast(doc.embedContainer)) : undefined;
- const data = lightboxView?.dataDoc[Doc.LayoutFieldKey(lightboxView.Document)];
- if (lightboxView && (!data || data instanceof List)) {
- lightboxView.layoutDoc[Doc.LayoutFieldKey(lightboxView.Document)] = new List<Doc>([doc]);
- return true;
- }
- }
- return LightboxView.Instance.AddDocTab(doc, OpenWhere.lightbox);
- case OpenWhere.close: return CollectionDockingView.CloseSplit(doc, whereMods);
- case OpenWhere.replace: return CollectionDockingView.ReplaceTab(doc, whereMods, this.stack, panelName, undefined, keyValue);
- case OpenWhere.toggle: return CollectionDockingView.ToggleSplit(doc, whereMods, this.stack, TabDocView.DontSelectOnActivate, keyValue);
- case OpenWhere.add:default:return CollectionDockingView.AddSplit(doc, whereMods, this.stack, undefined, keyValue);
+ case OpenWhere.lightbox: return LightboxView.Instance.AddDocTab(docs[0], location);
+ case OpenWhere.close: return CollectionDockingView.CloseSplit(docs[0], whereMods);
+ case OpenWhere.replace: return CollectionDockingView.ReplaceTab(docs[0], whereMods, this.stack, panelName, undefined, keyValue);
+ case OpenWhere.toggle: return CollectionDockingView.ToggleSplit(docs[0], whereMods, this.stack, TabDocView.DontSelectOnActivate, keyValue);
+ case OpenWhere.add:default:return CollectionDockingView.AddSplit(docs[0], whereMods, this.stack, undefined, keyValue);
}
};
remDocTab = (doc: Doc | Doc[]) => {
if (doc === this._document) {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
CollectionDockingView.CloseSplit(this._document);
return true;
}
return false;
};
- getCurrentFrame = () => {
- return NumCast(Cast(PresBox.Instance.activeItem.presentation_targetDoc, Doc, null)._currentFrame);
- };
- static Activate = (tabDoc: Doc) => {
- const tab = Array.from(CollectionDockingView.Instance?.tabMap!).find(tab => tab.DashDoc === tabDoc && !tab.contentItem.config.props.keyValue);
- tab?.header.parent.setActiveContentItem(tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost)
- return tab !== undefined;
- };
+ getCurrentFrame = () => NumCast(Cast(PresBox.Instance.activeItem.presentation_targetDoc, Doc, null)._currentFrame);
+
@action
- focusFunc = (doc: Doc, options: FocusViewOptions) => {
+ focusFunc = () => {
if (!this.tab.header.parent._activeContentItem || this.tab.header.parent._activeContentItem !== this.tab.contentItem) {
this.tab.header.parent.setActiveContentItem(this.tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost)
}
@@ -426,7 +578,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
@observable _forceInvalidateScreenToLocal = 0;
ScreenToLocalTransform = () => {
this._forceInvalidateScreenToLocal;
- const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont?.children?.[0] as HTMLElement);
+ const { translateX, translateY } = ClientUtils.GetScreenTransform(this._mainCont?.children?.[0] as HTMLElement);
return CollectionDockingView.Instance?.ScreenToLocalBoxXf().translate(-translateX, -translateY) ?? Transform.Identity();
};
PanelWidth = () => this._panelWidth;
@@ -434,7 +586,9 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
miniMapColor = () => Colors.MEDIUM_GRAY;
tabView = () => this._view;
disableMinimap = () => !this._document;
- whenChildContentActiveChanges = (isActive: boolean) => (this._isAnyChildContentActive = isActive);
+ whenChildContentActiveChanges = (isActive: boolean) => {
+ this._isAnyChildContentActive = isActive;
+ };
isContentActive = () => this._isContentActive;
waitForDoubleClick = () => (SnappingManager.ExploreMode ? 'never' : undefined);
@computed get docView() {
@@ -443,7 +597,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
<DocumentView
key={this._document[Id]}
ref={action((r: DocumentView) => {
- this._lastView && DocumentManager.Instance.RemoveView(this._lastView);
+ this._lastView && DocumentView.removeView(this._lastView);
this._view = r;
this._lastView = this._view;
})}
@@ -452,7 +606,6 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
hideTitle={this._props.keyValue}
Document={this._document}
TemplateDataDocument={!Doc.AreProtosEqual(this._document[DocData], this._document) ? this._document[DocData] : undefined}
- onBrowseClickScript={DocumentView.exploreMode}
waitForDoubleClickToClick={this.waitForDoubleClick}
isContentActive={this.isContentActive}
isDocumentActive={returnFalse}
@@ -465,8 +618,9 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
addDocument={undefined}
removeDocument={this.remDocTab}
addDocTab={this.addDocTab}
+ suppressSetHeight={!!this._document._layout_fitWidth}
ScreenToLocalTransform={this.ScreenToLocalTransform}
- dontCenter={'y'}
+ dontCenter="y"
whenChildContentsActiveChanged={this.whenChildContentActiveChanges}
focus={this.focusFunc}
containerViewPath={returnEmptyDoclist}
@@ -484,19 +638,24 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
style={{
fontFamily: Doc.UserDoc().renderStyle === 'comic' ? 'Comic Sans MS' : undefined,
}}
- onPointerOver={action(() => (this._hovering = true))}
- onPointerLeave={action(() => (this._hovering = false))}
- onDragOver={action(() => (this._hovering = true))}
- onDragLeave={action(() => (this._hovering = false))}
+ onPointerOver={action(() => { this._hovering = true; })} // prettier-ignore
+ onPointerLeave={action(() => { this._hovering = false; })} // prettier-ignore
+ onDragOver={action(() => { this._hovering = true; })} // prettier-ignore
+ onDragLeave={action(() => { this._hovering = false; })} // prettier-ignore
ref={ref => {
- if ((this._mainCont = ref)) {
+ this._mainCont = ref;
+ if (this._mainCont) {
if (this._lastTab) {
- this._view && DocumentManager.Instance.RemoveView(this._view);
+ this._view && DocumentView.removeView(this._view);
}
this._lastTab = this.tab;
(this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document);
- DocServer.GetRefField(this._props.documentId).then(action(doc => doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document)));
- new _global.ResizeObserver(action((entries: any) => this._forceInvalidateScreenToLocal++)).observe(ref);
+ DocServer.GetRefField(this._props.documentId).then(
+ action(doc => {
+ doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document);
+ })
+ );
+ new _global.ResizeObserver(action(() => this._forceInvalidateScreenToLocal++)).observe(ref);
}
}}>
{this.docView}
@@ -504,142 +663,3 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
);
}
}
-
-interface TabMinimapViewProps {
- document: Doc;
- tabView: () => DocumentView | undefined;
- addDocTab: (doc: Doc, where: OpenWhere) => boolean;
- PanelWidth: () => number;
- PanelHeight: () => number;
- background: () => string;
-}
-interface TabMiniThumbProps {
- miniWidth: () => number;
- miniHeight: () => number;
- miniTop: () => number;
- miniLeft: () => number;
-}
-
-@observer
-class TabMiniThumb extends React.Component<TabMiniThumbProps> {
- render() {
- return <div className="miniThumb" style={{ width: `${this.props.miniWidth()}% `, height: `${this.props.miniHeight()}% `, left: `${this.props.miniLeft()}% `, top: `${this.props.miniTop()}% ` }} />;
- }
-}
-@observer
-export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps> {
- static miniStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
- if (doc) {
- switch (property.split(':')[0]) {
- default:
- return DefaultStyleProvider(doc, props, property);
- case StyleProp.PointerEvents:
- return 'none';
- case StyleProp.DocContents:
- const background = ((type: DocumentType) => {
- // prettier-ignore
- switch (type) {
- case DocumentType.PDF: return 'pink';
- case DocumentType.AUDIO: return 'lightgreen';
- case DocumentType.WEB: return 'brown';
- case DocumentType.IMG: return 'blue';
- case DocumentType.MAP: return 'orange';
- case DocumentType.VID: return 'purple';
- case DocumentType.RTF: return 'yellow';
- case DocumentType.COL: return undefined;
- default: return 'gray';
- }
- })(doc.type as DocumentType);
- return !background ? undefined : <div style={{ width: NumCast(doc._width), height: NumCast(doc._height), position: 'absolute', display: 'block', background }} />;
- }
- }
- };
-
- @computed get renderBounds() {
- const compView = this._props.tabView()?.ComponentView as CollectionFreeFormView;
- const bounds = compView?.freeformData?.(true)?.bounds;
- if (!bounds) return undefined;
- const xbounds = bounds.r - bounds.x;
- const ybounds = bounds.b - bounds.y;
- const dim = Math.max(xbounds, ybounds);
- return { l: bounds.x + xbounds / 2 - dim / 2, t: bounds.y + ybounds / 2 - dim / 2, cx: bounds.x + xbounds / 2, cy: bounds.y + ybounds / 2, dim };
- }
- @computed get xPadding() {
- return !this.renderBounds ? 0 : Math.max(0, this._props.PanelWidth() / NumCast(this._props.document._freeform_scale, 1) - 2 * (this.renderBounds.cx - this.renderBounds.l));
- }
- @computed get yPadding() {
- return !this.renderBounds ? 0 : Math.max(0, this._props.PanelHeight() / NumCast(this._props.document._freeform_scale, 1) - 2 * (this.renderBounds.cy - this.renderBounds.l));
- }
- childLayoutTemplate = () => Cast(this._props.document.childLayoutTemplate, Doc, null);
- returnMiniSize = () => NumCast(this._props.document._miniMapSize, 150);
- miniDown = (e: React.PointerEvent) => {
- const doc = this._props.document;
- const miniSize = this.returnMiniSize();
- doc &&
- setupMoveUpEvents(
- this,
- e,
- action((e: PointerEvent, down: number[], delta: number[]) => {
- const renderBounds = this.renderBounds ?? { l: 0, r: 0, t: 0, b: 0, dim: 1 };
- doc._freeform_panX = clamp(NumCast(doc._freeform_panX) + (delta[0] / miniSize) * renderBounds.dim, renderBounds.l, renderBounds.l + renderBounds.dim);
- doc._freeform_panY = clamp(NumCast(doc._freeform_panY) + (delta[1] / miniSize) * renderBounds.dim, renderBounds.t, renderBounds.t + renderBounds.dim);
- return false;
- }),
- emptyFunction,
- emptyFunction
- );
- };
- popup = () => {
- if (!this.renderBounds) return <></>;
- const renderBounds = this.renderBounds;
- const miniWidth = () => (this._props.PanelWidth() / NumCast(this._props.document._freeform_scale, 1) / renderBounds.dim) * 100;
- const miniHeight = () => (this._props.PanelHeight() / NumCast(this._props.document._freeform_scale, 1) / renderBounds.dim) * 100;
- const miniLeft = () => 50 + ((NumCast(this._props.document._freeform_panX) - renderBounds.cx) / renderBounds.dim) * 100 - miniWidth() / 2;
- const miniTop = () => 50 + ((NumCast(this._props.document._freeform_panY) - renderBounds.cy) / renderBounds.dim) * 100 - miniHeight() / 2;
- const miniSize = this.returnMiniSize();
- return (
- <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this._props.background() }}>
- <CollectionFreeFormView
- Document={this._props.document}
- docViewPath={returnEmptyDocViewList}
- childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
- noOverlay={true} // don't render overlay Docs since they won't scale
- isContentActive={emptyFunction}
- isAnyChildContentActive={returnFalse}
- select={emptyFunction}
- isSelected={returnFalse}
- dontRegisterView={true}
- fieldKey={Doc.LayoutFieldKey(this._props.document)}
- addDocument={returnFalse}
- moveDocument={returnFalse}
- removeDocument={returnFalse}
- PanelWidth={this.returnMiniSize}
- PanelHeight={this.returnMiniSize}
- ScreenToLocalTransform={Transform.Identity}
- renderDepth={0}
- whenChildContentsActiveChanged={emptyFunction}
- focus={emptyFunction}
- styleProvider={TabMinimapView.miniStyleProvider}
- addDocTab={this._props.addDocTab}
- pinToPres={TabDocView.PinDoc}
- childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
- childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
- searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
- fitContentsToBox={returnTrue}
- xPadding={this.xPadding}
- yPadding={this.yPadding}
- />
- <div className="miniOverlay" onPointerDown={this.miniDown}>
- <TabMiniThumb miniLeft={miniLeft} miniTop={miniTop} miniWidth={miniWidth} miniHeight={miniHeight} />
- </div>
- </div>
- );
- };
- render() {
- return this._props.document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._props.document)) || this._props.document?._type_collection !== CollectionViewType.Freeform ? null : (
- <div className="miniMap-hidden">
- <Popup icon={<FontAwesomeIcon icon="globe-asia" size="lg" />} color={SettingsManager.userVariantColor} type={Type.TERT} onPointerDown={e => e.stopPropagation()} placement="top-end" popup={this.popup} />
- </div>
- );
- }
-}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index c6bbcb0a5..b82421e6b 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -1,45 +1,51 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/no-noninteractive-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 { IconButton, Size } from 'browndash-components';
import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Utils, emptyFunction, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../Utils';
-import { Doc, DocListCast, Field, FieldResult, Opt, StrListCast } from '../../../fields/Doc';
+import { ClientUtils, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
+import { Doc, DocListCast, Field, FieldResult, FieldType, Opt, StrListCast } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { RichTextField } from '../../../fields/RichTextField';
import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast, toList } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
+import { DocUtils } from '../../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
-import { DocUtils, Docs } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../util/DragManager';
-import { LinkManager } from '../../util/LinkManager';
-import { ScriptingGlobals } from '../../util/ScriptingGlobals';
+import { Docs } from '../../documents/Documents';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
import { SettingsManager } from '../../util/SettingsManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { UndoManager, undoBatch, undoable } from '../../util/UndoManager';
import { EditableView } from '../EditableView';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { StyleProp } from '../StyleProvider';
-import { DocumentView, DocumentViewInternal, OpenWhere } from '../nodes/DocumentView';
+import { StyleProp } from '../StyleProp';
+import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
import { FieldViewProps, StyleProviderFuncType } from '../nodes/FieldView';
-import { KeyValueBox } from '../nodes/KeyValueBox';
+import { OpenWhere } from '../nodes/OpenWhere';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
-import { CollectionTreeView, TreeViewType } from './CollectionTreeView';
+import { CollectionTreeView } from './CollectionTreeView';
+import { TreeViewType } from './CollectionTreeViewType';
import { CollectionView } from './CollectionView';
import { TreeSort } from './TreeSort';
import './TreeView.scss';
-const { default: { TREE_BULLET_WIDTH } } = require('../global/globalCssVariables.module.scss'); // prettier-ignore
+
+const { TREE_BULLET_WIDTH } = require('../global/globalCssVariables.module.scss'); // prettier-ignore
export interface TreeViewProps {
treeView: CollectionTreeView;
+ // eslint-disable-next-line no-use-before-define
parentTreeView: TreeView | CollectionTreeView | undefined;
observeHeight: (ref: any) => void;
unobserveHeight: (ref: any) => void;
@@ -49,7 +55,7 @@ export interface TreeViewProps {
treeViewParent: Doc;
renderDepth: number;
dragAction: dropActionType;
- addDocTab: (doc: Doc, where: OpenWhere) => boolean;
+ addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean;
panelWidth: () => number;
panelHeight: () => number;
addDocument: (doc: Doc | Doc[], annotationKey?: string, relativeTo?: Doc, before?: boolean) => boolean;
@@ -88,6 +94,7 @@ const treeBulletWidth = function () {
*/
@observer
export class TreeView extends ObservableReactComponent<TreeViewProps> {
+ // eslint-disable-next-line no-use-before-define
static _editTitleOnLoad: Opt<{ id: string; parent: TreeView | CollectionTreeView | undefined }>;
static _openTitleScript: Opt<ScriptField | undefined>;
static _openLevelScript: Opt<ScriptField | undefined>;
@@ -102,6 +109,9 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
get treeViewOpenIsTransient() {
return this.treeView.Document.treeView_OpenIsTransient || Doc.IsDataProto(this.Document);
}
+ @computed get treeViewOpen() {
+ return (!this.treeViewOpenIsTransient && Doc.GetT(this.Document, 'treeView_Open', 'boolean', true)) || this._transientOpenState;
+ }
set treeViewOpen(c: boolean) {
if (this.treeViewOpenIsTransient) this._transientOpenState = c;
else {
@@ -138,9 +148,6 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
@computed get Document() {
return this._props.Document;
}
- @computed get treeViewOpen() {
- return (!this.treeViewOpenIsTransient && Doc.GetT(this.Document, 'treeView_Open', 'boolean', true)) || this._transientOpenState;
- }
@computed get treeViewExpandedView() {
return this.validExpandViewTypes.includes(StrCast(this.Document.treeView_ExpandedView)) ? StrCast(this.Document.treeView_ExpandedView) : this.defaultExpandedView;
}
@@ -193,12 +200,13 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
}
return false;
};
- @undoBatch remove = (doc: Doc | Doc[], key: string) => {
+ @undoBatch remove = (docIn: Doc | Doc[], key: string) => {
+ const docs = toList(docIn);
this.treeView._props.select(false);
- const ind = DocListCast(this.dataDoc[key]).indexOf(doc instanceof Doc ? doc : doc.lastElement());
+ const ind = DocListCast(this.dataDoc[key]).indexOf(docs.lastElement());
- const res = (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && Doc.RemoveDocFromList(this.dataDoc, key, doc), true);
- res && ind > 0 && DocumentManager.Instance.getDocumentView(DocListCast(this.dataDoc[key])[ind - 1], this.treeView.DocumentView?.())?.select(false);
+ const res = docs.reduce((flg, doc) => flg && Doc.RemoveDocFromList(this.dataDoc, key, doc), true);
+ res && ind > 0 && DocumentView.getDocumentView(DocListCast(this.dataDoc[key])[ind - 1], this.treeView.DocumentView?.())?.select(false);
return res;
};
@@ -222,8 +230,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
this.treeViewOpen = !this.treeViewOpen;
} else {
// choose an appropriate embedding or make one. --- choose the first embedding that (1) user owns, (2) has no context field ... otherwise make a new embedding
- const bestEmbedding = docView.Document.author === Doc.CurrentUserEmail && !Doc.IsDataProto(docView.Document) ? docView.Document : Doc.BestEmbedding(docView.Document);
- this._props.addDocTab(bestEmbedding, OpenWhere.lightbox);
+ const bestEmbedding = docView.Document.author === ClientUtils.CurrentUserEmail() && !Doc.IsDataProto(docView.Document) ? docView.Document : Doc.BestEmbedding(docView.Document);
+ this._props.addDocTab(bestEmbedding, OpenWhere.lightboxAlways);
}
};
@@ -231,7 +239,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
recurToggle = (childList: Doc[]) => {
if (childList.length > 0) {
childList.forEach(child => {
- child.runProcess = !!!child.runProcess;
+ child.runProcess = !child.runProcess;
TreeView.ToggleChildrenRun.get(child)?.();
});
}
@@ -274,9 +282,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
this.recurToggle(this.childDocs);
});
- TreeView.GetRunningChildren.set(this.Document, () => {
- return this.getRunningChildren(this.childDocs);
- });
+ TreeView.GetRunningChildren.set(this.Document, () => this.getRunningChildren(this.childDocs));
}
_treeEle: any;
@@ -302,7 +308,9 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
super.componentDidUpdate(prevProps);
this._disposers.opening = reaction(
() => this.treeViewOpen,
- open => !open && (this._renderCount = 20)
+ open => {
+ !open && (this._renderCount = 20);
+ }
);
this._props.hierarchyIndex !== undefined && this._props.AddToMap?.(this.Document, this._props.hierarchyIndex);
}
@@ -311,7 +319,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
this._props.hierarchyIndex !== undefined && this._props.AddToMap?.(this.Document, this._props.hierarchyIndex);
}
- onDragUp = (e: PointerEvent) => {
+ onDragUp = () => {
document.removeEventListener('pointerup', this.onDragUp, true);
document.removeEventListener('pointermove', this.onDragMove, true);
};
@@ -325,7 +333,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
document.addEventListener('pointerup', this.onDragUp, true);
}
};
- onPointerLeave = (e: React.PointerEvent): void => {
+ onPointerLeave = (): void => {
Doc.UnBrushDoc(this.dataDoc);
if (this._header.current?.className !== 'treeView-header-editing') {
this._header.current!.className = 'treeView-header';
@@ -369,7 +377,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
const bulletData = bullet[DocData];
bulletData.title = ComputedField.MakeFunction('this.text?.Text');
bulletData.data = new List<Doc>([]);
- DocumentManager.Instance.AddViewRenderedCb(bullet, dv => dv.ComponentView?.setFocus?.());
+ DocumentView.addViewRenderedCb(bullet, dv => dv.ComponentView?.setFocus?.());
return bullet;
}
@@ -386,7 +394,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return this.localAdd(folder);
};
- preTreeDrop = (e: Event, de: DragManager.DropEvent, docDropAction: dropActionType) => {
+ preTreeDrop = () => {
// fall through and let the CollectionTreeView handle this since treeView items have no special properties of their own
};
@@ -396,7 +404,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
if (!this._header.current) return false;
const rect = this._header.current.getBoundingClientRect();
const before = pt[1] < rect.top + rect.height / 2;
- const inside = this.treeView.fileSysMode && !this.Document.isFolder ? false : pt[0] > rect.left + rect.width * 0.33 || (!before && this.treeViewOpen && this.childDocs?.length ? true : false);
+ const inside = this.treeView.fileSysMode && !this.Document.isFolder ? false : pt[0] > rect.left + rect.width * 0.33 || !!(!before && this.treeViewOpen && this.childDocs?.length);
if (de.complete.linkDragData) {
const sourceDoc = de.complete.linkDragData.linkSourceGetAnchor();
const destDoc = this.Document;
@@ -404,7 +412,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
e.stopPropagation();
return true;
}
- const docDragData = de.complete.docDragData;
+ const { docDragData } = de.complete;
if (docDragData && pt[0] < rect.left + rect.width) {
if (docDragData.draggedDocuments[0] === this.Document) return true;
const added = this.dropDocuments(
@@ -424,14 +432,14 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return false;
};
- localAdd = (doc: Doc | Doc[]) => {
- const innerAdd = (doc: Doc) => {
+ localAdd = (docs: Doc | Doc[]): boolean => {
+ const innerAdd = (doc: Doc): boolean => {
const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[this.fieldKey])) instanceof ComputedField;
const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, this.fieldKey, doc);
dataIsComputed && Doc.SetContainer(doc, DocCast(this.Document.embedContainer));
return added;
};
- return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean);
+ return toList(docs).reduce((flg, doc) => flg && innerAdd(doc), true as boolean);
};
dropping: boolean = false;
@@ -450,7 +458,9 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
const addDoc = inside ? this.localAdd : parentAddDoc;
const canAdd = !StrCast((inside ? this.Document : this._props.treeViewParent)?.treeView_FreezeChildren).includes('add') || forceAdd;
if (canAdd && (dropAction !== dropActionType.inPlace || droppedDocuments.every(d => d.embedContainer === this._props.parentTreeView?.Document))) {
- const move = (!dropAction || canEmbed || dropAction === dropActionType.proto || dropAction === dropActionType.move || dropAction === dropActionType.same || dropAction === dropActionType.inPlace) && moveDocument;
+ const move =
+ (!dropAction || (canEmbed && dropAction !== dropActionType.copy) || dropAction === dropActionType.proto || dropAction === dropActionType.move || dropAction === dropActionType.same || dropAction === dropActionType.inPlace) &&
+ moveDocument;
this._props.parentTreeView instanceof TreeView && (this._props.parentTreeView.dropping = true);
const res = droppedDocuments.reduce((added, d) => (move ? move(d, undefined, addDoc) || (dropAction === dropActionType.proto ? addDoc(d) : false) : addDoc(d)) || added, false);
this._props.parentTreeView instanceof TreeView && (this._props.parentTreeView.dropping = false);
@@ -461,8 +471,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
refTransform = (ref: HTMLDivElement | undefined | null) => {
if (!ref) return this.ScreenToLocalTransform();
- const { scale, translateX, translateY } = Utils.GetScreenTransform(ref);
- const outerXf = Utils.GetScreenTransform(this.treeView.MainEle());
+ const { translateX, translateY } = ClientUtils.GetScreenTransform(ref);
+ const outerXf = ClientUtils.GetScreenTransform(this.treeView.MainEle());
const offset = this.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
return this.ScreenToLocalTransform().translate(offset[0], offset[1]);
};
@@ -489,29 +499,34 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
const ids: { [key: string]: string } = {};
const rows: JSX.Element[] = [];
const doc = this.Document;
- doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
+ doc &&
+ Object.keys(doc).forEach(key => {
+ !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key);
+ });
+ // eslint-disable-next-line no-restricted-syntax
for (const key of Object.keys(ids).slice().sort()) {
+ // eslint-disable-next-line no-continue
if (this._props.skipFields?.includes(key) || key === 'title' || key === 'treeView_Open') continue;
const contents = doc[key];
let contentElement: (JSX.Element | null)[] | JSX.Element = [];
- let leftOffset = observable({ width: 0 });
+ const leftOffset = observable({ width: 0 });
const expandedWidth = () => this._props.panelWidth() - leftOffset.width;
if (contents instanceof Doc || (Cast(contents, listSpec(Doc)) && Cast(contents, listSpec(Doc))!.length && Cast(contents, listSpec(Doc))![0] instanceof Doc)) {
- const remDoc = (doc: Doc | Doc[]) => this.remove(doc, key);
- const moveDoc = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.move(doc, target, addDoc);
- const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => {
- const innerAdd = (doc: Doc) => {
+ const remDoc = (docs: Doc | Doc[]) => this.remove(docs, key);
+ const moveDoc = (docs: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.move(docs, target, addDoc);
+ const addDoc = (docs: Doc | Doc[], addBefore?: Doc, before?: boolean) => {
+ const innerAdd = (iDoc: Doc) => {
const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField;
- const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
- dataIsComputed && Doc.SetContainer(doc, DocCast(this.Document.embedContainer));
+ const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, iDoc, addBefore, before, false, true);
+ dataIsComputed && Doc.SetContainer(iDoc, DocCast(this.Document.embedContainer));
return added;
};
- return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean);
+ return toList(docs).reduce((flg, iDoc) => flg && innerAdd(iDoc), true as boolean);
};
contentElement = TreeView.GetChildElements(
- contents instanceof Doc ? [contents] : DocListCast(contents),
+ toList(contents as any),
this.treeView,
this,
doc,
@@ -548,11 +563,11 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
contentElement = (
<EditableView
key="editableView"
- contents={contents !== undefined ? Field.toString(contents as Field) : 'null'}
+ contents={contents !== undefined ? Field.toString(contents as FieldType) : 'null'}
height={13}
fontSize={12}
GetValue={() => Field.toKeyValueString(doc, key)}
- SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)}
+ SetValue={(value: string) => Doc.SetField(doc, key, value, true)}
/>
);
}
@@ -571,14 +586,24 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
);
}
rows.push(
- <div style={{ display: 'flex', overflow: 'auto' }} key={'newKeyValue'}>
+ <div style={{ display: 'flex', overflow: 'auto' }} key="newKeyValue">
<EditableView
key="editableView"
- contents={'+key:value'}
+ contents="+key=value"
height={13}
fontSize={12}
GetValue={returnEmptyString}
- SetValue={value => value.indexOf(':') !== -1 && KeyValueBox.SetField(doc, value.substring(0, value.indexOf(':')), value.substring(value.indexOf(':') + 1, value.length), true)}
+ SetValue={input => {
+ const match = input.match(/([a-zA-Z0-9_-]+)(=|=:=)([a-zA-Z,_@?+\-*/ 0-9()]+)/);
+ if (match) {
+ const key = match[1];
+ const assign = match[2];
+ const val = match[3];
+ Doc.SetField(doc, key, assign + val, false);
+ return true;
+ }
+ return false;
+ }}
/>
</div>
);
@@ -609,7 +634,9 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
const docs = TreeView.sortDocs(this.childDocs || ([] as Doc[]), ordering);
doc.zIndex = addBefore ? NumCast(addBefore.zIndex) + (before ? -0.5 : 0.5) : 1000;
docs.push(doc);
- docs.sort((a, b) => (NumCast(a.zIndex) > NumCast(b.zIndex) ? 1 : -1)).forEach((d, i) => (d.zIndex = i));
+ docs.sort((a, b) => (NumCast(a.zIndex) > NumCast(b.zIndex) ? 1 : -1)).forEach((d, i) => {
+ d.zIndex = i;
+ });
}
const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField;
const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false);
@@ -617,10 +644,10 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return added;
};
- const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true);
+ const addDoc = (docs: Doc | Doc[], addBefore?: Doc, before?: boolean) => toList(docs).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true);
const docs = expandKey === 'embeddings' ? this.childEmbeddings : expandKey === 'links' ? this.childLinks : expandKey === 'annotations' ? this.childAnnos : this.childDocs;
- let downX = 0,
- downY = 0;
+ let downX = 0;
+ let downY = 0;
if (docs?.length && this._renderCount < docs?.length) {
this._renderTimer && clearTimeout(this._renderTimer);
this._renderTimer = setTimeout(
@@ -656,7 +683,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
style={{ cursor: 'inherit' }}
key={expandKey + 'more'}
title={`Sorted by : ${this.Document.treeView_SortCriterion}. click to cycle`}
- className="" //this.doc.treeView_HideTitle ? 'no-indent' : ''}
+ className="" // this.doc.treeView_HideTitle ? 'no-indent' : ''}
onPointerDown={e => {
downX = e.clientX;
downY = e.clientY;
@@ -708,7 +735,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
</ul>
</div>
);
- } else if (this.treeViewExpandedView === 'fields') {
+ }
+ if (this.treeViewExpandedView === 'fields') {
return (
<ul key={this.Document[Id] + this.Document.title} style={{ cursor: 'inherit' }}>
<div>{this.expandedField}</div>
@@ -751,7 +779,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
@computed get renderBullet() {
TraceMobx();
- const iconType = this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':open' : !this.childDocs.length ? ':empty' : '')) || 'question';
+ const iconType = this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':treeOpen' : !this.childDocs.length ? ':empty' : '')) || 'question';
const color = SettingsManager.userColor;
const checked = this.onCheckedClick ? this.Document.treeView_Checked ?? 'unchecked' : undefined;
return (
@@ -793,7 +821,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
@computed get validExpandViewTypes() {
const annos = () => (DocListCast(this.Document[this.fieldKey + '_annotations']).length && !this.treeView.dashboardMode ? 'annotations' : '');
- const links = () => (LinkManager.Links(this.Document).length && !this.treeView.dashboardMode ? 'links' : '');
+ const links = () => (Doc.Links(this.Document).length && !this.treeView.dashboardMode ? 'links' : '');
const data = () => (this.childDocs || this.treeView.dashboardMode ? this.fieldKey : '');
const embeddings = () => (this.treeView.dashboardMode ? '' : 'embeddings');
const fields = () => (Doc.noviceMode ? '' : 'fields');
@@ -880,14 +908,15 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
titleStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
if (!doc || doc !== this.Document) return this._props?.treeView?._props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView
- const treeView = this.treeView;
+ const { treeView } = this;
// prettier-ignore
switch (property.split(':')[0]) {
case StyleProp.Opacity: return this.treeView.outlineMode ? undefined : 1;
- case StyleProp.BackgroundColor: return this.selected ? '#7089bb' : undefined;//StrCast(doc._backgroundColor, StrCast(doc.backgroundColor));
+ case StyleProp.BackgroundColor: return this.selected ? '#7089bb' : undefined; // StrCast(doc._backgroundColor, StrCast(doc.backgroundColor));
case StyleProp.Highlighting: if (this.treeView.outlineMode) return undefined;
+ break;
case StyleProp.BoxShadow: return undefined;
- case StyleProp.DocContents:
+ case StyleProp.DocContents: {
const highlightIndex = this.treeView.outlineMode ? Doc.DocBrushStatus.unbrushed : Doc.GetBrushHighlightStatus(doc);
const highlightColor = ['transparent', 'rgb(68, 118, 247)', 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex];
return treeView.outlineMode ? null : (
@@ -906,6 +935,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
{StrCast(doc?.title)}
</div>
);
+ }
+ default:
}
return treeView._props.styleProvider?.(doc, props, property);
};
@@ -913,13 +944,13 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
if (property.startsWith(StyleProp.Decorations)) return null;
return this._props?.treeView?._props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView
};
- onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
+ onKeyDown = (e: React.KeyboardEvent) => {
if (this.Document.treeView_HideHeader || (this.Document.treeView_HideHeaderIfTemplate && this.treeView._props.childLayoutTemplate?.()) || this.treeView.outlineMode) {
switch (e.key) {
case 'Tab':
e.stopPropagation?.();
e.preventDefault?.();
- setTimeout(() => RichTextMenu.Instance.TextView?.EditorView?.focus(), 150);
+ setTimeout(() => RichTextMenu.Instance?.TextView?.EditorView?.focus(), 150);
UndoManager.RunInBatch(() => (e.shiftKey ? this._props.outdentDocument?.(true) : this._props.indentDocument?.(true)), 'tab');
return true;
case 'Backspace':
@@ -933,6 +964,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
e.stopPropagation?.();
e.preventDefault?.();
return UndoManager.RunInBatch(this.makeTextCollection, 'bullet');
+ default:
}
}
return false;
@@ -948,22 +980,24 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
const view = this._editTitle ? (
<EditableView
key="_editTitle"
- oneLine={true}
- display={'inline-block'}
+ oneLine
+ display="inline-block"
editing={this._editTitle}
- background={'#7089bb'}
+ background="#7089bb"
contents={StrCast(this.Document.title)}
height={12}
- sizeToContent={true}
+ sizeToContent
fontSize={12}
- isEditingCallback={action(e => (this._editTitle = e))}
+ isEditingCallback={action(e => {
+ this._editTitle = e;
+ })}
GetValue={() => StrCast(this.Document.title)}
OnTab={undoBatch((shift?: boolean) => {
if (!shift) this._props.indentDocument?.(true);
else this._props.outdentDocument?.(true);
})}
OnEmpty={undoBatch(() => this.treeView.outlineMode && this._props.removeDoc?.(this.Document))}
- OnFillDown={val => this.treeView.fileSysMode && this.makeFolder()}
+ OnFillDown={() => this.treeView.fileSysMode && this.makeFolder()}
SetValue={undoBatch((value: string, shiftKey: boolean, enterKey: boolean) => {
Doc.SetInPlace(this.Document, 'title', value, false);
this.treeView.outlineMode && enterKey && this.makeTextCollection();
@@ -973,7 +1007,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
<DocumentView
key="title"
ref={action((r: any) => {
- this._docRef = r ? r : undefined;
+ this._docRef = r || undefined;
if (this._docRef && TreeView._editTitleOnLoad?.id === this.Document[Id] && TreeView._editTitleOnLoad.parent === this._props.parentTreeView) {
this._docRef.select(false);
this.setEditTitle(this._docRef);
@@ -981,10 +1015,10 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
}
})}
Document={this.Document}
- layout_fitWidth={returnTrue}
+ fitWidth={returnTrue}
scriptContext={this}
- hideDecorations={true}
- hideClickBehaviors={true}
+ hideDecorations
+ hideClickBehaviors
styleProvider={this.titleStyleProvider}
onClickScriptDisable="never" // tree docViews have a script to show fields, etc.
containerViewPath={this.treeView.childContainerViewPath}
@@ -1004,7 +1038,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
PanelHeight={return18}
contextMenuItems={this.contextMenuItems}
renderDepth={1}
- isContentActive={emptyFunction} //this._props.isContentActive}
+ isContentActive={emptyFunction} // this._props.isContentActive}
isDocumentActive={this._props.isContentActive}
focus={this.refocus}
whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
@@ -1034,99 +1068,101 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
}}>
{view}
</div>
- <div className="treeView-rightButtons" ref={action((r: any) => r && (this.headerEleWidth = r.getBoundingClientRect().width))}>
+ <div
+ className="treeView-rightButtons"
+ ref={action((r: any) => {
+ r && (this.headerEleWidth = r.getBoundingClientRect().width);
+ })}>
{this.titleButtons}
</div>
</>
);
}
- renderBulletHeader = (contents: JSX.Element, editing: boolean) => {
- return (
- <>
+ renderBulletHeader = (contents: JSX.Element, editing: boolean) => (
+ <>
+ <div
+ className={`treeView-header` + (editing ? '-editing' : '')}
+ key="titleheader"
+ ref={this._header}
+ onClick={this.ignoreEvent}
+ onPointerDown={e => {
+ this.treeView.isContentActive() &&
+ setupMoveUpEvents(
+ this,
+ e,
+ () => {
+ (this._dref ?? this._docRef)?.startDragging(e.clientX, e.clientY, '' as any);
+ return true;
+ },
+ returnFalse,
+ emptyFunction
+ );
+ }}
+ onPointerEnter={this.onPointerEnter}
+ onPointerLeave={this.onPointerLeave}>
<div
- className={`treeView-header` + (editing ? '-editing' : '')}
- key="titleheader"
- ref={this._header}
- onClick={this.ignoreEvent}
- onPointerDown={e => {
- this.treeView.isContentActive() &&
- setupMoveUpEvents(
- this,
- e,
- () => {
- this._dref?.startDragging(e.clientX, e.clientY, '' as any);
- return true;
- },
- returnFalse,
- emptyFunction
- );
+ className="treeView-background"
+ style={{
+ background: SettingsManager.userColor,
}}
- onPointerEnter={this.onPointerEnter}
- onPointerLeave={this.onPointerLeave}>
- <div
- className="treeView-background"
- style={{
- background: SettingsManager.userColor,
- }}
- />
- {contents}
- </div>
- {this.renderBorder}
- </>
- );
- };
-
- fitWidthFilter = (doc: Doc) => (doc.type === DocumentType.IMG ? false : undefined);
- renderEmbeddedDocument = (asText: boolean, isActive: () => boolean | undefined) => {
- return (
- <div style={{ height: this.embeddedPanelHeight(), width: this.embeddedPanelWidth() }}>
- <DocumentView
- key={this.Document[Id]}
- ref={action((r: DocumentView | null) => (this._dref = r))}
- Document={this.Document}
- layout_fitWidth={this.fitWidthFilter}
- PanelWidth={this.embeddedPanelWidth}
- PanelHeight={this.embeddedPanelHeight}
- LayoutTemplateString={asText ? FormattedTextBox.LayoutString('text') : undefined}
- LayoutTemplate={this.treeView._props.childLayoutTemplate}
- isContentActive={isActive}
- isDocumentActive={isActive}
- styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider}
- fitContentsToBox={returnTrue}
- hideTitle={asText}
- hideDecorations={true}
- hideClickBehaviors={true}
- hideLinkButton={BoolCast(this.treeView.Document.childHideLinkButton)}
- dontRegisterView={BoolCast(this.treeView.Document.childDontRegisterViews, this._props.dontRegisterView)}
- ScreenToLocalTransform={this.docTransform}
- renderDepth={this._props.renderDepth + 1}
- onClickScript={this.onChildClick}
- onKey={this.onKeyDown}
- containerViewPath={this.treeView.childContainerViewPath}
- childFilters={returnEmptyFilter}
- childFiltersByRanges={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- focus={this.refocus}
- addDocument={this._props.addDocument}
- moveDocument={this.move}
- removeDocument={this._props.removeDoc}
- whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
- xPadding={NumCast(this.treeView.Document.childXPadding, this.treeView._props.childXPadding)}
- yPadding={NumCast(this.treeView.Document.childYPadding, this.treeView._props.childYPadding)}
- addDocTab={this._props.addDocTab}
- pinToPres={this.treeView._props.pinToPres}
- disableBrushing={this.treeView._props.disableBrushing}
- scriptContext={this}
/>
+ {contents}
</div>
- );
- };
+ {this.renderBorder}
+ </>
+ );
+
+ fitWidthFilter = (doc: Doc) => (doc.type === DocumentType.IMG ? false : undefined);
+ renderEmbeddedDocument = (asText: boolean, isActive: () => boolean | undefined) => (
+ <div style={{ height: this.embeddedPanelHeight(), width: this.embeddedPanelWidth() }}>
+ <DocumentView
+ key={this.Document[Id]}
+ ref={action((r: DocumentView | null) => {
+ this._dref = r;
+ })}
+ Document={this.Document}
+ fitWidth={this.fitWidthFilter}
+ PanelWidth={this.embeddedPanelWidth}
+ PanelHeight={this.embeddedPanelHeight}
+ LayoutTemplateString={asText ? FormattedTextBox.LayoutString('text') : undefined}
+ LayoutTemplate={this.treeView._props.childLayoutTemplate}
+ isContentActive={isActive}
+ isDocumentActive={isActive}
+ styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider}
+ fitContentsToBox={returnTrue}
+ hideTitle={asText}
+ hideDecorations
+ hideClickBehaviors
+ hideLinkButton={BoolCast(this.treeView.Document.childHideLinkButton)}
+ dontRegisterView={BoolCast(this.treeView.Document.childDontRegisterViews, this._props.dontRegisterView)}
+ ScreenToLocalTransform={this.docTransform}
+ renderDepth={this._props.renderDepth + 1}
+ onClickScript={this.onChildClick}
+ onKey={this.onKeyDown}
+ containerViewPath={this.treeView.childContainerViewPath}
+ childFilters={returnEmptyFilter}
+ childFiltersByRanges={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ focus={this.refocus}
+ addDocument={this._props.addDocument}
+ moveDocument={this.move}
+ removeDocument={this._props.removeDoc}
+ whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
+ xPadding={NumCast(this.treeView.Document.childXPadding, this.treeView._props.childXPadding)}
+ yPadding={NumCast(this.treeView.Document.childYPadding, this.treeView._props.childYPadding)}
+ addDocTab={this._props.addDocTab}
+ pinToPres={this.treeView._props.pinToPres}
+ disableBrushing={this.treeView._props.disableBrushing}
+ scriptContext={this}
+ />
+ </div>
+ );
// renders the text version of a document as the header. This is used in the file system mode and in other vanilla tree views.
@computed get renderTitleAsHeader() {
return this.treeView.Document.treeView_HideUnrendered && this.Document.layout_unrendered && !this.Document.treeView_FieldKey ? (
- <div></div>
+ <div />
) : (
<>
{this.renderBullet}
@@ -1136,14 +1172,12 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
}
// renders the document in the header field instead of a text proxy.
- renderDocumentAsHeader = (asText: boolean) => {
- return (
- <>
- {this.renderBullet}
- {this.renderEmbeddedDocument(asText, this._props.isContentActive)}
- </>
- );
- };
+ renderDocumentAsHeader = (asText: boolean) => (
+ <>
+ {this.renderBullet}
+ {this.renderEmbeddedDocument(asText, this._props.isContentActive)}
+ </>
+ );
@computed get renderBorder() {
const sorting = StrCast(this.Document.treeView_SortCriterion, TreeSort.WhenAdded);
@@ -1159,7 +1193,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
const pt = [de.clientX, de.clientY];
const rect = this._header.current!.getBoundingClientRect();
const before = pt[1] < rect.top + rect.height / 2;
- const inside = this.treeView.fileSysMode && !this.Document.isFolder ? false : pt[0] > rect.left + rect.width * 0.33 || (!before && this.treeViewOpen && this.childDocs?.length ? true : false);
+ const inside = this.treeView.fileSysMode && !this.Document.isFolder ? false : pt[0] > rect.left + rect.width * 0.33 || !!(!before && this.treeViewOpen && this.childDocs?.length);
this.treeView.onTreeDrop(de, (docs: Doc[]) => this.dropDocuments(docs, before, inside, dropActionType.copy, undefined, undefined, false, false));
};
@@ -1174,7 +1208,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
className={`treeView-container${this._props.isContentActive() ? '-active' : ''}`}
ref={this.createTreeDropTarget}
onDrop={this.onTreeDrop}
- //onPointerDown={e => this._props.isContentActive(true) && SelectionManager.DeselectAll()} // bcz: this breaks entering a text filter in a filterBox since it deselects the filter's target document
+ // onPointerDown={e => this._props.isContentActive(true) && DocumentView.DeselectAll()} // bcz: this breaks entering a text filter in a filterBox since it deselects the filter's target document
// onKeyDown={this.onKeyDown}
>
<li className="collection-child">
@@ -1198,11 +1232,10 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
const aN = parseInt(a.match(reN)![0], 10);
const bN = parseInt(b.match(reN)![0], 10);
return aN === bN ? 0 : aN > bN ? 1 : -1;
- } else {
- return aA > bA ? 1 : -1;
}
+ return aA > bA ? 1 : -1;
};
- docs.sort(function (d1, d2): 0 | 1 | -1 {
+ docs.sort((d1, d2): 0 | 1 | -1 => {
const a = criterion === TreeSort.AlphaUp ? d2 : d1;
const b = criterion === TreeSort.AlphaUp ? d1 : d2;
const first = a[criterion === TreeSort.Zindex ? 'zIndex' : 'title'];
@@ -1219,7 +1252,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
childDocs: Doc[],
treeView: CollectionTreeView,
parentTreeView: CollectionTreeView | TreeView | undefined,
- treeView_Parent: Doc,
+ treeViewParent: Doc,
dataDoc: Doc | undefined,
parentCollectionDoc: Doc | undefined,
containerPrevSibling: Doc | undefined,
@@ -1227,13 +1260,13 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
remove: undefined | ((doc: Doc | Doc[]) => boolean),
move: DragManager.MoveFunction,
dragAction: dropActionType,
- addDocTab: (doc: Doc, where: OpenWhere) => boolean,
+ addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean,
styleProvider: undefined | StyleProviderFuncType,
screenToLocalXf: () => Transform,
isContentActive: (outsideReaction?: boolean) => boolean,
panelWidth: () => number,
renderDepth: number,
- treeView_HideHeaderFields: () => boolean,
+ treeViewHideHeaderFields: () => boolean,
renderedIds: string[],
onCheckedClick: undefined | (() => ScriptField),
onChildClick: undefined | (() => ScriptField),
@@ -1250,19 +1283,14 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
hierarchyIndex?: number[],
renderCount?: number
) {
- const viewSpecScript = Cast(treeView_Parent.viewSpecScript, ScriptField);
- if (viewSpecScript) {
- childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
- }
-
- const docs = TreeView.sortDocs(childDocs, StrCast(treeView_Parent.treeView_SortCriterion, TreeSort.WhenAdded));
+ const docs = TreeView.sortDocs(childDocs, StrCast(treeViewParent.treeView_SortCriterion, TreeSort.WhenAdded));
const rowWidth = () => panelWidth() - treeBulletWidth() * (treeView._props.NativeDimScaling?.() || 1);
- const treeView_Refs = new Map<Doc, TreeView | undefined>();
+ const treeViewRefs = new Map<Doc, TreeView | undefined>();
return docs
.filter(child => child instanceof Doc)
.map((child, i) => {
if (renderCount && i > renderCount) return null;
- const pair = Doc.GetLayoutDataDocPair(treeView_Parent, dataDoc, child);
+ const pair = Doc.GetLayoutDataDocPair(treeViewParent, dataDoc, child);
if (!pair.layout || pair.data instanceof Promise) {
return null;
}
@@ -1272,14 +1300,14 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
const fieldKey = Doc.LayoutFieldKey(newParent);
if (remove && fieldKey && Cast(newParent[fieldKey], listSpec(Doc)) !== undefined) {
remove(child);
- FormattedTextBox.SetSelectOnLoad(child);
+ Doc.SetSelectOnLoad(child);
TreeView._editTitleOnLoad = editTitle ? { id: child[Id], parent } : undefined;
Doc.AddDocToList(newParent, fieldKey, child, addAfter, false);
newParent.treeView_Open = true;
Doc.SetContainer(child, treeView.Document);
}
};
- const indent = i === 0 ? undefined : (editTitle: boolean) => dentDoc(editTitle, docs[i - 1], undefined, treeView_Refs.get(docs[i - 1]));
+ const indent = i === 0 ? undefined : (editTitle: boolean) => dentDoc(editTitle, docs[i - 1], undefined, treeViewRefs.get(docs[i - 1]));
const outdent = !parentCollectionDoc ? undefined : (editTitle: boolean) => dentDoc(editTitle, parentCollectionDoc, containerPrevSibling, parentTreeView instanceof TreeView ? parentTreeView._props.parentTreeView : undefined);
const addDocument = (doc: Doc | Doc[], annotationKey?: string, relativeTo?: Doc, before?: boolean) => add(doc, relativeTo ?? docs[i], before !== undefined ? before : false);
const childLayout = Doc.Layout(pair.layout);
@@ -1290,12 +1318,11 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return (
<TreeView
key={child[Id]}
- ref={r => treeView_Refs.set(child, r ? r : undefined)}
+ ref={r => treeViewRefs.set(child, r || undefined)}
Document={pair.layout}
dataDoc={pair.data}
- treeViewParent={treeView_Parent}
+ treeViewParent={treeViewParent}
prevSibling={docs[i]}
- // TODO: [AL] add these
hierarchyIndex={hierarchyIndex ? [...hierarchyIndex, i + 1] : undefined}
AddToMap={AddToMap}
RemFromMap={RemFromMap}
@@ -1305,7 +1332,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
onCheckedClick={onCheckedClick}
onChildClick={onChildClick}
renderDepth={renderDepth}
- removeDoc={StrCast(treeView_Parent.treeView_FreezeChildren).includes('remove') ? undefined : remove}
+ removeDoc={StrCast(treeViewParent.treeView_FreezeChildren).includes('remove') ? undefined : remove}
addDocument={addDocument}
styleProvider={styleProvider}
panelWidth={rowWidth}
@@ -1316,7 +1343,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
addDocTab={addDocTab}
ScreenToLocalTransform={screenToLocalXf}
isContentActive={isContentActive}
- treeViewHideHeaderFields={treeView_HideHeaderFields}
+ treeViewHideHeaderFields={treeViewHideHeaderFields}
renderedIds={renderedIds}
skipFields={skipFields}
firstLevel={firstLevel}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
index 08dfb32ad..d2ce17f99 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
@@ -10,12 +10,13 @@ export interface CollectionFreeFormViewBackgroundGridProps {
PanelWidth: () => number;
PanelHeight: () => number;
color: () => string;
+ // eslint-disable-next-line react/require-default-props
isAnnotationOverlay?: boolean;
nativeDimScaling: () => number;
zoomScaling: () => number;
layoutDoc: Doc;
- cachedCenteringShiftX: number;
- cachedCenteringShiftY: number;
+ centeringShiftX: number;
+ centeringShiftY: number;
}
@observer
export class CollectionFreeFormBackgroundGrid extends React.Component<CollectionFreeFormViewBackgroundGridProps> {
@@ -32,7 +33,7 @@ export class CollectionFreeFormBackgroundGrid extends React.Component<Collection
const w = this.props.PanelWidth() / this.props.nativeDimScaling() + 2 * renderGridSpace;
const h = this.props.PanelHeight() / this.props.nativeDimScaling() + 2 * renderGridSpace;
const strokeStyle = this.props.color();
- return !this.props.nativeDimScaling() ? null : (
+ return (
<canvas
className="collectionFreeFormView-grid"
width={w}
@@ -41,8 +42,8 @@ export class CollectionFreeFormBackgroundGrid extends React.Component<Collection
ref={el => {
const ctx = el?.getContext('2d');
if (ctx) {
- const Cx = this.props.cachedCenteringShiftX % renderGridSpace;
- const Cy = this.props.cachedCenteringShiftY % renderGridSpace;
+ const Cx = this.props.centeringShiftX % renderGridSpace;
+ const Cy = this.props.centeringShiftY % renderGridSpace;
ctx.lineWidth = Math.min(1, Math.max(0.5, this.props.zoomScaling()));
ctx.setLineDash(gridSpace > 50 ? [3, 3] : [1, 5]);
ctx.clearRect(0, 0, w, h);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts b/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts
new file mode 100644
index 000000000..6ad67a864
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts
@@ -0,0 +1,217 @@
+import { action, observable } from 'mobx';
+import { CollectionFreeFormView } from '.';
+import { intersectRect } from '../../../../Utils';
+import { Doc, Opt } from '../../../../fields/Doc';
+import { NumCast, StrCast } from '../../../../fields/Types';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
+import { StyleProp } from '../../StyleProp';
+import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView';
+import { DocumentView } from '../../nodes/DocumentView';
+import { FieldViewProps } from '../../nodes/FieldView';
+import './CollectionFreeFormView.scss';
+
+export class CollectionFreeFormClusters {
+ private _view: CollectionFreeFormView;
+ private _clusterDistance: number = 75;
+ private _hitCluster: number = -1;
+ @observable _clusterSets: Doc[][] = [];
+
+ constructor(view: CollectionFreeFormView) {
+ this._view = view;
+ }
+ get Document() { return this._view.Document; } // prettier-ignore
+ get DocumentView() { return this._view.DocumentView?.(); } // prettier-ignore
+ get childDocs() { return this._view.childDocs; } // prettier-ignore
+ get childLayoutPairs() { return this._view.childLayoutPairs; } // prettier-ignore
+ get screenToContentsXf() { return this._view.screenToFreeformContentsXf; } // prettier-ignore
+ get viewStyleProvider() { return this._view._props.styleProvider; } // prettier-ignore
+ get viewMoveDocument() { return this._view._props.moveDocument; } // prettier-ignore
+ get selectDocuments() { return this._view.selectDocuments; } // prettier-ignore
+
+ static overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) {
+ const doc2Layout = Doc.Layout(doc2);
+ const doc1Layout = Doc.Layout(doc1);
+ const x2 = NumCast(doc2.x) - clusterDistance;
+ const y2 = NumCast(doc2.y) - clusterDistance;
+ const w2 = NumCast(doc2Layout._width) + clusterDistance;
+ const h2 = NumCast(doc2Layout._height) + clusterDistance;
+ const x = NumCast(doc1.x) - clusterDistance;
+ const y = NumCast(doc1.y) - clusterDistance;
+ const w = NumCast(doc1Layout._width) + clusterDistance;
+ const h = NumCast(doc1Layout._height) + clusterDistance;
+ return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
+ }
+ handlePointerDown(probe: number[]) {
+ this._hitCluster = this.childLayoutPairs
+ .map(pair => pair.layout)
+ .reduce((cluster, cd) => {
+ const grouping = this.Document._freeform_useClusters ? NumCast(cd.layout_cluster, -1) : NumCast(cd.group, -1);
+ if (grouping !== -1) {
+ const layoutDoc = Doc.Layout(cd);
+ const cx = NumCast(cd.x) - this._clusterDistance / 2;
+ const cy = NumCast(cd.y) - this._clusterDistance / 2;
+ const cw = NumCast(layoutDoc._width) + this._clusterDistance;
+ const ch = NumCast(layoutDoc._height) + this._clusterDistance;
+ return !layoutDoc.z && intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 }) ? grouping : cluster;
+ }
+ return cluster;
+ }, -1);
+ return this._hitCluster;
+ }
+
+ tryToDrag(e: PointerEvent) {
+ const cluster = this._hitCluster;
+ if (cluster !== -1) {
+ const ptsParent = e;
+ if (ptsParent) {
+ const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.Document._freeform_useClusters ? NumCast(cd.layout_cluster) : NumCast(cd.group, -1)) === cluster);
+ const clusterDocs = eles.map(ele => DocumentView.getDocumentView(ele, this.DocumentView)!);
+ const { left, top } = clusterDocs[0].getBounds || { left: 0, top: 0 };
+ const de = new DragManager.DocumentDragData(eles, e.ctrlKey || e.altKey ? dropActionType.embed : undefined);
+ de.moveDocument = this.viewMoveDocument;
+ de.offset = this.screenToContentsXf.transformDirection(ptsParent.clientX - left, ptsParent.clientY - top);
+ DragManager.StartDocumentDrag(
+ clusterDocs.map(v => v.ContentDiv!),
+ de,
+ ptsParent.clientX,
+ ptsParent.clientY,
+ { hideSource: !de.dropAction }
+ );
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ initLayout() {
+ if (this.Document._freeform_useClusters && !this._clusterSets.length && this.childDocs.length) {
+ return this.updateClusters(true);
+ }
+ return false;
+ }
+ @action
+ updateClusters(useClusters: boolean) {
+ this.Document._freeform_useClusters = useClusters;
+ this._clusterSets.length = 0;
+ this.childLayoutPairs.map(pair => pair.layout).map(c => this.addDocument(c));
+ }
+
+ @action
+ addDocuments(docs: Doc[]) {
+ const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
+ if (this.Document._freeform_useClusters) {
+ const docFirst = docs[0];
+ docs.forEach(doc => this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)));
+ const preferredInd = NumCast(docFirst.layout_cluster);
+ docs.forEach(doc => {
+ doc.layout_cluster = -1;
+ });
+ docs.map(doc =>
+ this._clusterSets.map((set, i) =>
+ set.forEach(member => {
+ if (docFirst.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && CollectionFreeFormClusters.overlapping(doc, member, this._clusterDistance)) {
+ docFirst.layout_cluster = i;
+ }
+ })
+ )
+ );
+ if (
+ docFirst.layout_cluster === -1 &&
+ preferredInd !== -1 &&
+ this._clusterSets.length > preferredInd &&
+ (!this._clusterSets[preferredInd] || !this._clusterSets[preferredInd].filter(member => Doc.IndexOf(member, childLayouts) !== -1).length)
+ ) {
+ docFirst.layout_cluster = preferredInd;
+ }
+ this._clusterSets.forEach((set, i) => {
+ if (docFirst.layout_cluster === -1 && !set.filter(member => Doc.IndexOf(member, childLayouts) !== -1).length) {
+ docFirst.layout_cluster = i;
+ }
+ });
+ if (docFirst.layout_cluster === -1) {
+ docs.forEach(doc => {
+ doc.layout_cluster = this._clusterSets.length;
+ this._clusterSets.push([doc]);
+ });
+ } else if (this._clusterSets.length) {
+ for (let i = this._clusterSets.length; i <= NumCast(docFirst.layout_cluster); i++) !this._clusterSets[i] && this._clusterSets.push([]);
+ docs.forEach(doc => {
+ this._clusterSets[(doc.layout_cluster = NumCast(docFirst.layout_cluster))].push(doc);
+ });
+ }
+ childLayouts.map(child => !this._clusterSets.some((set, i) => Doc.IndexOf(child, set) !== -1 && child.layout_cluster === i) && this.addDocument(child));
+ }
+ }
+
+ @action
+ addDocument = (doc: Doc) => {
+ const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
+ if (this.Document._freeform_useClusters) {
+ this._clusterSets.forEach(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1));
+ const preferredInd = NumCast(doc.layout_cluster);
+ doc.layout_cluster = -1;
+ this._clusterSets.forEach((set, i) =>
+ set.forEach(member => {
+ if (doc.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && CollectionFreeFormClusters.overlapping(doc, member, this._clusterDistance)) {
+ doc.layout_cluster = i;
+ }
+ })
+ );
+ if (doc.layout_cluster === -1 && preferredInd !== -1 && this._clusterSets.length > preferredInd && (!this._clusterSets[preferredInd] || !this._clusterSets[preferredInd].filter(member => Doc.IndexOf(member, childLayouts) !== -1).length)) {
+ doc.layout_cluster = preferredInd;
+ }
+ this._clusterSets.forEach((set, i) => {
+ if (doc.layout_cluster === -1 && !set.filter(member => Doc.IndexOf(member, childLayouts) !== -1).length) {
+ doc.layout_cluster = i;
+ }
+ });
+ if (doc.layout_cluster === -1) {
+ doc.layout_cluster = this._clusterSets.length;
+ this._clusterSets.push([doc]);
+ } else if (this._clusterSets.length) {
+ for (let i = this._clusterSets.length; i <= doc.layout_cluster; i++) !this._clusterSets[i] && this._clusterSets.push([]);
+ this._clusterSets[doc.layout_cluster ?? 0].push(doc);
+ }
+ }
+ };
+
+ styleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => {
+ if (doc && this.childDocs?.includes(doc))
+ switch (property.split(':')[0]) {
+ case StyleProp.BackgroundColor:
+ {
+ const cluster = NumCast(doc?.layout_cluster);
+ if (this.Document._freeform_useClusters && doc?.type !== DocumentType.IMG) {
+ if (this._clusterSets.length <= cluster) {
+ setTimeout(() => doc && this.addDocument(doc));
+ } else {
+ const palette = ['#da42429e', '#31ea318c', 'rgba(197, 87, 20, 0.55)', '#4a7ae2c4', 'rgba(216, 9, 255, 0.5)', '#ff7601', '#1dffff', 'yellow', 'rgba(27, 130, 49, 0.55)', 'rgba(0, 0, 0, 0.268)'];
+ // override palette cluster color with an explicitly set cluster doc color
+ return this._clusterSets[cluster]?.reduce((b, s) => StrCast(s.backgroundColor, b), palette[cluster % palette.length]);
+ }
+ }
+ }
+ break;
+ case StyleProp.FillColor:
+ if (doc && this.Document._currentFrame !== undefined) {
+ return CollectionFreeFormDocumentView.getStringValues(doc, NumCast(this.Document._currentFrame))?.fillColor;
+ }
+ break;
+ default:
+ }
+ return this.viewStyleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1
+ };
+
+ tryToSelect = (addToSel: boolean) => {
+ if (addToSel && this._hitCluster !== -1) {
+ !addToSel && DocumentView.DeselectAll();
+ const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.Document._freeform_useClusters ? NumCast(cd.layout_cluster) : NumCast(cd.group, -1)) === this._hitCluster);
+ this.selectDocuments(eles);
+ return true;
+ }
+ return false;
+ };
+}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
index 58f6b1593..fc39cafaa 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
@@ -5,28 +5,28 @@ import * as React from 'react';
import { SettingsManager } from '../../../util/SettingsManager';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import './CollectionFreeFormView.scss';
-// import assets from './assets/link.png';
/**
* An Fsa Arc. The first array element is a test condition function that will be observed.
* The second array element is a function that will be invoked when the first test function
* returns a truthy value
*/
+// eslint-disable-next-line no-use-before-define
export type infoArc = [() => any, (res?: any) => infoState];
export const StateMessage = Symbol('StateMessage');
-export const StateEntryFunc = Symbol('StateEntryFunc');
export const StateMessageGIF = Symbol('StateMessageGIF');
+export const StateEntryFunc = Symbol('StateEntryFunc');
export class infoState {
[StateMessage]: string = '';
- [StateEntryFunc]?: () => any;
[StateMessageGIF]?: string = '';
+ [StateEntryFunc]?: () => any;
[key: string]: infoArc;
- constructor(message: string, arcs: { [key: string]: infoArc }, entryFunc?: () => any, messageGif?: string) {
+ constructor(message: string, arcs: { [key: string]: infoArc }, messageGif?: string, entryFunc?: () => any) {
this[StateMessage] = message;
Object.assign(this, arcs);
- this[StateEntryFunc] = entryFunc;
this[StateMessageGIF] = messageGif;
+ this[StateEntryFunc] = entryFunc;
}
}
@@ -36,16 +36,18 @@ export class infoState {
* @param arcs an object with fields containing @infoArcs (an object with field names indicating the arc transition and
* field values being a tuple of an arc transition trigger function (that returns a truthy value when the arc should fire),
* and an arc transition action function (that sets the next state)
+ * @param gif the gif displayed when in this state
* @param entryFunc a function to call when entering the state
* @returns an FSA state
*/
export function InfoState(
msg: string, //
arcs: { [key: string]: infoArc },
- entryFunc?: () => any,
- gif?: string
+ gif?: string,
+ entryFunc?: () => any
) {
- return new infoState(msg, arcs, entryFunc, gif);
+ // eslint-disable-next-line new-cap
+ return new infoState(msg, arcs, gif, entryFunc);
}
export interface CollectionFreeFormInfoStateProps {
@@ -57,7 +59,7 @@ export interface CollectionFreeFormInfoStateProps {
@observer
export class CollectionFreeFormInfoState extends ObservableReactComponent<CollectionFreeFormInfoStateProps> {
_disposers: IReactionDisposer[] = [];
- @observable _hide = false;
+ @observable _expanded = false;
constructor(props: any) {
super(props);
@@ -72,22 +74,17 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec
}
clearState = () => this._disposers.map(disposer => disposer());
- initState = () =>
- (this._disposers = this.Arcs.map(arc => ({ test: arc[0], act: arc[1] })).map(arc => {
- return reaction(
- //
- arc.test,
- res => {
- if (res) {
- const next = arc.act(res);
- this._props.next(next);
- }
- },
- { fireImmediately: true }
- );
- }));
+ initState = () => {
+ this._disposers = this.Arcs
+ .map(arc => ({ test: arc[0], act: arc[1] }))
+ .map(arc => reaction(
+ arc.test,
+ res => res && this._props.next(arc.act(res)),
+ { fireImmediately: true }
+ )
+ )}; // prettier-ignore
- componentDidMount(): void {
+ componentDidMount() {
this.initState();
}
componentDidUpdate(prevProps: Readonly<CollectionFreeFormInfoStateProps>) {
@@ -95,18 +92,30 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec
this.clearState();
this.initState();
}
- componentWillUnmount(): void {
+ componentWillUnmount() {
this.clearState();
}
+
render() {
+ const gif = this.State?.[StateMessageGIF];
return (
- <div className="collectionFreeform-infoUI" style={{ display: this._hide ? 'none' : undefined }}>
- <div className="msg">{this.State?.[StateMessage]}</div>
- <div className="gif-container" style={{ display: this.State?.[StateMessageGIF] ? undefined : 'none' }}>
- <img className="gif" src={this.State?.[StateMessageGIF]} alt="state message gif"></img>
+ <div className="collectionFreeform-infoUI">
+ <p className="collectionFreeform-infoUI-msg">
+ {this.State?.[StateMessage]}
+ <button
+ type="button"
+ className={'collectionFreeform-' + (!gif ? 'hidden' : 'infoUI-button')}
+ onClick={action(() => {
+ this._expanded = !this._expanded;
+ })}>
+ {this._expanded ? 'Less...' : 'More...'}
+ </button>
+ </p>
+ <div className={'collectionFreeform-' + (!this._expanded || !gif ? 'hidden' : 'infoUI-gif-container')}>
+ <img src={`/assets/${gif}`} alt="state message gif" />
</div>
- <div style={{ position: 'absolute', top: -10, left: -10 }}>
- <IconButton icon="x" color={SettingsManager.userColor} size={Size.XSMALL} type={Type.TERT} background={SettingsManager.userBackgroundColor} onClick={action(e => this.props.close())} />
+ <div className="collectionFreeform-infoUI-close">
+ <IconButton icon="x" color={SettingsManager.userColor} size={Size.XSMALL} type={Type.TERT} background={SettingsManager.userBackgroundColor} onClick={action(() => this.props.close())} />
</div>
</div>
);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx
index 43b877705..5d8373fc7 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx
@@ -1,40 +1,47 @@
import { makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, Field, FieldResult } from '../../../../fields/Doc';
+import { Doc, DocListCast, FieldType, FieldResult } from '../../../../fields/Doc';
import { InkTool } from '../../../../fields/InkField';
import { StrCast } from '../../../../fields/Types';
-import { DocumentManager } from '../../../util/DocumentManager';
-import { LinkManager } from '../../../util/LinkManager';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton';
+import { TopBar } from '../../topbar/TopBar';
import { CollectionFreeFormInfoState, InfoState, StateEntryFunc, infoState } from './CollectionFreeFormInfoState';
-import { CollectionFreeFormView } from './CollectionFreeFormView';
import './CollectionFreeFormView.scss';
+import { DocData } from '../../../../fields/DocSymbols';
+import { CollectionFreeFormView } from './CollectionFreeFormView';
export interface CollectionFreeFormInfoUIProps {
Document: Doc;
- Freeform: CollectionFreeFormView;
- close: () => boolean;
+ LayoutDoc: Doc;
+ childDocs: () => Doc[];
+ close: () => void;
}
@observer
export class CollectionFreeFormInfoUI extends ObservableReactComponent<CollectionFreeFormInfoUIProps> {
+ public static Init() {
+ CollectionFreeFormView.SetInfoUICreator((doc: Doc, layout: Doc, childDocs: () => Doc[], close: () => void) => (
+ //
+ <CollectionFreeFormInfoUI Document={doc} LayoutDoc={layout} childDocs={childDocs} close={close} />
+ ));
+ }
_firstDocPos = { x: 0, y: 0 };
constructor(props: any) {
super(props);
makeObservable(this);
- this.currState = this.setupStates();
+ this._currState = this.setupStates();
}
_originalbackground: string | undefined;
@observable _currState: infoState | undefined = undefined;
- get currState() { return this._currState!; } // prettier-ignore
- set currState(val) { runInAction(() => (this._currState = val)); } // prettier-ignore
+ get currState() { return this._currState; } // prettier-ignore
+ set currState(val) { runInAction(() => {this._currState = val;}); } // prettier-ignore
componentWillUnmount(): void {
- this._props.Freeform.dataDoc.backgroundColor = this._originalbackground;
+ this._props.Document[DocData].backgroundColor = this._originalbackground;
}
setCurrState = (state: infoState) => {
@@ -45,23 +52,24 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio
};
setupStates = () => {
- this._originalbackground = StrCast(this._props.Freeform.dataDoc.backgroundColor);
+ this._originalbackground = StrCast(this._props.Document[DocData].backgroundColor);
// state entry functions
- const setBackground = (colour: string) => () => (this._props.Freeform.dataDoc.backgroundColor = colour);
- const setOpacity = (opacity: number) => () => (this._props.Freeform.layoutDoc.opacity = opacity);
+ // const setBackground = (colour: string) => () => {this._props.Document[DocData].backgroundColor = colour;} // prettier-ignore
+ // const setOpacity = (opacity: number) => () => {this._props.LayoutDoc.opacity = opacity;} // prettier-ignore
// arc transition trigger conditions
- const firstDoc = () => (this._props.Freeform.childDocs.length ? this._props.Freeform.childDocs[0] : undefined);
- const numDocs = () => this._props.Freeform.childDocs.length;
+ const firstDoc = () => (this._props.childDocs().length ? this._props.childDocs()[0] : undefined);
+ const numDocs = () => this._props.childDocs().length;
- let docX: FieldResult<Field>;
- let docY: FieldResult<Field>;
+ let docX: FieldResult<FieldType>;
+ let docY: FieldResult<FieldType>;
const docNewX = () => firstDoc()?.x;
const docNewY = () => firstDoc()?.y;
const linkStart = () => DocumentLinksButton.StartLink;
+ const linkUnstart = () => !DocumentLinksButton.StartLink;
- const numDocLinks = () => LinkManager.Instance.getAllDirectLinks(firstDoc())?.length;
+ const numDocLinks = () => Doc.Links(firstDoc())?.length;
const linkMenuOpen = () => DocButtonState.Instance.LinkEditorDocView;
const activeTool = () => Doc.ActiveTool;
@@ -70,85 +78,96 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio
let trail: number;
- const trailView = () => DocumentManager.Instance.DocumentViews.find(view => view.Document === Doc.MyTrails);
const presentationMode = () => Doc.ActivePresentation?.presentation_status;
// set of states
- const start = InfoState('Click anywhere and begin typing to create your first text document.', {
- docCreated: [() => numDocs(), () => {
- docX = firstDoc()?.x;
- docY = firstDoc()?.y;
- return oneDoc;
- }],
- }, setBackground("blue")); // prettier-ignore
-
- const oneDoc = InfoState('Hello world! You can drag and drop to move your document around.', {
- // docCreated: [() => numDocs() > 1, () => multipleDocs],
- docDeleted: [() => numDocs() < 1, () => start],
- docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => {
- docX = firstDoc()?.x;
- docY = firstDoc()?.y;
- return movedDoc1;
- }],
- }, setBackground("red")); // prettier-ignore
-
- const movedDoc1 = InfoState('Great moves. Try creating a second document.', {
- docCreated: [() => numDocs() == 2, () => multipleDocs],
- docDeleted: [() => numDocs() < 1, () => start],
- docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => {
- docX = firstDoc()?.x;
- docY = firstDoc()?.y;
- return movedDoc2;
- }],
- }, setBackground("yellow")); // prettier-ignore
-
- const movedDoc2 = InfoState('Slick moves. Try creating a second document.', {
- docCreated: [() => numDocs() == 2, () => multipleDocs],
- docDeleted: [() => numDocs() < 1, () => start],
- docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => {
- docX = firstDoc()?.x;
- docY = firstDoc()?.y;
- return movedDoc3;
- }],
- }, setBackground("pink")); // prettier-ignore
-
- const movedDoc3 = InfoState('Groovy moves. Try creating a second document.', {
- docCreated: [() => numDocs() == 2, () => multipleDocs],
- docDeleted: [() => numDocs() < 1, () => start],
- docMoved: [() => (docX && docX != docNewX()) || (docY && docY != docNewY()), () => {
- docX = firstDoc()?.x;
- docY = firstDoc()?.y;
- return movedDoc1;
- }],
- }, setBackground("green")); // prettier-ignore
-
- const multipleDocs = InfoState('Let\'s create a new link. Click the link icon on one of your documents.', {
- linkStarted: [() => linkStart(), () => startedLink],
- docRemoved: [() => numDocs() < 2, () => oneDoc],
- }, setBackground("purple")); // prettier-ignore
-
- const startedLink = InfoState('Now click the highlighted link icon on your other document.', {
- linkCreated: [() => numDocLinks(), () => madeLink],
- docRemoved: [() => numDocs() < 2, () => oneDoc],
- }, setBackground("orange")); // prettier-ignore
-
- const madeLink = InfoState('You made your first link! You can view your links by selecting the blue dot.', {
- linkCreated: [() => !numDocLinks(), () => multipleDocs],
- linkViewed: [() => linkMenuOpen(), () => {
- alert(numDocLinks() + " cheer for " + numDocLinks() + " link!");
- return viewedLink;
- }],
- }, setBackground("blue")); // prettier-ignore
-
- const viewedLink = InfoState('Great work. You are now ready to create your own hypermedia world.', {
- linkDeleted: [() => !numDocLinks(), () => multipleDocs],
- docRemoved: [() => numDocs() < 2, () => oneDoc],
- docCreated: [() => numDocs() == 3, () => {
- trail = pin().length;
- return presentDocs;
- }],
- activePen: [() => activeTool() === InkTool.Pen, () => penMode],
- }, setBackground("black")); // prettier-ignore
+ const start = InfoState(
+ 'Click anywhere and begin typing to create your first text document.',
+ {
+ docCreated: [() => numDocs(), () => {
+ docX = firstDoc()?.x;
+ docY = firstDoc()?.y;
+ // eslint-disable-next-line no-use-before-define
+ return oneDoc;
+ }],
+ }
+ ); // prettier-ignore
+
+ const oneDoc = InfoState(
+ 'Hello world! You can drag and drop to move your document around.',
+ {
+ // docCreated: [() => numDocs() > 1, () => multipleDocs],
+ docDeleted: [() => numDocs() < 1, () => start],
+ docMoved: [() => (docX && docX !== docNewX()) || (docY && docY !== docNewY()), () => {
+ docX = firstDoc()?.x;
+ docY = firstDoc()?.y;
+ // eslint-disable-next-line no-use-before-define
+ return movedDoc;
+ }],
+ }
+ ); // prettier-ignore
+
+ const movedDoc = InfoState(
+ 'Great moves. Try creating a second document. You can see the list of supported document types by typing a colon (":")',
+ {
+ // eslint-disable-next-line no-use-before-define
+ docCreated: [() => numDocs() === 2, () => multipleDocs],
+ docDeleted: [() => numDocs() < 1, () => start],
+ },
+ 'dash-colon-menu.gif',
+ () => TopBar.Instance.FlipDocumentationIcon()
+ ); // prettier-ignore
+
+ const multipleDocs = InfoState(
+ 'Let\'s create a new link. Click the link icon on one of your documents.',
+ {
+ // eslint-disable-next-line no-use-before-define
+ linkStarted: [() => linkStart(), () => startedLink],
+ docRemoved: [() => numDocs() < 2, () => oneDoc],
+ },
+ 'dash-create-link-board.gif'
+ ); // prettier-ignore
+
+ const startedLink = InfoState(
+ 'Now click the highlighted link icon on your other document.',
+ {
+ linkUnstart: [() => linkUnstart(), () => multipleDocs],
+ // eslint-disable-next-line no-use-before-define
+ linkCreated: [() => numDocLinks(), () => madeLink],
+ docRemoved: [() => numDocs() < 2, () => oneDoc],
+ },
+ 'dash-create-link-board.gif'
+ ); // prettier-ignore
+
+ const madeLink = InfoState(
+ 'You made your first link! You can view your links by selecting the blue dot.',
+ {
+ linkCreated: [() => !numDocLinks(), () => multipleDocs],
+ linkViewed: [() => linkMenuOpen(), () => {
+ alert(numDocLinks() + " cheer for " + numDocLinks() + " link!");
+ // eslint-disable-next-line no-use-before-define
+ return viewedLink;
+ }],
+ },
+ 'dash-following-link.gif'
+ ); // prettier-ignore
+
+ const viewedLink = InfoState(
+ 'Great work. You are now ready to create your own hypermedia world. Click the ? icon in the top right corner to learn more.',
+ {
+ linkDeleted: [() => !numDocLinks(), () => multipleDocs],
+ docRemoved: [() => numDocs() < 2, () => oneDoc],
+ docCreated: [() => numDocs() === 3, () => {
+ trail = pin().length;
+ // eslint-disable-next-line no-use-before-define
+ return presentDocs;
+ }],
+ // eslint-disable-next-line no-use-before-define
+ activePen: [() => activeTool() === InkTool.Pen, () => penMode],
+ },
+ 'documentation.png',
+ () => TopBar.Instance.FlipDocumentationIcon()
+ ); // prettier-ignore
const presentDocs = InfoState(
'Another document! You could make a presentation. Click the pin icon in the top left corner.',
@@ -157,12 +176,12 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio
() => pin().length > trail,
() => {
trail = pin().length;
+ // eslint-disable-next-line no-use-before-define
return pinnedDoc1;
},
],
docRemoved: [() => numDocs() < 3, () => viewedLink],
},
- setBackground('black'),
'/assets/dash-pin-with-view.gif'
);
@@ -180,11 +199,13 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio
() => pin().length > trail,
() => {
trail = pin().length;
+ // eslint-disable-next-line no-use-before-define
return pinnedDoc2;
},
],
// editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
// manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
+ // eslint-disable-next-line no-use-before-define
autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
docRemoved: [() => numDocs() < 3, () => viewedLink],
});
@@ -194,11 +215,13 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio
() => pin().length > trail,
() => {
trail = pin().length;
+ // eslint-disable-next-line no-use-before-define
return pinnedDoc3;
},
],
// editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
// manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
+ // eslint-disable-next-line no-use-before-define
autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
docRemoved: [() => numDocs() < 3, () => viewedLink],
});
@@ -213,6 +236,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio
],
// editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
// manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
+ // eslint-disable-next-line no-use-before-define
autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
docRemoved: [() => numDocs() < 3, () => viewedLink],
});
@@ -230,26 +254,32 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent<Collectio
const manualPresentationMode = InfoState("You're in manual presentation mode.", {
// editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
+ // eslint-disable-next-line no-use-before-define
autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
docRemoved: [() => numDocs() < 3, () => viewedLink],
- docCreated: [() => numDocs() == 4, () => completed],
+ // eslint-disable-next-line no-use-before-define
+ docCreated: [() => numDocs() === 4, () => completed],
});
const autoPresentationMode = InfoState("You're in auto presentation mode.", {
// editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
docRemoved: [() => numDocs() < 3, () => viewedLink],
- docCreated: [() => numDocs() == 4, () => completed],
+ // eslint-disable-next-line no-use-before-define
+ docCreated: [() => numDocs() === 4, () => completed],
});
- const completed = InfoState('Eager to learn more? Click the ? icon in the top right corner to read our full documentation.', {
- docRemoved: [() => numDocs() == 1, () => oneDoc],
- }, setBackground("white")); // prettier-ignore
+ const completed = InfoState(
+ 'Eager to learn more? Click the ? icon in the top right corner to read our full documentation.',
+ { docRemoved: [() => numDocs() === 1, () => oneDoc] },
+ 'documentation.png',
+ () => TopBar.Instance.FlipDocumentationIcon()
+ ); // prettier-ignore
return start;
};
render() {
- return <CollectionFreeFormInfoState next={this.setCurrState} close={this._props.close} infoState={this.currState} />;
+ return !this.currState ? null : <CollectionFreeFormInfoState next={this.setCurrState} close={this._props.close} infoState={this.currState} />;
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index b8c0967c1..a4496a417 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -1,11 +1,11 @@
-import { Doc, Field, FieldResult } from '../../../../fields/Doc';
+/* eslint-disable no-use-before-define */
+import { Doc, Field, FieldType, FieldResult } from '../../../../fields/Doc';
import { Id, ToString } from '../../../../fields/FieldSymbols';
import { ObjectField } from '../../../../fields/ObjectField';
import { RefField } from '../../../../fields/RefField';
import { listSpec } from '../../../../fields/Schema';
import { Cast, NumCast, StrCast } from '../../../../fields/Types';
import { aggregateBounds } from '../../../../Utils';
-import * as React from 'react';
export interface ViewDefBounds {
type: string;
@@ -49,9 +49,9 @@ export interface PoolData {
export interface ViewDefResult {
ele: JSX.Element;
bounds?: ViewDefBounds;
- inkMask?: number; //sort elements into either the mask layer (which has a mixedBlendMode appropriate for transparent masks), or the regular documents layer; -1 = no mask, 0 = mask layer but stroke is transparent (hidden, as in during a presentation when you want to smoothly animate it into being a mask), >0 = mask layer and not hidden
+ inkMask?: number; // sort elements into either the mask layer (which has a mixedBlendMode appropriate for transparent masks), or the regular documents layer; -1 = no mask, 0 = mask layer but stroke is transparent (hidden, as in during a presentation when you want to smoothly animate it into being a mask), >0 = mask layer and not hidden
}
-function toLabel(target: FieldResult<Field>) {
+function toLabel(target: FieldResult<FieldType>) {
if (typeof target === 'number' || Number(target)) {
const truncated = Number(Number(target).toFixed(0));
const precise = Number(Number(target).toFixed(2));
@@ -85,9 +85,9 @@ interface PivotColumn {
filters: string[];
}
-export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) {
+export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[] /* , engineProps: any */) {
const docMap = new Map<string, PoolData>();
- childPairs.forEach(({ layout, data }, i) => {
+ childPairs.forEach(({ layout, data }) => {
docMap.set(layout[Id], {
x: NumCast(layout.x),
y: NumCast(layout.y),
@@ -98,10 +98,15 @@ export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc
replica: '',
});
});
+ // eslint-disable-next-line no-use-before-define
return normalizeResults(panelDim, 12, docMap, poolData, viewDefsToJSX, [], 0, []);
}
-export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) {
+function toNumber(val: FieldResult<FieldType>) {
+ return val === undefined ? undefined : NumCast(val, Number(StrCast(val)));
+}
+
+export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[] /* , engineProps: any */) {
const docMap = new Map<string, PoolData>();
const burstDiam = [NumCast(pivotDoc._width), NumCast(pivotDoc._height)];
const burstScale = NumCast(pivotDoc._starburstDocScale, 1);
@@ -129,23 +134,23 @@ export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc
export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) {
const docMap = new Map<string, PoolData>();
const fieldKey = 'data';
- const pivotColumnGroups = new Map<FieldResult<Field>, PivotColumn>();
+ const pivotColumnGroups = new Map<FieldResult<FieldType>, PivotColumn>();
let nonNumbers = 0;
const pivotFieldKey = toLabel(engineProps?.pivotField ?? pivotDoc._pivotField) || 'author';
- childPairs.map(pair => {
+ childPairs.forEach(pair => {
const listValue = Cast(pair.layout[pivotFieldKey], listSpec('string'), null);
const num = toNumber(pair.layout[pivotFieldKey]);
- if (num === undefined || Number.isNaN(num)) {
+ if (num === undefined || isNaN(num)) {
nonNumbers++;
}
- const val = Field.toString(pair.layout[pivotFieldKey] as Field);
+ const val = Field.toString(pair.layout[pivotFieldKey] as FieldType);
if (listValue) {
- listValue.forEach((val, i) => {
- !pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val], replicas: [] });
- pivotColumnGroups.get(val)!.docs.push(pair.layout);
- pivotColumnGroups.get(val)!.replicas.push(i.toString());
+ listValue.forEach((lval, i) => {
+ !pivotColumnGroups.get(lval) && pivotColumnGroups.set(lval, { docs: [], filters: [lval], replicas: [] });
+ pivotColumnGroups.get(lval)!.docs.push(pair.layout);
+ pivotColumnGroups.get(lval)!.replicas.push(i.toString());
});
} else if (val) {
!pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val], replicas: [] });
@@ -185,11 +190,11 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
const textlen = Array.from(pivotColumnGroups.keys())
.map(c => getTextWidth(toLabel(c), desc))
.reduce((p, c) => Math.max(p, c), 0 as number);
- const max_text = Math.min(Math.ceil(textlen / 120) * 28, panelDim[1] / 2);
+ const maxText = Math.min(Math.ceil(textlen / 120) * 28, panelDim[1] / 2);
const maxInColumn = Array.from(pivotColumnGroups.values()).reduce((p, s) => Math.max(p, s.docs.length), 1);
const colWidth = panelDim[0] / pivotColumnGroups.size;
- const colHeight = panelDim[1] - max_text;
+ const colHeight = panelDim[1] - maxText;
let numCols = 0;
let bestArea = 0;
let pivotAxisWidth = 0;
@@ -213,7 +218,7 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
let x = 0;
const sortedPivotKeys = pivotNumbers ? Array.from(pivotColumnGroups.keys()).sort((n1: FieldResult, n2: FieldResult) => toNumber(n1)! - toNumber(n2)!) : Array.from(pivotColumnGroups.keys()).sort();
sortedPivotKeys.forEach(key => {
- const val = pivotColumnGroups.get(key)!;
+ const val = pivotColumnGroups.get(key);
let y = 0;
let xCount = 0;
const text = toLabel(key);
@@ -223,11 +228,11 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
x,
y: pivotAxisWidth,
width: pivotAxisWidth * expander * numCols,
- height: max_text,
+ height: maxText,
fontSize,
payload: val,
});
- val.docs.forEach((doc, i) => {
+ val?.docs.forEach((doc, i) => {
const layoutDoc = Doc.Layout(doc);
let wid = pivotAxisWidth;
let hgt = pivotAxisWidth / (Doc.NativeAspect(layoutDoc) || 1);
@@ -240,6 +245,7 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
y: -y + (pivotAxisWidth - hgt) / 2,
width: wid,
height: hgt,
+ backgroundColor: StrCast(layoutDoc.backgroundColor),
pair: { layout: doc },
replica: val.replicas[i],
});
@@ -262,19 +268,16 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
payload: pivotColumnGroups.get(key)!.filters,
}));
groupNames.push(...dividers);
- return normalizeResults(panelDim, max_text, docMap, poolData, viewDefsToJSX, groupNames, 0, []);
-}
-
-function toNumber(val: FieldResult<Field>) {
- return val === undefined ? undefined : NumCast(val, Number(StrCast(val)));
+ // eslint-disable-next-line no-use-before-define
+ return normalizeResults(panelDim, maxText, docMap, poolData, viewDefsToJSX, groupNames, 0, []);
}
-export function computeTimelineLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps?: any) {
+export function computeTimelineLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[] /* , engineProps?: any */) {
const fieldKey = 'data';
const pivotDateGroups = new Map<number, Doc[]>();
const docMap = new Map<string, PoolData>();
const groupNames: ViewDefBounds[] = [];
- const timelineFieldKey = Field.toString(pivotDoc._pivotField as Field);
+ const timelineFieldKey = Field.toString(pivotDoc._pivotField as FieldType);
const curTime = toNumber(pivotDoc[fieldKey + '-timelineCur']);
const curTimeSpan = Cast(pivotDoc[fieldKey + '-timelineSpan'], 'number', null);
const minTimeReq = curTimeSpan === undefined ? Cast(pivotDoc[fieldKey + '-timelineMinReq'], 'number', null) : curTime && curTime - curTimeSpan;
@@ -290,7 +293,7 @@ export function computeTimelineLayout(poolData: Map<string, PoolData>, pivotDoc:
let maxTime = maxTimeReq === undefined ? -Number.MAX_VALUE : maxTimeReq;
childPairs.forEach(pair => {
const num = NumCast(pair.layout[timelineFieldKey], Number(StrCast(pair.layout[timelineFieldKey])));
- if (!Number.isNaN(num) && (!minTimeReq || num >= minTimeReq) && (!maxTimeReq || num <= maxTimeReq)) {
+ if (!isNaN(num) && (!minTimeReq || num >= minTimeReq) && (!maxTimeReq || num <= maxTimeReq)) {
!pivotDateGroups.get(num) && pivotDateGroups.set(num, []);
pivotDateGroups.get(num)!.push(pair.layout);
minTime = Math.min(num, minTime);
@@ -340,6 +343,7 @@ export function computeTimelineLayout(poolData: Map<string, PoolData>, pivotDoc:
if (!stack && (curTime === undefined || Math.abs(x - (curTime - minTime) * scaling) > pivotAxisWidth)) {
groupNames.push({ type: 'text', text: toLabel(key), x: x, y: stack * 25, height: fontHeight, fontSize, payload: undefined });
}
+ // eslint-disable-next-line no-use-before-define
layoutDocsAtTime(keyDocs, key);
});
if (sortedKeys.length && curTime !== undefined && curTime > sortedKeys[sortedKeys.length - 1]) {
@@ -388,7 +392,7 @@ function normalizeResults(
minWidth: number,
extras: ViewDefBounds[]
): ViewDefResult[] {
- const grpEles = groupNames.map(gn => ({ x: gn.x, y: gn.y, width: gn.width, height: gn.height } as ViewDefBounds));
+ const grpEles = groupNames.map(gn => ({ x: gn.x, y: gn.y, width: gn.width, height: gn.height }) as ViewDefBounds);
const docEles = Array.from(docMap.entries()).map(ele => ele[1]);
const aggBounds = aggregateBounds(
extras.concat(grpEles.concat(docEles.map(de => ({ ...de, type: 'doc', payload: '' })))).filter(e => e.zIndex !== -99),
@@ -400,11 +404,11 @@ function normalizeResults(
const height = aggBounds.b - aggBounds.y === 0 ? 1 : aggBounds.b - aggBounds.y;
const wscale = panelDim[0] / width;
let scale = wscale * height > panelDim[1] ? panelDim[1] / height : wscale;
- if (Number.isNaN(scale)) scale = 1;
+ if (isNaN(scale)) scale = 1;
Array.from(docMap.entries())
.filter(ele => ele[1].pair)
- .map(ele => {
+ .forEach(ele => {
const newPosRaw = ele[1];
if (newPosRaw) {
const newPos: PoolData = {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
index 69cbae86f..e543b4008 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
@@ -3,27 +3,37 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../../../fields/Doc';
import { ScriptField } from '../../../../fields/ScriptField';
-import { PresBox } from '../../nodes/trails/PresBox';
-import { CollectionFreeFormView } from './CollectionFreeFormView';
+import { ObservableReactComponent } from '../../ObservableReactComponent';
import './CollectionFreeFormView.scss';
+
export interface CollectionFreeFormPannableContentsProps {
Document: Doc;
viewDefDivClick?: ScriptField;
children?: React.ReactNode | undefined;
- transition?: string;
+ transition: () => string;
isAnnotationOverlay: boolean | undefined;
+ showPresPaths: () => boolean;
transform: () => string;
brushedView: () => { panX: number; panY: number; width: number; height: number } | undefined;
}
@observer
-export class CollectionFreeFormPannableContents extends React.Component<CollectionFreeFormPannableContentsProps> {
+export class CollectionFreeFormPannableContents extends ObservableReactComponent<CollectionFreeFormPannableContentsProps> {
+ static _overlayPlugin: ((fform: Doc) => React.JSX.Element) | null = null;
+ /**
+ * Setup a plugin function that returns components to display on a layer above the collection
+ * See PresBox which renders presenstation paths over the collection
+ * @param plugin a function that receives the collection Doc and returns JSX Elements
+ */
+ public static SetOverlayPlugin(plugin: ((fform: Doc) => React.JSX.Element) | null) {
+ CollectionFreeFormPannableContents._overlayPlugin = plugin;
+ }
constructor(props: CollectionFreeFormPannableContentsProps) {
super(props);
makeObservable(this);
}
@computed get presPaths() {
- return CollectionFreeFormView.ShowPresPaths ? PresBox.Instance.pathLines(this.props.Document) : null;
+ return this._props.showPresPaths() ? CollectionFreeFormPannableContents._overlayPlugin?.(this._props.Document) : null;
}
// rectangle highlight used when following trail/link to a region of a collection that isn't a document
showViewport = (viewport: { panX: number; panY: number; width: number; height: number } | undefined) =>
@@ -42,7 +52,7 @@ export class CollectionFreeFormPannableContents extends React.Component<Collecti
render() {
return (
<div
- className={'collectionfreeformview' + (this.props.viewDefDivClick ? '-viewDef' : '-none')}
+ className={'collectionfreeformview' + (this._props.viewDefDivClick ? '-viewDef' : '-none')}
onScroll={e => {
const target = e.target as any;
if (getComputedStyle(target)?.overflow === 'visible') {
@@ -50,13 +60,13 @@ export class CollectionFreeFormPannableContents extends React.Component<Collecti
}
}}
style={{
- transform: this.props.transform(),
- transition: this.props.transition,
- width: this.props.isAnnotationOverlay ? undefined : 0, // if not an overlay, then this will be the size of the collection, but panning and zooming will move it outside the visible border of the collection and make it selectable. This problem shows up after zooming/panning on a background collection -- you can drag the collection by clicking on apparently empty space outside the collection
+ transform: this._props.transform(),
+ transition: this._props.transition(),
+ width: this._props.isAnnotationOverlay ? undefined : 0, // if not an overlay, then this will be the size of the collection, but panning and zooming will move it outside the visible border of the collection and make it selectable. This problem shows up after zooming/panning on a background collection -- you can drag the collection by clicking on apparently empty space outside the collection
}}>
{this.props.children}
{this.presPaths}
- {this.showViewport(this.props.brushedView())}
+ {this.showViewport(this._props.brushedView())}
</div>
);
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index fa8218bdd..f64c6715b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -4,26 +4,22 @@ import * as mobxUtils from 'mobx-utils';
import * as React from 'react';
import * as uuid from 'uuid';
import CursorField from '../../../../fields/CursorField';
-import { Doc, FieldResult } from '../../../../fields/Doc';
import { Id } from '../../../../fields/FieldSymbols';
-import { List } from '../../../../fields/List';
import { listSpec } from '../../../../fields/Schema';
import { Cast } from '../../../../fields/Types';
-import { CollectionViewProps } from '../CollectionView';
+import { CollectionViewProps } from '../CollectionSubView';
import './CollectionFreeFormView.scss';
@observer
export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
@computed protected get cursors(): CursorField[] {
- const doc = this.props.Document;
-
- let cursors: FieldResult<List<CursorField>>;
- const id = Doc.UserDoc()[Id];
- if (!id || !(cursors = Cast(doc.cursors, listSpec(CursorField)))) {
+ const { Document } = this.props;
+ const cursors = Cast(Document.cursors, listSpec(CursorField));
+ if (!cursors) {
return [];
}
const now = mobxUtils.now();
- return (cursors || []).filter(({ data: { metadata } }) => metadata.id !== id && now - metadata.timestamp < 1000);
+ return (cursors || []).filter(({ data: { metadata } }) => metadata.id !== Document[Id] && now - metadata.timestamp < 1000);
}
@computed get renderedCursors() {
@@ -33,46 +29,44 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV
metadata,
position: { x, y },
},
- }) => {
- return (
- <div key={metadata.id} className="collectionFreeFormRemoteCursors-cont" style={{ transform: `translate(${x - 10}px, ${y - 10}px)` }}>
- <canvas
- className="collectionFreeFormRemoteCursors-canvas"
- ref={el => {
- if (el) {
- const ctx = el.getContext('2d');
- if (ctx) {
- ctx.fillStyle = '#' + uuid.v5(metadata.id, uuid.v5.URL).substring(0, 6).toUpperCase() + '22';
- ctx.fillRect(0, 0, 20, 20);
+ }) => (
+ <div key={metadata.id} className="collectionFreeFormRemoteCursors-cont" style={{ transform: `translate(${x - 10}px, ${y - 10}px)` }}>
+ <canvas
+ className="collectionFreeFormRemoteCursors-canvas"
+ ref={el => {
+ if (el) {
+ const ctx = el.getContext('2d');
+ if (ctx) {
+ ctx.fillStyle = '#' + uuid.v5(metadata.id, uuid.v5.URL).substring(0, 6).toUpperCase() + '22';
+ ctx.fillRect(0, 0, 20, 20);
- ctx.fillStyle = 'black';
- ctx.lineWidth = 0.5;
+ ctx.fillStyle = 'black';
+ ctx.lineWidth = 0.5;
- ctx.beginPath();
+ ctx.beginPath();
- ctx.moveTo(10, 0);
- ctx.lineTo(10, 8);
+ ctx.moveTo(10, 0);
+ ctx.lineTo(10, 8);
- ctx.moveTo(10, 20);
- ctx.lineTo(10, 12);
+ ctx.moveTo(10, 20);
+ ctx.lineTo(10, 12);
- ctx.moveTo(0, 10);
- ctx.lineTo(8, 10);
+ ctx.moveTo(0, 10);
+ ctx.lineTo(8, 10);
- ctx.moveTo(20, 10);
- ctx.lineTo(12, 10);
+ ctx.moveTo(20, 10);
+ ctx.lineTo(12, 10);
- ctx.stroke();
- }
+ ctx.stroke();
}
- }}
- width={20}
- height={20}
- />
- <p className="collectionFreeFormRemoteCursors-symbol">{metadata.identifier[0].toUpperCase()}</p>
- </div>
- );
- }
+ }
+ }}
+ width={20}
+ height={20}
+ />
+ <p className="collectionFreeFormRemoteCursors-symbol">{metadata.identifier[0].toUpperCase()}</p>
+ </div>
+ )
);
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index 9e7d364ea..2c94446fb 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -273,33 +273,34 @@
margin: 15px;
padding: 10px;
+ .collectionFreeform-infoUI-close {
+ position: absolute;
+ top: -10;
+ left: -10;
+ }
- .msg {
+ .collectionFreeform-infoUI-msg {
+ position: relative;
+ max-width: 500;
+ margin: 10;
+ }
+ .collectionFreeform-infoUI-button {
+ border-radius: 50px;
+ font-size: 12px;
+ padding: 6;
position: relative;
- // display: block;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -o-user-select: none;
- user-select: none;
}
- .gif-container {
+ .collectionFreeform-infoUI-gif-container {
position: relative;
margin-top: 5px;
- // display: block;
+ pointer-events: none;
- justify-content: center;
- align-items: center;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -o-user-select: none;
- user-select: none;
-
- .gif {
- background-color: transparent;
+ > img {
height: 300px;
}
}
+ .collectionFreeform-hidden {
+ display: none;
+ }
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 9500b918a..cc195385b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,60 +1,65 @@
+/* eslint-disable react/jsx-props-no-spreading */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import { Bezier } from 'bezier-js';
import { Colors } from 'browndash-components';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
+import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils';
import { DateField } from '../../../../fields/DateField';
-import { Doc, DocListCast, Field, Opt } from '../../../../fields/Doc';
+import { ActiveInkWidth, Doc, DocListCast, Field, FieldType, Opt, SetActiveInkColor, SetActiveInkWidth } from '../../../../fields/Doc';
import { DocData, Height, Width } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
-import { InkData, InkField, InkTool, PointData, Segment } from '../../../../fields/InkField';
+import { InkData, InkField, InkTool, Segment } from '../../../../fields/InkField';
import { List } from '../../../../fields/List';
import { RichTextField } from '../../../../fields/RichTextField';
import { listSpec } from '../../../../fields/Schema';
import { ScriptField } from '../../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast, toList } from '../../../../fields/Types';
import { ImageField } from '../../../../fields/URLField';
import { TraceMobx } from '../../../../fields/util';
+import { Gestures, PointData } from '../../../../pen-gestures/GestureTypes';
import { GestureUtils } from '../../../../pen-gestures/GestureUtils';
-import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, numberValue, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils';
-import { CognitiveServices } from '../../../cognitive_services/CognitiveServices';
-import { Docs, DocUtils } from '../../../documents/Documents';
+import { aggregateBounds, clamp, emptyFunction, intersectRect, Utils } from '../../../../Utils';
+import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
-import { DocumentManager } from '../../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../../util/DragManager';
-import { ReplayMovements } from '../../../util/ReplayMovements';
+import { DocUtils } from '../../../documents/DocUtils';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
import { CompileScript } from '../../../util/Scripting';
import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
-import { SelectionManager } from '../../../util/SelectionManager';
-import { freeformScrollMode } from '../../../util/SettingsManager';
-import { SnappingManager } from '../../../util/SnappingManager';
+import { freeformScrollMode, SnappingManager } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager';
import { Timeline } from '../../animationtimeline/Timeline';
import { ContextMenu } from '../../ContextMenu';
-import { GestureOverlay } from '../../GestureOverlay';
-import { CtrlKey } from '../../GlobalKeyHandler';
-import { ActiveInkWidth, InkingStroke, SetActiveInkColor, SetActiveInkWidth } from '../../InkingStroke';
-import { LightboxView } from '../../LightboxView';
+import { InkingStroke } from '../../InkingStroke';
import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView';
import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp';
-import { DocumentView, OpenWhere } from '../../nodes/DocumentView';
-import { FieldViewProps, FocusViewOptions } from '../../nodes/FieldView';
+import { DocumentView } from '../../nodes/DocumentView';
+import { FieldViewProps } from '../../nodes/FieldView';
+import { FocusViewOptions } from '../../nodes/FocusViewOptions';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
-import { PinProps, PresBox } from '../../nodes/trails/PresBox';
-import { CreateImage } from '../../nodes/WebBoxRenderer';
-import { StyleProp } from '../../StyleProvider';
+import { OpenWhere, OpenWhereMod } from '../../nodes/OpenWhere';
+import { PinDocView, PinProps } from '../../PinFuncs';
+import { StyleProp } from '../../StyleProp';
import { CollectionSubView } from '../CollectionSubView';
-import { TreeViewType } from '../CollectionTreeView';
+import { TreeViewType } from '../CollectionTreeViewType';
import { CollectionFreeFormBackgroundGrid } from './CollectionFreeFormBackgroundGrid';
-import { CollectionFreeFormInfoUI } from './CollectionFreeFormInfoUI';
+import { CollectionFreeFormClusters } from './CollectionFreeFormClusters';
import { computePassLayout, computePivotLayout, computeStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult } from './CollectionFreeFormLayoutEngines';
import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannableContents';
import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors';
import './CollectionFreeFormView.scss';
import { MarqueeView } from './MarqueeView';
+class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> {
+ render() {
+ return this.props.elements().filter(ele => ele.bounds?.z).map(ele => ele.ele); // prettier-ignore
+ }
+}
export interface collectionFreeformViewProps {
NativeWidth?: () => number;
NativeHeight?: () => number;
@@ -71,115 +76,102 @@ export interface collectionFreeformViewProps {
@observer
export class CollectionFreeFormView extends CollectionSubView<Partial<collectionFreeformViewProps>>() {
public get displayName() {
- return 'CollectionFreeFormView(' + this.Document.title?.toString() + ')';
+ return 'CollectionFreeFormView(' + (this.Document.title?.toString() ?? '') + ')';
} // this makes mobx trace() statements more descriptive
-
- @observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, '');
- @computed get paintFunc() {
- const field = this.layoutDoc[this.fieldKey];
- const paintFunc = StrCast(Field.toJavascriptString(Cast(field, RichTextField, null)?.Text as Field)).trim();
- return !paintFunc
- ? ''
- : paintFunc.includes('dashDiv')
- ? `const dashDiv = document.querySelector('#${this._paintedId}');
- (async () => { ${paintFunc} })()`
- : paintFunc;
- }
- constructor(props: any) {
- super(props);
- makeObservable(this);
+ public unprocessedDocs: Doc[] = [];
+ public static collectionsWithUnprocessedInk = new Set<CollectionFreeFormView>();
+ public static from(dv?: DocumentView): CollectionFreeFormView | undefined {
+ const parent = CollectionFreeFormDocumentView.from(dv)?._props.parent;
+ return parent instanceof CollectionFreeFormView ? parent : undefined;
}
- @observable
- public static ShowPresPaths = false;
+ private _clusters = new CollectionFreeFormClusters(this);
+ private _oldWheel: any;
private _panZoomTransitionTimer: any;
private _lastX: number = 0;
private _lastY: number = 0;
private _downX: number = 0;
private _downY: number = 0;
private _downTime = 0;
- private _clusterDistance: number = 75;
- private _hitCluster: number = -1;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _renderCutoffData = observable.map<string, boolean>();
private _batch: UndoManager.Batch | undefined = undefined;
private _brushtimer: any;
private _brushtimer1: any;
+ private _eraserLock = 0;
+ private _keyTimer: NodeJS.Timeout | undefined; // timer for turning off transition flag when key frame change has completed. Need to clear this if you do a second navigation before first finishes, or else first timer can go off during second naviation.
- public get isAnnotationOverlay() {
- return this._props.isAnnotationOverlay;
- }
- public get scaleFieldKey() {
- return (this._props.viewField ?? '') + '_freeform_scale';
- }
- private get panXFieldKey() {
- return (this._props.viewField ?? '') + '_freeform_panX';
- }
- private get panYFieldKey() {
- return (this._props.viewField ?? '') + '_freeform_panY';
- }
- private get autoResetFieldKey() {
- return (this._props.viewField ?? '') + '_freeform_autoReset';
- }
+ private _presEaseFunc: string = 'ease';
+
+ @action
+ setPresEaseFunc = (easeFunc: string) => {
+ this._presEaseFunc = easeFunc;
+ };
+ private get isAnnotationOverlay() { return this._props.isAnnotationOverlay; } // prettier-ignore
+ private get scaleFieldKey() { return (this._props.viewField ?? '') + '_freeform_scale'; } // prettier-ignore
+ private get panXFieldKey() { return (this._props.viewField ?? '') + '_freeform_panX'; } // prettier-ignore
+ private get panYFieldKey() { return (this._props.viewField ?? '') + '_freeform_panY'; } // prettier-ignore
+ private get autoResetFieldKey() { return (this._props.viewField ?? '') + '_freeform_autoReset'; } // prettier-ignore
@observable.shallow _layoutElements: ViewDefResult[] = []; // shallow because some layout items (eg pivot labels) are just generated 'divs' and can't be frozen as observables
@observable _panZoomTransition: number = 0; // sets the pan/zoom transform ease time- used by nudge(), focus() etc to smoothly zoom/pan. set to 0 to use document's transition time or default of 0
@observable _firstRender = false; // this turns off rendering of the collection's content so that there's instant feedback when a tab is switched of what content will be shown. could be used for performance improvement
@observable _showAnimTimeline = false;
- @observable _clusterSets: Doc[][] = [];
@observable _deleteList: DocumentView[] = [];
@observable _timelineRef = React.createRef<Timeline>();
@observable _marqueeViewRef = React.createRef<MarqueeView>();
@observable _brushedView: { width: number; height: number; panX: number; panY: number } | undefined = undefined; // highlighted region of freeform canvas used by presentations to indicate a region
@observable GroupChildDrag: boolean = false; // child document view being dragged. needed to update drop areas of groups when a group item is dragged.
+ @observable _childPointerEvents: 'none' | 'all' | 'visiblepainted' | undefined = undefined;
+ @observable _lightboxDoc: Opt<Doc> = undefined;
+ @observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, '');
+ @observable _keyframeEditing = false;
+ constructor(props: any) {
+ super(props);
+ makeObservable(this);
+ }
+
+ @computed get layoutEngine() {
+ return this._props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine);
+ }
+ @computed get childPointerEvents() {
+ return SnappingManager.IsResizing
+ ? 'none'
+ : this._props.childPointerEvents?.() ??
+ (this._props.viewDefDivClick || //
+ (this.layoutEngine === computePassLayout.name && !this._props.isSelected()) ||
+ this.isContentActive() === false
+ ? 'none'
+ : this._props.pointerEvents?.());
+ }
@computed get contentViews() {
const viewsMask = this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z && ele.inkMask !== -1 && ele.inkMask !== undefined).map(ele => ele.ele);
const renderableEles = this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z && (ele.inkMask === -1 || ele.inkMask === undefined)).map(ele => ele.ele);
if (viewsMask.length) renderableEles.push(<div className={`collectionfreeformview-mask${this._layoutElements.some(ele => (ele.inkMask ?? 0) > 0) ? '' : '-empty'}`}>{viewsMask}</div>);
return renderableEles;
}
- @computed get fitToContentVals() {
- const hgt = this.contentBounds.b - this.contentBounds.y;
- const wid = this.contentBounds.r - this.contentBounds.x;
- return {
- bounds: { ...this.contentBounds, cx: this.contentBounds.x + wid / 2, cy: this.contentBounds.y + hgt / 2 },
- scale:
- (!this.childDocs.length || !Number.isFinite(hgt) || !Number.isFinite(wid)
- ? 1 //
- : Math.min(this._props.PanelHeight() / hgt, this._props.PanelWidth() / wid)) / (this._props.NativeDimScaling?.() || 1),
- };
- }
@computed get fitContentsToBox() {
return (this._props.fitContentsToBox?.() || this.Document._freeform_fitContentsToBox) && !this.isAnnotationOverlay;
}
- @computed get contentBounds() {
- const cb = Cast(this.dataDoc.contentBounds, listSpec('number'));
- return cb
- ? { x: cb[0], y: cb[1], r: cb[2], b: cb[3] }
- : aggregateBounds(
- this._layoutElements.filter(e => e.bounds?.width && !e.bounds.z).map(e => e.bounds!),
- NumCast(this.layoutDoc._xPadding, this._props.xPadding ?? 10),
- NumCast(this.layoutDoc._yPadding, this._props.yPadding ?? 10)
- );
- }
@computed get nativeWidth() {
return this._props.NativeWidth?.() || Doc.NativeWidth(this.Document, Cast(this.Document.resolvedDataDoc, Doc, null));
}
@computed get nativeHeight() {
return this._props.NativeHeight?.() || Doc.NativeHeight(this.Document, Cast(this.Document.resolvedDataDoc, Doc, null));
}
- @computed get cachedCenteringShiftX(): number {
- const scaling = !this.nativeDimScaling ? 1 : this.nativeDimScaling;
- return this._props.isAnnotationOverlay || this._props.originTopLeft ? 0 : this._props.PanelWidth() / 2 / scaling; // shift so pan position is at center of window for non-overlay collections
+ @computed get centeringShiftX(): number {
+ return this._props.isAnnotationOverlay || this._props.originTopLeft ? 0 : this._props.PanelWidth() / 2 / this.nativeDimScaling; // shift so pan position is at center of window for non-overlay collections
}
- @computed get cachedCenteringShiftY(): number {
+ @computed get centeringShiftY(): number {
+ const panLocAtCenter = !(this._props.isAnnotationOverlay || this._props.originTopLeft);
+ if (!panLocAtCenter) return 0;
const dv = this.DocumentView?.();
- const fitWidth = this._props.layout_fitWidth?.(this.Document) ?? dv?.layoutDoc.layout_fitWidth;
- const scaling = !this.nativeDimScaling ? 1 : this.nativeDimScaling;
+ const aspect = !this.fitWidth && dv?.nativeWidth && dv?.nativeHeight;
+ const scaling = this.nativeDimScaling;
// if freeform has a native aspect, then the panel height needs to be adjusted to match it
- const aspect = dv?.nativeWidth && dv?.nativeHeight && !fitWidth ? dv.nativeHeight / dv.nativeWidth : this._props.PanelHeight() / this._props.PanelWidth();
- return this._props.isAnnotationOverlay || this._props.originTopLeft ? 0 : (aspect * this._props.PanelWidth()) / 2 / scaling; // shift so pan position is at center of window for non-overlay collections
+ const height = aspect ? (dv.nativeHeight / dv.nativeWidth) * this._props.PanelWidth() : this._props.PanelHeight();
+ return height / 2 / scaling; // shift so pan position is at center of window for non-overlay collections
}
@computed get panZoomXf() {
return new Transform(this.panX(), this.panY(), 1 / this.zoomScaling());
@@ -187,34 +179,36 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@computed get screenToFreeformContentsXf() {
return this._props
.ScreenToLocalTransform() //
- .translate(-this.cachedCenteringShiftX, -this.cachedCenteringShiftY)
+ .translate(-this.centeringShiftX, -this.centeringShiftY)
.transform(this.panZoomXf);
}
+ @computed get backgroundColor() {
+ return this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor);
+ }
+ @computed get fitWidth() {
+ return this._props.fitWidth?.(this.Document) ?? this.layoutDoc.layout_fitWidth;
+ }
+ @computed get nativeDimScaling() {
+ if (this._firstRender || (this._props.isAnnotationOverlay && !this._props.annotationLayerHostsContent)) return 1;
+ const hscale = this._props.PanelHeight() / (this.nativeHeight || this._props.PanelHeight());
+ const wscale = this._props.PanelWidth() / (this.nativeWidth || this._props.PanelWidth());
+ return wscale < hscale || this.fitWidth ? wscale : hscale;
+ }
+ @computed get fitContentBounds() { return !this._firstRender && this.fitContentsToBox ? this.contentBounds() : undefined; } // prettier-ignore
+ @computed get paintFunc() {
+ const field = this.dataDoc[this.fieldKey];
+ const paintFunc = StrCast(Field.toJavascriptString(Cast(field, RichTextField, null)?.Text as FieldType)).trim();
+ return !paintFunc
+ ? ''
+ : paintFunc.includes('dashDiv')
+ ? `const dashDiv = document.querySelector('#${this._paintedId}');
+ (async () => { ${paintFunc} })()`
+ : paintFunc;
+ }
public static gotoKeyframe(timer: NodeJS.Timeout | undefined, docs: Doc[], duration: number) {
return DocumentView.SetViewTransition(docs, 'all', duration, timer, undefined, true);
}
- public static updateKeyframe(timer: NodeJS.Timeout | undefined, docs: Doc[], time: number) {
- const newTimer = DocumentView.SetViewTransition(docs, 'all', 1000, timer, undefined, true);
- const timecode = Math.round(time);
- docs.forEach(doc => {
- CollectionFreeFormDocumentView.animFields.forEach(val => {
- const findexed = Cast(doc[`${val.key}_indexed`], listSpec('number'), null);
- findexed?.length <= timecode + 1 && findexed.push(undefined as any as number);
- });
- CollectionFreeFormDocumentView.animStringFields.forEach(val => {
- const findexed = Cast(doc[`${val}_indexed`], listSpec('string'), null);
- findexed?.length <= timecode + 1 && findexed.push(undefined as any as string);
- });
- CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => {
- const findexed = Cast(doc[`${val}_indexed`], listSpec(InkField), null);
- findexed?.length <= timecode + 1 && findexed.push(undefined as any);
- });
- });
- return newTimer;
- }
-
- _keyTimer: NodeJS.Timeout | undefined; // timer for turning off transition flag when key frame change has completed. Need to clear this if you do a second navigation before first finishes, or else first timer can go off during second naviation.
changeKeyFrame = (back = false) => {
const currentFrame = Cast(this.Document._currentFrame, 'number', null);
if (currentFrame === undefined) {
@@ -225,66 +219,84 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._keyTimer = CollectionFreeFormView.gotoKeyframe(this._keyTimer, [...this.childDocs, this.layoutDoc], 1000);
this.Document._currentFrame = Math.max(0, (currentFrame || 0) - 1);
} else {
- this._keyTimer = CollectionFreeFormView.updateKeyframe(this._keyTimer, [...this.childDocs, this.layoutDoc], currentFrame || 0);
+ this._keyTimer = CollectionFreeFormDocumentView.updateKeyframe(this._keyTimer, [...this.childDocs, this.layoutDoc], currentFrame || 0);
this.Document._currentFrame = Math.max(0, (currentFrame || 0) + 1);
this.Document.lastFrame = Math.max(NumCast(this.Document._currentFrame), NumCast(this.Document.lastFrame));
}
};
- @observable _keyframeEditing = false;
- @action setKeyFrameEditing = (set: boolean) => (this._keyframeEditing = set);
+ @action setKeyFrameEditing = (set: boolean) => {
+ this._keyframeEditing = set;
+ };
getKeyFrameEditing = () => this._keyframeEditing;
- onBrowseClickHandler = () => this._props.onBrowseClickScript?.() || ScriptCast(this.layoutDoc.onBrowseClick);
+
+ override contentBounds = () => {
+ const { x, y, r, b } = aggregateBounds(
+ this._layoutElements.filter(e => e.bounds?.width && !e.bounds.z).map(e => e.bounds!),
+ NumCast(this.layoutDoc._xPadding, this._props.xPadding ?? 0),
+ NumCast(this.layoutDoc._yPadding, this._props.yPadding ?? 0)
+ );
+ const [width, height] = [r - x, b - y];
+ return {
+ width,
+ height,
+ cx: x + width / 2,
+ cy: y + height / 2,
+ bounds: { x, y, r, b },
+ scale: (!this.childDocs.length || !Number.isFinite(height) || !Number.isFinite(width)
+ ? 1 //
+ : Math.min(this._props.PanelHeight() / height,this._props.PanelWidth() / width )) / (this._props.NativeDimScaling?.() || 1),
+ }; // prettier-ignore
+ };
onChildClickHandler = () => this._props.childClickScript || ScriptCast(this.Document.onChildClick);
onChildDoubleClickHandler = () => this._props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
elementFunc = () => this._layoutElements;
viewTransition = () => (this._panZoomTransition ? '' + this._panZoomTransition : undefined);
+ panZoomTransition = () => (this._panZoomTransition ? `transform ${this._panZoomTransition}ms` : Cast(this.layoutDoc._viewTransition, 'string', Cast(this.Document._viewTransition, 'string', null)));
fitContentOnce = () => {
- const vals = this.fitToContentVals;
- this.layoutDoc._freeform_panX = vals.bounds.cx;
- this.layoutDoc._freeform_panY = vals.bounds.cy;
- this.layoutDoc._freeform_scale = vals.scale;
+ const { cx, cy, scale } = this.contentBounds(); // prettier-ignore
+ this.layoutDoc._freeform_panX = cx;
+ this.layoutDoc._freeform_panY = cy;
+ this.layoutDoc._freeform_scale = scale;
};
- freeformData = (force?: boolean) => (!this._firstRender && (this.fitContentsToBox || force) ? this.fitToContentVals : undefined);
// freeform_panx, freeform_pany, freeform_scale all attempt to get values first from the layout controller, then from the layout/dataDoc (or template layout doc), and finally from the resolved template data document.
// this search order, for example, allows icons of cropped images to find the panx/pany/zoom on the cropped image's data doc instead of the usual layout doc because the zoom/panX/panY define the cropped image
- panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1));
- panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panY, 1));
- zoomScaling = () => this.freeformData()?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.[this.scaleFieldKey], 1));
- PanZoomCenterXf = () =>
- this._props.isAnnotationOverlay && this.zoomScaling() === 1 ? `` : `translate(${this.cachedCenteringShiftX}px, ${this.cachedCenteringShiftY}px) scale(${this.zoomScaling()}) translate(${-this.panX()}px, ${-this.panY()}px)`;
+ panX = () => this.fitContentBounds?.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1));
+ panY = () => this.fitContentBounds?.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panY, 1));
+ zoomScaling = () => this.fitContentBounds?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); // , NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1));
+ PanZoomCenterXf = () => (this._props.isAnnotationOverlay && this.zoomScaling() === 1 ? `` : `translate(${this.centeringShiftX}px, ${this.centeringShiftY}px) scale(${this.zoomScaling()}) translate(${-this.panX()}px, ${-this.panY()}px)`);
ScreenToContentsXf = () => this.screenToFreeformContentsXf.copy();
getActiveDocuments = () => this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout);
isAnyChildContentActive = () => this._props.isAnyChildContentActive();
addLiveTextBox = (newDoc: Doc) => {
- FormattedTextBox.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+ Doc.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
this.addDocument(newDoc);
};
selectDocuments = (docs: Doc[]) => {
- SelectionManager.DeselectAll();
- docs.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).forEach(dv => dv && SelectionManager.SelectView(dv, true));
+ DocumentView.DeselectAll();
+ docs.map(doc => DocumentView.getDocumentView(doc, this.DocumentView?.())).forEach(dv => dv && DocumentView.SelectView(dv, true));
};
addDocument = (newBox: Doc | Doc[]) => {
- let retVal = false;
- if (newBox instanceof Doc) {
- if ((retVal = this._props.addDocument?.(newBox) || false)) {
- this.bringToFront(newBox);
- this.updateCluster(newBox);
+ const newBoxes = toList(newBox);
+ const retVal = newBoxes.every(doc => {
+ const added = this._props.addDocument?.(doc);
+ if (added) {
+ this.bringToFront(doc);
+ this._clusters.addDocument(doc);
}
- } else {
- retVal = this._props.addDocument?.(newBox) || false;
- // bcz: deal with clusters
- }
+ return added;
+ });
if (retVal) {
- const newBoxes = newBox instanceof Doc ? [newBox] : newBox;
- for (const newBox of newBoxes) {
- if (newBox.activeFrame !== undefined) {
- const vals = CollectionFreeFormDocumentView.animFields.map(field => newBox[field.key]);
- CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[`${field.key}_indexed`]);
- CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[field.key]);
- delete newBox.activeFrame;
- CollectionFreeFormDocumentView.animFields.forEach((field, i) => field.key !== 'opacity' && (newBox[field.key] = vals[i]));
+ newBoxes.forEach(box => {
+ if (box.activeFrame !== undefined) {
+ const vals = CollectionFreeFormDocumentView.animFields.map(field => box[field.key]);
+ CollectionFreeFormDocumentView.animFields.forEach(field => delete box[`${field.key}_indexed`]);
+ CollectionFreeFormDocumentView.animFields.forEach(field => delete box[field.key]);
+ delete box.activeFrame;
+ CollectionFreeFormDocumentView.animFields.forEach((field, i) => {
+ field.key !== 'opacity' && (box[field.key] = vals[i]);
+ });
}
- }
+ });
if (this.Document._currentFrame !== undefined && !this._props.isAnnotationOverlay) {
CollectionFreeFormDocumentView.setupKeyframes(newBoxes, NumCast(this.Document._currentFrame), true);
}
@@ -299,25 +311,67 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return dispTime === -1 || curTime === -1 || (curTime - dispTime >= -1e-4 && curTime <= endTime);
}
+ /**
+ * focuses on a specified point in the freeform coordinate space. (alternative to focusing on a Document)
+ * @param options
+ * @returns how long a transition it will be to focus on the point, or undefined the doc is a group or something else already moved
+ */
+ focusOnPoint = (options: FocusViewOptions) => {
+ const { pointFocus, zoomTime, didMove } = options;
+ if (!this.Document.isGroup && pointFocus && !didMove) {
+ const dfltScale = this.isAnnotationOverlay ? 1 : 0.5;
+ if (this.layoutDoc[this.scaleFieldKey] !== dfltScale) {
+ this.zoomSmoothlyAboutPt(this.screenToFreeformContentsXf.transformPoint(pointFocus.X, pointFocus.Y), dfltScale, zoomTime);
+ options.didMove = true;
+ return zoomTime;
+ }
+ }
+ return undefined;
+ };
+
+ /**
+ * Focusing on a member of a group -
+ * Since groups can't pan and zoom like regular collections, this method focuses on a Doc in a group by
+ * focusing on the group with an additional transformation to force the final focus to be on the center of the group item.
+ * @param anchor
+ * @param options
+ * @returns
+ */
groupFocus = (anchor: Doc, options: FocusViewOptions) => {
- options.docTransform = new Transform(-NumCast(this.layoutDoc[this.panXFieldKey]) + NumCast(anchor.x), -NumCast(this.layoutDoc[this.panYFieldKey]) + NumCast(anchor.y), 1);
+ if (options.pointFocus) return undefined;
+ options.docTransform = new Transform(NumCast(anchor.x) + NumCast(anchor._width)/2 - NumCast(this.layoutDoc[this.panXFieldKey]),
+ NumCast(anchor.y) + NumCast(anchor._height)/2- NumCast(this.layoutDoc[this.panYFieldKey]), 1); // prettier-ignore
const res = this._props.focus(this.Document, options);
options.docTransform = undefined;
return res;
};
- focus = (anchor: Doc, options: FocusViewOptions) => {
- if (this._lightboxDoc) return;
- if (anchor === this.Document) {
- // if (options.willZoomCentered && options.zoomScale) {
- // this.fitContentOnce();
- // options.didMove = true;
- // }
+ /**
+ * focuses the freeform view on the anchor subject to options.
+ * If a pointFocus is specified, then groupFocus is triggered instad
+ * Otherwise, this shifts the pan and zoom to the anchor target (as specified by options).
+ * NOTE: focusing on a group only has an effet if the options contextPath is empty.
+ * @param anchor
+ * @param options
+ * @returns
+ */
+ focus = (anchor: Doc, options: FocusViewOptions): any => {
+ if (anchor.isGroup && !options.docTransform && options.contextPath?.length) {
+ // don't focus on group if there's a context path because we're about to focus on a group item
+ // which will override any group focus. (If we allowed the group to focus, it would mark didMove even if there were no net movement)
+ return undefined;
+ }
+ if (options.easeFunc) this.setPresEaseFunc(options.easeFunc);
+ if (this._lightboxDoc) return undefined;
+ if (options.pointFocus) return this.focusOnPoint(options);
+ const anchorInCollection = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor);
+ const anchorInChildViews = this.childLayoutPairs.map(pair => pair.layout).includes(anchor);
+ if (!anchorInCollection && !anchorInChildViews) {
+ return undefined;
}
- if (anchor.type !== DocumentType.CONFIG && !DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor)) return;
const xfToCollection = options?.docTransform ?? Transform.Identity();
const savedState = { panX: NumCast(this.Document[this.panXFieldKey]), panY: NumCast(this.Document[this.panYFieldKey]), scale: options?.willZoomCentered ? this.Document[this.scaleFieldKey] : undefined };
- const cantTransform = this.fitContentsToBox || ((this.Document.isGroup || this.layoutDoc._lockedTransform) && !LightboxView.LightboxDoc);
+ const cantTransform = this.fitContentsToBox || ((this.Document.isGroup || this.layoutDoc._lockedTransform) && !DocumentView.LightboxDoc());
const { panX, panY, scale } = cantTransform || (!options.willPan && !options.willZoomCentered) ? savedState : this.calculatePanIntoView(anchor, xfToCollection, options?.willZoomCentered ? options?.zoomScale ?? 0.75 : undefined);
// focus on the document in the collection
@@ -327,15 +381,20 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (didMove) {
const focusTime = options?.instant ? 0 : options.zoomTime ?? 500;
(options.zoomScale ?? options.willZoomCentered) && scale && (this.Document[this.scaleFieldKey] = scale);
- this.setPan(panX, panY, focusTime, true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
+ this.setPan(panX, panY, focusTime); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
return focusTime;
}
+ return undefined;
};
getView = async (doc: Doc, options: FocusViewOptions): Promise<Opt<DocumentView>> =>
new Promise<Opt<DocumentView>>(res => {
if (doc.hidden && this._lightboxDoc !== doc) options.didMove = !(doc.hidden = false);
- const findDoc = (finish: (dv: DocumentView) => void) => DocumentManager.Instance.AddViewRenderedCb(doc, dv => finish(dv));
+ if (doc === this.Document) {
+ res(this.DocumentView?.());
+ return;
+ }
+ const findDoc = (finish: (dv: DocumentView) => void) => DocumentView.addViewRenderedCb(doc, dv => finish(dv));
findDoc(dv => res(dv));
});
@@ -344,39 +403,41 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const refDoc = docDragData.droppedDocuments[0];
const fromScreenXf = NumCast(refDoc.z) ? this.ScreenToLocalBoxXf() : this.screenToFreeformContentsXf;
const [xpo, ypo] = fromScreenXf.transformPoint(de.x, de.y);
- const x = xpo - docDragData.offset[0];
- const y = ypo - docDragData.offset[1];
- const zsorted = this.childLayoutPairs
- .map(pair => pair.layout)
- .slice()
- .sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
- zsorted.forEach((doc, index) => (doc.zIndex = doc.stroke_isInkMask ? 5000 : index + 1));
- const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000));
- const dropPos = this.Document._currentFrame !== undefined ? [NumCast(dvals.x), NumCast(dvals.y)] : [NumCast(refDoc.x), NumCast(refDoc.y)];
-
- for (let i = 0; i < docDragData.droppedDocuments.length; i++) {
- const d = docDragData.droppedDocuments[i];
- const layoutDoc = Doc.Layout(d);
- const delta = Utils.rotPt(x - dropPos[0], y - dropPos[1], fromScreenXf.Rotate);
- if (this.Document._currentFrame !== undefined) {
- CollectionFreeFormDocumentView.setupKeyframes([d], NumCast(this.Document._currentFrame), false);
- const pvals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000)); // get filled in values (uses defaults when not value is specified) for position
- const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000), false); // get non-default values for everything else
- vals.x = NumCast(pvals.x) + delta.x;
- vals.y = NumCast(pvals.y) + delta.y;
- CollectionFreeFormDocumentView.setValues(NumCast(this.Document._currentFrame), d, vals);
- } else {
- d.x = NumCast(d.x) + delta.x;
- d.y = NumCast(d.y) + delta.y;
- }
- d._layout_modificationDate = new DateField();
- const nd = [Doc.NativeWidth(layoutDoc), Doc.NativeHeight(layoutDoc)];
- layoutDoc._width = NumCast(layoutDoc._width, 300);
- layoutDoc._height = NumCast(layoutDoc._height, nd[0] && nd[1] ? (nd[1] / nd[0]) * NumCast(layoutDoc._width) : 300);
- !d._keepZWhenDragged && (d.zIndex = zsorted.length + 1 + i); // bringToFront
- }
+ const [x, y] = [xpo - docDragData.offset[0], ypo - docDragData.offset[1]];
+ runInAction(() => {
+ // needs to be in action to avoid having each edit trigger a freeform layout engine recompute - this triggers just one for each document at the end
+ const zsorted = this.childLayoutPairs
+ .map(pair => pair.layout) //
+ .sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
+ zsorted.forEach((doc, index) => {
+ doc.zIndex = doc.stroke_isInkMask ? 5000 : index + 1;
+ });
+ const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000));
+ const dropPos = this.Document._currentFrame !== undefined ? [NumCast(dvals.x), NumCast(dvals.y)] : [NumCast(refDoc.x), NumCast(refDoc.y)];
+
+ docDragData.droppedDocuments.forEach((d, i) => {
+ const layoutDoc = Doc.Layout(d);
+ const delta = Utils.rotPt(x - dropPos[0], y - dropPos[1], fromScreenXf.Rotate);
+ if (this.Document._currentFrame !== undefined) {
+ CollectionFreeFormDocumentView.setupKeyframes([d], NumCast(this.Document._currentFrame), false);
+ const pvals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000)); // get filled in values (uses defaults when not value is specified) for position
+ const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000), false); // get non-default values for everything else
+ vals.x = NumCast(pvals.x) + delta.x;
+ vals.y = NumCast(pvals.y) + delta.y;
+ CollectionFreeFormDocumentView.setValues(NumCast(this.Document._currentFrame), d, vals);
+ } else {
+ d.x = NumCast(d.x) + delta.x;
+ d.y = NumCast(d.y) + delta.y;
+ }
+ d._layout_modificationDate = new DateField();
+ const nd = [Doc.NativeWidth(layoutDoc), Doc.NativeHeight(layoutDoc)];
+ layoutDoc._width = NumCast(layoutDoc._width, 300);
+ layoutDoc._height = NumCast(layoutDoc._height, nd[0] && nd[1] ? (nd[1] / nd[0]) * NumCast(layoutDoc._width) : 300);
+ !d._keepZWhenDragged && (d.zIndex = zsorted.length + 1 + i); // bringToFront
+ });
+ (docDragData.droppedDocuments.length === 1 || de.shiftKey) && this._clusters.addDocuments(docDragData.droppedDocuments);
+ });
- (docDragData.droppedDocuments.length === 1 || de.shiftKey) && this.updateClusterDocs(docDragData.droppedDocuments);
return true;
}
@@ -400,11 +461,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
internalLinkDrop(e: Event, de: DragManager.DropEvent, linkDragData: DragManager.LinkDragData) {
if (this.DocumentView?.() && linkDragData.linkDragView.containerViewPath?.().includes(this.DocumentView())) {
const [x, y] = this.screenToFreeformContentsXf.transformPoint(de.x, de.y);
- let added = false;
// do nothing if link is dropped into any freeform view parent of dragged document
const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, x, y, title: 'dropped annotation' });
- added = this._props.addDocument?.(source) ? true : false;
- de.complete.linkDocument = DocUtils.MakeLink(linkDragData.linkSourceGetAnchor(), source, { link_relationship: 'annotated by:annotation of' }); // TODODO this is where in text links get passed
+ const added = !!this._props.addDocument?.(source);
+ de.complete.linkDocument = DocUtils.MakeLink(linkDragData.linkSourceGetAnchor(), source, { link_relationship: 'annotated by:annotation of' });
if (de.complete.linkDocument) {
de.complete.linkDocument.layout_isSvg = true;
this.addDocument(de.complete.linkDocument);
@@ -418,186 +478,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de, de.complete.annoDragData);
- else if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData);
- else if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData);
+ if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData);
+ if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData);
return false;
};
onExternalDrop = (e: React.DragEvent) => (([x, y]) => super.onExternalDrop(e, { x, y }))(this.screenToFreeformContentsXf.transformPoint(e.pageX, e.pageY));
- static overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) {
- const doc2Layout = Doc.Layout(doc2);
- const doc1Layout = Doc.Layout(doc1);
- const x2 = NumCast(doc2.x) - clusterDistance;
- const y2 = NumCast(doc2.y) - clusterDistance;
- const w2 = NumCast(doc2Layout._width) + clusterDistance;
- const h2 = NumCast(doc2Layout._height) + clusterDistance;
- const x = NumCast(doc1.x) - clusterDistance;
- const y = NumCast(doc1.y) - clusterDistance;
- const w = NumCast(doc1Layout._width) + clusterDistance;
- const h = NumCast(doc1Layout._height) + clusterDistance;
- return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
- }
- pickCluster(probe: number[]) {
- return this.childLayoutPairs
- .map(pair => pair.layout)
- .reduce((cluster, cd) => {
- const grouping = this.Document._freeform_useClusters ? NumCast(cd.layout_cluster, -1) : NumCast(cd.group, -1);
- if (grouping !== -1) {
- const layoutDoc = Doc.Layout(cd);
- const cx = NumCast(cd.x) - this._clusterDistance / 2;
- const cy = NumCast(cd.y) - this._clusterDistance / 2;
- const cw = NumCast(layoutDoc._width) + this._clusterDistance;
- const ch = NumCast(layoutDoc._height) + this._clusterDistance;
- return !layoutDoc.z && intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 }) ? grouping : cluster;
- }
- return cluster;
- }, -1);
- }
-
- tryDragCluster(e: PointerEvent, cluster: number) {
- if (cluster !== -1) {
- const ptsParent = e;
- if (ptsParent) {
- const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.Document._freeform_useClusters ? NumCast(cd.layout_cluster) : NumCast(cd.group, -1)) === cluster);
- const clusterDocs = eles.map(ele => DocumentManager.Instance.getDocumentView(ele, this.DocumentView?.())!);
- const { left, top } = clusterDocs[0].getBounds || { left: 0, top: 0 };
- const de = new DragManager.DocumentDragData(eles, e.ctrlKey || e.altKey ? dropActionType.embed : undefined);
- de.moveDocument = this._props.moveDocument;
- de.offset = this.screenToFreeformContentsXf.transformDirection(ptsParent.clientX - left, ptsParent.clientY - top);
- DragManager.StartDocumentDrag(
- clusterDocs.map(v => v.ContentDiv!),
- de,
- ptsParent.clientX,
- ptsParent.clientY,
- { hideSource: !de.dropAction }
- );
- return true;
- }
- }
-
- return false;
- }
-
- @action
- updateClusters(_freeform_useClusters: boolean) {
- this.Document._freeform_useClusters = _freeform_useClusters;
- this._clusterSets.length = 0;
- this.childLayoutPairs.map(pair => pair.layout).map(c => this.updateCluster(c));
- }
-
- @action
- updateClusterDocs(docs: Doc[]) {
- const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
- if (this.Document._freeform_useClusters) {
- const docFirst = docs[0];
- docs.map(doc => this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)));
- const preferredInd = NumCast(docFirst.layout_cluster);
- docs.map(doc => (doc.layout_cluster = -1));
- docs.map(doc =>
- this._clusterSets.map((set, i) =>
- set.map(member => {
- if (docFirst.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && CollectionFreeFormView.overlapping(doc, member, this._clusterDistance)) {
- docFirst.layout_cluster = i;
- }
- })
- )
- );
- if (
- docFirst.layout_cluster === -1 &&
- preferredInd !== -1 &&
- this._clusterSets.length > preferredInd &&
- (!this._clusterSets[preferredInd] || !this._clusterSets[preferredInd].filter(member => Doc.IndexOf(member, childLayouts) !== -1).length)
- ) {
- docFirst.layout_cluster = preferredInd;
- }
- this._clusterSets.map((set, i) => {
- if (docFirst.layout_cluster === -1 && !set.filter(member => Doc.IndexOf(member, childLayouts) !== -1).length) {
- docFirst.layout_cluster = i;
- }
- });
- if (docFirst.layout_cluster === -1) {
- docs.map(doc => {
- doc.layout_cluster = this._clusterSets.length;
- this._clusterSets.push([doc]);
- });
- } else if (this._clusterSets.length) {
- for (let i = this._clusterSets.length; i <= NumCast(docFirst.layout_cluster); i++) !this._clusterSets[i] && this._clusterSets.push([]);
- docs.map(doc => this._clusterSets[(doc.layout_cluster = NumCast(docFirst.layout_cluster))].push(doc));
- }
- childLayouts.map(child => !this._clusterSets.some((set, i) => Doc.IndexOf(child, set) !== -1 && child.layout_cluster === i) && this.updateCluster(child));
- }
- }
-
- @action
- updateCluster = (doc: Doc) => {
- const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
- if (this.Document._freeform_useClusters) {
- this._clusterSets.forEach(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1));
- const preferredInd = NumCast(doc.layout_cluster);
- doc.layout_cluster = -1;
- this._clusterSets.forEach((set, i) =>
- set.forEach(member => {
- if (doc.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && CollectionFreeFormView.overlapping(doc, member, this._clusterDistance)) {
- doc.layout_cluster = i;
- }
- })
- );
- if (doc.layout_cluster === -1 && preferredInd !== -1 && this._clusterSets.length > preferredInd && (!this._clusterSets[preferredInd] || !this._clusterSets[preferredInd].filter(member => Doc.IndexOf(member, childLayouts) !== -1).length)) {
- doc.layout_cluster = preferredInd;
- }
- this._clusterSets.forEach((set, i) => {
- if (doc.layout_cluster === -1 && !set.filter(member => Doc.IndexOf(member, childLayouts) !== -1).length) {
- doc.layout_cluster = i;
- }
- });
- if (doc.layout_cluster === -1) {
- doc.layout_cluster = this._clusterSets.length;
- this._clusterSets.push([doc]);
- } else if (this._clusterSets.length) {
- for (let i = this._clusterSets.length; i <= doc.layout_cluster; i++) !this._clusterSets[i] && this._clusterSets.push([]);
- this._clusterSets[doc.layout_cluster ?? 0].push(doc);
- }
- }
- };
-
- clusterStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => {
- let styleProp = this._props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1
- if (doc && this.childDocList?.includes(doc))
- switch (property) {
- case StyleProp.BackgroundColor:
- const cluster = NumCast(doc?.layout_cluster);
- if (this.Document._freeform_useClusters && doc?.type !== DocumentType.IMG) {
- if (this._clusterSets.length <= cluster) {
- setTimeout(() => doc && this.updateCluster(doc));
- } else {
- // choose a cluster color from a palette
- const colors = ['#da42429e', '#31ea318c', 'rgba(197, 87, 20, 0.55)', '#4a7ae2c4', 'rgba(216, 9, 255, 0.5)', '#ff7601', '#1dffff', 'yellow', 'rgba(27, 130, 49, 0.55)', 'rgba(0, 0, 0, 0.268)'];
- styleProp = colors[cluster % colors.length];
- const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor);
- // override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document
- set?.map(s => (styleProp = StrCast(s.backgroundColor)));
- }
- }
- break;
- case StyleProp.FillColor:
- if (doc && this.Document._currentFrame !== undefined) {
- return CollectionFreeFormDocumentView.getStringValues(doc, NumCast(this.Document._currentFrame))?.fillColor;
- }
- }
- return styleProp;
- };
-
- trySelectCluster = (addToSel: boolean) => {
- if (this._hitCluster !== -1) {
- !addToSel && SelectionManager.DeselectAll();
- const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.Document._freeform_useClusters ? NumCast(cd.layout_cluster) : NumCast(cd.group, -1)) === this._hitCluster);
- this.selectDocuments(eles);
- return true;
- }
- return false;
- };
-
@action
onPointerDown = (e: React.PointerEvent): void => {
this._downX = this._lastX = e.pageX;
@@ -618,27 +505,33 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
break;
case InkTool.None:
if (!(this._props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine))) {
- this._hitCluster = this.pickCluster(this.screenToFreeformContentsXf.transformPoint(e.clientX, e.clientY));
- setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, this._hitCluster !== -1 ? true : false, false);
+ const hit = this._clusters.handlePointerDown(this.screenToFreeformContentsXf.transformPoint(e.clientX, e.clientY));
+ setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, hit !== -1, false);
}
break;
+ default:
}
}
}
};
- public unprocessedDocs: Doc[] = [];
- public static collectionsWithUnprocessedInk = new Set<CollectionFreeFormView>();
@undoBatch
onGesture = (e: Event, ge: GestureUtils.GestureEvent) => {
switch (ge.gesture) {
- default:
- case GestureUtils.Gestures.Line:
- case GestureUtils.Gestures.Circle:
- case GestureUtils.Gestures.Rectangle:
- case GestureUtils.Gestures.Triangle:
- case GestureUtils.Gestures.Stroke:
- const points = ge.points;
+ case Gestures.Text:
+ if (ge.text) {
+ const B = this.screenToFreeformContentsXf.transformPoint(ge.points[0].X, ge.points[0].Y);
+ this.addDocument(Docs.Create.TextDocument(ge.text, { title: ge.text, x: B[0], y: B[1] }));
+ e.stopPropagation();
+ }
+ break;
+ case Gestures.Line:
+ case Gestures.Circle:
+ case Gestures.Rectangle:
+ case Gestures.Triangle:
+ case Gestures.Stroke:
+ default: {
+ const { points } = ge;
const B = this.screenToFreeformContentsXf.transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale;
const inkDoc = Docs.Create.InkDocument(
@@ -647,7 +540,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
x: B.x - inkWidth / 2,
y: B.y - inkWidth / 2,
_width: B.width + inkWidth,
- _height: B.height + inkWidth }, // prettier-ignore
+ _height: B.height + inkWidth,
+ stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore
inkWidth
);
if (Doc.ActiveTool === InkTool.Write) {
@@ -656,29 +550,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
this.addDocument(inkDoc);
e.stopPropagation();
- break;
- case GestureUtils.Gestures.Rectangle:
- const strokes = this.getActiveDocuments()
- .filter(doc => doc.type === DocumentType.INK)
- .map(i => {
- const d = Cast(i.stroke, InkField);
- const x = NumCast(i.x) - Math.min(...(d?.inkData.map(pd => pd.X) ?? [0]));
- const y = NumCast(i.y) - Math.min(...(d?.inkData.map(pd => pd.Y) ?? [0]));
- return !d ? [] : d.inkData.map(pd => ({ X: x + pd.X, Y: y + pd.Y }));
- });
-
- CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then(results => {});
- break;
- case GestureUtils.Gestures.Text:
- if (ge.text) {
- const B = this.screenToFreeformContentsXf.transformPoint(ge.points[0].X, ge.points[0].Y);
- this.addDocument(Docs.Create.TextDocument(ge.text, { title: ge.text, x: B[0], y: B[1] }));
- e.stopPropagation();
- }
+ }
}
};
@action
- onEraserUp = (e: PointerEvent): void => {
+ onEraserUp = (): void => {
this._deleteList.forEach(ink => ink._props.removeDocument?.(ink.Document));
this._deleteList = [];
this._batch?.end();
@@ -687,12 +563,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@action
onClick = (e: React.MouseEvent) => {
if (this._lightboxDoc) this._lightboxDoc = undefined;
- if (Utils.isClick(e.pageX, e.pageY, this._downX, this._downY, this._downTime)) {
- if (this.onBrowseClickHandler()) {
- this.onBrowseClickHandler().script.run({ documentView: this.DocumentView?.(), clientX: e.clientX, clientY: e.clientY });
- e.stopPropagation();
- e.preventDefault();
- } else if (this.isContentActive() && e.shiftKey) {
+ if (ClientUtils.isClick(e.pageX, e.pageY, this._downX, this._downY, this._downTime)) {
+ if (this.isContentActive() && e.shiftKey) {
// reset zoom of freeform view to 1-to-1 on a shift + double click
this.zoomSmoothlyAboutPt(this.screenToFreeformContentsXf.transformPoint(e.clientX, e.clientY), 1);
e.stopPropagation();
@@ -701,26 +573,23 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
};
- @action
scrollPan = (e: WheelEvent | { deltaX: number; deltaY: number }): void => {
- PresBox.Instance?.pauseAutoPres();
- this.setPan(NumCast(this.Document[this.panXFieldKey]) - e.deltaX, NumCast(this.Document[this.panYFieldKey]) - e.deltaY, 0, true);
+ SnappingManager.TriggerUserPanned();
+ this.setPan(NumCast(this.Document[this.panXFieldKey]) - e.deltaX, NumCast(this.Document[this.panYFieldKey]) - e.deltaY, 0);
};
@action
pan = (e: PointerEvent): void => {
- const ctrlKey = e.ctrlKey && !e.shiftKey;
- const shiftKey = e.shiftKey && !e.ctrlKey;
- PresBox.Instance?.pauseAutoPres();
+ const [ctrlKey, shiftKey] = [e.ctrlKey && !e.shiftKey, e.shiftKey && !e.ctrlKey];
+ SnappingManager.TriggerUserPanned();
this.DocumentView?.().clearViewTransition();
const [dxi, dyi] = this.screenToFreeformContentsXf.transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
const { x: dx, y: dy } = Utils.rotPt(dxi, dyi, this.ScreenToLocalBoxXf().Rotate);
- this.setPan(NumCast(this.Document[this.panXFieldKey]) - (ctrlKey ? 0 : dx), NumCast(this.Document[this.panYFieldKey]) - (shiftKey ? 0 : dy), 0, true);
+ this.setPan(NumCast(this.Document[this.panXFieldKey]) - (ctrlKey ? 0 : dx), NumCast(this.Document[this.panYFieldKey]) - (shiftKey ? 0 : dy), 0);
this._lastX = e.clientX;
this._lastY = e.clientY;
};
- _eraserLock = 0;
/**
* Erases strokes by intersecting them with an invisible "eraser stroke".
* By default this iterates through all intersected ink strokes, determines their segmentation, draws back the non-intersected segments,
@@ -743,7 +612,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
segments.forEach(segment =>
this.forceStrokeGesture(
e,
- GestureUtils.Gestures.Stroke,
+ Gestures.Stroke,
segment.reduce((data, curve) => [...data, ...curve.points.map(p => intersect.inkView.ComponentView?.ptToScreen?.({ X: p.x, Y: p.y }) ?? { X: 0, Y: 0 })], [] as PointData[])
)
);
@@ -756,12 +625,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
});
return false;
};
- forceStrokeGesture = (e: PointerEvent, gesture: GestureUtils.Gestures, points: InkData, text?: any) => {
- this.onGesture(e, new GestureUtils.GestureEvent(gesture, points, GestureOverlay.getBounds(points), text));
+ forceStrokeGesture = (e: PointerEvent, gesture: Gestures, points: InkData, text?: any) => {
+ this.onGesture(e, new GestureUtils.GestureEvent(gesture, points, InkField.getBounds(points), text));
};
onPointerMove = (e: PointerEvent) => {
- if (this.tryDragCluster(e, this._hitCluster)) {
+ if (this._clusters.tryToDrag(e)) {
e.stopPropagation(); // we're moving a cluster, so stop propagation and return true to end panning and let the document drag take over
return true;
}
@@ -780,26 +649,25 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
getEraserIntersections = (lastPoint: { X: number; Y: number }, currPoint: { X: number; Y: number }) => {
const eraserMin = { X: Math.min(lastPoint.X, currPoint.X), Y: Math.min(lastPoint.Y, currPoint.Y) };
const eraserMax = { X: Math.max(lastPoint.X, currPoint.X), Y: Math.max(lastPoint.Y, currPoint.Y) };
-
- return this.childDocs
- .map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.()))
+ // prettier-ignore
+ return this.childDocs
+ .map(doc => DocumentView.getDocumentView(doc, this.DocumentView?.()))
.filter(inkView => inkView?.ComponentView instanceof InkingStroke)
- .map(inkView => ({ inkViewBounds: inkView!.getBounds, inkStroke: inkView!.ComponentView as InkingStroke, inkView: inkView! }))
- .filter(
- ({ inkViewBounds }) =>
+ .map(inkView => inkView!)
+ .map(inkView => ({ inkViewBounds: inkView.getBounds, inkStroke: inkView.ComponentView as InkingStroke, inkView }))
+ .filter(({ inkViewBounds }) =>
inkViewBounds && // bounding box of eraser segment and ink stroke overlap
eraserMin.X <= inkViewBounds.right &&
eraserMin.Y <= inkViewBounds.bottom &&
eraserMax.X >= inkViewBounds.left &&
- eraserMax.Y >= inkViewBounds.top
- )
+ eraserMax.Y >= inkViewBounds.top)
.reduce(
(intersections, { inkStroke, inkView }) => {
const { inkData } = inkStroke.inkScaledData();
// Convert from screen space to ink space for the intersection.
const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint);
const currPointInkSpace = inkStroke.ptFromScreen(currPoint);
- for (var i = 0; i < inkData.length - 3; i += 4) {
+ for (let i = 0; i < inkData.length - 3; i += 4) {
const rawIntersects = InkField.Segment(inkData, i).intersects({
// compute all unique intersections
p1: { x: prevPointInkSpace.X, y: prevPointInkSpace.Y },
@@ -825,16 +693,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@action
segmentInkStroke = (ink: DocumentView, excludeT: number): Segment[] => {
const segments: Segment[] = [];
- var segment: Segment = [];
- var startSegmentT = 0;
+ let segment: Segment = [];
+ let startSegmentT = 0;
const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData();
// This iterates through all segments of the curve and splits them where they intersect another curve.
// if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted)
- for (var i = 0; i < inkData.length - 3; i += 4) {
+ for (let i = 0; i < inkData.length - 3; i += 4) {
const inkSegment = InkField.Segment(inkData, i);
// Getting all t-value intersections of the current curve with all other curves.
const tVals = this.getInkIntersections(i, ink, inkSegment).sort();
if (tVals.length) {
+ // eslint-disable-next-line no-loop-func
tVals.forEach((t, index) => {
const docCurveTVal = t + Math.floor(i / 4);
if (excludeT < startSegmentT || excludeT > docCurveTVal) {
@@ -883,13 +752,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this.childDocs
.filter(doc => doc.type === DocumentType.INK && !doc.dontIntersect)
.forEach(doc => {
- const otherInk = DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())?.ComponentView as InkingStroke;
+ const otherInk = DocumentView.getDocumentView(doc, this.DocumentView?.())?.ComponentView as InkingStroke;
const { inkData: otherInkData } = otherInk?.inkScaledData() ?? { inkData: [] };
const otherScreenPts = otherInkData.map(point => otherInk.ptToScreen(point));
const otherCtrlPts = otherScreenPts.map(spt => (ink.ComponentView as InkingStroke).ptFromScreen(spt));
- for (var j = 0; j < otherCtrlPts.length - 3; j += 4) {
+ for (let j = 0; j < otherCtrlPts.length - 3; j += 4) {
const neighboringSegment = i === j || i === j - 4 || i === j + 4;
// Ensuring that the curve intersected by the eraser is not checked for further ink intersections.
+ // eslint-disable-next-line no-continue
if (ink?.Document === otherInk.Document && neighboringSegment) continue;
const otherCurve = new Bezier(otherCtrlPts.slice(j, j + 4).map(p => ({ x: p.X, y: p.Y })));
@@ -900,7 +770,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (apt.d !== undefined && apt.d < 1 && apt.t !== undefined && !tVals.includes(apt.t)) {
tVals.push(apt.t);
}
- this.bintersects(curve, otherCurve).forEach((val: string | number, i: number) => {
+ this.bintersects(curve, otherCurve).forEach((val: string | number /* , i: number */) => {
// Converting the Bezier.js Split type to a t-value number.
const t = +val.toString().split('/')[0];
if (i % 2 === 0 && !tVals.includes(t)) tVals.push(t); // bcz: Hack! don't know why but intersection points are doubled from bezier.js (but not identical).
@@ -927,25 +797,22 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this.setPan(0, 0);
return;
}
- if (deltaScale * invTransform.Scale > NumCast(this.Document[this.scaleFieldKey + '_max'], Number.MAX_VALUE)) {
- deltaScale = NumCast(this.Document[this.scaleFieldKey + '_max'], 1) / invTransform.Scale;
- }
- if (deltaScale * invTransform.Scale < NumCast(this.Document[this.scaleFieldKey + '_min'], this.isAnnotationOverlay ? 1 : 0)) {
- deltaScale = NumCast(this.Document[this.scaleFieldKey + '_min'], 1) / invTransform.Scale;
- }
-
+ const minScale = NumCast(this.Document[this.scaleFieldKey + '_min'], this.isAnnotationOverlay ? 1 : 0);
+ const maxScale = NumCast(this.Document[this.scaleFieldKey + '_max'], Number.MAX_VALUE);
+ deltaScale = clamp(deltaScale, minScale / invTransform.Scale, maxScale / invTransform.Scale);
const localTransform = invTransform.scaleAbout(deltaScale, x, y);
if (localTransform.Scale >= 0.05 || localTransform.Scale > this.zoomScaling()) {
const safeScale = Math.min(Math.max(0.05, localTransform.Scale), 20);
+ const allowScroll = this.Document[this.scaleFieldKey] !== minScale && Math.abs(safeScale) === minScale;
this.Document[this.scaleFieldKey] = Math.abs(safeScale);
- this.setPan(-localTransform.TranslateX / safeScale, (this._props.originTopLeft ? undefined : NumCast(this.Document.layout_scrollTop) * safeScale) || -localTransform.TranslateY / safeScale);
+ this.setPan(-localTransform.TranslateX / safeScale, (this._props.originTopLeft ? undefined : NumCast(this.Document.layout_scrollTop) * safeScale) || -localTransform.TranslateY / safeScale, undefined, allowScroll);
}
};
@action
onPointerWheel = (e: React.WheelEvent): void => {
if (this.Document.isGroup || !this.isContentActive()) return; // group style collections neither pan nor zoom
- PresBox.Instance?.pauseAutoPres();
+ SnappingManager.TriggerUserPanned();
if (this.layoutDoc._Transform || this.Document.treeView_OutlineMode === TreeViewType.outline) return;
e.stopPropagation();
const docHeight = NumCast(this.Document[Doc.LayoutFieldKey(this.Document) + '_nativeHeight'], this.nativeHeight);
@@ -953,7 +820,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
switch (
!e.ctrlKey && !e.shiftKey && !e.metaKey && !e.altKey ?//
Doc.UserDoc().freeformScrollMode : // no modifiers, do assigned mode
- e.ctrlKey && !CtrlKey? // otherwise, if ctrl key (pinch gesture) try to zoom else pan
+ e.ctrlKey && !SnappingManager.CtrlKey? // otherwise, if ctrl key (pinch gesture) try to zoom else pan
freeformScrollMode.Zoom : freeformScrollMode.Pan // prettier-ignore
) {
case freeformScrollMode.Pan:
@@ -963,8 +830,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this.scrollPan({ deltaX: -deltaX * this.screenToFreeformContentsXf.Scale, deltaY: e.shiftKey ? 0 : -deltaY * this.screenToFreeformContentsXf.Scale });
break;
}
- default:
+ // eslint-disable-next-line no-fallthrough
case freeformScrollMode.Zoom:
+ default:
if ((e.ctrlKey || !scrollable) && this._props.isContentActive()) {
this.zoom(e.clientX, e.clientY, Math.max(-1, Math.min(1, e.deltaY))); // if (!this._props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc?
// e.preventDefault();
@@ -974,67 +842,40 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
@action
- setPan(panX: number, panY: number, panTime: number = 0, clamp: boolean = false) {
- // this is the easiest way to do this -> will talk with Bob about using mobx to do this to remove this line of code.
- if (Doc.UserDoc()?.presentationMode === 'watching') ReplayMovements.Instance.pauseFromInteraction();
+ setPan(panXIn: number, panYIn: number, panTime: number = 0, allowScroll = false) {
+ let [panX, panY] = [panXIn, panYIn];
- if (!this.isAnnotationOverlay && clamp) {
+ if (!this.isAnnotationOverlay && this.childDocs.length) {
// this section wraps the pan position, horizontally and/or vertically whenever the content is panned out of the viewing bounds
- const docs = this.childLayoutPairs.map(pair => pair.layout).filter(doc => doc instanceof Doc && doc.type !== DocumentType.LINK);
- const measuredDocs = docs
- .map(doc => ({ pos: { x: NumCast(doc.x), y: NumCast(doc.y) }, size: { width: NumCast(doc._width), height: NumCast(doc._height) } }))
- .filter(({ pos, size }) => pos && size)
- .map(({ pos, size }) => ({ pos: pos!, size: size! }));
- if (measuredDocs.length) {
- const ranges = measuredDocs.reduce(
- (
- { xrange, yrange },
- { pos, size } // computes range of content
- ) => ({
- xrange: { min: Math.min(xrange.min, pos.x), max: Math.max(xrange.max, pos.x + (size.width || 0)) },
- yrange: { min: Math.min(yrange.min, pos.y), max: Math.max(yrange.max, pos.y + (size.height || 0)) },
- }),
- {
- xrange: { min: this._props.originTopLeft ? 0 : Number.MAX_VALUE, max: -Number.MAX_VALUE },
- yrange: { min: this._props.originTopLeft ? 0 : Number.MAX_VALUE, max: -Number.MAX_VALUE },
- }
- );
- const scaling = this.zoomScaling() * (this._props.NativeDimScaling?.() || 1);
- const panelWidMax = (this._props.PanelWidth() / scaling) * (this._props.originTopLeft ? 2 / this.nativeDimScaling : 1);
- const panelWidMin = (this._props.PanelWidth() / scaling) * (this._props.originTopLeft ? 0 : 1);
- const panelHgtMax = (this._props.PanelHeight() / scaling) * (this._props.originTopLeft ? 2 / this.nativeDimScaling : 1);
- const panelHgtMin = (this._props.PanelHeight() / scaling) * (this._props.originTopLeft ? 0 : 1);
- if (ranges.xrange.min >= panX + panelWidMax / 2) panX = ranges.xrange.max + (this._props.originTopLeft ? 0 : panelWidMax / 2);
- else if (ranges.xrange.max <= panX - panelWidMin / 2) panX = ranges.xrange.min - (this._props.originTopLeft ? panelWidMax / 2 : panelWidMin / 2);
- if (ranges.yrange.min >= panY + panelHgtMax / 2) panY = ranges.yrange.max + (this._props.originTopLeft ? 0 : panelHgtMax / 2);
- else if (ranges.yrange.max <= panY - panelHgtMin / 2) panY = ranges.yrange.min - (this._props.originTopLeft ? panelHgtMax / 2 : panelHgtMin / 2);
- }
+ const { bounds: { x: xrangeMin, y: yrangeMin, r: xrangeMax, b: yrangeMax } } = this.contentBounds(); // prettier-ignore
+ const scaling = this.zoomScaling() * (this._props.NativeDimScaling?.() || 1);
+ const [widScaling, hgtScaling] = [this._props.PanelWidth() / scaling, this._props.PanelHeight() / scaling];
+ panX = clamp(panX, xrangeMin - widScaling / 2, xrangeMax + widScaling / 2);
+ panY = clamp(panY, yrangeMin - hgtScaling / 2, yrangeMax + hgtScaling / 2);
}
- if (!this.layoutDoc._lockedTransform || LightboxView.LightboxDoc) {
+ if (!this.layoutDoc._lockedTransform || DocumentView.LightboxDoc()) {
this.setPanZoomTransition(panTime);
const minScale = NumCast(this.dataDoc._freeform_scale_min, 1);
const scale = 1 - minScale / this.zoomScaling();
const minPanX = NumCast(this.dataDoc._freeform_panX_min, 0);
const minPanY = NumCast(this.dataDoc._freeform_panY_min, 0);
const maxPanX = NumCast(this.dataDoc._freeform_panX_max, this.nativeWidth);
- const newPanX = Math.min(minPanX + scale * maxPanX, Math.max(minPanX, panX));
+ const newPanX = clamp(panX, minPanX, minPanX + scale * maxPanX);
const fitYscroll = (((this.nativeHeight / this.nativeWidth) * this._props.PanelWidth() - this._props.PanelHeight()) * this.ScreenToLocalBoxXf().Scale) / minScale;
const nativeHeight = (this._props.PanelHeight() / this._props.PanelWidth() / (this.nativeHeight / this.nativeWidth)) * this.nativeHeight;
const maxScrollTop = this.nativeHeight / this.ScreenToLocalBoxXf().Scale - this._props.PanelHeight();
const maxPanY =
minPanY + // minPanY + scrolling introduced by view scaling + scrolling introduced by layout_fitWidth
- scale * NumCast(this.dataDoc._panY_max, nativeHeight) +
+ scale * NumCast(this.dataDoc._freeform_panY_max, nativeHeight) +
(!this._props.getScrollHeight?.() ? fitYscroll : 0); // when not zoomed, scrolling is handled via a scrollbar, not panning
- let newPanY = Math.max(minPanY, Math.min(maxPanY, panY));
- if (false && NumCast(this.layoutDoc.layout_scrollTop) && NumCast(this.layoutDoc._freeform_scale, minScale) !== minScale) {
- const relTop = NumCast(this.layoutDoc.layout_scrollTop) / maxScrollTop;
- this.layoutDoc.layout_scrollTop = undefined;
- newPanY = minPanY + relTop * (maxPanY - minPanY);
- } else if (fitYscroll > 2 && this.layoutDoc.layout_scrollTop === undefined && NumCast(this.layoutDoc._freeform_scale, minScale) === minScale) {
- const maxPanY = minPanY + fitYscroll;
- const relTop = (panY - minPanY) / (maxPanY - minPanY);
- setTimeout(() => (this.layoutDoc.layout_scrollTop = relTop * maxScrollTop), 10);
- newPanY = minPanY;
+ const newPanY = clamp(panY, minPanY, maxPanY);
+ // this mess fixes a problem when zooming to the default on an image that is fit width and can scroll.
+ // Without this, the scroll always goes to the top, instead of matching the pan position.
+ if (fitYscroll > 2 && allowScroll && NumCast(this.layoutDoc._freeform_scale, minScale) === minScale) {
+ setTimeout(() => {
+ const relTop = (clamp(panY, minPanY, fitYscroll) - minPanY) / fitYscroll;
+ this.layoutDoc.layout_scrollTop = relTop * maxScrollTop;
+ }, 10);
}
!this.Document._verticalScroll && (this.Document[this.panXFieldKey] = this.isAnnotationOverlay ? newPanX : panX);
!this.Document._horizontalScroll && (this.Document[this.panYFieldKey] = this.isAnnotationOverlay ? newPanY : panY);
@@ -1045,11 +886,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
nudge = (x: number, y: number, nudgeTime: number = 500) => {
const collectionDoc = this.Document;
if (collectionDoc?._type_collection !== CollectionViewType.Freeform) {
+ SnappingManager.TriggerUserPanned();
this.setPan(
NumCast(this.layoutDoc[this.panXFieldKey]) + ((this._props.PanelWidth() / 2) * x) / this.zoomScaling(), // nudge x,y as a function of panel dimension and scale
NumCast(this.layoutDoc[this.panYFieldKey]) + ((this._props.PanelHeight() / 2) * -y) / this.zoomScaling(),
- nudgeTime,
- true
+ nudgeTime
);
return true;
}
@@ -1085,7 +926,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._panZoomTransition = transitionTime;
this._panZoomTransitionTimer && clearTimeout(this._panZoomTransitionTimer);
this._panZoomTransitionTimer = setTimeout(
- action(() => (this._panZoomTransition = 0)),
+ action(() => {
+ this._panZoomTransition = 0;
+ }),
transitionTime
);
};
@@ -1112,9 +955,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (scale !== undefined) {
const maxZoom = 5; // sets the limit for how far we will zoom. this is useful for preventing small text boxes from filling the screen. So probably needs to be more sophisticated to consider more about the target and context
const newScale =
- scale === 0
- ? NumCast(this.layoutDoc[this.scaleFieldKey])
- : Math.min(maxZoom, (1 / (this.nativeDimScaling || 1)) * scale * Math.min(this._props.PanelWidth() / Math.abs(bounds.width), this._props.PanelHeight() / Math.abs(bounds.height)));
+ scale === 0 ? NumCast(this.layoutDoc[this.scaleFieldKey]) : Math.min(maxZoom, (1 / this.nativeDimScaling) * scale * Math.min(this._props.PanelWidth() / Math.abs(bounds.width), this._props.PanelHeight() / Math.abs(bounds.height)));
return {
panX: this._props.isAnnotationOverlay ? bounds.left - (Doc.NativeWidth(this.layoutDoc) / newScale - bounds.width) / 2 : (bounds.left + bounds.right) / 2,
panY: this._props.isAnnotationOverlay ? bounds.top - (Doc.NativeHeight(this.layoutDoc) / newScale - bounds.height) / 2 : (bounds.top + bounds.bot) / 2,
@@ -1160,7 +1001,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
newDoc[DocData][Doc.LayoutFieldKey(newDoc, fieldProps.LayoutTemplateString)] = undefined; // the copy should not copy the text contents of it source, just the render style
newDoc.x = NumCast(textDoc.x) + (below ? 0 : NumCast(textDoc._width) + 10);
newDoc.y = NumCast(textDoc.y) + (below ? NumCast(textDoc._height) + 10 : 0);
- FormattedTextBox.SetSelectOnLoad(newDoc);
+ Doc.SetSelectOnLoad(newDoc);
FormattedTextBox.DontSelectInitialText = true;
return this.addDocument?.(newDoc);
}, 'copied text note');
@@ -1170,20 +1011,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
e.stopPropagation?.();
return this.createTextDocCopy(fieldProps, !e.altKey && e.key !== 'Tab');
}
+ return undefined;
};
- @computed get childPointerEvents() {
- const engine = this._props.layoutEngine?.() || StrCast(this.Document._layoutEngine);
- return SnappingManager.IsResizing
- ? 'none'
- : this._props.childPointerEvents?.() ??
- (this._props.viewDefDivClick || //
- (engine === computePassLayout.name && !this._props.isSelected()) ||
- this.isContentActive() === false
- ? 'none'
- : this._props.pointerEvents?.());
- }
- @observable _childPointerEvents: 'none' | 'all' | 'visiblepainted' | undefined = undefined;
+ removeDocument = (docs: Doc | Doc[], annotationKey?: string | undefined) => {
+ const ret = !!this._props.removeDocument?.(docs, annotationKey);
+ // if this is a group and we have fewer than 2 Docs, then just promote what's left to our parent and get rid of the group.
+ if (ret && DocListCast(this.dataDoc[annotationKey ?? this.fieldKey]).length < 2 && this.Document.isGroup) {
+ this.promoteCollection();
+ }
+ return ret;
+ };
childPointerEventsFunc = () => this._childPointerEvents;
childContentsActive = () => (this._props.childContentsActive ?? this.isContentActive() === false ? returnFalse : emptyFunction)();
getChildDocView(entry: PoolData) {
@@ -1191,20 +1029,22 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const childData = entry.pair.data;
return (
<CollectionFreeFormDocumentView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...OmitKeys(entry, ['replica', 'pair']).omit}
key={childLayout[Id] + (entry.replica || '')}
Document={childLayout}
+ parent={this}
containerViewPath={this.DocumentView?.().docViewPath}
- styleProvider={this.clusterStyleProvider}
+ styleProvider={this._clusters.styleProvider}
TemplateDataDocument={childData}
dragStarting={this.dragStarting}
dragEnding={this.dragEnding}
+ isAnyChildContentActive={this.isAnyChildContentActive}
isGroupActive={this._props.isGroupActive}
renderDepth={this._props.renderDepth + 1}
hideDecorations={BoolCast(childLayout._layout_isSvg && childLayout.type === DocumentType.LINK)}
- suppressSetHeight={this.layoutEngine ? true : false}
+ suppressSetHeight={!!this.layoutEngine}
RenderCutoffProvider={this.renderCutoffProvider}
- CollectionFreeFormView={this}
LayoutTemplate={childLayout.z ? undefined : this._props.childLayoutTemplate}
LayoutTemplateString={childLayout.z ? undefined : this._props.childLayoutString}
rootSelected={childData ? this.rootSelected : returnFalse}
@@ -1212,7 +1052,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
onClickScript={this.onChildClickHandler}
onKey={this.onKeyDown}
onDoubleClickScript={this.onChildDoubleClickHandler}
- onBrowseClickScript={this.onBrowseClickHandler}
bringToFront={this.bringToFront}
ScreenToLocalTransform={childLayout.z ? this.ScreenToLocalBoxXf : this.ScreenToContentsXf}
PanelWidth={childLayout[Width]}
@@ -1225,50 +1064,55 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
focus={this.Document.isGroup ? this.groupFocus : this.isAnnotationOverlay ? this._props.focus : this.focus}
addDocTab={this.addDocTab}
addDocument={this._props.addDocument}
- removeDocument={this._props.removeDocument}
+ removeDocument={this.removeDocument}
moveDocument={this._props.moveDocument}
pinToPres={this._props.pinToPres}
whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
dragAction={(this.Document.childDragAction ?? this._props.childDragAction) as dropActionType}
- layout_showTitle={this._props.childlayout_showTitle}
+ showTitle={this._props.childlayout_showTitle}
dontRegisterView={this._props.dontRegisterView}
pointerEvents={this.childPointerEventsFunc}
/>
);
}
- addDocTab = action((doc: Doc, where: OpenWhere) => {
- if (this._props.isAnnotationOverlay) return this._props.addDocTab(doc, where);
+ addDocTab = action((docsIn: Doc | Doc[], location: OpenWhere) => {
+ const docs = toList(docsIn);
+ if (this._props.isAnnotationOverlay) return this._props.addDocTab(docs, location);
+ const where = location.split(':')[0];
switch (where) {
case OpenWhere.inParent:
- return this._props.addDocument?.(doc) || false;
- case OpenWhere.inParentFromScreen:
- const docContext = DocCast((doc instanceof Doc ? doc : doc?.[0])?.embedContainer);
+ return this._props.addDocument?.(docs) || false;
+ case OpenWhere.inParentFromScreen: {
+ const docContext = DocCast(docs[0]?.embedContainer);
return (
(this.addDocument?.(
- (doc instanceof Doc ? [doc] : doc).map(doc => {
- const pt = this.screenToFreeformContentsXf.transformPoint(NumCast(doc.x), NumCast(doc.y));
- doc.x = pt[0];
- doc.y = pt[1];
+ toList(docs).map(doc => {
+ [doc.x, doc.y] = this.screenToFreeformContentsXf.transformPoint(NumCast(doc.x), NumCast(doc.y));
return doc;
})
) &&
(!docContext || this._props.removeDocument?.(docContext))) ||
false
);
+ }
case undefined:
case OpenWhere.lightbox:
- if (this.layoutDoc._isLightbox) {
- this._lightboxDoc = doc;
- return true;
- }
- if (this.childDocList?.includes(doc)) {
- if (doc.hidden) doc.hidden = false;
- return true;
+ {
+ const firstDoc = docs[0];
+ if (this.layoutDoc._isLightbox) {
+ this._lightboxDoc = firstDoc;
+ return true;
+ }
+ if (firstDoc === this.Document || this.childDocList?.includes(firstDoc) || this.childLayoutPairs.map(pair => pair.layout)?.includes(firstDoc)) {
+ if (firstDoc.hidden) firstDoc.hidden = false;
+ if (!location.includes(OpenWhereMod.always)) return true;
+ }
}
+ break;
+ default:
}
- return this._props.addDocTab(doc, where);
+ return this._props.addDocTab(docs, location);
});
- @observable _lightboxDoc: Opt<Doc> = undefined;
getCalculatedPositions(pair: { layout: Doc; data?: Doc }): PoolData {
const random = (min: number, max: number, x: number, y: number) => /* min should not be equal to max */ min + (((Math.abs(x * y) * 9301 + 49297) % 233280) / 233280) * (max - min);
@@ -1287,14 +1131,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
!this.layoutDoc._rotation_jitter ? null
: NumCast(this.layoutDoc._rotation_jitter) * random(-1, 1, NumCast(x), NumCast(y)) );
return {
- x: Number.isNaN(NumCast(x)) ? 0 : NumCast(x),
- y: Number.isNaN(NumCast(y)) ? 0 : NumCast(y),
+ x: isNaN(NumCast(x)) ? 0 : NumCast(x),
+ y: isNaN(NumCast(y)) ? 0 : NumCast(y),
z: Cast(z, 'number'),
autoDim,
rotation,
- color: Cast(color, 'string') ? StrCast(color) : this._props.styleProvider?.(childDoc, this._props, StyleProp.Color),
- backgroundColor: Cast(backgroundColor, 'string') ? StrCast(backgroundColor) : this.clusterStyleProvider(childDoc, this._props, StyleProp.BackgroundColor),
- opacity: !_width ? 0 : this._keyframeEditing ? 1 : Cast(opacity, 'number') ?? this._props.styleProvider?.(childDoc, this._props, StyleProp.Opacity),
+ color: Cast(color, 'string', null),
+ backgroundColor: Cast(backgroundColor, 'string', null),
+ opacity: !_width ? 0 : this._keyframeEditing ? 1 : Cast(opacity, 'number', null),
zIndex: Cast(zIndex, 'number'),
width: _width,
height: _height,
@@ -1310,9 +1154,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
e.stopPropagation();
};
- viewDefsToJSX = (views: ViewDefBounds[]) => {
- return !Array.isArray(views) ? [] : views.filter(ele => this.viewDefToJSX(ele)).map(ele => this.viewDefToJSX(ele)!);
- };
+ viewDefsToJSX = (views: ViewDefBounds[]) => (!Array.isArray(views) ? [] : views.filter(ele => this.viewDefToJSX(ele)).map(ele => this.viewDefToJSX(ele)!));
viewDefToJSX(viewDef: ViewDefBounds): Opt<ViewDefResult> {
const { x, y, z } = viewDef;
@@ -1333,7 +1175,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
),
bounds: viewDef,
};
- } else if (viewDef.type === 'div') {
+ }
+ if (viewDef.type === 'div') {
return [x, y].some(val => val === undefined)
? undefined
: {
@@ -1349,13 +1192,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
bounds: viewDef,
};
}
+ return undefined;
}
- renderCutoffProvider = computedFn(
- function renderCutoffProvider(this: any, doc: Doc) {
- return this.Document.isTemplateDoc ? false : !this._renderCutoffData.get(doc[Id] + '');
- }.bind(this)
- );
+ /**
+ * Determines whether the passed doc should be rendered
+ * since rendering a large collection of documents can be slow, at startup, docs are rendered in batches.
+ * each doc's render() method will call the cutoff provider which will let the doc know if it should render itself yet, or wait
+ */
+ renderCutoffProvider = computedFn((doc: Doc) => (this.Document.isTemplateDoc ? false : !this._renderCutoffData.get(doc[Id] + '')));
doEngineLayout(
poolData: Map<string, PoolData>,
@@ -1365,27 +1210,23 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
doFreeformLayout(poolData: Map<string, PoolData>) {
- this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => poolData.set(pair.layout[Id], this.getCalculatedPositions(pair)));
+ this._clusters.initLayout();
+ this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => poolData.set(pair.layout[Id], this.getCalculatedPositions(pair)));
return [] as ViewDefResult[];
}
- @computed get layoutEngine() {
- return this._props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine);
- }
@computed get doInternalLayoutComputation() {
TraceMobx();
const newPool = new Map<string, PoolData>();
- // prettier-ignore
switch (this.layoutEngine) {
case computePassLayout.name : return { newPool, computedElementData: this.doEngineLayout(newPool, computePassLayout) };
case computeTimelineLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computeTimelineLayout) };
case computePivotLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computePivotLayout) };
case computeStarburstLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computeStarburstLayout) };
- }
- return { newPool, computedElementData: this.doFreeformLayout(newPool) };
+ default: return { newPool, computedElementData: this.doFreeformLayout(newPool) };
+ } // prettier-ignore
}
- @action
doLayoutComputation = (newPool: Map<string, PoolData>, computedElementData: ViewDefResult[]) => {
const elements = computedElementData.slice();
Array.from(newPool.entries())
@@ -1398,14 +1239,22 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
})
);
- this.Document._freeform_useClusters && !this._clusterSets.length && this.childDocs.length && this.updateClusters(true);
return elements;
};
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
// create an anchor that saves information about the current state of the freeform view (pan, zoom, view type)
- const anchor = Docs.Create.ConfigDocument({ title: 'ViewSpec - ' + StrCast(this.layoutDoc._type_collection), layout_unrendered: true, presentation_transition: 500, annotationOn: this.Document });
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: !this.Document.isGroup, type_collection: true, filters: true } }, this.Document);
+ const anchor = Docs.Create.ConfigDocument({
+ title: 'ViewSpec - ' + StrCast(this.layoutDoc._type_collection),
+ layout_unrendered: true,
+ presentation_transition: 500,
+ annotationOn: this.Document,
+ });
+ PinDocView(
+ anchor,
+ { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ? { ...pinProps.pinData, poslayoutview: pinProps.pinData.dataview } : {}), pannable: !this.Document.isGroup, type_collection: true, filters: true } },
+ this.Document
+ );
if (addAsAnnotation) {
if (Cast(this.dataDoc[this._props.fieldKey + '_annotations'], listSpec(Doc), null) !== undefined) {
@@ -1417,8 +1266,16 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return anchor;
};
- @action closeInfo = () => (this.Document._hideInfo = true);
- infoUI = () => (this.Document._hideInfo || this.Document.annotationOn || this._props.renderDepth ? null : <CollectionFreeFormInfoUI Document={this.Document} Freeform={this} close={this.closeInfo} />);
+ childDocsFunc = () => this.childDocs;
+ closeInfo = action(() => { Doc.IsInfoUIDisabled = true }); // prettier-ignore
+ static _infoUI: ((doc: Doc, layout: Doc, childDocs: () => Doc[], close: () => void) => JSX.Element) | null = null;
+ static SetInfoUICreator(func: (doc: Doc, layout: Doc, childDocs: () => Doc[], close: () => void) => JSX.Element) {
+ CollectionFreeFormView._infoUI = func;
+ }
+ infoUI = () =>
+ Doc.IsInfoUIDisabled || this.Document.annotationOn || this._props.renderDepth
+ ? null //
+ : CollectionFreeFormView._infoUI?.(this.Document, this.layoutDoc, this.childDocsFunc, this.closeInfo) || null;
componentDidMount() {
this._props.setContentViewBox?.(this);
@@ -1459,7 +1316,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._disposers.pointerevents = reaction(
() => this.childPointerEvents,
- pointerevents => (this._childPointerEvents = pointerevents as any),
+ pointerevents => {
+ this._childPointerEvents = pointerevents as any;
+ },
{ fireImmediately: true }
);
@@ -1476,6 +1335,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (!code.includes('dashDiv')) {
const script = CompileScript(code, { params: { docView: 'any' }, typecheck: false, editable: true });
if (script.compiled) script.run({ this: this.DocumentView?.() });
+ // eslint-disable-next-line no-eval
} else code && !first && eval?.(code);
},
{ fireImmediately: true }
@@ -1484,45 +1344,20 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._disposers.layoutElements = reaction(
// layoutElements can't be a computed value because doLayoutComputation() is an action that has side effect of updating clusters
() => this.doInternalLayoutComputation,
- computation => (this._layoutElements = this.doLayoutComputation(computation.newPool, computation.computedElementData)),
+ computation => {
+ this._layoutElements = this.doLayoutComputation(computation.newPool, computation.computedElementData);
+ },
{ fireImmediately: true }
);
}
- static replaceCanvases(oldDiv: HTMLElement, newDiv: HTMLElement) {
- if (oldDiv.childNodes && newDiv) {
- for (let i = 0; i < oldDiv.childNodes.length; i++) {
- this.replaceCanvases(oldDiv.childNodes[i] as HTMLElement, newDiv.childNodes[i] as HTMLElement);
- }
- }
- if (oldDiv instanceof HTMLCanvasElement) {
- if (oldDiv.className === 'collectionFreeFormView-grid') {
- const newCan = newDiv as HTMLCanvasElement;
- const parEle = newCan.parentElement as HTMLElement;
- parEle.removeChild(newCan);
- parEle.appendChild(document.createElement('div'));
- } else {
- const canvas = oldDiv;
- const img = document.createElement('img'); // create a Image Element
- try {
- img.src = canvas.toDataURL(); //image source
- } catch (e) {
- console.log(e);
- }
- img.style.width = canvas.style.width;
- img.style.height = canvas.style.height;
- const newCan = newDiv as HTMLCanvasElement;
- if (newCan) {
- const parEle = newCan.parentElement as HTMLElement;
- parEle.removeChild(newCan);
- parEle.appendChild(img);
- }
- }
- }
+ componentWillUnmount() {
+ this.dataDoc[this.autoResetFieldKey] && this.resetView();
+ Object.values(this._disposers).forEach(disposer => disposer?.());
}
updateIcon = () =>
- CollectionFreeFormView.UpdateIcon(
+ UpdateIcon(
this.layoutDoc[Id] + '-icon' + new Date().getTime(),
this.DocumentView?.().ContentDiv!,
NumCast(this.layoutDoc._width),
@@ -1540,55 +1375,20 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
);
- public static UpdateIcon(
- filename: string,
- docViewContent: HTMLElement,
- width: number,
- height: number,
- panelWidth: number,
- panelHeight: number,
- scrollTop: number,
- realNativeHeight: number,
- noSuffix: boolean,
- replaceRootFilename: string | undefined,
- cb: (iconFile: string, nativeWidth: number, nativeHeight: number) => any
- ) {
- const newDiv = docViewContent.cloneNode(true) as HTMLDivElement;
- newDiv.style.width = width.toString();
- newDiv.style.height = height.toString();
- this.replaceCanvases(docViewContent, newDiv);
- const htmlString = new XMLSerializer().serializeToString(newDiv);
- const nativeWidth = width;
- const nativeHeight = height;
- return CreateImage(Utils.prepend(''), document.styleSheets, htmlString, nativeWidth, (nativeWidth * panelHeight) / panelWidth, (scrollTop * panelHeight) / realNativeHeight)
- .then(async (data_url: any) => {
- const returnedFilename = await Utils.convertDataUri(data_url, filename, noSuffix, replaceRootFilename);
- cb(returnedFilename as string, nativeWidth, nativeHeight);
- })
- .catch(function (error: any) {
- console.error('oops, something went wrong!', error);
- });
- }
-
- componentWillUnmount() {
- this.dataDoc[this.autoResetFieldKey] && this.resetView();
- Object.values(this._disposers).forEach(disposer => disposer?.());
- }
-
- @action
- onCursorMove = (e: React.PointerEvent) => {
+ onCursorMove = () => {
// super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
};
@undoBatch
promoteCollection = () => {
const childDocs = this.childDocs.slice();
- childDocs.forEach(doc => {
+ childDocs.forEach(docIn => {
+ const doc = docIn;
const scr = this.screenToFreeformContentsXf.inverse().transformPoint(NumCast(doc.x), NumCast(doc.y));
doc.x = scr?.[0];
doc.y = scr?.[1];
});
- this._props.addDocTab(childDocs as any as Doc, OpenWhere.inParentFromScreen);
+ this._props.addDocTab(childDocs, OpenWhere.inParentFromScreen);
};
@undoBatch
@@ -1597,7 +1397,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const width = Math.max(...docs.map(doc => NumCast(doc._width))) + 20;
const height = Math.max(...docs.map(doc => NumCast(doc._height))) + 20;
const dim = Math.ceil(Math.sqrt(docs.length));
- docs.forEach((doc, i) => {
+ docs.forEach((docIn, i) => {
+ const doc = docIn;
doc.x = NumCast(this.Document[this.panXFieldKey]) + (i % dim) * width - (width * dim) / 2;
doc.y = NumCast(this.Document[this.panYFieldKey]) + Math.floor(i / dim) * height - (height * dim) / 2;
});
@@ -1630,7 +1431,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
};
- onContextMenu = (e: React.MouseEvent) => {
+ onContextMenu = () => {
if (this._props.isAnnotationOverlay || !ContextMenu.Instance) return;
const appearance = ContextMenu.Instance.findByDescription('Appearance...');
@@ -1641,7 +1442,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
!appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' });
return;
}
- !Doc.noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: 'Reset default note style', event: () => (Doc.UserDoc().defaultTextLayout = undefined), icon: 'eye' });
+ !Doc.noviceMode &&
+ Doc.UserDoc().defaultTextLayout &&
+ appearanceItems.push({
+ description: 'Reset default note style',
+ event: () => {
+ Doc.UserDoc().defaultTextLayout = undefined;
+ },
+ icon: 'eye',
+ });
appearanceItems.push({ description: `Pin View`, event: () => this._props.pinToPres(this.Document, { pinViewport: MarqueeView.CurViewBounds(this.dataDoc, this._props.PanelWidth(), this._props.PanelHeight()) }), icon: 'map-pin' });
!Doc.noviceMode && appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: 'compress-arrows-alt' });
this._props.renderDepth && appearanceItems.push({ description: 'Ungroup collection', event: this.promoteCollection, icon: 'table' });
@@ -1649,15 +1458,28 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this.Document.isGroup && this.Document.transcription && appearanceItems.push({ description: 'Ink to text', event: this.transcribeStrokes, icon: 'font' });
!Doc.noviceMode ? appearanceItems.push({ description: 'Arrange contents in grid', event: this.layoutDocsInGrid, icon: 'table' }) : null;
- !Doc.noviceMode ? appearanceItems.push({ description: (this.Document._freeform_useClusters ? 'Hide' : 'Show') + ' Clusters', event: () => this.updateClusters(!this.Document._freeform_useClusters), icon: 'braille' }) : null;
+ !Doc.noviceMode ? appearanceItems.push({ description: (this.Document._freeform_useClusters ? 'Hide' : 'Show') + ' Clusters', event: () => this._clusters.updateClusters(!this.Document._freeform_useClusters), icon: 'braille' }) : null;
!appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' });
const options = ContextMenu.Instance.findByDescription('Options...');
const optionItems = options && 'subitems' in options ? options.subitems : [];
!this._props.isAnnotationOverlay &&
!Doc.noviceMode &&
- optionItems.push({ description: (this._showAnimTimeline ? 'Close' : 'Open') + ' Animation Timeline', event: action(() => (this._showAnimTimeline = !this._showAnimTimeline)), icon: 'eye' });
- this._props.renderDepth && optionItems.push({ description: 'Use Background Color as Default', event: () => (Cast(Doc.UserDoc().emptyCollection, Doc, null).backgroundColor = StrCast(this.layoutDoc.backgroundColor)), icon: 'palette' });
+ optionItems.push({
+ description: (this._showAnimTimeline ? 'Close' : 'Open') + ' Animation Timeline',
+ event: action(() => {
+ this._showAnimTimeline = !this._showAnimTimeline;
+ }),
+ icon: 'eye',
+ });
+ this._props.renderDepth &&
+ optionItems.push({
+ description: 'Use Background Color as Default',
+ event: () => {
+ Cast(Doc.UserDoc().emptyCollection, Doc, null).backgroundColor = StrCast(this.layoutDoc.backgroundColor);
+ },
+ icon: 'palette',
+ });
this._props.renderDepth && optionItems.push({ description: 'Fit Content Once', event: this.fitContentOnce, icon: 'object-group' });
if (!Doc.noviceMode) {
optionItems.push({ description: (!Doc.NativeWidth(this.layoutDoc) || !Doc.NativeHeight(this.layoutDoc) ? 'Freeze' : 'Unfreeze') + ' Aspect', event: this.toggleNativeDimensions, icon: 'snowflake' });
@@ -1696,15 +1518,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const isDocInView = (doc: Doc, rect: { left: number; top: number; width: number; height: number }) => intersectRect(docDims(doc), rect);
const snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to
- activeDocs
- .filter(doc => doc.isGroup && SnappingManager.IsResizing !== doc && !DragManager.docsBeingDragged.includes(doc))
- .forEach(doc => DocumentManager.Instance.getDocumentView(doc)?.ComponentView?.dragStarting?.(snapToDraggedDoc, false, visited));
+ activeDocs.filter(doc => doc.isGroup && SnappingManager.IsResizing !== doc[Id] && !DragManager.docsBeingDragged.includes(doc)).forEach(doc => DocumentView.getDocumentView(doc)?.ComponentView?.dragStarting?.(snapToDraggedDoc, false, visited));
const horizLines: number[] = [];
const vertLines: number[] = [];
const invXf = this.screenToFreeformContentsXf.inverse();
snappableDocs
- .filter(doc => !doc.isGroup && (snapToDraggedDoc || (SnappingManager.IsResizing !== doc && !DragManager.docsBeingDragged.includes(doc))))
+ .filter(doc => !doc.isGroup && (snapToDraggedDoc || (SnappingManager.IsResizing !== doc[Id] && !DragManager.docsBeingDragged.includes(doc))))
.forEach(doc => {
const { left, top, width, height } = docDims(doc);
const topLeftInScreen = invXf.transformPoint(left, top);
@@ -1713,36 +1533,48 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
horizLines.push(topLeftInScreen[1], topLeftInScreen[1] + docSize[1] / 2, topLeftInScreen[1] + docSize[1]); // horiz center line
vertLines.push(topLeftInScreen[0], topLeftInScreen[0] + docSize[0] / 2, topLeftInScreen[0] + docSize[0]); // right line
});
- SnappingManager.addSnapLines(horizLines, vertLines);
+ this.layoutDoc._freeform_snapLines && SnappingManager.addSnapLines(horizLines, vertLines);
};
incrementalRendering = () => this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id])).length !== 0;
incrementalRender = action(() => {
- if (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.())) {
- const layout_unrendered = this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id]));
+ if (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.())) {
+ const layoutUnrendered = this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id]));
const loadIncrement = this.Document.isTemplateDoc ? Number.MAX_VALUE : 5;
- for (var i = 0; i < Math.min(layout_unrendered.length, loadIncrement); i++) {
- this._renderCutoffData.set(layout_unrendered[i][Id] + '', true);
+ for (let i = 0; i < Math.min(layoutUnrendered.length, loadIncrement); i++) {
+ this._renderCutoffData.set(layoutUnrendered[i][Id] + '', true);
}
}
this.childDocs.some(doc => !this._renderCutoffData.get(doc[Id])) && setTimeout(this.incrementalRender, 1);
});
- @computed get placeholder() {
- return (
- <div className="collectionfreeformview-placeholder" style={{ background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) }}>
- <span className="collectionfreeformview-placeholderSpan">{this.Document.annotationOn ? '' : this.Document.title?.toString()}</span>
- </div>
- );
- }
-
+ showPresPaths = () => SnappingManager.ShowPresPaths;
brushedView = () => this._brushedView;
- gridColor = () =>
- DashColor(lightOrDark(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor)))
- .fade(0.5)
- .toString();
- @computed get backgroundGrid() {
+ gridColor = () => DashColor(lightOrDark(this.backgroundColor)).fade(0.5).toString(); // prettier-ignore
+ nativeDim = () => this.nativeDimScaling;
+
+ brushView = action((viewport: { width: number; height: number; panX: number; panY: number }, transTime: number, holdTime: number = 2500) => {
+ this._brushtimer1 && clearTimeout(this._brushtimer1);
+ this._brushtimer && clearTimeout(this._brushtimer);
+ this._brushedView = undefined;
+ this._brushtimer1 = setTimeout(
+ action(() => {
+ this._brushedView = { ...viewport, panX: viewport.panX - viewport.width / 2, panY: viewport.panY - viewport.height / 2 };
+ this._brushtimer = setTimeout(action(() => { this._brushedView = undefined; }), holdTime); // prettier-ignore
+ }),
+ transTime + 1
+ );
+ });
+ lightboxPanelWidth = () => Math.max(0, this._props.PanelWidth() - 30);
+ lightboxPanelHeight = () => Math.max(0, this._props.PanelHeight() - 30);
+ lightboxScreenToLocal = () => this.ScreenToLocalBoxXf().translate(-15, -15);
+ onPassiveWheel = (e: WheelEvent) => {
+ const docHeight = NumCast(this.Document[Doc.LayoutFieldKey(this.Document) + '_nativeHeight'], this.nativeHeight);
+ const scrollable = NumCast(this.layoutDoc[this.scaleFieldKey], 1) === 1 && docHeight > this._props.PanelHeight() / this.nativeDimScaling;
+ this._props.isSelected() && !scrollable && e.preventDefault();
+ };
+ get backgroundGrid() {
return (
<div>
<CollectionFreeFormBackgroundGrid // bcz : UGHH don't know why, but if we don't wrap in a div, then PDF's don't render when taking snapshot of a dashboard and the background grid is on!!?
@@ -1755,12 +1587,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
zoomScaling={this.zoomScaling}
layoutDoc={this.layoutDoc}
isAnnotationOverlay={this.isAnnotationOverlay}
- cachedCenteringShiftX={this.cachedCenteringShiftX}
- cachedCenteringShiftY={this.cachedCenteringShiftY}
+ centeringShiftX={this.centeringShiftX}
+ centeringShiftY={this.centeringShiftY}
/>
</div>
);
}
+ transitionFunc = () => (this._panZoomTransition ? `transform ${this._panZoomTransition}ms ${this._presEaseFunc}` : Cast(this.layoutDoc._viewTransition, 'string', Cast(this.Document._viewTransition, 'string', null)));
get pannableContents() {
this.incrementalRender(); // needs to happen synchronously or freshly typed text documents will flash and miss their first characters
return (
@@ -1769,7 +1602,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
brushedView={this.brushedView}
isAnnotationOverlay={this.isAnnotationOverlay}
transform={this.PanZoomCenterXf}
- transition={this._panZoomTransition ? `transform ${this._panZoomTransition}ms` : Cast(this.layoutDoc._viewTransition, 'string', Cast(this.Document._viewTransition, 'string', null))}
+ showPresPaths={this.showPresPaths}
+ transition={this.transitionFunc}
viewDefDivClick={this._props.viewDefDivClick}>
{this.props.children ?? null} {/* most likely case of children is document content that's being annoated: eg., an image */}
{this.contentViews}
@@ -1786,7 +1620,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
nudge={this.isAnnotationOverlay || this._props.renderDepth > 0 ? undefined : this.nudge}
addDocTab={this.addDocTab}
slowLoadDocuments={this.slowLoadDocuments}
- trySelectCluster={this.trySelectCluster}
+ trySelectCluster={this._clusters.tryToSelect}
activeDocuments={this.getActiveDocuments}
selectDocuments={this.selectDocuments}
addDocument={this.addDocument}
@@ -1802,39 +1636,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
</MarqueeView>
);
}
-
- @computed get nativeDimScaling() {
- if (this._firstRender || (this._props.isAnnotationOverlay && !this._props.annotationLayerHostsContent)) return 0;
- const nw = this.nativeWidth;
- const nh = this.nativeHeight;
- const hscale = nh ? this._props.PanelHeight() / nh : 1;
- const wscale = nw ? this._props.PanelWidth() / nw : 1;
- return wscale < hscale || (this._props.layout_fitWidth?.(this.Document) ?? this.layoutDoc.layout_fitWidth) ? wscale : hscale;
- }
- nativeDim = () => this.nativeDimScaling;
-
- @action
- brushView = (viewport: { width: number; height: number; panX: number; panY: number }, transTime: number, holdTime: number = 2500) => {
- this._brushtimer1 && clearTimeout(this._brushtimer1);
- this._brushtimer && clearTimeout(this._brushtimer);
- this._brushedView = undefined;
- this._brushtimer1 = setTimeout(
- action(() => {
- this._brushedView = { ...viewport, panX: viewport.panX - viewport.width / 2, panY: viewport.panY - viewport.height / 2 };
- this._brushtimer = setTimeout(action(() => (this._brushedView = undefined)), holdTime); // prettier-ignore
- }),
- transTime + 1
+ get placeholder() {
+ return (
+ <div className="collectionfreeformview-placeholder" style={{ background: this.backgroundColor }}>
+ <span className="collectionfreeformview-placeholderSpan">{this.Document.annotationOn ? '' : this.Document.title?.toString()}</span>
+ </div>
);
- };
- lightboxPanelWidth = () => Math.max(0, this._props.PanelWidth() - 30);
- lightboxPanelHeight = () => Math.max(0, this._props.PanelHeight() - 30);
- lightboxScreenToLocal = () => this.ScreenToLocalBoxXf().translate(-15, -15);
- onPassiveWheel = (e: WheelEvent) => {
- const docHeight = NumCast(this.Document[Doc.LayoutFieldKey(this.Document) + '_nativeHeight'], this.nativeHeight);
- const scrollable = NumCast(this.layoutDoc[this.scaleFieldKey], 1) === 1 && docHeight > this._props.PanelHeight() / this.nativeDimScaling;
- this._props.isSelected() && !scrollable && e.preventDefault();
- };
- _oldWheel: any;
+ }
render() {
TraceMobx();
return (
@@ -1858,11 +1666,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
style={{
pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : (this._props.pointerEvents?.() as any),
textAlign: this.isAnnotationOverlay ? 'initial' : undefined,
- transform: `scale(${this.nativeDimScaling || 1})`,
- width: `${100 / (this.nativeDimScaling || 1)}%`,
- height: this._props.getScrollHeight?.() ?? `${100 / (this.nativeDimScaling || 1)}%`,
+ transform: `scale(${this.nativeDimScaling})`,
+ width: `${100 / this.nativeDimScaling}%`,
+ height: this._props.getScrollHeight?.() ?? `${100 / this.nativeDimScaling}%`,
}}>
- {this.paintFunc ? null : this._lightboxDoc ? (
+ {this.paintFunc ? (
+ <FormattedTextBox {...this.props} /> // need this so that any live dashfieldviews will update the underlying text that the code eval reads
+ ) : this._lightboxDoc ? (
<div style={{ padding: 15, width: '100%', height: '100%' }}>
<DocumentView
{...this._props}
@@ -1876,7 +1686,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
onClickScript={this.onChildClickHandler}
onKey={this.onKeyDown}
onDoubleClickScript={this.onChildDoubleClickHandler}
- onBrowseClickScript={this.onBrowseClickHandler}
childFilters={this.childDocFilters}
childFiltersByRanges={this.childDocRangeFilters}
searchFilterDocs={this.searchFilterDocs}
@@ -1899,47 +1708,24 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
);
}
}
-
-@observer
-class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> {
- render() {
- return this.props.elements().filter(ele => ele.bounds?.z).map(ele => ele.ele); // prettier-ignore
- }
-}
-
-export function CollectionBrowseClick(dv: DocumentView, clientX: number, clientY: number) {
- const browseTransitionTime = 500;
- SelectionManager.DeselectAll();
- dv &&
- DocumentManager.Instance.showDocument(dv.Document, { zoomScale: 0.8, willZoomCentered: true }, (focused: boolean) => {
- if (!focused) {
- const selfFfview = !dv.Document.isGroup && dv.ComponentView instanceof CollectionFreeFormView ? dv.ComponentView : undefined;
- let containers = dv.containerViewPath?.() ?? [];
- let parFfview = dv.CollectionFreeFormView;
- for (var cont of containers) {
- parFfview = parFfview ?? cont.CollectionFreeFormView;
- }
- while (parFfview?.Document.isGroup) parFfview = parFfview.DocumentView?.().CollectionFreeFormView;
- const ffview = selfFfview && selfFfview.layoutDoc[selfFfview.scaleFieldKey] !== 0.5 ? selfFfview : parFfview; // if focus doc is a freeform that is not at it's default 0.5 scale, then zoom out on it. Otherwise, zoom out on the parent ffview
- ffview?.zoomSmoothlyAboutPt(ffview.screenToFreeformContentsXf.transformPoint(clientX, clientY), ffview?.isAnnotationOverlay ? 1 : 0.5, browseTransitionTime);
- Doc.linkFollowHighlight(dv?.Document, false);
- }
- });
-}
-ScriptingGlobals.add(CollectionBrowseClick);
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function nextKeyFrame(readOnly: boolean) {
- !readOnly && (SelectionManager.Views[0].ComponentView as CollectionFreeFormView)?.changeKeyFrame();
+ !readOnly && (DocumentView.Selected()[0].ComponentView as CollectionFreeFormView)?.changeKeyFrame();
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function prevKeyFrame(readOnly: boolean) {
- !readOnly && (SelectionManager.Views[0].ComponentView as CollectionFreeFormView)?.changeKeyFrame(true);
+ !readOnly && (DocumentView.Selected()[0].ComponentView as CollectionFreeFormView)?.changeKeyFrame(true);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function curKeyFrame(readOnly: boolean) {
- const selView = SelectionManager.Views;
+ const selView = DocumentView.Selected();
if (readOnly) return selView[0].ComponentView?.getKeyFrameEditing?.() ? Colors.MEDIUM_BLUE : 'transparent';
runInAction(() => selView[0].ComponentView?.setKeyFrameEditing?.(!selView[0].ComponentView?.getKeyFrameEditing?.()));
+ return undefined;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function pinWithView(pinContent: boolean) {
- SelectionManager.Views.forEach(view =>
+ DocumentView.Selected().forEach(view =>
view._props.pinToPres(view.Document, {
currentFrame: Cast(view.Document.currentFrame, 'number', null),
pinData: {
@@ -1950,29 +1736,33 @@ ScriptingGlobals.add(function pinWithView(pinContent: boolean) {
})
);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function bringToFront() {
- SelectionManager.Views.forEach(view => view.CollectionFreeFormView?.bringToFront(view.Document));
+ DocumentView.Selected().forEach(view => CollectionFreeFormView.from(view)?.bringToFront(view.Document));
});
-ScriptingGlobals.add(function sendToBack(doc: Doc) {
- SelectionManager.Views.forEach(view => view.CollectionFreeFormView?.bringToFront(view.Document, true));
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function sendToBack() {
+ DocumentView.Selected().forEach(view => CollectionFreeFormView.from(view)?.bringToFront(view.Document, true));
});
-ScriptingGlobals.add(function datavizFromSchema(doc: Doc) {
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function datavizFromSchema() {
// creating a dataviz doc to represent the schema table
- SelectionManager.Views.forEach(view => {
+ DocumentView.Selected().forEach(viewIn => {
+ const view = viewIn;
if (!view.layoutDoc.schema_columnKeys) {
view.layoutDoc.schema_columnKeys = new List<string>(['title', 'type', 'author', 'author_date']);
}
- const keys = Cast(view.layoutDoc.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text');
+ const keys = Cast(view.layoutDoc.schema_columnKeys, listSpec('string'))?.filter(key => key !== 'text');
if (!keys) return;
const children = DocListCast(view.Document[Doc.LayoutFieldKey(view.Document)]);
- let csvRows = [];
+ const csvRows = [];
csvRows.push(keys.join(','));
for (let i = 0; i < children.length; i++) {
- let eachRow = [];
+ const eachRow = [];
for (let j = 0; j < keys.length; j++) {
- var cell = children[i][keys[j]]?.toString();
- if (cell) cell = cell.toString().replace(/\,/g, '');
+ let cell = children[i][keys[j]]?.toString();
+ if (cell) cell = cell.toString().replace(/,/g, '');
eachRow.push(cell);
}
csvRows.push(eachRow);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index 79cc534dc..adac5a102 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -9,6 +9,7 @@ import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
@observer
export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
+ // eslint-disable-next-line no-use-before-define
static Instance: MarqueeOptionsMenu;
public createCollection: (e: KeyboardEvent | React.PointerEvent | undefined, group?: boolean) => void = unimplementedFunction;
@@ -29,14 +30,13 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
}
render() {
- const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ width: 19 }} />;
const buttons = (
<>
- <IconButton tooltip={'Create a Collection'} onPointerDown={this.createCollection} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} />
- <IconButton tooltip={'Create a Grouping'} onPointerDown={e => this.createCollection(e, true)} icon={<FontAwesomeIcon icon="layer-group" />} color={this.userColor} />
- <IconButton tooltip={'Summarize Documents'} onPointerDown={this.summarize} icon={<FontAwesomeIcon icon="compress-arrows-alt" />} color={this.userColor} />
- <IconButton tooltip={'Delete Documents'} onPointerDown={this.delete} icon={<FontAwesomeIcon icon="trash-alt" />} color={this.userColor} />
- <IconButton tooltip={'Pin selected region'} onPointerDown={this.pinWithView} icon={<FontAwesomeIcon icon="map-pin" />} color={this.userColor} />
+ <IconButton tooltip="Create a Collection" onPointerDown={this.createCollection} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} />
+ <IconButton tooltip="Create a Grouping" onPointerDown={e => this.createCollection(e, true)} icon={<FontAwesomeIcon icon="layer-group" />} color={this.userColor} />
+ <IconButton tooltip="Summarize Documents" onPointerDown={this.summarize} icon={<FontAwesomeIcon icon="compress-arrows-alt" />} color={this.userColor} />
+ <IconButton tooltip="Delete Documents" onPointerDown={this.delete} icon={<FontAwesomeIcon icon="trash-alt" />} color={this.userColor} />
+ <IconButton tooltip="Pin selected region" onPointerDown={this.pinWithView} icon={<FontAwesomeIcon icon="map-pin" />} color={this.userColor} />
</>
);
return this.getElement(buttons);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index b913e05ad..b96444024 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -1,7 +1,9 @@
+/* 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 { Utils, intersectRect, lightOrDark, returnFalse } from '../../../../Utils';
+import { ClientUtils, lightOrDark, returnFalse } from '../../../../ClientUtils';
+import { intersectRect } from '../../../../Utils';
import { Doc, Opt } from '../../../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
@@ -12,22 +14,24 @@ import { Cast, FieldValue, NumCast, StrCast } from '../../../../fields/Types';
import { ImageField } from '../../../../fields/URLField';
import { GetEffectiveAcl } from '../../../../fields/util';
import { CognitiveServices } from '../../../cognitive_services/CognitiveServices';
+import { DocUtils } from '../../../documents/DocUtils';
import { DocumentType } from '../../../documents/DocumentTypes';
-import { DocUtils, Docs, DocumentOptions } from '../../../documents/Documents';
-import { SelectionManager } from '../../../util/SelectionManager';
-import { freeformScrollMode } from '../../../util/SettingsManager';
-import { SnappingManager } from '../../../util/SnappingManager';
+import { Docs, DocumentOptions } from '../../../documents/Documents';
+import { SnappingManager, freeformScrollMode } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
import { UndoManager, undoBatch } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { MarqueeViewBounds } from '../../PinFuncs';
import { PreviewCursor } from '../../PreviewCursor';
-import { OpenWhere } from '../../nodes/DocumentView';
+import { DocumentView } from '../../nodes/DocumentView';
+import { OpenWhere } from '../../nodes/OpenWhere';
import { pasteImageBitmap } from '../../nodes/WebBoxRenderer';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { SubCollectionViewProps } from '../CollectionSubView';
import { MarqueeOptionsMenu } from './MarqueeOptionsMenu';
import './MarqueeView.scss';
+
interface MarqueeViewProps {
getContainerTransform: () => Transform;
getTransform: () => Transform;
@@ -44,13 +48,6 @@ interface MarqueeViewProps {
slowLoadDocuments: (files: File[] | string, options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: ((doc: Doc[]) => void) | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => Promise<void>;
}
-export interface MarqueeViewBounds {
- left: number;
- top: number;
- width: number;
- height: number;
-}
-
@observer
export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps & MarqueeViewProps> {
public static CurViewBounds(pinDoc: Doc, panelWidth: number, panelHeight: number) {
@@ -101,13 +98,15 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
};
@action
- onKeyPress = (e: KeyboardEvent) => {
- //make textbox and add it to this collection
+ onKeyDown = (e: KeyboardEvent) => {
+ // make textbox and add it to this collection
// tslint:disable-next-line:prefer-const
const cm = ContextMenu.Instance;
const [x, y] = this.Transform.transformPoint(this._downX, this._downY);
if (e.key === '?') {
- cm.setDefaultItem('?', (str: string) => this._props.addDocTab(Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, { _width: 400, x, y, _height: 512, _nativeWidth: 850, title: 'bing', data_useCors: true }), OpenWhere.addRight));
+ cm.setDefaultItem('?', (str: string) =>
+ this._props.addDocTab(Docs.Create.WebDocument(`https://wikipedia.org/wiki/${str}`, { _width: 400, x, y, _height: 512, _nativeWidth: 850, title: `wiki:${str}`, data_useCors: true }), OpenWhere.addRight)
+ );
cm.displayMenu(this._downX, this._downY, undefined, true);
e.stopPropagation();
} else if (e.key === 'u' && this._props.ungroup) {
@@ -139,7 +138,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
}
}
let ypos = y;
- ns.map(line => {
+ ns.forEach(line => {
const indent = line.search(/\S|$/);
const newBox = Docs.Create.TextDocument(line, { _width: 200, _height: 35, x: x + (indent / 3) * 10, y: ypos, title: line });
this._props.addDocument?.(newBox);
@@ -153,7 +152,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
pasteImageBitmap((data: any, error: any) => {
error && console.log(error);
data &&
- Utils.convertDataUri(data, this._props.Document[Id] + '-thumb-frozen').then(returnedfilename => {
+ ClientUtils.convertDataUri(data, this._props.Document[Id] + '-thumb-frozen').then(returnedfilename => {
this._props.Document['thumb-frozen'] = new ImageField(returnedfilename);
});
})
@@ -163,11 +162,11 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
const slide = DocUtils.copyDragFactory(DocCast(Doc.UserDoc().emptySlide))!;
slide.x = x;
slide.y = y;
- FormattedTextBox.SelectOnLoad = slide[Id];
+ Doc.SetSelectOnLoad(slide);
TreeView._editTitleOnLoad = { id: slide[Id], parent: undefined };
this._props.addDocument?.(slide);
e.stopPropagation();
- }*/ else if (e.key === 'p' && e.ctrlKey) {
+ } */ else if (e.key === 'p' && e.ctrlKey) {
e.preventDefault();
(async () => {
const text: string = await navigator.clipboard.readText();
@@ -175,14 +174,14 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
this.pasteTable(ns, x, y);
})();
e.stopPropagation();
- } else if (!e.ctrlKey && !e.metaKey && SelectionManager.Views.length < 2) {
+ } else if (!e.ctrlKey && !e.metaKey && DocumentView.Selected().length < 2) {
FormattedTextBox.SelectOnLoadChar = Doc.UserDoc().defaultTextLayout && !this._props.childLayoutString ? e.key : '';
FormattedTextBox.LiveTextUndo = UndoManager.StartBatch('type new note');
this._props.addLiveTextDocument(DocUtils.GetNewTextDoc('-typed text-', x, y, 200, 100));
e.stopPropagation();
}
};
- //heuristically converts pasted text into a table.
+ // heuristically converts pasted text into a table.
// assumes each entry is separated by a tab
// skips all rows until it gets to a row with more than one entry
// assumes that 1st row has header entry for each column
@@ -190,15 +189,15 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
// any row that has only one column is a section header-- this header is then added as a column to subsequent rows until the next header
// assumes each cell is a string or a number
pasteTable(ns: string[], x: number, y: number) {
- let csvRows = [];
+ const csvRows = [];
const headers = ns[0].split('\t');
csvRows.push(headers.join(','));
ns[0] = '';
const eachCell = ns.join('\t').split('\t');
let eachRow = [];
for (let i = 1; i < eachCell.length; i++) {
- eachRow.push(eachCell[i].replace(/\,/g, ''));
- if (i % headers.length == 0) {
+ eachRow.push(eachCell[i].replace(/,/g, ''));
+ if (i % headers.length === 0) {
csvRows.push(eachRow);
eachRow = [];
}
@@ -231,7 +230,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
this._lastY = e.pageY;
this._lassoPts.push([e.clientX, e.clientY]);
if (!e.cancelBubble) {
- if (!Utils.isClick(this._lastX, this._lastY, this._downX, this._downY, Date.now())) {
+ if (!ClientUtils.isClick(this._lastX, this._lastY, this._downX, this._downY, Date.now())) {
if (!this._commandExecuted) {
this.showMarquee();
}
@@ -249,7 +248,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
if (this._visible) {
const mselect = this.marqueeSelect();
if (!e.shiftKey) {
- SelectionManager.DeselectAll(mselect.length ? undefined : this._props.Document);
+ DocumentView.DeselectAll(mselect.length ? undefined : this._props.Document);
}
const docs = mselect.length ? mselect : [this._props.Document];
this._props.selectDocuments(docs);
@@ -309,7 +308,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
const effectiveAcl = GetEffectiveAcl(this._props.Document[DocData]);
if ([AclAdmin, AclEdit, AclAugment].includes(effectiveAcl)) {
PreviewCursor.Instance.Doc = doc;
- PreviewCursor.Show(x, y, this.onKeyPress, this._props.addLiveTextDocument, this._props.getTransform, this._props.addDocument, this._props.nudge, this._props.slowLoadDocuments);
+ PreviewCursor.Show(x, y, this.onKeyDown, this._props.addLiveTextDocument, this._props.getTransform, this._props.addDocument, this._props.nudge, this._props.slowLoadDocuments);
}
this.clearSelection();
}
@@ -318,7 +317,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
@action
onClick = (e: React.MouseEvent): void => {
if (this._props.pointerEvents?.() === 'none') return;
- if (Utils.isClick(e.clientX, e.clientY, this._downX, this._downY, Date.now())) {
+ if (ClientUtils.isClick(e.clientX, e.clientY, this._downX, this._downY, Date.now())) {
if (Doc.ActiveTool === InkTool.None) {
if (!this._props.trySelectCluster(e.shiftKey)) {
!SnappingManager.ExploreMode && this.setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Document);
@@ -333,15 +332,21 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
};
@action
- showMarquee = () => (this._visible = true);
+ showMarquee = () => {
+ this._visible = true;
+ };
@action
- hideMarquee = () => (this._visible = false);
+ hideMarquee = () => {
+ this._visible = false;
+ };
@undoBatch
delete = action((e?: React.PointerEvent<Element> | KeyboardEvent | undefined, hide?: boolean) => {
const selected = this.marqueeSelect(false);
- SelectionManager.DeselectAll();
- selected.forEach(doc => (hide ? (doc.hidden = true) : this._props.removeDocument?.(doc)));
+ DocumentView.DeselectAll();
+ selected.forEach(doc => {
+ hide ? (doc.hidden = true) : this._props.removeDocument?.(doc);
+ });
this.cleanupInteractions(false);
MarqueeOptionsMenu.Instance.fadeOut(true);
@@ -372,9 +377,9 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
});
@undoBatch
- pileup = action((e: KeyboardEvent | React.PointerEvent | undefined) => {
+ pileup = action(() => {
const selected = this.marqueeSelect(false);
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
selected.forEach(d => this._props.removeDocument?.(d));
const newCollection = DocUtils.pileup(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2)!;
this._props.addDocument?.(newCollection);
@@ -384,7 +389,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
});
/**
- * This triggers the TabDocView.PinDoc method which is the universal method
+ * This triggers the DocumentView.PinDoc method which is the universal method
* used to pin documents to the currently active presentation trail.
*
* This one is unique in that it includes the bounds associated with marquee view.
@@ -480,7 +485,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
});
@undoBatch
- summary = action((e: KeyboardEvent | React.PointerEvent | undefined) => {
+ summary = action(() => {
const selected = this.marqueeSelect(false).map(d => {
this._props.removeDocument?.(d);
d.x = NumCast(d.x) - this.Bounds.left;
@@ -497,7 +502,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
_layout_showSidebar: true,
title: 'overview',
});
- const portal = Docs.Create.FreeformDocument(selected, { x: this.Bounds.left + 200, y: this.Bounds.top, isGroup: true, backgroundColor: 'transparent' });
+ const portal = Docs.Create.FreeformDocument(selected, { title: 'summarized documents', x: this.Bounds.left + 200, y: this.Bounds.top, isGroup: true, backgroundColor: 'transparent' });
DocUtils.MakeLink(summary, portal, { link_relationship: 'summary of:summarized by' });
portal.hidden = true;
@@ -525,8 +530,8 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
(e as any).propagationIsStopped = true;
if (e.key === 'g') this.collection(e, true);
if (e.key === 'c' || e.key === 't') this.collection(e);
- if (e.key === 's' || e.key === 'S') this.summary(e);
- if (e.key === 'p') this.pileup(e);
+ if (e.key === 's' || e.key === 'S') this.summary();
+ if (e.key === 'p') this.pileup();
this.cleanupInteractions(false);
}
if (e.key === 'r' || e.key === ' ') {
@@ -538,6 +543,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
};
touchesLine(r1: { left: number; top: number; width: number; height: number }) {
+ // eslint-disable-next-line no-restricted-syntax
for (const lassoPt of this._lassoPts) {
const topLeft = this.Transform.transformPoint(lassoPt[0], lassoPt[1]);
if (r1.left < topLeft[0] && topLeft[0] < r1.left + r1.width && r1.top < topLeft[1] && topLeft[1] < r1.top + r1.height) {
@@ -558,6 +564,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
let hasLeft = false;
let hasBottom = false;
let hasRight = false;
+ // eslint-disable-next-line no-restricted-syntax
for (const lassoPt of this._lassoPts) {
const truePoint = this.Transform.transformPoint(lassoPt[0], lassoPt[1]);
hasLeft = hasLeft || (truePoint[0] > tl[0] && truePoint[0] < r1.left && truePoint[1] > r1.top && truePoint[1] < r1.top + r1.height);
@@ -660,6 +667,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
};
render() {
return (
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events
<div
className="marqueeView"
ref={r => {
@@ -671,7 +679,9 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
cursor: [InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool) || this._visible ? 'crosshair' : 'pointer',
}}
onDragOver={e => e.preventDefault()}
- onScroll={e => (e.currentTarget.scrollTop = e.currentTarget.scrollLeft = 0)}
+ onScroll={e => {
+ e.currentTarget.scrollTop = e.currentTarget.scrollLeft = 0;
+ }}
onClick={this.onClick}
onPointerDown={this.onPointerDown}>
{this._visible ? this.marqueeDiv : null}
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index f25872c2b..2d9191dd7 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -1,10 +1,11 @@
import { action, computed, Lambda, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { returnFalse, returnZero, setupMoveUpEvents } from '../../../../ClientUtils';
import { Doc, Opt } from '../../../../fields/Doc';
import { Id } from '../../../../fields/FieldSymbols';
import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents } from '../../../../Utils';
+import { emptyFunction } from '../../../../Utils';
import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
import { Transform } from '../../../util/Transform';
@@ -12,10 +13,10 @@ import { undoBatch } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { ContextMenuProps } from '../../ContextMenuItem';
import { DocumentView } from '../../nodes/DocumentView';
-import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { CollectionSubView } from '../CollectionSubView';
import './CollectionGridView.scss';
import Grid, { Layout } from './Grid';
+
@observer
export class CollectionGridView extends CollectionSubView() {
private _containerRef: React.RefObject<HTMLDivElement> = React.createRef();
@@ -76,15 +77,13 @@ export class CollectionGridView extends CollectionSubView() {
pairs.forEach((pair, i) => {
const existing = oldLayouts.find(l => l.i === pair.layout[Id]);
if (existing) newLayouts.push(existing);
- else {
- if (Object.keys(this.dropLocation).length) {
- // external drop
- this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.dropLocation as { x: number; y: number }, !this.flexGrid));
- this.dropLocation = {};
- } else {
- // internal drop
- this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.unflexedPosition(i), !this.flexGrid));
- }
+ else if (Object.keys(this.dropLocation).length) {
+ // external drop
+ this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.dropLocation as { x: number; y: number }, !this.flexGrid));
+ this.dropLocation = {};
+ } else {
+ // internal drop
+ this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.unflexedPosition(i), !this.flexGrid));
}
});
pairs?.length && this.setLayoutList(newLayouts);
@@ -139,9 +138,7 @@ export class CollectionGridView extends CollectionSubView() {
/**
* Creates a layout object for a grid item
*/
- makeLayoutItem = (doc: Doc, pos: { x: number; y: number }, Static: boolean = false, w: number = this.defaultW, h: number = this.defaultH) => {
- return { i: doc[Id], w, h, x: pos.x, y: pos.y, static: Static };
- };
+ makeLayoutItem = (doc: Doc, pos: { x: number; y: number }, Static: boolean = false, w: number = this.defaultW, h: number = this.defaultH) => ({ i: doc[Id], w, h, x: pos.x, y: pos.y, static: Static });
/**
* Adds a layout to the list of layouts.
@@ -189,6 +186,7 @@ export class CollectionGridView extends CollectionSubView() {
getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) {
return (
<DocumentView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
NativeWidth={returnZero}
NativeHeight={returnZero}
@@ -218,7 +216,7 @@ export class CollectionGridView extends CollectionSubView() {
if (this.flexGrid) {
const savedLayouts = this.savedLayoutList;
this.childLayoutPairs.forEach(({ layout: doc }) => {
- const gridLayout = savedLayouts.find(gridLayout => gridLayout.i === doc[Id]);
+ const gridLayout = savedLayouts.find(layout => layout.i === doc[Id]);
if (gridLayout) Object.assign(gridLayout, layoutArray.find(layout => layout.i === doc[Id]) || gridLayout);
});
@@ -317,7 +315,9 @@ export class CollectionGridView extends CollectionSubView() {
e,
returnFalse,
action(() => {
- undoBatch(() => (this.Document.gridRowHeight = this._rowHeight))();
+ undoBatch(() => {
+ this.Document.gridRowHeight = this._rowHeight;
+ })();
this._rowHeight = undefined;
}),
emptyFunction,
@@ -331,8 +331,20 @@ export class CollectionGridView extends CollectionSubView() {
*/
onContextMenu = () => {
const displayOptionsMenu: ContextMenuProps[] = [];
- displayOptionsMenu.push({ description: 'Toggle Content Display Style', event: () => (this.Document.display = this.Document.display ? undefined : 'contents'), icon: 'copy' });
- displayOptionsMenu.push({ description: 'Toggle Vertical Centering', event: () => (this.Document.centerY = !this.Document.centerY), icon: 'copy' });
+ displayOptionsMenu.push({
+ description: 'Toggle Content Display Style',
+ event: () => {
+ this.Document.display = this.Document.display ? undefined : 'contents';
+ },
+ icon: 'copy',
+ });
+ displayOptionsMenu.push({
+ description: 'Toggle Vertical Centering',
+ event: () => {
+ this.Document.centerY = !this.Document.centerY;
+ },
+ icon: 'copy',
+ });
ContextMenu.Instance.addItem({ description: 'Display', subitems: displayOptionsMenu, icon: 'tv' });
};
@@ -346,14 +358,14 @@ export class CollectionGridView extends CollectionSubView() {
e,
returnFalse,
returnFalse,
- (e: PointerEvent, doubleTap?: boolean) => {
- if (doubleTap && !e.button) {
+ (clickEv: PointerEvent, doubleTap?: boolean) => {
+ if (doubleTap && !clickEv.button) {
undoBatch(
action(() => {
const text = Docs.Create.TextDocument('', { _width: 150, _height: 50 });
- FormattedTextBox.SetSelectOnLoad(text); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+ Doc.SetSelectOnLoad(text); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
Doc.AddDocToList(this.Document, this._props.fieldKey, text);
- this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(e.clientX, e.clientY))));
+ this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(clickEv.clientX, clickEv.clientY))));
})
)();
}
@@ -386,7 +398,7 @@ export class CollectionGridView extends CollectionSubView() {
width={this._props.PanelWidth()}
nodeList={this.contents.length ? this.contents : null}
layout={this.contents.length ? this.renderedLayoutList : undefined}
- childrenDraggable={this._props.isSelected() ? true : false}
+ childrenDraggable={!!this._props.isSelected()}
numCols={this.numCols}
rowHeight={this.rowHeight}
setLayout={this.setLayout}
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 228af78aa..eac0dc0e1 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -1,25 +1,27 @@
+/* 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 { Toggle, ToggleType, Type } from 'browndash-components';
import { IReactionDisposer, action, makeObservable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Utils, emptyFunction, returnEmptyDoclist, returnTrue } from '../../../../Utils';
+import { ClientUtils, returnTrue } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Doc, Opt } from '../../../../fields/Doc';
import { Height, Width } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
import { CollectionViewType } from '../../../documents/DocumentTypes';
import { BranchingTrailManager } from '../../../util/BranchingTrailManager';
-import { DocumentManager } from '../../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../../util/DragManager';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
import { SettingsManager } from '../../../util/SettingsManager';
import { Transform } from '../../../util/Transform';
import { UndoStack } from '../../UndoStack';
import { DocumentLinksButton } from '../../nodes/DocumentLinksButton';
import { DocumentView } from '../../nodes/DocumentView';
import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup';
-import { CollectionStackedTimeline } from '../CollectionStackedTimeline';
import { CollectionSubView } from '../CollectionSubView';
import './CollectionLinearView.scss';
@@ -46,13 +48,15 @@ export class CollectionLinearView extends CollectionSubView() {
this._dropDisposer?.();
this._widthDisposer?.();
this._selectedDisposer?.();
- this.childLayoutPairs.map((pair, ind) => ScriptCast(DocCast(pair.layout.proto)?.onPointerUp)?.script.run({ this: pair.layout.proto }, console.log));
+ this.childLayoutPairs.map(pair => ScriptCast(DocCast(pair.layout.proto)?.onPointerUp)?.script.run({ this: pair.layout.proto }, console.log));
}
componentDidMount() {
this._widthDisposer = reaction(
() => 5 + NumCast(this.dataDoc.linearBtnWidth, this.dimension()) + (this.layoutDoc.linearView_IsOpen ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (NumCast(doc._width) || this.dimension()) + tot + 4, 0) : 0),
- width => this.childDocs.length && (this.layoutDoc._width = width),
+ width => {
+ this.childDocs.length && (this.layoutDoc._width = width);
+ },
{ fireImmediately: true }
);
}
@@ -64,14 +68,14 @@ export class CollectionLinearView extends CollectionSubView() {
dimension = () => NumCast(this.layoutDoc._height);
getTransform = (ele: Opt<HTMLDivElement>) => {
if (!ele) return Transform.Identity();
- const { scale, translateX, translateY } = Utils.GetScreenTransform(ele);
+ const { translateX, translateY } = ClientUtils.GetScreenTransform(ele);
return new Transform(-translateX, -translateY, 1);
};
@action
exitLongLinks = () => {
if (DocumentLinksButton.StartLink?.Document) {
- action((e: React.PointerEvent<HTMLDivElement>) => Doc.UnBrushDoc(DocumentLinksButton.StartLink?.Document as Doc));
+ action(() => Doc.UnBrushDoc(DocumentLinksButton.StartLink?.Document as Doc));
}
DocumentLinksButton.StartLink = undefined;
DocumentLinksButton.StartLinkView = undefined;
@@ -97,8 +101,8 @@ export class CollectionLinearView extends CollectionSubView() {
e.preventDefault();
};
- getLinkUI = () => {
- return !DocumentLinksButton.StartLink ? null : (
+ getLinkUI = () =>
+ !DocumentLinksButton.StartLink ? null : (
<span className="bottomPopup-background" style={{ pointerEvents: 'all' }} onPointerDown={e => e.stopPropagation()}>
<span className="bottomPopup-text">
Creating link from:{' '}
@@ -108,7 +112,7 @@ export class CollectionLinearView extends CollectionSubView() {
</b>
</span>
- <Tooltip title={<div className="dash-tooltip">{'Toggle description pop-up'} </div>} placement="top">
+ <Tooltip title={<div className="dash-tooltip">Toggle description pop-up </div>} placement="top">
<span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}>
Labels: {LinkDescriptionPopup.Instance.showDescriptions ? LinkDescriptionPopup.Instance.showDescriptions : 'ON'}
</span>
@@ -121,16 +125,15 @@ export class CollectionLinearView extends CollectionSubView() {
</Tooltip>
</span>
);
- };
- getCurrentlyPlayingUI = () => {
- return !CollectionStackedTimeline.CurrentlyPlaying?.length ? null : (
+ getCurrentlyPlayingUI = () =>
+ !DocumentView.CurrentlyPlaying?.length ? null : (
<span className="bottomPopup-background">
<span className="bottomPopup-text">
Currently playing:
- {CollectionStackedTimeline.CurrentlyPlaying.map((clip, i) => (
+ {DocumentView.CurrentlyPlaying.map((clip, i) => (
<>
- <span className="audio-title" onPointerDown={() => DocumentManager.Instance.showDocument(clip.Document, { willZoomCentered: true })}>
- {clip.Document.title + (i === CollectionStackedTimeline.CurrentlyPlaying.length - 1 ? ' ' : ',')}
+ <span className="audio-title" onPointerDown={() => DocumentView.showDocument(clip.Document, { willZoomCentered: true })}>
+ {clip.Document.title + (i === DocumentView.CurrentlyPlaying.length - 1 ? ' ' : ',')}
</span>
<FontAwesomeIcon icon={!clip.ComponentView?.IsPlaying?.() ? 'play' : 'pause'} size="lg" onPointerDown={() => clip.ComponentView?.TogglePause?.()} />{' '}
<FontAwesomeIcon icon="times" size="lg" onPointerDown={() => clip.ComponentView?.Pause?.()} />{' '}
@@ -139,7 +142,6 @@ export class CollectionLinearView extends CollectionSubView() {
</span>
</span>
);
- };
getDisplayDoc = (doc: Doc, preview: boolean = false) => {
// hack to avoid overhead of making UndoStack,etc into DocumentView style Boxes. If the UndoStack is ever intended to become part of the persisten state of the dashboard, then this would have to change.
@@ -149,6 +151,7 @@ export class CollectionLinearView extends CollectionSubView() {
case '<CurrentlyPlayingUI>': return this.getCurrentlyPlayingUI();
case '<UndoStack>': return <UndoStack key={doc[Id]}/>;
case '<Branching>': return Doc.UserDoc().isBranchingMode ? <BranchingTrailManager key={doc[Id]} /> : null;
+ default:
}
const nested = doc._type_collection === CollectionViewType.Linear;
@@ -161,7 +164,9 @@ export class CollectionLinearView extends CollectionSubView() {
<div
className={preview ? 'preview' : `collectionLinearView-docBtn`}
key={doc[Id]}
- ref={r => (dref = r || undefined)}
+ ref={r => {
+ dref = r || undefined;
+ }}
style={{
pointerEvents: 'all',
width: NumCast(doc._width),
@@ -194,7 +199,7 @@ export class CollectionLinearView extends CollectionSubView() {
childFilters={this._props.childFilters}
childFiltersByRanges={this._props.childFiltersByRanges}
searchFilterDocs={this._props.searchFilterDocs}
- hideResizeHandles={true}
+ hideResizeHandles
/>
</div>
);
@@ -220,30 +225,26 @@ export class CollectionLinearView extends CollectionSubView() {
ScriptCast(this.Document.onClick)?.script.run({ this: this.Document }, console.log);
}}
tooltip={isExpanded ? 'Close' : 'Open'}
- fillWidth={true}
- align={'center'}
+ fillWidth
+ align="center"
/>
);
return (
<div className={`collectionLinearView-outer ${this.layoutDoc.linearView_SubMenu}`} style={{ backgroundColor: this.layoutDoc.linearView_IsOpen ? undefined : 'transparent' }}>
<div className="collectionLinearView" ref={this.createDashEventsTarget} onContextMenu={this.myContextMenu} style={{ minHeight: this.dimension(), pointerEvents: 'all' }}>
- {
- <>
- {!this.layoutDoc.linearView_Expandable ? null : menuOpener}
- {!this.layoutDoc.linearView_IsOpen ? null : (
- <div
- className="collectionLinearView-content"
- style={{
- height: this.dimension(),
- flexDirection: flexDir as any,
- gap: flexGap,
- }}>
- {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))}
- </div>
- )}
- </>
- }
+ {!this.layoutDoc.linearView_Expandable ? null : menuOpener}
+ {!this.layoutDoc.linearView_IsOpen ? null : (
+ <div
+ className="collectionLinearView-content"
+ style={{
+ height: this.dimension(),
+ flexDirection: flexDir as any,
+ gap: flexGap,
+ }}>
+ {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))}
+ </div>
+ )}
</div>
</div>
);
diff --git a/src/client/views/collections/collectionLinear/index.ts b/src/client/views/collections/collectionLinear/index.ts
index ff73e14ae..ab3b4b0b5 100644
--- a/src/client/views/collections/collectionLinear/index.ts
+++ b/src/client/views/collections/collectionLinear/index.ts
@@ -1 +1 @@
-export * from "./CollectionLinearView"; \ No newline at end of file
+export * from './CollectionLinearView';
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 125dd2781..b8509a005 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -1,3 +1,5 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { Button, IconButton } from 'browndash-components';
@@ -7,7 +9,7 @@ import * as React from 'react';
import { FaChevronRight } from 'react-icons/fa';
import { Doc, DocListCast } from '../../../../fields/Doc';
import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { DragManager, dropActionType } from '../../../util/DragManager';
+import { DragManager } from '../../../util/DragManager';
import { SettingsManager } from '../../../util/SettingsManager';
import { Transform } from '../../../util/Transform';
import { undoBatch, undoable } from '../../../util/UndoManager';
@@ -16,6 +18,7 @@ import { CollectionSubView } from '../CollectionSubView';
import './CollectionMulticolumnView.scss';
import ResizeBar from './MulticolumnResizer';
import WidthLabel from './MulticolumnWidthLabel';
+import { dropActionType } from '../../../util/DropActionTypes';
interface WidthSpecifier {
magnitude: number;
@@ -80,7 +83,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
private get resolvedLayoutInformation(): LayoutData {
let starSum = 0;
const widthSpecifiers: WidthSpecifier[] = [];
- this.childLayouts.map(layout => {
+ this.childLayouts.forEach(layout => {
const unit = StrCast(layout._dimUnit, '*');
const magnitude = NumCast(layout._dimMagnitude, this.minimumDim);
if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) {
@@ -140,6 +143,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) {
return this._props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)) - 2 * NumCast(this.Document._xMargin);
}
+ return undefined;
}
/**
@@ -159,6 +163,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
if (this.resolvedLayoutInformation && this.totalRatioAllocation !== undefined) {
return this.totalRatioAllocation / this.resolvedLayoutInformation.starSum;
}
+ return undefined;
}
/**
@@ -175,7 +180,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
* or the ratio width evaluated to a pixel value
*/
private lookupPixels = (layout: Doc): number => {
- const columnUnitLength = this.columnUnitLength;
+ const { columnUnitLength } = this;
if (columnUnitLength === undefined) {
return 0; // we're still waiting on promises to resolve
}
@@ -193,19 +198,19 @@ export class CollectionMulticolumnView extends CollectionSubView() {
* documents before the target.
*/
private lookupIndividualTransform = (layout: Doc) => {
- const columnUnitLength = this.columnUnitLength;
+ const { columnUnitLength } = this;
if (columnUnitLength === undefined) {
return Transform.Identity(); // we're still waiting on promises to resolve
}
let offset = 0;
- var xf = Transform.Identity();
- this.childLayouts.map(candidate => {
+ // eslint-disable-next-line no-restricted-syntax
+ for (const { layout: candidate } of this.childLayoutPairs) {
if (candidate === layout) {
- return (xf = this.ScreenToLocalBoxXf().translate(-offset / (this._props.NativeDimScaling?.() || 1), 0));
+ return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1));
}
offset += this.lookupPixels(candidate) + resizerWidth;
- });
- return xf;
+ }
+ return Transform.Identity();
};
@undoBatch
@@ -213,7 +218,9 @@ export class CollectionMulticolumnView extends CollectionSubView() {
let dropInd = -1;
if (de.complete.docDragData && this._mainCont) {
let curInd = -1;
- de.complete.docDragData?.droppedDocuments.forEach(d => (curInd = this.childDocs.indexOf(d)));
+ de.complete.docDragData?.droppedDocuments.forEach(d => {
+ curInd = this.childDocs.indexOf(d);
+ });
Array.from(this._mainCont.children).forEach((child, index) => {
const brect = child.getBoundingClientRect();
if (brect.x < de.x && brect.x + brect.width > de.x) {
@@ -265,7 +272,6 @@ export class CollectionMulticolumnView extends CollectionSubView() {
this.lookupIndividualTransform(childLayout)
.translate(-NumCast(this.layoutDoc._xMargin), -NumCast(this.layoutDoc._yMargin))
.scale(this._props.NativeDimScaling?.() || 1);
- const shouldNotScale = () => this._props.fitContentsToBox?.() || BoolCast(childLayout.freeform_fitContentsToBox);
return (
<DocumentView
Document={childLayout}
@@ -281,11 +287,11 @@ export class CollectionMulticolumnView extends CollectionSubView() {
dragAction={StrCast(this.Document.childDragAction, this._props.childDragAction) as dropActionType}
onClickScript={this.onChildClickHandler}
onDoubleClickScript={this.onChildDoubleClickHandler}
- suppressSetHeight={true}
+ suppressSetHeight
ScreenToLocalTransform={dxf}
isContentActive={this.isChildContentActive}
isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
- hideResizeHandles={childLayout.layout_fitWidth || this._props.childHideResizeHandles ? true : false}
+ hideResizeHandles={!!(childLayout.layout_fitWidth || this._props.childHideResizeHandles)}
hideDecorationTitle={this._props.childHideDecorationTitle}
fitContentsToBox={this._props.fitContentsToBox}
focus={this._props.focus}
@@ -312,17 +318,19 @@ export class CollectionMulticolumnView extends CollectionSubView() {
const collector: JSX.Element[] = [];
this.childLayouts.forEach((layout, i) => {
collector.push(
+ // eslint-disable-next-line react/no-array-index-key
<Tooltip title={'Tab: ' + StrCast(layout.title)} key={'wrapper' + i}>
<div className="document-wrapper" style={{ flexDirection: 'column', width: this.lookupPixels(layout) }}>
{this.getDisplayDoc(layout)}
{this.layoutDoc._chromeHidden ? null : (
- <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(e => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} />
+ <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(() => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} />
)}
<WidthLabel layout={layout} collectionDoc={this.Document} />
</div>
</Tooltip>,
<ResizeBar
width={resizerWidth}
+ // eslint-disable-next-line react/no-array-index-key
key={'resizer' + i}
styleProvider={this._props.styleProvider}
isContentActive={this._props.isContentActive}
@@ -353,14 +361,29 @@ export class CollectionMulticolumnView extends CollectionSubView() {
{this.contents}
{!this._startIndex ? null : (
<Tooltip title="scroll back">
- <div style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }} onClick={action(e => (this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown)))}>
- <Button tooltip="Scroll back" icon={<FontAwesomeIcon icon="chevron-left" size="lg" />} onClick={action(e => (this._startIndex = Math.max(0, this._startIndex - this.maxShown)))} color={SettingsManager.userColor} />
+ <div
+ style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }}
+ onClick={action(() => {
+ this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
+ })}>
+ <Button
+ tooltip="Scroll back"
+ icon={<FontAwesomeIcon icon="chevron-left" size="lg" />}
+ onClick={action(() => {
+ this._startIndex = Math.max(0, this._startIndex - this.maxShown);
+ })}
+ color={SettingsManager.userColor}
+ />
</div>
</Tooltip>
)}
{this._startIndex > this.childLayoutPairs.length - 1 || !this.maxShown ? null : (
<Tooltip title="scroll forward">
- <div style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }} onClick={action(e => (this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown)))}>
+ <div
+ style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }}
+ onClick={action(() => {
+ this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
+ })}>
<IconButton icon={<FaChevronRight />} color={SettingsManager.userColor} />
</div>
</Tooltip>
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 17bf3e50c..3fe3d5343 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast } from '../../../../fields/Doc';
import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { DragManager, dropActionType } from '../../../util/DragManager';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
import { Transform } from '../../../util/Transform';
import { undoBatch } from '../../../util/UndoManager';
import { DocumentView } from '../../nodes/DocumentView';
@@ -11,6 +12,7 @@ import { CollectionSubView } from '../CollectionSubView';
import './CollectionMultirowView.scss';
import HeightLabel from './MultirowHeightLabel';
import ResizeBar from './MultirowResizer';
+
interface HeightSpecifier {
magnitude: number;
unit: string;
@@ -63,7 +65,7 @@ export class CollectionMultirowView extends CollectionSubView() {
private get resolvedLayoutInformation(): LayoutData {
let starSum = 0;
const heightSpecifiers: HeightSpecifier[] = [];
- this.childLayoutPairs.map(pair => {
+ this.childLayoutPairs.forEach(pair => {
const unit = StrCast(pair.layout._dimUnit, '*');
const magnitude = NumCast(pair.layout._dimMagnitude, this.minimumDim);
if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) {
@@ -123,6 +125,7 @@ export class CollectionMultirowView extends CollectionSubView() {
if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) {
return this._props.PanelHeight() - (this.totalFixedAllocation + resizerHeight * (layoutInfoLen - 1)) - 2 * NumCast(this.Document._yMargin);
}
+ return undefined;
}
/**
@@ -142,6 +145,7 @@ export class CollectionMultirowView extends CollectionSubView() {
if (this.resolvedLayoutInformation && this.totalRatioAllocation !== undefined) {
return this.totalRatioAllocation / this.resolvedLayoutInformation.starSum;
}
+ return undefined;
}
/**
@@ -158,13 +162,12 @@ export class CollectionMultirowView extends CollectionSubView() {
* or the ratio width evaluated to a pixel value
*/
private lookupPixels = (layout: Doc): number => {
- const rowUnitLength = this.rowUnitLength;
- if (rowUnitLength === undefined) {
+ if (this.rowUnitLength === undefined) {
return 0; // we're still waiting on promises to resolve
}
let height = NumCast(layout._dimMagnitude, this.minimumDim);
if (StrCast(layout._dimUnit, '*') === DimUnit.Ratio) {
- height *= rowUnitLength;
+ height *= this.rowUnitLength;
}
return height;
};
@@ -176,11 +179,11 @@ export class CollectionMultirowView extends CollectionSubView() {
* documents before the target.
*/
private lookupIndividualTransform = (layout: Doc) => {
- const rowUnitLength = this.rowUnitLength;
- if (rowUnitLength === undefined) {
+ if (this.rowUnitLength === undefined) {
return Transform.Identity(); // we're still waiting on promises to resolve
}
let offset = 0;
+ // eslint-disable-next-line no-restricted-syntax
for (const { layout: candidate } of this.childLayoutPairs) {
if (candidate === layout) {
return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1));
@@ -195,7 +198,9 @@ export class CollectionMultirowView extends CollectionSubView() {
let dropInd = -1;
if (de.complete.docDragData && this._mainCont) {
let curInd = -1;
- de.complete.docDragData?.droppedDocuments.forEach(d => (curInd = this.childDocs.indexOf(d)));
+ de.complete.docDragData?.droppedDocuments.forEach(d => {
+ curInd = this.childDocs.indexOf(d);
+ });
Array.from(this._mainCont.children).forEach((child, index) => {
const brect = child.getBoundingClientRect();
if (brect.y < de.y && brect.y + brect.height > de.y) {
@@ -247,7 +252,6 @@ export class CollectionMultirowView extends CollectionSubView() {
this.lookupIndividualTransform(layout)
.translate(-NumCast(this.layoutDoc._xMargin), -NumCast(this.layoutDoc._yMargin))
.scale(this._props.NativeDimScaling?.() || 1);
- const shouldNotScale = () => this._props.fitContentsToBox?.() || BoolCast(layout.freeform_fitContentsToBox);
return (
<DocumentView
Document={layout}
@@ -266,7 +270,7 @@ export class CollectionMultirowView extends CollectionSubView() {
ScreenToLocalTransform={dxf}
isContentActive={this.isChildContentActive}
isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
- hideResizeHandles={layout.layout_fitWidth || this._props.childHideResizeHandles ? true : false}
+ hideResizeHandles={!!(layout.layout_fitWidth || this._props.childHideResizeHandles)}
hideDecorationTitle={this._props.childHideDecorationTitle}
fitContentsToBox={this._props.fitContentsToBox}
focus={this._props.focus}
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
index d580d9c52..931e2c5e0 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
@@ -1,10 +1,11 @@
+/* eslint-disable react/require-default-props */
import { action } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../../../fields/Doc';
import { NumCast, StrCast } from '../../../../fields/Types';
import { UndoManager } from '../../../util/UndoManager';
-import { StyleProp } from '../../StyleProvider';
+import { StyleProp } from '../../StyleProp';
import { StyleProviderFuncType } from '../../nodes/FieldView';
import { DimUnit } from './CollectionMulticolumnView';
@@ -52,27 +53,6 @@ export default class ResizeBar extends React.Component<ResizerProps> {
}
};
- private get isActivated() {
- const { toLeft, toRight } = this.props;
- if (toLeft && toRight) {
- if (StrCast(toLeft._dimUnit, '*') === DimUnit.Pixel && StrCast(toRight._dimUnit, '*') === DimUnit.Pixel) {
- return false;
- }
- return true;
- } else if (toLeft) {
- if (StrCast(toLeft._dimUnit, '*') === DimUnit.Pixel) {
- return false;
- }
- return true;
- } else if (toRight) {
- if (StrCast(toRight._dimUnit, '*') === DimUnit.Pixel) {
- return false;
- }
- return true;
- }
- return false;
- }
-
@action
private onPointerUp = () => {
window.removeEventListener('pointermove', this.onPointerMove);
@@ -90,7 +70,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
width: this.props.width,
backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor),
}}>
- <div className={'multiColumnResizer-hdl'} onPointerDown={e => this.registerResizing(e)} />
+ <div className="multiColumnResizer-hdl" onPointerDown={e => this.registerResizing(e)} />
</div>
);
}
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
index a9579d931..a7a0b3457 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
@@ -19,7 +19,7 @@ export default class WidthLabel extends React.Component<WidthLabelProps> {
const getUnit = () => StrCast(layout.dimUnit);
const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(3));
return (
- <div className={'label-wrapper'}>
+ <div className="label-wrapper">
<EditableView
GetValue={getMagnitude}
SetValue={value => {
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
index 878c7ff3c..66215f109 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
import { computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -20,7 +21,7 @@ export default class HeightLabel extends React.Component<HeightLabelProps> {
const getUnit = () => StrCast(layout.dimUnit);
const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(decimals ?? 3));
return (
- <div className={'label-wrapper'}>
+ <div className="label-wrapper">
<EditableView
GetValue={getMagnitude}
SetValue={value => {
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
index 73d08d5ef..cff0a8b4c 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
@@ -1,10 +1,11 @@
+/* eslint-disable react/require-default-props */
import { action } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../../../fields/Doc';
import { NumCast, StrCast } from '../../../../fields/Types';
import { UndoManager } from '../../../util/UndoManager';
-import { StyleProp } from '../../StyleProvider';
+import { StyleProp } from '../../StyleProp';
import { StyleProviderFuncType } from '../../nodes/FieldView';
import { DimUnit } from './CollectionMultirowView';
@@ -33,7 +34,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
};
private onPointerMove = ({ movementY }: PointerEvent) => {
- const { toTop: toTop, toBottom: toBottom, columnUnitLength } = this.props;
+ const { toTop, toBottom, columnUnitLength } = this.props;
const movingDown = movementY > 0;
const toNarrow = movingDown ? toBottom : toTop;
const toWiden = movingDown ? toTop : toBottom;
@@ -50,27 +51,6 @@ export default class ResizeBar extends React.Component<ResizerProps> {
}
};
- private get isActivated() {
- const { toTop, toBottom } = this.props;
- if (toTop && toBottom) {
- if (StrCast(toTop._dimUnit, '*') === DimUnit.Pixel && StrCast(toBottom._dimUnit, '*') === DimUnit.Pixel) {
- return false;
- }
- return true;
- } else if (toTop) {
- if (StrCast(toTop._dimUnit, '*') === DimUnit.Pixel) {
- return false;
- }
- return true;
- } else if (toBottom) {
- if (StrCast(toBottom._dimUnit, '*') === DimUnit.Pixel) {
- return false;
- }
- return true;
- }
- return false;
- }
-
@action
private onPointerUp = () => {
window.removeEventListener('pointermove', this.onPointerMove);
@@ -88,7 +68,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
height: this.props.height,
backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor),
}}>
- <div className={'multiRowResizer-hdl'} onPointerDown={e => this.registerResizing(e)} />
+ <div className="multiRowResizer-hdl" onPointerDown={e => this.registerResizing(e)} />
</div>
);
}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
index ac0bd2378..6fb8e40db 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
@@ -176,12 +176,12 @@
}
}
- .schema-column-resizer.left {
+ /*.schema-column-resizer.left {
min-width: 5px;
transform: translate(-3px, 0px);
align-self: flex-start;
background-color: $medium-gray;
- }
+ }*/ // creates awkward thick gray borders between colheaders
}
.schema-header-menu {
@@ -226,6 +226,15 @@
align-items: center;
}
+.schemaRTFCell {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ position: relative;
+ min-width: 10px;
+ min-height: 10px;
+}
+
.schema-row {
cursor: grab;
justify-content: flex-end;
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 12f0ad5e9..7c2cfd15f 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -1,44 +1,38 @@
+/* eslint-disable no-restricted-syntax */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, makeObservable, observable, ObservableMap, observe, trace } from 'mobx';
+import { Popup, PopupTrigger, Type } from 'browndash-components';
+import { ObservableMap, action, computed, makeObservable, observable, observe, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, Field, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
+import { returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
+import { Doc, DocListCast, Field, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
+import { DocData } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { List } from '../../../../fields/List';
-import { listSpec } from '../../../../fields/Schema';
-import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
-import { Docs, DocumentOptions, DocUtils, FInfo } from '../../../documents/Documents';
-import { DocumentManager } from '../../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../../util/DragManager';
-import { SelectionManager } from '../../../util/SelectionManager';
-import { undoable, undoBatch } from '../../../util/UndoManager';
+import { ColumnType } from '../../../../fields/SchemaHeaderField';
+import { BoolCast, NumCast, StrCast } from '../../../../fields/Types';
+import { DocUtils } from '../../../documents/DocUtils';
+import { Docs, DocumentOptions, FInfo } from '../../../documents/Documents';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
+import { SettingsManager } from '../../../util/SettingsManager';
+import { undoBatch, undoable } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { EditableView } from '../../EditableView';
+import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { StyleProp } from '../../StyleProp';
+import { DefaultStyleProvider } from '../../StyleProvider';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../../nodes/FieldView';
-import { KeyValueBox } from '../../nodes/KeyValueBox';
-import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { DefaultStyleProvider, StyleProp } from '../../StyleProvider';
+import { FieldViewProps } from '../../nodes/FieldView';
+import { FocusViewOptions } from '../../nodes/FocusViewOptions';
import { CollectionSubView } from '../CollectionSubView';
import './CollectionSchemaView.scss';
import { SchemaColumnHeader } from './SchemaColumnHeader';
import { SchemaRowBox } from './SchemaRowBox';
-import { Popup, PopupTrigger, Type } from 'browndash-components';
-import { SettingsManager } from '../../../util/SettingsManager';
-const { default: { SCHEMA_NEW_NODE_HEIGHT } } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore
-
-export enum ColumnType {
- Number,
- String,
- Boolean,
- Date,
- Image,
- RTF,
- Enumeration,
- Any,
-}
+
+const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore
export const FInfotoColType: { [key: string]: ColumnType } = {
string: ColumnType.String,
@@ -55,7 +49,6 @@ const defaultColumnKeys: string[] = ['title', 'type', 'author', 'author_date', '
@observer
export class CollectionSchemaView extends CollectionSubView() {
private _keysDisposer: any;
- private _closestDropIndex: number = 0;
private _previewRef: HTMLDivElement | null = null;
private _makeNewColumn: boolean = false;
private _documentOptions: DocumentOptions = new DocumentOptions();
@@ -87,7 +80,13 @@ export class CollectionSchemaView extends CollectionSubView() {
@observable _menuValue: string = '';
@observable _filterColumnIndex: number | undefined = undefined;
@observable _filterSearchValue: string = '';
- @observable _selectedCell: [Doc, number] | undefined = undefined;
+ @observable _selectedCol: number = 0;
+ @observable _selectedCells: Array<Doc> = [];
+ @observable _mouseCoordinates = { x: 0, y: 0 };
+ @observable _lowestSelectedIndex = -1; // lowest index among selected rows; used to properly sync dragged docs with cursor position
+ @observable _relCursorIndex = -1; // cursor index relative to the current selected cells
+ @observable _draggedColIndex = 0;
+ @observable _colBeingDragged = false;
// target HTMLelement portal for showing a popup menu to edit cell values.
public get MenuTarget() {
@@ -95,14 +94,14 @@ export class CollectionSchemaView extends CollectionSubView() {
}
@computed get _selectedDocs() {
- const selected = SelectionManager.Docs.filter(doc => Doc.AreProtosEqual(DocCast(doc.embedContainer), this.Document));
+ // get all selected documents then filter out any whose parent is not this schema document
+ const selected = DocumentView.SelectedDocs().filter(doc => this.childDocs.includes(doc));
if (!selected.length) {
- for (const sel of SelectionManager.Docs) {
- const contextPath = DocumentManager.GetContextPath(sel, true);
- if (contextPath.includes(this.Document)) {
- const parentInd = contextPath.indexOf(this.Document);
- return parentInd < contextPath.length - 1 ? [contextPath[parentInd + 1]] : [];
- }
+ // if no schema doc is directly selected, test if a child of a schema doc is selected (such as in the preview window)
+ const childOfSchemaDoc = DocumentView.SelectedDocs().find(sel => DocumentView.getContextPath(sel, true).includes(this.Document));
+ if (childOfSchemaDoc) {
+ const contextPath = DocumentView.getContextPath(childOfSchemaDoc, true);
+ return [contextPath[contextPath.indexOf(childOfSchemaDoc) - 1]]; // the schema doc that is "selected" by virtue of one of its children being selected
}
}
return selected;
@@ -121,7 +120,7 @@ export class CollectionSchemaView extends CollectionSubView() {
}
@computed get columnKeys() {
- return Cast(this.layoutDoc.schema_columnKeys, listSpec('string'), defaultColumnKeys);
+ return StrListCast(this.layoutDoc.schema_columnKeys, defaultColumnKeys);
}
@computed get storedColumnWidths() {
@@ -131,12 +130,17 @@ export class CollectionSchemaView extends CollectionSubView() {
);
const totalWidth = widths.reduce((sum, width) => sum + width, 0);
+ // If the total width of all columns is not the width of the schema table minus the width of the row menu, resize them appropriately
if (totalWidth !== this.tableWidth - CollectionSchemaView._rowMenuWidth) {
return widths.map(w => (w / totalWidth) * (this.tableWidth - CollectionSchemaView._rowMenuWidth));
}
return widths;
}
+ @computed get rowHeights() {
+ return this.childDocs.map(() => this.rowHeightFunc());
+ }
+
@computed get displayColumnWidths() {
return this._displayColumnWidths ?? this.storedColumnWidths;
}
@@ -156,8 +160,8 @@ export class CollectionSchemaView extends CollectionSubView() {
Object.entries(this._documentOptions).forEach((pair: [string, FInfo]) => this.fieldInfos.set(pair[0], pair[1]));
this._keysDisposer = observe(
this.dataDoc[this.fieldKey ?? 'data'] as List<Doc>,
- change => {
- switch (change.type as any) {
+ (change: any) => {
+ switch (change.type) {
case 'splice':
// prettier-ignore
(change as any).added.forEach((doc: Doc) => // for each document added
@@ -165,7 +169,9 @@ export class CollectionSchemaView extends CollectionSubView() {
Object.keys(proto).forEach(action(key => // check if any of its keys are new, and add them
!this.fieldInfos.get(key) && this.fieldInfos.set(key, new FInfo("-no description-", key === 'author'))))));
break;
- case 'update': //let oldValue = change.oldValue; // fill this in if the entire child list will ever be reassigned with a new list
+ case 'update': // let oldValue = change.oldValue; // fill this in if the entire child list will ever be reassigned with a new list
+ break;
+ default:
}
},
true
@@ -177,6 +183,9 @@ export class CollectionSchemaView extends CollectionSubView() {
document.removeEventListener('keydown', this.onKeyDown);
}
+ // ViewBoxInterface overrides
+ override isUnstyledView = returnTrue; // used by style provider : turns off opacity, animation effects, scaling
+
rowIndex = (doc: Doc) => this.sortedDocs.docs.indexOf(doc);
@action
@@ -189,13 +198,12 @@ export class CollectionSchemaView extends CollectionSubView() {
const lastIndex = this.rowIndex(lastDoc);
const curDoc = this.sortedDocs.docs[lastIndex];
if (lastIndex >= 0 && lastIndex < this.childDocs.length - 1) {
- !e.shiftKey && this.clearSelection();
const newDoc = this.sortedDocs.docs[lastIndex + 1];
if (this._selectedDocs.includes(newDoc)) {
- SelectionManager.DeselectView(DocumentManager.Instance.getFirstDocumentView(curDoc));
+ DocumentView.DeselectView(DocumentView.getFirstDocumentView(curDoc));
+ this.deselectCell(curDoc);
} else {
- this.addDocToSelection(newDoc, e.shiftKey, lastIndex + 1);
- this._selectedCell && (this._selectedCell[0] = newDoc);
+ this.selectCell(newDoc, this._selectedCol, e.shiftKey, e.ctrlKey);
this.scrollToDoc(newDoc, {});
}
}
@@ -209,12 +217,12 @@ export class CollectionSchemaView extends CollectionSubView() {
const firstIndex = this.rowIndex(firstDoc);
const curDoc = this.sortedDocs.docs[firstIndex];
if (firstIndex > 0 && firstIndex < this.childDocs.length) {
- !e.shiftKey && this.clearSelection();
const newDoc = this.sortedDocs.docs[firstIndex - 1];
- if (this._selectedDocs.includes(newDoc)) SelectionManager.DeselectView(DocumentManager.Instance.getFirstDocumentView(curDoc));
- else {
- this.addDocToSelection(newDoc, e.shiftKey, firstIndex - 1);
- this._selectedCell && (this._selectedCell[0] = newDoc);
+ if (this._selectedDocs.includes(newDoc)) {
+ DocumentView.DeselectView(DocumentView.getFirstDocumentView(curDoc));
+ this.deselectCell(curDoc);
+ } else {
+ this.selectCell(newDoc, this._selectedCol, e.shiftKey, e.ctrlKey);
this.scrollToDoc(newDoc, {});
}
}
@@ -223,30 +231,35 @@ export class CollectionSchemaView extends CollectionSubView() {
}
break;
case 'ArrowRight':
- if (this._selectedCell) {
- this._selectedCell[1] = Math.min(this._selectedCell[1] + 1, this.columnKeys.length - 1);
+ if (this._selectedCells) {
+ this._selectedCol = Math.min(this._colEles.length - 1, this._selectedCol + 1);
} else if (this._selectedDocs.length > 0) {
- this.selectCell(this._selectedDocs[0], 0);
+ this.selectCell(this._selectedDocs[0], 0, false, false);
}
break;
case 'ArrowLeft':
- if (this._selectedCell) {
- this._selectedCell[1] = Math.max(this._selectedCell[1] - 1, 0);
+ if (this._selectedCells) {
+ this._selectedCol = Math.max(0, this._selectedCol - 1);
} else if (this._selectedDocs.length > 0) {
- this.selectCell(this._selectedDocs[0], 0);
+ this.selectCell(this._selectedDocs[0], 0, false, false);
}
break;
case 'Backspace': {
- this.removeDocument(this._selectedDocs);
+ undoable(() => this.removeDocument(this._selectedDocs), 'delete schema row');
break;
}
case 'Escape': {
- this.deselectCell();
+ this.deselectAllCells();
+ break;
}
+ default:
}
}
};
+ @action
+ changeSelectedCellColumn = () => {};
+
@undoBatch
setColumnSort = (field: string | undefined, desc: boolean = false) => {
this.layoutDoc.sortField = field;
@@ -261,7 +274,7 @@ export class CollectionSchemaView extends CollectionSubView() {
this.addNewKey(newKey, defaultVal);
}
- let currKeys = [...this.columnKeys];
+ const currKeys = this.columnKeys.slice(); // copy the column key array first, then change it.
currKeys[index] = newKey;
this.layoutDoc.schema_columnKeys = new List<string>(currKeys);
};
@@ -278,13 +291,16 @@ export class CollectionSchemaView extends CollectionSubView() {
const newDesiredTableWidth = currWidths.reduce((w, cw) => w + cw, 0);
this.layoutDoc.schema_columnWidths = new List<number>(currWidths.map(w => (w / newDesiredTableWidth) * (this.tableWidth - CollectionSchemaView._rowMenuWidth)));
- let currKeys = this.columnKeys.slice();
+ const currKeys = this.columnKeys.slice();
currKeys.splice(0, 0, key);
this.layoutDoc.schema_columnKeys = new List<string>(currKeys);
};
@action
- addNewKey = (key: string, defaultVal: any) => this.childDocs.forEach(doc => (doc[key] = defaultVal));
+ addNewKey = (key: string, defaultVal: any) =>
+ this.childDocs.forEach(doc => {
+ doc[DocData][key] = defaultVal;
+ });
@undoBatch
removeColumn = (index: number) => {
@@ -294,7 +310,7 @@ export class CollectionSchemaView extends CollectionSubView() {
const newDesiredTableWidth = currWidths.reduce((w, cw) => w + cw, 0);
this.layoutDoc.schema_columnWidths = new List<number>(currWidths.map(w => (w / newDesiredTableWidth) * (this.tableWidth - CollectionSchemaView._rowMenuWidth)));
- let currKeys = this.columnKeys.slice();
+ const currKeys = this.columnKeys.slice();
currKeys.splice(index, 1);
this.layoutDoc.schema_columnKeys = new List<string>(currKeys);
};
@@ -302,7 +318,7 @@ export class CollectionSchemaView extends CollectionSubView() {
@action
startResize = (e: any, index: number) => {
this._displayColumnWidths = this.storedColumnWidths;
- setupMoveUpEvents(this, e, (e, delta) => this.resizeColumn(e, index), this.finishResize, emptyFunction);
+ setupMoveUpEvents(this, e, moveEv => this.resizeColumn(moveEv, index), this.finishResize, emptyFunction);
};
@action
@@ -341,34 +357,32 @@ export class CollectionSchemaView extends CollectionSubView() {
@undoBatch
moveColumn = (fromIndex: number, toIndex: number) => {
- let currKeys = this.columnKeys.slice();
+ if (this._selectedCol === fromIndex) this._selectedCol = toIndex;
+ else if (toIndex === this._selectedCol) this._selectedCol = fromIndex; // keeps selected cell consistent
+
+ const currKeys = this.columnKeys.slice();
currKeys.splice(toIndex, 0, currKeys.splice(fromIndex, 1)[0]);
this.layoutDoc.schema_columnKeys = new List<string>(currKeys);
- let currWidths = this.storedColumnWidths.slice();
+ const currWidths = this.storedColumnWidths.slice();
currWidths.splice(toIndex, 0, currWidths.splice(fromIndex, 1)[0]);
this.layoutDoc.schema_columnWidths = new List<number>(currWidths);
+
+ this._draggedColIndex = toIndex;
};
@action
dragColumn = (e: PointerEvent, index: number) => {
+ this._draggedColIndex = index;
+ this._colBeingDragged = true;
const dragData = new DragManager.ColumnDragData(index);
const dragEles = [this._colEles[index]];
this.childDocs.forEach(doc => dragEles.push(this._rowEles.get(doc).children[1].children[index]));
DragManager.StartColumnDrag(dragEles, dragData, e.x, e.y);
-
- document.removeEventListener('pointermove', this.highlightDropColumn);
- document.addEventListener('pointermove', this.highlightDropColumn);
- let stopHighlight = (e: PointerEvent) => {
- document.removeEventListener('pointermove', this.highlightDropColumn);
- document.removeEventListener('pointerup', stopHighlight);
- };
- document.addEventListener('pointerup', stopHighlight);
-
return true;
};
- findDropIndex = (mouseX: number) => {
+ findColDropIndex = (mouseX: number) => {
let index: number | undefined;
this.displayColumnWidths.reduce((total, curr, i) => {
if (total <= mouseX && total + curr >= mouseX) {
@@ -376,28 +390,72 @@ export class CollectionSchemaView extends CollectionSubView() {
else index = i + 1;
}
return total + curr;
- }, CollectionSchemaView._rowMenuWidth);
+ }, 2 * CollectionSchemaView._rowMenuWidth); // probably prone to issues; find better implementation (!!!)
return index;
};
+ /**
+ * Calculates the relative index of the cursor in the group of selected rows, ie.
+ * if five rows are selected and the cursor is in the middle row, its relative index would be 2.
+ * Used to align actively dragged documents properly with the cursor.
+ * @param mouseY the initial Y position of the cursor on drag
+ */
@action
- highlightDropColumn = (e: PointerEvent) => {
- e.stopPropagation();
- const mouseX = this.ScreenToLocalBoxXf().transformPoint(e.clientX, e.clientY)[0];
- const index = this.findDropIndex(mouseX);
+ setRelCursorIndex = (mouseY: number) => {
+ this._mouseCoordinates.y = mouseY; // updates this.rowDropIndex computed value to overwrite the old cached value
+
+ const rowHeight = CollectionSchemaView._rowHeight;
+ const adjInitMouseY = mouseY - rowHeight - 100; // rowHeight: height of the column menu cells | 100: height of the top menu
+ const yOffset = this._lowestSelectedIndex * rowHeight;
+
+ const heights = this._selectedDocs.map(() => this.rowHeightFunc());
+ let index: number = 0;
+ heights.reduce((total, curr, i) => {
+ if (total <= adjInitMouseY && total + curr >= adjInitMouseY) {
+ if (adjInitMouseY <= total + curr) index = i;
+ else index = i + 1;
+ }
+ return total + curr;
+ }, yOffset);
+ this._relCursorIndex = index;
+ };
+
+ findRowDropIndex = (mouseY: number) => {
+ const rowHeight = CollectionSchemaView._rowHeight;
+ let index: number = 0;
+ this.rowHeights.reduce((total, curr, i) => {
+ if (total <= mouseY && total + curr >= mouseY) {
+ if (mouseY <= total + curr) index = i;
+ else index = i + 1;
+ }
+ return total + curr;
+ }, rowHeight);
+
+ // fix index if selected rows are dragged out of bounds
+ let adjIndex = index - this._relCursorIndex;
+ const maxY = this.rowHeights.reduce((total, curr) => total + curr, 0) + rowHeight;
+ if (mouseY > maxY) adjIndex = this.childDocs.length - 1;
+ else if (adjIndex <= 0) adjIndex = 0;
+
+ return adjIndex;
+ };
+
+ highlightDraggedColumn = (index: number) =>
this._colEles.forEach((colRef, i) => {
- let leftStyle = '';
- let rightStyle = '';
- if (i + 1 === index) rightStyle = `solid 12px ${Colors.MEDIUM_BLUE}`;
- if (i === index && i === 0) leftStyle = `solid 12px ${Colors.MEDIUM_BLUE}`;
- colRef.style.borderLeft = leftStyle;
- colRef.style.borderRight = rightStyle;
- this.childDocs.forEach(doc => {
- this._rowEles.get(doc).children[1].children[i].style.borderLeft = leftStyle;
- this._rowEles.get(doc).children[1].children[i].style.borderRight = rightStyle;
+ const edgeStyle = i === index ? `solid 2px ${Colors.MEDIUM_BLUE}` : '';
+ const cellEles = [
+ colRef,
+ ...this.childDocs //
+ .filter(doc => i !== this._selectedCol || !this._selectedDocs.includes(doc))
+ .map(doc => this._rowEles.get(doc).children[1].children[i]),
+ ];
+ cellEles[0].style.borderTop = edgeStyle;
+ cellEles.forEach(ele => {
+ ele.style.borderLeft = edgeStyle;
+ ele.style.borderRight = edgeStyle;
});
+ cellEles.slice(-1)[0].style.borderBottom = edgeStyle;
});
- };
@action
addRowRef = (doc: Doc, ref: HTMLDivElement) => this._rowEles.set(doc, ref);
@@ -412,13 +470,16 @@ export class CollectionSchemaView extends CollectionSubView() {
};
@action
- addDocToSelection = (doc: Doc, extendSelection: boolean, index: number) => {
- const rowDocView = DocumentManager.Instance.getDocumentView(doc);
- if (rowDocView) SelectionManager.SelectView(rowDocView, extendSelection);
+ addDocToSelection = (doc: Doc, extendSelection: boolean) => {
+ const rowDocView = DocumentView.getDocumentView(doc);
+ if (rowDocView) DocumentView.SelectView(rowDocView, extendSelection);
};
@action
- clearSelection = () => SelectionManager.DeselectAll();
+ clearSelection = () => {
+ DocumentView.DeselectAll();
+ this.deselectAllCells();
+ };
selectRows = (doc: Doc, lastSelected: Doc) => {
const index = this.rowIndex(doc);
@@ -427,63 +488,97 @@ export class CollectionSchemaView extends CollectionSubView() {
const endRow = Math.max(lastSelectedRow, index);
for (let i = startRow; i <= endRow; i++) {
const currDoc = this.sortedDocs.docs[i];
- if (!this._selectedDocs.includes(currDoc)) this.addDocToSelection(currDoc, true, i);
+ if (!this._selectedDocs.includes(currDoc)) {
+ this.selectCell(currDoc, this._selectedCol, false, true);
+ }
}
};
@action
- selectCell = (doc: Doc, index: number) => (this._selectedCell = [doc, index]);
+ selectCell = (doc: Doc, col: number, shiftKey: boolean, ctrlKey: boolean) => {
+ if (!shiftKey && !ctrlKey) this.clearSelection();
+ !this._selectedCells && (this._selectedCells = []);
+ !shiftKey && this._selectedCells && this._selectedCells.push(doc);
+ const index = this.rowIndex(doc);
+
+ if (!this) return;
+ const lastSelected = Array.from(this._selectedDocs).lastElement();
+ if (shiftKey && lastSelected && !this._selectedDocs.includes(doc)) this.selectRows(doc, lastSelected);
+ else if (ctrlKey) {
+ if (lastSelected && this._selectedDocs.includes(doc)) {
+ DocumentView.DeselectView(DocumentView.getFirstDocumentView(doc));
+ this.deselectCell(doc);
+ } else this.addDocToSelection(doc, true);
+ } else this.addDocToSelection(doc, false);
+ this._selectedCol = col;
+
+ if (this._lowestSelectedIndex === -1 || index < this._lowestSelectedIndex) this._lowestSelectedIndex = index;
+
+ // let selectedIndexes: Array<Number> = this._selectedCells.map(doc => this.rowIndex(doc));
+ };
+
+ @action
+ deselectCell = (doc: Doc) => {
+ this._selectedCells && (this._selectedCells = this._selectedCells.filter(d => d !== doc));
+ if (this.rowIndex(doc) === this._lowestSelectedIndex) this._lowestSelectedIndex = Math.min(...this._selectedDocs.map(d => this.rowIndex(d)));
+ };
@action
- deselectCell = () => (this._selectedCell = undefined);
+ deselectAllCells = () => {
+ this._selectedCells = [];
+ this._lowestSelectedIndex = -1;
+ };
sortedSelectedDocs = () => this.sortedDocs.docs.filter(doc => this._selectedDocs.includes(doc));
- setDropIndex = (index: number) => (this._closestDropIndex = index);
+ @computed
+ get rowDropIndex() {
+ const mouseY = this.ScreenToLocalBoxXf().transformPoint(this._mouseCoordinates.x, this._mouseCoordinates.y)[1];
+ return this.findRowDropIndex(mouseY);
+ }
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
if (de.complete.columnDragData) {
- const mouseX = this.ScreenToLocalBoxXf().transformPoint(de.x, de.y)[0];
- const index = this.findDropIndex(mouseX);
- this.moveColumn(de.complete.columnDragData.colIndex, index ?? de.complete.columnDragData.colIndex);
+ this._colBeingDragged = false;
+ e.stopPropagation();
this._colEles.forEach((colRef, i) => {
+ // style for menu cell
colRef.style.borderLeft = '';
colRef.style.borderRight = '';
+ colRef.style.borderTop = '';
+
this.childDocs.forEach(doc => {
- this._rowEles.get(doc).children[1].children[i].style.borderLeft = '';
- this._rowEles.get(doc).children[1].children[i].style.borderRight = '';
+ if (!(this._selectedDocs.includes(doc) && i === this._selectedCol)) {
+ this._rowEles.get(doc).children[1].children[i].style.borderLeft = '';
+ this._rowEles.get(doc).children[1].children[i].style.borderRight = '';
+ this._rowEles.get(doc).children[1].children[i].style.borderBottom = '';
+ }
});
});
-
- e.stopPropagation();
return true;
}
+
const draggedDocs = de.complete.docDragData?.draggedDocuments;
if (draggedDocs && super.onInternalDrop(e, de) && !this.sortField) {
- const pushedDocs = this.childDocs.filter((doc, index) => index >= this._closestDropIndex && !draggedDocs.includes(doc));
- const pushedAndDraggedDocs = [...pushedDocs, ...draggedDocs];
- const removed = this.childDocs.slice().filter(doc => !pushedAndDraggedDocs.includes(doc));
- this.dataDoc[this.fieldKey ?? 'data'] = new List<Doc>([...removed, ...draggedDocs, ...pushedDocs]);
+ const map = draggedDocs?.map(doc => this.rowIndex(doc));
+ console.log(map);
+ this.dataDoc[this.fieldKey ?? 'data'] = new List<Doc>([...this.sortedDocs.docs]);
this.clearSelection();
draggedDocs.forEach(doc => {
- const draggedView = DocumentManager.Instance.getFirstDocumentView(doc);
- if (draggedView) DocumentManager.Instance.RemoveView(draggedView);
- DocumentManager.Instance.AddViewRenderedCb(doc, dv => dv.select(true));
+ DocumentView.addViewRenderedCb(doc, dv => dv.select(true));
});
+ this._lowestSelectedIndex = Math.min(...(draggedDocs?.map(doc => this.rowIndex(doc)) ?? []));
return true;
}
return false;
};
- onExternalDrop = async (e: React.DragEvent): Promise<void> => {
- super.onExternalDrop(e, {}, undoBatch(action(docus => docus.map((doc: Doc) => this.addDocument(doc)))));
- };
-
+ onExternalDrop = (e: React.DragEvent) => super.onExternalDrop(e, {}, docs => docs.map(doc => this.addDocument(doc)));
onDividerDown = (e: React.PointerEvent) => setupMoveUpEvents(this, e, this.onDividerMove, emptyFunction, emptyFunction);
@action
- onDividerMove = (e: PointerEvent, down: number[], delta: number[]) => {
+ onDividerMove = (e: PointerEvent) => {
const nativeWidth = this._previewRef!.getBoundingClientRect();
const minWidth = 40;
const maxWidth = 1000;
@@ -513,37 +608,76 @@ export class CollectionSchemaView extends CollectionSubView() {
const rect = found.getBoundingClientRect();
const localRect = this.ScreenToLocalBoxXf().transformBounds(rect.left, rect.top, rect.width, rect.height);
if (localRect.y < this.rowHeightFunc() || localRect.y + localRect.height > this._props.PanelHeight()) {
- let focusSpeed = options.zoomTime ?? 50;
+ const focusSpeed = options.zoomTime ?? 50;
smoothScroll(focusSpeed, this._tableContentRef!, localRect.y + this._tableContentRef!.scrollTop - this.rowHeightFunc(), options.easeFunc);
return focusSpeed;
}
}
+ return undefined;
};
@computed get fieldDefaultInput() {
switch (this._newFieldType) {
case ColumnType.Number:
- return <input type="number" name="" id="" value={this._newFieldDefault ?? 0} onPointerDown={e => e.stopPropagation()} onChange={action(e => (this._newFieldDefault = e.target.value))} />;
+ return (
+ <input
+ type="number"
+ name=""
+ id=""
+ value={this._newFieldDefault ?? 0}
+ onPointerDown={e => e.stopPropagation()}
+ onChange={action((e: any) => {
+ this._newFieldDefault = e.target.value;
+ })}
+ />
+ );
case ColumnType.Boolean:
return (
<>
- <input type="checkbox" name="" id="" value={this._newFieldDefault} onPointerDown={e => e.stopPropagation()} onChange={action(e => (this._newFieldDefault = e.target.checked))} />
+ <input
+ type="checkbox"
+ name=""
+ id=""
+ value={this._newFieldDefault}
+ onPointerDown={e => e.stopPropagation()}
+ onChange={action((e: any) => {
+ this._newFieldDefault = e.target.checked;
+ })}
+ />
{this._newFieldDefault ? 'true' : 'false'}
</>
);
case ColumnType.String:
- return <input type="text" name="" id="" value={this._newFieldDefault ?? ''} onPointerDown={e => e.stopPropagation()} onChange={action(e => (this._newFieldDefault = e.target.value))} />;
+ return (
+ <input
+ type="text"
+ name=""
+ id=""
+ value={this._newFieldDefault ?? ''}
+ onPointerDown={e => e.stopPropagation()}
+ onChange={action((e: any) => {
+ this._newFieldDefault = e.target.value;
+ })}
+ />
+ );
+ default:
+ return undefined;
}
}
onSearchKeyDown = (e: React.KeyboardEvent) => {
switch (e.key) {
case 'Enter':
- this._menuKeys.length > 0 && this._menuValue.length > 0 ? this.setKey(this._menuKeys[0]) : action(() => (this._makeNewField = true))();
+ this._menuKeys.length > 0 && this._menuValue.length > 0
+ ? this.setKey(this._menuKeys[0])
+ : runInAction(() => {
+ this._makeNewField = true;
+ });
break;
case 'Escape':
this.closeColumnMenu();
break;
+ default:
}
};
@@ -558,7 +692,28 @@ export class CollectionSchemaView extends CollectionSubView() {
};
setColumnValues = (key: string, value: string) => {
- this.childDocs.forEach(doc => KeyValueBox.SetField(doc, key, value));
+ const selectedDocs: Doc[] = [];
+ this.childDocs.forEach(doc => {
+ const docIsSelected = this._selectedCells && !(this._selectedCells?.filter(d => d === doc).length === 0);
+ if (docIsSelected) {
+ selectedDocs.push(doc);
+ }
+ });
+ if (selectedDocs.length === 1) {
+ this.childDocs.forEach(doc => Doc.SetField(doc, key, value));
+ } else {
+ selectedDocs.forEach(doc => Doc.SetField(doc, key, value));
+ }
+ return true;
+ };
+
+ setSelectedColumnValues = (key: string, value: string) => {
+ this.childDocs.forEach(doc => {
+ const docIsSelected = this._selectedCells && !(this._selectedCells?.filter(d => d === doc).length === 0);
+ if (docIsSelected) {
+ Doc.SetField(doc, key, value);
+ }
+ });
return true;
};
@@ -575,7 +730,9 @@ export class CollectionSchemaView extends CollectionSubView() {
};
@action
- closeColumnMenu = () => (this._columnMenuIndex = undefined);
+ closeColumnMenu = () => {
+ this._columnMenuIndex = undefined;
+ };
@action
openFilterMenu = (index: number) => {
@@ -584,7 +741,9 @@ export class CollectionSchemaView extends CollectionSubView() {
};
@action
- closeFilterMenu = () => (this._filterColumnIndex = undefined);
+ closeFilterMenu = () => {
+ this._filterColumnIndex = undefined;
+ };
openContextMenu = (x: number, y: number, index: number) => {
this.closeColumnMenu();
@@ -614,7 +773,7 @@ export class CollectionSchemaView extends CollectionSubView() {
this._menuKeys = this.documentKeys.filter(value => value.toLowerCase().includes(this._menuValue.toLowerCase()));
};
- getFieldFilters = (field: string) => StrListCast(this.Document._childFilters).filter(filter => filter.split(Doc.FilterSep)[0] == field);
+ getFieldFilters = (field: string) => StrListCast(this.Document._childFilters).filter(filter => filter.split(Doc.FilterSep)[0] === field);
removeFieldFilters = (field: string) => {
this.getFieldFilters(field).forEach(filter => Doc.setDocFilter(this.Document, field, filter.split(Doc.FilterSep)[1], 'remove'));
@@ -626,11 +785,14 @@ export class CollectionSchemaView extends CollectionSubView() {
case 'Escape':
this.closeFilterMenu();
break;
+ default:
}
};
@action
- updateFilterSearch = (e: React.ChangeEvent<HTMLInputElement>) => (this._filterSearchValue = e.target.value);
+ updateFilterSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this._filterSearchValue = e.target.value;
+ };
@computed get newFieldMenu() {
return (
@@ -639,7 +801,7 @@ export class CollectionSchemaView extends CollectionSubView() {
<input
type="radio"
name="newFieldType"
- checked={this._newFieldType == ColumnType.Number}
+ checked={this._newFieldType === ColumnType.Number}
onChange={action(() => {
this._newFieldType = ColumnType.Number;
this._newFieldDefault = 0;
@@ -651,7 +813,7 @@ export class CollectionSchemaView extends CollectionSubView() {
<input
type="radio"
name="newFieldType"
- checked={this._newFieldType == ColumnType.Boolean}
+ checked={this._newFieldType === ColumnType.Boolean}
onChange={action(() => {
this._newFieldType = ColumnType.Boolean;
this._newFieldDefault = false;
@@ -663,7 +825,7 @@ export class CollectionSchemaView extends CollectionSubView() {
<input
type="radio"
name="newFieldType"
- checked={this._newFieldType == ColumnType.String}
+ checked={this._newFieldType === ColumnType.String}
onChange={action(() => {
this._newFieldType = ColumnType.String;
this._newFieldDefault = '';
@@ -675,7 +837,7 @@ export class CollectionSchemaView extends CollectionSubView() {
<div className="schema-key-warning">{this._newFieldWarning}</div>
<div
className="schema-column-menu-button"
- onPointerDown={action(e => {
+ onPointerDown={action(() => {
if (this.documentKeys.includes(this._menuValue)) {
this._newFieldWarning = 'Field already exists';
} else if (this._menuValue.length === 0) {
@@ -702,7 +864,7 @@ export class CollectionSchemaView extends CollectionSubView() {
<div className="schema-key-search">
<div
className="schema-column-menu-button"
- onPointerDown={action(e => {
+ onPointerDown={action((e: any) => {
e.stopPropagation();
this._makeNewField = true;
})}>
@@ -740,7 +902,7 @@ export class CollectionSchemaView extends CollectionSubView() {
}
@computed get renderColumnMenu() {
- const x = this._columnMenuIndex! == -1 ? 0 : this.displayColumnWidths.reduce((total, curr, index) => total + (index < this._columnMenuIndex! ? curr : 0), CollectionSchemaView._rowMenuWidth);
+ const x = this._columnMenuIndex! === -1 ? 0 : this.displayColumnWidths.reduce((total, curr, index) => total + (index < this._columnMenuIndex! ? curr : 0), CollectionSchemaView._rowMenuWidth);
return (
<div className="schema-column-menu" style={{ left: x, minWidth: CollectionSchemaView._minColWidth }}>
<input className="schema-key-search-input" type="text" onKeyDown={this.onSearchKeyDown} onChange={this.updateKeySearch} onPointerDown={e => e.stopPropagation()} />
@@ -749,7 +911,6 @@ export class CollectionSchemaView extends CollectionSubView() {
);
}
get renderKeysMenu() {
- console.log('RNDERMENUT:' + this._columnMenuIndex);
return (
<div className="schema-column-menu" style={{ left: 0, minWidth: CollectionSchemaView._minColWidth }}>
<input className="schema-key-search-input" type="text" onKeyDown={this.onSearchKeyDown} onChange={this.updateKeySearch} onPointerDown={e => e.stopPropagation()} />
@@ -779,17 +940,11 @@ export class CollectionSchemaView extends CollectionSubView() {
}
return (
<div key={key} className="schema-filter-option">
- <input
+ <input //
type="checkbox"
onPointerDown={e => e.stopPropagation()}
onClick={e => e.stopPropagation()}
- onChange={action(e => {
- if (e.target.checked) {
- Doc.setDocFilter(this.Document, columnKey, key, 'check');
- } else {
- Doc.setDocFilter(this.Document, columnKey, key, 'remove');
- }
- })}
+ onChange={e => Doc.setDocFilter(this.Document, columnKey, key, e.target.checked ? 'check' : 'remove')}
checked={bool}
/>
<span style={{ paddingLeft: 4 }}>{key}</span>
@@ -806,7 +961,7 @@ export class CollectionSchemaView extends CollectionSubView() {
{this.renderFilterOptions}
<div
className="schema-column-menu-button"
- onPointerDown={action(e => {
+ onPointerDown={action((e: any) => {
e.stopPropagation();
this.closeFilterMenu();
})}>
@@ -816,22 +971,41 @@ export class CollectionSchemaView extends CollectionSubView() {
);
}
+ @action
+ onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {
+ if (DragManager.docsBeingDragged.length) {
+ this._mouseCoordinates = { x: e.clientX, y: e.clientY };
+ }
+ if (this._colBeingDragged) {
+ const newIndex = this.findColDropIndex(e.clientX);
+ if (newIndex !== this._draggedColIndex) this.moveColumn(this._draggedColIndex, newIndex ?? this._draggedColIndex);
+ this._draggedColIndex = newIndex || this._draggedColIndex;
+ this.highlightDraggedColumn(newIndex ?? this._draggedColIndex);
+ }
+ };
+
@computed get sortedDocs() {
+ const draggedDocs = this.isContentActive() ? DragManager.docsBeingDragged : [];
const field = StrCast(this.layoutDoc.sortField);
- const desc = BoolCast(this.layoutDoc.sortDesc);
+ const desc = BoolCast(this.layoutDoc.sortDesc); // is this an ascending or descending sort
+ const staticDocs = this.childDocs.filter(d => !draggedDocs.includes(d));
const docs = !field
- ? this.childDocs
- : [...this.childDocs].sort((docA, docB) => {
- const aStr = Field.toString(docA[field] as Field);
- const bStr = Field.toString(docB[field] as Field);
- var out = 0;
+ ? staticDocs
+ : [...staticDocs].sort((docA, docB) => {
+ // this sorts the documents based on the selected field. returning -1 for a before b, 0 for a = b, 1 for a > b
+ const aStr = Field.toString(docA[field] as FieldType);
+ const bStr = Field.toString(docB[field] as FieldType);
+ let out = 0;
if (aStr < bStr) out = -1;
if (aStr > bStr) out = 1;
if (desc) out *= -1;
return out;
});
+
+ docs.splice(this.rowDropIndex, 0, ...draggedDocs);
return { docs };
}
+
rowHeightFunc = () => (BoolCast(this.layoutDoc._schema_singleLine) ? CollectionSchemaView._rowSingleLineHeight : CollectionSchemaView._rowHeight);
sortedDocsFunc = () => this.sortedDocs;
isContentActive = () => this._props.isSelected() || this._props.isContentActive();
@@ -841,8 +1015,8 @@ export class CollectionSchemaView extends CollectionSubView() {
_oldWheel: any;
render() {
return (
- <div className="collectionSchemaView" ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)}>
- <div ref={this._menuTarget} style={{ background: 'red', top: 0, left: 0, position: 'absolute', zIndex: 10000 }}></div>
+ <div className="collectionSchemaView" ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)} onPointerMove={e => this.onPointerMove(e)}>
+ <div ref={this._menuTarget} style={{ background: 'red', top: 0, left: 0, position: 'absolute', zIndex: 10000 }} />
<div
className="schema-table"
style={{ width: `calc(100% - ${this.previewWidth}px)` }}
@@ -858,7 +1032,7 @@ export class CollectionSchemaView extends CollectionSubView() {
placement="right"
background={SettingsManager.userBackgroundColor}
color={SettingsManager.userColor}
- toggle={<FontAwesomeIcon onPointerDown={e => this.openColumnMenu(-1, true)} icon="plus" />}
+ toggle={<FontAwesomeIcon onPointerDown={() => this.openColumnMenu(-1, true)} icon="plus" />}
trigger={PopupTrigger.CLICK}
type={Type.TERT}
isOpen={this._columnMenuIndex !== -1 ? false : undefined}
@@ -867,6 +1041,7 @@ export class CollectionSchemaView extends CollectionSubView() {
</div>
{this.columnKeys.map((key, index) => (
<SchemaColumnHeader
+ // eslint-disable-next-line react/no-array-index-key
key={index}
columnIndex={index}
columnKeys={this.columnKeys}
@@ -886,28 +1061,42 @@ export class CollectionSchemaView extends CollectionSubView() {
</div>
{this._columnMenuIndex !== undefined && this._columnMenuIndex !== -1 && this.renderColumnMenu}
{this._filterColumnIndex !== undefined && this.renderFilterMenu}
- <CollectionSchemaViewDocs schema={this} childDocs={this.sortedDocsFunc} rowHeight={this.rowHeightFunc} setRef={(ref: HTMLDivElement | null) => (this._tableContentRef = ref)} />
+ {
+ // eslint-disable-next-line no-use-before-define
+ <CollectionSchemaViewDocs
+ schema={this}
+ childDocs={this.sortedDocsFunc}
+ rowHeight={this.rowHeightFunc}
+ setRef={(ref: HTMLDivElement | null) => {
+ this._tableContentRef = ref;
+ }}
+ />
+ }
{this.layoutDoc.chromeHidden ? null : (
<div className="schema-add">
<EditableView
GetValue={returnEmptyString}
SetValue={undoable(value => (value ? this.addRow(Docs.Create.TextDocument(value, { title: value, _layout_autoHeight: true })) : false), 'add text doc')}
placeholder={"Type text to create note or ':' to create specific type"}
- contents={'+ New Node'}
+ contents="+ New Node"
menuCallback={this.menuCallback}
height={CollectionSchemaView._newNodeInputHeight}
/>
</div>
)}
</div>
- {this.previewWidth > 0 && <div className="schema-preview-divider" style={{ width: CollectionSchemaView._previewDividerWidth }} onPointerDown={this.onDividerDown}></div>}
+ {this.previewWidth > 0 && <div className="schema-preview-divider" style={{ width: CollectionSchemaView._previewDividerWidth }} onPointerDown={this.onDividerDown} />}
{this.previewWidth > 0 && (
- <div style={{ width: `${this.previewWidth}px` }} ref={ref => (this._previewRef = ref)}>
+ <div
+ style={{ width: `${this.previewWidth}px` }}
+ ref={ref => {
+ this._previewRef = ref;
+ }}>
{Array.from(this._selectedDocs).lastElement() && (
<DocumentView
Document={Array.from(this._selectedDocs).lastElement()}
fitContentsToBox={returnTrue}
- dontCenter={'y'}
+ dontCenter="y"
onClickScriptDisable="always"
focus={emptyFunction}
defaultDoubleClick={returnIgnore}
@@ -938,28 +1127,6 @@ export class CollectionSchemaView extends CollectionSubView() {
}
}
-interface CollectionSchemaViewDocsProps {
- schema: CollectionSchemaView;
- setRef: (ref: HTMLDivElement | null) => void;
- childDocs: () => { docs: Doc[] };
- rowHeight: () => number;
-}
-
-@observer
-class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsProps> {
- render() {
- return (
- <div className="schema-table-content" ref={this.props.setRef} style={{ height: `calc(100% - ${CollectionSchemaView._newNodeInputHeight + this.props.rowHeight()}px)` }}>
- {this.props.childDocs().docs.map((doc: Doc, index: number) => (
- <div key={doc[Id]} className="schema-row-wrapper" style={{ height: this.props.rowHeight() }}>
- <CollectionSchemaViewDoc doc={doc} schema={this.props.schema} index={index} rowHeight={this.props.rowHeight} />
- </div>
- ))}
- </div>
- );
- }
-}
-
interface CollectionSchemaViewDocProps {
schema: CollectionSchemaView;
index: number;
@@ -980,10 +1147,12 @@ class CollectionSchemaViewDoc extends ObservableReactComponent<CollectionSchemaV
if (property === StyleProp.Opacity) return 1;
return DefaultStyleProvider(doc, props, property);
};
+ isRowContentActive = () => this._props.schema.isContentActive() || this._props.schema._props.isSelected() || this._props.schema._props.isAnyChildContentActive();
render() {
return (
<DocumentView
key={this._props.doc[Id]}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props.schema._props}
containerViewPath={this._props.schema.childContainerViewPath}
LayoutTemplate={this._props.schema._props.childLayoutTemplate}
@@ -1003,16 +1172,37 @@ class CollectionSchemaViewDoc extends ObservableReactComponent<CollectionSchemaV
searchFilterDocs={this._props.schema.searchFilterDocs}
rootSelected={this._props.schema.rootSelected}
ScreenToLocalTransform={this.screenToLocalXf}
- dragWhenActive={true}
+ dragWhenActive
isDocumentActive={this._props.schema._props.childDocumentsActive?.() ? this._props.schema._props.isDocumentActive : this._props.schema.isContentActive}
- isContentActive={emptyFunction}
+ isContentActive={this.isRowContentActive}
whenChildContentsActiveChanged={this._props.schema._props.whenChildContentsActiveChanged}
- hideDecorations={true}
- hideTitle={true}
- hideDocumentButtonBar={true}
- hideLinkAnchors={true}
- layout_fitWidth={returnTrue}
+ hideDecorations
+ hideTitle
+ hideDocumentButtonBar
+ hideLinkAnchors
+ fitWidth={returnTrue}
/>
);
}
}
+interface CollectionSchemaViewDocsProps {
+ schema: CollectionSchemaView;
+ setRef: (ref: HTMLDivElement | null) => void;
+ childDocs: () => { docs: Doc[] };
+ rowHeight: () => number;
+}
+
+@observer
+class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsProps> {
+ render() {
+ return (
+ <div className="schema-table-content" ref={this.props.setRef} style={{ height: `calc(100% - ${CollectionSchemaView._newNodeInputHeight + this.props.rowHeight()}px)` }}>
+ {this.props.childDocs().docs.map((doc: Doc, index: number) => (
+ <div key={doc[Id]} className="schema-row-wrapper" style={{ height: this.props.rowHeight() }}>
+ <CollectionSchemaViewDoc doc={doc} schema={this.props.schema} index={index} rowHeight={this.props.rowHeight} />
+ </div>
+ ))}
+ </div>
+ );
+ }
+}
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 5f8b412be..6b5a34ec0 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -1,8 +1,10 @@
+/* eslint-disable react/no-unused-prop-types */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from 'mobx';
+import { action } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, setupMoveUpEvents } from '../../../../Utils';
+import { setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Colors } from '../../global/globalEnums';
import './CollectionSchemaView.scss';
@@ -24,8 +26,6 @@ export interface SchemaColumnHeaderProps {
@observer
export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps> {
- @observable _ref: HTMLDivElement | null = null;
-
get fieldKey() {
return this.props.columnKeys[this.props.columnIndex];
}
@@ -34,9 +34,9 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps>
sortClicked = (e: React.PointerEvent) => {
e.stopPropagation();
e.preventDefault();
- if (this.props.sortField == this.fieldKey && this.props.sortDesc) {
+ if (this.props.sortField === this.fieldKey && this.props.sortDesc) {
this.props.setSort(undefined);
- } else if (this.props.sortField == this.fieldKey) {
+ } else if (this.props.sortField === this.fieldKey) {
this.props.setSort(this.fieldKey, true);
} else {
this.props.setSort(this.fieldKey, false);
@@ -45,7 +45,7 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps>
@action
onPointerDown = (e: React.PointerEvent) => {
- this.props.isContentActive(true) && setupMoveUpEvents(this, e, e => this.props.dragColumn(e, this.props.columnIndex), emptyFunction, emptyFunction, false);
+ this.props.isContentActive(true) && setupMoveUpEvents(this, e, moveEv => this.props.dragColumn(moveEv, this.props.columnIndex), emptyFunction, emptyFunction);
};
render() {
@@ -58,19 +58,18 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps>
onPointerDown={this.onPointerDown}
ref={col => {
if (col) {
- this._ref = col;
this.props.setColRef(this.props.columnIndex, col);
}
}}>
- <div className="schema-column-resizer left" onPointerDown={e => this.props.resizeColumn(e, this.props.columnIndex)}></div>
+ <div className="schema-column-resizer left" onPointerDown={e => this.props.resizeColumn(e, this.props.columnIndex)} />
<div className="schema-column-title">{this.fieldKey}</div>
<div className="schema-header-menu">
<div className="schema-header-button" onPointerDown={e => this.props.openContextMenu(e.clientX, e.clientY, this.props.columnIndex)}>
<FontAwesomeIcon icon="ellipsis-h" />
</div>
- <div className="schema-sort-button" onPointerDown={this.sortClicked} style={this.props.sortField == this.fieldKey ? { backgroundColor: Colors.MEDIUM_BLUE } : {}}>
- <FontAwesomeIcon icon="caret-right" style={this.props.sortField == this.fieldKey ? { transform: `rotate(${this.props.sortDesc ? '270deg' : '90deg'})` } : {}} />
+ <div className="schema-sort-button" onPointerDown={this.sortClicked} style={this.props.sortField === this.fieldKey ? { backgroundColor: Colors.MEDIUM_BLUE } : {}}>
+ <FontAwesomeIcon icon="caret-right" style={this.props.sortField === this.fieldKey ? { transform: `rotate(${this.props.sortDesc ? '270deg' : '90deg'})` } : {}} />
</div>
</div>
</div>
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 39fea2d2e..760089ffb 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -5,17 +5,16 @@ import { computedFn } from 'mobx-utils';
import * as React from 'react';
import { CgClose, CgLock, CgLockUnlock } from 'react-icons/cg';
import { FaExternalLinkAlt } from 'react-icons/fa';
-import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../../Utils';
+import { returnFalse, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Doc } from '../../../../fields/Doc';
import { BoolCast } from '../../../../fields/Types';
-import { DragManager } from '../../../util/DragManager';
-import { SnappingManager } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
import { undoable } from '../../../util/UndoManager';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
-import { OpenWhere } from '../../nodes/DocumentView';
import { FieldView, FieldViewProps } from '../../nodes/FieldView';
+import { OpenWhere } from '../../nodes/OpenWhere';
import { CollectionSchemaView } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
import { SchemaTableCell } from './SchemaTableCell';
@@ -42,7 +41,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
}
@computed get schemaDoc() {
- return this.DocumentView?.().containerViewPath?.().lastElement()?.Document;
+ return this.schemaView.Document;
}
@computed get rowIndex() {
@@ -53,63 +52,21 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
this._props.setContentViewBox?.(this);
}
- select = (ctrlKey: boolean, shiftKey: boolean) => {
- if (!this.schemaView) return;
- const lastSelected = Array.from(this.schemaView._selectedDocs).lastElement();
- if (shiftKey && lastSelected) this.schemaView.selectRows(this.Document, lastSelected);
- else {
- this._props.select?.(ctrlKey);
- }
- };
-
- onPointerEnter = (e: any) => {
- if (SnappingManager.IsDragging && this._props.isContentActive()) {
- document.removeEventListener('pointermove', this.onPointerMove);
- document.addEventListener('pointermove', this.onPointerMove);
- }
- };
-
- onPointerMove = (e: any) => {
- const dragIsRow = DragManager.docsBeingDragged.some(doc => doc.embedContainer === this.schemaDoc); // this.schemaView?._selectedDocs.has(doc) ?? false;
-
- if (this._ref && dragIsRow) {
- const rect = this._ref.getBoundingClientRect();
- const y = e.clientY - rect.top; //y position within the element.
- const height = this._ref.clientHeight;
- const halfLine = height / 2;
- if (y <= halfLine) {
- this._ref.style.borderTop = `solid 2px ${Colors.MEDIUM_BLUE}`;
- this._ref.style.borderBottom = '0px';
- this.schemaView?.setDropIndex(this.rowIndex);
- } else if (y > halfLine) {
- this._ref.style.borderTop = '0px';
- this._ref.style.borderBottom = `solid 2px ${Colors.MEDIUM_BLUE}`;
- this.schemaView?.setDropIndex(this.rowIndex + 1);
- }
- }
- };
-
- onPointerLeave = (e: any) => {
- if (this._ref) {
- this._ref.style.borderTop = '0px';
- this._ref.style.borderBottom = '0px';
- }
- document.removeEventListener('pointermove', this.onPointerMove);
- };
-
+ setCursorIndex = (mouseY: number) => this.schemaView?.setRelCursorIndex(mouseY);
+ selectedCol = () => this.schemaView._selectedCol;
getFinfo = computedFn((fieldKey: string) => this.schemaView?.fieldInfos.get(fieldKey));
- selectCell = (doc: Doc, col: number) => this.schemaView?.selectCell(doc, col);
- deselectCell = () => this.schemaView?.deselectCell();
- selectedCell = () => this.schemaView?._selectedCell;
+ selectCell = (doc: Doc, col: number, shift: boolean, ctrl: boolean) => this.schemaView?.selectCell(doc, col, shift, ctrl);
+ deselectCell = () => this.schemaView?.deselectAllCells();
+ selectedCells = () => this.schemaView?._selectedDocs;
setColumnValues = (field: any, value: any) => this.schemaView?.setColumnValues(field, value) ?? false;
+ setSelectedColumnValues = (field: any, value: any) => this.schemaView?.setSelectedColumnValues(field, value) ?? false;
columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth);
render() {
return (
<div
className="schema-row"
+ onPointerDown={e => this.setCursorIndex(e.clientY)}
style={{ height: this._props.PanelHeight(), backgroundColor: this._props.isSelected() ? Colors.LIGHT_BLUE : undefined }}
- onPointerEnter={this.onPointerEnter}
- onPointerLeave={this.onPointerLeave}
ref={(row: HTMLDivElement | null) => {
row && this.schemaView?.addRowRef?.(this.Document, row);
this._ref = row;
@@ -121,8 +78,8 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
pointerEvents: !this._props.isContentActive() ? 'none' : undefined,
}}>
<IconButton
- tooltip="whether document interactions are enabled"
- icon={this.Document._lockedPosition ? <CgLockUnlock size="12px" /> : <CgLock size="12px" />}
+ tooltip="close"
+ icon={<CgClose size="16px" />}
size={Size.XSMALL}
onPointerDown={e =>
setupMoveUpEvents(
@@ -130,15 +87,16 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
e,
returnFalse,
emptyFunction,
- undoable(e => {
- e.stopPropagation();
- Doc.toggleLockedPosition(this.Document);
+ undoable(clickEv => {
+ clickEv.stopPropagation();
+ this._props.removeDocument?.(this.Document);
}, 'Delete Row')
)
- }></IconButton>
+ }
+ />
<IconButton
- tooltip="close"
- icon={<CgClose size={'16px'} />}
+ tooltip="whether document interactions are enabled"
+ icon={this.Document._lockedPosition ? <CgLockUnlock size="12px" /> : <CgLock size="12px" />}
size={Size.XSMALL}
onPointerDown={e =>
setupMoveUpEvents(
@@ -146,10 +104,10 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
e,
returnFalse,
emptyFunction,
- undoable(e => {
- e.stopPropagation();
- this._props.removeDocument?.(this.Document);
- }, 'Delete Row')
+ undoable(clickEv => {
+ clickEv.stopPropagation();
+ Doc.toggleLockedPosition(this.Document);
+ }, 'toggle document lock')
)
}
/>
@@ -163,8 +121,8 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
e,
returnFalse,
emptyFunction,
- undoable(e => {
- e.stopPropagation();
+ undoable(clickEv => {
+ clickEv.stopPropagation();
this._props.addDocTab(this.Document, OpenWhere.addRight);
}, 'Open schema Doc preview')
)
@@ -185,8 +143,10 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
getFinfo={this.getFinfo}
selectCell={this.selectCell}
deselectCell={this.deselectCell}
- selectedCell={this.selectedCell}
+ selectedCells={this.selectedCells}
+ selectedCol={this.selectedCol}
setColumnValues={this.setColumnValues}
+ setSelectedColumnValues={this.setSelectedColumnValues}
oneLine={BoolCast(this.schemaDoc?._singleLine)}
menuTarget={this.schemaView.MenuTarget}
transform={() => {
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index ed1b519b4..5874364e0 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -1,42 +1,45 @@
+/* eslint-disable jsx-a11y/alt-text */
+/* eslint-disable react/jsx-props-no-spreading */
+/* eslint-disable no-use-before-define */
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Popup, Size, Type } from 'browndash-components';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import { extname } from 'path';
import * as React from 'react';
import DatePicker from 'react-datepicker';
+import 'react-datepicker/dist/react-datepicker.css';
import Select from 'react-select';
-import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../../Utils';
+import { ClientUtils, StopEvent, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { DateField } from '../../../../fields/DateField';
import { Doc, DocListCast, Field } from '../../../../fields/Doc';
import { RichTextField } from '../../../../fields/RichTextField';
-import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast } from '../../../../fields/Types';
+import { ColumnType } from '../../../../fields/SchemaHeaderField';
+import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast, toList } from '../../../../fields/Types';
import { ImageField } from '../../../../fields/URLField';
import { FInfo, FInfoFieldType } from '../../../documents/Documents';
-import { DocFocusOrOpen } from '../../../util/DocumentManager';
+import { dropActionType } from '../../../util/DropActionTypes';
+import { SnappingManager } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
import { undoBatch, undoable } from '../../../util/UndoManager';
import { EditableView } from '../../EditableView';
import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { DefaultStyleProvider } from '../../StyleProvider';
+import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider';
import { Colors } from '../../global/globalEnums';
-import { OpenWhere, returnEmptyDocViewList } from '../../nodes/DocumentView';
+import { DocumentView } from '../../nodes/DocumentView';
import { FieldViewProps } from '../../nodes/FieldView';
-import { KeyValueBox } from '../../nodes/KeyValueBox';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
-import { ColumnType, FInfotoColType } from './CollectionSchemaView';
+import { FInfotoColType } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
-import 'react-datepicker/dist/react-datepicker.css';
-import { Popup, Size, Type } from 'browndash-components';
-import { IconLookup, faCaretDown } from '@fortawesome/free-solid-svg-icons';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { SettingsManager } from '../../../util/SettingsManager';
-import { dropActionType } from '../../../util/DragManager';
export interface SchemaTableCellProps {
Document: Doc;
col: number;
deselectCell: () => void;
- selectCell: (doc: Doc, col: number) => void;
- selectedCell: () => [Doc, number] | undefined;
+ selectCell: (doc: Doc, col: number, shift: boolean, ctrl: boolean) => void;
+ selectedCells: () => Doc[] | undefined;
+ selectedCol: () => number;
fieldKey: string;
maxWidth?: () => number;
columnWidth: () => number;
@@ -45,12 +48,23 @@ export interface SchemaTableCellProps {
isRowActive: () => boolean | undefined;
getFinfo: (fieldKey: string) => FInfo | undefined;
setColumnValues: (field: string, value: string) => boolean;
+ setSelectedColumnValues: (field: string, value: string) => boolean;
oneLine?: boolean; // whether all input should fit on one line vs allowing textare multiline inputs
allowCRs?: boolean; // allow carriage returns in text input (othewrise CR ends the edit)
finishEdit?: () => void; // notify container that edit is over (eg. to hide view in DashFieldView)
options?: string[];
menuTarget: HTMLDivElement | null;
transform: () => Transform;
+ autoFocus?: boolean; // whether to set focus on creation, othwerise wait for a click
+ rootSelected?: () => boolean;
+}
+
+function selectedCell(props: SchemaTableCellProps) {
+ return (
+ props.isRowActive() &&
+ props.selectedCol() === props.col && //
+ props.selectedCells()?.filter(d => d === props.Document)?.length
+ );
}
@observer
@@ -60,8 +74,8 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
makeObservable(this);
}
- static addFieldDoc = (doc: Doc, where: OpenWhere) => {
- DocFocusOrOpen(doc);
+ static addFieldDoc = (docs: Doc | Doc[] /* , where: OpenWhere */) => {
+ DocumentView.FocusOrOpen(toList(docs)[0]);
return true;
};
public static renderProps(props: SchemaTableCellProps) {
@@ -76,7 +90,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
doc = DocCast(doc.proto);
}
const parenCount = Math.max(0, protoCount - 1);
- const color = protoCount === 0 || (fieldKey.startsWith('_') && Document[fieldKey] === undefined) ? 'black' : 'blue';
+ const color = protoCount === 0 || (fieldKey.startsWith('_') && Document[fieldKey] === undefined) ? 'black' : 'blue'; // color of text in cells
const textDecoration = color !== 'black' && parenCount ? 'underline' : '';
const fieldProps: FieldViewProps = {
childFilters: returnEmptyFilter,
@@ -89,16 +103,18 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
select: emptyFunction,
dragAction: dropActionType.move,
renderDepth: 1,
+ noSidebar: true,
isContentActive: returnFalse,
whenChildContentsActiveChanged: emptyFunction,
ScreenToLocalTransform: Transform.Identity,
focus: emptyFunction,
addDocTab: SchemaTableCell.addFieldDoc,
pinToPres: returnZero,
- Document,
+ Document: DocCast(Document.rootDocument, Document),
fieldKey: fieldKey,
PanelWidth: columnWidth,
PanelHeight: props.rowHeight,
+ rootSelected: props.rootSelected,
};
const readOnly = getFinfo(fieldKey)?.readOnly ?? false;
const cursor = !readOnly ? 'text' : 'default';
@@ -106,11 +122,6 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
return { color, textDecoration, fieldProps, cursor, pointerEvents };
}
- @computed get selected() {
- const selected: [Doc, number] | undefined = this._props.selectedCell();
- return this._props.isRowActive() && selected?.[0] === this._props.Document && selected[1] === this._props.col;
- }
-
@computed get defaultCellContent() {
const { color, textDecoration, fieldProps, pointerEvents } = SchemaTableCell.renderProps(this._props);
@@ -124,17 +135,20 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
pointerEvents,
}}>
<EditableView
+ ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)}
oneLine={this._props.oneLine}
allowCRs={this._props.allowCRs}
contents={undefined}
fieldContents={fieldProps}
- editing={this.selected ? undefined : false}
- GetValue={() => Field.toKeyValueString(this._props.Document, this._props.fieldKey)}
+ editing={selectedCell(this._props) ? undefined : false}
+ GetValue={() => Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)}
SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => {
if (shiftDown && enterKey) {
this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value);
+ this._props.finishEdit?.();
+ return true;
}
- const ret = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined);
+ const ret = Doc.SetField(fieldProps.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(fieldProps.Document) ? true : undefined);
this._props.finishEdit?.();
return ret;
}, 'edit schema cell')}
@@ -146,30 +160,27 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
get getCellType() {
const columnTypeStr = this._props.getFinfo(this._props.fieldKey)?.fieldType;
const cellValue = this._props.Document[this._props.fieldKey];
+
if (cellValue instanceof ImageField) return ColumnType.Image;
if (cellValue instanceof DateField) return ColumnType.Date;
if (cellValue instanceof RichTextField) return ColumnType.RTF;
if (typeof cellValue === 'number') return ColumnType.Any;
if (typeof cellValue === 'string' && columnTypeStr !== FInfoFieldType.enumeration) return ColumnType.Any;
if (typeof cellValue === 'boolean') return ColumnType.Boolean;
-
- if (columnTypeStr && columnTypeStr in FInfotoColType) {
- return FInfotoColType[columnTypeStr];
- }
+ if (columnTypeStr && columnTypeStr in FInfotoColType) return FInfotoColType[columnTypeStr];
return ColumnType.Any;
}
get content() {
- const cellType: ColumnType = this.getCellType;
// prettier-ignore
- switch (cellType) {
- case ColumnType.Image: return <SchemaImageCell {...this._props} />;
- case ColumnType.Boolean: return <SchemaBoolCell {...this._props} />;
- case ColumnType.RTF: return <SchemaRTFCell {...this._props} />;
- case ColumnType.Enumeration: return <SchemaEnumerationCell {...this._props} options={this._props.getFinfo(this._props.fieldKey)?.values?.map(val => val.toString())} />;
- case ColumnType.Date: return <SchemaDateCell {...this._props} />;
- default: return this.defaultCellContent;
+ switch (this.getCellType) {
+ case ColumnType.Image: return <SchemaImageCell {...this._props} />;
+ case ColumnType.Boolean: return <SchemaBoolCell {...this._props} />;
+ case ColumnType.RTF: return <SchemaRTFCell {...this._props} />;
+ case ColumnType.Enumeration: return <SchemaEnumerationCell {...this._props} options={this._props.getFinfo(this._props.fieldKey)?.values?.map(val => Field.toString(val))} />;
+ case ColumnType.Date: return <SchemaDateCell {...this._props} />;
+ default: return this.defaultCellContent;
}
}
@@ -177,8 +188,18 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
return (
<div
className="schema-table-cell"
- onPointerDown={action(e => !this.selected && this._props.selectCell(this._props.Document, this._props.col))}
- style={{ padding: this._props.padding, maxWidth: this._props.maxWidth?.(), width: this._props.columnWidth() || undefined, border: this.selected ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}>
+ onContextMenu={e => StopEvent(e)}
+ onPointerDown={action(e => {
+ const shift: boolean = e.shiftKey;
+ const ctrl: boolean = e.ctrlKey;
+ if (this._props.isRowActive?.() !== false) {
+ if (selectedCell(this._props) && ctrl) {
+ this._props.selectCell(this._props.Document, this._props.col, shift, ctrl);
+ e.stopPropagation();
+ } else !selectedCell(this._props) && this._props.selectCell(this._props.Document, this._props.col, shift, ctrl);
+ }
+ })}
+ style={{ padding: this._props.padding, maxWidth: this._props.maxWidth?.(), width: this._props.columnWidth() || undefined, border: selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}>
{this.content}
</div>
);
@@ -197,8 +218,8 @@ export class SchemaImageCell extends ObservableReactComponent<SchemaTableCellPro
choosePath(url: URL) {
if (url.protocol === 'data') return url.href; // if the url ises the data protocol, just return the href
- if (url.href.indexOf(window.location.origin) === -1) return Utils.CorsProxy(url.href); // otherwise, put it through the cors proxy erver
- if (!/\.(png|jpg|jpeg|gif|webp)$/.test(url.href.toLowerCase())) return url.href; //Why is this here — good question
+ if (url.href.indexOf(window.location.origin) === -1) return ClientUtils.CorsProxy(url.href); // otherwise, put it through the cors proxy erver
+ if (!/\.(png|jpg|jpeg|gif|webp)$/.test(url.href.toLowerCase())) return url.href; // Why is this here — good question
const ext = extname(url.href);
return url.href.replace(ext, '_s' + ext);
@@ -206,14 +227,14 @@ export class SchemaImageCell extends ObservableReactComponent<SchemaTableCellPro
get url() {
const field = Cast(this._props.Document[this._props.fieldKey], ImageField, null); // retrieve the primary image URL that is being rendered from the data doc
- const alts = DocListCast(this._props.Document[this._props.fieldKey + '-alternates']); // retrieve alternate documents that may be rendered as alternate images
+ const alts = DocListCast(this._props.Document[this._props.fieldKey + '_alternates']); // retrieve alternate documents that may be rendered as alternate images
const altpaths = alts
.map(doc => Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url)
.filter(url => url)
.map(url => this.choosePath(url)); // access the primary layout data of the alternate documents
const paths = field ? [this.choosePath(field.url), ...altpaths] : altpaths;
// If there is a path, follow it; otherwise, follow a link to a default image icon
- const url = paths.length ? paths : [Utils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png')];
+ const url = paths.length ? paths : [ClientUtils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png')];
return url[0];
}
@@ -237,7 +258,7 @@ export class SchemaImageCell extends ObservableReactComponent<SchemaTableCellPro
};
@action
- removeHoverPreview = (e: React.PointerEvent) => {
+ removeHoverPreview = () => {
if (!this._previewRef) return;
document.body.removeChild(this._previewRef);
};
@@ -249,7 +270,7 @@ export class SchemaImageCell extends ObservableReactComponent<SchemaTableCellPro
const height = this._props.rowHeight() ? this._props.rowHeight() - (this._props.padding || 6) * 2 : undefined;
const width = height ? height * aspect : undefined; // increase the width of the image if necessary to maintain proportionality
- return <img src={this.url} width={width ? width : undefined} height={height} style={{}} draggable="false" onPointerEnter={this.showHoverPreview} onPointerMove={this.moveHoverPreview} onPointerLeave={this.removeHoverPreview} />;
+ return <img src={this.url} width={width || undefined} height={height} style={{}} draggable="false" onPointerEnter={this.showHoverPreview} onPointerMove={this.moveHoverPreview} onPointerLeave={this.removeHoverPreview} />;
}
}
@@ -273,26 +294,26 @@ export class SchemaDateCell extends ObservableReactComponent<SchemaTableCellProp
// } else {
// ^ DateCast is always undefined for some reason, but that is what the field should be set to
date && (this._props.Document[this._props.fieldKey] = new DateField(date));
- //}
+ // }
}, 'date change');
render() {
- const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props);
+ const { pointerEvents } = SchemaTableCell.renderProps(this._props);
return (
<>
<div style={{ pointerEvents: 'none' }}>
- <DatePicker dateFormat="Pp" selected={this.date?.date ?? Date.now()} onChange={e => {}} />
+ <DatePicker dateFormat="Pp" selected={this.date?.date ?? Date.now()} onChange={emptyFunction} />
</div>
{pointerEvents === 'none' ? null : (
<Popup
icon={<FontAwesomeIcon size="sm" icon="caret-down" />}
size={Size.XSMALL}
type={Type.TERT}
- color={SettingsManager.userColor}
- background={SettingsManager.userBackgroundColor}
+ color={SnappingManager.userColor}
+ background={SnappingManager.userBackgroundColor}
popup={
<div style={{ width: 'fit-content', height: '200px' }}>
- <DatePicker open={true} dateFormat="Pp" selected={this.date?.date ?? Date.now()} onChange={this.handleChange} />
+ <DatePicker open dateFormat="Pp" selected={this.date?.date ?? Date.now()} onChange={this.handleChange} />
</div>
}
/>
@@ -308,17 +329,14 @@ export class SchemaRTFCell extends ObservableReactComponent<SchemaTableCellProps
makeObservable(this);
}
- @computed get selected() {
- const selected: [Doc, number] | undefined = this._props.selectedCell();
- return this._props.isRowActive() && selected?.[0] === this._props.Document && selected[1] === this._props.col;
- }
- selectedFunc = () => this.selected;
+ // if the text box blurs and none of its contents are focused(), then the edit finishes
+ selectedFunc = () => !!selectedCell(this._props);
render() {
const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props);
fieldProps.isContentActive = this.selectedFunc;
return (
- <div className="schemaRTFCell" style={{ display: 'flex', fontStyle: this.selected ? undefined : 'italic', width: '100%', height: '100%', position: 'relative', color, textDecoration, cursor, pointerEvents }}>
- {this.selected ? <FormattedTextBox {...fieldProps} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
+ <div className="schemaRTFCell" style={{ fontStyle: selectedCell(this._props) ? undefined : 'italic', color, textDecoration, cursor, pointerEvents }}>
+ {selectedCell(this._props) ? <FormattedTextBox {...fieldProps} autoFocus onBlur={() => this._props.finishEdit?.()} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
</div>
);
}
@@ -330,10 +348,6 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp
makeObservable(this);
}
- @computed get selected() {
- const selected: [Doc, number] | undefined = this._props.selectedCell();
- return this._props.isRowActive() && selected?.[0] === this._props.Document && selected[1] === this._props.col;
- }
render() {
const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props);
return (
@@ -344,21 +358,22 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp
checked={BoolCast(this._props.Document[this._props.fieldKey])}
onChange={undoBatch((value: React.ChangeEvent<HTMLInputElement> | undefined) => {
if ((value?.nativeEvent as any).shiftKey) {
- this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString());
- }
- KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString());
+ this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? ''));
+ } else Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? ''));
})}
/>
<EditableView
contents={undefined}
fieldContents={fieldProps}
- editing={this.selected ? undefined : false}
+ editing={selectedCell(this._props) ? undefined : false}
GetValue={() => Field.toKeyValueString(this._props.Document, this._props.fieldKey)}
SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => {
if (shiftDown && enterKey) {
this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value);
+ this._props.finishEdit?.();
+ return true;
}
- const set = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value);
+ const set = Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined);
this._props.finishEdit?.();
return set;
})}
@@ -374,12 +389,8 @@ export class SchemaEnumerationCell extends ObservableReactComponent<SchemaTableC
makeObservable(this);
}
- @computed get selected() {
- const selected: [Doc, number] | undefined = this._props.selectedCell();
- return this._props.isRowActive() && selected?.[0] === this._props.Document && selected[1] === this._props.col;
- }
render() {
- const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props);
+ const { color, textDecoration, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props);
const options = this._props.options?.map(facet => ({ value: facet, label: facet }));
return (
<div className="schemaSelectionCell" style={{ color, textDecoration, cursor, pointerEvents }}>
@@ -424,7 +435,7 @@ export class SchemaEnumerationCell extends ObservableReactComponent<SchemaTableC
placeholder={StrCast(this._props.Document[this._props.fieldKey], 'select...')}
options={options}
isMulti={false}
- onChange={val => KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), `"${val?.value ?? ''}"`)}
+ onChange={val => Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), `"${val?.value ?? ''}"`)}
/>
</div>
</div>
diff --git a/src/client/views/global/globalEnums.tsx b/src/client/views/global/globalEnums.tsx
index 610c2b102..46caa3702 100644
--- a/src/client/views/global/globalEnums.tsx
+++ b/src/client/views/global/globalEnums.tsx
@@ -1,44 +1,49 @@
export enum Colors {
- BLACK = "#000000",
- DARK_GRAY = "#323232",
- MEDIUM_GRAY = "#9F9F9F",
- LIGHT_GRAY = "#DFDFDF",
- WHITE = "#FFFFFF",
- MEDIUM_BLUE = "#4476F7",
- MEDIUM_BLUE_ALT = "#4476f73d", // REDUCED OPACITY
- LIGHT_BLUE = "#BDDDF5",
- PINK = "#E0217D",
- ERROR_RED = "#ff0033",
- YELLOW = "#F5D747",
- DROP_SHADOW = "#32323215",
+ BLACK = '#000000',
+ DARK_GRAY = '#323232',
+ MEDIUM_GRAY = '#9F9F9F',
+ LIGHT_GRAY = '#DFDFDF',
+ WHITE = '#FFFFFF',
+ MEDIUM_BLUE = '#4476F7',
+ MEDIUM_BLUE_ALT = '#4476f73d', // REDUCED OPACITY
+ LIGHT_BLUE = '#BDDDF5',
+ PINK = '#E0217D',
+ ERROR_RED = '#ff0033',
+ YELLOW = '#F5D747',
+ DROP_SHADOW = '#32323215',
}
export enum FontSizes {
- //Bolded
- LARGE_HEADER = "16px",
+ // Bolded
+ LARGE_HEADER = '16px',
- //Bolded or unbolded
- BODY_TEXT = "12px",
+ // Bolded or unbolded
+ BODY_TEXT = '12px',
- //Bolded
- SMALL_TEXT = "9px",
+ // Bolded
+ SMALL_TEXT = '9px',
}
export enum Padding {
- MINIMUM_PADDING = "4px",
- SMALL_PADDING = "8px",
- MEDIUM_PADDING = "16px",
- LARGE_PADDING = "32px",
+ MINIMUM_PADDING = '4px',
+ SMALL_PADDING = '8px',
+ MEDIUM_PADDING = '16px',
+ LARGE_PADDING = '32px',
}
export enum IconSizes {
- ICON_SIZE = "28px",
+ ICON_SIZE = '28px',
}
export enum Borders {
- STANDARD = "solid 1px #9F9F9F"
+ STANDARD = 'solid 1px #9F9F9F',
}
export enum Shadows {
- STANDARD_SHADOW = "0px 3px 4px rgba(0, 0, 0, 0.3)"
-} \ No newline at end of file
+ STANDARD_SHADOW = '0px 3px 4px rgba(0, 0, 0, 0.3)',
+}
+
+export enum VideoThumbnails {
+ DENSE = 20,
+ SPARSE = 5,
+}
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 0579b07c7..2b804c5d3 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -1,43 +1,62 @@
import { Colors } from 'browndash-components';
import { action, runInAction } from 'mobx';
-import { Doc, Opt } from '../../../fields/Doc';
+import { aggregateBounds } from '../../../Utils';
+import {
+ ActiveFillColor,
+ ActiveInkColor,
+ ActiveInkHideTextLabels,
+ ActiveInkWidth,
+ ActiveIsInkMask,
+ Doc,
+ DocListCast,
+ Opt,
+ SetActiveFillColor,
+ SetActiveInkColor,
+ SetActiveInkHideTextLabels,
+ SetActiveInkWidth,
+ SetActiveIsInkMask,
+} from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
import { InkTool } from '../../../fields/InkField';
import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
import { WebField } from '../../../fields/URLField';
-import { GestureUtils } from '../../../pen-gestures/GestureUtils';
-import { aggregateBounds } from '../../../Utils';
+import { Gestures } from '../../../pen-gestures/GestureTypes';
import { DocumentType } from '../../documents/DocumentTypes';
import { LinkManager } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
-import { SelectionManager } from '../../util/SelectionManager';
-import { undoable, UndoManager } from '../../util/UndoManager';
-import { CollectionFreeFormView } from '../collections/collectionFreeForm';
+import { UndoManager, undoable } from '../../util/UndoManager';
import { GestureOverlay } from '../GestureOverlay';
-import { ActiveFillColor, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, SetActiveIsInkMask } from '../InkingStroke';
-// import { InkTranscription } from '../InkTranscription';
+import { InkingStroke } from '../InkingStroke';
+import { CollectionFreeFormView } from '../collections/collectionFreeForm';
import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocumentView } from '../nodes/DocumentView';
-import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
-import { WebBox } from '../nodes/WebBox';
+import { ImageBox } from '../nodes/ImageBox';
import { VideoBox } from '../nodes/VideoBox';
-import { DocData } from '../../../fields/DocSymbols';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
-import { PrefetchProxy } from '../../../fields/Proxy';
-import { MakeTemplate } from '../../util/DropConverter';
+import { WebBox } from '../nodes/WebBox';
+import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
+import { NumListCast } from '../../../fields/Doc';
+import { List } from '../../../fields/List';
+// import { InkTranscription } from '../InkTranscription';
+
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function IsNoneSelected() {
- return SelectionManager.Views.length <= 0;
+ return DocumentView.Selected().length <= 0;
}, 'are no document selected');
// toggle: Set overlay status of selected document
-ScriptingGlobals.add(function setView(view: string) {
- const selected = SelectionManager.Docs.lastElement();
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function setView(view: string, getSelected: boolean) {
+ if (getSelected) return DocumentView.SelectedDocs();
+ const selected = DocumentView.SelectedDocs().lastElement();
selected ? (selected._type_collection = view) : console.log('[FontIconBox.tsx] changeView failed');
+ return undefined;
});
// toggle: Set overlay status of selected document
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: boolean) {
- const selectedViews = SelectionManager.Views;
+ const selectedViews = DocumentView.Selected();
if (Doc.ActiveTool !== InkTool.None) {
if (checkResult) {
return ActiveFillColor();
@@ -61,77 +80,79 @@ ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: b
obj[fieldKey] = color;
CollectionFreeFormDocumentView.setStringValues(contentFrameNumber, dv.Document, obj);
} else {
- dv.Document[DocData][fieldKey] = color;
+ const dataKey = Doc.LayoutFieldKey(dv.Document);
+ const alternate = (dv.layoutDoc[dataKey + '_usePath'] ? '_' + dv.layoutDoc[dataKey + '_usePath'] : '').replace(':hover', '');
+ dv.dataDoc[fieldKey + alternate] = color;
}
});
} else {
- const selected = SelectionManager.Docs.length ? SelectionManager.Docs : LinkManager.Instance.currentLink ? [LinkManager.Instance.currentLink] : [];
+ const selected = DocumentView.SelectedDocs().length ? DocumentView.SelectedDocs() : LinkManager.Instance.currentLink ? [LinkManager.Instance.currentLink] : [];
if (checkResult) {
return selected.lastElement()?._backgroundColor ?? 'transparent';
}
SetActiveFillColor(color ?? 'transparent');
- selected.forEach(doc => (doc[DocData].backgroundColor = color));
+ selected.forEach(doc => { doc[DocData].backgroundColor = color; }); // prettier-ignore
}
+ return '';
});
// toggle: Set overlay status of selected document
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function setDefaultTemplate(checkResult?: boolean) {
- if (checkResult) {
- return Doc.UserDoc().defaultTextLayout;
- }
- const view = SelectionManager.Views.length === 1 && SelectionManager.Views[0].ComponentView instanceof FormattedTextBox ? SelectionManager.Views[0] : undefined;
-
- if (view) {
- const tempDoc = view.Document;
- if (!view.layoutDoc.isTemplateDoc) {
- MakeTemplate(tempDoc);
- }
- Doc.UserDoc().defaultTextLayout = new PrefetchProxy(tempDoc);
- tempDoc && Doc.AddDocToList(Cast(Doc.UserDoc().template_notes, Doc, null), 'data', tempDoc);
- } else Doc.UserDoc().defaultTextLayout = undefined;
+ return DocumentView.setDefaultTemplate(checkResult);
});
// toggle: Set overlay status of selected document
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boolean) {
if (checkResult) {
- return SelectionManager.Views.length ? StrCast(SelectionManager.Docs.lastElement().layout_headingColor) : Doc.SharingDoc().headingColor;
+ return DocumentView.Selected().length ? StrCast(DocumentView.SelectedDocs().lastElement().layout_headingColor) : Doc.SharingDoc().headingColor;
}
- if (SelectionManager.Views.length) {
- SelectionManager.Docs.forEach(doc => {
+ if (DocumentView.Selected().length) {
+ DocumentView.SelectedDocs().forEach(doc => {
doc[DocData].layout_headingColor = color === 'transparent' ? undefined : color;
doc.layout_showTitle = color === 'transparent' ? undefined : StrCast(doc.layout_showTitle, 'title');
});
} else {
Doc.SharingDoc().headingColor = undefined;
- Doc.GetProto(Doc.SharingDoc()).headingColor = color;
- Doc.UserDoc().layout_showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().layout_showTitle, 'author_date');
+ Doc.GetProto(Doc.SharingDoc()).headingColor = color === 'transparent' ? undefined : color;
+ Doc.UserDoc().layout_showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().layout_showTitle, 'title');
}
+ return undefined;
});
// toggle: Set overlay status of selected document
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) {
- const selected = SelectionManager.Views.length ? SelectionManager.Views[0] : undefined;
+ const selected = DocumentView.Selected().length ? DocumentView.Selected()[0] : undefined;
if (checkResult) {
if (NumCast(selected?.Document.z) >= 1) return true;
return false;
}
- selected ? selected.CollectionFreeFormDocumentView?.float() : console.log('[FontIconBox.tsx] toggleOverlay failed');
+ selected ? CollectionFreeFormDocumentView.from(selected)?.float() : console.log('[FontIconBox.tsx] toggleOverlay failed');
+ return undefined;
});
-ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce', checkResult?: boolean, persist?: boolean) {
- const selected = SelectionManager.Docs.lastElement();
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' | 'clusters' | 'viewAll' | 'fitOnce', checkResult?: boolean, persist?: boolean) {
+ const selected = DocumentView.SelectedDocs().lastElement();
// prettier-ignore
- const map: Map<'flashcards' | 'center' |'grid' | 'snaplines' | 'clusters' | 'arrange'| 'viewAll' | 'fitOnce', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc, dv:DocumentView) => void;}> = new Map([
+ const map: Map<'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'like' | 'star' | 'idea' | 'chat' | '1' | '2' | '3' | '4',
+ {
+ waitForRender?: boolean;
+ checkResult: (doc: Doc) => any;
+ setDoc: (doc: Doc, dv: DocumentView) => void;
+ }> = new Map([
['grid', {
checkResult: (doc:Doc) => BoolCast(doc?._freeform_backgroundGrid, false),
- setDoc: (doc:Doc,dv:DocumentView) => doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid,
+ setDoc: (doc:Doc) => { doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid; },
}],
['snaplines', {
checkResult: (doc:Doc) => BoolCast(doc?._freeform_snapLines, false),
- setDoc: (doc:Doc, dv:DocumentView) => doc._freeform_snapLines = !doc._freeform_snapLines,
+ setDoc: (doc:Doc) => { doc._freeform_snapLines = !doc._freeform_snapLines; },
}],
['viewAll', {
- checkResult: (doc:Doc) => BoolCast(doc?._freeform_fitContentsToBox, false),
- setDoc: (doc:Doc,dv:DocumentView) => {
+ checkResult: (doc: Doc) => BoolCast(doc?._freeform_fitContentsToBox, false),
+ setDoc: (doc: Doc, dv: DocumentView) => {
if (persist) doc._freeform_fitContentsToBox = !doc._freeform_fitContentsToBox;
else if (doc._freeform_fitContentsToBox) doc._freeform_fitContentsToBox = undefined;
else (dv.ComponentView as CollectionFreeFormView)?.fitContentOnce();
@@ -139,54 +160,152 @@ ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'center' | 'grid
}],
['center', {
checkResult: (doc:Doc) => BoolCast(doc?._stacking_alignCenter, false),
- setDoc: (doc:Doc,dv:DocumentView) => doc._stacking_alignCenter = !doc._stacking_alignCenter,
+ setDoc: (doc:Doc) => { doc._stacking_alignCenter = !doc._stacking_alignCenter; },
}],
['clusters', {
waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire
checkResult: (doc:Doc) => BoolCast(doc?._freeform_useClusters, false),
- setDoc: (doc:Doc,dv:DocumentView) => doc._freeform_useClusters = !doc._freeform_useClusters,
+ setDoc: (doc:Doc) => { doc._freeform_useClusters = !doc._freeform_useClusters; },
}],
['flashcards', {
- checkResult: (doc:Doc) => BoolCast(Doc.UserDoc().defaultToFlashcards, false),
- setDoc: (doc:Doc,dv:DocumentView) => Doc.UserDoc().defaultToFlashcards = !Doc.UserDoc().defaultToFlashcards,
+ checkResult: (doc: Doc) => BoolCast(Doc.UserDoc().defaultToFlashcards, false),
+ setDoc: (doc: Doc, dv: DocumentView) => Doc.UserDoc().defaultToFlashcards = !Doc.UserDoc().defaultToFlashcards,
+ }],
+ ['time', {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "time",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "time",
+ }],
+ ['docType', {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "type",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "type",
+ }],
+ ['color', {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "color",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "color",
+ }],
+ ['links', {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "links",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "links",
}],
- ]);
+ ['like', {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && StrCast(doc?.cardSort_customField) === "like",
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ doc.cardSort = "custom";
+ doc.cardSort_customField = "like";
+ doc.cardSort_visibleSortGroups = new List<number>();
+ }
+ }],
+ ['star', {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && StrCast(doc?.cardSort_customField) === "star",
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ doc.cardSort = "custom";
+ doc.cardSort_customField = "star";
+ doc.cardSort_visibleSortGroups = new List<number>();
+ }
+ }],
+ ['idea', {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && StrCast(doc?.cardSort_customField) === "idea",
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ doc.cardSort = "custom";
+ doc.cardSort_customField = "idea";
+ doc.cardSort_visibleSortGroups = new List<number>();
+ }
+ }],
+ ['chat', {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && StrCast(doc?.cardSort_customField) === "chat",
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ doc.cardSort = "custom";
+ doc.cardSort_customField = "chat";
+ doc.cardSort_visibleSortGroups = new List<number>();
+ },
+ }],
+ ]);
+ for (let i = 0; i < 8; i++) {
+ map.set((i + 1 + '') as any, {
+ checkResult: (doc: Doc) => NumListCast(doc?.cardSort_visibleSortGroups).includes(i),
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ const list = NumListCast(doc.cardSort_visibleSortGroups);
+ doc.cardSort_visibleSortGroups = new List<number>(list.includes(i) ? list.filter(d => d !== i) : [...list, i]);
+ },
+ });
+ }
if (checkResult) {
return map.get(attr)?.checkResult(selected);
}
const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} };
- SelectionManager.Views.map(dv => map.get(attr)?.setDoc(dv.layoutDoc, dv));
+ DocumentView.Selected().map(dv => map.get(attr)?.setDoc(dv.layoutDoc, dv));
setTimeout(() => batch.end(), 100);
+ return undefined;
});
+ScriptingGlobals.add(function cardHasLabel(label: string) {
+ const selected = DocumentView.SelectedDocs().lastElement();
+ const labelNum = Number(label) - 1;
+ return labelNum < 4 || (selected && DocListCast(selected[Doc.LayoutFieldKey(selected)]).some(doc => doc[StrCast(selected.cardSort_customField)] == labelNum));
+}, '');
+
+// ScriptingGlobals.add(function setCardSortAttr(attr: 'time' | 'docType' | 'color', value: any, checkResult?: boolean) {
+// // const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+// const selected = SelectionManager.Docs.lastElement();
+// // prettier-ignore
+// const map: Map<'time' | 'docType' | 'color', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc, dv:DocumentView) => void;}> = new Map([
+// ['time', {
+// checkResult: (doc:Doc) => StrCast(doc?.cardSort),
+// setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "time",
+// }],
+// ['docType', {
+// checkResult: (doc:Doc) => StrCast(doc?.cardSort),
+// setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "type",
+// }],
+// ['color', {
+// checkResult: (doc:Doc) => StrCast(doc?.cardSort),
+// setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "color",
+// }],
+// // ['custom', {
+// // checkResult: () => RichTextMenu.Instance.textAlign,
+// // setDoc: () => value && editorView?.state ? RichTextMenu.Instance.align(editorView, editorView.dispatch, value):(Doc.UserDoc().textAlign = value),
+// // }]
+// // ,
+// ]);
+
+// if (checkResult) {
+// return map.get(attr)?.checkResult(selected);
+// }
+
+// console.log('hey')
+// SelectionManager.Views.map(dv => map.get(attr)?.setDoc(dv.layoutDoc, dv));
+// console.log('success')
+// });
+
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize' | 'alignment', value: any, checkResult?: boolean) {
const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- const selected = SelectionManager.Docs.lastElement();
// prettier-ignore
const map: Map<'font'|'fontColor'|'highlight'|'fontSize'|'alignment', { checkResult: () => any; setDoc: () => void;}> = new Map([
['font', {
checkResult: () => RichTextMenu.Instance?.fontFamily,
- setDoc: () => value && RichTextMenu.Instance.setFontFamily(value),
+ setDoc: () => value && RichTextMenu.Instance?.setFontField(value, 'fontFamily'),
}],
['highlight', {
- checkResult: () =>(selected ?? Doc.UserDoc())._fontHighlight,
- setDoc: () => value && RichTextMenu.Instance.setHighlight(value),
+ checkResult: () => RichTextMenu.Instance?.fontHighlight,
+ setDoc: () => value && RichTextMenu.Instance?.setFontField(value, 'fontHighlight'),
}],
['fontColor', {
checkResult: () => RichTextMenu.Instance?.fontColor,
- setDoc: () => value && RichTextMenu.Instance.setColor(value),
+ setDoc: () => value && RichTextMenu.Instance?.setFontField(value, 'fontColor'),
}],
['alignment', {
- checkResult: () => RichTextMenu.Instance.textAlign,
- setDoc: () => value && editorView?.state ? RichTextMenu.Instance.align(editorView, editorView.dispatch, value):(Doc.UserDoc().textAlign = value),
+ checkResult: () => RichTextMenu.Instance?.textAlign,
+ setDoc: () => { value && editorView?.state ? RichTextMenu.Instance?.align(editorView, editorView.dispatch, value):(Doc.UserDoc().textAlign = value); },
}],
['fontSize', {
checkResult: () => RichTextMenu.Instance?.fontSize.replace('px', ''),
setDoc: () => {
- if (typeof value === 'number') value = value.toString();
- if (value && Number(value).toString() === value) value += 'px';
- RichTextMenu.Instance.setFontSize(value);
+ let fsize = value;
+ if (typeof fsize === 'number') fsize = fsize.toString();
+ if (fsize && Number(fsize).toString() === fsize) fsize += 'px';
+ RichTextMenu.Instance?.setFontField(fsize, 'fontSize');
},
}],
]);
@@ -195,61 +314,55 @@ ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highligh
return map.get(attr)?.checkResult();
}
map.get(attr)?.setDoc?.();
+ return undefined;
});
-type attrname = 'noAutoLink' | 'dictation' | 'bold' | 'italics' | 'underline' | 'left' | 'center' | 'right' | 'vcent' | 'bullet' | 'decimal';
-type attrfuncs = [attrname, { checkResult: () => boolean; toggle: () => any }];
+type attrname = 'noAutoLink' | 'dictation' | 'bold' | 'italics' | 'elide' | 'underline' | 'left' | 'center' | 'right' | 'vcent' | 'bullet' | 'decimal';
+type attrfuncs = [attrname, { checkResult: () => boolean; toggle?: () => any }];
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?: boolean) {
const textView = RichTextMenu.Instance?.TextView;
const editorView = textView?.EditorView;
// prettier-ignore
const alignments:attrfuncs[] = (['left','right','center','vcent'] as ("left"|"center"|"right"|"vcent")[]).map((where) =>
- [ where, { checkResult: () =>(editorView ? (where === 'vcent' ? RichTextMenu.Instance.textVcenter:
- (RichTextMenu.Instance.textAlign === where)):
- where === 'vcent' ? BoolCast(Doc.UserDoc()._layout_centered):
- (Doc.UserDoc().textAlign ===where) ? true:false),
- toggle: () => (editorView?.state ? (where === 'vcent' ? RichTextMenu.Instance.vcenterToggle(editorView, editorView.dispatch):
- RichTextMenu.Instance.align(editorView, editorView.dispatch, where)):
+ [ where, { checkResult: () => editorView ? (where === 'vcent' ? RichTextMenu.Instance?.textVcenter ?? false:
+ (RichTextMenu.Instance?.textAlign === where)):
+ where === 'vcent' ? BoolCast(Doc.UserDoc()._layout_centered):
+ (Doc.UserDoc().textAlign === where),
+ toggle: () => { editorView?.state ? (where === 'vcent' ? RichTextMenu.Instance?.vcenterToggle():
+ RichTextMenu.Instance?.align(editorView, editorView.dispatch, where)):
where === 'vcent' ? Doc.UserDoc()._layout_centered = !Doc.UserDoc()._layout_centered:
- (Doc.UserDoc().textAlign = where))}]); // prettier-ignore
+ (Doc.UserDoc().textAlign = where); }
+ }]); // prettier-ignore
// prettier-ignore
const listings:attrfuncs[] = (['bullet','decimal'] as attrname[]).map(list =>
- [ list, { checkResult: () => (editorView ? RichTextMenu.Instance.getActiveListStyle() === list:false),
- toggle: () => editorView?.state && RichTextMenu.Instance.changeListType(list) }]);
+ [ list, { checkResult: () => (editorView ? RichTextMenu.Instance?.listStyle === list:false),
+ toggle: () => editorView?.state && RichTextMenu.Instance?.changeListType(list) }]);
// prettier-ignore
const attrs:attrfuncs[] = [
- ['dictation', { checkResult: () => textView?._recordingDictation ? true:false,
- toggle: () => textView && runInAction(() => (textView._recordingDictation = !textView._recordingDictation)) }],
- ['noAutoLink',{ checkResult: () => (editorView ? RichTextMenu.Instance.noAutoLink : false),
+ ['dictation', { checkResult: () => !!textView?._recordingDictation,
+ toggle: () => textView && runInAction(() => { textView._recordingDictation = !textView._recordingDictation;} ) }],
+ ['elide', { checkResult: () => false,
+ toggle: () => editorView ? RichTextMenu.Instance?.elideSelection(): 0}],
+ ['noAutoLink',{ checkResult: () => ((editorView && RichTextMenu.Instance?.noAutoLink) ?? false),
toggle: () => editorView && RichTextMenu.Instance?.toggleNoAutoLinkAnchor()}],
- ['bold', { checkResult: () => (editorView ? RichTextMenu.Instance.bold : (Doc.UserDoc().fontWeight === 'bold') ? true:false),
- toggle: editorView ? RichTextMenu.Instance.toggleBold : () => (Doc.UserDoc().fontWeight = Doc.UserDoc().fontWeight === 'bold' ? undefined : 'bold')}],
- ['italics', { checkResult: () => (editorView ? RichTextMenu.Instance.italics : (Doc.UserDoc().fontStyle === 'italics') ? true:false),
- toggle: editorView ? RichTextMenu.Instance.toggleItalics : () => (Doc.UserDoc().fontStyle = Doc.UserDoc().fontStyle === 'italics' ? undefined : 'italics')}],
- ['underline', { checkResult: () => (editorView ? RichTextMenu.Instance.underline : (Doc.UserDoc().textDecoration === 'underline') ? true:false),
- toggle: editorView ? RichTextMenu.Instance.toggleUnderline : () => (Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === 'underline' ? undefined : 'underline') }]]
+ ['bold', { checkResult: () => (editorView ? RichTextMenu.Instance?.bold??false : (Doc.UserDoc().fontWeight === 'bold')),
+ toggle: editorView ? RichTextMenu.Instance?.toggleBold : () => { Doc.UserDoc().fontWeight = Doc.UserDoc().fontWeight === 'bold' ? undefined : 'bold'; }}],
+ ['italics', { checkResult: () => (editorView ? RichTextMenu.Instance?.italics ?? false : (Doc.UserDoc().fontStyle === 'italics')),
+ toggle: editorView ? RichTextMenu.Instance?.toggleItalics : () => { Doc.UserDoc().fontStyle = Doc.UserDoc().fontStyle === 'italics' ? undefined : 'italics'; }}],
+ ['underline', { checkResult: () => (editorView ? RichTextMenu.Instance?.underline ?? false: (Doc.UserDoc().textDecoration === 'underline')),
+ toggle: editorView ? RichTextMenu.Instance?.toggleUnderline : () => { Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === 'underline' ? undefined : 'underline'; } }]]
const map = new Map(attrs.concat(alignments).concat(listings));
if (checkResult) {
return map.get(charStyle)?.checkResult();
}
- undoable(() => map.get(charStyle)?.toggle(), 'toggle ' + charStyle)();
+ undoable(() => map.get(charStyle)?.toggle?.(), 'toggle ' + charStyle)();
+ return undefined;
});
-export function checkInksToGroup() {
- if (Doc.ActiveTool === InkTool.Write) {
- CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => {
- // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those
- // find all inkDocs in ffView.unprocessedDocs that are within 200 pixels of each other
- const inksToGroup = ffView.unprocessedDocs.filter(inkDoc => {
- // console.log(inkDoc.x, inkDoc.y);
- });
- });
- }
-}
-
-export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) {
+export function createInkGroup(/* inksToGroup?: Doc[], isSubGroup?: boolean */) {
// TODO nda - if document being added to is a inkGrouping then we can just add to that group
if (Doc.ActiveTool === InkTool.Write) {
CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => {
@@ -315,26 +428,24 @@ export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) {
CollectionFreeFormView.collectionsWithUnprocessedInk.clear();
}
-function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean, checkResult?: boolean) {
+function setActiveTool(tool: InkTool | Gestures, keepPrim: boolean, checkResult?: boolean) {
// InkTranscription.Instance?.createInkGroup();
if (checkResult) {
return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool
- ? GestureOverlay.Instance?.KeepPrimitiveMode || ![GestureUtils.Gestures.Circle, GestureUtils.Gestures.Line, GestureUtils.Gestures.Rectangle].includes(tool as GestureUtils.Gestures)
- ? true
- : true
+ ? GestureOverlay.Instance?.KeepPrimitiveMode || ![Gestures.Circle, Gestures.Line, Gestures.Rectangle].includes(tool as Gestures)
: false;
}
runInAction(() => {
if (GestureOverlay.Instance) {
GestureOverlay.Instance.KeepPrimitiveMode = keepPrim;
}
- if (Object.values(GestureUtils.Gestures).includes(tool as any)) {
+ if (Object.values(Gestures).includes(tool as any)) {
if (GestureOverlay.Instance.InkShape === tool && !keepPrim) {
Doc.ActiveTool = InkTool.None;
GestureOverlay.Instance.InkShape = undefined;
} else {
Doc.ActiveTool = InkTool.Pen;
- GestureOverlay.Instance.InkShape = tool as GestureUtils.Gestures;
+ GestureOverlay.Instance.InkShape = tool as Gestures;
}
} else if (tool) {
// pen or eraser
@@ -348,33 +459,40 @@ function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean,
Doc.ActiveTool = InkTool.None;
}
});
+ return undefined;
}
ScriptingGlobals.add(setActiveTool, 'sets the active ink tool mode');
// toggle: Set overlay status of selected document
-ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'fillColor' | 'strokeWidth' | 'strokeColor', value: any, checkResult?: boolean) {
- const selected = SelectionManager.Docs.lastElement() ?? Doc.UserDoc();
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'labels' | 'fillColor' | 'strokeWidth' | 'strokeColor', value: any, checkResult?: boolean) {
+ const selected = DocumentView.SelectedDocs().lastElement() ?? Doc.UserDoc();
// prettier-ignore
- const map: Map<'inkMask' | 'fillColor' | 'strokeWidth' | 'strokeColor', { checkResult: () => any; setInk: (doc: Doc) => void; setMode: () => void }> = new Map([
+ const map: Map<'inkMask' | 'labels' | 'fillColor' | 'strokeWidth' | 'strokeColor', { checkResult: () => any; setInk: (doc: Doc) => void; setMode: () => void }> = new Map([
['inkMask', {
checkResult: () => ((selected?._layout_isSvg ? BoolCast(selected[DocData].stroke_isInkMask) : ActiveIsInkMask())),
- setInk: (doc: Doc) => (doc[DocData].stroke_isInkMask = !doc.stroke_isInkMask),
+ setInk: (doc: Doc) => { doc[DocData].stroke_isInkMask = !doc.stroke_isInkMask; },
setMode: () => selected?.type !== DocumentType.INK && SetActiveIsInkMask(!ActiveIsInkMask()),
}],
+ ['labels', {
+ checkResult: () => ((selected?._stroke_showLabel ? BoolCast(selected[DocData].stroke_showLabel) : ActiveInkHideTextLabels())),
+ setInk: (doc: Doc) => { doc[DocData].stroke_showLabel = !doc.stroke_showLabel; },
+ setMode: () => selected?.type !== DocumentType.INK && SetActiveInkHideTextLabels(!ActiveInkHideTextLabels()),
+ }],
['fillColor', {
checkResult: () => (selected?._layout_isSvg ? StrCast(selected[DocData].fillColor) : ActiveFillColor() ?? "transparent"),
- setInk: (doc: Doc) => (doc[DocData].fillColor = StrCast(value)),
+ setInk: (doc: Doc) => { doc[DocData].fillColor = StrCast(value); },
setMode: () => SetActiveFillColor(StrCast(value)),
}],
[ 'strokeWidth', {
checkResult: () => (selected?._layout_isSvg ? NumCast(selected[DocData].stroke_width) : ActiveInkWidth()),
- setInk: (doc: Doc) => (doc[DocData].stroke_width = NumCast(value)),
+ setInk: (doc: Doc) => { doc[DocData].stroke_width = NumCast(value); },
setMode: () => { SetActiveInkWidth(value.toString()); selected?.type === DocumentType.INK && setActiveTool( GestureOverlay.Instance.InkShape ?? InkTool.Pen, true, false);},
}],
['strokeColor', {
checkResult: () => (selected?._layout_isSvg? StrCast(selected[DocData].color) : ActiveInkColor()),
- setInk: (doc: Doc) => (doc[DocData].color = String(value)),
+ setInk: (doc: Doc) => { doc[DocData].color = String(value); },
setMode: () => { SetActiveInkColor(StrCast(value)); selected?.type === DocumentType.INK && setActiveTool(GestureOverlay.Instance.InkShape ?? InkTool.Pen, true, false);},
}],
]);
@@ -383,75 +501,112 @@ ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'fillColor' | '
return map.get(option)?.checkResult();
}
map.get(option)?.setMode();
- SelectionManager.Docs.filter(doc => doc._layout_isSvg).map(doc => map.get(option)?.setInk(doc));
+ DocumentView.SelectedDocs()
+ .filter(doc => doc._layout_isSvg)
+ .map(doc => map.get(option)?.setInk(doc));
+ return undefined;
+});
+
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function toggleRaiseOnDrag(readOnly?: boolean) {
+ if (readOnly) {
+ return DocumentView.Selected().some(dv => dv.Document.keepZWhenDragged);
+ }
+ DocumentView.Selected().forEach(dv => {
+ dv.Document.keepZWhenDragged = !dv.Document.keepZWhenDragged;
+ });
+ return undefined;
});
/** WEB
* webSetURL
- **/
+ * */
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function webSetURL(url: string, checkResult?: boolean) {
- const selected = SelectionManager.Views.lastElement();
+ const selected = DocumentView.Selected().lastElement();
if (selected?.Document.type === DocumentType.WEB) {
if (checkResult) {
return StrCast(selected.Document.data, Cast(selected.Document.data, WebField, null)?.url?.href);
}
selected.ComponentView?.setData?.(url);
- //selected.Document.data = new WebField(url);
}
+ return '';
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function webForward(checkResult?: boolean) {
- const selected = SelectionManager.Views.lastElement()?.ComponentView as WebBox;
+ const selected = DocumentView.Selected().lastElement()?.ComponentView as WebBox;
if (checkResult) {
return selected?.forward(checkResult) ? undefined : 'lightGray';
}
selected?.forward();
+ return undefined;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function webBack() {
- const selected = SelectionManager.Views.lastElement()?.ComponentView as WebBox;
+ const selected = DocumentView.Selected().lastElement()?.ComponentView as WebBox;
selected?.back();
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function videoSnapshot() {
- const selected = SelectionManager.Views.lastElement()?.ComponentView as VideoBox;
+ const selected = DocumentView.Selected().lastElement()?.ComponentView as VideoBox;
selected?.Snapshot();
});
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function imageSetPixelSize() {
+ const selected = DocumentView.Selected().lastElement()?.ComponentView as ImageBox;
+ selected?.setNativeSize();
+});
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function imageRotate90() {
+ const selected = DocumentView.Selected().lastElement()?.ComponentView as ImageBox;
+ selected?.rotate();
+});
+
/** Schema
* toggleSchemaPreview
- **/
+ * */
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function toggleSchemaPreview(checkResult?: boolean) {
- const selected = SelectionManager.Docs.lastElement();
+ const selected = DocumentView.SelectedDocs().lastElement();
if (checkResult && selected) {
const result: boolean = NumCast(selected.schema_previewWidth) > 0;
if (result) return Colors.MEDIUM_BLUE;
- else return 'transparent';
- } else if (selected) {
+ return 'transparent';
+ }
+ if (selected) {
if (NumCast(selected.schema_previewWidth) > 0) {
selected.schema_previewWidth = 0;
} else {
selected.schema_previewWidth = 200;
}
}
+ return '';
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function toggleSingleLineSchema(checkResult?: boolean) {
- const selected = SelectionManager.Docs.lastElement();
+ const selected = DocumentView.SelectedDocs().lastElement();
if (checkResult && selected) {
return NumCast(selected._schema_singleLine) > 0 ? Colors.MEDIUM_BLUE : 'transparent';
}
if (selected) {
selected._schema_singleLine = !selected._schema_singleLine;
}
+ return undefined;
});
/** STACK
* groupBy
*/
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function setGroupBy(key: string, checkResult?: boolean) {
- SelectionManager.Docs.map(doc => (doc._text_fontFamily = key));
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
+ DocumentView.SelectedDocs().forEach(doc => { doc._text_fontFamily = key; }); // prettier-ignore
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
if (checkResult) {
- return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+ return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc())?.fontFamily);
}
- if (editorView) RichTextMenu.Instance.setFontFamily(key);
+ if (editorView) RichTextMenu.Instance?.setFontField(key, 'fontFamily');
else Doc.UserDoc().fontFamily = key;
+ return undefined;
});
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index 028d3da53..cd735318e 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -1,14 +1,16 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable react/require-default-props */
+import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
-import { observable, action } from 'mobx';
+import * as React from 'react';
import { Doc, StrListCast } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { Cast, DocCast } from '../../../fields/Types';
-import { LinkManager } from '../../util/LinkManager';
+import { DocumentType } from '../../documents/DocumentTypes';
import { DocumentView } from '../nodes/DocumentView';
import './LinkMenu.scss';
import { LinkMenuItem } from './LinkMenuItem';
-import * as React from 'react';
-import { DocumentType } from '../../documents/DocumentTypes';
interface LinkMenuGroupProps {
sourceDoc: Doc;
@@ -22,25 +24,24 @@ interface LinkMenuGroupProps {
@observer
export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
private _menuRef = React.createRef<HTMLDivElement>();
+ @observable _collapsed = false;
getBackgroundColor = (): string | undefined => {
- const link_relationshipList = StrListCast(Doc.UserDoc().link_relationshipList);
+ const linkRelationshipList = StrListCast(Doc.UserDoc().link_relationshipList);
const linkColorList = StrListCast(Doc.UserDoc().link_ColorList);
let color: string | undefined;
// if this link's relationship property is not default "link", set its color
- if (link_relationshipList) {
- const relationshipIndex = link_relationshipList.indexOf(this.props.groupType);
+ if (linkRelationshipList) {
+ const relationshipIndex = linkRelationshipList.indexOf(this.props.groupType);
const RGBcolor: string = linkColorList[relationshipIndex];
if (RGBcolor) {
- //set opacity to 0.25 by modifiying the rgb string
+ // set opacity to 0.25 by modifiying the rgb string
color = RGBcolor.slice(0, RGBcolor.length - 1) + ', 0.25)';
}
}
return color;
};
- @observable _collapsed = false;
-
render() {
const set = new Set<Doc>(this.props.group);
const groupItems = Array.from(set.keys()).map(linkDoc => {
@@ -57,8 +58,7 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
? this.props.docView._props.LayoutTemplateString?.includes('link_anchor_1')
? DocCast(linkDoc.link_anchor_2)
: DocCast(linkDoc.link_anchor_1)
- : LinkManager.getOppositeAnchor(linkDoc, sourceDoc) ||
- LinkManager.getOppositeAnchor(linkDoc, Cast(linkDoc.link_anchor_2, Doc, null).annotationOn === sourceDoc ? Cast(linkDoc.link_anchor_2, Doc, null) : Cast(linkDoc.link_anchor_1, Doc, null));
+ : Doc.getOppositeAnchor(linkDoc, sourceDoc) || Doc.getOppositeAnchor(linkDoc, Cast(linkDoc.link_anchor_2, Doc, null)?.annotationOn === sourceDoc ? Cast(linkDoc.link_anchor_2, Doc, null) : Cast(linkDoc.link_anchor_1, Doc, null));
return !destDoc || !sourceDoc ? null : (
<LinkMenuItem
key={linkDoc[Id]}
@@ -76,7 +76,12 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
return (
<div className="linkMenu-group" ref={this._menuRef}>
- <div className="linkMenu-group-name" onClick={action(() => (this._collapsed = !this._collapsed))} style={{ background: this.getBackgroundColor() }}>
+ <div
+ className="linkMenu-group-name"
+ onClick={action(() => {
+ this._collapsed = !this._collapsed;
+ })}
+ style={{ background: this.getBackgroundColor() }}>
<p className={this.props.groupType === '*' || this.props.groupType === '' ? '' : 'expand-one'}> {this.props.groupType}:</p>
</div>
{this._collapsed ? null : <div className="linkMenu-group-wrapper">{groupItems}</div>}
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 81dd0eb98..9ce04ffac 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -1,24 +1,25 @@
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
+/* 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 } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils';
+import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { Doc } from '../../../fields/Doc';
import { Cast, DocCast, StrCast } from '../../../fields/Types';
import { WebField } from '../../../fields/URLField';
import { DocumentType } from '../../documents/DocumentTypes';
-import { DocumentManager } from '../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../util/DragManager';
-import { LinkFollower } from '../../util/LinkFollower';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
import { LinkManager } from '../../util/LinkManager';
-import { SelectionManager } from '../../util/SelectionManager';
-import { SettingsManager } from '../../util/SettingsManager';
+import { SnappingManager } from '../../util/SnappingManager';
import { undoBatch } from '../../util/UndoManager';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { DocumentView, DocumentViewInternal, OpenWhere } from '../nodes/DocumentView';
+import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
import { LinkInfo } from '../nodes/LinkDocPreview';
+import { OpenWhere } from '../nodes/OpenWhere';
import './LinkMenuItem.scss';
interface LinkMenuItemProps {
@@ -34,14 +35,14 @@ interface LinkMenuItemProps {
// drag links and drop link targets (embedding them if needed)
export async function StartLinkTargetsDrag(dragEle: HTMLElement, docView: DocumentView, downX: number, downY: number, sourceDoc: Doc, specificLinks?: Doc[]) {
- const draggedDocs = (specificLinks ? specificLinks : LinkManager.Links(sourceDoc)).map(link => LinkManager.getOppositeAnchor(link, sourceDoc)).filter(l => l) as Doc[];
+ const draggedDocs = (specificLinks || LinkManager.Links(sourceDoc)).map(link => Doc.getOppositeAnchor(link, sourceDoc)).filter(l => l) as Doc[];
if (draggedDocs.length) {
const moddrag: Doc[] = [];
- for (const draggedDoc of draggedDocs) {
+ draggedDocs.forEach(async draggedDoc => {
const doc = await Cast(draggedDoc.annotationOn, Doc);
if (doc) moddrag.push(doc);
- }
+ });
const dragData = new DragManager.DocumentDragData(moddrag.length ? moddrag : draggedDocs);
dragData.canEmbed = true;
@@ -77,7 +78,7 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
onIconDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, returnFalse, returnFalse, () => {
- const ancestor = DocumentManager.LinkCommonAncestor(this._props.linkDoc);
+ const ancestor = DocumentView.linkCommonAncestor(this._props.linkDoc);
if (!ancestor?.ComponentView?.removeDocument?.(this._props.linkDoc)) {
ancestor?.ComponentView?.addDocument?.(this._props.linkDoc);
}
@@ -88,10 +89,10 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
setupMoveUpEvents(
this,
e,
- e => {
+ moveEv => {
const dragData = new DragManager.DocumentDragData([this._props.linkDoc], dropActionType.embed);
dragData.dropPropertiesToRemove = ['hidden'];
- DragManager.StartDocumentDrag([this._editRef.current!], dragData, e.x, e.y);
+ DragManager.StartDocumentDrag([this._editRef.current!], dragData, moveEv.x, moveEv.y);
return true;
},
emptyFunction,
@@ -101,12 +102,16 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
Doc.ActivePresentation = trail;
DocumentViewInternal.addDocTabFunc(trail, OpenWhere.replaceRight);
} else {
- SelectionManager.SelectView(this._props.docView, false);
+ DocumentView.SelectView(this._props.docView, false);
LinkManager.Instance.currentLink = this._props.linkDoc === LinkManager.Instance.currentLink ? undefined : this._props.linkDoc;
LinkManager.Instance.currentLinkAnchor = LinkManager.Instance.currentLink ? this.sourceAnchor : undefined;
- if ((SettingsManager.Instance.propertiesWidth ?? 0) < 100) {
- setTimeout(action(() => (SettingsManager.Instance.propertiesWidth = 250)));
+ if ((SnappingManager.PropertiesWidth ?? 0) < 100) {
+ setTimeout(
+ action(() => {
+ SnappingManager.SetPropertiesWidth(250);
+ })
+ );
}
}
})
@@ -117,11 +122,13 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
setupMoveUpEvents(
this,
e,
- e => {
- const eleClone: any = this._drag.current!.cloneNode(true);
- eleClone.style.transform = `translate(${e.x}px, ${e.y}px)`;
- StartLinkTargetsDrag(eleClone, this._props.docView, e.x, e.y, this._props.sourceDoc, [this._props.linkDoc]);
- this._props.clearLinkEditor?.();
+ moveEv => {
+ const eleClone: any = this._drag.current?.cloneNode(true);
+ if (eleClone) {
+ eleClone.style.transform = `translate(${moveEv.x}px, ${moveEv.y}px)`;
+ StartLinkTargetsDrag(eleClone, this._props.docView, moveEv.x, moveEv.y, this._props.sourceDoc, [this._props.linkDoc]);
+ this._props.clearLinkEditor?.();
+ }
return true;
},
emptyFunction,
@@ -138,17 +145,17 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
: undefined;
if (focusDoc) this._props.docView._props.focus(focusDoc, { instant: true });
- LinkFollower.FollowLink(this._props.linkDoc, this._props.sourceDoc, false);
+ DocumentView.FollowLink(this._props.linkDoc, this._props.sourceDoc, false);
}
}
);
};
- deleteLink = (e: React.PointerEvent): void => setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => LinkManager.Instance.deleteLink(this._props.linkDoc))));
+ deleteLink = (e: React.PointerEvent): void => setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => Doc.DeleteLink?.(this._props.linkDoc))));
@observable _hover = false;
docView = () => this._props.docView;
render() {
- const destinationIcon = Doc.toIcon(this._props.destinationDoc) as any as IconProp;
+ const destinationIcon = Doc.toIcon(this._props.destinationDoc);
const title = StrCast(this._props.destinationDoc.title).length > 18 ? StrCast(this._props.destinationDoc.title).substr(0, 14) + '...' : this._props.destinationDoc.title;
@@ -164,26 +171,30 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
return (
<div
className="linkMenu-item"
- onPointerEnter={action(e => (this._hover = true))}
- onPointerLeave={action(e => (this._hover = false))}
+ onPointerEnter={action(() => {
+ this._hover = true;
+ })}
+ onPointerLeave={action(() => {
+ this._hover = false;
+ })}
style={{
fontSize: this._hover ? 'larger' : undefined,
fontWeight: this._hover ? 'bold' : undefined,
- background: LinkManager.Instance.currentLink === this._props.linkDoc ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor,
+ background: LinkManager.Instance.currentLink === this._props.linkDoc ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
}}>
<div className="linkMenu-item-content expand-two">
<div
ref={this._drag}
- className="linkMenu-name" //title="drag to view target. click to customize."
+ className="linkMenu-name" // title="drag to view target. click to customize."
onPointerDown={this.onLinkButtonDown}>
<div className="linkMenu-item-buttons">
- <Tooltip disableInteractive={true} title={<div className="dash-tooltip">Edit Link</div>}>
+ <Tooltip disableInteractive title={<div className="dash-tooltip">Edit Link</div>}>
<div className="linkMenu-icon-wrapper" ref={this._editRef} onPointerDown={this.onEdit} onClick={e => e.stopPropagation()}>
<FontAwesomeIcon className="linkMenu-icon" icon="edit" size="sm" />
</div>
</Tooltip>
- <Tooltip disableInteractive={true} title={<div className="dash-tooltip">Show/Hide Link</div>}>
- <div title="click to show link" className="linkMenu-icon-wrapper" onPointerDown={this.onIconDown}>
+ <Tooltip disableInteractive title={<div className="dash-tooltip">Show/Hide Link</div>}>
+ <div className="linkMenu-icon-wrapper" onPointerDown={this.onIconDown}>
<FontAwesomeIcon className="linkMenu-icon" icon={destinationIcon} size="sm" />
</div>
</Tooltip>
@@ -211,7 +222,7 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
</p>
) : null}
<div className="linkMenu-title-wrapper">
- <Tooltip disableInteractive={true} title={<div className="dash-tooltip">Follow Link</div>}>
+ <Tooltip disableInteractive title={<div className="dash-tooltip">Follow Link</div>}>
<p className="linkMenu-destination-title">
{this._props.linkDoc.linksToAnnotation && Cast(this._props.destinationDoc.data, WebField)?.url.href === this._props.linkDoc.annotationUri ? 'Annotation in' : ''} {StrCast(title)}
</p>
@@ -221,7 +232,7 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
</div>
<div className="linkMenu-item-buttons">
- <Tooltip disableInteractive={true} title={<div className="dash-tooltip">Delete Link</div>}>
+ <Tooltip disableInteractive title={<div className="dash-tooltip">Delete Link</div>}>
<div className="linkMenu-deleteButton" onPointerDown={this.deleteLink} onClick={e => e.stopPropagation()}>
<FontAwesomeIcon className="fa-icon" icon="trash" size="sm" />
</div>
diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx
index c9e3c203d..76a8396ff 100644
--- a/src/client/views/linking/LinkPopup.tsx
+++ b/src/client/views/linking/LinkPopup.tsx
@@ -1,14 +1,11 @@
-import { action, observable } from 'mobx';
+/* eslint-disable react/require-default-props */
import { observer } from 'mobx-react';
-import { EditorView } from 'prosemirror-view';
import * as React from 'react';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { Doc } from '../../../fields/Doc';
import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
-import { DefaultStyleProvider } from '../StyleProvider';
-import { OpenWhere, returnEmptyDocViewList } from '../nodes/DocumentView';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
+import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider';
import { SearchBox } from '../search/SearchBox';
import './LinkPopup.scss';
@@ -28,16 +25,6 @@ interface LinkPopupProps {
@observer
export class LinkPopup extends React.Component<LinkPopupProps> {
- @observable private linkURL: string = '';
- @observable public view?: EditorView = undefined;
-
- // TODO: should check for valid URL
- @undoBatch
- makeLinkToURL = (target: string, lcoation: string) => ((this.view as any)?.TextView as FormattedTextBox).makeLinkAnchor(undefined, OpenWhere.addRight, target, target);
-
- @action
- onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => (this.linkURL = e.target.value);
-
getPWidth = () => 500;
getPHeight = () => 500;
@@ -64,7 +51,7 @@ export class LinkPopup extends React.Component<LinkPopupProps> {
docViewPath={returnEmptyDocViewList}
linkFrom={linkDoc}
linkCreateAnchor={this.props.linkCreateAnchor}
- linkSearch={true}
+ linkSearch
linkCreated={this.props.linkCreated}
fieldKey="data"
isSelected={returnTrue}
diff --git a/src/client/views/linking/LinkRelationshipSearch.tsx b/src/client/views/linking/LinkRelationshipSearch.tsx
deleted file mode 100644
index 0902d53b2..000000000
--- a/src/client/views/linking/LinkRelationshipSearch.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import './LinkEditor.scss';
-
-interface link_relationshipSearchProps {
- results: string[] | undefined;
- display: string;
- //callback fn to set rel + hide dropdown upon setting
- handleRelationshipSearchChange: (result: string) => void;
- toggleSearch: () => void;
-}
-@observer
-export class link_relationshipSearch extends React.Component<link_relationshipSearchProps> {
- handleResultClick = (e: React.MouseEvent) => {
- const relationship = (e.target as HTMLParagraphElement).textContent;
- if (relationship) {
- this.props.handleRelationshipSearchChange(relationship);
- }
- };
-
- handleMouseEnter = () => {
- this.props.toggleSearch();
- };
-
- handleMouseLeave = () => {
- this.props.toggleSearch();
- };
-
- /**
- * Render an empty div to increase the height of LinkEditor to accommodate 2+ results
- */
- emptyDiv = () => {
- if (this.props.results && this.props.results.length > 2 && this.props.display === 'block') {
- return <div style={{ height: '50px' }} />;
- }
- };
-
- render() {
- return (
- <div className="linkEditor-relationship-dropdown-container">
- <div className="linkEditor-relationship-dropdown" style={{ display: this.props.display }} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
- {
- // return a dropdown of relationship results if there exist results
- this.props.results ? (
- this.props.results.map(result => {
- return (
- <p key={result} onClick={this.handleResultClick}>
- {result}
- </p>
- );
- })
- ) : (
- <p>No matching relationships</p>
- )
- }
- </div>
-
- {/*Render an empty div to increase the height of LinkEditor to accommodate 2+ results */}
- {this.emptyDiv()}
- </div>
- );
- }
-}
diff --git a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
index bce2b296f..3eb99f47a 100644
--- a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
+++ b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
@@ -1,34 +1,37 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action } from 'mobx';
import * as React from 'react';
import { Doc } from '../../../../fields/Doc';
import { InkTool } from '../../../../fields/InkField';
-import { SelectionManager } from '../../../util/SelectionManager';
import { SnappingManager } from '../../../util/SnappingManager';
import { CollectionDockingView } from '../../collections/CollectionDockingView';
-import { OpenWhereMod } from '../../nodes/DocumentView';
+import { DocumentView } from '../../nodes/DocumentView';
+import { OpenWhereMod } from '../../nodes/OpenWhere';
import { NewLightboxView } from '../NewLightboxView';
import './ButtonMenu.scss';
-import { IButtonMenu } from './utils';
-export const ButtonMenu = (props: IButtonMenu) => {
+export function ButtonMenu() {
return (
- <div className={`newLightboxButtonMenu-container`}>
+ <div className="newLightboxButtonMenu-container">
<div
className="newLightboxView-navBtn"
title="toggle fit width"
onClick={e => {
e.stopPropagation();
NewLightboxView.LightboxDoc!._fitWidth = !NewLightboxView.LightboxDoc!._fitWidth;
- }}></div>
+ }}
+ />
<div
className="newLightboxView-tabBtn"
title="open in tab"
onClick={e => {
e.stopPropagation();
CollectionDockingView.AddSplit(NewLightboxView.LightboxDoc || NewLightboxView.LightboxDoc!, OpenWhereMod.none);
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
NewLightboxView.SetNewLightboxDoc(undefined);
- }}></div>
+ }}
+ />
<div
className="newLightboxView-penBtn"
title="toggle pen annotation"
@@ -36,7 +39,8 @@ export const ButtonMenu = (props: IButtonMenu) => {
onClick={e => {
e.stopPropagation();
Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen;
- }}></div>
+ }}
+ />
<div
className="newLightboxView-exploreBtn"
title="toggle explore mode to navigate among documents only"
@@ -44,7 +48,8 @@ export const ButtonMenu = (props: IButtonMenu) => {
onClick={action(e => {
e.stopPropagation();
SnappingManager.SetExploreMode(!SnappingManager.ExploreMode);
- })}></div>
+ })}
+ />
</div>
);
-};
+}
diff --git a/src/client/views/newlightbox/ExploreView/ExploreView.tsx b/src/client/views/newlightbox/ExploreView/ExploreView.tsx
index a1d6375c4..f8c07cc43 100644
--- a/src/client/views/newlightbox/ExploreView/ExploreView.tsx
+++ b/src/client/views/newlightbox/ExploreView/ExploreView.tsx
@@ -1,32 +1,34 @@
-import './ExploreView.scss';
-import { IBounds, IExploreView, emptyBounds } from './utils';
-import { IRecommendation } from '../components';
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import * as React from 'react';
-import { NewLightboxView } from '../NewLightboxView';
import { StrCast } from '../../../../fields/Types';
+import { NewLightboxView } from '../NewLightboxView';
+import './ExploreView.scss';
+import { IExploreView, emptyBounds } from './utils';
-export const ExploreView = (props: IExploreView) => {
+export function ExploreView(props: IExploreView) {
const { recs, bounds = emptyBounds } = props;
return (
- <div className={`exploreView-container`}>
+ <div className="exploreView-container">
{recs &&
recs.map(rec => {
- const x_bound: number = Math.max(Math.abs(bounds.max_x), Math.abs(bounds.min_x));
- const y_bound: number = Math.max(Math.abs(bounds.max_y), Math.abs(bounds.min_y));
+ const xBound: number = Math.max(Math.abs(bounds.max_x), Math.abs(bounds.min_x));
+ const yBound: number = Math.max(Math.abs(bounds.max_y), Math.abs(bounds.min_y));
if (rec.embedding) {
- const x = (rec.embedding.x / x_bound) * 50;
- const y = (rec.embedding.y / y_bound) * 50;
+ const x = (rec.embedding.x / xBound) * 50;
+ const y = (rec.embedding.y / yBound) * 50;
return (
- <div className={`exploreView-doc`} onClick={() => {}} style={{ top: `calc(50% + ${y}%)`, left: `calc(50% + ${x}%)` }}>
+ <div className="exploreView-doc" onClick={() => {}} style={{ top: `calc(50% + ${y}%)`, left: `calc(50% + ${x}%)` }}>
{rec.title}
</div>
);
- } else return null;
+ }
+ return null;
})}
- <div className={`exploreView-doc`} style={{ top: `calc(50% + ${0}%)`, left: `calc(50% + ${0}%)`, background: '#073763', color: 'white' }}>
+ <div className="exploreView-doc" style={{ top: `calc(50% + ${0}%)`, left: `calc(50% + ${0}%)`, background: '#073763', color: 'white' }}>
{StrCast(NewLightboxView.LightboxDoc?.title)}
</div>
</div>
);
-};
+}
diff --git a/src/client/views/newlightbox/ExploreView/index.ts b/src/client/views/newlightbox/ExploreView/index.ts
index bf94eedcd..f2ebf511f 100644
--- a/src/client/views/newlightbox/ExploreView/index.ts
+++ b/src/client/views/newlightbox/ExploreView/index.ts
@@ -1 +1 @@
-export * from './ExploreView' \ No newline at end of file
+export * from './ExploreView';
diff --git a/src/client/views/newlightbox/ExploreView/utils.ts b/src/client/views/newlightbox/ExploreView/utils.ts
index 7d9cf226d..2d1bd75a9 100644
--- a/src/client/views/newlightbox/ExploreView/utils.ts
+++ b/src/client/views/newlightbox/ExploreView/utils.ts
@@ -1,20 +1,21 @@
-import { IRecommendation } from "../components";
+import { IRecommendation } from '../components';
export interface IExploreView {
- recs?: IRecommendation[],
- bounds?: IBounds
+ recs?: IRecommendation[];
+ // eslint-disable-next-line no-use-before-define
+ bounds?: IBounds;
}
export const emptyBounds = {
max_x: 0,
max_y: 0,
min_x: 0,
- min_y: 0
-}
+ min_y: 0,
+};
export interface IBounds {
- max_x: number,
- max_y: number,
- min_x: number,
- min_y: number
-} \ No newline at end of file
+ max_x: number;
+ max_y: number;
+ min_x: number;
+ min_y: number;
+}
diff --git a/src/client/views/newlightbox/Header/LightboxHeader.tsx b/src/client/views/newlightbox/Header/LightboxHeader.tsx
index a272ce294..882d28fba 100644
--- a/src/client/views/newlightbox/Header/LightboxHeader.tsx
+++ b/src/client/views/newlightbox/Header/LightboxHeader.tsx
@@ -1,62 +1,59 @@
-import './LightboxHeader.scss';
+import { Button, IconButton, Size, Type } from 'browndash-components';
import * as React from 'react';
-import { INewLightboxHeader } from "./utils";
-import { NewLightboxView } from '../NewLightboxView';
+import { BsBookmark, BsBookmarkFill } from 'react-icons/bs';
+import { MdTravelExplore } from 'react-icons/md';
+import { Doc } from '../../../../fields/Doc';
import { StrCast } from '../../../../fields/Types';
+import { Colors } from '../../global/globalEnums';
+import { DocumentView } from '../../nodes/DocumentView';
+import { NewLightboxView } from '../NewLightboxView';
import { EditableText } from '../components/EditableText';
import { getType } from '../utils';
-import { Button, IconButton, Size, Type } from 'browndash-components';
-import { MdExplore, MdTravelExplore } from 'react-icons/md'
-import { BsBookmark, BsBookmarkFill } from 'react-icons/bs'
-import { Doc } from '../../../../fields/Doc';
-import { LightboxView } from '../../LightboxView';
-import { Colors } from '../../global/globalEnums';
-
+import './LightboxHeader.scss';
+import { INewLightboxHeader } from './utils';
-export const NewLightboxHeader = (props: INewLightboxHeader) => {
- const {height = 100, width} = props;
- const [doc, setDoc] = React.useState<Doc | undefined>(LightboxView.LightboxDoc)
- const [editing, setEditing] = React.useState<boolean>(false)
- const [title, setTitle] = React.useState<JSX.Element | null>(
- (null)
- )
+export function NewLightboxHeader(props: INewLightboxHeader) {
+ const { height = 100, width } = props;
+ const [doc, setDoc] = React.useState<Doc | undefined>(DocumentView.LightboxDoc());
+ const [editing, setEditing] = React.useState<boolean>(false);
+ const [title, setTitle] = React.useState<JSX.Element | null>(null);
React.useEffect(() => {
- let lbDoc = LightboxView.LightboxDoc
- setDoc(lbDoc)
+ const lbDoc = DocumentView.LightboxDoc();
+ setDoc(lbDoc);
if (lbDoc) {
setTitle(
- <EditableText
- editing={editing}
- text={StrCast(lbDoc.title)}
- onEdit={(newText: string) => {
- if(lbDoc) lbDoc.title = newText;
- }}
- setEditing={setEditing}
- />)
+ <EditableText
+ editing={editing}
+ text={StrCast(lbDoc.title)}
+ onEdit={(newText: string) => {
+ if (lbDoc) lbDoc.title = newText;
+ }}
+ setEditing={setEditing}
+ />
+ );
}
- }, [LightboxView.LightboxDoc])
+ }, [DocumentView.LightboxDoc()]);
- const [saved, setSaved] = React.useState<boolean>(false)
+ const [saved, setSaved] = React.useState<boolean>(false);
- if (!doc) return null
- else return <div className={`newLightboxHeader-container`} onPointerDown={(e) => e.stopPropagation()} style={{ minHeight: height, height: height, width: width }}>
- <div className={`title-container`}>
- <div className={`lb-label`}>Title</div>
- {title}
- </div>
- <div className={`type-container`}>
- <div className={`lb-label`}>Type</div>
- <div className={`type`}>{getType(StrCast(doc.type))}</div>
- </div>
- <div style={{gridColumn: 2, gridRow: 1, height: '100%', display: 'flex', justifyContent: 'flex-end', alignItems: 'center'}}>
- <IconButton size={Size.XSMALL} onClick={() => setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? <BsBookmarkFill/> : <BsBookmark/>}/>
- <IconButton size={Size.XSMALL} onClick={() => setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? <BsBookmarkFill/> : <BsBookmark/>}/>
- </div>
- <div style={{gridColumn: 2, gridRow: 2, height: '100%', display: 'flex', justifyContent: 'flex-end', alignItems: 'center'}}>
- <Button onClick={() => {
- console.log(NewLightboxView.ExploreMode)
- NewLightboxView.SetExploreMode(!NewLightboxView.ExploreMode)
- }} size={Size.XSMALL} color={Colors.DARK_GRAY} type={Type.SEC} text={"t-SNE 2D Embeddings"} icon={<MdTravelExplore/>}/>
+ if (!doc) return null;
+ return (
+ <div className="newLightboxHeader-container" onPointerDown={e => e.stopPropagation()} style={{ minHeight: height, height: height, width: width }}>
+ <div className="title-container">
+ <div className="lb-label">Title</div>
+ {title}
+ </div>
+ <div className="type-container">
+ <div className="lb-label">Type</div>
+ <div className="type">{getType(StrCast(doc.type))}</div>
+ </div>
+ <div style={{ gridColumn: 2, gridRow: 1, height: '100%', display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
+ <IconButton size={Size.XSMALL} onClick={() => setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? <BsBookmarkFill /> : <BsBookmark />} />
+ <IconButton size={Size.XSMALL} onClick={() => setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? <BsBookmarkFill /> : <BsBookmark />} />
+ </div>
+ <div style={{ gridColumn: 2, gridRow: 2, height: '100%', display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
+ <Button onClick={() => NewLightboxView.SetExploreMode(!NewLightboxView.ExploreMode)} size={Size.XSMALL} color={Colors.DARK_GRAY} type={Type.SEC} text="t-SNE 2D Embeddings" icon={<MdTravelExplore />} />
+ </div>
</div>
- </div>
-} \ No newline at end of file
+ );
+}
diff --git a/src/client/views/newlightbox/Header/index.ts b/src/client/views/newlightbox/Header/index.ts
index 090677c16..88a533585 100644
--- a/src/client/views/newlightbox/Header/index.ts
+++ b/src/client/views/newlightbox/Header/index.ts
@@ -1 +1 @@
-export * from './LightboxHeader' \ No newline at end of file
+export * from './LightboxHeader';
diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx
index 12b9870ca..c86ddb745 100644
--- a/src/client/views/newlightbox/NewLightboxView.tsx
+++ b/src/client/views/newlightbox/NewLightboxView.tsx
@@ -1,23 +1,19 @@
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../../Utils';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
+import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc';
import { InkTool } from '../../../fields/InkField';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { DocUtils } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
-import { LinkManager } from '../../util/LinkManager';
-import { SelectionManager } from '../../util/SelectionManager';
+import { Cast, NumCast, StrCast, toList } from '../../../fields/Types';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { GestureOverlay } from '../GestureOverlay';
-import { LightboxView } from '../LightboxView';
import { DefaultStyleProvider } from '../StyleProvider';
-import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline';
-import { TabDocView } from '../collections/TabDocView';
-import { DocumentView, OpenWhere } from '../nodes/DocumentView';
+import { DocumentView } from '../nodes/DocumentView';
+import { OpenWhere } from '../nodes/OpenWhere';
import { ExploreView } from './ExploreView';
import { IBounds, emptyBounds } from './ExploreView/utils';
import { NewLightboxHeader } from './Header';
@@ -25,11 +21,11 @@ import './NewLightboxView.scss';
import { RecommendationList } from './RecommendationList';
import { IRecommendation } from './components';
-enum LightboxStatus {
- RECOMMENDATIONS = 'recommendations',
- ANNOTATIONS = 'annotations',
- NONE = 'none',
-}
+// enum LightboxStatus {
+// RECOMMENDATIONS = 'recommendations',
+// ANNOTATIONS = 'annotations',
+// NONE = 'none',
+// }
interface LightboxViewProps {
PanelWidth: number;
@@ -46,10 +42,6 @@ type LightboxSavedState = {
};
@observer
export class NewLightboxView extends React.Component<LightboxViewProps> {
- @computed public static get LightboxDoc() {
- return this._doc;
- }
- private static LightboxDocTemplate = () => NewLightboxView._layoutTemplate;
@observable private static _layoutTemplate: Opt<Doc> = undefined;
@observable private static _layoutTemplateString: Opt<string> = undefined;
@observable private static _doc: Opt<Doc> = undefined;
@@ -62,59 +54,39 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
// keywords
@observable private static _keywords: string[] = [];
- @action public static SetKeywords(kw: string[]) {
- this._keywords = kw;
- }
- @computed public static get Keywords() {
- return this._keywords;
- }
-
- // query
@observable private static _query: string = '';
- @action public static SetQuery(query: string) {
- this._query = query;
- }
- @computed public static get Query() {
- return this._query;
- }
-
- // keywords
@observable private static _recs: IRecommendation[] = [];
- @action public static SetRecs(recs: IRecommendation[]) {
- this._recs = recs;
- }
- @computed public static get Recs() {
- return this._recs;
- }
-
- // bounds
@observable private static _bounds: IBounds = emptyBounds;
- @action public static SetBounds(bounds: IBounds) {
- this._bounds = bounds;
- }
- @computed public static get Bounds() {
- return this._bounds;
- }
-
- // explore
@observable private static _explore: Opt<boolean> = false;
- @action public static SetExploreMode(status: Opt<boolean>) {
- this._explore = status;
- }
- @computed public static get ExploreMode() {
- return this._explore;
- }
-
- // newLightbox sidebar status
@observable private static _sidebarStatus: Opt<string> = '';
- @action public static SetSidebarStatus(sidebarStatus: Opt<string>) {
- this._sidebarStatus = sidebarStatus;
+ static path: { doc: Opt<Doc>; target: Opt<Doc>; history: Opt<{ doc: Doc; target?: Doc }[]>; future: Opt<Doc[]>; saved: Opt<LightboxSavedState> }[] = [];
+ private static LightboxDocTemplate = () => NewLightboxView._layoutTemplate;
+ public static GetSavedState(doc: Doc) {
+ return this.LightboxDoc === doc && this._savedState ? this._savedState : undefined;
}
- @computed public static get SidebarStatus() {
- return this._sidebarStatus;
+ // adds a cookie to the newLightbox view - the cookie becomes part of a filter which will display any documents whose cookie metadata field matches this cookie
+ @action
+ public static SetCookie(cookie: string) {
+ if (this.LightboxDoc && cookie) {
+ this._docFilters = (f => (this._docFilters ? [this._docFilters.push(f) as any, this._docFilters][1] : [f]))(`cookies:${cookie}:provide`);
+ }
}
+ public static AddDocTab = (docsIn: Doc | Doc[], location: OpenWhere, layoutTemplate?: Doc | string) => {
+ DocumentView.DeselectAll();
+ const doc = toList(docsIn).lastElement();
+ return (
+ doc &&
+ NewLightboxView.SetNewLightboxDoc(
+ doc,
+ undefined,
+ [...DocListCast(doc[Doc.LayoutFieldKey(doc)]), ...DocListCast(doc[Doc.LayoutFieldKey(doc) + '_annotations']).filter(anno => anno.annotationOn !== doc), ...(NewLightboxView._future ?? [])].sort(
+ (a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)
+ ),
+ layoutTemplate
+ )
+ );
+ };
- static path: { doc: Opt<Doc>; target: Opt<Doc>; history: Opt<{ doc: Doc; target?: Doc }[]>; future: Opt<Doc[]>; saved: Opt<LightboxSavedState> }[] = [];
@action public static SetNewLightboxDoc(doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) {
if (this.LightboxDoc && this.LightboxDoc !== doc && this._savedState) {
if (this._savedState.panX !== undefined) this.LightboxDoc._freeform_panX = this._savedState.panX;
@@ -129,12 +101,12 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
Doc.ActiveTool = InkTool.None;
SnappingManager.SetExploreMode(false);
} else {
- const l = DocUtils.MakeLinkToActiveAudio(() => doc).lastElement();
+ const l = CreateLinkToActiveAudio(() => doc).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
- CollectionStackedTimeline.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
- //TabDocView.PinDoc(doc, { hidePresBox: true });
+ DocumentView.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
+ // DocumentView.PinDoc(doc, { hidePresBox: true });
this._history ? this._history.push({ doc, target }) : (this._history = [{ doc, target }]);
- if (doc !== LightboxView.LightboxDoc) {
+ if (doc !== DocumentView.LightboxDoc()) {
this._savedState = {
layout_fieldKey: StrCast(doc.layout_fieldKey),
panX: Cast(doc.freeform_panX, 'number', null),
@@ -151,7 +123,7 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
...future
.slice()
.sort((a, b) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow))
- .sort((a, b) => LinkManager.Links(a).length - LinkManager.Links(b).length),
+ .sort((a, b) => Doc.Links(a).length - Doc.Links(b).length),
];
}
this._doc = doc;
@@ -166,85 +138,34 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
public static IsNewLightboxDocView(path: DocumentView[]) {
return (path ?? []).includes(this._docView!);
}
- @computed get leftBorder() {
- return Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]);
- }
- @computed get topBorder() {
- return Math.min(this.props.PanelHeight / 4, this.props.maxBorder[1]);
- }
- newLightboxWidth = () => this.props.PanelWidth - 420;
- newLightboxHeight = () => this.props.PanelHeight - 140;
- newLightboxScreenToLocal = () => new Transform(-this.leftBorder, -this.topBorder, 1);
- navBtn = (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: string, display: () => string, click: (e: React.MouseEvent) => void, color?: string) => {
- return (
- <div
- className="newLightboxView-navBtn-frame"
- style={{
- display: display(),
- left,
- width: bottom !== undefined ? undefined : Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]),
- bottom,
- }}>
- <div className="newLightboxView-navBtn" title={color} style={{ top, color: color ? 'red' : 'white', background: color ? 'white' : undefined }} onClick={click}>
- <div style={{ height: 10 }}>{color}</div>
- <FontAwesomeIcon icon={icon as any} size="3x" />
- </div>
- </div>
- );
- };
- public static GetSavedState(doc: Doc) {
- return this.LightboxDoc === doc && this._savedState ? this._savedState : undefined;
- }
-
- // adds a cookie to the newLightbox view - the cookie becomes part of a filter which will display any documents whose cookie metadata field matches this cookie
- @action
- public static SetCookie(cookie: string) {
- if (this.LightboxDoc && cookie) {
- this._docFilters = (f => (this._docFilters ? [this._docFilters.push(f) as any, this._docFilters][1] : [f]))(`cookies:${cookie}:provide`);
- }
- }
- public static AddDocTab = (doc: Doc, location: OpenWhere, layoutTemplate?: Doc | string) => {
- SelectionManager.DeselectAll();
- return NewLightboxView.SetNewLightboxDoc(
- doc,
- undefined,
- [...DocListCast(doc[Doc.LayoutFieldKey(doc)]), ...DocListCast(doc[Doc.LayoutFieldKey(doc) + '_annotations']).filter(anno => anno.annotationOn !== doc), ...(NewLightboxView._future ?? [])].sort(
- (a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)
- ),
- layoutTemplate
- );
- };
- docFilters = () => NewLightboxView._docFilters || [];
- addDocTab = NewLightboxView.AddDocTab;
@action public static Next() {
const doc = NewLightboxView._doc!;
const target = (NewLightboxView._docTarget = this._future?.pop());
- const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target);
+ const targetDocView = target && DocumentView.getLightboxDocumentView(target);
if (targetDocView && target) {
- const l = DocUtils.MakeLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
+ const l = CreateLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
- DocumentManager.Instance.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
+ DocumentView.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
if (NewLightboxView._history?.lastElement().target !== target) NewLightboxView._history?.push({ doc, target });
- } else {
- if (!target && NewLightboxView.path.length) {
- const saved = NewLightboxView._savedState;
- if (LightboxView.LightboxDoc && saved) {
- LightboxView.LightboxDoc._freeform_panX = saved.panX;
- LightboxView.LightboxDoc._freeform_panY = saved.panY;
- LightboxView.LightboxDoc._freeform_scale = saved.scale;
- LightboxView.LightboxDoc._layout_scrollTop = saved.scrollTop;
- }
- const pop = NewLightboxView.path.pop();
- if (pop) {
- NewLightboxView._doc = pop.doc;
- NewLightboxView._docTarget = pop.target;
- NewLightboxView._future = pop.future;
- NewLightboxView._history = pop.history;
- NewLightboxView._savedState = pop.saved;
- }
- } else {
- NewLightboxView.SetNewLightboxDoc(target);
+ } else if (!target && NewLightboxView.path.length) {
+ const saved = NewLightboxView._savedState;
+ const lightboxDoc = DocumentView.LightboxDoc();
+ if (lightboxDoc && saved) {
+ lightboxDoc._freeform_panX = saved.panX;
+ lightboxDoc._freeform_panY = saved.panY;
+ lightboxDoc._freeform_scale = saved.scale;
+ lightboxDoc._layout_scrollTop = saved.scrollTop;
+ }
+ const pop = NewLightboxView.path.pop();
+ if (pop) {
+ NewLightboxView._doc = pop.doc;
+ NewLightboxView._docTarget = pop.target;
+ NewLightboxView._future = pop.future;
+ NewLightboxView._history = pop.history;
+ NewLightboxView._savedState = pop.saved;
}
+ } else {
+ NewLightboxView.SetNewLightboxDoc(target);
}
}
@@ -254,76 +175,120 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
NewLightboxView.SetNewLightboxDoc(undefined);
return;
}
- const { doc, target } = NewLightboxView._history?.lastElement();
- const docView = DocumentManager.Instance.getLightboxDocumentView(target || doc);
+ const { doc, target } = NewLightboxView._history?.lastElement() ?? { doc: undefined, target: undefined };
+ const docView = DocumentView.getLightboxDocumentView(target || doc);
if (docView) {
NewLightboxView._docTarget = target;
- target && DocumentManager.Instance.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
+ target && DocumentView.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
} else {
NewLightboxView.SetNewLightboxDoc(doc, target);
}
if (NewLightboxView._future?.lastElement() !== previous.target || previous.doc) NewLightboxView._future?.push(previous.target || previous.doc);
}
- @action
- stepInto = () => {
- NewLightboxView.path.push({
- doc: LightboxView.LightboxDoc,
- target: NewLightboxView._docTarget,
- future: NewLightboxView._future,
- history: NewLightboxView._history,
- saved: NewLightboxView._savedState,
- });
- const coll = NewLightboxView._docTarget;
- if (coll) {
- const fieldKey = Doc.LayoutFieldKey(coll);
- const contents = [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + '_annotations'])];
- const links = LinkManager.Links(coll)
- .map(link => LinkManager.getOppositeAnchor(link, coll))
- .filter(doc => doc)
- .map(doc => doc!);
- NewLightboxView.SetNewLightboxDoc(coll, undefined, contents.length ? contents : links);
- }
- };
+
+ @action public static SetKeywords(kw: string[]) {
+ this._keywords = kw;
+ }
+ @computed public static get Keywords() {
+ return this._keywords;
+ }
+ @computed public static get LightboxDoc() {
+ return this._doc;
+ }
+
+ // query
+ @action public static SetQuery(query: string) {
+ this._query = query;
+ }
+ @computed public static get Query() {
+ return this._query;
+ }
+
+ // keywords
+ @action public static SetRecs(recs: IRecommendation[]) {
+ this._recs = recs;
+ }
+ @computed public static get Recs() {
+ return this._recs;
+ }
+
+ // bounds
+ @action public static SetBounds(bounds: IBounds) {
+ this._bounds = bounds;
+ }
+ @computed public static get Bounds() {
+ return this._bounds;
+ }
+ // newLightbox sidebar status
+ @action public static SetSidebarStatus(sidebarStatus: Opt<string>) {
+ this._sidebarStatus = sidebarStatus;
+ }
+
+ // explore
+ @action public static SetExploreMode(status: Opt<boolean>) {
+ this._explore = status;
+ }
+
+ addDocTab = NewLightboxView.AddDocTab;
+
+ @computed public static get ExploreMode() {
+ return this._explore;
+ }
+
+ @computed public static get SidebarStatus() {
+ return this._sidebarStatus;
+ }
+ @computed get leftBorder() {
+ return Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]);
+ }
+ @computed get topBorder() {
+ return Math.min(this.props.PanelHeight / 4, this.props.maxBorder[1]);
+ }
@computed
get documentView() {
- if (!LightboxView.LightboxDoc) return null;
- else
- return (
- <GestureOverlay isActive={true}>
- <DocumentView
- ref={action((r: DocumentView | null) => (NewLightboxView._docView = r !== null ? r : undefined))}
- Document={LightboxView.LightboxDoc}
- PanelWidth={this.newLightboxWidth}
- PanelHeight={this.newLightboxHeight}
- LayoutTemplate={NewLightboxView.LightboxDocTemplate}
- isDocumentActive={returnTrue} // without this being true, sidebar annotations need to be activated before text can be selected.
- isContentActive={returnTrue}
- styleProvider={DefaultStyleProvider}
- ScreenToLocalTransform={this.newLightboxScreenToLocal}
- renderDepth={0}
- containerViewPath={returnEmptyDoclist}
- childFilters={this.docFilters}
- childFiltersByRanges={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- addDocument={undefined}
- removeDocument={undefined}
- whenChildContentsActiveChanged={emptyFunction}
- addDocTab={this.addDocTab}
- pinToPres={TabDocView.PinDoc}
- onBrowseClickScript={DocumentView.exploreMode}
- focus={emptyFunction}
- />
- </GestureOverlay>
- );
+ const lightboxDoc = DocumentView.LightboxDoc();
+ if (!lightboxDoc) return null;
+ return (
+ <GestureOverlay isActive>
+ <DocumentView
+ ref={action((r: DocumentView | null) => {
+ NewLightboxView._docView = r !== null ? r : undefined;
+ })}
+ Document={lightboxDoc}
+ PanelWidth={this.newLightboxWidth}
+ PanelHeight={this.newLightboxHeight}
+ LayoutTemplate={NewLightboxView.LightboxDocTemplate}
+ isDocumentActive={returnTrue} // without this being true, sidebar annotations need to be activated before text can be selected.
+ isContentActive={returnTrue}
+ styleProvider={DefaultStyleProvider}
+ ScreenToLocalTransform={this.newLightboxScreenToLocal}
+ renderDepth={0}
+ containerViewPath={returnEmptyDoclist}
+ childFilters={this.docFilters}
+ childFiltersByRanges={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ addDocument={undefined}
+ removeDocument={undefined}
+ whenChildContentsActiveChanged={emptyFunction}
+ addDocTab={this.addDocTab}
+ pinToPres={DocumentView.PinDoc}
+ focus={emptyFunction}
+ />
+ </GestureOverlay>
+ );
}
+ newLightboxWidth = () => this.props.PanelWidth - 420;
+ newLightboxHeight = () => this.props.PanelHeight - 140;
+ newLightboxScreenToLocal = () => new Transform(-this.leftBorder, -this.topBorder, 1);
+
+ docFilters = () => NewLightboxView._docFilters || [];
- future = () => NewLightboxView._future;
render() {
- let newLightboxHeaderHeight = 100;
- let downx = 0,
- downy = 0;
- return !LightboxView.LightboxDoc ? null : (
+ const newLightboxHeaderHeight = 100;
+ let downx = 0;
+ let downy = 0;
+ return !DocumentView.LightboxDoc() ? null : (
<div
className="newLightboxView-frame"
onPointerDown={e => {
@@ -335,7 +300,7 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
NewLightboxView.SetNewLightboxDoc(undefined);
}
}}>
- <div className={`app-document`} style={{ gridTemplateColumns: `calc(100% - 400px) 400px` }}>
+ <div className="app-document" style={{ gridTemplateColumns: `calc(100% - 400px) 400px` }}>
<div
className="newLightboxView-contents"
style={{
@@ -350,7 +315,7 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
{this.documentView}
</div>
) : (
- <div className={`explore`}>
+ <div className="explore">
<ExploreView recs={NewLightboxView.Recs} bounds={NewLightboxView.Bounds} />
</div>
)}
@@ -363,6 +328,7 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
}
interface NewLightboxTourBtnProps {
navBtn: (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: string, display: () => string, click: (e: React.MouseEvent) => void, color?: string) => JSX.Element;
+ // eslint-disable-next-line react/no-unused-prop-types
future: () => Opt<Doc[]>;
stepInto: () => void;
}
@@ -374,7 +340,7 @@ export class NewLightboxTourBtn extends React.Component<NewLightboxTourBtnProps>
0,
0,
'chevron-down',
- () => (LightboxView.LightboxDoc /*&& this.props.future()?.length*/ ? '' : 'none'),
+ () => (DocumentView.LightboxDoc() /* && this.props.future()?.length */ ? '' : 'none'),
e => {
e.stopPropagation();
this.props.stepInto();
diff --git a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
index 9f3c32e4e..dc3339cd3 100644
--- a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
+++ b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
@@ -1,77 +1,73 @@
-import { GrClose } from 'react-icons/gr';
-import { IRecommendation, Recommendation } from "../components";
-import './RecommendationList.scss';
+/* eslint-disable react/jsx-props-no-spreading */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable guard-for-in */
+import { IconButton, Size, Type } from 'browndash-components';
import * as React from 'react';
-import { IRecommendationList } from "./utils";
-import { NewLightboxView } from '../NewLightboxView';
-import { DocCast, StrCast } from '../../../../fields/Types';
import { FaCaretDown, FaCaretUp } from 'react-icons/fa';
-import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
-import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils';
-import { IBounds } from '../ExploreView/utils';
+import { GrClose } from 'react-icons/gr';
+import { DocListCast, StrListCast } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
-import { Id } from '../../../../fields/FieldSymbols';
-import { LightboxView } from '../../LightboxView';
-import { IconButton, Size, Type } from 'browndash-components';
+import { StrCast } from '../../../../fields/Types';
import { Colors } from '../../global/globalEnums';
+import { DocumentView } from '../../nodes/DocumentView';
+import { IBounds } from '../ExploreView/utils';
+import { NewLightboxView } from '../NewLightboxView';
+import { IRecommendation, Recommendation } from '../components';
+import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils';
+import './RecommendationList.scss';
-export const RecommendationList = (props: IRecommendationList) => {
- const {loading, keywords} = props
- const [loadingKeywords, setLoadingKeywords] = React.useState<boolean>(true)
- const [showMore, setShowMore] = React.useState<boolean>(false)
- const [keywordsLoc, setKeywordsLoc] = React.useState<string[]>([])
- const [update, setUpdate] = React.useState<boolean>(true)
- const initialRecs: IRecommendation[] = [
- {loading: true},
- {loading: true},
- {loading: true},
- {loading: true},
- {loading: true}
- ];
- const [recs, setRecs] = React.useState<IRecommendation[]>(initialRecs)
+export function RecommendationList() {
+ const [loadingKeywords, setLoadingKeywords] = React.useState<boolean>(true);
+ const [showMore, setShowMore] = React.useState<boolean>(false);
+ const [keywordsLoc, setKeywordsLoc] = React.useState<string[]>([]);
+ const [update, setUpdate] = React.useState<boolean>(true);
+ const initialRecs: IRecommendation[] = [{ loading: true }, { loading: true }, { loading: true }, { loading: true }, { loading: true }];
+ const [recs, setRecs] = React.useState<IRecommendation[]>(initialRecs);
React.useEffect(() => {
const getKeywords = async () => {
- let text = StrCast(LightboxView.LightboxDoc?.text)
- console.log('[1] fetching keywords')
- const response = await fetchKeywords(text, 5, true)
- console.log('[2] response:', response)
+ const text = StrCast(DocumentView.LightboxDoc()?.text);
+ console.log('[1] fetching keywords');
+ const response = await fetchKeywords(text, 5, true);
+ console.log('[2] response:', response);
const kw = response.keywords;
console.log(kw);
NewLightboxView.SetKeywords(kw);
- if (LightboxView.LightboxDoc) {
- console.log('setting keywords on doc')
- LightboxView.LightboxDoc.keywords = new List<string>(kw);
+ const lightboxDoc = DocumentView.LightboxDoc();
+ if (lightboxDoc) {
+ console.log('setting keywords on doc');
+ lightboxDoc.keywords = new List<string>(kw);
setKeywordsLoc(NewLightboxView.Keywords);
}
- setLoadingKeywords(false)
- }
- let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords)
+ setLoadingKeywords(false);
+ };
+ const keywordsList = StrListCast(DocumentView.LightboxDoc()!.keywords);
if (!keywordsList || keywordsList.length < 2) {
- setLoadingKeywords(true)
- getKeywords()
- setUpdate(!update)
+ setLoadingKeywords(true);
+ getKeywords();
+ setUpdate(!update);
} else {
- setKeywordsLoc(keywordsList)
- setLoadingKeywords(false)
- setUpdate(!update)
+ setKeywordsLoc(keywordsList);
+ setLoadingKeywords(false);
+ setUpdate(!update);
}
- }, [NewLightboxView.LightboxDoc])
+ }, [NewLightboxView.LightboxDoc]);
- // terms: vannevar bush, information spaces,
+ // terms: vannevar bush, information spaces,
React.useEffect(() => {
const getRecommendations = async () => {
- console.log('fetching recommendations')
- let query = 'undefined'
- if (keywordsLoc) query = keywordsLoc.join(',')
- let src = StrCast(NewLightboxView.LightboxDoc?.text)
- let dashDocs:IDocRequest[] = [];
+ console.log('fetching recommendations');
+ let query = 'undefined';
+ if (keywordsLoc) query = keywordsLoc.join(',');
+ const src = StrCast(NewLightboxView.LightboxDoc?.text);
+ const dashDocs: IDocRequest[] = [];
// get linked docs
- let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links)
- console.log("linked docs", linkedDocs)
+ const linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links);
+ console.log('linked docs', linkedDocs);
// get context docs (docs that are also in the collection)
- // let contextDocs: Doc[] = DocListCast(DocCast(LightboxView.LightboxDoc?.context).data)
- // let docId = LightboxView.LightboxDoc && LightboxView.LightboxDoc[Id]
+ // let contextDocs: Doc[] = DocListCast(DocCast(DocumentView.LightboxDoc()?.context).data)
+ // let docId = DocumentView.LightboxDoc() && DocumentView.LightboxDoc()[Id]
// console.log("context docs", contextDocs)
// contextDocs.forEach((doc: Doc) => {
// if (docId !== doc[Id]){
@@ -83,114 +79,135 @@ export const RecommendationList = (props: IRecommendationList) => {
// })
// }
// })
- console.log("dash docs", dashDocs)
+ console.log('dash docs', dashDocs);
if (query !== undefined) {
- const response = await fetchRecommendations(src, query, [], true)
- const num_recs = response.num_recommendations
- const recs = response.recommendations
- const keywords = response.keywords
- const response_bounds: IBounds = {
- max_x: response.max_x,
- max_y: response.max_y,
- min_x: response.min_x,
- min_y: response.min_y
- }
+ const response = await fetchRecommendations(src, query, [], true);
+ const theRecs = response.recommendations;
+ const responseBounds: IBounds = {
+ max_x: response.max_x,
+ max_y: response.max_y,
+ min_x: response.min_x,
+ min_y: response.min_y,
+ };
// if (NewLightboxView.NewLightboxDoc) {
// NewLightboxView.NewLightboxDoc.keywords = new List<string>(keywords);
// setKeywordsLoc(NewLightboxView.Keywords);
// }
// console.log(response_bounds)
- NewLightboxView.SetBounds(response_bounds)
+ NewLightboxView.SetBounds(responseBounds);
const recommendations: IRecommendation[] = [];
- for (const key in recs) {
- console.log(key)
- const title = recs[key].title;
- const url = recs[key].url
- const type = recs[key].type
- const text = recs[key].text
- const transcript = recs[key].transcript
- const previewUrl = recs[key].previewUrl
- const embedding = recs[key].embedding
- const distance = recs[key].distance
- const source = recs[key].source
- const related_concepts = recs[key].related_concepts
- const docId = recs[key].doc_id
- related_concepts.length >= 1 && recommendations.push({
- title: title,
- data: url,
- type: type,
- text: text,
- transcript: transcript,
- previewUrl: previewUrl,
- embedding: embedding,
- distance: Math.round(distance * 100) / 100,
- source: source,
- related_concepts: related_concepts,
- docId: docId
- })
+ // eslint-disable-next-line no-restricted-syntax
+ for (const key in theRecs) {
+ console.log(key);
+ const { title } = theRecs[key];
+ const { url } = theRecs[key];
+ const { type } = theRecs[key];
+ const { text } = theRecs[key];
+ const { transcript } = theRecs[key];
+ const { previewUrl } = theRecs[key];
+ const { embedding } = theRecs[key];
+ const { distance } = theRecs[key];
+ const { source } = theRecs[key];
+ const { related_concepts: relatedConcepts } = theRecs[key];
+ const docId = theRecs[key].doc_id;
+ relatedConcepts.length >= 1 &&
+ recommendations.push({
+ title: title,
+ data: url,
+ type: type,
+ text: text,
+ transcript: transcript,
+ previewUrl: previewUrl,
+ embedding: embedding,
+ distance: Math.round(distance * 100) / 100,
+ source: source,
+ related_concepts: relatedConcepts,
+ docId: docId,
+ });
}
recommendations.sort((a, b) => {
if (a.distance && b.distance) {
- return a.distance - b.distance
- } else return 0
- })
- console.log("[rec]: ", recommendations)
- NewLightboxView.SetRecs(recommendations)
- setRecs(recommendations)
+ return a.distance - b.distance;
+ }
+ return 0;
+ });
+ console.log('[rec]: ', recommendations);
+ NewLightboxView.SetRecs(recommendations);
+ setRecs(recommendations);
}
- }
+ };
getRecommendations();
- }, [update])
-
-
+ }, [update]);
- return <div className={`recommendationlist-container`} onPointerDown={(e) => {e.stopPropagation()}}>
- <div className={`header`}>
- <div className={`title`}>
- Recommendations
- </div>
- {NewLightboxView.LightboxDoc && <div style={{fontSize: 10}}>
- The recommendations are produced based on the text in the document <b><u>{StrCast(NewLightboxView.LightboxDoc.title)}</u></b>. The following keywords are used to fetch the recommendations.
- </div>}
- <div className={`lb-label`}>Keywords</div>
- {loadingKeywords ? <div className={`keywords`}>
- <div className={`keyword ${loadingKeywords && 'loading'}`}/>
- <div className={`keyword ${loadingKeywords && 'loading'}`}/>
- <div className={`keyword ${loadingKeywords && 'loading'}`}/>
- <div className={`keyword ${loadingKeywords && 'loading'}`}/>
+ return (
+ <div
+ className="recommendationlist-container"
+ onPointerDown={e => {
+ e.stopPropagation();
+ }}>
+ <div className="header">
+ <div className="title">Recommendations</div>
+ {NewLightboxView.LightboxDoc && (
+ <div style={{ fontSize: 10 }}>
+ The recommendations are produced based on the text in the document{' '}
+ <b>
+ <u>{StrCast(NewLightboxView.LightboxDoc.title)}</u>
+ </b>
+ . The following keywords are used to fetch the recommendations.
</div>
- :
- <div className={`keywords`}>
- {keywordsLoc && keywordsLoc.map((word, ind) => {
- return <div className={`keyword`}>
- {word}
- <IconButton type={Type.PRIM} size={Size.XSMALL} color={Colors.DARK_GRAY} icon={<GrClose/>} onClick={() => {
- let kw = keywordsLoc
- kw.splice(ind)
- NewLightboxView.SetKeywords(kw)
- }}/>
+ )}
+ <div className="lb-label">Keywords</div>
+ {loadingKeywords ? (
+ <div className="keywords">
+ <div className={`keyword ${loadingKeywords && 'loading'}`} />
+ <div className={`keyword ${loadingKeywords && 'loading'}`} />
+ <div className={`keyword ${loadingKeywords && 'loading'}`} />
+ <div className={`keyword ${loadingKeywords && 'loading'}`} />
</div>
- })}
- </div>
- }
- {!showMore ?
- <div className={`lb-caret`} onClick={() => {setShowMore(true)}}>
- More <FaCaretDown/>
- </div>
- :
- <div className={`more`}>
- <div className={`lb-caret`} onClick={() => {setShowMore(false)}}>
- Less <FaCaretUp/>
- </div>
- <div className={`lb-label`}>Type</div>
- <div className={`lb-label`}>Sources</div>
+ ) : (
+ <div className="keywords">
+ {keywordsLoc &&
+ keywordsLoc.map((word, ind) => (
+ <div className="keyword">
+ {word}
+ <IconButton
+ type={Type.PRIM}
+ size={Size.XSMALL}
+ color={Colors.DARK_GRAY}
+ icon={<GrClose />}
+ onClick={() => {
+ const kw = keywordsLoc;
+ kw.splice(ind);
+ NewLightboxView.SetKeywords(kw);
+ }}
+ />
+ </div>
+ ))}
+ </div>
+ )}
+ {!showMore ? (
+ <div
+ className="lb-caret"
+ onClick={() => {
+ setShowMore(true);
+ }}>
+ More <FaCaretDown />
+ </div>
+ ) : (
+ <div className="more">
+ <div
+ className="lb-caret"
+ onClick={() => {
+ setShowMore(false);
+ }}>
+ Less <FaCaretUp />
+ </div>
+ <div className="lb-label">Type</div>
+ <div className="lb-label">Sources</div>
+ </div>
+ )}
</div>
- }
- </div>
- <div className={`recommendations`}>
- {recs && recs.map((rec: IRecommendation) => {
- return <Recommendation {...rec} />
- })}
+ <div className="recommendations">{recs && recs.map((rec: IRecommendation) => <Recommendation {...rec} />)}</div>
</div>
- </div>
-} \ No newline at end of file
+ );
+}
diff --git a/src/client/views/newlightbox/RecommendationList/index.ts b/src/client/views/newlightbox/RecommendationList/index.ts
index f4555c1f2..226eafb7e 100644
--- a/src/client/views/newlightbox/RecommendationList/index.ts
+++ b/src/client/views/newlightbox/RecommendationList/index.ts
@@ -1 +1 @@
-export * from './RecommendationList' \ No newline at end of file
+export * from './RecommendationList';
diff --git a/src/client/views/newlightbox/RecommendationList/utils.ts b/src/client/views/newlightbox/RecommendationList/utils.ts
index cdfff3258..fbf8ac19f 100644
--- a/src/client/views/newlightbox/RecommendationList/utils.ts
+++ b/src/client/views/newlightbox/RecommendationList/utils.ts
@@ -1,9 +1,8 @@
-import { IRecommendation } from "../components";
+import { IRecommendation } from '../components';
export interface IRecommendationList {
- loading?: boolean,
- keywords?: string[],
- recs?: IRecommendation[]
- getRecs?: any
+ loading?: boolean;
+ keywords?: string[];
+ recs?: IRecommendation[];
+ getRecs?: any;
}
-
diff --git a/src/client/views/newlightbox/components/EditableText/index.ts b/src/client/views/newlightbox/components/EditableText/index.ts
index e3367b175..444881a74 100644
--- a/src/client/views/newlightbox/components/EditableText/index.ts
+++ b/src/client/views/newlightbox/components/EditableText/index.ts
@@ -1 +1 @@
-export * from './EditableText'
+export * from './EditableText';
diff --git a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
index 23027808f..375408d01 100644
--- a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
+++ b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
@@ -1,12 +1,12 @@
import * as React from 'react';
-import { IRecommendation } from './utils';
-import './Recommendation.scss';
-import { getType } from '../../utils';
import { FaEyeSlash } from 'react-icons/fa';
-import { NewLightboxView } from '../../NewLightboxView';
-import { DocumentManager } from '../../../../util/DocumentManager';
import { Doc } from '../../../../../fields/Doc';
import { Docs } from '../../../../documents/Documents';
+import { DocumentView } from '../../../nodes/DocumentView';
+import { NewLightboxView } from '../../NewLightboxView';
+import { getType } from '../../utils';
+import './Recommendation.scss';
+import { IRecommendation } from './utils';
export const Recommendation = (props: IRecommendation) => {
const { title, data, type, text, transcript, loading, source, previewUrl, related_concepts, distance, docId } = props;
@@ -17,7 +17,7 @@ export const Recommendation = (props: IRecommendation) => {
onClick={() => {
let doc: Doc | null = null;
if (source == 'Dash' && docId) {
- const docView = DocumentManager.Instance.getDocumentViewsById(docId).lastElement();
+ const docView = DocumentView.getDocumentViewsById(docId).lastElement();
if (docView) {
doc = docView.Document;
}
diff --git a/src/client/views/newlightbox/components/Recommendation/index.ts b/src/client/views/newlightbox/components/Recommendation/index.ts
index 12ebf9d6e..4fce185ec 100644
--- a/src/client/views/newlightbox/components/Recommendation/index.ts
+++ b/src/client/views/newlightbox/components/Recommendation/index.ts
@@ -1,2 +1,2 @@
-export * from './utils'
-export * from './Recommendation' \ No newline at end of file
+export * from './utils';
+export * from './Recommendation';
diff --git a/src/client/views/newlightbox/components/Recommendation/utils.ts b/src/client/views/newlightbox/components/Recommendation/utils.ts
index 796ce0eb0..4a55d394e 100644
--- a/src/client/views/newlightbox/components/Recommendation/utils.ts
+++ b/src/client/views/newlightbox/components/Recommendation/utils.ts
@@ -1,23 +1,23 @@
-import { DocumentType } from "../../../../documents/DocumentTypes"
+import { DocumentType } from '../../../../documents/DocumentTypes';
export interface IRecommendation {
- loading?: boolean
- type?: DocumentType | string,
- data?: string,
- title?: string,
- text?: string,
- source?: string,
- previewUrl?: string,
+ loading?: boolean;
+ type?: DocumentType | string;
+ data?: string;
+ title?: string;
+ text?: string;
+ source?: string;
+ previewUrl?: string;
transcript?: {
- text: string,
- start: number,
- duration: number
- }[],
+ text: string;
+ start: number;
+ duration: number;
+ }[];
embedding?: {
- x: number,
- y: number
- },
- distance?: number,
- related_concepts?: string[],
- docId?: string
-} \ No newline at end of file
+ x: number;
+ y: number;
+ };
+ distance?: number;
+ related_concepts?: string[];
+ docId?: string;
+}
diff --git a/src/client/views/newlightbox/components/SkeletonDoc/index.ts b/src/client/views/newlightbox/components/SkeletonDoc/index.ts
index 396b7272b..98379f404 100644
--- a/src/client/views/newlightbox/components/SkeletonDoc/index.ts
+++ b/src/client/views/newlightbox/components/SkeletonDoc/index.ts
@@ -1 +1 @@
-export * from './SkeletonDoc' \ No newline at end of file
+export * from './SkeletonDoc';
diff --git a/src/client/views/newlightbox/components/Template/index.ts b/src/client/views/newlightbox/components/Template/index.ts
index 36b5f3f46..f5b83ad09 100644
--- a/src/client/views/newlightbox/components/Template/index.ts
+++ b/src/client/views/newlightbox/components/Template/index.ts
@@ -1 +1 @@
-export * from './Template' \ No newline at end of file
+export * from './Template';
diff --git a/src/client/views/newlightbox/components/index.ts b/src/client/views/newlightbox/components/index.ts
index 3f9128690..1c266c5d8 100644
--- a/src/client/views/newlightbox/components/index.ts
+++ b/src/client/views/newlightbox/components/index.ts
@@ -1,3 +1,3 @@
-export * from './Template'
-export * from './Recommendation'
-export * from './SkeletonDoc' \ No newline at end of file
+export * from './Template';
+export * from './Recommendation';
+export * from './SkeletonDoc';
diff --git a/src/client/views/newlightbox/utils.ts b/src/client/views/newlightbox/utils.ts
index c879718e3..a0d6b9f4a 100644
--- a/src/client/views/newlightbox/utils.ts
+++ b/src/client/views/newlightbox/utils.ts
@@ -1,5 +1,5 @@
+/* eslint-disable no-use-before-define */
import { DocumentType } from '../../documents/DocumentTypes';
-import { IRecommendation } from './components';
export interface IDocRequest {
id: string;
@@ -12,7 +12,7 @@ export const fetchRecommendations = async (src: string, query: string, docs?: ID
console.log('[rec] making request');
if (dummy) {
return {
- recommendations: [], //dummyRecs,
+ recommendations: [], // dummyRecs,
keywords: dummyKeywords,
num_recommendations: 4,
max_x: 100,
@@ -79,6 +79,7 @@ export const getType = (type: DocumentType | string) => {
}
};
+/*
const dummyRecs = {
a: {
title: 'Vannevar Bush - American Engineer',
@@ -117,4 +118,6 @@ const dummyRecs = {
},
};
+*/
+
const dummyKeywords = ['user control', 'vannevar bush', 'hypermedia', 'hypertext'];
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 8a38ef663..9deed4de4 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -1,27 +1,34 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { action, computed, IReactionDisposer, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
import { DateField } from '../../../fields/DateField';
import { Doc } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { ComputedField } from '../../../fields/ScriptField';
import { Cast, DateCast, NumCast } from '../../../fields/Types';
import { AudioField, nullAudio } from '../../../fields/URLField';
-import { emptyFunction, formatTime, returnFalse, setupMoveUpEvents } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { formatTime } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { Networking } from '../../Network';
import { DragManager } from '../../util/DragManager';
-import { LinkManager } from '../../util/LinkManager';
import { undoBatch } from '../../util/UndoManager';
import { CollectionStackedTimeline, TrimScope } from '../collections/CollectionStackedTimeline';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { DocViewUtils } from '../DocViewUtils';
+import { PinDocView, PinProps } from '../PinFuncs';
import './AudioBox.scss';
-import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView';
-import { PinProps, PresBox } from './trails';
+import { DocumentView } from './DocumentView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { OpenWhere } from './OpenWhere';
/**
* AudioBox
@@ -41,7 +48,7 @@ declare class MediaRecorder {
constructor(e: any); // whatever MediaRecorder has
}
-export enum media_state {
+export enum mediaState {
PendingRecording = 'pendingRecording',
Recording = 'recording',
Paused = 'paused',
@@ -93,19 +100,19 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
return this._props.PanelHeight() < 50;
} // used to collapse timeline when node is shrunk
@computed get links() {
- return LinkManager.Links(this.dataDoc);
+ return Doc.Links(this.dataDoc);
}
@computed get mediaState() {
- return this.dataDoc.mediaState as media_state;
+ return this.dataDoc.mediaState as mediaState;
+ }
+ set mediaState(value) {
+ this.dataDoc.mediaState = value;
}
@computed get path() {
// returns the path of the audio file
const path = Cast(this.Document[this.fieldKey], AudioField, null)?.url.href || '';
return path === nullAudio ? '' : path;
}
- set mediaState(value) {
- this.dataDoc.mediaState = value;
- }
@computed get timeline() {
return this._stackedTimeline;
@@ -116,17 +123,17 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
this._dropDisposer?.();
Object.values(this._disposers).forEach(disposer => disposer?.());
- this.mediaState === media_state.Recording && this.stopRecording();
+ this.mediaState === mediaState.Recording && this.stopRecording();
}
@action
componentDidMount() {
this._props.setContentViewBox?.(this);
if (this.path) {
- this.mediaState = media_state.Paused;
+ this.mediaState = mediaState.Paused;
this.setPlayheadTime(NumCast(this.layoutDoc.clipStart));
} else {
- this.mediaState = undefined as any as media_state;
+ this.mediaState = undefined as any as mediaState;
}
}
@@ -148,24 +155,24 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
this.Document,
this.dataDoc,
this.annotationKey,
- this._ele?.currentTime || Cast(this.Document._layout_currentTimecode, 'number', null) || (this.mediaState === media_state.Recording ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined),
+ this._ele?.currentTime || Cast(this.Document._layout_currentTimecode, 'number', null) || (this.mediaState === mediaState.Recording ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined),
undefined,
undefined,
addAsAnnotation
) || this.Document
: Docs.Create.ConfigDocument({ title: '#' + timecode, _timecodeToShow: timecode, annotationOn: this.Document });
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), temporal: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), temporal: true } }, this.Document);
return anchor;
};
// updates timecode and shows it in timeline, follows links at time
@action
timecodeChanged = () => {
- if (this.mediaState !== media_state.Recording && this._ele) {
+ if (this.mediaState !== mediaState.Recording && this._ele) {
this.links
.map(l => this.getLinkData(l))
- .forEach(({ la1, la2, linkTime }) => {
+ .forEach(({ la1, linkTime }) => {
if (linkTime > NumCast(this.layoutDoc._layout_currentTimecode) && linkTime < this._ele!.currentTime) {
Doc.linkFollowHighlight(la1);
}
@@ -179,7 +186,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@action
playFrom = (seekTimeInSeconds: number, endTime?: number, fullPlay: boolean = false) => {
clearTimeout(this._play); // abort any previous clip ending
- if (Number.isNaN(this._ele?.duration)) {
+ if (isNaN(this._ele?.duration ?? Number.NaN)) {
// audio element isn't loaded yet... wait 1/2 second and try again
setTimeout(() => this.playFrom(seekTimeInSeconds, endTime), 500);
} else if (this.timeline && this._ele && AudioBox.Enabled) {
@@ -190,7 +197,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
if (seekTimeInSeconds >= 0 && this.timeline.trimStart <= end && seekTimeInSeconds <= this.timeline.trimEnd) {
this._ele.currentTime = start;
this._ele.play();
- this.mediaState = media_state.Playing;
+ this.mediaState = mediaState.Playing;
this.addCurrentlyPlaying();
this._play = setTimeout(
() => {
@@ -212,9 +219,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@action
removeCurrentlyPlaying = () => {
const docView = this.DocumentView?.();
- if (CollectionStackedTimeline.CurrentlyPlaying && docView) {
- const index = CollectionStackedTimeline.CurrentlyPlaying.indexOf(docView);
- index !== -1 && CollectionStackedTimeline.CurrentlyPlaying.splice(index, 1);
+ if (DocumentView.CurrentlyPlaying && docView) {
+ const index = DocumentView.CurrentlyPlaying.indexOf(docView);
+ index !== -1 && DocumentView.CurrentlyPlaying.splice(index, 1);
}
};
@@ -222,17 +229,17 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@action
addCurrentlyPlaying = () => {
const docView = this.DocumentView?.();
- if (!CollectionStackedTimeline.CurrentlyPlaying) {
- CollectionStackedTimeline.CurrentlyPlaying = [];
+ if (!DocumentView.CurrentlyPlaying) {
+ DocumentView.CurrentlyPlaying = [];
}
- if (docView && CollectionStackedTimeline.CurrentlyPlaying.indexOf(docView) === -1) {
- CollectionStackedTimeline.CurrentlyPlaying.push(docView);
+ if (docView && DocumentView.CurrentlyPlaying.indexOf(docView) === -1) {
+ DocumentView.CurrentlyPlaying.push(docView);
}
};
// update the recording time
updateRecordTime = () => {
- if (this.mediaState === media_state.Recording) {
+ if (this.mediaState === mediaState.Recording) {
setTimeout(this.updateRecordTime, 30);
if (!this._paused) {
this.layoutDoc._layout_currentTimecode = (new Date().getTime() - this._recordStart - this._pausedTime) / 1000;
@@ -245,7 +252,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
this._stream = await navigator.mediaDevices.getUserMedia({ audio: true });
this._recorder = new MediaRecorder(this._stream);
this.dataDoc[this.fieldKey + '_recordingStart'] = new DateField();
- DocUtils.ActiveRecordings.push(this);
+ DocViewUtils.ActiveRecordings.push(this);
this._recorder.ondataavailable = async (e: any) => {
const [{ result }] = await Networking.UploadFilesToServer({ file: e.data });
if (!(result instanceof Error)) {
@@ -253,7 +260,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
};
this._recordStart = new Date().getTime();
- runInAction(() => (this.mediaState = media_state.Recording));
+ runInAction(() => {
+ this.mediaState = mediaState.Recording;
+ });
setTimeout(this.updateRecordTime);
this._recorder.start();
setTimeout(this.stopRecording, 60 * 60 * 1000); // stop after an hour
@@ -268,34 +277,34 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
const now = new Date().getTime();
this._paused && (this._pausedTime += now - this._pauseStart);
this.dataDoc[this.fieldKey + '_duration'] = (now - this._recordStart - this._pausedTime) / 1000;
- this.mediaState = media_state.Paused;
+ this.mediaState = mediaState.Paused;
this._stream?.getAudioTracks()[0].stop();
- const ind = DocUtils.ActiveRecordings.indexOf(this);
- ind !== -1 && DocUtils.ActiveRecordings.splice(ind, 1);
+ const ind = DocViewUtils.ActiveRecordings.indexOf(this);
+ ind !== -1 && DocViewUtils.ActiveRecordings.splice(ind, 1);
}
};
// context menu
- specificContextMenu = (e: React.MouseEvent): void => {
+ specificContextMenu = (): void => {
const funcs: ContextMenuProps[] = [];
funcs.push({
description: (this.layoutDoc.hideAnchors ? "Don't hide" : 'Hide') + ' anchors',
- event: e => (this.layoutDoc.hideAnchors = !this.layoutDoc.hideAnchors),
+ event: () => { this.layoutDoc.hideAnchors = !this.layoutDoc.hideAnchors; }, // prettier-ignore
icon: 'expand-arrows-alt',
});
funcs.push({
description: (this.layoutDoc.dontAutoFollowLinks ? '' : "Don't") + ' follow links when encountered',
- event: e => (this.layoutDoc.dontAutoFollowLinks = !this.layoutDoc.dontAutoFollowLinks),
+ event: () => { this.layoutDoc.dontAutoFollowLinks = !this.layoutDoc.dontAutoFollowLinks}, // prettier-ignore
icon: 'expand-arrows-alt',
});
funcs.push({
description: (this.layoutDoc.dontAutoPlayFollowedLinks ? '' : "Don't") + ' play when link is selected',
- event: e => (this.layoutDoc.dontAutoPlayFollowedLinks = !this.layoutDoc.dontAutoPlayFollowedLinks),
+ event: () => { this.layoutDoc.dontAutoPlayFollowedLinks = !this.layoutDoc.dontAutoPlayFollowedLinks; }, // prettier-ignore
icon: 'expand-arrows-alt',
});
funcs.push({
description: (this.layoutDoc.autoPlayAnchors ? "Don't auto" : 'Auto') + ' play anchors onClick',
- event: e => (this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors),
+ event: () => { this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors; }, // prettier-ignore
icon: 'expand-arrows-alt',
});
ContextMenu.Instance?.addItem({
@@ -341,9 +350,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
};
- IsPlaying = () => this.mediaState === media_state.Playing;
+ IsPlaying = () => this.mediaState === mediaState.Playing;
TogglePause = () => {
- if (this.mediaState === media_state.Paused) this.Play();
+ if (this.mediaState === mediaState.Paused) this.Play();
else this.pause();
};
// pause playback without removing from the playback list to allow user to play it again.
@@ -351,7 +360,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
pause = () => {
if (this._ele) {
this._ele.pause();
- this.mediaState = media_state.Paused;
+ this.mediaState = mediaState.Paused;
// if paused in the middle of playback, prevents restart on next play
if (!this._finished) clearTimeout(this._play);
@@ -383,7 +392,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
newDoc.overlayY = NumCast(this.Document.y) + NumCast(this.layoutDoc._height);
Doc.AddToMyOverlay(newDoc);
} else {
- this._props.addDocument?.(newDoc);
+ this._props.addDocTab(newDoc, OpenWhere.addRight);
}
}),
false
@@ -433,7 +442,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
};
// plays link
- playLink = (link: Doc, options: FocusViewOptions) => {
+ playLink = (link: Doc /* , options: FocusViewOptions */) => {
if (link.annotationOn === this.Document) {
if (!this.layoutDoc.dontAutoPlayFollowedLinks) {
this.playFrom(this.timeline?.anchorStart(link) || 0, this.timeline?.anchorEnd(link));
@@ -459,13 +468,17 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
};
@action
- timelineWhenChildContentsActiveChanged = (isActive: boolean) => this._props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive));
+ timelineWhenChildContentsActiveChanged = (isActive: boolean) => {
+ this._props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive));
+ };
timelineScreenToLocal = () => this.ScreenToLocalBoxXf().translate(0, -AudioBox.topControlsHeight);
- setPlayheadTime = (time: number) => (this._ele!.currentTime /*= this.layoutDoc._layout_currentTimecode*/ = time);
+ setPlayheadTime = (time: number) => {
+ this._ele!.currentTime /* = this.layoutDoc._layout_currentTimecode */ = time;
+ };
- playing = () => this.mediaState === media_state.Playing;
+ playing = () => this.mediaState === mediaState.Playing;
isActiveChild = () => this._isAnyChildContentActive;
@@ -496,7 +509,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
e,
returnFalse,
returnFalse,
- action(e => {
+ action(() => {
if (this.timeline?.IsTrimming !== TrimScope.None) {
this.timeline?.CancelTrimming();
} else {
@@ -522,7 +535,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
e,
returnFalse,
returnFalse,
- action((e: PointerEvent, doubleTap?: boolean) => {
+ action((moveEv: PointerEvent, doubleTap?: boolean) => {
if (doubleTap) {
this.startTrim(TrimScope.All);
} else if (this.timeline) {
@@ -562,14 +575,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
setupTimelineDrop = (r: HTMLDivElement | null) => {
if (r && this.timeline) {
this._dropDisposer?.();
- this._dropDisposer = DragManager.MakeDropTarget(
- r,
- (e, de) => {
- const [xp, yp] = this.ScreenToLocalBoxXf().transformPoint(de.x, de.y);
- de.complete.docDragData && this.timeline?.internalDocDrop(e, de, de.complete.docDragData, xp);
- },
- this.layoutDoc
- );
+ this._dropDisposer = DragManager.MakeDropTarget(r, (e, de) => de.complete.docDragData && this.timeline?.internalDocDrop(e, de, de.complete.docDragData), this.layoutDoc);
}
};
@@ -580,7 +586,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
<div className="audiobox-dictation" onPointerDown={this.onFile}>
<FontAwesomeIcon size="2x" icon="file-alt" />
</div>
- {[media_state.Recording, media_state.Playing].includes(this.mediaState) ? (
+ {[mediaState.Recording, mediaState.Playing].includes(this.mediaState) ? (
<div className="recording-controls" onClick={e => e.stopPropagation()}>
<div className="record-button" onPointerDown={this.Record}>
<FontAwesomeIcon size="2x" icon="stop" />
@@ -606,7 +612,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
<div
className="audiobox-file"
style={{
- pointerEvents: this._isAnyChildContentActive || this._props.isContentActive() ? 'all' : 'none',
flexDirection: this.miniPlayer ? 'row' : 'column',
justifyContent: this.miniPlayer ? 'flex-start' : 'space-between',
}}>
@@ -614,31 +619,29 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
<div className="controls-left">
<div
className="audiobox-button"
- title={this.mediaState === media_state.Paused ? 'play' : 'pause'}
+ title={this.mediaState === mediaState.Paused ? 'play' : 'pause'}
onPointerDown={
- this.mediaState === media_state.Paused
+ this.mediaState === mediaState.Paused
? this.Play
: e => {
e.stopPropagation();
this.Pause();
}
}>
- <FontAwesomeIcon icon={this.mediaState === media_state.Paused ? 'play' : 'pause'} size={'1x'} />
+ <FontAwesomeIcon icon={this.mediaState === mediaState.Paused ? 'play' : 'pause'} size="1x" />
</div>
{!this.miniPlayer && (
<>
<Tooltip title={<>trim audio</>}>
<div className="audiobox-button" onPointerDown={this.onClipPointerDown}>
- <FontAwesomeIcon icon={this.timeline?.IsTrimming !== TrimScope.None ? 'check' : 'cut'} size={'1x'} />
+ <FontAwesomeIcon icon={this.timeline?.IsTrimming !== TrimScope.None ? 'check' : 'cut'} size="1x" />
</div>
</Tooltip>
- {this.timeline?.IsTrimming == TrimScope.None && !NumCast(this.layoutDoc.clipStart) && NumCast(this.layoutDoc.clipEnd) === this.rawDuration ? (
- <></>
- ) : (
- <Tooltip title={<>{this.timeline?.IsTrimming !== TrimScope.None ? 'Cancel trimming' : 'Edit original timeline'}</>}>
+ {this.timeline?.IsTrimming === TrimScope.None && !NumCast(this.layoutDoc.clipStart) && NumCast(this.layoutDoc.clipEnd) === this.rawDuration ? null : (
+ <Tooltip title={this.timeline?.IsTrimming !== TrimScope.None ? 'Cancel trimming' : 'Edit original timeline'}>
<div className="audiobox-button" onPointerDown={this.onResetPointerDown}>
- <FontAwesomeIcon icon={this.timeline?.IsTrimming !== TrimScope.None ? 'cancel' : 'arrows-left-right'} size={'1x'} />
+ <FontAwesomeIcon icon={this.timeline?.IsTrimming !== TrimScope.None ? 'cancel' : 'arrows-left-right'} size="1x" />
</div>
</Tooltip>
)}
@@ -662,9 +665,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
max="1"
value={this._muted ? 0 : this._volume}
className="toolbar-slider volume"
- onPointerDown={(e: React.PointerEvent) => {
- e.stopPropagation();
- }}
+ onPointerDown={e => e.stopPropagation()}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.setVolume(Number(e.target.value))}
/>
</div>
@@ -691,8 +692,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
value={this.timeline?._zoomFactor ?? 1}
className="toolbar-slider"
id="zoom-slider"
- onPointerDown={(e: React.PointerEvent) => e.stopPropagation()}
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.zoom(Number(e.target.value))}
+ onPointerDown={e => e.stopPropagation()}
+ onChange={e => this.zoom(Number(e.target.value))}
/>
</div>
)}
@@ -707,9 +708,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@computed get renderTimeline() {
return (
<CollectionStackedTimeline
- ref={action((r: CollectionStackedTimeline | null) => (this._stackedTimeline = r))}
+ ref={action((r: CollectionStackedTimeline | null) => {
+ this._stackedTimeline = r;
+ })}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
- CollectionFreeFormDocumentView={undefined}
dataFieldKey={this.fieldKey}
fieldKey={this.annotationKey}
dictationKey={this.fieldKey + '_dictation'}
@@ -740,10 +743,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// returns the html audio element
@computed get audio() {
return (
+ // eslint-disable-next-line jsx-a11y/media-has-caption
<audio
ref={this.setRef}
className={`audiobox-control${this._props.isContentActive() ? '-interactive' : ''}`}
- onLoadedData={action(e => this._ele?.duration && this._ele?.duration !== Infinity && (this.dataDoc[this.fieldKey + '_duration'] = this._ele.duration))}>
+ onLoadedData={action(() => {
+ this._ele?.duration && this._ele?.duration !== Infinity && (this.dataDoc[this.fieldKey + '_duration'] = this._ele.duration);
+ })}>
<source src={this.path} type="audio/mpeg" />
Not supported.
</audio>
@@ -752,9 +758,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
render() {
return (
- <div ref={this.setupTimelineDrop} className="audiobox-container" onContextMenu={this.specificContextMenu} style={{ pointerEvents: this.layoutDoc._lockedPosition ? 'none' : undefined }}>
+ <div ref={this.setupTimelineDrop} className="audiobox-container" onContextMenu={this.specificContextMenu} style={{ pointerEvents: this._isAnyChildContentActive || this._props.isContentActive() ? 'all' : 'none' }}>
{!this.path ? this.recordingControls : this.playbackControls}
</div>
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.AUDIO, {
+ layout: { view: AudioBox, dataField: 'data' },
+ options: { acl: '', _height: 100, _layout_fitWidth: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true, systemIcon: 'BsFillVolumeUpFill' },
+});
diff --git a/src/client/views/nodes/ChatBox/ChatBox.scss b/src/client/views/nodes/ChatBox/ChatBox.scss
new file mode 100644
index 000000000..f1ad3d074
--- /dev/null
+++ b/src/client/views/nodes/ChatBox/ChatBox.scss
@@ -0,0 +1,228 @@
+$background-color: #f8f9fa;
+$text-color: #333;
+$input-background: #fff;
+$button-color: #007bff;
+$button-hover-color: darken($button-color, 10%);
+$shadow-color: rgba(0, 0, 0, 0.075);
+$border-radius: 8px;
+
+.chatBox {
+ display: flex;
+ flex-direction: column;
+ width: 100%; /* Adjust the width as needed, could be in percentage */
+ height: 100%; /* Adjust the height as needed, could be in percentage */
+ background-color: $background-color;
+ font-family: 'Helvetica Neue', Arial, sans-serif;
+ //margin: 20px auto;
+ //overflow: hidden;
+
+ .scroll-box {
+ flex-grow: 1;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ height: 100%;
+ padding: 10px;
+ display: flex;
+ flex-direction: column-reverse;
+
+ &::-webkit-scrollbar {
+ width: 8px;
+ }
+ &::-webkit-scrollbar-thumb {
+ background-color: darken($background-color, 10%);
+ border-radius: $border-radius;
+ }
+
+
+ .chat-content {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .messages {
+ display: flex;
+ flex-direction: column;
+ .message {
+ padding: 10px;
+ margin-bottom: 10px;
+ border-radius: $border-radius;
+ background-color: lighten($background-color, 5%);
+ box-shadow: 0 2px 5px $shadow-color;
+ //display: flex;
+ align-items: center;
+ max-width: 70%;
+ word-break: break-word;
+ .message-footer { // Assuming this is the container for the toggle button
+ //max-width: 70%;
+
+
+ .toggle-logs-button {
+ margin-top: 10px; // Padding on sides to align with the text above
+ width: 95%;
+ //display: block; // Ensures the button extends the full width of its container
+ text-align: center; // Centers the text inside the button
+ //padding: 8px 0; // Adequate padding for touch targets
+ background-color: $button-color;
+ color: #fff;
+ border: none;
+ border-radius: $border-radius;
+ cursor: pointer;
+ //transition: background-color 0.3s;
+ //margin-top: 10px; // Adds space above the button
+ box-shadow: 0 2px 4px $shadow-color; // Consistent shadow with other elements
+ &:hover {
+ background-color: $button-hover-color;
+ }
+ }
+ .tool-logs {
+ width: 100%;
+ background-color: $input-background;
+ color: $text-color;
+ margin-top: 5px;
+ //padding: 10px;
+ //border-radius: $border-radius;
+ //box-shadow: inset 0 2px 4px $shadow-color;
+ //transition: opacity 1s ease-in-out;
+ font-family: monospace;
+ overflow-x: auto;
+ max-height: 150px; // Ensuring it does not grow too large
+ overflow-y: auto;
+ }
+
+ }
+
+ .custom-link {
+ color: lightblue;
+ text-decoration: underline;
+ cursor: pointer;
+ }
+ &.user {
+ align-self: flex-end;
+ background-color: $button-color;
+ color: #fff;
+ }
+
+ &.chatbot {
+ align-self: flex-start;
+ background-color: $input-background;
+ color: $text-color;
+ }
+
+ span {
+ flex-grow: 1;
+ padding-right: 10px;
+ }
+
+ img {
+ max-width: 50px;
+ max-height: 50px;
+ border-radius: 50%;
+ }
+ }
+ }
+ padding-bottom: 0;
+ }
+
+ .chat-form {
+ display: flex;
+ flex-grow: 1;
+ //height: 50px;
+ bottom: 0;
+ width: 100%;
+ padding: 10px;
+ background-color: $input-background;
+ box-shadow: inset 0 -1px 2px $shadow-color;
+
+ input[type="text"] {
+ flex-grow: 1;
+ border: 1px solid darken($input-background, 10%);
+ border-radius: $border-radius;
+ padding: 8px 12px;
+ margin-right: 10px;
+ }
+
+ button {
+ padding: 8px 16px;
+ background-color: $button-color;
+ color: #fff;
+ border: none;
+ border-radius: $border-radius;
+ cursor: pointer;
+ transition: background-color 0.3s;
+
+ &:hover {
+ background-color: $button-hover-color;
+ }
+ }
+ margin-bottom: 0;
+ }
+}
+
+.initializing-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba($background-color, 0.95);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 1.5em;
+ color: $text-color;
+ z-index: 10; // Ensure it's above all other content (may be better solution)
+
+ &::before {
+ content: 'Initializing...';
+ font-weight: bold;
+ }
+}
+
+
+.modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: rgba(0, 0, 0, 0.4);
+
+ .modal-content {
+ background-color: $input-background;
+ color: $text-color;
+ padding: 20px;
+ border-radius: $border-radius;
+ box-shadow: 0 2px 10px $shadow-color;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: auto;
+ min-width: 300px;
+
+ h4 {
+ margin-bottom: 15px;
+ }
+
+ p {
+ margin-bottom: 20px;
+ }
+
+ button {
+ padding: 10px 20px;
+ background-color: $button-color;
+ color: #fff;
+ border: none;
+ border-radius: $border-radius;
+ cursor: pointer;
+ margin: 5px;
+ transition: background-color 0.3s;
+
+ &:hover {
+ background-color: $button-hover-color;
+ }
+ }
+ }
+}
diff --git a/src/client/views/nodes/ChatBox/ChatBox.tsx b/src/client/views/nodes/ChatBox/ChatBox.tsx
new file mode 100644
index 000000000..880c332ac
--- /dev/null
+++ b/src/client/views/nodes/ChatBox/ChatBox.tsx
@@ -0,0 +1,609 @@
+import { MathJaxContext } from 'better-react-mathjax';
+import { action, makeObservable, observable, observe, reaction, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import OpenAI, { ClientOptions } from 'openai';
+import { ImageFile, Message } from 'openai/resources/beta/threads/messages';
+import { RunStep } from 'openai/resources/beta/threads/runs/steps';
+import * as React from 'react';
+import { Doc } from '../../../../fields/Doc';
+import { Id } from '../../../../fields/FieldSymbols';
+import { CsvCast, DocCast, PDFCast, StrCast } from '../../../../fields/Types';
+import { CsvField } from '../../../../fields/URLField';
+import { Networking } from '../../../Network';
+import { DocUtils } from '../../../documents/DocUtils';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
+import { DocumentManager } from '../../../util/DocumentManager';
+import { LinkManager } from '../../../util/LinkManager';
+import { ViewBoxAnnotatableComponent } from '../../DocComponent';
+import { FieldView, FieldViewProps } from '../FieldView';
+import './ChatBox.scss';
+import MessageComponent from './MessageComponent';
+import { ANNOTATION_LINK_TYPE, ASSISTANT_ROLE, AssistantMessage, DOWNLOAD_TYPE } from './types';
+
+@observer
+export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
+ @observable modalStatus = false;
+ @observable currentFile = { url: '' };
+ @observable history: AssistantMessage[] = [];
+ @observable.deep current_message: AssistantMessage | undefined = undefined;
+
+ @observable isLoading: boolean = false;
+ @observable isInitializing: boolean = true;
+ @observable expandedLogIndex: number | null = null;
+ @observable linked_docs_to_add: Doc[] = [];
+
+ private openai: OpenAI;
+ private interim_history: string = '';
+ private assistantID: string = '';
+ private threadID: string = '';
+ private _oldWheel: any;
+ private vectorStoreID: string = '';
+ private mathJaxConfig: any;
+ private linkedCsvIDs: string[] = [];
+
+ public static LayoutString(fieldKey: string) {
+ return FieldView.LayoutString(ChatBox, fieldKey);
+ }
+ constructor(props: FieldViewProps) {
+ super(props);
+ makeObservable(this);
+ this.openai = this.initializeOpenAI();
+ this.history = [];
+ this.threadID = StrCast(this.dataDoc.thread_id);
+ this.assistantID = StrCast(this.dataDoc.assistant_id);
+ this.vectorStoreID = StrCast(this.dataDoc.vector_store_id);
+ this.openai = this.initializeOpenAI();
+ if (this.assistantID === '' || this.threadID === '' || this.vectorStoreID === '') {
+ this.createAssistant();
+ } else {
+ this.retrieveCsvUrls();
+ this.isInitializing = false;
+ }
+ this.mathJaxConfig = {
+ loader: { load: ['input/asciimath'] },
+ tex: {
+ inlineMath: [
+ ['$', '$'],
+ ['\\(', '\\)'],
+ ],
+ displayMath: [
+ ['$$', '$$'],
+ ['[', ']'],
+ ],
+ },
+ };
+ reaction(
+ () => this.history.map((msg: AssistantMessage) => ({ role: msg.role, text: msg.text, image: msg.image, tool_logs: msg.tool_logs, links: msg.links })),
+ serializableHistory => {
+ this.dataDoc.data = JSON.stringify(serializableHistory);
+ }
+ );
+ }
+
+ toggleToolLogs = (index: number) => {
+ this.expandedLogIndex = this.expandedLogIndex === index ? null : index;
+ };
+
+ retrieveCsvUrls() {
+ const linkedDocs = LinkManager.Instance.getAllRelatedLinks(this.Document)
+ .map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)))
+ .map(d => DocCast(d?.annotationOn, d))
+ .filter(d => d);
+
+ linkedDocs.forEach(doc => {
+ const aiFieldId = StrCast(doc[this.Document[Id] + '_ai_field_id']);
+ if (CsvCast(doc.data)) {
+ this.linkedCsvIDs.push(StrCast(aiFieldId));
+ console.log(this.linkedCsvIDs);
+ }
+ });
+ }
+
+ initializeOpenAI() {
+ const configuration: ClientOptions = {
+ apiKey: process.env.OPENAI_KEY,
+ dangerouslyAllowBrowser: true,
+ };
+ return new OpenAI(configuration);
+ }
+
+ onPassiveWheel = (e: WheelEvent) => {
+ if (this._props.isContentActive()) {
+ e.stopPropagation();
+ }
+ };
+
+ createLink = (linkInfo: string, startIndex: number, endIndex: number, linkType: ANNOTATION_LINK_TYPE, annotationIndex: number = 0) => {
+ const text = this.interim_history;
+ const subString = this.current_message?.text.substring(startIndex, endIndex) ?? '';
+ if (!text) return;
+ const textToDisplay = `${annotationIndex}`;
+ let fileInfo = linkInfo;
+ const fileName = subString.split('/')[subString.split('/').length - 1];
+ if (linkType === ANNOTATION_LINK_TYPE.DOWNLOAD_FILE) {
+ fileInfo = linkInfo + '!!!' + fileName;
+ }
+
+ const formattedLink = `[${textToDisplay}](${fileInfo}~~~${linkType})`;
+ console.log(formattedLink);
+ const newText = text.replace(subString, formattedLink);
+ runInAction(() => {
+ this.interim_history = newText;
+ console.log(newText);
+ this.current_message?.links?.push({
+ start: startIndex,
+ end: endIndex,
+ url: linkType === ANNOTATION_LINK_TYPE.DOWNLOAD_FILE ? fileName : linkInfo,
+ id: linkType === ANNOTATION_LINK_TYPE.DOWNLOAD_FILE ? linkInfo : undefined,
+ link_type: linkType,
+ });
+ });
+ };
+
+ @action
+ createAssistant = async () => {
+ this.isInitializing = true;
+ try {
+ const vectorStore = await this.openai.beta.vectorStores.create({
+ name: 'Vector Store for Assistant',
+ });
+ const assistant = await this.openai.beta.assistants.create({
+ name: 'Document Analyser Assistant',
+ instructions: `
+ You will analyse documents with which you are provided. You will answer questions and provide insights based on the information in the documents.
+ For writing math formulas:
+ You have a MathJax render environment.
+ - Write all in-line equations within a single dollar sign, $, to render them as TeX (this means any time you want to use a dollar sign to represent a dollar sign itself, you must escape it with a backslash: "$");
+ - Use a double dollar sign, $$, to render equations on a new line;
+ Example: $$x^2 + 3x$$ is output for "x² + 3x" to appear as TeX.`,
+ model: 'gpt-4-turbo',
+ tools: [{ type: 'file_search' }, { type: 'code_interpreter' }],
+ tool_resources: {
+ file_search: {
+ vector_store_ids: [vectorStore.id],
+ },
+ code_interpreter: {
+ file_ids: this.linkedCsvIDs,
+ },
+ },
+ });
+ const thread = await this.openai.beta.threads.create();
+
+ runInAction(() => {
+ this.dataDoc.assistant_id = assistant.id;
+ this.dataDoc.thread_id = thread.id;
+ this.dataDoc.vector_store_id = vectorStore.id;
+ this.assistantID = assistant.id;
+ this.threadID = thread.id;
+ this.vectorStoreID = vectorStore.id;
+ this.isInitializing = false;
+ });
+ } catch (error) {
+ console.error('Initialization failed:', error);
+ this.isInitializing = false;
+ }
+ };
+
+ @action
+ runAssistant = async (inputText: string) => {
+ // Ensure an assistant and thread are created
+ if (!this.assistantID || !this.threadID || !this.vectorStoreID) {
+ await this.createAssistant();
+ console.log('Assistant and thread created:', this.assistantID, this.threadID);
+ }
+ let currentText: string = '';
+ let currentToolCallMessage: string = '';
+
+ // Send the user's input to the assistant
+ await this.openai.beta.threads.messages.create(this.threadID, {
+ role: 'user',
+ content: inputText,
+ });
+
+ // Listen to the streaming responses
+ const stream = this.openai.beta.threads.runs
+ .stream(this.threadID, {
+ assistant_id: this.assistantID,
+ })
+ .on('runStepCreated', (runStep: RunStep) => {
+ currentText = '';
+ runInAction(() => {
+ this.current_message = { role: ASSISTANT_ROLE.ASSISTANT, text: currentText, tool_logs: '', links: [] };
+ });
+ this.isLoading = true;
+ })
+ .on('toolCallDelta', (toolCallDelta, snapshot) => {
+ this.isLoading = false;
+ if (toolCallDelta.type === 'code_interpreter') {
+ if (toolCallDelta.code_interpreter?.input) {
+ currentToolCallMessage += toolCallDelta.code_interpreter.input;
+ runInAction(() => {
+ if (this.current_message) {
+ this.current_message.tool_logs = currentToolCallMessage;
+ }
+ });
+ }
+ if (toolCallDelta.code_interpreter?.outputs) {
+ currentToolCallMessage += '\n Code interpreter output:';
+ toolCallDelta.code_interpreter.outputs.forEach(output => {
+ if (output.type === 'logs') {
+ runInAction(() => {
+ if (this.current_message) {
+ this.current_message.tool_logs += '\n|' + output.logs;
+ }
+ });
+ }
+ });
+ }
+ }
+ })
+ .on('textDelta', (textDelta, snapshot) => {
+ this.isLoading = false;
+ currentText += textDelta.value;
+ runInAction(() => {
+ if (this.current_message) {
+ // this.current_message = {...this.current_message, text: current_text};
+ this.current_message.text = currentText;
+ }
+ });
+ })
+ .on('messageDone', async event => {
+ console.log(event);
+ const textItem = event.content.find(item => item.type === 'text');
+ if (textItem && textItem.type === 'text') {
+ const { text } = textItem;
+ console.log(text.value);
+ try {
+ runInAction(() => {
+ this.interim_history = text.value;
+ });
+ } catch (e) {
+ console.error('Error parsing JSON response:', e);
+ }
+
+ const { annotations } = text;
+ console.log('Annotations: ' + annotations);
+ let index = 0;
+ annotations.forEach(async annotation => {
+ console.log(' ' + annotation);
+ console.log(' ' + annotation.text);
+ if (annotation.type === 'file_path') {
+ const { file_path: filePath } = annotation;
+ const fileToDownload = filePath.file_id;
+ console.log(fileToDownload);
+ if (filePath) {
+ console.log(filePath);
+ console.log(fileToDownload);
+ this.createLink(fileToDownload, annotation.start_index, annotation.end_index, ANNOTATION_LINK_TYPE.DOWNLOAD_FILE);
+ }
+ } else {
+ const { file_citation: fileCitation } = annotation;
+ if (fileCitation) {
+ const citedFile = await this.openai.files.retrieve(fileCitation.file_id);
+ const citationUrl = citedFile.filename;
+ this.createLink(citationUrl, annotation.start_index, annotation.end_index, ANNOTATION_LINK_TYPE.DASH_DOC, index);
+ index++;
+ }
+ }
+ });
+ runInAction(() => {
+ if (this.current_message) {
+ console.log('current message: ' + this.current_message.text);
+ this.current_message.text = this.interim_history;
+ this.history.push({ ...this.current_message });
+ this.current_message = undefined;
+ }
+ });
+ }
+ })
+ .on('toolCallDone', toolCall => {
+ runInAction(() => {
+ if (this.current_message && currentToolCallMessage) {
+ this.current_message.tool_logs = currentToolCallMessage;
+ }
+ });
+ })
+ .on('imageFileDone', (content: ImageFile, snapshot: Message) => {
+ console.log('Image file done:', content);
+ })
+ .on('end', () => {
+ console.log('Streaming done');
+ });
+ };
+
+ @action
+ goToLinkedDoc = async (link: string) => {
+ const linkedDocs = LinkManager.Instance.getAllRelatedLinks(this.Document)
+ .map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)))
+ .map(d => DocCast(d?.annotationOn, d))
+ .filter(d => d);
+
+ const linkedDoc = linkedDocs.find(doc => {
+ const docUrl = CsvCast(doc.data, PDFCast(doc.data)).url.pathname.replace('/files/pdfs/', '').replace('/files/csvs/', '');
+ console.log('URL: ' + docUrl + ' Citation URL: ' + link);
+ return link === docUrl;
+ });
+
+ if (linkedDoc) {
+ await DocumentManager.Instance.showDocument(DocCast(linkedDoc), { willZoomCentered: true }, () => {});
+ }
+ };
+
+ @action
+ askGPT = async (event: React.FormEvent<HTMLFormElement>): Promise<void> => {
+ event.preventDefault();
+
+ const textInput = event.currentTarget.elements.namedItem('messageInput') as HTMLInputElement;
+ const trimmedText = textInput.value.trim();
+
+ if (!this.assistantID || !this.threadID) {
+ try {
+ await this.createAssistant();
+ } catch (err) {
+ console.error('Error:', err);
+ }
+ }
+
+ if (trimmedText) {
+ try {
+ textInput.value = '';
+ runInAction(() => {
+ this.history.push({ role: ASSISTANT_ROLE.USER, text: trimmedText });
+ });
+ await this.runAssistant(trimmedText);
+ this.dataDoc.data = this.history.toString();
+ } catch (err) {
+ console.error('Error:', err);
+ }
+ }
+ };
+
+ @action
+ uploadLinks = async (linkedDocs: Doc[]) => {
+ if (this.isInitializing) {
+ console.log('Initialization in progress, upload aborted.');
+ return;
+ }
+ const urls = linkedDocs.map(doc => CsvCast(doc.data, PDFCast(doc.data)).url.pathname);
+ const csvUrls = urls.filter(url => url.endsWith('.csv'));
+ console.log(this.assistantID, this.threadID, urls);
+
+ const { openai_file_ids: openaiFileIds } = await Networking.PostToServer('/uploadPDFToVectorStore', { urls, threadID: this.threadID, assistantID: this.assistantID, vector_store_id: this.vectorStoreID });
+
+ linkedDocs.forEach((doc, i) => {
+ doc[this.Document[Id] + '_ai_field_id'] = openaiFileIds[i];
+ console.log('AI Field ID: ' + openaiFileIds[i]);
+ });
+
+ if (csvUrls.length > 0) {
+ for (let i = 0; i < csvUrls.length; i++) {
+ this.linkedCsvIDs.push(openaiFileIds[urls.indexOf(csvUrls[i])]);
+ }
+ console.log('linked csvs:' + this.linkedCsvIDs);
+ await this.openai.beta.assistants.update(this.assistantID, {
+ tools: [{ type: 'file_search' }, { type: 'code_interpreter' }],
+ tool_resources: {
+ file_search: {
+ vector_store_ids: [this.vectorStoreID],
+ },
+ code_interpreter: {
+ file_ids: this.linkedCsvIDs,
+ },
+ },
+ });
+ }
+ };
+
+ downloadToComputer = (url: string, fileName: string) => {
+ fetch(url, { method: 'get', mode: 'no-cors', referrerPolicy: 'no-referrer' })
+ .then(res => res.blob())
+ .then(res => {
+ const aElement = document.createElement('a');
+ aElement.setAttribute('download', fileName);
+ const href = URL.createObjectURL(res);
+ aElement.href = href;
+ aElement.setAttribute('target', '_blank');
+ aElement.click();
+ URL.revokeObjectURL(href);
+ });
+ };
+
+ createDocumentInDash = async (url: string) => {
+ const fileSuffix = url.substring(url.lastIndexOf('.') + 1);
+ console.log(fileSuffix);
+ let doc: Doc | null = null;
+ switch (fileSuffix) {
+ case 'pdf':
+ doc = DocCast(await DocUtils.DocumentFromType('pdf', url, {}));
+ break;
+ case 'csv':
+ doc = DocCast(await DocUtils.DocumentFromType('csv', url, {}));
+ break;
+ case 'png':
+ case 'jpg':
+ case 'jpeg':
+ doc = DocCast(await DocUtils.DocumentFromType('image', url, {}));
+ break;
+ default:
+ console.error('Unsupported file type:', fileSuffix);
+ break;
+ }
+ if (doc) {
+ doc && this._props.addDocument?.(doc);
+ await DocumentManager.Instance.showDocument(doc, { willZoomCentered: true }, () => {});
+ }
+ };
+
+ downloadFile = async (fileInfo: string, downloadType: DOWNLOAD_TYPE) => {
+ try {
+ console.log(fileInfo);
+ const [fileId, fileName] = fileInfo.split(/!!!/);
+ const { file_path: filePath } = await Networking.PostToServer('/downloadFileFromOpenAI', { file_id: fileId, file_name: fileName });
+ const fileLink = CsvCast(new CsvField(filePath)).url.href;
+ if (downloadType === DOWNLOAD_TYPE.DASH) {
+ this.createDocumentInDash(fileLink);
+ } else {
+ this.downloadToComputer(fileLink, fileName);
+ }
+ } catch (error) {
+ console.error('Error downloading file:', error);
+ }
+ };
+
+ handleDownloadToDevice = () => {
+ this.downloadFile(this.currentFile.url, DOWNLOAD_TYPE.DEVICE);
+ this.modalStatus = false; // Close the modal after the action
+ this.currentFile = { url: '' }; // Reset the current file
+ };
+
+ handleAddToDash = () => {
+ // Assuming `downloadFile` is a method that handles adding to Dash
+ this.downloadFile(this.currentFile.url, DOWNLOAD_TYPE.DASH);
+ this.modalStatus = false; // Close the modal after the action
+ this.currentFile = { url: '' }; // Reset the current file
+ };
+
+ renderModal = () => {
+ if (!this.modalStatus) return null;
+
+ return (
+ <div className="modal">
+ <div className="modal-content">
+ <h4>File Actions</h4>
+ <p>Choose an action for the file:</p>
+ <button type="button" onClick={this.handleDownloadToDevice}>
+ Download to Device
+ </button>
+ <button type="button" onClick={this.handleAddToDash}>
+ Add to Dash
+ </button>
+ <button
+ type="button"
+ onClick={() => {
+ this.modalStatus = false;
+ }}>
+ Cancel
+ </button>
+ </div>
+ </div>
+ );
+ };
+ @action
+ showModal = () => {
+ this.modalStatus = true;
+ };
+
+ @action
+ setCurrentFile = (file: { url: string }) => {
+ this.currentFile = file;
+ };
+
+ componentDidMount() {
+ this._props.setContentViewBox?.(this);
+ if (this.dataDoc.data) {
+ try {
+ const storedHistory = JSON.parse(StrCast(this.dataDoc.data));
+ runInAction(() => {
+ this.history = storedHistory.map((msg: AssistantMessage) => ({
+ role: msg.role,
+ text: msg.text,
+ quote: msg.quote,
+ tool_logs: msg.tool_logs,
+ image: msg.image,
+ }));
+ });
+ } catch (e) {
+ console.error('Failed to parse history from dataDoc:', e);
+ }
+ }
+ reaction(
+ () => {
+ const linkedDocs = LinkManager.Instance.getAllRelatedLinks(this.Document)
+ .map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)))
+ .map(d => DocCast(d?.annotationOn, d))
+ .filter(d => d);
+ return linkedDocs;
+ },
+
+ linked => this.linked_docs_to_add.push(...linked.filter(linkedDoc => !this.linked_docs_to_add.includes(linkedDoc)))
+ );
+
+ observe(
+ // right now this skips during initialization which is necessary because it would be blank
+ // However, it will upload the same link twice when it is
+ this.linked_docs_to_add,
+ change => {
+ // observe pushes/splices on a user link DB 'data' field (should only happen for local changes)
+ switch (change.type as any) {
+ case 'splice':
+ if ((change as any).addedCount > 0) {
+ // maybe check here if its already in the urls datadoc array so doesn't add twice
+ console.log((change as any).added as Doc[]);
+ this.uploadLinks((change as any).added as Doc[]);
+ }
+ // (change as any).removed.forEach((link: any) => remLinkFromDoc(toRealField(link)));
+ break;
+ case 'update': // let oldValue = change.oldValue;
+ default:
+ }
+ },
+ true
+ );
+ }
+
+ render() {
+ return (
+ <MathJaxContext config={this.mathJaxConfig}>
+ <div className="chatBox">
+ {this.isInitializing && <div className="initializing-overlay">Initializing...</div>}
+ {this.renderModal()}
+ <div
+ className="scroll-box chat-content"
+ ref={r => {
+ this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel);
+ this._oldWheel = r;
+ r?.addEventListener('wheel', this.onPassiveWheel, { passive: false });
+ }}>
+ <div className="messages">
+ {this.history.map((message, index) => (
+ <MessageComponent
+ key={index}
+ message={message}
+ toggleToolLogs={this.toggleToolLogs}
+ expandedLogIndex={this.expandedLogIndex}
+ index={index}
+ showModal={this.showModal}
+ goToLinkedDoc={this.goToLinkedDoc}
+ setCurrentFile={this.setCurrentFile}
+ />
+ ))}
+ {!this.current_message ? null : (
+ <MessageComponent
+ key={this.history.length}
+ message={this.current_message}
+ toggleToolLogs={this.toggleToolLogs}
+ expandedLogIndex={this.expandedLogIndex}
+ index={this.history.length}
+ showModal={this.showModal}
+ goToLinkedDoc={this.goToLinkedDoc}
+ setCurrentFile={this.setCurrentFile}
+ isCurrent
+ />
+ )}
+ </div>
+ </div>
+ <form onSubmit={this.askGPT} className="chat-form">
+ <input type="text" name="messageInput" autoComplete="off" placeholder="Type a message..." />
+ <button type="submit">Send</button>
+ </form>
+ </div>
+ </MathJaxContext>
+ );
+ }
+}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.CHAT, {
+ layout: { view: ChatBox, dataField: 'data' },
+ options: { acl: '', chat: '', chat_history: '', chat_thread_id: '', chat_assistant_id: '', chat_vector_store_id: '' },
+});
diff --git a/src/client/views/nodes/ChatBox/MessageComponent.tsx b/src/client/views/nodes/ChatBox/MessageComponent.tsx
new file mode 100644
index 000000000..fced0b4d5
--- /dev/null
+++ b/src/client/views/nodes/ChatBox/MessageComponent.tsx
@@ -0,0 +1,116 @@
+/* eslint-disable react/require-default-props */
+import React from 'react';
+import { observer } from 'mobx-react';
+import { MathJax, MathJaxContext } from 'better-react-mathjax';
+import ReactMarkdown from 'react-markdown';
+import { TbCircle0Filled, TbCircle1Filled, TbCircle2Filled, TbCircle3Filled, TbCircle4Filled, TbCircle5Filled, TbCircle6Filled, TbCircle7Filled, TbCircle8Filled, TbCircle9Filled } from 'react-icons/tb';
+import { AssistantMessage } from './types';
+
+interface MessageComponentProps {
+ message: AssistantMessage;
+ toggleToolLogs: (index: number) => void;
+ expandedLogIndex: number | null;
+ index: number;
+ showModal: () => void;
+ goToLinkedDoc: (url: string) => void;
+ setCurrentFile: (file: { url: string }) => void;
+ isCurrent?: boolean;
+}
+
+const MessageComponent: React.FC<MessageComponentProps> = function ({ message, toggleToolLogs, expandedLogIndex, goToLinkedDoc, index, showModal, setCurrentFile, isCurrent = false }) {
+ // const messageClass = `${message.role} ${isCurrent ? 'current-message' : ''}`;
+
+ const LinkRenderer = ({ href, children }: { href: string; children: React.ReactNode }) => {
+ // console.log(href + " " + children)
+ const regex = /([a-zA-Z0-9_.!-]+)~~~(citation|file_path)/;
+ const matches = href.match(regex);
+ // console.log(href)
+ // console.log(matches)
+ const url = matches ? matches[1] : href;
+ const linkType = matches ? matches[2] : null;
+ if (linkType === 'citation') {
+ switch (children) {
+ case '0':
+ children = <TbCircle0Filled />;
+ break;
+ case '1':
+ children = <TbCircle1Filled />;
+ break;
+ case '2':
+ children = <TbCircle2Filled />;
+ break;
+ case '3':
+ children = <TbCircle3Filled />;
+ break;
+ case '4':
+ children = <TbCircle4Filled />;
+ break;
+ case '5':
+ children = <TbCircle5Filled />;
+ break;
+ case '6':
+ children = <TbCircle6Filled />;
+ break;
+ case '7':
+ children = <TbCircle7Filled />;
+ break;
+ case '8':
+ children = <TbCircle8Filled />;
+ break;
+ case '9':
+ children = <TbCircle9Filled />;
+ break;
+ default:
+ break;
+ }
+ }
+ // console.log(linkType)
+ const style = {
+ color: 'lightblue',
+ verticalAlign: linkType === 'citation' ? 'super' : 'baseline',
+ fontSize: linkType === 'citation' ? 'smaller' : 'inherit',
+ };
+
+ return (
+ <a
+ href="#"
+ onClick={e => {
+ e.preventDefault();
+ if (linkType === 'citation') {
+ goToLinkedDoc(url);
+ } else if (linkType === 'file_path') {
+ showModal();
+ setCurrentFile({ url });
+ }
+ }}
+ style={style}>
+ {children}
+ </a>
+ );
+ };
+
+ return (
+ <div className={`message ${message.role}`}>
+ <MathJaxContext>
+ <MathJax dynamic hideUntilTypeset="every">
+ <ReactMarkdown components={{ a: LinkRenderer }}>{message.text ? message.text : ''}</ReactMarkdown>
+ </MathJax>
+ </MathJaxContext>
+ {message.image && <img src={message.image} alt="" />}
+ <div className="message-footer">
+ {message.tool_logs && (
+ <button className="toggle-logs-button" onClick={() => toggleToolLogs(index)}>
+ {expandedLogIndex === index ? 'Hide Code Interpreter Logs' : 'Show Code Interpreter Logs'}
+ </button>
+ )}
+ {expandedLogIndex === index && (
+ <div className="tool-logs">
+ <pre>{message.tool_logs}</pre>
+ </div>
+ )}
+ </div>
+ </div>
+ );
+};
+
+export default observer(MessageComponent);
diff --git a/src/client/views/nodes/ChatBox/types.ts b/src/client/views/nodes/ChatBox/types.ts
new file mode 100644
index 000000000..8212a7050
--- /dev/null
+++ b/src/client/views/nodes/ChatBox/types.ts
@@ -0,0 +1,23 @@
+export enum ASSISTANT_ROLE {
+ USER = 'User',
+ ASSISTANT = 'Assistant',
+}
+
+export enum ANNOTATION_LINK_TYPE {
+ DASH_DOC = 'citation',
+ DOWNLOAD_FILE = 'file_path',
+}
+
+export enum DOWNLOAD_TYPE {
+ DASH = 'dash',
+ DEVICE = 'device',
+}
+
+export interface AssistantMessage {
+ role: ASSISTANT_ROLE;
+ text: string;
+ quote?: string;
+ image?: string;
+ tool_logs?: string;
+ links?: { start: number; end: number; url: string; id?: string; link_type: ANNOTATION_LINK_TYPE }[];
+}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 2800ea200..0bcaa06de 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,22 +1,24 @@
import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { OmitKeys, numberRange } from '../../../Utils';
+import { OmitKeys } from '../../../ClientUtils';
+import { numberRange } from '../../../Utils';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { TransitionTimer } from '../../../fields/DocSymbols';
+import { InkField } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { ComputedField } from '../../../fields/ScriptField';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { DocumentManager } from '../../util/DocumentManager';
+import { DragManager } from '../../util/DragManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
-import { SelectionManager } from '../../util/SelectionManager';
import { DocComponent } from '../DocComponent';
-import { StyleProp } from '../StyleProvider';
-import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
+import { StyleProp } from '../StyleProp';
import './CollectionFreeFormDocumentView.scss';
-import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView';
+import { DocumentView, DocumentViewProps } from './DocumentView';
import { FieldViewProps } from './FieldView';
+import { OpenWhere } from './OpenWhere';
/// Ugh, typescript has no run-time way of iterating through the keys of an interface. so we need
/// manaully keep this list of keys in synch wih the fields of the freeFormProps interface
@@ -36,16 +38,18 @@ interface freeFormProps {
highlight?: boolean;
transition?: string;
}
+
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
RenderCutoffProvider: (doc: Doc) => boolean;
- CollectionFreeFormView: CollectionFreeFormView;
+ isAnyChildContentActive: () => boolean;
+ parent: any;
}
@observer
export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps & freeFormProps>() {
get displayName() { // this makes mobx trace() statements more descriptive
return 'CollectionFreeFormDocumentView(' + this.Document.title + ')';
} // prettier-ignore
- public static CollectionFreeFormDocViewClassName = 'collectionFreeFormDocumentView-container';
+ public static CollectionFreeFormDocViewClassName = DragManager.dragClassName;
public static animFields: { key: string; val?: number }[] = [
{ key: 'x' },
{ key: 'y' },
@@ -61,6 +65,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
]; // fields that are configured to be animatable using animation frames
public static animStringFields = ['backgroundColor', 'color', 'fillColor']; // fields that are configured to be animatable using animation frames
public static animDataFields = (doc: Doc) => (Doc.LayoutFieldKey(doc) ? [Doc.LayoutFieldKey(doc)] : []); // fields that are configured to be animatable using animation frames
+ public static from(dv?: DocumentView): CollectionFreeFormDocumentView | undefined {
+ return dv?._props.parent instanceof CollectionFreeFormDocumentView ? dv._props.parent : undefined;
+ }
constructor(props: CollectionFreeFormDocumentViewProps & freeFormProps) {
super(props);
@@ -91,33 +98,53 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
@observable AutoDim = this.props.autoDim;
@observable Transition = this.props.transition;
+ componentDidMount(): void {
+ if (this.props.transition && !this.Document[TransitionTimer]) {
+ const num = Number(this.props.transition.match(/([0-9.]+)s/)?.[1]) * 1000 || Number(this.props.transition.match(/([0-9.]+)ms/)?.[1]);
+ this.Document[TransitionTimer] = setTimeout(
+ action(() => {
+ this.Document[TransitionTimer] = this.Transition = undefined;
+ }),
+ num
+ );
+ }
+ }
+
componentDidUpdate(prevProps: Readonly<React.PropsWithChildren<CollectionFreeFormDocumentViewProps & freeFormProps>>) {
super.componentDidUpdate(prevProps);
- this.WrapperKeys.forEach(action(keys => ((this as any)[keys.upper] = (this.props as any)[keys.lower])));
+ this.WrapperKeys.forEach(
+ action(keys => {
+ (this as any)[keys.upper] = (this.props as any)[keys.lower];
+ })
+ );
}
- CollectionFreeFormView = this.props.CollectionFreeFormView; // needed for type checking
// this way, downstream code only invalidates when it uses a specific prop, not when any prop changes
- DataTransition = () => this._props.transition; // prettier-ignore
+ DataTransition = () => this.Transition || StrCast(this.Document.dataTransition); // prettier-ignore
RenderCutoffProvider = this.props.RenderCutoffProvider; // needed for type checking
PanelWidth = () => this._props.autoDim ? this._props.PanelWidth?.() : this.Width; // prettier-ignore
PanelHeight = () => this._props.autoDim ? this._props.PanelHeight?.() : this.Height; // prettier-ignore
styleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
- if (doc === this.layoutDoc) {
- switch (property) {
- case StyleProp.Opacity: return this.Opacity; // only change the opacity for this specific document, not its children
+ const overrideProp = () => {
+ switch (property.split(':')[0]) {
+ case StyleProp.Opacity: return this.Opacity;
case StyleProp.BackgroundColor: return this.BackgroundColor;
case StyleProp.Color: return this.Color;
- } // prettier-ignore
- }
- return this._props.styleProvider?.(doc, props, property);
+ default: return undefined;
+ }}; // prettier-ignore
+
+ // only override values for this specific document, not any children
+ return (doc === this.layoutDoc ? overrideProp() : undefined) ?? this._props.styleProvider?.(doc, props, property);
};
public static getValues(doc: Doc, time: number, fillIn: boolean = true) {
return CollectionFreeFormDocumentView.animFields.reduce(
(p, val) => {
- p[val.key] = Cast(doc[`${val.key}_indexed`], listSpec('number'), fillIn ? [NumCast(doc[val.key], val.val)] : []).reduce((p, v, i) => ((i <= Math.round(time) && v !== undefined) || p === undefined ? v : p), undefined as any as number);
+ p[val.key] = Cast(doc[`${val.key}_indexed`], listSpec('number'), fillIn ? [NumCast(doc[val.key], val.val)] : []).reduce(
+ (prev, v, i) => ((i <= Math.round(time) && v !== undefined) || prev === undefined ? v : prev),
+ undefined as any as number
+ );
return p;
},
{} as { [val: string]: Opt<number> }
@@ -127,7 +154,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
public static getStringValues(doc: Doc, time: number) {
return CollectionFreeFormDocumentView.animStringFields.reduce(
(p, val) => {
- p[val] = Cast(doc[`${val}_indexed`], listSpec('string'), [StrCast(doc[val])]).reduce((p, v, i) => ((i <= Math.round(time) && v !== undefined) || p === undefined ? v : p), undefined as any as string);
+ p[val] = Cast(doc[`${val}_indexed`], listSpec('string'), [StrCast(doc[val])]).reduce((prev, v, i) => ((i <= Math.round(time) && v !== undefined) || prev === undefined ? v : prev), undefined as any as string);
return p;
},
{} as { [val: string]: Opt<string> }
@@ -138,7 +165,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
const timecode = Math.round(time);
Object.keys(vals).forEach(val => {
const findexed = Cast(d[`${val}_indexed`], listSpec('string'), []).slice();
- findexed[timecode] = vals[val] as any as string;
+ findexed[timecode] = vals[val] || '';
d[`${val}_indexed`] = new List<string>(findexed);
});
}
@@ -147,7 +174,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
const timecode = Math.round(time);
Object.keys(vals).forEach(val => {
const findexed = Cast(d[`${val}_indexed`], listSpec('number'), []).slice();
- findexed[timecode] = vals[val] as any as number;
+ findexed[timecode] = vals[val] || 0;
d[`${val}_indexed`] = new List<number>(findexed);
});
}
@@ -157,25 +184,50 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
const currentFrame = Cast(doc._currentFrame, 'number', null);
if (currentFrame === undefined) {
doc._currentFrame = 0;
- CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
+ this.setupKeyframes(childDocs, 0);
}
- CollectionFreeFormView.updateKeyframe(undefined, [...childDocs, doc], currentFrame || 0);
+ this.updateKeyframe(undefined, [...childDocs, doc], currentFrame || 0);
doc._currentFrame = newFrame === undefined ? 0 : Math.max(0, newFrame);
}
}
+ public static updateKeyframe(timer: NodeJS.Timeout | undefined, docs: Doc[], time: number) {
+ const newTimer = DocumentView.SetViewTransition(docs, 'all', 1000, timer, undefined, true);
+ const timecode = Math.round(time);
+ docs.forEach(doc => {
+ this.animFields.forEach(val => {
+ const findexed = Cast(doc[`${val.key}_indexed`], listSpec('number'), null);
+ findexed?.length <= timecode + 1 && findexed.push(undefined as any as number);
+ });
+ this.animStringFields.forEach(val => {
+ const findexed = Cast(doc[`${val}_indexed`], listSpec('string'), null);
+ findexed?.length <= timecode + 1 && findexed.push(undefined as any as string);
+ });
+ this.animDataFields(doc).forEach(val => {
+ const findexed = Cast(doc[`${val}_indexed`], listSpec(InkField), null);
+ findexed?.length <= timecode + 1 && findexed.push(undefined as any);
+ });
+ });
+ return newTimer;
+ }
public static setupKeyframes(docs: Doc[], currTimecode: number, makeAppear: boolean = false) {
docs.forEach(doc => {
if (doc.appearFrame === undefined) doc.appearFrame = currTimecode;
- if (!doc['opacity_indexed']) {
+ if (!doc.opacity_indexed) {
// opacity is unlike other fields because it's value should not be undefined before it appears to enable it to fade-in
- doc['opacity_indexed'] = new List<number>(numberRange(currTimecode + 1).map(t => (!doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1)));
+ doc.opacity_indexed = new List<number>(numberRange(currTimecode + 1).map(t => (!doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1)));
}
- CollectionFreeFormDocumentView.animFields.forEach(val => (doc[val.key] = ComputedField.MakeInterpolatedNumber(val.key, 'activeFrame', doc, currTimecode, val.val)));
- CollectionFreeFormDocumentView.animStringFields.forEach(val => (doc[val] = ComputedField.MakeInterpolatedString(val, 'activeFrame', doc, currTimecode)));
- CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => (doc[val] = ComputedField.MakeInterpolatedDataField(val, 'activeFrame', doc, currTimecode)));
+ CollectionFreeFormDocumentView.animFields.forEach(val => {
+ doc[val.key] = ComputedField.MakeInterpolatedNumber(val.key, 'activeFrame', doc, currTimecode, val.val);
+ });
+ CollectionFreeFormDocumentView.animStringFields.forEach(val => {
+ doc[val] = ComputedField.MakeInterpolatedString(val, 'activeFrame', doc, currTimecode);
+ });
+ CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => {
+ doc[val] = ComputedField.MakeInterpolatedDataField(val, 'activeFrame', doc, currTimecode);
+ });
const targetDoc = doc; // data fields, like rtf 'text' exist on the data doc, so
- //doc !== targetDoc && (targetDoc.embedContainer = doc.embedContainer); // the computed fields don't see the layout doc -- need to copy the embedContainer to the data doc (HACK!!!) and set the activeFrame on the data doc (HACK!!!)
+ // doc !== targetDoc && (targetDoc.embedContainer = doc.embedContainer); // the computed fields don't see the layout doc -- need to copy the embedContainer to the data doc (HACK!!!) and set the activeFrame on the data doc (HACK!!!)
targetDoc.activeFrame = ComputedField.MakeFunction('this.embedContainer?._currentFrame||0');
targetDoc.dataTransition = 'inherit';
});
@@ -186,22 +238,20 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
const containerDocView = this._props.containerViewPath?.().lastElement();
const screenXf = containerDocView?.screenToContentsTransform();
if (screenXf) {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
if (topDoc.z) {
const spt = screenXf.inverse().transformPoint(NumCast(topDoc.x), NumCast(topDoc.y));
topDoc.z = 0;
- topDoc.x = spt[0];
- topDoc.y = spt[1];
+ [topDoc.x, topDoc.y] = spt;
this._props.removeDocument?.(topDoc);
this._props.addDocTab(topDoc, OpenWhere.inParentFromScreen);
} else {
const spt = this.screenToLocalTransform().inverse().transformPoint(0, 0);
const fpt = screenXf.transformPoint(spt[0], spt[1]);
topDoc.z = 1;
- topDoc.x = fpt[0];
- topDoc.y = fpt[1];
+ [topDoc.x, topDoc.y] = fpt;
}
- setTimeout(() => SelectionManager.SelectView(DocumentManager.Instance.getDocumentView(topDoc, containerDocView), false), 0);
+ setTimeout(() => DocumentView.SelectView(DocumentView.getDocumentView(topDoc, containerDocView), false), 0);
}
};
@@ -223,10 +273,12 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
// 'inactive' - this is a group child but it is not active
// undefined - this is not activated by a group
isGroupActive = () => {
- if (this.CollectionFreeFormView.isAnyChildContentActive()) return undefined;
- const isGroup = this.dataDoc.isGroup && (!this.layoutDoc.backgroundColor || this.layoutDoc.backgroundColor === 'transparent');
+ if (this._props.isAnyChildContentActive()) return undefined;
+ const backColor = this.BackgroundColor;
+ const isGroup = this.dataDoc.isGroup && (!backColor || backColor === 'transparent');
return isGroup ? (this._props.isDocumentActive?.() ? 'group' : this._props.isGroupActive?.() ? 'child' : 'inactive') : this._props.isGroupActive?.() ? 'child' : undefined;
};
+ localRotation = () => this._props.rotation;
render() {
TraceMobx();
@@ -237,7 +289,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
width: this.PanelWidth(),
height: this.PanelHeight(),
transform: `translate(${this.X}px, ${this.Y}px) rotate(${NumCast(this.Rotation)}deg)`,
- transition: this.Transition || StrCast(this.Document.dataTransition),
+ transition: this.DataTransition(),
zIndex: this.ZIndex,
display: this.Width ? undefined : 'none',
}}>
@@ -245,18 +297,24 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
<div style={{ position: 'absolute', width: this.PanelWidth(), height: this.PanelHeight(), background: 'lightGreen' }} />
) : (
<DocumentView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...OmitKeys(this._props,this.WrapperKeys.map(val => val.lower)).omit} // prettier-ignore
+ parent={this}
DataTransition={this.DataTransition}
+ LocalRotation={this.localRotation}
CollectionFreeFormDocumentView={this.returnThis}
styleProvider={this.styleProvider}
ScreenToLocalTransform={this.screenToLocalTransform}
isGroupActive={this.isGroupActive}
+ PanelWidth={this.PanelWidth}
+ PanelHeight={this.PanelHeight}
/>
)}
</div>
);
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function gotoFrame(doc: any, newFrame: any) {
CollectionFreeFormDocumentView.gotoKeyFrame(doc, newFrame);
});
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 9fd4d696a..84d14d4ef 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -1,30 +1,31 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@mui/material';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnFalse, returnNone, returnZero, setupMoveUpEvents, unimplementedFunction } from '../../../Utils';
-import { Doc, Opt, DocListCast } from '../../../fields/Doc';
-import { DocCast, NumCast, RTFCast, StrCast } from '../../../fields/Types';
-import { DocUtils, Docs } from '../../documents/Documents';
-import { DragManager, dropActionType } from '../../util/DragManager';
-import { undoBatch } from '../../util/UndoManager';
-import { SnappingManager } from '../../util/SnappingManager';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
-import { StyleProp } from '../StyleProvider';
-import { Tooltip } from '@mui/material';
-import { CSSTransition } from 'react-transition-group';
+import { returnFalse, returnNone, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
+import { Doc, Opt } from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
+import { RichTextField } from '../../../fields/RichTextField';
+import { DocCast, NumCast, RTFCast, StrCast, toList } from '../../../fields/Types';
+import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
+import { DocUtils } from '../../documents/DocUtils';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
+import { undoable } from '../../util/UndoManager';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { PinDocView, PinProps } from '../PinFuncs';
+import { StyleProp } from '../StyleProp';
import './ComparisonBox.scss';
import { DocumentView } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
-import { PinProps, PresBox } from './trails';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
-import { RichTextField } from '../../../fields/RichTextField';
-import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
-import { DocData } from '../../../fields/DocSymbols';
-import { KeyValueBox } from './KeyValueBox';
@observer
-export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(ComparisonBox, fieldKey);
}
@@ -71,17 +72,17 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
}
};
- @undoBatch
- private internalDrop = (e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => {
+ private internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => {
if (dropEvent.complete.docDragData) {
- const droppedDocs = dropEvent.complete.docDragData?.droppedDocuments;
- const added = dropEvent.complete.docDragData.moveDocument?.(droppedDocs, this.Document, (doc: Doc | Doc[]) => this.addDoc(doc instanceof Doc ? doc : doc.lastElement(), fieldKey));
- Doc.SetContainer(droppedDocs.lastElement(), this.dataDoc);
+ const { droppedDocuments } = dropEvent.complete.docDragData;
+ const added = dropEvent.complete.docDragData.moveDocument?.(droppedDocuments, this.Document, (doc: Doc | Doc[]) => this.addDoc(toList(doc).lastElement(), fieldKey));
+ Doc.SetContainer(droppedDocuments.lastElement(), this.dataDoc);
!added && e.preventDefault();
e.stopPropagation(); // prevent parent Doc from registering new position so that it snaps back into place
return added;
}
- };
+ return undefined;
+ }, 'internal drop');
private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
if (e.button !== 2) {
@@ -90,11 +91,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
e,
this.onPointerMove,
emptyFunction,
- action((e, doubleTap) => {
+ action((moveEv, doubleTap) => {
if (doubleTap) {
this._isAnyChildContentActive = true;
- if (!this.dataDoc[this.fieldKey + '_1']) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
- if (!this.dataDoc[this.fieldKey + '_2']) this.dataDoc[this.fieldKey + '_2'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
+ if (!this.dataDoc[this.fieldKey + '_1'] && !this.dataDoc[this.fieldKey]) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
+ if (!this.dataDoc[this.fieldKey + '_2'] && !this.dataDoc[this.fieldKey + '_alternate']) this.dataDoc[this.fieldKey + '_2'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
}
}),
false,
@@ -107,7 +108,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this.layoutDoc[this.clipHeightKey] = (targetWidth * 100) / this._props.PanelHeight();
setTimeout(
- action(() => (this._animating = '')),
+ action(() => {
+ this._animating = '';
+ }),
200
);
})
@@ -133,18 +136,17 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
});
if (anchor) {
if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
- /* addAsAnnotation &&*/ this.addDocument(anchor);
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), clippable: true } }, this.Document);
+ /* addAsAnnotation && */ this.addDocument(anchor);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), clippable: true } }, this.Document);
return anchor;
}
return this.Document;
};
- @undoBatch
- clearDoc = (fieldKey: string) => {
+ clearDoc = undoable((fieldKey: string) => {
delete this.dataDoc[fieldKey];
this.dataDoc[fieldKey] = 'empty';
- };
+ }, 'clear doc');
// clearDoc = (fieldKey: string) => delete this.dataDoc[fieldKey];
moveDoc = (doc: Doc, addDocument: (document: Doc | Doc[]) => boolean, which: string) => this.remDoc(doc, which) && addDocument(doc);
@@ -162,33 +164,63 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
return false;
};
- whenChildContentsActiveChanged = action((isActive: boolean) => (this._isAnyChildContentActive = isActive));
-
closeDown = (e: React.PointerEvent, which: string) => {
setupMoveUpEvents(
this,
e,
- e => {
+ moveEv => {
const de = new DragManager.DocumentDragData([DocCast(this.dataDoc[which])], dropActionType.move);
de.moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => {
return addDocument(doc);
};
de.canEmbed = true;
- DragManager.StartDocumentDrag([this._closeRef.current!], de, e.clientX, e.clientY);
+ DragManager.StartDocumentDrag([this._closeRef.current!], de, moveEv.clientX, moveEv.clientY);
return true;
},
emptyFunction,
- e => this.clearDoc(which)
+ () => this.clearDoc(which)
);
};
docStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
if (property === StyleProp.PointerEvents) return 'none';
return this._props.styleProvider?.(doc, props, property);
};
- moveDoc1 = (doc: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true);
- moveDoc2 = (doc: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true);
- remDoc1 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true);
- remDoc2 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true);
+ moveDoc1 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true);
+ moveDoc2 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true);
+ remDoc1 = (docs: Doc | Doc[]) => toList(docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true);
+ remDoc2 = (docs: Doc | Doc[]) => toList(docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true);
+
+ /**
+ * Tests for whether a comparison box slot (ie, before or after) has renderable text content
+ * @param whichSlot field key for start or end slot
+ * @returns a JSX layout string if a text field is found, othwerise undefined
+ */
+ testForTextFields = (whichSlot: string) => {
+ const slotData = Doc.Get(this.dataDoc, whichSlot, true);
+ const slotHasText = slotData instanceof RichTextField || typeof slotData === 'string';
+ const subjectText = RTFCast(this.Document[this.fieldKey])?.Text.trim();
+ const altText = RTFCast(this.Document[this.fieldKey + '_alternate'])?.Text.trim();
+ const layoutTemplateString =
+ slotHasText ? FormattedTextBox.LayoutString(whichSlot):
+ whichSlot.endsWith('1') ? (subjectText !== undefined ? FormattedTextBox.LayoutString(this.fieldKey) : undefined) :
+ altText !== undefined ? FormattedTextBox.LayoutString(this.fieldKey + '_alternate'): undefined; // prettier-ignore
+
+ // A bit hacky to try out the concept of using GPT to fill in flashcards
+ // If the second slot doesn't have anything in it, but the fieldKey slot has text (e.g., this.text is a string)
+ // and the fieldKey + "_alternate" has text that includes a GPT query (indicated by (( && )) ) that is parameterized (optionally) by the fieldKey text (this) or other metadata (this.<field>).
+ // eg., this.text_alternate is
+ // "((Provide a one sentence definition for (this) that doesn't use any word in (this.excludeWords) ))"
+ // where (this) is replaced by the text in the fieldKey slot abd this.excludeWords is repalced by the conetnts of the excludeWords field
+ // The GPT call will put the "answer" in the second slot of the comparison (eg., text_2)
+ if (whichSlot.endsWith('2') && !layoutTemplateString?.includes(whichSlot)) {
+ const queryText = altText?.replace('(this)', subjectText); // TODO: this should be done in Doc.setField but it doesn't know about the fieldKey ...
+ if (queryText?.match(/\(\(.*\)\)/)) {
+ Doc.SetField(this.Document, whichSlot, ':=' + queryText, false); // make the second slot be a computed field on the data doc that calls ChatGpt
+ }
+ }
+ return layoutTemplateString;
+ };
+
_closeRef = React.createRef<HTMLDivElement>();
/**
@@ -283,22 +315,24 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
</Tooltip>
);
};
- const displayDoc = (which: string) => {
- const whichDoc = DocCast(this.dataDoc[which]);
+ const displayDoc = (whichSlot: string) => {
+ const whichDoc = DocCast(this.dataDoc[whichSlot]);
const targetDoc = DocCast(whichDoc?.annotationOn, whichDoc);
// if there is no Doc in the first comparison slot, but the comparison box's fieldKey slot has a RichTextField, then render a text box to show the contents of the document's field key slot
- const layoutTemplateString = !targetDoc && which.endsWith('1') && this.Document[this.fieldKey] instanceof RichTextField ? FormattedTextBox.LayoutString(this.fieldKey) : undefined;
+ const layoutString = !targetDoc && whichSlot.endsWith('1') && this.Document[this.fieldKey] instanceof RichTextField ? FormattedTextBox.LayoutString(this.fieldKey) : undefined;
- return targetDoc || layoutTemplateString ? (
+ return targetDoc || layoutString ? (
<>
<DocumentView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
+ ignoreUsePath={layoutString ? true : undefined}
renderDepth={this.props.renderDepth + 1}
- LayoutTemplateString={layoutTemplateString}
- Document={layoutTemplateString ? this.Document : targetDoc}
+ LayoutTemplateString={layoutString}
+ Document={layoutString ? this.Document : targetDoc}
containerViewPath={this.DocumentView?.().docViewPath}
- moveDocument={which.endsWith('1') ? this.moveDoc1 : this.moveDoc2}
- removeDocument={which.endsWith('1') ? this.remDoc1 : this.remDoc2}
+ moveDocument={whichSlot.endsWith('1') ? this.moveDoc1 : this.moveDoc2}
+ removeDocument={whichSlot.endsWith('1') ? this.remDoc1 : this.remDoc2}
NativeWidth={() => NumCast(this.layoutDoc.width, 200)}
NativeHeight={(): number => {
return NumCast(this.layoutDoc.height, 200);
@@ -307,10 +341,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
isDocumentActive={returnFalse}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
styleProvider={this._isAnyChildContentActive ? this._props.styleProvider : this.docStyleProvider}
- hideLinkButton={true}
+ hideLinkButton
pointerEvents={this._isAnyChildContentActive ? undefined : returnNone}
/>
- {layoutTemplateString ? null : clearButton(which)}
+ {layoutString ? null : clearButton(whichSlot)}
</> // placeholder image if doc is missing
) : (
<div className="placeholder">
@@ -318,13 +352,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
</div>
);
};
- const displayBox = (which: string, index: number, cover: number) => {
- return (
- <div className={`${index === 0 ? 'before' : 'after'}Box-cont`} key={which} style={{ width: this._props.PanelWidth() }} onPointerDown={e => this.registerSliding(e, cover)} ref={ele => this.createDropTarget(ele, which, index)}>
- {displayDoc(which)}
- </div>
- );
- };
+ const displayBox = (which: string, index: number, cover: number) => (
+ <div className={`${index === 0 ? 'before' : 'after'}Box-cont`} key={which} style={{ width: this._props.PanelWidth() }} onPointerDown={e => this.registerSliding(e, cover)} ref={ele => this.createDropTarget(ele, which, index)}>
+ {displayDoc(which)}
+ </div>
+ );
const displayBoxReveal = (which: string, which2: string, index: number, cover: number) => {
return (
@@ -434,3 +466,18 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
}
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.COMPARISON, {
+ data: '',
+ layout: { view: ComparisonBox, dataField: 'data' },
+ options: {
+ acl: '',
+ backgroundColor: 'gray',
+ dropAction: dropActionType.move,
+ waitForDoubleClickToClick: 'always',
+ _layout_reflowHorizontal: true,
+ _layout_reflowVertical: true,
+ _layout_nativeDimEditable: true,
+ systemIcon: 'BsLayoutSplit',
+ },
+});
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.scss b/src/client/views/nodes/DataVizBox/DataVizBox.scss
index 6b5738790..9825d926f 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.scss
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.scss
@@ -30,8 +30,17 @@
}
.liveSchema-checkBox {
+ margin-left: 10px;
margin-bottom: -35px;
}
+ .filterData-checkBox {
+ margin-left: 10px;
+ margin-bottom: -10px;
+ }
+
+ .displaySchemaLive {
+ margin-bottom: 20px;
+ }
.dataviz-sidebar {
position: absolute;
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 66a08f13e..4d5f15a3e 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -1,33 +1,37 @@
+/* eslint-disable react/jsx-props-no-spreading */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Checkbox } from '@mui/material';
import { Colors, Toggle, ToggleType, Type } from 'browndash-components';
import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils';
+import { returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../../fields/Doc';
import { InkTool } from '../../../../fields/InkField';
import { List } from '../../../../fields/List';
-import { listSpec } from '../../../../fields/Schema';
import { Cast, CsvCast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
import { CsvField } from '../../../../fields/URLField';
import { TraceMobx } from '../../../../fields/util';
-import { DocUtils, Docs } from '../../../documents/Documents';
-import { DocumentManager } from '../../../util/DocumentManager';
+import { DocUtils } from '../../../documents/DocUtils';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
import { UndoManager, undoable } from '../../../util/UndoManager';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent';
+import { ContextMenu } from '../../ContextMenu';
+import { ViewBoxAnnotatableComponent } from '../../DocComponent';
import { MarqueeAnnotator } from '../../MarqueeAnnotator';
+import { PinProps } from '../../PinFuncs';
import { SidebarAnnos } from '../../SidebarAnnos';
import { AnchorMenu } from '../../pdf/AnchorMenu';
-import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup';
+import { GPTPopup, GPTPopupMode } from '../../pdf/GPTPopup/GPTPopup';
import { DocumentView } from '../DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView';
-import { PinProps } from '../trails';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import './DataVizBox.scss';
import { Histogram } from './components/Histogram';
import { LineChart } from './components/LineChart';
import { PieChart } from './components/PieChart';
import { TableBox } from './components/TableBox';
-import { Checkbox } from '@mui/material';
export enum DataVizView {
TABLE = 'table',
@@ -37,12 +41,13 @@ export enum DataVizView {
}
@observer
-export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
private _marqueeref = React.createRef<MarqueeAnnotator>();
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
private _disposers: { [name: string]: IReactionDisposer } = {};
anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
+ 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<number, HTMLDivElement[]>();
@@ -62,9 +67,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
setupMoveUpEvents(
this,
e,
- action(e => {
+ action(moveEv => {
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
- this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]);
+ this._marqueeref.current?.onInitiateSelection([moveEv.clientX, moveEv.clientY]);
return true;
}),
returnFalse,
@@ -95,7 +100,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
// all CSV records in the dataset (that aren't an empty row)
@computed.struct get records() {
- var records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href);
+ const records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href);
return records?.filter(record => Object.keys(record).some(key => record[key])) ?? [];
}
@@ -110,31 +115,36 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
@computed.struct get axes() {
return StrListCast(this.layoutDoc._dataViz_axes);
}
- selectAxes = (axes: string[]) => (this.layoutDoc._dataViz_axes = new List<string>(axes));
+ selectAxes = (axes: string[]) => {
+ this.layoutDoc._dataViz_axes = new List<string>(axes);
+ };
@computed.struct get titleCol() {
return StrCast(this.layoutDoc._dataViz_titleCol);
}
- selectTitleCol = (titleCol: string) => (this.layoutDoc._dataViz_titleCol = titleCol);
+ selectTitleCol = (titleCol: string) => {
+ this.layoutDoc._dataViz_titleCol = titleCol;
+ };
@action // pinned / linked anchor doc includes selected rows, graph titles, and graph colors
restoreView = (data: Doc) => {
- const changedView = this.dataVizView !== data.config_dataViz && (this.layoutDoc._dataViz = data.config_dataViz);
- const changedAxes = this.axes.join('') !== StrListCast(data.config_dataVizAxes).join('') && (this.layoutDoc._dataViz_axes = new List<string>(StrListCast(data.config_dataVizAxes)));
+ // const changedView = data.config_dataViz && this.dataVizView !== data.config_dataViz && (this.layoutDoc._dataViz = data.config_dataViz);
+ // const changedAxes = data.config_dataVizAxes && this.axes.join('') !== StrListCast(data.config_dataVizAxes).join('') && (this.layoutDoc._dataViz_axes = new List<string>(StrListCast(data.config_dataVizAxes)));
this.layoutDoc.dataViz_selectedRows = Field.Copy(data.dataViz_selectedRows);
this.layoutDoc.dataViz_histogram_barColors = Field.Copy(data.dataViz_histogram_barColors);
this.layoutDoc.dataViz_histogram_defaultColor = data.dataViz_histogram_defaultColor;
this.layoutDoc.dataViz_pie_sliceColors = Field.Copy(data.dataViz_pie_sliceColors);
- Object.keys(this.layoutDoc).map(key => {
+ Object.keys(this.layoutDoc).forEach(key => {
if (key.startsWith('dataViz_histogram_title') || key.startsWith('dataViz_lineChart_title') || key.startsWith('dataViz_pieChart_title')) {
this.layoutDoc['_' + key] = data[key];
}
});
- const func = () => this._vizRenderer?.restoreView(data);
- if (changedView || changedAxes) {
- setTimeout(func, 100);
- return true;
- }
- return func() ?? false;
+ return true;
+ // const func = () => this._vizRenderer?.restoreView(data);
+ // if (changedView || changedAxes) {
+ // setTimeout(func, 100);
+ // return true;
+ // }
+ // return func() ?? false;
};
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
const visibleAnchor = AnchorMenu.Instance.GetAnchor?.(undefined, addAsAnnotation);
@@ -150,7 +160,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
annotationOn: this.Document,
// when we clear selection -> we should have it so chartBox getAnchor returns undefined
// this is for when we want the whole doc (so when the chartBox getAnchor returns without a marker)
- /*put in some options*/
+ /* put in some options */
});
anchor.config_dataViz = this.dataVizView;
anchor.config_dataVizAxes = this.axes.length ? new List<string>(this.axes) : undefined;
@@ -158,24 +168,21 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
anchor.dataViz_histogram_barColors = Field.Copy(this.layoutDoc.dataViz_histogram_barColors);
anchor.dataViz_histogram_defaultColor = this.layoutDoc.dataViz_histogram_defaultColor;
anchor.dataViz_pie_sliceColors = Field.Copy(this.layoutDoc.dataViz_pie_sliceColors);
- Object.keys(this.layoutDoc).map(key => {
+ Object.keys(this.layoutDoc).forEach(key => {
if (key.startsWith('dataViz_histogram_title') || key.startsWith('dataViz_lineChart_title') || key.startsWith('dataViz_pieChart_title')) {
anchor[key] = this.layoutDoc[key];
}
});
this.addDocument(anchor);
- //addAsAnnotation && this.addDocument(anchor);
+ // addAsAnnotation && this.addDocument(anchor);
return anchor;
};
createNoteAnnotation = () => {
- const createFunc = undoable(
- action(() => {
- const note = this._sidebarRef.current?.anchorMenuClick(this.getAnchor(false), ['latitude', 'longitude', '-linkedTo']);
- }),
- 'create note annotation'
- );
+ const createFunc = undoable(() => {
+ this._sidebarRef.current?.anchorMenuClick(this.getAnchor(false), ['latitude', 'longitude', '-linkedTo']);
+ }, 'create note annotation');
if (!this.layoutDoc.layout_showSidebar) {
this.toggleSidebar();
setTimeout(createFunc);
@@ -192,7 +199,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
};
@computed get SidebarShown() {
- return this.layoutDoc._layout_showSidebar ? true : false;
+ return !!this.layoutDoc._layout_showSidebar;
}
@computed get sidebarHandle() {
return (
@@ -206,7 +213,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={this.sidebarBtnDown}>
- <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" />
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon="comment-alt" size="sm" />
</div>
);
}
@@ -218,7 +225,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
setupMoveUpEvents(
this,
e,
- (e, down, delta) =>
+ (moveEv, down, delta) =>
runInAction(() => {
const localDelta = this._props
.ScreenToLocalTransform()
@@ -246,7 +253,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
options.didMove = true;
this.toggleSidebar();
}
- return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
+ return new Promise<Opt<DocumentView>>(res => {
+ DocumentView.addViewRenderedCb(doc, dv => res(dv));
+ });
};
@computed get sidebarWidthPercent() {
return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%');
@@ -266,59 +275,60 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
if (!DataVizBox.dataset.has(CsvCast(this.dataDoc[this.fieldKey]).url.href)) this.fetchData();
this._disposers.datavis = reaction(
() => {
- if (this.layoutDoc.dataViz_schemaLive==undefined) this.layoutDoc.dataViz_schemaLive = true;
+ if (this.layoutDoc.dataViz_schemaLive === undefined) this.layoutDoc.dataViz_schemaLive = true;
const getFrom = DocCast(this.layoutDoc.dataViz_asSchema);
- const keys = Cast(getFrom?.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text');
- if (!keys) return;
- const children = DocListCast(getFrom[Doc.LayoutFieldKey(getFrom)]);
- var current: { [key: string]: string }[] = [];
+ if (!getFrom?.schema_columnKeys) return undefined;
+ const keys = StrListCast(getFrom?.schema_columnKeys).filter(key => key !== 'text');
+ const children = DocListCast(getFrom?.[Doc.LayoutFieldKey(getFrom)]);
+ const current: { [key: string]: string }[] = [];
children
.filter(child => child)
.forEach(child => {
const row: { [key: string]: string } = {};
keys.forEach(key => {
- var cell = child[key];
- if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
+ let cell = child[key];
+ if (cell && (cell as string)) cell = cell.toString().replace(/,/g, '');
row[key] = StrCast(cell);
});
current.push(row);
});
- if (!this.layoutDoc._dataViz_schemaOG){ // makes a copy of the original table for the "live" toggle
- let csvRows = [];
- csvRows.push(keys.join(','));
- for (let i = 0; i < children.length-1; i++) {
- let eachRow = [];
- for (let j = 0; j < keys.length; j++) {
- var cell = children[i][keys[j]];
- if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
- eachRow.push(cell);
- }
- csvRows.push(eachRow);
+ if (!this.layoutDoc._dataViz_schemaOG) {
+ // makes a copy of the original table for the "live" toggle
+ const csvRows = [];
+ csvRows.push(keys.join(','));
+ for (let i = 0; i < children.length - 1; i++) {
+ const eachRow = [];
+ for (let j = 0; j < keys.length; j++) {
+ let cell = children[i][keys[j]];
+ if (cell && (cell as string)) cell = cell.toString().replace(/,/g, '');
+ eachRow.push(cell);
}
- const blob = new Blob([csvRows.join('\n')], { type: 'text/csv' });
- const options = { x: 0, y: 0, title: 'schemaTable for static dataviz', _width: 300, _height: 100, type: 'text/csv' };
- const file = new File([blob], 'schemaTable for static dataviz', options);
- const loading = Docs.Create.LoadingDocument(file, options);
- DocUtils.uploadFileToDoc(file, {}, loading);
- this.layoutDoc._dataViz_schemaOG = loading;
- }
- const ogDoc = this.layoutDoc._dataViz_schemaOG as Doc
- const ogHref = CsvCast(ogDoc[this.fieldKey])? CsvCast(ogDoc[this.fieldKey]).url.href : undefined;
- const href = CsvCast(this.Document[this.fieldKey]).url.href
- if (ogHref && !DataVizBox.datasetSchemaOG.has(href)){ // sets original dataset to the var
- const lastRow = current.pop();
- DataVizBox.datasetSchemaOG.set(href, current);
- current.push(lastRow!);
- fetch('/csvData?uri=' + ogHref)
- .then(res => res.json().then(action(res => !res.errno && DataVizBox.datasetSchemaOG.set(href, res))));
+ csvRows.push(eachRow);
}
+ const blob = new Blob([csvRows.join('\n')], { type: 'text/csv' });
+ const options = { x: 0, y: 0, title: 'schemaTable for static dataviz', _width: 300, _height: 100, type: 'text/csv' };
+ const file = new File([blob], 'schemaTable for static dataviz', options);
+ const loading = Docs.Create.LoadingDocument(file, options);
+ DocUtils.uploadFileToDoc(file, {}, loading);
+ this.layoutDoc._dataViz_schemaOG = loading;
+ }
+ const ogDoc = this.layoutDoc._dataViz_schemaOG as Doc;
+ const ogHref = CsvCast(ogDoc[this.fieldKey]) ? CsvCast(ogDoc[this.fieldKey]).url.href : undefined;
+ const { href } = CsvCast(this.Document[this.fieldKey]).url;
+ if (ogHref && !DataVizBox.datasetSchemaOG.has(href)) {
+ // sets original dataset to the var
+ const lastRow = current.pop();
+ DataVizBox.datasetSchemaOG.set(href, current);
+ current.push(lastRow!);
+ fetch('/csvData?uri=' + ogHref).then(res => res.json().then(action(jsonRes => !jsonRes.errno && DataVizBox.datasetSchemaOG.set(href, jsonRes))));
+ }
return current;
},
current => {
if (current) {
- const href = CsvCast(this.Document[this.fieldKey]).url.href;
- if (this.layoutDoc.dataViz_schemaLive) DataVizBox.dataset.set(href, current);
- else DataVizBox.dataset.set(href, DataVizBox.datasetSchemaOG.get(href)!);
+ const { href } = CsvCast(this.Document[this.fieldKey]).url;
+ if (this.layoutDoc.dataViz_schemaLive) DataVizBox.dataset.set(href, current);
+ else DataVizBox.dataset.set(href, DataVizBox.datasetSchemaOG.get(href)!);
}
},
{ fireImmediately: true }
@@ -328,8 +338,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
fetchData = () => {
if (!this.Document.dataViz_asSchema) {
DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, []); // assign temporary dataset as a lock to prevent duplicate server requests
- fetch('/csvData?uri=' + this.dataUrl?.url.href) //
- .then(res => res.json().then(action(res => !res.errno && DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, res))));
+ fetch('/csvData?uri=' + (this.dataUrl?.url.href ?? '')) //
+ .then(res => res.json().then(action(jsonRes => !jsonRes.errno && DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, jsonRes))));
}
};
@@ -342,19 +352,21 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
records: this.records,
axes: this.axes,
titleCol: this.titleCol,
- //width: this.SidebarShown? this._props.PanelWidth()*.9/1.2: this._props.PanelWidth() * 0.9,
- height: (this._props.PanelHeight() / scale - 32) /* height of 'change view' button */ * 0.9,
+ // width: this.SidebarShown? this._props.PanelWidth()*.9/1.2: this._props.PanelWidth() * 0.9,
+ height: (this._props.PanelHeight() / scale - 55) /* height of 'change view' button */ * 0.8,
width: ((this._props.PanelWidth() - this.sidebarWidth()) / scale) * 0.9,
margin: { top: 10, right: 25, bottom: 75, left: 45 },
};
if (!this.records.length) return 'no data/visualization';
switch (this.dataVizView) {
case DataVizView.TABLE: return <TableBox {...sharedProps} docView={this.DocumentView} selectAxes={this.selectAxes} selectTitleCol={this.selectTitleCol}/>;
- case DataVizView.LINECHART: return <LineChart {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)} vizBox={this} />;
- case DataVizView.HISTOGRAM: return <Histogram {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)} />;
- case DataVizView.PIECHART: return <PieChart {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)}
+ case DataVizView.LINECHART: return <LineChart {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => {this._vizRenderer = r ?? undefined;}} vizBox={this} />;
+ case DataVizView.HISTOGRAM: return <Histogram {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => {this._vizRenderer = r ?? undefined;}} />;
+ case DataVizView.PIECHART: return <PieChart {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => {this._vizRenderer = r ?? undefined;}}
margin={{ top: 10, right: 15, bottom: 15, left: 15 }} />;
+ default:
} // prettier-ignore
+ return null;
}
@action
@@ -366,10 +378,13 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
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'))) {
+ /* empty */
} else {
// if textLayer is hit, then we select text instead of using a marquee so clear out the marquee.
setTimeout(
- action(() => (this._marqueeing = undefined)),
+ action(() => {
+ this._marqueeing = undefined;
+ }),
100
); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it.
@@ -397,16 +412,81 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
GPTPopup.Instance.addDoc = this.sidebarAddDocument;
};
+ // represents whether or not a data viz box created from a schema table displays live updates to the canvas
@action
changeLiveSchemaCheckbox = () => {
- this.layoutDoc.dataViz_schemaLive = !this.layoutDoc.dataViz_schemaLive
- }
+ this.layoutDoc.dataViz_schemaLive = !this.layoutDoc.dataViz_schemaLive;
+ };
+
+ // represents whether or not clicking on a peice of data in the visualization
+ // (i.e. a data point in a linechart, a bar on a histogram, or a slice of a pie chart)
+ // filters the data onto a new data viz doc created off of this one
+ @action
+ changeFilteringCheckbox = () => {
+ this.layoutDoc.dataViz_filterSelection = !this.layoutDoc.dataViz_filterSelection;
+ };
+
+ specificContextMenu = (): void => {
+ const cm = ContextMenu.Instance;
+ const options = cm.findByDescription('Options...');
+ const optionItems = options && 'subitems' in options ? options.subitems : [];
+ optionItems.push({ description: `Analyze with AI`, event: () => this.askGPT(), icon: 'lightbulb' });
+ !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' });
+ };
+
+ askGPT = action(async () => {
+ GPTPopup.Instance.setSidebarId('data_sidebar');
+ GPTPopup.Instance.addDoc = this.sidebarAddDocument;
+ GPTPopup.Instance.createFilteredDoc = this.createFilteredDoc;
+ GPTPopup.Instance.setDataJson('');
+ GPTPopup.Instance.setMode(GPTPopupMode.DATA);
+ const data = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href);
+ GPTPopup.Instance.setDataJson(JSON.stringify(data));
+ GPTPopup.Instance.generateDataAnalysis();
+ });
+
+ /**
+ * creates a new dataviz document filter from this one
+ * it appears to the right of this document, with the
+ * parameters passed in being used to create an initial display
+ */
+ createFilteredDoc = (axes?: any) => {
+ const embedding = Doc.MakeEmbedding(this.Document!);
+ embedding._layout_showSidebar = false;
+ embedding._dataViz = DataVizView.LINECHART;
+ embedding._dataViz_axes = new List<string>(axes);
+ embedding._dataViz_parentViz = this.Document;
+ embedding.histogramBarColors = Field.Copy(this.layoutDoc.histogramBarColors);
+ embedding.defaultHistogramColor = this.layoutDoc.defaultHistogramColor;
+ embedding.pieSliceColors = Field.Copy(this.layoutDoc.pieSliceColors);
+ embedding._layout_showSidebar = false;
+ embedding.width = NumCast(this.layoutDoc._width) - this.sidebarWidth();
+ embedding._layout_sidebarWidthPercent = '0%';
+ this._props.addDocument?.(embedding);
+ embedding._dataViz_axes = new List<string>(axes);
+ this.layoutDoc.dataViz_selectedRows = new List<number>(this.records.map((rec, i) => i));
+ embedding.x = Number(embedding.x) + Number(this.Document.width);
+
+ return true;
+ };
render() {
const scale = this._props.NativeDimScaling?.() || 1;
+ const toggleBtn = (name: string, type: DataVizView) => (
+ <Toggle
+ text={name}
+ toggleType={ToggleType.BUTTON}
+ type={Type.SEC}
+ color="black"
+ onClick={() => {
+ this.layoutDoc._dataViz = type;
+ }}
+ toggleStatus={this.layoutDoc._dataViz === type}
+ />
+ );
return !this.records.length ? (
// displays how to get data into the DataVizBox if its empty
- <div className="start-message">To create a DataViz box, either import / drag a CSV file into your canvas or copy a data table and use the command 'ctrl + p' to bring the data table to your canvas.</div>
+ <div className="start-message">To create a DataViz box, either import / drag a CSV file into your canvas or copy a data table and use the command (ctrl + p) to bring the data table to your canvas.</div>
) : (
<div
className="dataViz-box"
@@ -418,20 +498,29 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
transform: `scale(${scale})`,
position: 'absolute',
}}
+ onContextMenu={this.specificContextMenu}
onWheel={e => e.stopPropagation()}
ref={this._mainCont}>
<div className="datatype-button">
- <Toggle text={' TABLE '} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.TABLE)} toggleStatus={this.layoutDoc._dataViz === DataVizView.TABLE} />
- <Toggle text={'LINECHART'} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.LINECHART)} toggleStatus={this.layoutDoc._dataViz === DataVizView.LINECHART} />
- <Toggle text={'HISTOGRAM'} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.HISTOGRAM)} toggleStatus={this.layoutDoc._dataViz === DataVizView.HISTOGRAM} />
- <Toggle text={'PIE CHART'} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.PIECHART)} toggleStatus={this.layoutDoc._dataViz == -DataVizView.PIECHART} />
+ {toggleBtn(' TABLE ', DataVizView.TABLE)}
+ {toggleBtn('LINECHART', DataVizView.LINECHART)}
+ {toggleBtn('HISTOGRAM', DataVizView.HISTOGRAM)}
+ {toggleBtn('PIE CHART', DataVizView.PIECHART)}
</div>
- {(this.layoutDoc && this.layoutDoc.dataViz_asSchema)?(
- <div className={'liveSchema-checkBox'} style={{ width: this._props.width }}>
- <Checkbox color="primary" onChange={this.changeLiveSchemaCheckbox} checked={this.layoutDoc.dataViz_schemaLive as boolean} />
- Display Live Updates to Canvas
- </div>
+ {this.layoutDoc && this.layoutDoc.dataViz_asSchema ? (
+ <div className="displaySchemaLive">
+ <div className="liveSchema-checkBox" style={{ width: this._props.width }}>
+ <Checkbox color="primary" onChange={this.changeLiveSchemaCheckbox} checked={this.layoutDoc.dataViz_schemaLive as boolean} />
+ Display Live Updates to Canvas
+ </div>
+ </div>
+ ) : null}
+ {this.layoutDoc._dataViz !== DataVizView.TABLE ? (
+ <div className="filterData-checkBox">
+ <Checkbox color="primary" onChange={this.changeFilteringCheckbox} checked={this.layoutDoc.dataViz_filterSelection as boolean} />
+ Select data to filter
+ </div>
) : null}
{this.renderVizView}
@@ -444,7 +533,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
Document={this.Document}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
- usePanelWidth={true}
+ usePanelWidth
showSidebar={this.SidebarShown}
nativeWidth={NumCast(this.layoutDoc._nativeWidth)}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
@@ -478,3 +567,23 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
);
}
}
+Docs.Prototypes.TemplateMap.set(DocumentType.DATAVIZ, {
+ layout: { view: DataVizBox, dataField: 'data' },
+ options: {
+ acl: '',
+ dataViz_title: '',
+ dataViz_line: '',
+ dataViz_pie: '',
+ dataViz_histogram: '',
+ dataViz: 'table',
+ _layout_fitWidth: true,
+ _layout_reflowHorizontal: true,
+ _layout_reflowVertical: true,
+ _layout_nativeDimEditable: true,
+ },
+});
+
+Docs.Prototypes.TemplateMap.set(DocumentType.DATAVIZ, {
+ layout: { view: DataVizBox, dataField: 'data' },
+ options: { dataViz_title: '', dataViz_line: '', dataViz_pie: '', dataViz_histogram: '', dataViz: 'table', _layout_fitWidth: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true },
+});
diff --git a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
index 24023077f..60bc8df18 100644
--- a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
+++ b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
@@ -1,9 +1,12 @@
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* eslint-disable jsx-a11y/alt-text */
import { IconButton } from 'browndash-components';
import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { CgClose } from 'react-icons/cg';
-import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../Utils';
+import { ClientUtils, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Doc } from '../../../../fields/Doc';
import { StrCast } from '../../../../fields/Types';
import { DragManager } from '../../../util/DragManager';
@@ -14,56 +17,52 @@ interface SchemaCSVPopUpProps {}
@observer
export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
+ // eslint-disable-next-line no-use-before-define
static Instance: SchemaCSVPopUp;
- @observable
- public dataVizDoc: Doc | undefined = undefined;
+ @observable public dataVizDoc: Doc | undefined = undefined;
+ @observable public view: DocumentView | undefined = undefined;
+ @observable public target: Doc | undefined = undefined;
+ @observable public visible: boolean = false;
+
+ constructor(props: SchemaCSVPopUpProps) {
+ super(props);
+ makeObservable(this);
+ SchemaCSVPopUp.Instance = this;
+ }
+
@action
public setDataVizDoc = (doc: Doc) => {
this.dataVizDoc = doc;
};
- @observable
- public view: DocumentView | undefined = undefined;
@action
public setView = (docView: DocumentView) => {
this.view = docView;
};
- @observable
- public target: Doc | undefined = undefined;
@action
public setTarget = (doc: Doc) => {
this.target = doc;
};
- @observable
- public visible: boolean = false;
@action
public setVisible = (vis: boolean) => {
this.visible = vis;
};
- constructor(props: SchemaCSVPopUpProps) {
- super(props);
- makeObservable(this);
- SchemaCSVPopUp.Instance = this;
- }
-
- dataBox = () => {
- return (
- <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
- {this.heading('Schema Table as Data Visualization Doc')}
- <div className="image-content-wrapper">
- <div className="img-wrapper">
- <div className="img-container" onPointerDown={e => this.drag(e)}>
- <img width={150} height={150} src={'/assets/dataVizBox.png'} />
- </div>
+ dataBox = () => (
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
+ {this.heading('Schema Table as Data Visualization Doc')}
+ <div className="image-content-wrapper">
+ <div className="img-wrapper">
+ <div className="img-container" onPointerDown={e => this.drag(e)}>
+ <img width={150} height={150} src="/assets/dataVizBox.png" />
</div>
</div>
</div>
- );
- };
+ </div>
+ );
heading = (headingText: string) => (
<div className="summary-heading">
@@ -78,24 +77,22 @@ export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
setupMoveUpEvents(
{},
e,
- e => {
+ moveEv => {
const sourceAnchorCreator = () => this.dataVizDoc!;
- const targetCreator = (annotationOn: Doc | undefined) => {
+ const targetCreator = () => {
const embedding = Doc.MakeEmbedding(this.dataVizDoc!);
return embedding;
};
- if (this.view && sourceAnchorCreator && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) {
- DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], new DragManager.AnchorAnnoDragData(this.view, sourceAnchorCreator, targetCreator), downX, downY, {
- dragComplete: e => {
- this.setVisible(false);
- },
+ if (this.view && sourceAnchorCreator && !ClientUtils.isClick(moveEv.clientX, moveEv.clientY, downX, downY, Date.now())) {
+ DragManager.StartAnchorAnnoDrag(moveEv.target instanceof HTMLElement ? [moveEv.target] : [], new DragManager.AnchorAnnoDragData(this.view, sourceAnchorCreator, targetCreator), downX, downY, {
+ dragComplete: () => this.setVisible(false),
});
return true;
}
return false;
},
emptyFunction,
- action(e => {})
+ action(() => {})
);
};
diff --git a/src/client/views/nodes/DataVizBox/components/Chart.scss b/src/client/views/nodes/DataVizBox/components/Chart.scss
index 41ce637ac..0eb27b65b 100644
--- a/src/client/views/nodes/DataVizBox/components/Chart.scss
+++ b/src/client/views/nodes/DataVizBox/components/Chart.scss
@@ -15,18 +15,12 @@
font-size: larger;
display: flex;
flex-direction: row;
- margin-top: -20px;
- margin-bottom: -20px;
+ margin-top: -35px;
}
.asHistogram-checkBox {
- align-items: left;
- align-self: left;
- align-content: left;
- justify-content: flex-end;
- float: left;
- left: 0;
- position: relative;
- margin-bottom: -35px;
+ margin-left: 10px;
+ margin-bottom: -10px;
+ margin-top: -20px;
}
.selected-data {
align-items: center;
@@ -120,11 +114,62 @@
}
}
}
-.selectAll-buttons {
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
+.tableBox-selectButtons {
margin-top: 5px;
- margin-right: 10px;
- float: right;
+ margin-left: 25px;
+ display: inline-block;
+ padding: 2px;
+ .tableBox-selectTitle {
+ display: inline-flex;
+ flex-direction: row;
+ }
+ .tableBox-filtering {
+ display: flex;
+ flex-direction: row;
+ float: right;
+ margin-right: 10px;
+ .tableBox-filterAll {
+ min-width: 75px;
+ }
+ }
+}
+
+.tableBox-filterPopup {
+ background: $light-gray;
+ position: absolute;
+ min-width: 235px;
+ top: 60px;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ z-index: 2;
+ padding: 7px;
+ border-radius: 5px;
+ margin: 3px;
+ .tableBox-filterPopup-selectColumn {
+ margin-top: 5px;
+ flex-direction: row;
+ .tableBox-filterPopup-selectColumn-each {
+ margin-left: 25px;
+ border-radius: 3px;
+ background: $light-gray;
+ }
+ }
+ .tableBox-filterPopup-setValue {
+ margin-top: 5px;
+ display: flex;
+ flex-direction: row;
+ .tableBox-filterPopup-setValue-each {
+ margin-right: 5px;
+ border-radius: 3px;
+ background: $light-gray;
+ }
+ .tableBox-filterPopup-setValue-input {
+ margin: 5px;
+ }
+ }
+ .tableBox-filterPopup-setFilter {
+ margin-top: 5px;
+ align-self: center;
+ }
}
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index 6672603f3..14d7e9bf6 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -1,7 +1,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { ColorPicker, EditableText, IconButton, Size, Type } from 'browndash-components';
import * as d3 from 'd3';
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaFillDrip } from 'react-icons/fa';
@@ -12,7 +12,7 @@ import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
import { Docs } from '../../../../documents/Documents';
import { undoable } from '../../../../util/UndoManager';
import { ObservableReactComponent } from '../../../ObservableReactComponent';
-import { PinProps, PresBox } from '../../trails';
+import { PinProps, PinDocView } from '../../../PinFuncs';
import { scaleCreatorNumerical, yAxisCreator } from '../utils/D3Utils';
import './Chart.scss';
@@ -37,14 +37,14 @@ export interface HistogramProps {
@observer
export class Histogram extends ObservableReactComponent<HistogramProps> {
private _disposers: { [key: string]: IReactionDisposer } = {};
- private _histogramRef: React.RefObject<HTMLDivElement> = React.createRef();
+ private _histogramRef: HTMLDivElement | null = null;
private _histogramSvg: d3.Selection<SVGGElement, unknown, null, undefined> | undefined;
private numericalXData: boolean = false; // whether the data is organized by numbers rather than categoreis
private numericalYData: boolean = false; // whether the y axis is controlled by provided data rather than frequency
private maxBins = 15; // maximum number of bins that is readable on a normal sized doc
@observable _currSelected: any | undefined = undefined; // Object of selected bar
- private curBarSelected: any = undefined; // histogram bin of selected bar
- private selectedData: any = undefined; // Selection of selected bar
+ private curBarSelected: any = undefined; // histogram bin of selected bar for when just one bar is selected
+ private selectedData: any[] = []; // array of selected bars
private hoverOverData: any = undefined; // Selection of bar being hovered over
constructor(props: any) {
@@ -63,14 +63,13 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
@computed get _histogramData() {
if (this._props.axes.length < 1) return [];
if (this._props.axes.length < 2) {
- var ax0 = this._props.axes[0];
- if (!/[A-Za-z-:]/.test(this._props.records[0][ax0])){
+ const ax0 = this._props.axes[0];
+ if (!/[A-Za-z-:]/.test(this._props.records[0][ax0])) {
this.numericalXData = true;
}
return this._tableData.map(record => ({ [ax0]: record[this._props.axes[0]] }));
}
- var ax0 = this._props.axes[0];
- var ax1 = this._props.axes[1];
+ const [ax0, ax1] = this._props.axes;
if (!/[A-Za-z-:]/.test(this._props.records[0][ax0])) {
this.numericalXData = true;
}
@@ -81,11 +80,11 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
}
@computed get defaultGraphTitle() {
- var ax0 = this._props.axes[0];
- var ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined;
+ const [ax0, ax1] = this._props.axes;
if (this._props.axes.length < 2 || !ax1 || !/\d/.test(this._props.records[0][ax1]) || !this.numericalYData) {
return ax0 + ' Histogram';
- } else return ax0 + ' by ' + ax1 + ' Histogram';
+ }
+ return ax0 + ' by ' + ax1 + ' Histogram';
}
@computed get parentViz() {
@@ -104,21 +103,30 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
Array.from(Object.keys(this._disposers)).forEach(key => this._disposers[key]());
}
componentDidMount() {
- this._disposers.chartData = reaction(
- () => ({ dataSet: this._histogramData, w: this.width, h: this.height }),
- ({ dataSet, w, h }) => dataSet!.length > 0 && this.drawChart(dataSet, w, h),
- { fireImmediately: true }
- );
+ // restore selected bars
+ const svg = this._histogramSvg;
+ if (svg) {
+ const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_histogram_selectedData);
+ svg.selectAll('rect').attr('class', (d: any) => {
+ let selected = false;
+ selectedDataBars.forEach(eachSelectedData => {
+ if (d[0] === eachSelectedData) selected = true;
+ });
+ if (selected) {
+ this.selectedData.push(d);
+ return 'histogram-bar hover';
+ }
+ return 'histogram-bar';
+ });
+ }
}
- @action
- restoreView = (data: Doc) => {};
// create a document anchor that stores whatever is needed to reconstruct the viewing state (selection,zoom,etc)
getAnchor = (pinProps?: PinProps) => {
const anchor = Docs.Create.ConfigDocument({
title: 'histogram doc selection' + this._currSelected,
});
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document);
return anchor;
};
@@ -132,68 +140,102 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
// cleans data by converting numerical data to numbers and taking out empty cells
data = (dataSet: any) => {
- var validData = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || Number.isNaN(d[key])));
+ const validData = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || isNaN(d[key] as any)));
const field = dataSet[0] ? Object.keys(dataSet[0])[0] : undefined;
return !field
? []
: validData.map((d: { [x: string]: any }) =>
!this.numericalXData //
? d[field]
- : +d[field!].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '')
+ : +d[field!].replace(/\$/g, '').replace(/%/g, '').replace(/</g, '')
);
};
// outlines the bar selected / hovered over
highlightSelectedBar = (changeSelectedVariables: boolean, svg: any, eachRectWidth: any, pointerX: any, xAxisTitle: any, yAxisTitle: any, histDataSet: any) => {
- var sameAsCurrent: boolean;
- var barCounter = -1;
+ let barCounter = -1;
const selected = svg.selectAll('.histogram-bar').filter((d: any) => {
barCounter++; // uses the order of bars and width of each bar to find which one the pointer is over
- if (barCounter * eachRectWidth <= pointerX && pointerX <= (barCounter + 1) * eachRectWidth) {
- var showSelected = this.numericalYData
- ? this._histogramData.filter((data: { [x: string]: any }) => StrCast(data[xAxisTitle]).replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') == d[0])[0]
- : histDataSet.filter((data: { [x: string]: any }) => data[xAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') == d[0])[0];
+ if (d.length && barCounter * eachRectWidth <= pointerX && pointerX <= (barCounter + 1) * eachRectWidth) {
+ let showSelected = this.numericalYData
+ ? this._histogramData.filter((data: { [x: string]: any }) => StrCast(data[xAxisTitle]).replace(/\$/g, '').replace(/%/g, '').replace(/</g, '') == d[0])[0]
+ : histDataSet.filter((data: { [x: string]: any }) => data[xAxisTitle].replace(/\$/g, '').replace(/%/g, '').replace(/</g, '') == d[0])[0];
if (this.numericalXData) {
// calculating frequency
- if (d[0] && d[1] && d[0] != d[1]) {
+ if (d[0] && d[1] && d[0] !== d[1]) {
showSelected = { [xAxisTitle]: d3.min(d) + ' to ' + d3.max(d), frequency: d.length };
} else if (!this.numericalYData) showSelected = { [xAxisTitle]: showSelected[xAxisTitle], frequency: d.length };
}
if (changeSelectedVariables) {
// for when a bar is selected - not just hovered over
- sameAsCurrent = this._currSelected ? showSelected[xAxisTitle] == this._currSelected![xAxisTitle] && showSelected[yAxisTitle] == this._currSelected![yAxisTitle] : false;
- this._currSelected = sameAsCurrent ? undefined : showSelected;
- this.selectedData = sameAsCurrent ? undefined : d;
+ let sameAsAny = false;
+ const selectedDataBars = Cast(this._props.layoutDoc.dataViz_histogram_selectedData, listSpec('number'), null);
+ this.selectedData.forEach(eachData => {
+ if (!sameAsAny) {
+ let match = true;
+ Object.keys(d).forEach(key => {
+ if (d[key] !== eachData[key]) match = false;
+ });
+ if (match) {
+ sameAsAny = true;
+ const index = this.selectedData.indexOf(eachData);
+ this.selectedData.splice(index, 1);
+ selectedDataBars.splice(index, 1);
+ this._currSelected = undefined;
+ }
+ }
+ });
+ if (!sameAsAny) {
+ this.selectedData.push(d);
+ selectedDataBars.push(d[0]);
+ this._currSelected = this.selectedData.length > 1 ? undefined : showSelected;
+ }
+
+ // for filtering child dataviz docs
+ if (this._props.layoutDoc.dataViz_filterSelection) {
+ const selectedRows = Cast(this._props.layoutDoc.dataViz_selectedRows, listSpec('number'), null);
+ this._tableDataIds.forEach(rowID => {
+ let match = false;
+ for (let i = 0; i < d.length; i++) {
+ console.log('Compare: ' + this._props.records[rowID][xAxisTitle].replace(/\$/g, '').replace(/%/g, '').replace(/</g, '') + ' = ' + d[i]);
+ if (this._props.records[rowID][xAxisTitle].replace(/\$/g, '').replace(/%/g, '').replace(/</g, '') == d[i]) match = true;
+ }
+ if (match && !selectedRows?.includes(rowID))
+ selectedRows?.push(rowID); // adding to filtered rows
+ else if (match && sameAsAny) selectedRows.splice(selectedRows.indexOf(rowID), 1); // removing from filtered rows
+ });
+ }
} else this.hoverOverData = d;
return true;
}
return false;
});
if (changeSelectedVariables) {
- if (sameAsCurrent!) this.curBarSelected = undefined;
- else this.curBarSelected = selected;
+ if (this._currSelected) this.curBarSelected = selected;
+ else this.curBarSelected = undefined;
}
};
// draws the histogram
drawChart = (dataSet: any, width: number, height: number) => {
- d3.select(this._histogramRef.current).select('svg').remove();
- d3.select(this._histogramRef.current).select('.tooltip').remove();
+ if (dataSet?.length <= 0) return;
+ d3.select(this._histogramRef).select('svg').remove();
+ d3.select(this._histogramRef).select('.tooltip').remove();
const data = this.data(dataSet);
const xAxisTitle = Object.keys(dataSet[0])[0];
const yAxisTitle = this.numericalYData ? Object.keys(dataSet[0])[1] : 'frequency';
const uniqueArr: unknown[] = [...new Set(data)];
- var numBins = this.numericalXData && Number.isInteger(data[0]) ? this.rangeVals.xMax! - this.rangeVals.xMin! : uniqueArr.length;
- var translateXAxis = !this.numericalXData || numBins < this.maxBins ? width / (numBins + 1) / 2 : 0;
+ let numBins = this.numericalXData && Number.isInteger(data[0]) ? this.rangeVals.xMax! - this.rangeVals.xMin! : uniqueArr.length;
+ let translateXAxis = !this.numericalXData || numBins < this.maxBins ? width / (numBins + 1) / 2 : 0;
if (numBins > this.maxBins) numBins = this.maxBins;
const startingPoint = this.numericalXData ? this.rangeVals.xMin! : 0;
const endingPoint = this.numericalXData ? this.rangeVals.xMax! : numBins;
// converts data into Objects
- var histDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || Number.isNaN(d[key])));
+ let histDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || isNaN(d[key] as any)));
if (!this.numericalXData) {
- var histStringDataSet: { [x: string]: unknown }[] = [];
+ const histStringDataSet: { [x: string]: unknown }[] = [];
if (this.numericalYData) {
for (let i = 0; i < dataSet.length; i++) {
histStringDataSet.push({ [yAxisTitle]: dataSet[i][yAxisTitle], [xAxisTitle]: dataSet[i][xAxisTitle] });
@@ -203,7 +245,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
histStringDataSet.push({ [yAxisTitle]: 0, [xAxisTitle]: uniqueArr[i] });
}
for (let i = 0; i < data.length; i++) {
- let barData = histStringDataSet.filter(each => each[xAxisTitle] == data[i]);
+ const barData = histStringDataSet.filter(each => each[xAxisTitle] == data[i]);
histStringDataSet.filter(each => each[xAxisTitle] == data[i])[0][yAxisTitle] = Number(barData[0][yAxisTitle]) + 1;
}
}
@@ -211,31 +253,29 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
}
// initial graph and binning data for histogram
- var svg = (this._histogramSvg = d3
- .select(this._histogramRef.current)
+ const svg = (this._histogramSvg = d3
+ .select(this._histogramRef)
.append('svg')
.attr('class', 'graph')
.attr('width', width + this._props.margin.right + this._props.margin.left)
.attr('height', height + this._props.margin.top + this._props.margin.bottom)
.append('g')
.attr('transform', 'translate(' + this._props.margin.left + ',' + this._props.margin.top + ')'));
- var x = d3
+ let x = d3
.scaleLinear()
.domain(this.numericalXData ? [startingPoint!, endingPoint!] : [0, numBins])
.range([0, width]);
- var histogram = d3
+ const histogram = d3
.histogram()
- .value(function (d) {
- return d;
- })
+ .value(d => d)
.domain([startingPoint!, endingPoint!])
.thresholds(x.ticks(numBins));
- var bins = histogram(data);
- var eachRectWidth = width / bins.length;
- var graphStartingPoint = bins[0].x1 && bins[1] ? bins[0].x1! - (bins[1].x1! - bins[1].x0!) : 0;
+ const bins = histogram(data);
+ let eachRectWidth = width / bins.length;
+ const graphStartingPoint = bins[0].x1 && bins[1] ? bins[0].x1! - (bins[1].x1! - bins[1].x0!) : 0;
bins[0].x0 = graphStartingPoint;
x = x.domain([graphStartingPoint, endingPoint]).range([0, Number.isInteger(this.rangeVals.xMin!) ? width - eachRectWidth : width]);
- var xAxis;
+ let xAxis;
// more calculations based on bins
// x-axis
@@ -244,7 +284,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
// uniqueArr.sort()
histDataSet.sort();
for (let i = 0; i < data.length; i++) {
- var index = 0;
+ let index = 0;
for (let j = 0; j < uniqueArr.length; j++) {
if (uniqueArr[j] == data[i]) {
index = j;
@@ -254,7 +294,9 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
}
bins.pop();
eachRectWidth = width / bins.length;
- bins.forEach(d => (d.x0 = d.x0!));
+ bins.forEach(d => {
+ d.x0 = d.x0!;
+ });
xAxis = d3
.axisBottom(x)
.ticks(bins.length > 1 ? bins.length - 1 : 1)
@@ -264,12 +306,12 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
x.domain([0, bins.length - 1]);
translateXAxis = eachRectWidth / 2;
} else {
- var allSame = true;
- for (var i = 0; i < bins.length; i++) {
+ let allSame = true;
+ for (let i = 0; i < bins.length; i++) {
if (bins[i] && bins[i][0]) {
- var compare = bins[i][0];
+ const compare = bins[i][0];
for (let j = 1; j < bins[i].length; j++) {
- if (bins[i][j] != compare) allSame = false;
+ if (bins[i][j] !== compare) allSame = false;
}
}
}
@@ -278,8 +320,8 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
eachRectWidth = width / bins.length;
} else {
eachRectWidth = width / (bins.length + 1);
- var tickDiff = bins.length >= 2 ? bins[bins.length - 2].x1! - bins[bins.length - 2].x0! : 0;
- var curDomain = x.domain();
+ const tickDiff = bins.length >= 2 ? bins[bins.length - 2].x1! - bins[bins.length - 2].x0! : 0;
+ const curDomain = x.domain();
x.domain([curDomain[0], curDomain[0] + tickDiff * bins.length]);
}
@@ -287,16 +329,13 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
x.range([0, width - eachRectWidth]);
}
// y-axis
- const maxFrequency = this.numericalYData
- ? d3.max(histDataSet, function (d: any) {
- return d[yAxisTitle] ? Number(d[yAxisTitle]!.replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '')) : 0;
- })
- : d3.max(bins, function (d) {
- return d.length;
- });
- var y = d3.scaleLinear().range([height, 0]);
+ const maxFrequency = this.numericalYData ?
+ d3.max(histDataSet, (d: any) => (d[yAxisTitle] ? Number(d[yAxisTitle]!.replace(/\$/g, '')
+ .replace(/%/g, '').replace(/</g, '')) : 0)) :
+ d3.max(bins, d => d.length); // prettier-ignore
+ const y = d3.scaleLinear().range([height, 0]);
y.domain([0, +maxFrequency!]);
- var yAxis = d3.axisLeft(y).ticks(maxFrequency!);
+ const yAxis = d3.axisLeft(y).ticks(maxFrequency!);
if (this.numericalYData) {
const yScale = scaleCreatorNumerical(0, Number(maxFrequency), height, 0);
yAxisCreator(svg.append('g'), width, yScale);
@@ -311,17 +350,23 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
const onPointClick = action((e: any) => this.highlightSelectedBar(true, svg, eachRectWidth, d3.pointer(e)[0], xAxisTitle, yAxisTitle, histDataSet));
const onHover = action((e: any) => {
this.highlightSelectedBar(false, svg, eachRectWidth, d3.pointer(e)[0], xAxisTitle, yAxisTitle, histDataSet);
+ // eslint-disable-next-line no-use-before-define
updateHighlights();
});
- const mouseOut = action((e: any) => {
+ const mouseOut = action(() => {
this.hoverOverData = undefined;
+ // eslint-disable-next-line no-use-before-define
updateHighlights();
});
const updateHighlights = () => {
const hoverOverBar = this.hoverOverData;
- const selectedData = this.selectedData;
- svg.selectAll('rect').attr('class', function (d: any) {
- return (hoverOverBar && hoverOverBar[0] == d[0]) || (selectedData && selectedData[0] == d[0]) ? 'histogram-bar hover' : 'histogram-bar';
+ const { selectedData } = this;
+ svg.selectAll('rect').attr('class', (d: any) => {
+ let selected = false;
+ selectedData.forEach(eachSelectedData => {
+ if (d[0] === eachSelectedData[0]) selected = true;
+ });
+ return (hoverOverBar && hoverOverBar[0] == d[0]) || selected ? 'histogram-bar hover' : 'histogram-bar';
});
};
svg.on('click', onPointClick).on('mouseover', onHover).on('mouseout', mouseOut);
@@ -332,7 +377,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
.style('text-anchor', 'middle')
.text(xAxisTitle);
svg.append('text')
- .attr('transform', 'rotate(-90)' + ' ' + 'translate( 0, ' + -10 + ')')
+ .attr('transform', 'rotate(-90) translate( 0, ' + -10 + ')')
.attr('x', -(height / 2))
.attr('y', -20)
.style('text-anchor', 'middle')
@@ -340,7 +385,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
d3.format('.0f');
// draw bars
- var selected = this.selectedData;
+ const selected = this.selectedData;
svg.selectAll('rect')
.data(bins)
.enter()
@@ -348,49 +393,34 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
.attr(
'transform',
this.numericalYData
- ? function (d) {
- const eachData = histDataSet.filter((data: { [x: string]: number }) => {
- return data[xAxisTitle] == d[0];
- });
- const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0;
- return 'translate(' + x(d.x0!) + ',' + y(length) + ')';
- }
- : function (d) {
- return 'translate(' + x(d.x0!) + ',' + y(d.length) + ')';
+ ? d => {
+ const eachData = histDataSet.filter((hData: { [x: string]: number }) => hData[xAxisTitle] == d[0]);
+ const length = eachData.length ? StrCast(eachData[0][yAxisTitle]).replace(/\$/g, '').replace(/%/g, '').replace(/</g, '') : 0;
+ return 'translate(' + x(d.x0!) + ',' + y(Number(length)) + ')';
}
+ : d => 'translate(' + x(d.x0!) + ',' + y(d.length) + ')'
)
.attr(
'height',
this.numericalYData
- ? function (d) {
- const eachData = histDataSet.filter((data: { [x: string]: number }) => {
- return data[xAxisTitle] == d[0];
- });
- const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0;
- return height - y(length);
- }
- : function (d) {
- return height - y(d.length);
+ ? d => {
+ const eachData = histDataSet.filter((hData: { [x: string]: number }) => hData[xAxisTitle] == d[0]);
+ const length = eachData.length ? StrCast(eachData[0][yAxisTitle]).replace(/\$/g, '').replace(/%/g, '').replace(/</g, '') : 0;
+ return height - y(Number(length));
}
+ : d => height - y(d.length)
)
.attr('width', eachRectWidth)
- .attr(
- 'class',
- selected
- ? function (d) {
- return selected && selected[0] === d[0] ? 'histogram-bar hover' : 'histogram-bar';
- }
- : function (d) {
- return 'histogram-bar';
- }
- )
+ .attr('class', selected ? d => (selected && selected[0] == d[0] ? 'histogram-bar hover' : 'histogram-bar') : () => 'histogram-bar')
.attr('fill', d => {
- var barColor;
+ let barColor;
const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::'));
barColors.forEach(each => {
+ // eslint-disable-next-line prefer-destructuring
if (d[0] && d[0].toString() && each[0] == d[0].toString()) barColor = each[1];
else {
const range = StrCast(each[0]).split(' to ');
+ // eslint-disable-next-line prefer-destructuring
if (Number(range[0]) <= d[0] && d[0] <= Number(range[1])) barColor = each[1];
}
});
@@ -400,7 +430,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
@action changeSelectedColor = (color: string) => {
this.curBarSelected.attr('fill', color);
- const barName = StrCast(this._currSelected[this._props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, ''));
+ const barName = StrCast(this._currSelected[this._props.axes[0]].replace(/\$/g, '').replace(/%/g, '').replace(/</g, ''));
const barColors = Cast(this._props.layoutDoc.dataViz_histogram_barColors, listSpec('string'), null);
barColors.forEach(each => each.split('::')[0] === barName && barColors.splice(barColors.indexOf(each), 1));
@@ -409,65 +439,73 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
@action eraseSelectedColor = () => {
this.curBarSelected.attr('fill', this._props.layoutDoc.dataViz_histogram_defaultColor);
- const barName = StrCast(this._currSelected[this._props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, ''));
+ const barName = StrCast(this._currSelected[this._props.axes[0]].replace(/\$/g, '').replace(/%/g, '').replace(/</g, ''));
const barColors = Cast(this._props.layoutDoc.dataViz_histogram_barColors, listSpec('string'), null);
barColors.forEach(each => each.split('::')[0] === barName && barColors.splice(barColors.indexOf(each), 1));
};
- updateBarColors = () => {
- var svg = this._histogramSvg;
- if (svg)
+ // reloads the bar colors and selected bars
+ updateSavedUI = () => {
+ const svg = this._histogramSvg;
+ if (svg) {
+ // bar color
svg.selectAll('rect').attr('fill', (d: any) => {
- var barColor;
+ let barColor;
const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::'));
barColors.forEach(each => {
+ // eslint-disable-next-line prefer-destructuring
if (d[0] && d[0].toString() && each[0] == d[0].toString()) barColor = each[1];
else {
const range = StrCast(each[0]).split(' to ');
+ // eslint-disable-next-line prefer-destructuring
if (Number(range[0]) <= d[0] && d[0] <= Number(range[1])) barColor = each[1];
}
});
return barColor ? StrCast(barColor) : StrCast(this._props.layoutDoc.dataViz_histogram_defaultColor);
});
+ }
};
render() {
- this.updateBarColors();
+ this.updateSavedUI();
this._histogramData;
- var curSelectedBarName = '';
- var titleAccessor: any = 'dataViz_histogram_title';
- if (this._props.axes.length == 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
- else if (this._props.axes.length > 0) titleAccessor = titleAccessor + this._props.axes[0];
+ let curSelectedBarName = '';
+ let titleAccessor: any = 'dataViz_histogram_title';
+ if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
+ else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0];
if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle;
if (!this._props.layoutDoc.dataViz_histogram_defaultColor) this._props.layoutDoc.dataViz_histogram_defaultColor = '#69b3a2';
if (!this._props.layoutDoc.dataViz_histogram_barColors) this._props.layoutDoc.dataViz_histogram_barColors = new List<string>();
- var selected = 'none';
+ if (!this._props.layoutDoc.dataViz_histogram_selectedData) this._props.layoutDoc.dataViz_histogram_selectedData = new List<string>();
+ let selected = 'none';
if (this._currSelected) {
- curSelectedBarName = StrCast(this._currSelected![this._props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, ''));
+ curSelectedBarName = StrCast(this._currSelected![this._props.axes[0]].replace(/\$/g, '').replace(/%/g, '').replace(/</g, ''));
selected = '{ ';
- Object.keys(this._currSelected).forEach(key =>
+ Object.keys(this._currSelected).forEach(key => {
key //
? (selected += key + ': ' + this._currSelected[key] + ', ')
- : ''
- );
+ : '';
+ });
selected = selected.substring(0, selected.length - 2) + ' }';
- if (this._props.titleCol!="" && (!this._currSelected["frequency"] || this._currSelected["frequency"]<10)){
- selected+= "\n" + this._props.titleCol + ": "
+ if (this._props.titleCol !== '' && (!this._currSelected.frequency || this._currSelected.frequency < 10)) {
+ selected += '\n' + this._props.titleCol + ': ';
this._tableData.forEach(each => {
- if (this._currSelected[this._props.axes[0]]==each[this._props.axes[0]]) {
- if (this._props.axes[1]){
- if (this._currSelected[this._props.axes[1]]==each[this._props.axes[1]]) selected+= each[this._props.titleCol] + ", ";
- }
- else selected+= each[this._props.titleCol] + ", ";
+ if (this._currSelected[this._props.axes[0]] === each[this._props.axes[0]]) {
+ if (this._props.axes[1]) {
+ if (this._currSelected[this._props.axes[1]] === each[this._props.axes[1]]) selected += each[this._props.titleCol] + ', ';
+ } else selected += each[this._props.titleCol] + ', ';
}
- })
- selected = selected.slice(0,-1).slice(0,-1);
+ });
+ selected = selected.slice(0, -1).slice(0, -1);
}
}
- var selectedBarColor;
- var barColors = StrListCast(this._props.layoutDoc.histogramBarColors).map(each => each.split('::'));
- barColors.forEach(each => each[0] === curSelectedBarName && (selectedBarColor = each[1]));
+ let selectedBarColor;
+ const barColors = StrListCast(this._props.layoutDoc.histogramBarColors).map(each => each.split('::'));
+ barColors.forEach(each => {
+ // eslint-disable-next-line prefer-destructuring
+ each[0] === curSelectedBarName && (selectedBarColor = each[1]);
+ });
if (this._histogramData.length > 0 || !this.parentViz) {
return this._props.axes.length >= 1 ? (
@@ -476,55 +514,63 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
<EditableText
val={StrCast(this._props.layoutDoc[titleAccessor])}
setVal={undoable(
- action(val => (this._props.layoutDoc[titleAccessor] = val as string)),
+ action(val => {
+ this._props.layoutDoc[titleAccessor] = val as string;
+ }),
'Change Graph Title'
)}
- color={'black'}
+ color="black"
size={Size.LARGE}
fillWidth
/>
&nbsp; &nbsp;
<ColorPicker
- tooltip={'Change Default Bar Color'}
+ tooltip="Change Default Bar Color"
type={Type.SEC}
icon={<FaFillDrip />}
selectedColor={StrCast(this._props.layoutDoc.dataViz_histogram_defaultColor)}
- setFinalColor={undoable(color => (this._props.layoutDoc.dataViz_histogram_defaultColor = color), 'Change Default Bar Color')}
- setSelectedColor={undoable(color => (this._props.layoutDoc.dataViz_histogram_defaultColor = color), 'Change Default Bar Color')}
+ setFinalColor={undoable(color => {
+ this._props.layoutDoc.dataViz_histogram_defaultColor = color;
+ }, 'Change Default Bar Color')}
+ setSelectedColor={undoable(color => {
+ this._props.layoutDoc.dataViz_histogram_defaultColor = color;
+ }, 'Change Default Bar Color')}
size={Size.XSMALL}
/>
</div>
- <div ref={this._histogramRef} />
- {selected != 'none' ? (
- <div className={'selected-data'}>
+ <div
+ ref={r => {
+ this._histogramRef = r;
+ r && this.drawChart(this._histogramData, this.width, this.height);
+ }}
+ />
+ {selected !== 'none' ? (
+ <div className="selected-data">
Selected: {selected}
&nbsp; &nbsp;
<ColorPicker
- tooltip={'Change Bar Color'}
+ tooltip="Change Bar Color"
type={Type.SEC}
icon={<FaFillDrip />}
- selectedColor={selectedBarColor ? selectedBarColor : this.curBarSelected.attr('fill')}
+ selectedColor={selectedBarColor || this.curBarSelected.attr('fill')}
setFinalColor={undoable(color => this.changeSelectedColor(color), 'Change Selected Bar Color')}
setSelectedColor={undoable(color => this.changeSelectedColor(color), 'Change Selected Bar Color')}
size={Size.XSMALL}
/>
&nbsp;
<IconButton
- icon={<FontAwesomeIcon icon={'eraser'} />}
+ icon={<FontAwesomeIcon icon="eraser" />}
size={Size.XSMALL}
- color={'black'}
+ color="black"
type={Type.SEC}
- tooltip={'Revert to the default bar color'}
- onClick={undoable(
- action(() => this.eraseSelectedColor()),
- 'Change Selected Bar Color'
- )}
+ tooltip="Revert to the default bar color" //
+ onClick={undoable(this.eraseSelectedColor, 'Change Selected Bar Color')}
/>
</div>
) : null}
</div>
) : (
- <span className="chart-container"> {'first use table view to select a column to graph'}</span>
+ <span className="chart-container"> first use table view to select a column to graph</span>
);
}
// when it is a brushed table and the incoming table doesn't have any rows selected
diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
index e093ec648..c2f5388a2 100644
--- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
@@ -3,23 +3,20 @@ import * as d3 from 'd3';
import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, NumListCast, StrListCast } from '../../../../../fields/Doc';
+import { Doc, NumListCast, StrListCast } from '../../../../../fields/Doc';
import { List } from '../../../../../fields/List';
import { listSpec } from '../../../../../fields/Schema';
import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
import { Docs } from '../../../../documents/Documents';
-import { DocumentManager } from '../../../../util/DocumentManager';
import { undoable } from '../../../../util/UndoManager';
+import {} from '../../../DocComponent';
import { ObservableReactComponent } from '../../../ObservableReactComponent';
-import { PinProps, PresBox } from '../../trails';
+import { PinDocView, PinProps } from '../../../PinFuncs';
+import { DocumentView } from '../../DocumentView';
import { DataVizBox } from '../DataVizBox';
-import { createLineGenerator, drawLine, minMaxRange, scaleCreatorNumerical, xAxisCreator, xGrid, yAxisCreator, yGrid } from '../utils/D3Utils';
+import { DataPoint, createLineGenerator, drawLine, minMaxRange, scaleCreatorNumerical, xAxisCreator, xGrid, yAxisCreator, yGrid } from '../utils/D3Utils';
import './Chart.scss';
-export interface DataPoint {
- x: number;
- y: number;
-}
export interface SelectedDataPoint extends DataPoint {
elem?: d3.Selection<d3.BaseType, unknown, SVGGElement, unknown>;
}
@@ -45,15 +42,23 @@ export interface LineChartProps {
@observer
export class LineChart extends ObservableReactComponent<LineChartProps> {
private _disposers: { [key: string]: IReactionDisposer } = {};
- private _lineChartRef: React.RefObject<HTMLDivElement> = React.createRef();
+ private _lineChartRef: HTMLDivElement | null = null;
private _lineChartSvg: d3.Selection<SVGGElement, unknown, null, undefined> | undefined;
- @observable _currSelected: any | undefined = undefined;
+ @observable _currSelected: DataPoint | undefined = undefined;
+
// TODO: nda - some sort of mapping that keeps track of the annotated points so we can easily remove when annotations list updates
constructor(props: any) {
super(props);
makeObservable(this);
}
+ @computed get titleAccessor() {
+ let titleAccessor: any = 'dataViz_lineChart_title';
+ if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
+ else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0];
+ return titleAccessor;
+ }
+
@computed get _tableDataIds() {
return !this.parentViz ? this._props.records.map((rec, i) => i) : NumListCast(this.parentViz.dataViz_selectedRows);
}
@@ -62,7 +67,6 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
return !this.parentViz ? this._props.records : this._tableDataIds.map(rowId => this._props.records[rowId]);
}
@computed get _lineChartData() {
- var guids = StrListCast(this._props.layoutDoc.dataViz_rowIds);
if (this._props.axes.length <= 1) return [];
return this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[1]]) })).sort((a, b) => (a.x < b.x ? -1 : 1));
}
@@ -71,16 +75,11 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
}
@computed get parentViz() {
return DocCast(this._props.Document.dataViz_parentViz);
- // return LinkManager.Instance.getAllRelatedLinks(this._props.Document) // out of all links
- // .filter(link => {
- // return link.link_anchor_1 == this._props.Document.dataViz_parentViz;
- // }) // get links where this chart doc is the target of the link
- // .map(link => DocCast(link.link_anchor_1)); // then return the source of the link
}
@computed get incomingHighlited() {
// return selected x and y axes
// otherwise, use the selection of whatever is linked to us
- const incomingVizBox = DocumentManager.Instance.getFirstDocumentView(this.parentViz)?.ComponentView as DataVizBox;
+ const incomingVizBox = DocumentView.getFirstDocumentView(this.parentViz)?.ComponentView as DataVizBox;
const highlitedRowIds = NumListCast(incomingVizBox?.layoutDoc?.dataViz_highlitedRows);
return this._tableData.filter((record, i) => highlitedRowIds.includes(this._tableDataIds[i])); // get all the datapoints they have selected field set by incoming anchor
}
@@ -91,40 +90,10 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
Array.from(Object.keys(this._disposers)).forEach(key => this._disposers[key]());
}
componentDidMount() {
- this._disposers.chartData = reaction(
- () => ({ dataSet: this._lineChartData, w: this.width, h: this.height }),
- ({ dataSet, w, h }) => {
- if (dataSet) {
- this.drawChart([dataSet], this.rangeVals, w, h);
- }
- },
- { fireImmediately: true }
- );
- this._disposers.annos = reaction(
- () => DocListCast(this._props.dataDoc[this._props.fieldKey + '_annotations']),
- annotations => {
- // modify how d3 renders so that anything in this annotations list would be potentially highlighted in some way
- // could be blue colored to make it look like anchor
- // this.drawAnnotations()
- // loop through annotations and draw them
- // annotations.forEach(a => this.drawAnnotations(Number(a.x), Number(a.y)));
- // this.drawAnnotations(annotations.x, annotations.y);
- },
- { fireImmediately: true }
- );
- this._disposers.highlights = reaction(
- () => ({
- selected: this._currSelected,
- incomingHighlited: this.incomingHighlited,
- }),
- ({ selected, incomingHighlited }) => {
- // redraw annotations when the chart data has changed, or the local or inherited selection has changed
- this.clearAnnotations();
- selected && this.drawAnnotations(Number(selected.x), Number(selected.y), true);
- incomingHighlited?.forEach((record: any) => this.drawAnnotations(Number(record[this._props.axes[0]]), Number(record[this._props.axes[1]])));
- },
- { fireImmediately: true }
- );
+ // coloring the selected point
+ if (!this._props.layoutDoc[this.titleAccessor]) this._props.layoutDoc[this.titleAccessor] = this.defaultGraphTitle;
+ if (!this._props.layoutDoc.dataViz_lineChart_selectedData) this._props.layoutDoc.dataViz_lineChart_selectedData = new List<string>();
+ this._disposers.selector = reaction(() => StrListCast(this._props.layoutDoc.dataViz_lineChart_selectedData).slice(), this.colorSelectedPts, { fireImmediately: true });
}
// anything that doesn't need to be recalculated should just be stored as drawCharts (i.e. computed values) and drawChart is gonna iterate over these observables and generate svgs based on that
@@ -137,51 +106,33 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
element.classList.remove('selected');
}
};
- // gets called whenever the "data_annotations" fields gets updated
- drawAnnotations = (dataX: number, dataY: number, selected?: boolean) => {
- // TODO: nda - can optimize this by having some sort of mapping of the x and y values to the individual circle elements
- // loop through all html elements with class .circle-d1 and find the one that has "data-x" and "data-y" attributes that match the dataX and dataY
- // if it exists, then highlight it
- // if it doesn't exist, then remove the highlight
- const elements = document.querySelectorAll('.datapoint');
- for (let i = 0; i < elements.length; i++) {
- const element = elements[i];
- const x = element.getAttribute('data-x');
- const y = element.getAttribute('data-y');
- if (x === dataX.toString() && y === dataY.toString()) {
- element.classList.add(selected ? 'selected' : 'brushed');
- }
- // TODO: nda - this remove highlight code should go where we remove the links
- // } else {
- // }
- }
- };
-
- @action
- restoreView = (data: Doc) => {
- const coords = Cast(data.config_dataVizSelection, listSpec('number'), null);
- if (coords?.length > 1 && (this._currSelected?.x !== coords[0] || this._currSelected?.y !== coords[1])) {
- this.setCurrSelected(coords[0], coords[1]);
- return true;
- }
- if (this._currSelected) {
- this.setCurrSelected();
- return true;
- }
- return false;
- };
// create a document anchor that stores whatever is needed to reconstruct the viewing state (selection,zoom,etc)
getAnchor = (pinProps?: PinProps) => {
const anchor = Docs.Create.ConfigDocument({
//
- title: 'line doc selection' + this._currSelected?.x,
+ title: 'line doc selection' + (this._currSelected?.x ?? ''),
});
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document);
anchor.config_dataVizSelection = this._currSelected ? new List<number>([this._currSelected.x, this._currSelected.y]) : undefined;
return anchor;
};
+ private colorSelectedPts = () => {
+ const elements = document.querySelectorAll('.datapoint');
+ for (let i = 0; i < elements.length; i++) {
+ const dx = Number(elements[i].getAttribute('data-x'));
+ const dy = Number(elements[i].getAttribute('data-y'));
+ const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_lineChart_selectedData);
+ const selected = selectedDataBars.some(eachSelectedData => {
+ const [sx, sy] = eachSelectedData.split(','); // parse each selected point into x,y
+ return Number(sx) === dx && Number(sy) === dy;
+ });
+ if (selected) elements[i].classList.add('brushed');
+ else elements[i].classList.remove('brushed');
+ }
+ };
+
@computed get height() {
return this._props.height - this._props.margin.top - this._props.margin.bottom;
}
@@ -191,36 +142,55 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
}
@computed get defaultGraphTitle() {
- var ax0 = this._props.axes[0];
- var ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined;
+ const ax0 = this._props.axes[0];
+ const ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined;
if (this._props.axes.length < 2 || !/\d/.test(this._props.records[0][ax0]) || !ax1) {
return ax0 + ' Line Chart';
- } else return ax1 + ' by ' + ax0 + ' Line Chart';
+ }
+ return ax1 + ' by ' + ax0 + ' Line Chart';
}
setupTooltip() {
- return d3
- .select(this._lineChartRef.current)
- .append('div')
- .attr('class', 'tooltip')
- .style('opacity', 0)
- .style('background', '#fff')
- .style('border', '1px solid #ccc')
- .style('padding', '5px')
- .style('position', 'absolute')
- .style('font-size', '12px');
+ return d3.select(this._lineChartRef).append('div').attr('class', 'tooltip').style('opacity', 0).style('background', '#fff').style('border', '1px solid #ccc').style('padding', '5px').style('position', 'absolute').style('font-size', '12px');
}
- // TODO: nda - use this everyewhere we update currSelected?
@action
- setCurrSelected(x?: number, y?: number) {
- // TODO: nda - get rid of svg element in the list?
- if (this._currSelected && this._currSelected.x == x && this._currSelected.y == y) this._currSelected = undefined;
- else this._currSelected = x !== undefined && y !== undefined ? { x, y } : undefined;
- this._props.records.forEach(record => record[this._props.axes[0]] === x && record[this._props.axes[1]] === y && (record.selected = true));
+ setCurrSelected(d: DataPoint) {
+ let ptWasSelected = false;
+ const selectedDatapoints = Cast(this._props.layoutDoc.dataViz_lineChart_selectedData, listSpec('string'), null);
+ selectedDatapoints?.forEach(eachData => {
+ if (!ptWasSelected) {
+ const [dx, dy] = eachData.split(',');
+ if (Number(dx) === d.x && Number(dy) === d.y) {
+ ptWasSelected = true;
+ const index = selectedDatapoints.indexOf(eachData);
+ selectedDatapoints.splice(index, 1);
+ this._currSelected = undefined;
+ }
+ }
+ });
+ if (!ptWasSelected) {
+ selectedDatapoints.push(d.x + ',' + d.y);
+ this._currSelected = selectedDatapoints.length > 1 ? undefined : d;
+ }
+
+ // for filtering child dataviz docs
+ if (this._props.layoutDoc.dataViz_filterSelection) {
+ const selectedRows = Cast(this._props.layoutDoc.dataViz_selectedRows, listSpec('number'), null);
+ this._tableDataIds.forEach(rowID => {
+ if (
+ Number(this._props.records[rowID][this._props.axes[0]].replace(/\$/g, '').replace(/%/g, '').replace(/</g, '')) === d.x && //
+ Number(this._props.records[rowID][this._props.axes[1]].replace(/\$/g, '').replace(/%/g, '').replace(/</g, '')) === d.y
+ ) {
+ if (!selectedRows?.includes(rowID))
+ selectedRows?.push(rowID); // adding to filtered rows
+ else if (ptWasSelected) selectedRows.splice(selectedRows.indexOf(rowID), 1); // removing from filtered rows
+ }
+ });
+ }
}
- drawDataPoints(data: DataPoint[], idx: number, xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>) {
+ drawDataPoints(data: DataPoint[], idx: number, xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>, higlightFocusPt: any, tooltip: any) {
if (this._lineChartSvg) {
const circleClass = '.circle-' + idx;
this._lineChartSvg
@@ -232,24 +202,38 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
.attr('cx', d => xScale(d.x))
.attr('cy', d => yScale(d.y))
.attr('data-x', d => d.x)
- .attr('data-y', d => d.y);
+ .attr('data-y', d => d.y)
+ .on('mouseenter', e => {
+ const d0 = { x: Number(e.target.getAttribute('data-x')), y: Number(e.target.getAttribute('data-y')) };
+ this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip);
+ higlightFocusPt.style('display', null);
+ })
+ .on('mouseleave', () => {
+ tooltip?.transition().duration(300).style('opacity', 0);
+ })
+ .on('click', (e: any) => {
+ const d0 = { x: Number(e.target.getAttribute('data-x')), y: Number(e.target.getAttribute('data-y')) };
+ // find .circle-d1 with data-x = d0.x and data-y = d0.y
+ this.setCurrSelected(d0);
+ this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip);
+ });
}
}
drawChart = (dataSet: any[][], rangeVals: { xMin?: number; xMax?: number; yMin?: number; yMax?: number }, width: number, height: number) => {
// clearing tooltip and the current chart
- d3.select(this._lineChartRef.current).select('svg').remove();
- d3.select(this._lineChartRef.current).select('.tooltip').remove();
+ d3.select(this._lineChartRef).select('svg').remove();
+ d3.select(this._lineChartRef).select('.tooltip').remove();
- var { xMin, xMax, yMin, yMax } = rangeVals;
+ let { xMin, xMax, yMin, yMax } = rangeVals;
if (xMin === undefined || xMax === undefined || yMin === undefined || yMax === undefined) {
return;
}
// adding svg
- const margin = this._props.margin;
+ const { margin } = this._props;
const svg = (this._lineChartSvg = d3
- .select(this._lineChartRef.current)
+ .select(this._lineChartRef)
.append('svg')
.attr('class', 'graph')
.attr('width', `${width + margin.left + margin.right}`)
@@ -257,18 +241,19 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`));
- var validSecondData;
- if (this._props.axes.length>2){ // for when there are 2 lines on the chart
- var next = this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[2]]) })).sort((a, b) => (a.x < b.x ? -1 : 1));
+ let validSecondData;
+ if (this._props.axes.length > 2) {
+ // for when there are 2 lines on the chart
+ const next = this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[2]]) })).sort((a, b) => (a.x < b.x ? -1 : 1));
validSecondData = next.filter(d => {
- if (!d.x || Number.isNaN(d.x) || !d.y || Number.isNaN(d.y)) return false;
+ if (!d.x || isNaN(d.x) || !d.y || isNaN(d.y)) return false;
return true;
});
- var secondDataRange = minMaxRange([validSecondData]);
- if (secondDataRange.xMax!>xMax) xMax = secondDataRange.xMax;
- if (secondDataRange.yMax!>yMax) yMax = secondDataRange.yMax;
- if (secondDataRange.xMin!<xMin) xMin = secondDataRange.xMin;
- if (secondDataRange.yMin!<yMin) yMin = secondDataRange.yMin;
+ const secondDataRange = minMaxRange([validSecondData]);
+ if (secondDataRange.xMax! > xMax) xMax = secondDataRange.xMax;
+ if (secondDataRange.yMax! > yMax) yMax = secondDataRange.yMax;
+ if (secondDataRange.xMin! < xMin) xMin = secondDataRange.xMin;
+ if (secondDataRange.yMin! < yMin) yMin = secondDataRange.yMin;
}
// creating the x and y scales
@@ -282,85 +267,47 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
xAxisCreator(svg.append('g'), height, xScale);
yAxisCreator(svg.append('g'), width, yScale);
+ const higlightFocusPt = svg.append('g').style('display', 'none');
+ higlightFocusPt.append('circle').attr('r', 5).attr('class', 'circle');
+ const tooltip = this.setupTooltip();
+
if (validSecondData) {
drawLine(svg.append('path'), validSecondData, lineGen, true);
- this.drawDataPoints(validSecondData, 0, xScale, yScale);
- svg.append('path').attr("stroke", "red");
+ this.drawDataPoints(validSecondData, 0, xScale, yScale, higlightFocusPt, tooltip);
+ svg.append('path').attr('stroke', 'red');
// legend
- var color = d3.scaleOrdinal()
- .range(["black", "blue"])
- .domain([this._props.axes[1], this._props.axes[2]])
- svg.selectAll("mydots")
+ const color: any = d3.scaleOrdinal().range(['black', 'blue']).domain([this._props.axes[1], this._props.axes[2]]);
+ svg.selectAll('mydots')
.data([this._props.axes[1], this._props.axes[2]])
.enter()
- .append("circle")
- .attr("cx", 5)
- .attr("cy", function(d,i){ return -30 + i*15})
- .attr("r", 7)
- .style("fill", function(d){ return color(d)})
- svg.selectAll("mylabels")
+ .append('circle')
+ .attr('cx', 5)
+ .attr('cy', (d, i) => -30 + i * 15)
+ .attr('r', 7)
+ .style('fill', d => color(d));
+ svg.selectAll('mylabels')
.data([this._props.axes[1], this._props.axes[2]])
.enter()
- .append("text")
- .attr("x", 25)
- .attr("y", function(d,i){ return -30 + i*15})
- .style("fill", function(d){ return color(d)})
- .text(function(d){ return d})
- .attr("text-anchor", "left")
- .style("alignment-baseline", "middle")
+ .append('text')
+ .attr('x', 25)
+ .attr('y', (d, i) => -30 + i * 15)
+ .style('fill', d => color(d))
+ .text(d => d)
+ .attr('text-anchor', 'left')
+ .style('alignment-baseline', 'middle');
}
// get valid data points
const data = dataSet[0];
- var validData = data.filter(d => {
- Object.keys(data[0]).map(key => {
- if (!d[key] || Number.isNaN(d[key])) return false;
- });
- return true;
- });
+ const keys = Object.keys(data[0]);
+ const validData = data.filter(d => !keys.some(key => isNaN(d[key])));
// draw the plot line
drawLine(svg.append('path'), validData, lineGen, false);
- // draw the datapoint circle
- this.drawDataPoints(validData, 0, xScale, yScale);
- const higlightFocusPt = svg.append('g').style('display', 'none');
- higlightFocusPt.append('circle').attr('r', 5).attr('class', 'circle');
- const tooltip = this.setupTooltip();
- // add all the tooltipContent to the tooltip
- const mousemove = action((e: any) => {
- const bisect = d3.bisector((d: DataPoint) => d.x).left;
- const xPos = d3.pointer(e)[0];
- const x0 = Math.min(data.length - 1, bisect(data, xScale.invert(xPos - 5))); // shift x by -5 so that you can reach points on the left-side axis
- const d0 = data[x0];
- if (d0) this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip);
-
- this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip);
- });
-
- const onPointClick = action((e: any) => {
- const bisect = d3.bisector((d: DataPoint) => d.x).left;
- const xPos = d3.pointer(e)[0];
- const x0 = bisect(data, xScale.invert(xPos - 5)); // shift x by -5 so that you can reach points on the left-side axis
- const d0 = data[x0];
- // find .circle-d1 with data-x = d0.x and data-y = d0.y
- const selected = svg.selectAll('.datapoint').filter((d: any) => d['data-x'] === d0.x && d['data-y'] === d0.y);
- this.setCurrSelected(d0.x, d0.y);
- this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip);
- });
-
- svg.append('rect')
- .attr('class', 'overlay')
- .attr('width', width)
- .attr('height', this.height + margin.top + margin.bottom)
- .attr('fill', 'none')
- .attr('translate', `translate(${margin.left}, ${-(margin.top + margin.bottom)})`)
- .style('opacity', 0)
- .on('mouseover', () => higlightFocusPt.style('display', null))
- .on('mouseout', () => tooltip.transition().duration(300).style('opacity', 0))
- .on('mousemove', mousemove)
- .on('click', onPointClick);
+ // draw the datapoint circle
+ this.drawDataPoints(validData, 0, xScale, yScale, higlightFocusPt, tooltip);
// axis titles
svg.append('text')
@@ -368,13 +315,14 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
.style('text-anchor', 'middle')
.text(this._props.axes[0]);
svg.append('text')
- .attr('transform', 'rotate(-90)' + ' ' + 'translate( 0, ' + -10 + ')')
+ .attr('transform', 'rotate(-90) translate(0, -10)')
.attr('x', -(height / 2))
.attr('y', -30)
.attr('height', 20)
.attr('width', 20)
.style('text-anchor', 'middle')
.text(this._props.axes[1]);
+ this.colorSelectedPts();
};
private updateTooltip(
@@ -394,57 +342,61 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
}
render() {
- var titleAccessor: any = 'dataViz_lineChart_title';
- if (this._props.axes.length == 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
- else if (this._props.axes.length > 0) titleAccessor = titleAccessor + this._props.axes[0];
- if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle;
const selectedPt = this._currSelected ? `{ ${this._props.axes[0]}: ${this._currSelected.x} ${this._props.axes[1]}: ${this._currSelected.y} }` : 'none';
- var selectedTitle = "";
- if (this._currSelected && this._props.titleCol){
- selectedTitle+= "\n" + this._props.titleCol + ": "
+ let selectedTitle = '';
+ if (this._currSelected && this._props.titleCol) {
+ selectedTitle += '\n' + this._props.titleCol + ': ';
this._tableData.forEach(each => {
- var mapThisEntry = false;
- if (this._currSelected.x==each[this._props.axes[0]] && this._currSelected.y==each[this._props.axes[1]]) mapThisEntry = true;
- else if (this._currSelected.y==each[this._props.axes[0]] && this._currSelected.x==each[this._props.axes[1]]) mapThisEntry = true;
- if (mapThisEntry) selectedTitle += each[this._props.titleCol] + ", ";
- })
- selectedTitle = selectedTitle.slice(0,-1).slice(0,-1);
+ let mapThisEntry = false;
+ if (this._currSelected?.x === each[this._props.axes[0]] && this._currSelected?.y === each[this._props.axes[1]]) mapThisEntry = true;
+ else if (this._currSelected?.y === each[this._props.axes[0]] && this._currSelected?.x === each[this._props.axes[1]]) mapThisEntry = true;
+ if (mapThisEntry) selectedTitle += each[this._props.titleCol] + ', ';
+ });
+ selectedTitle = selectedTitle.slice(0, -1).slice(0, -1);
}
- if (this._lineChartData.length > 0 || !this.parentViz || this.parentViz.length == 0) {
+ if (this._lineChartData.length > 0 || !this.parentViz || this.parentViz.length === 0) {
return this._props.axes.length >= 2 && /\d/.test(this._props.records[0][this._props.axes[0]]) && /\d/.test(this._props.records[0][this._props.axes[1]]) ? (
<div className="chart-container" style={{ width: this._props.width + this._props.margin.right }}>
<div className="graph-title">
<EditableText
- val={StrCast(this._props.layoutDoc[titleAccessor])}
+ val={StrCast(this._props.layoutDoc[this.titleAccessor])}
setVal={undoable(
- action(val => (this._props.layoutDoc[titleAccessor] = val as string)),
+ action(val => {
+ this._props.layoutDoc[this.titleAccessor] = val as string;
+ }),
'Change Graph Title'
)}
- color={'black'}
+ color="black"
size={Size.LARGE}
fillWidth
/>
</div>
- <div ref={this._lineChartRef} />
- {selectedPt != 'none' ? (
- <div className={'selected-data'}>
+ <div
+ ref={r => {
+ this._lineChartRef = r;
+ this.drawChart([this._lineChartData], this.rangeVals, this.width, this.height);
+ }}
+ />
+ {selectedPt !== 'none' ? (
+ <div className="selected-data">
{`Selected: ${selectedPt}`}
{`${selectedTitle}`}
<Button
- onClick={e => {
+ onClick={() => {
this._props.vizBox.sidebarBtnDown;
this._props.vizBox.sidebarAddDocument;
- }}></Button>
+ }}
+ />
</div>
) : null}
</div>
) : (
- <span className="chart-container"> {'first use table view to select two numerical axes to plot'}</span>
- );
- } else
- return (
- // when it is a brushed table and the incoming table doesn't have any rows selected
- <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
+ <span className="chart-container"> first use table view to select two numerical axes to plot</span>
);
+ }
+ return (
+ // when it is a brushed table and the incoming table doesn't have any rows selected
+ <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
+ );
}
}
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index fc23f47de..19ea8e4fa 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -1,7 +1,7 @@
import { Checkbox } from '@mui/material';
import { ColorPicker, EditableText, Size, Type } from 'browndash-components';
import * as d3 from 'd3';
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaFillDrip } from 'react-icons/fa';
@@ -12,7 +12,7 @@ import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
import { Docs } from '../../../../documents/Documents';
import { undoable } from '../../../../util/UndoManager';
import { ObservableReactComponent } from '../../../ObservableReactComponent';
-import { PinProps, PresBox } from '../../trails';
+import { PinProps, PinDocView } from '../../../PinFuncs';
import './Chart.scss';
export interface PieChartProps {
@@ -36,10 +36,10 @@ export interface PieChartProps {
@observer
export class PieChart extends ObservableReactComponent<PieChartProps> {
private _disposers: { [key: string]: IReactionDisposer } = {};
- private _piechartRef: React.RefObject<HTMLDivElement> = React.createRef();
+ private _piechartRef: HTMLDivElement | null = null;
private _piechartSvg: d3.Selection<SVGGElement, unknown, null, undefined> | undefined;
- private curSliceSelected: any = undefined; // d3 data of selected slice
- private selectedData: any = undefined; // Selection of selected slice
+ private curSliceSelected: any = undefined; // d3 data of selected slice for when just one slice is selected
+ private selectedData: any[] = []; // array of selected slices
private hoverOverData: any = undefined; // Selection of slice being hovered over
@observable _currSelected: any | undefined = undefined; // Object of selected slice
@@ -74,8 +74,8 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
}
@computed get defaultGraphTitle() {
- var ax0 = this._props.axes[0];
- var ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined;
+ const ax0 = this._props.axes[0];
+ const ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined;
if (this._props.axes.length < 2 || !/\d/.test(this._props.records[0][ax0]) || !ax1) {
return ax0 + ' Pie Chart';
}
@@ -84,31 +84,37 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
@computed get parentViz() {
return DocCast(this._props.Document.dataViz_parentViz);
- // return LinkManager.Instance.getAllRelatedLinks(this._props.Document) // out of all links
- // .filter(link => link.link_anchor_1 == this._props.Document.dataViz_parentViz) // get links where this chart doc is the target of the link
- // .map(link => DocCast(link.link_anchor_1)); // then return the source of the link
}
componentWillUnmount() {
Array.from(Object.keys(this._disposers)).forEach(key => this._disposers[key]());
}
componentDidMount() {
- this._disposers.chartData = reaction(
- () => ({ dataSet: this._pieChartData, w: this.width, h: this.height }),
- ({ dataSet, w, h }) => dataSet!.length > 0 && this.drawChart(dataSet, w, h),
- { fireImmediately: true }
- );
+ // restore selected slices
+ const svg = this._piechartSvg;
+ if (svg && this._pieChartData[0]) {
+ const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_pie_selectedData);
+ svg.selectAll('path').attr('class', (d: any) => {
+ let selected = false;
+ selectedDataBars.forEach(eachSelectedData => {
+ if (d.data === eachSelectedData) selected = true;
+ });
+ if (selected) {
+ this.selectedData.push(d);
+ return 'slice hover';
+ }
+ return 'slice';
+ });
+ }
}
- @action
- restoreView = (data: Doc) => {};
// create a document anchor that stores whatever is needed to reconstruct the viewing state (selection,zoom,etc)
getAnchor = (pinProps?: PinProps) => {
const anchor = Docs.Create.ConfigDocument({
//
title: 'piechart doc selection' + this._currSelected,
});
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document);
return anchor;
};
@@ -122,30 +128,29 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
// cleans data by converting numerical data to numbers and taking out empty cells
data = (dataSet: any) => {
- const validData = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || Number.isNaN(d[key])));
+ const validData = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] /* || isNaN(d[key] as any) */));
const field = dataSet[0] ? Object.keys(dataSet[0])[0] : undefined;
return !field
? undefined
: validData.map((d: { [x: string]: any }) =>
this.byCategory
? d[field] //
- : +d[field].replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '')
+ : +d[field].replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '')
);
};
// outlines the slice selected / hovered over
highlightSelectedSlice = (changeSelectedVariables: boolean, svg: any, arc: any, radius: any, pointer: any, pieDataSet: any) => {
- var index = -1;
- var sameAsCurrent: boolean;
+ let index = -1;
const selected = svg.selectAll('.slice').filter((d: any) => {
index++;
- var p1 = [0, 0]; // center of pie
- var p3 = [arc.centroid(d)[0] * 2, arc.centroid(d)[1] * 2]; // outward peak of arc
- var p2 = [radius * Math.sin(d.startAngle), -radius * Math.cos(d.startAngle)]; // start of arc
- var p4 = [radius * Math.sin(d.endAngle), -radius * Math.cos(d.endAngle)]; // end of arc
+ const p1 = [0, 0]; // center of pie
+ const p3 = [arc.centroid(d)[0] * 2, arc.centroid(d)[1] * 2]; // outward peak of arc
+ const p2 = [radius * Math.sin(d.startAngle), -radius * Math.cos(d.startAngle)]; // start of arc
+ const p4 = [radius * Math.sin(d.endAngle), -radius * Math.cos(d.endAngle)]; // end of arc
// draw an imaginary horizontal line from the pointer to see how many times it crosses a slice edge
- var lineCrossCount = 0;
+ let lineCrossCount = 0;
// if for all 4 lines
if (Math.min(p1[1], p2[1]) <= pointer[1] && pointer[1] <= Math.max(p1[1], p2[1])) {
// within y bounds
@@ -160,68 +165,116 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
if (Math.min(p4[1], p1[1]) <= pointer[1] && pointer[1] <= Math.max(p4[1], p1[1])) {
if (pointer[0] <= ((pointer[1] - p4[1]) * (p1[0] - p4[0])) / (p1[1] - p4[1]) + p4[0]) lineCrossCount++;
}
- if (lineCrossCount % 2 != 0) {
+ if (lineCrossCount % 2 !== 0 || d.startAngle % (2 * Math.PI) === d.endAngle % (2 * Math.PI)) {
// inside the slice of it crosses an odd number of edges
- var showSelected = this.byCategory ? pieDataSet[index] : this._pieChartData[index];
+ const showSelected = this.byCategory ? pieDataSet[index] : this._pieChartData[index];
+ let key = 'data'; // key that represents slice
+ // eslint-disable-next-line prefer-destructuring
+ if (Object.keys(showSelected)[0] === 'frequency') key = Object.keys(showSelected)[1];
if (changeSelectedVariables) {
- // for when a bar is selected - not just hovered over
- sameAsCurrent = this._currSelected
- ? showSelected[Object.keys(showSelected)[0]] == this._currSelected![Object.keys(showSelected)[0]] && showSelected[Object.keys(showSelected)[1]] == this._currSelected![Object.keys(showSelected)[1]]
- : this._currSelected === showSelected;
- this._currSelected = sameAsCurrent ? undefined : showSelected;
- this.selectedData = sameAsCurrent ? undefined : d;
+ let sameAsAny = false;
+ const selectedDataSlices = Cast(this._props.layoutDoc.dataViz_pie_selectedData, listSpec('number'), null);
+ this.selectedData.forEach(eachData => {
+ if (!sameAsAny) {
+ let match = true;
+ Object.keys(d).forEach(objKey => {
+ if (d[objKey] !== eachData[objKey]) match = false;
+ });
+ if (match) {
+ sameAsAny = true;
+ const selIndex = this.selectedData.indexOf(eachData);
+ this.selectedData.splice(selIndex, 1);
+ selectedDataSlices.splice(selIndex, 1);
+ this._currSelected = undefined;
+ }
+ }
+ });
+ if (!sameAsAny) {
+ this.selectedData.push(d);
+ selectedDataSlices.push(d[key]);
+ this._currSelected = this.selectedData.length > 1 ? undefined : showSelected;
+ }
+
+ // for filtering child dataviz docs
+ if (this._props.layoutDoc.dataViz_filterSelection) {
+ const selectedRows = Cast(this._props.layoutDoc.dataViz_selectedRows, listSpec('number'), null);
+ this._tableDataIds.forEach(rowID => {
+ let match = false;
+ if (this._props.records[rowID][this._props.axes[0]] == d[key]) match = true;
+ if (match && !selectedRows?.includes(rowID))
+ selectedRows?.push(rowID); // adding to filtered rows
+ else if (match && sameAsAny) selectedRows.splice(selectedRows.indexOf(rowID), 1); // removing from filtered rows
+ });
+ }
} else this.hoverOverData = d;
return true;
}
return false;
});
if (changeSelectedVariables) {
- if (sameAsCurrent!) this.curSliceSelected = undefined;
- else this.curSliceSelected = selected;
+ if (this._currSelected) this.curSliceSelected = selected;
+ else this.curSliceSelected = undefined;
}
};
// draws the pie chart
drawChart = (dataSet: any, width: number, height: number) => {
- d3.select(this._piechartRef.current).select('svg').remove();
- d3.select(this._piechartRef.current).select('.tooltip').remove();
+ if (!dataSet?.length) return;
+ d3.select(this._piechartRef).select('svg').remove();
+ d3.select(this._piechartRef).select('.tooltip').remove();
- var percentField = Object.keys(dataSet[0])[0];
- var descriptionField = Object.keys(dataSet[0])[1]!;
- var radius = Math.min(width, height - this._props.margin.top - this._props.margin.bottom) / 2;
+ let percentField = Object.keys(dataSet[0])[0];
+ let descriptionField = Object.keys(dataSet[0])[1]!;
+ const radius = Math.min(width, height - this._props.margin.top - this._props.margin.bottom) / 2;
// converts data into Objects
- var data = this.data(dataSet);
- var pieDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || Number.isNaN(d[key])));
+ let data = this.data(dataSet);
+ let pieDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key]));
+ if (!pieDataSet.length) return;
if (this.byCategory) {
- let uniqueCategories = [...new Set(data)];
- var pieStringDataSet: { frequency: number }[] = [];
+ const uniqueCategories = [...new Set(data)];
+ const pieStringDataSet: { frequency: number }[] = [];
for (let i = 0; i < uniqueCategories.length; i++) {
pieStringDataSet.push({ frequency: 0, [percentField]: uniqueCategories[i] });
}
for (let i = 0; i < data.length; i++) {
- let sliceData = pieStringDataSet.filter((each: any) => each[percentField] == data[i]);
- sliceData[0].frequency = sliceData[0].frequency + 1;
+ // eslint-disable-next-line no-loop-func
+ const sliceData = pieStringDataSet.filter((each: any) => each[percentField] == data[i]);
+ sliceData[0].frequency += 1;
}
pieDataSet = pieStringDataSet;
- percentField = Object.keys(pieDataSet[0])[0];
- descriptionField = Object.keys(pieDataSet[0])[1]!;
+ if (!pieDataSet.length) return;
+ [percentField, descriptionField] = Object.keys(pieDataSet[0]);
data = this.data(pieStringDataSet);
}
- var trackDuplicates: { [key: string]: any } = {};
- data.forEach((eachData: any) => (!trackDuplicates[eachData] ? (trackDuplicates[eachData] = 0) : null));
+ let trackDuplicates: { [key: string]: any } = {};
+ data.forEach((eachData: any) => {
+ !trackDuplicates[eachData] ? (trackDuplicates[eachData] = 0) : null;
+ });
// initial chart
- var svg = (this._piechartSvg = d3
- .select(this._piechartRef.current)
+ const svg = (this._piechartSvg = d3
+ .select(this._piechartRef)
.append('svg')
.attr('class', 'graph')
.attr('width', width + this._props.margin.right + this._props.margin.left)
.attr('height', height + this._props.margin.top + this._props.margin.bottom)
.append('g'));
- let g = svg.append('g').attr('transform', 'translate(' + (width / 2 + this._props.margin.left) + ',' + height / 2 + ')');
- var pie = d3.pie();
- var arc = d3.arc().innerRadius(0).outerRadius(radius);
+ const g = svg.append('g').attr('transform', 'translate(' + (width / 2 + this._props.margin.left) + ',' + height / 2 + ')');
+ const pie = d3.pie();
+ const arc = d3.arc().innerRadius(0).outerRadius(radius);
+
+ const updateHighlights = () => {
+ const hoverOverSlice = this.hoverOverData;
+ const { selectedData } = this;
+ svg.selectAll('path').attr('class', (d: any) => {
+ let selected = false;
+ selectedData.forEach((eachSelectedData: any) => {
+ if (d.startAngle === eachSelectedData.startAngle) selected = true;
+ });
+ return selected || (hoverOverSlice && d.startAngle === hoverOverSlice.startAngle && d.endAngle === hoverOverSlice.endAngle) ? 'slice hover' : 'slice';
+ });
+ };
// click/hover
const onPointClick = action((e: any) => this.highlightSelectedSlice(true, svg, arc, radius, d3.pointer(e), pieDataSet));
@@ -229,61 +282,61 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
this.highlightSelectedSlice(false, svg, arc, radius, d3.pointer(e), pieDataSet);
updateHighlights();
});
- const mouseOut = action((e: any) => {
+ const mouseOut = action(() => {
this.hoverOverData = undefined;
updateHighlights();
});
- const updateHighlights = () => {
- const hoverOverSlice = this.hoverOverData;
- const selectedData = this.selectedData;
- svg.selectAll('path').attr('class', function (d: any) {
- return (selectedData && d.startAngle == selectedData.startAngle && d.endAngle == selectedData.endAngle) || (hoverOverSlice && d.startAngle == hoverOverSlice.startAngle && d.endAngle == hoverOverSlice.endAngle)
- ? 'slice hover'
- : 'slice';
- });
- };
-
// drawing the slices
- var selected = this.selectedData;
- var arcs = g.selectAll('arc').data(pie(data)).enter().append('g');
+ const selected = this.selectedData;
+ const arcs = g.selectAll('arc').data(pie(data)).enter().append('g');
const possibleDataPointVals: { [x: string]: any }[] = [];
pieDataSet.forEach((each: { [x: string]: any | { valueOf(): number } }) => {
- var dataPointVal: { [x: string]: any } = {};
+ const dataPointVal: { [x: string]: any } = {};
dataPointVal[percentField] = each[percentField];
if (descriptionField) dataPointVal[descriptionField] = each[descriptionField];
try {
- dataPointVal[percentField] = Number(dataPointVal[percentField].replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, ''));
- } catch (error) {}
+ dataPointVal[percentField] = Number(dataPointVal[percentField].replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, ''));
+ } catch (error) {
+ /* empty */
+ }
possibleDataPointVals.push(dataPointVal);
});
const sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
+
+ // to make sure all important slice information is on 'd' object
+ let addKey: any = false;
+ if (pieDataSet.length && Object.keys(pieDataSet[0])[0] === 'frequency') {
+ // eslint-disable-next-line prefer-destructuring
+ addKey = Object.keys(pieDataSet[0])[1];
+ }
arcs.append('path')
- .attr('fill', (d, i) => {
- var dataPoint;
+ .attr('fill', (d: any, i) => {
+ let dataPoint;
const possibleDataPoints = possibleDataPointVals.filter((pval: any) => pval[percentField] === Number(d.data));
- if (possibleDataPoints.length == 1) dataPoint = possibleDataPoints[0];
+ if (possibleDataPoints.length === 1) [dataPoint] = possibleDataPoints;
else {
dataPoint = possibleDataPoints[trackDuplicates[d.data.toString()]];
trackDuplicates[d.data.toString()] = trackDuplicates[d.data.toString()] + 1;
}
- var sliceColor;
+ let sliceColor;
if (dataPoint) {
+ if (addKey) d[addKey] = dataPoint[addKey]; // adding all slice information to d
const sliceTitle = dataPoint[this._props.axes[0]];
- const accessByName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
- sliceColors.forEach(each => each[0] == accessByName && (sliceColor = each[1]));
+ const accessByName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '') : sliceTitle;
+ sliceColors.forEach(each => {
+ // eslint-disable-next-line prefer-destructuring
+ each[0] === accessByName && (sliceColor = each[1]);
+ });
}
return sliceColor ? StrCast(sliceColor) : d3.schemeSet3[i] ? d3.schemeSet3[i] : d3.schemeSet3[i % d3.schemeSet3.length];
})
- .attr(
- 'class',
- selected
- ? function (d) {
- return selected && d.startAngle == selected.startAngle && d.endAngle == selected.endAngle ? 'slice hover' : 'slice';
- }
- : function (d) {
- return 'slice';
- }
- )
+ .attr('class', d => {
+ let selectThisData = false;
+ selected.forEach((eachSelectedData: any) => {
+ if (d.startAngle === eachSelectedData.startAngle) selectThisData = true;
+ });
+ return selectThisData ? 'slice hover' : 'slice';
+ })
// @ts-ignore
.attr('d', arc)
.on('click', onPointClick)
@@ -292,36 +345,39 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
// adding labels
trackDuplicates = {};
- data.forEach((eachData: any) => (!trackDuplicates[eachData] ? (trackDuplicates[eachData] = 0) : null));
+ data.forEach((eachData: any) => {
+ !trackDuplicates[eachData] ? (trackDuplicates[eachData] = 0) : null;
+ });
arcs.size() < 100 &&
arcs
.append('text')
- .attr('transform', function (d) {
- var centroid = arc.centroid(d as unknown as d3.DefaultArcObject);
- var heightOffset = (centroid[1] / radius) * Math.abs(centroid[1]);
+ .attr('transform', d => {
+ const centroid = arc.centroid(d as unknown as d3.DefaultArcObject);
+ const heightOffset = (centroid[1] / radius) * Math.abs(centroid[1]);
return 'translate(' + (centroid[0] + centroid[0] / (radius * 0.02)) + ',' + (centroid[1] + heightOffset) + ')';
})
+ .attr('pointer-events', 'none')
.attr('text-anchor', 'middle')
- .text(function (d) {
- var dataPoint;
+ .text(d => {
+ let dataPoint;
const possibleDataPoints = possibleDataPointVals.filter((pval: any) => pval[percentField] === Number(d.data));
- if (possibleDataPoints.length == 1) dataPoint = pieDataSet[possibleDataPointVals.indexOf(possibleDataPoints[0])];
+ if (possibleDataPoints.length === 1) dataPoint = pieDataSet[possibleDataPointVals.indexOf(possibleDataPoints[0])];
else {
dataPoint = pieDataSet[possibleDataPointVals.indexOf(possibleDataPoints[trackDuplicates[d.data.toString()]])];
trackDuplicates[d.data.toString()] = trackDuplicates[d.data.toString()] + 1;
}
- return dataPoint ? dataPoint[percentField]! + (!descriptionField ? '' : ' - ' + dataPoint[descriptionField])! : '';
+ return dataPoint ? (descriptionField ? dataPoint[descriptionField] : dataPoint[percentField]!) : '';
});
};
@action changeSelectedColor = (color: string) => {
this.curSliceSelected.attr('fill', color);
const sliceTitle = this._currSelected[this._props.axes[0]];
- const sliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
+ const sliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '') : sliceTitle;
const sliceColors = Cast(this._props.layoutDoc.dataViz_pie_sliceColors, listSpec('string'), null);
- sliceColors.map(each => {
- if (each.split('::')[0] == sliceName) sliceColors.splice(sliceColors.indexOf(each), 1);
+ sliceColors.forEach(each => {
+ if (each.split('::')[0] === sliceName) sliceColors.splice(sliceColors.indexOf(each), 1);
});
sliceColors.push(StrCast(sliceName + '::' + color));
};
@@ -332,39 +388,40 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
};
render() {
- var titleAccessor: any = 'dataViz_pie_title';
- if (this._props.axes.length == 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
- else if (this._props.axes.length > 0) titleAccessor = titleAccessor + this._props.axes[0];
+ let titleAccessor: any = 'dataViz_pie_title';
+ if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
+ else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0];
if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle;
if (!this._props.layoutDoc.dataViz_pie_sliceColors) this._props.layoutDoc.dataViz_pie_sliceColors = new List<string>();
- var selected: string;
- var curSelectedSliceName = '';
+ if (!this._props.layoutDoc.dataViz_pie_selectedData) this._props.layoutDoc.dataViz_pie_selectedData = new List<string>();
+ let selected: string;
+ let curSelectedSliceName = '';
if (this._currSelected) {
selected = '{ ';
const sliceTitle = this._currSelected[this._props.axes[0]];
- curSelectedSliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
- Object.keys(this._currSelected).map(key => {
- key != '' ? (selected += key + ': ' + this._currSelected[key] + ', ') : '';
+ curSelectedSliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '') : sliceTitle;
+ Object.keys(this._currSelected).forEach(key => {
+ key !== '' ? (selected += key + ': ' + this._currSelected[key] + ', ') : '';
});
selected = selected.substring(0, selected.length - 2);
selected += ' }';
- if (this._props.titleCol!="" && (!this._currSelected["frequency"] || this._currSelected["frequency"]<10)){
- selected+= "\n" + this._props.titleCol + ": "
+ if (this._props.titleCol !== '' && (!this._currSelected.frequency || this._currSelected.frequency < 10)) {
+ selected += '\n' + this._props.titleCol + ': ';
this._tableData.forEach(each => {
- if (this._currSelected[this._props.axes[0]]==each[this._props.axes[0]]) {
- if (this._props.axes[1]){
- if (this._currSelected[this._props.axes[1]]==each[this._props.axes[1]]) selected+= each[this._props.titleCol] + ", ";
- }
- else selected+= each[this._props.titleCol] + ", ";
+ if (this._currSelected[this._props.axes[0]] === each[this._props.axes[0]]) {
+ if (this._props.axes[1]) {
+ if (this._currSelected[this._props.axes[1]] === each[this._props.axes[1]]) selected += each[this._props.titleCol] + ', ';
+ } else selected += each[this._props.titleCol] + ', ';
}
- })
- selected = selected.slice(0,-1).slice(0,-1);
+ });
+ selected = selected.slice(0, -1).slice(0, -1);
}
} else selected = 'none';
- var selectedSliceColor;
- var sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
+ let selectedSliceColor;
+ const sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
sliceColors.forEach(each => {
- if (each[0] == curSelectedSliceName!) selectedSliceColor = each[1];
+ // eslint-disable-next-line prefer-destructuring
+ if (each[0] === curSelectedSliceName!) selectedSliceColor = each[1];
});
if (this._pieChartData.length > 0 || !this.parentViz) {
@@ -374,30 +431,37 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
<EditableText
val={StrCast(this._props.layoutDoc[titleAccessor])}
setVal={undoable(
- action(val => (this._props.layoutDoc[titleAccessor] = val as string)),
+ action(val => {
+ this._props.layoutDoc[titleAccessor] = val as string;
+ }),
'Change Graph Title'
)}
- color={'black'}
+ color="black"
size={Size.LARGE}
fillWidth
/>
</div>
{this._props.axes.length === 1 && /\d/.test(this._props.records[0][this._props.axes[0]]) ? (
- <div className={'asHistogram-checkBox'} style={{ width: this._props.width }}>
+ <div className="asHistogram-checkBox" style={{ width: this._props.width }}>
<Checkbox color="primary" onChange={this.changeHistogramCheckBox} checked={this._props.layoutDoc.dataViz_pie_asHistogram as boolean} />
Organize data as histogram
</div>
) : null}
- <div ref={this._piechartRef} />
- {selected != 'none' ? (
- <div className={'selected-data'}>
+ <div
+ ref={r => {
+ this._piechartRef = r;
+ this.drawChart(this._pieChartData, this.width, this.height);
+ }}
+ />
+ {selected !== 'none' ? (
+ <div className="selected-data">
Selected: {selected}
&nbsp; &nbsp;
<ColorPicker
- tooltip={'Change Slice Color'}
+ tooltip="Change Slice Color"
type={Type.SEC}
icon={<FaFillDrip />}
- selectedColor={selectedSliceColor ? selectedSliceColor : this.curSliceSelected.attr('fill')}
+ selectedColor={selectedSliceColor || this.curSliceSelected.attr('fill')}
setFinalColor={undoable(color => this.changeSelectedColor(color), 'Change Selected Slice Color')}
setSelectedColor={undoable(color => this.changeSelectedColor(color), 'Change Selected Slice Color')}
size={Size.XSMALL}
@@ -406,12 +470,12 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
) : null}
</div>
) : (
- <span className="chart-container"> {'first use table view to select a column to graph'}</span>
- );
- } else
- return (
- // when it is a brushed table and the incoming table doesn't have any rows selected
- <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
+ <span className="chart-container"> first use table view to select a column to graph</span>
);
+ }
+ return (
+ // when it is a brushed table and the incoming table doesn't have any rows selected
+ <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
+ );
}
}
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index 1b239b5e5..a1deb1625 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -1,18 +1,25 @@
+/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import { Button, Type } from 'browndash-components';
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../../Utils';
+import { ClientUtils, setupMoveUpEvents } from '../../../../../ClientUtils';
+import { emptyFunction } from '../../../../../Utils';
import { Doc, Field, NumListCast } from '../../../../../fields/Doc';
+import { DocData } from '../../../../../fields/DocSymbols';
import { List } from '../../../../../fields/List';
import { listSpec } from '../../../../../fields/Schema';
import { Cast, DocCast } from '../../../../../fields/Types';
import { DragManager } from '../../../../util/DragManager';
+import { undoable } from '../../../../util/UndoManager';
import { ObservableReactComponent } from '../../../ObservableReactComponent';
import { DocumentView } from '../../DocumentView';
import { DataVizView } from '../DataVizBox';
import './Chart.scss';
-const { default: { DATA_VIZ_TABLE_ROW_HEIGHT } } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore
+
+const { DATA_VIZ_TABLE_ROW_HEIGHT } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore
+
interface TableBoxProps {
Document: Doc;
layoutDoc: Doc;
@@ -37,6 +44,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
_inputChangedDisposer?: IReactionDisposer;
_containerRef: HTMLDivElement | null = null;
+ @observable settingTitle: boolean = false; // true when setting a title column
+ @observable hasRowsToFilter: boolean = false; // true when any rows are selected
+ @observable filtering: boolean = false; // true when the filtering menu is open
+ @observable filteringColumn: any = ''; // column to filter
+ @observable filteringType: string = 'Value'; // "Value" or "Range"
+ filteringVal: any[] = ['', '']; // value or range to filter the column with
+
@observable _scrollTop = -1;
@observable _tableHeight = 0;
@observable _tableContainerHeight = 0;
@@ -49,6 +63,11 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
// if the tableData changes (ie., when records are selected by the parent (input) visulization),
// then we need to remove any selected rows that are no longer part of the visualized dataset.
this._inputChangedDisposer = reaction(() => this._tableData.slice(), this.filterSelectedRowsDown, { fireImmediately: true });
+ const selected = NumListCast(this._props.layoutDoc.dataViz_selectedRows);
+ if (selected.length > 0)
+ runInAction(() => {
+ this.hasRowsToFilter = true;
+ });
this.handleScroll();
}
componentWillUnmount() {
@@ -64,13 +83,10 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
@computed get parentViz() {
return DocCast(this._props.Document.dataViz_parentViz);
- // return LinkManager.Instance.getAllRelatedLinks(this._props.Document) // out of all links
- // .filter(link => link.link_anchor_1 == this._props.Document.dataViz_parentViz) // get links where this chart doc is the target of the link
- // .map(link => DocCast(link.link_anchor_1)); // then return the source of the link
}
@computed get columns() {
- return this._tableData.length ? Array.from(Object.keys(this._tableData[0])).filter(header => header != '' && header != undefined) : [];
+ return this._tableData.length ? Array.from(Object.keys(this._tableData[0])).filter(header => header !== '' && header !== undefined) : [];
}
// updates the 'dataViz_selectedRows' and 'dataViz_highlightedRows' fields to no longer include rows that aren't in the table
@@ -107,14 +123,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1);
else highlited?.push(rowId);
if (!selected?.includes(rowId)) selected?.push(rowId);
- } else {
+ } else if (selected?.includes(rowId)) {
// selecting a row
- if (selected?.includes(rowId)) {
- if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1);
- selected.splice(selected.indexOf(rowId), 1);
- } else selected?.push(rowId);
- }
+ if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1);
+ selected.splice(selected.indexOf(rowId), 1);
+ } else selected?.push(rowId);
e.stopPropagation();
+ this.hasRowsToFilter = selected.length > 0;
};
columnPointerDown = (e: React.PointerEvent, col: string) => {
@@ -123,13 +138,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
setupMoveUpEvents(
{},
e,
- e => {
+ moveEv => {
// dragging off a column to create a brushed DataVizBox
const sourceAnchorCreator = () => this._props.docView?.()!.Document!;
const targetCreator = (annotationOn: Doc | undefined) => {
const embedding = Doc.MakeEmbedding(this._props.docView?.()!.Document!);
embedding._dataViz = DataVizView.TABLE;
- embedding._dataViz_axes = new List<string>([col, col]);
+ embedding._dataViz_axes = new List<string>([col]);
embedding._dataViz_parentViz = this._props.Document;
embedding.annotationOn = annotationOn;
embedding.histogramBarColors = Field.Copy(this._props.layoutDoc.histogramBarColors);
@@ -137,15 +152,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
embedding.pieSliceColors = Field.Copy(this._props.layoutDoc.pieSliceColors);
return embedding;
};
- if (this._props.docView?.() && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) {
- DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, {
- dragComplete: e => {
- if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
- e.linkDocument.link_displayLine = true;
- e.linkDocument.link_matchEmbeddings = true;
- e.linkDocument.link_displayArrow = true;
- // e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this._props.Document;
- // e.annoDragData.linkSourceDoc.followLinkZoom = false;
+ if (this._props.docView?.() && !ClientUtils.isClick(moveEv.clientX, moveEv.clientY, downX, downY, Date.now())) {
+ DragManager.StartAnchorAnnoDrag(moveEv.target instanceof HTMLElement ? [moveEv.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, {
+ dragComplete: completeEv => {
+ if (!completeEv.aborted && completeEv.annoDragData && completeEv.annoDragData.linkSourceDoc && completeEv.annoDragData.dropDocument && completeEv.linkDocument) {
+ completeEv.linkDocument[DocData].link_matchEmbeddings = true;
+ completeEv.linkDocument[DocData].stroke_startMarker = true;
+ this._props.docView?.()?._props.addDocument?.(completeEv.linkDocument);
}
},
});
@@ -154,16 +167,16 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
return false;
},
emptyFunction,
- action(e => {
- if (e.shiftKey){
- if (this._props.titleCol == col) this._props.titleCol = "";
+ action(moveEv => {
+ if (moveEv.shiftKey || this.settingTitle) {
+ if (this.settingTitle) this.settingTitle = false;
+ if (this._props.titleCol === col) this._props.titleCol = '';
else this._props.titleCol = col;
this._props.selectTitleCol(this._props.titleCol);
- }
- else{
+ } else {
const newAxes = this._props.axes;
if (newAxes.includes(col)) newAxes.splice(newAxes.indexOf(col), 1);
- else if (newAxes.length > 2) newAxes[newAxes.length-1] = col;
+ else if (newAxes.length > 2) newAxes[newAxes.length - 1] = col;
else newAxes.push(col);
this._props.selectAxes(newAxes);
}
@@ -171,6 +184,134 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
);
};
+ /**
+ * These functions handle the filtering popup for when the "filter" button is pressed to select rows
+ */
+ filter = undoable((e: any) => {
+ let start: any;
+ let end: any;
+ if (this.filteringType === 'Range') {
+ start = Number.isNaN(Number(this.filteringVal[0])) ? this.filteringVal[0] : Number(this.filteringVal[0]);
+ end = Number.isNaN(Number(this.filteringVal[1])) ? this.filteringVal[1] : Number(this.filteringVal[1]);
+ }
+
+ this._tableDataIds.forEach(rowID => {
+ if (this.filteringType === 'Value') {
+ if (this._props.records[rowID][this.filteringColumn] === this.filteringVal[0]) {
+ if (!NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowID)) {
+ this.tableRowClick(e, rowID);
+ }
+ }
+ } else {
+ let compare = this._props.records[rowID][this.filteringColumn];
+ if (compare as Number) compare = Number(compare);
+ if (start <= compare && compare <= end) {
+ if (!NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowID)) {
+ this.tableRowClick(e, rowID);
+ }
+ }
+ }
+ });
+ this.filtering = false;
+ this.filteringColumn = '';
+ this.filteringVal = ['', ''];
+ }, 'filter table');
+ @action
+ setFilterColumn = (e: any) => {
+ this.filteringColumn = e.currentTarget.value;
+ };
+ @action
+ setFilterType = (e: any) => {
+ this.filteringType = e.currentTarget.value;
+ };
+ changeFilterValue = action((e: React.ChangeEvent<HTMLInputElement>) => {
+ this.filteringVal[0] = e.target.value;
+ });
+ changeFilterRange0 = action((e: React.ChangeEvent<HTMLInputElement>) => {
+ this.filteringVal[0] = e.target.value;
+ });
+ changeFilterRange1 = action((e: React.ChangeEvent<HTMLInputElement>) => {
+ this.filteringVal[1] = e.target.value;
+ });
+ @computed get renderFiltering() {
+ if (this.filteringColumn === '') [this.filteringColumn] = this.columns;
+ return (
+ <div className="tableBox-filterPopup" style={{ right: this._props.width * 0.05 }}>
+ <div className="tableBox-filterPopup-selectColumn">
+ Column:
+ <select className="tableBox-filterPopup-selectColumn-each" value={this.filteringColumn !== '' ? this.filteringColumn : this.columns[0]} onChange={e => this.setFilterColumn(e)}>
+ {this.columns.map(column => (
+ <option className="" key={column} value={column}>
+ {' '}
+ {column}{' '}
+ </option>
+ ))}
+ </select>
+ </div>
+ <div className="tableBox-filterPopup-setValue">
+ <select className="tableBox-filterPopup-setValue-each" value={this.filteringType} onChange={e => this.setFilterType(e)}>
+ <option className="" key="Value" value="Value">
+ {' '}
+ {'Value'}{' '}
+ </option>
+ <option className="" key="Range" value="Range">
+ {' '}
+ {'Range'}{' '}
+ </option>
+ </select>
+ :
+ {this.filteringType === 'Value' ? (
+ <input
+ className="tableBox-filterPopup-setValue-input"
+ defaultValue=""
+ autoComplete="off"
+ onChange={this.changeFilterValue}
+ onKeyDown={e => {
+ e.stopPropagation();
+ }}
+ type="text"
+ placeholder=""
+ id="search-input"
+ />
+ ) : (
+ <div>
+ <input
+ className="tableBox-filterPopup-setValue-input"
+ defaultValue=""
+ autoComplete="off"
+ onChange={this.changeFilterRange0}
+ onKeyDown={e => {
+ e.stopPropagation();
+ }}
+ type="text"
+ placeholder=""
+ id="search-input"
+ style={{ width: this._props.width * 0.15 }}
+ />
+ to
+ <input
+ className="tableBox-filterPopup-setValue-input"
+ defaultValue=""
+ autoComplete="off"
+ onChange={this.changeFilterRange1}
+ onKeyDown={e => {
+ e.stopPropagation();
+ }}
+ type="text"
+ placeholder=""
+ id="search-input"
+ style={{ width: this._props.width * 0.15 }}
+ />
+ </div>
+ )}
+ </div>
+ <div className="tableBox-filterPopup-setFilter">
+ <Button onClick={action(e => this.filter(e))} text="Set Filter" type={Type.SEC} color="black" />
+ </div>
+ </div>
+ );
+ }
+
render() {
if (this._tableData.length > 0) {
return (
@@ -184,9 +325,53 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds);
}
}}>
- <div className="selectAll-buttons">
- <Button onClick={action(() => (this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds)))} text="Select All" type={Type.SEC} color={'black'} />
- <Button onClick={action(() => (this._props.layoutDoc.dataViz_selectedRows = new List<number>()))} text="Deselect All" type={Type.SEC} color={'black'} />
+ <div className="tableBox-selectButtons">
+ <div className="tableBox-selectTitle">
+ <Button
+ onClick={action(() => {
+ this.settingTitle = !this.settingTitle;
+ })}
+ text="Select Title Column"
+ type={Type.SEC}
+ color="black"
+ />
+ </div>
+ <div className="tableBox-filtering">
+ {this.filtering ? this.renderFiltering : null}
+ <Button
+ onClick={action(() => {
+ this.filtering = !this.filtering;
+ })}
+ text="Filter"
+ type={Type.SEC}
+ color="black"
+ />
+ <div className="tableBox-filterAll">
+ {this.hasRowsToFilter ? (
+ <Button
+ onClick={action(() => {
+ this._props.layoutDoc.dataViz_selectedRows = new List<number>();
+ this.hasRowsToFilter = false;
+ })}
+ text="Deselect All"
+ type={Type.SEC}
+ color="black"
+ tooltip="Select rows to be displayed in any DataViz boxes dragged off of this one."
+ />
+ ) : (
+ <Button
+ onClick={action(() => {
+ this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds);
+ this.hasRowsToFilter = true;
+ })}
+ text="Select All"
+ type={Type.SEC}
+ color="black"
+ tooltip="Select rows to be displayed in any DataViz boxes dragged off of this one."
+ />
+ )}
+ </div>
+ </div>
</div>
<div
className={`tableBox-container ${this.columns[0]}`}
@@ -220,15 +405,23 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
<th
key={this.columns.indexOf(col)}
style={{
- color: this._props.axes.slice().reverse().lastElement() === col ? 'darkgreen'
- : (this._props.axes.length>2 && this._props.axes.lastElement() === col) ? 'darkred'
- : (this._props.axes.lastElement()===col || (this._props.axes.length>2 && this._props.axes[1]==col))? 'darkblue' : undefined,
- background: this._props.axes.slice().reverse().lastElement() === col ? '#E3fbdb'
- : (this._props.axes.length>2 && this._props.axes.lastElement() === col) ? '#Fbdbdb'
- : (this._props.axes.lastElement()===col || (this._props.axes.length>2 && this._props.axes[1]==col))? '#c6ebf7' : undefined,
- // blue: #ADD8E6
- // green: #E3fbdb
- // red: #Fbdbdb
+ color:
+ this._props.axes.slice().reverse().lastElement() === col
+ ? 'darkgreen'
+ : this._props.axes.length > 2 && this._props.axes.lastElement() === col
+ ? 'darkred'
+ : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] === col)
+ ? 'darkblue'
+ : undefined,
+ background: this.settingTitle
+ ? 'lightgrey'
+ : this._props.axes.slice().reverse().lastElement() === col
+ ? '#E3fbdb'
+ : this._props.axes.length > 2 && this._props.axes.lastElement() === col
+ ? '#Fbdbdb'
+ : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] === col)
+ ? '#c6ebf7'
+ : undefined,
fontWeight: 'bolder',
border: '3px solid black',
}}
@@ -250,11 +443,11 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
background: NumListCast(this._props.layoutDoc.dataViz_highlitedRows).includes(rowId) ? 'lightYellow' : NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowId) ? 'lightgrey' : '',
}}>
{this.columns.map(col => {
- var colSelected = false;
- if (this._props.axes.length>2) colSelected = this._props.axes[0]==col || this._props.axes[1]==col || this._props.axes[2]==col;
- else if (this._props.axes.length>1) colSelected = this._props.axes[0]==col || this._props.axes[1]==col;
- else if (this._props.axes.length>0) colSelected = this._props.axes[0]==col;
- if (this._props.titleCol==col) colSelected = true;
+ let colSelected = false;
+ if (this._props.axes.length > 2) colSelected = this._props.axes[0] === col || this._props.axes[1] === col || this._props.axes[2] === col;
+ else if (this._props.axes.length > 1) colSelected = this._props.axes[0] === col || this._props.axes[1] === col;
+ else if (this._props.axes.length > 0) colSelected = this._props.axes[0] === col;
+ if (this._props.titleCol === col) colSelected = true;
return (
<td key={this.columns.indexOf(col)} style={{ border: colSelected ? '3px solid black' : '1px solid black', fontWeight: colSelected ? 'bolder' : 'normal' }}>
<div className="tableBox-cell">{this._props.records[rowId][col]}</div>
@@ -269,10 +462,10 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
</div>
</div>
);
- } else
- return (
- // when it is a brushed table and the incoming table doesn't have any rows selected
- <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
- );
+ }
+ return (
+ // when it is a brushed table and the incoming table doesn't have any rows selected
+ <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
+ );
}
}
diff --git a/src/client/views/nodes/DataVizBox/utils/D3Utils.ts b/src/client/views/nodes/DataVizBox/utils/D3Utils.ts
index 336935d23..ffc859c92 100644
--- a/src/client/views/nodes/DataVizBox/utils/D3Utils.ts
+++ b/src/client/views/nodes/DataVizBox/utils/D3Utils.ts
@@ -1,15 +1,18 @@
import * as d3 from 'd3';
-import { DataPoint } from '../components/LineChart';
+export interface DataPoint {
+ x: number;
+ y: number;
+}
// TODO: nda - implement function that can handle range for strings
export const minMaxRange = (dataPts: DataPoint[][]) => {
// find the max and min of all the data points
- const yMin = d3.min(dataPts, d => d3.min(d, d => Number(d.y)));
- const yMax = d3.max(dataPts, d => d3.max(d, d => Number(d.y)));
+ const yMin = d3.min(dataPts, d => d3.min(d, m => Number(m.y)));
+ const yMax = d3.max(dataPts, d => d3.max(d, m => Number(m.y)));
- const xMin = d3.min(dataPts, d => d3.min(d, d => Number(d.x)));
- const xMax = d3.max(dataPts, d => d3.max(d, d => Number(d.x)));
+ const xMin = d3.min(dataPts, d => d3.min(d, m => Number(m.x)));
+ const xMax = d3.max(dataPts, d => d3.max(d, m => Number(m.x)));
return { xMin, xMax, yMin, yMax };
};
@@ -20,18 +23,15 @@ export const scaleCreatorCategorical = (labels: string[], range: number[]) => {
return scale;
};
-export const scaleCreatorNumerical = (domA: number, domB: number, rangeA: number, rangeB: number) => {
- return d3.scaleLinear().domain([domA, domB]).range([rangeA, rangeB]);
-};
+export const scaleCreatorNumerical = (domA: number, domB: number, rangeA: number, rangeB: number) => d3.scaleLinear().domain([domA, domB]).range([rangeA, rangeB]);
-export const createLineGenerator = (xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>) => {
+export const createLineGenerator = (xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>) =>
// TODO: nda - look into the different types of curves
- return d3
+ d3
.line<DataPoint>()
.x(d => xScale(d.x))
.y(d => yScale(d.y))
.curve(d3.curveMonotoneX);
-};
export const xAxisCreator = (g: d3.Selection<SVGGElement, unknown, null, undefined>, height: number, xScale: d3.ScaleLinear<number, number, never>) => {
g.attr('class', 'x-axis').attr('transform', `translate(0,${height})`).call(d3.axisBottom(xScale).tickSize(15));
@@ -48,7 +48,7 @@ export const xGrid = (g: d3.Selection<SVGGElement, unknown, null, undefined>, he
d3
.axisBottom(scale)
.tickSize(-height)
- .tickFormat((a, b) => '')
+ .tickFormat((/* a, b */) => '')
);
};
@@ -57,10 +57,16 @@ export const yGrid = (g: d3.Selection<SVGGElement, unknown, null, undefined>, wi
d3
.axisLeft(scale)
.tickSize(-width)
- .tickFormat((a, b) => '')
+ .tickFormat((/* a, b */) => '')
);
};
export const drawLine = (p: d3.Selection<SVGPathElement, unknown, null, undefined>, dataPts: DataPoint[], lineGen: d3.Line<DataPoint>, extra: boolean) => {
- p.datum(dataPts).attr('fill', 'none').attr('stroke', 'rgba(53, 162, 235, 0.5)').attr('stroke-width', 2).attr('stroke', extra? 'blue' : 'black').attr('class', 'line').attr('d', lineGen);
+ p.datum(dataPts)
+ .attr('fill', 'none')
+ .attr('stroke', 'rgba(53, 162, 235, 0.5)')
+ .attr('stroke-width', 2)
+ .attr('stroke', extra ? 'blue' : 'black')
+ .attr('class', 'line')
+ .attr('d', lineGen);
};
diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss
new file mode 100644
index 000000000..d2749f1ad
--- /dev/null
+++ b/src/client/views/nodes/DiagramBox.scss
@@ -0,0 +1,88 @@
+.DIYNodeBox {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ 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;
+
+ }
+ }
+
+ .search-bar {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ padding: 10px;
+
+ input[type="text"] {
+ flex: 1;
+ margin-right: 10px;
+ }
+
+ button {
+ padding: 5px 10px;
+ }
+ }
+
+ .content {
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width:100%;
+ height:100%;
+ .diagramBox{
+ 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%;
+ }
+ }
+ }
+
+ .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);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx
new file mode 100644
index 000000000..fa7e5868a
--- /dev/null
+++ b/src/client/views/nodes/DiagramBox.tsx
@@ -0,0 +1,305 @@
+import { makeObservable, observable, action, reaction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
+import { StyleProp } from '../StyleProvider';
+import './DiagramBox.scss';
+import { FieldView, FieldViewProps } from './FieldView';
+import { PinProps, PresBox } from './trails';
+import mermaid from 'mermaid';
+import { Doc, DocListCast } from '../../../fields/Doc';
+import { List } from '../../../fields/List';
+import { RichTextField } from '../../../fields/RichTextField';
+import { ContextMenu } from '../ContextMenu';
+import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT';
+import { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
+import OpenAI, { ClientOptions } from 'openai';
+import { line } from 'd3';
+import { InkingStroke } from '../InkingStroke';
+import { DocumentManager } from '../../util/DocumentManager';
+import { C } from '@fullcalendar/core/internal-common';
+import { Docs } from '../../documents/Documents';
+import { NumCast } from '../../../fields/Types';
+import { LinkManager } from '../../util/LinkManager';
+import { CsvCast, DocCast, StrCast } from '../../../fields/Types';
+import { DocumentType } from '../../documents/DocumentTypes';
+
+@observer
+export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+ public static LayoutString(fieldKey: string) {
+ return FieldView.LayoutString(DiagramBox, fieldKey);
+ }
+ private _ref: React.RefObject<HTMLDivElement> = React.createRef();
+ private _dragRef = React.createRef<HTMLDivElement>();
+ constructor(props: FieldViewProps) {
+ super(props);
+ makeObservable(this);
+ }
+
+ @observable inputValue = '';
+ @observable loading = false;
+ @observable errorMessage = '';
+ @observable mermaidCode = '';
+
+ @action handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.inputValue = e.target.value;
+ };
+ async componentDidMount() {
+ this._props.setContentViewBox?.(this);
+ mermaid.initialize({
+ securityLevel: 'loose',
+ startOnLoad: true,
+ flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
+ });
+ this.mermaidCode = 'asdasdasd';
+ 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]) {
+ 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) {
+ let 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
+ reaction(
+ () => DocListCast(this.Document.data),
+ docs => {
+ console.log('reaction happened');
+ this.convertDrawingToMermaidCode();
+ },
+ { fireImmediately: true }
+ );
+ }
+ renderMermaid = async (str: string) => {
+ try {
+ const { svg, bindFunctions } = await this.mermaidDiagram(str);
+ return { svg, bindFunctions };
+ } catch (error) {
+ console.error('Error rendering mermaid diagram:', error);
+ return { svg: '', bindFunctions: undefined };
+ }
+ };
+ mermaidDiagram = async (str: string) => {
+ return await mermaid.render('graph' + Date.now(), str);
+ };
+
+ async renderMermaidAsync(mermaidCode: string) {
+ 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);
+ }
+ }
+ } 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');
+ //}
+ let 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) => {
+ return true;
+ };
+ removeWords(inputStr: string) {
+ inputStr = inputStr.replace('```mermaid', '');
+ return inputStr.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) {
+ let docArray: Doc[] = DocListCast(this.Document.data);
+ let rectangleArray = docArray.filter(doc => doc.title == 'rectangle' || doc.title == 'circle');
+ let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke');
+ let textArray = docArray.filter(doc => doc.type == 'rich text');
+ const timeoutPromise = () =>
+ new Promise(resolve => {
+ setTimeout(resolve, 0);
+ });
+ await timeoutPromise();
+ let 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;';
+ let 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++) {
+ let inkScaleX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX;
+ let inkScaleY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY;
+ let inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke)
+ ?.inkScaledData()
+ .inkData.map(coord => coord.X)
+ .map(doc => doc * inkScaleX);
+ let 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
+ let minX: number = Math.min(...inkStrokeXArray);
+ let minY: number = Math.min(...inkStrokeYArray);
+ let startX = inkStrokeXArray[0] - minX + (lineArray[j]?.x as number);
+ let startY = inkStrokeYArray[0] - minY + (lineArray[j]?.y as number);
+ let endX = inkStrokeXArray[inkStrokeXArray.length - 1] - minX + (lineArray[j].x as number);
+ let 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) {
+ let 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) + ';';
+ }
+ }
+ }
+ }
+ }
+ }
+ //this will save the text
+ DocumentManager.Instance.AddViewRenderedCb(this.Document, docViewForYourCollection => {
+ if (docViewForYourCollection && docViewForYourCollection.ComponentView) {
+ if (docViewForYourCollection.ComponentView.addDocument && docViewForYourCollection.ComponentView.removeDocument) {
+ let docArray: Doc[] = DocListCast(this.Document.data);
+ docArray = docArray.filter(doc => doc.type == 'rich text');
+ let mermaidCodeDoc = docArray.filter(doc => (doc.text as RichTextField).Text == 'mermaidCodeTitle');
+ if (mermaidCodeDoc[0]) {
+ if (diagramExists) {
+ mermaidCodeDoc[0].title = mermaidCode;
+ } else {
+ mermaidCodeDoc[0].title = '';
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+ testInkingStroke = () => {
+ if (this.Document.data instanceof List) {
+ let docArray: Doc[] = DocListCast(this.Document.data);
+ let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke');
+ setTimeout(() => {
+ let 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++) {
+ let 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 + '))';
+ }
+ }
+ }
+ }
+ 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;
+ } else {
+ return false;
+ }
+ };
+
+ render() {
+ return (
+ <div ref={this._ref} className="DIYNodeBox">
+ <div ref={this._dragRef} className="DIYNodeBox-wrapper">
+ <div className="search-bar">
+ <input type="text" value={this.inputValue} onChange={this.handleInputChange} />
+ <button onClick={this.handleRenderClick}>Generate</button>
+ </div>
+ <div className="content">
+ {this.mermaidCode ? (
+ <div id={'dashDiv' + this.Document.title} className="diagramBox"></div>
+ ) : (
+ <div>{this.loading ? <div className="loading-circle"></div> : <div>{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}</div>}</div>
+ )}
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
+
+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' },
+});
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 07e179246..192c7875e 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,67 +1,24 @@
+/* eslint-disable react/require-default-props */
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import JsxParser from 'react-jsx-parser';
import * as XRegExp from 'xregexp';
-import { OmitKeys, Without, emptyPath } from '../../../Utils';
+import { OmitKeys } from '../../../ClientUtils';
+import { Without, emptyPath } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
import { AclPrivate, DocData } from '../../../fields/DocSymbols';
import { ScriptField } from '../../../fields/ScriptField';
-import { Cast, StrCast } from '../../../fields/Types';
+import { Cast, DocCast, StrCast } from '../../../fields/Types';
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
-import { InkingStroke } from '../InkingStroke';
-import { ObservableReactComponent } from '../ObservableReactComponent';
-import { CollectionCalendarView } from '../collections/CollectionCalendarView';
-import { CollectionDockingView } from '../collections/CollectionDockingView';
-import { CollectionView } from '../collections/CollectionView';
-import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
-import { CollectionSchemaView } from '../collections/collectionSchema/CollectionSchemaView';
-import { SchemaRowBox } from '../collections/collectionSchema/SchemaRowBox';
-import { PresElementBox } from '../nodes/trails/PresElementBox';
-import { SearchBox } from '../search/SearchBox';
-import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo';
-import { YoutubeBox } from './../../apis/youtube/YoutubeBox';
-import { AudioBox } from './AudioBox';
-import { ComparisonBox } from './ComparisonBox';
-import { DataVizBox } from './DataVizBox/DataVizBox';
+import { ObservableReactComponent, ObserverJsxParser } from '../ObservableReactComponent';
import './DocumentView.scss';
-import { EquationBox } from './EquationBox';
-import { FieldView, FieldViewProps } from './FieldView';
-import { FontIconBox } from './FontIconBox/FontIconBox';
-import { FunctionPlotBox } from './FunctionPlotBox';
-import { ImageBox } from './ImageBox';
-import { KeyValueBox } from './KeyValueBox';
-import { LabelBox } from './LabelBox';
-import { LinkAnchorBox } from './LinkAnchorBox';
-import { LinkBox } from './LinkBox';
-import { LoadingBox } from './LoadingBox';
-import { MapBox } from './MapBox/MapBox';
-import { MapPushpinBox } from './MapBox/MapPushpinBox';
-import { PDFBox } from './PDFBox';
-import { PhysicsSimulationBox } from './PhysicsBox/PhysicsSimulationBox';
-import { RecordingBox } from './RecordingBox';
-import { ScreenshotBox } from './ScreenshotBox';
-import { ScriptingBox } from './ScriptingBox';
-import { VideoBox } from './VideoBox';
-import { WebBox } from './WebBox';
-import { FormattedTextBox } from './formattedText/FormattedTextBox';
-import { ImportElementBox } from './importBox/ImportElementBox';
-import { PresBox } from './trails/PresBox';
+import { FieldViewProps } from './FieldView';
type BindingProps = Without<FieldViewProps, 'fieldKey'>;
export interface JsxBindings {
props: BindingProps;
}
-class ObserverJsxParser1 extends JsxParser {
- constructor(props: any) {
- super(props);
- observer(this as any);
- }
-}
-
-export const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any;
-
interface HTMLtagProps {
Document: Doc;
htmltag: string;
@@ -71,8 +28,8 @@ interface HTMLtagProps {
children?: JSX.Element[];
}
-//"<HTMLdiv borderRadius='100px' onClick={this.bannerColor=this.bannerColor==='red'?'green':'red'} overflow='hidden' position='absolute' width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)'> <ImageBox {...props} fieldKey={'data'}/> <HTMLspan width='200px' top='0' height='35px' textAlign='center' paddingTop='10px' transform='translate(-40px, 45px) rotate(-45deg)' position='absolute' color='{this.bannerColor===`green`?`light`:`dark`}blue' backgroundColor='{this.bannerColor===`green`?`dark`:`light`}blue'> {this.title}</HTMLspan></HTMLdiv>"
-//"<HTMLdiv borderRadius='100px' overflow='hidden' position='absolute' width='100%' height='100%'
+// "<HTMLdiv borderRadius='100px' onClick={this.bannerColor=this.bannerColor==='red'?'green':'red'} overflow='hidden' position='absolute' width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)'> <ImageBox {...props} fieldKey={'data'}/> <HTMLspan width='200px' top='0' height='35px' textAlign='center' paddingTop='10px' transform='translate(-40px, 45px) rotate(-45deg)' position='absolute' color='{this.bannerColor===`green`?`light`:`dark`}blue' backgroundColor='{this.bannerColor===`green`?`dark`:`light`}blue'> {this.title}</HTMLspan></HTMLdiv>"
+// "<HTMLdiv borderRadius='100px' overflow='hidden' position='absolute' width='100%' height='100%'
// transform='rotate({2*this.x+this.y}deg)'
// onClick = { this.bannerColor = this.bannerColor === 'red' ? 'green' : 'red' } >
// <ImageBox {...props} fieldKey={'data'}/>
@@ -85,22 +42,21 @@ interface HTMLtagProps {
// </HTMLdiv>"
@observer
export class HTMLtag extends React.Component<HTMLtagProps> {
- click = (e: React.MouseEvent) => {
+ click = () => {
const clickScript = (this.props as any).onClick as Opt<ScriptField>;
- clickScript?.script.run({ this: this.props.Document, self: this.props.Document, scale: this.props.scaling });
+ clickScript?.script.run({ this: this.props.Document, scale: this.props.scaling });
};
onInput = (e: React.FormEvent<HTMLDivElement>) => {
const onInputScript = (this.props as any).onInput as Opt<ScriptField>;
- onInputScript?.script.run({ this: this.props.Document, self: this.props.Document, value: (e.target as any).textContent });
+ onInputScript?.script.run({ this: this.props.Document, value: (e.target as any).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, offset: any, string: any) => {
+ const replacer = (match: any, expr: string) =>
// bcz: this executes a script to convert a property expression string: { script } into a value
- return (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: 'number' })?.script.run({ self: this.props.Document, this: this.props.Document, scale: this.props.scaling }).result as string) || '';
- };
- Object.keys(divKeys).map((prop: string) => {
+ (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;
style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer);
});
@@ -118,25 +74,33 @@ export interface DocumentContentsViewProps extends FieldViewProps {
}
@observer
export class DocumentContentsView extends ObservableReactComponent<DocumentContentsViewProps> {
+ private static DefaultLayoutString: string;
+ /**
+ * Set of all available rendering componets for Docs (e.g., ImageBox, CollectionFreeFormView, etc)
+ */
+ private static Components: { [key: string]: any };
+ public static Init(defaultLayoutString: string, components: { [key: string]: any }) {
+ DocumentContentsView.DefaultLayoutString = defaultLayoutString;
+ DocumentContentsView.Components = components;
+ }
constructor(props: any) {
super(props);
makeObservable(this);
}
-
@computed get layout(): string {
TraceMobx();
if (this._props.LayoutTemplateString) return this._props.LayoutTemplateString;
if (!this.layoutDoc) return '<p>awaiting layout</p>';
- if (this._props.layoutFieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, KeyValueBox.LayoutString());
- const layout = Cast(this.layoutDoc[this.layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')], 'string');
- if (layout === undefined) return this._props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString();
+ if (this._props.layoutFieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, DocumentContentsView.DefaultLayoutString);
+ const tempLayout = DocCast(this.layoutDoc[this.layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')]);
+ const layoutDoc = tempLayout ?? this.layoutDoc;
+ const layout = Cast(layoutDoc[layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(layoutDoc.layout_fieldKey, 'layout')], 'string');
+ if (layout === undefined) return this._props.Document.data ? "<FieldView {...props} fieldKey='data' />" : DocumentContentsView.DefaultLayoutString;
if (typeof layout === 'string') return layout;
return '<p>Loading layout</p>';
}
get layoutDoc() {
- // bcz: replaced this with below : is it correct? change was made to accommodate passing fieldKey's from a layout script
- // const template: Doc = this._props.LayoutTemplate?.() || Doc.Layout(this._props.Document, this._props.fieldKey ? Cast(this._props.Document[this._props.fieldKey], Doc, null) : undefined);
const template: Doc =
this._props.LayoutTemplate?.() ||
(this._props.LayoutTemplateString && this._props.Document) ||
@@ -156,8 +120,9 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
'LayoutTemplate',
'layoutFieldKey',
'dontCenter',
+ 'DataTransition',
'contextMenuItems',
- //'onClick', // don't need to omit this since it will be set
+ // 'onClick', // don't need to omit this since it will be set
'onDoubleClickScript',
'onPointerDownScript',
'onPointerUpScript',
@@ -186,21 +151,16 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
let layoutFrame = this.layout;
// replace code content with a script >{content}< as in <HTMLdiv>{this.title}</HTMLdiv>
- const replacer = (match: any, prefix: string, expr: string, postfix: string, offset: any, string: any) => {
- return prefix + ((ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix;
- };
+ 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;
layoutFrame = layoutFrame.replace(/(>[^{]*)[^=]\{([^.'][^<}]+)\}([^}]*<)/g, replacer);
// replace HTML<tag> with corresponding HTML tag as in: <HTMLdiv> becomes <HTMLtag Document={props.Document} htmltag='div'>
- const replacer2 = (match: any, p1: string, offset: any, string: any) => {
- return `<HTMLtag Document={props.Document} scaling='${this._props.NativeDimScaling?.() || 1}' htmltag='${p1}'`;
- };
+ const replacer2 = (match: any, p1: string) => `<HTMLtag Document={props.Document} scaling='${this._props.NativeDimScaling?.() || 1}' htmltag='${p1}'`;
layoutFrame = layoutFrame.replace(/<HTML([a-zA-Z0-9_-]+)/g, replacer2);
// replace /HTML<tag> with </HTMLdiv> as in: </HTMLdiv> becomes </HTMLtag>
- const replacer3 = (match: any, p1: string, offset: any, string: any) => {
- return `</HTMLtag`;
- };
+ const replacer3 = (/* match: any, p1: string, offset: any, string: any */) => `</HTMLtag`;
+
layoutFrame = layoutFrame.replace(/<\/HTML([a-zA-Z0-9_-]+)/g, replacer3);
// add onClick function to props
@@ -210,7 +170,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
const code = XRegExp.matchRecursive(splits[1], '{', '}', '', { valueNames: ['between', 'left', 'match', 'right', 'between'] });
layoutFrame = splits[0] + ` ${func}={props.${func}} ` + splits[1].substring(code[1].end + 1);
const script = code[1].value.replace(/^‘/, '').replace(/’$/, ''); // ‘’ are not valid quotes in javascript so get rid of them -- they may be present to make it easier to write complex scripts - see headerTemplate in currentUserUtils.ts
- return ScriptField.MakeScript(script, { this: Doc.name, self: Doc.name, scale: 'number', value: 'string' });
+ return ScriptField.MakeScript(script, { this: Doc.name, scale: 'number', value: 'string' });
}
return undefined;
// add input function to props
@@ -230,48 +190,10 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
key={42}
blacklistedAttrs={emptyPath}
renderInWrapper={false}
- components={{
- FormattedTextBox,
- ImageBox,
- FontIconBox,
- LabelBox,
- EquationBox,
- FieldView,
- CollectionFreeFormView,
- CollectionDockingView,
- CollectionSchemaView,
- CollectionCalendarView,
- CollectionView,
- WebBox,
- KeyValueBox,
- PDFBox,
- VideoBox,
- AudioBox,
- RecordingBox,
- PresBox,
- YoutubeBox,
- PresElementBox,
- SearchBox,
- FunctionPlotBox,
- DashWebRTCVideo,
- LinkAnchorBox,
- InkingStroke,
- LinkBox,
- ScriptingBox,
- MapBox,
- ScreenshotBox,
- DataVizBox,
- HTMLtag,
- ComparisonBox,
- LoadingBox,
- PhysicsSimulationBox,
- SchemaRowBox,
- ImportElementBox,
- MapPushpinBox,
- }}
+ components={DocumentContentsView.Components}
bindings={bindings}
jsx={layoutFrame}
- showWarnings={true}
+ showWarnings
onError={(test: any) => {
console.log('DocumentContentsView:' + test, bindings, layoutFrame);
}}
diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx
index 4a22766cc..ffd350e92 100644
--- a/src/client/views/nodes/DocumentIcon.tsx
+++ b/src/client/views/nodes/DocumentIcon.tsx
@@ -3,12 +3,11 @@ import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { factory } from 'typescript';
-import { Field } from '../../../fields/Doc';
-import { Id } from '../../../fields/FieldSymbols';
-import { DocumentManager } from '../../util/DocumentManager';
+import { FieldType } from '../../../fields/Doc';
+import { ToJavascriptString } from '../../../fields/FieldSymbols';
+import { StrCast } from '../../../fields/Types';
import { Transformer, ts } from '../../util/Scripting';
-import { SettingsManager } from '../../util/SettingsManager';
-import { LightboxView } from '../LightboxView';
+import { SnappingManager } from '../../util/SnappingManager';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { DocumentView } from './DocumentView';
@@ -24,26 +23,23 @@ export class DocumentIcon extends ObservableReactComponent<DocumentIconProps> {
makeObservable(this);
}
- static get DocViews() {
- return LightboxView.LightboxDoc ? DocumentManager.Instance.DocumentViews.filter(v => LightboxView.Contains(v)) : DocumentManager.Instance.DocumentViews;
- }
render() {
- const view = this._props.view;
- const { left, top, right, bottom } = view.getBounds || { left: 0, top: 0, right: 0, bottom: 0 };
+ const { view } = this._props;
+ const { left, top, right } = view.getBounds || { left: 0, top: 0, right: 0, bottom: 0 };
return (
<div
className="documentIcon-outerDiv"
- onPointerEnter={action(e => (this._hovered = true))}
- onPointerLeave={action(e => (this._hovered = false))}
+ onPointerEnter={action(() => { this._hovered = true; })} // prettier-ignore
+ onPointerLeave={action(() => { this._hovered = false; })} // prettier-ignore
style={{
pointerEvents: 'all',
opacity: this._hovered ? 0.3 : 1,
position: 'absolute',
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
transform: `translate(${(left + right) / 2}px, ${top}px)`,
}}>
- <Tooltip title={<>{this._props.view.Document.title}</>}>
+ <Tooltip title={<div>{StrCast(this._props.view.Document?.title)}</div>}>
<p>d{this._props.index}</p>
</Tooltip>
</div>
@@ -56,40 +52,40 @@ export class DocumentIconContainer extends React.Component {
public static getTransformer(): Transformer {
const usedDocuments = new Set<number>();
return {
- transformer: context => {
- return root => {
- function visit(node: ts.Node) {
- node = ts.visitEachChild(node, visit, context);
+ transformer: context => root => {
+ function visit(nodeIn: ts.Node) {
+ const node = ts.visitEachChild(nodeIn, visit, context);
- if (ts.isIdentifier(node)) {
- const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node;
- const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node;
- const isntParameter = !ts.isParameter(node.parent);
- if (isntPropAccess && isntPropAssign && isntParameter && !(node.text in globalThis)) {
- const match = node.text.match(/d([0-9]+)/);
- if (match) {
- const m = parseInt(match[1]);
- const doc = DocumentIcon.DocViews[m].Document;
- usedDocuments.add(m);
- return factory.createIdentifier(`idToDoc("${doc[Id]}")`);
- }
+ if (ts.isIdentifier(node)) {
+ const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node;
+ const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node;
+ const isntParameter = !ts.isParameter(node.parent);
+ if (isntPropAccess && isntPropAssign && isntParameter && !(node.text in globalThis)) {
+ const match = node.text.match(/d([0-9]+)/);
+ if (match) {
+ const m = parseInt(match[1]);
+ const doc = DocumentView.allViews()[m].Document;
+ usedDocuments.add(m);
+ return factory.createIdentifier(doc[ToJavascriptString]()); // `idToDoc("${doc[Id]}")`);
}
}
-
- return node;
}
- return ts.visitNode(root, visit);
- };
+
+ return node;
+ }
+ return ts.visitNode(root, visit);
},
getVars() {
- const docs = DocumentIcon.DocViews;
- const capturedVariables: { [name: string]: Field } = {};
- usedDocuments.forEach(index => (capturedVariables[`d${index}`] = docs.length > index ? docs[index].Document : `d${index}`));
+ const docs = DocumentView.allViews();
+ const capturedVariables: { [name: string]: FieldType } = {};
+ usedDocuments.forEach(index => {
+ capturedVariables[`d${index}`] = docs.length > index ? docs[index].Document : `d${index}`;
+ });
return capturedVariables;
},
};
}
render() {
- return DocumentIcon.DocViews.map((dv, i) => <DocumentIcon key={i} index={i} view={dv} />);
+ return DocumentView.allViews().map((dv, i) => <DocumentIcon key={dv.DocUniqueId} index={i} view={dv} />);
}
}
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 2a68d2bf6..0c5156339 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -1,23 +1,23 @@
+/* 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';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { StopEvent, emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils';
+import { StopEvent, returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { Doc } from '../../../fields/Doc';
-import { StrCast } from '../../../fields/Types';
-import { DocUtils } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
import { DragManager } from '../../util/DragManager';
-import { Hypothesis } from '../../util/HypothesisUtils';
import { LinkManager } from '../../util/LinkManager';
import { UndoManager, undoBatch } from '../../util/UndoManager';
import { ObservableReactComponent } from '../ObservableReactComponent';
+import { PinProps } from '../PinFuncs';
import './DocumentLinksButton.scss';
import { DocumentView } from './DocumentView';
import { LinkDescriptionPopup } from './LinkDescriptionPopup';
import { TaskCompletionBox } from './TaskCompletedBox';
-import { PinProps } from './trails';
-import { DocData } from '../../../fields/DocSymbols';
interface DocumentLinksButtonProps {
View: DocumentView;
@@ -25,20 +25,22 @@ interface DocumentLinksButtonProps {
AlwaysOn?: boolean;
InMenu?: boolean;
OnHover?: boolean;
- StartLink?: boolean; //whether the link HAS been started (i.e. now needs to be completed)
+ StartLink?: boolean; // whether the link HAS been started (i.e. now needs to be completed)
ShowCount?: boolean;
scaling?: () => number; // how uch doc is scaled so that link buttons can invert it
hideCount?: () => boolean;
}
export class DocButtonState {
- @observable public StartLink: Doc | undefined = undefined; //origin's Doc, if defined
+ @observable public StartLink: Doc | undefined = undefined; // origin's Doc, if defined
@observable public StartLinkView: DocumentView | undefined = undefined;
@observable public AnnotationId: string | undefined = undefined;
@observable public AnnotationUri: string | undefined = undefined;
@observable public LinkEditorDocView: DocumentView | undefined = undefined;
+ // eslint-disable-next-line no-use-before-define
public static _instance: DocButtonState | undefined;
public static get Instance() {
+ // eslint-disable-next-line no-return-assign
return DocButtonState._instance ?? (DocButtonState._instance = new DocButtonState());
}
constructor() {
@@ -49,7 +51,7 @@ export class DocButtonState {
export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksButtonProps> {
private _linkButton = React.createRef<HTMLDivElement>();
public static get StartLink() { return DocButtonState.Instance.StartLink; } // prettier-ignore
- public static set StartLink(value) { runInAction(() => (DocButtonState.Instance.StartLink = value)); } // prettier-ignore
+ public static set StartLink(value) { runInAction(() => {DocButtonState.Instance.StartLink = value}); } // prettier-ignore
@observable public static StartLinkView: DocumentView | undefined = undefined;
@observable public static AnnotationId: string | undefined = undefined;
@observable public static AnnotationUri: string | undefined = undefined;
@@ -87,12 +89,14 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
e,
this.onLinkButtonMoved,
emptyFunction,
- action((e, doubleTap) => {
+ action((clickEv, doubleTap) => {
doubleTap && DocumentView.showBackLinks(this._props.View.Document);
}),
undefined,
undefined,
- action(() => (DocButtonState.Instance.LinkEditorDocView = this._props.View))
+ action(() => {
+ DocButtonState.Instance.LinkEditorDocView = this._props.View;
+ })
);
};
@@ -102,9 +106,9 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
e,
this.onLinkButtonMoved,
emptyFunction,
- action((e, doubleTap) => {
+ action((clickEv, doubleTap) => {
if (doubleTap && this._props.InMenu && this._props.StartLink) {
- //action(() => Doc.BrushDoc(this._props.View.Document));
+ // action(() => Doc.BrushDoc(this._props.View.Document));
if (DocumentLinksButton.StartLink === this._props.View.Document) {
DocumentLinksButton.StartLink = undefined;
DocumentLinksButton.StartLinkView = undefined;
@@ -118,7 +122,7 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
};
@undoBatch
- onLinkClick = (e: React.MouseEvent): void => {
+ onLinkClick = (): void => {
if (this._props.InMenu && this._props.StartLink) {
DocumentLinksButton.AnnotationId = undefined;
DocumentLinksButton.AnnotationUri = undefined;
@@ -126,7 +130,7 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
DocumentLinksButton.StartLink = undefined;
DocumentLinksButton.StartLinkView = undefined;
} else {
- //if this LinkButton's Document is undefined
+ // if this LinkButton's Document is undefined
DocumentLinksButton.StartLink = this._props.View.Document;
DocumentLinksButton.StartLinkView = this._props.View;
}
@@ -139,7 +143,7 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
e,
returnFalse,
emptyFunction,
- action(e => DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this._props.View.Document, true, this._props.View))
+ action(clickEv => DocumentLinksButton.finishLinkClick(clickEv.clientX, clickEv.clientY, DocumentLinksButton.StartLink, this._props.View.Document, true, this._props.View))
);
};
@@ -151,25 +155,17 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
DocumentLinksButton.StartLinkView = undefined;
DocumentLinksButton.AnnotationId = undefined;
DocumentLinksButton.AnnotationUri = undefined;
- //!this._props.StartLink
+ // !this._props.StartLink
} else if (startLink !== endLink) {
+ // eslint-disable-next-line no-param-reassign
endLink = endLinkView?.ComponentView?.getAnchor?.(true, pinProps) || endLink;
+ // eslint-disable-next-line no-param-reassign
startLink = DocumentLinksButton.StartLinkView?.ComponentView?.getAnchor?.(true) || startLink;
const linkDoc = DocUtils.MakeLink(startLink, endLink, { link_relationship: DocumentLinksButton.AnnotationId ? 'hypothes.is annotation' : undefined });
LinkManager.Instance.currentLink = linkDoc;
if (linkDoc) {
- if (DocumentLinksButton.AnnotationId && DocumentLinksButton.AnnotationUri) {
- // if linking from a Hypothes.is annotation
- const linkDocData = linkDoc[DocData];
- linkDocData.linksToAnnotation = true;
- linkDocData.annotationId = DocumentLinksButton.AnnotationId;
- linkDocData.annotationUri = DocumentLinksButton.AnnotationUri;
- const dashHyperlink = Doc.globalServerPath(startIsAnnotation ? endLink : startLink);
- Hypothesis.makeLink(StrCast(startIsAnnotation ? endLink.title : startLink.title), dashHyperlink, DocumentLinksButton.AnnotationId, startIsAnnotation ? startLink : endLink); // edit annotation to add a Dash hyperlink to the linked doc
- }
-
TaskCompletionBox.textDisplayed = 'Link Created';
TaskCompletionBox.popupX = screenX;
TaskCompletionBox.popupY = screenY - 133;
@@ -192,7 +188,9 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
}
setTimeout(
- action(() => (TaskCompletionBox.taskCompleted = false)),
+ action(() => {
+ TaskCompletionBox.taskCompleted = false;
+ }),
2500
);
}
@@ -242,13 +240,13 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
showLinkCount(this._props.OnHover, this._props.Bottom)
) : (
<div className="documentLinksButton-menu">
- {this._props.StartLink ? ( //if link has been started from current node, then set behavior of link button to deactivate linking when clicked again
+ {this._props.StartLink ? ( // if link has been started from current node, then set behavior of link button to deactivate linking when clicked again
<div className={`documentLinksButton ${isActive ? `startLink` : ``}`} ref={this._linkButton} onPointerDown={isActive ? StopEvent : this.onLinkButtonDown} onClick={isActive ? this.clearLinks : this.onLinkClick}>
<FontAwesomeIcon className="documentdecorations-icon" icon="link" />
</div>
) : null}
- {!this._props.StartLink && DocumentLinksButton.StartLink !== this._props.View.Document ? ( //if the origin node is not this node
- <div className={'documentLinksButton-endLink'} ref={this._linkButton} onPointerDown={DocumentLinksButton.StartLink && this.completeLink}>
+ {!this._props.StartLink && DocumentLinksButton.StartLink !== this._props.View.Document ? ( // if the origin node is not this node
+ <div className="documentLinksButton-endLink" ref={this._linkButton} onPointerDown={DocumentLinksButton.StartLink && this.completeLink}>
<FontAwesomeIcon className="documentdecorations-icon" icon="link" />
</div>
) : null}
@@ -262,7 +260,7 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
const buttonTitle = 'Tap to view links; double tap to open link collection';
const title = this._props.ShowCount ? buttonTitle : menuTitle;
- //render circular tooltip if it isn't set to invisible and show the number of doc links the node has, and render inner-menu link button for starting/stopping links if currently in menu
+ // render circular tooltip if it isn't set to invisible and show the number of doc links the node has, and render inner-menu link button for starting/stopping links if currently in menu
return !Array.from(this.filteredLinks).length && !this._props.AlwaysOn ? null : (
<div
className="documentLinksButton-wrapper"
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index 5421c1b50..23dada260 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -234,6 +234,12 @@
}
}
+.documntViewInternal-dropdown {
+ > div {
+ transform-origin: top left !important;
+ }
+}
+
.contentFittingDocumentView {
position: relative;
display: flex;
@@ -256,6 +262,5 @@
.documentView-node:first-child {
position: relative;
- background: '#B59B66'; //$white;
}
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e1b501c5a..fca6cda81 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,55 +1,58 @@
+/* eslint-disable no-use-before-define */
+/* eslint-disable react/jsx-props-no-spreading */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { Howl } from 'howler';
import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal';
-import { DivWidth, Utils, emptyFunction, isTargetChildOf as isParentOf, lightOrDark, returnEmptyString, returnFalse, returnTrue, returnVal, simulateMouseClick } from '../../../Utils';
-import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc';
-import { AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols';
+import { Fade, JackInTheBox } from 'react-awesome-reveal';
+import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simulateMouseClick } from '../../../ClientUtils';
+import { Utils, emptyFunction } from '../../../Utils';
+import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../fields/Doc';
+import { AclAdmin, AclEdit, AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
+import { PrefetchProxy } from '../../../fields/Proxy';
import { listSpec } from '../../../fields/Schema';
import { ScriptField } from '../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, DocCast, NumCast, RTFCast, ScriptCast, StrCast } from '../../../fields/Types';
import { AudioField } from '../../../fields/URLField';
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
+import { AudioAnnoState } from '../../../server/SharedMediaTypes';
import { DocServer } from '../../DocServer';
-import { Networking } from '../../Network';
-import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
+import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
+import { DocUtils, FollowLinkScript } from '../../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
-import { DocOptions, DocUtils, Docs } from '../../documents/Documents';
-import { DictationManager } from '../../util/DictationManager';
-import { DocumentManager } from '../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../util/DragManager';
-import { FollowLinkScript } from '../../util/LinkFollower';
-import { LinkManager } from '../../util/LinkManager';
+import { Docs } from '../../documents/Documents';
+import { DragManager } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
+import { MakeTemplate, makeUserTemplateButton } from '../../util/DropConverter';
+import { UPDATE_SERVER_CACHE } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SearchUtil } from '../../util/SearchUtil';
-import { SelectionManager } from '../../util/SelectionManager';
-import { SettingsManager } from '../../util/SettingsManager';
-import { SharingManager } from '../../util/SharingManager';
import { SnappingManager } from '../../util/SnappingManager';
import { UndoManager, undoBatch, undoable } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { DocComponent, ViewBoxInterface } from '../DocComponent';
+import { DocComponent } from '../DocComponent';
import { EditableView } from '../EditableView';
-import { GestureOverlay } from '../GestureOverlay';
-import { LightboxView } from '../LightboxView';
-import { StyleProp } from '../StyleProvider';
-import { DocumentContentsView, ObserverJsxParser } from './DocumentContentsView';
+import { FieldsDropdown } from '../FieldsDropdown';
+import { ObserverJsxParser } from '../ObservableReactComponent';
+import { PinProps } from '../PinFuncs';
+import { StyleProp } from '../StyleProp';
+import { ViewBoxInterface } from '../ViewBoxInterface';
+import { DocumentContentsView } from './DocumentContentsView';
import { DocumentLinksButton } from './DocumentLinksButton';
import './DocumentView.scss';
import { FieldViewProps, FieldViewSharedProps } from './FieldView';
-import { KeyValueBox } from './KeyValueBox';
-import { LinkAnchorBox } from './LinkAnchorBox';
+import { FocusViewOptions } from './FocusViewOptions';
+import { OpenWhere, OpenWhereMod } from './OpenWhere';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
-import { PresEffect, PresEffectDirection } from './trails';
-import { FieldsDropdown } from '../FieldsDropdown';
-import { RTFCast } from '../../../fields/Types';
-import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT';
+import { PresEffect, PresEffectDirection } from './trails/PresEnums';
+import SpringAnimation from './trails/SlideEffect';
+import { SpringSettings, SpringType, springMappings } from './trails/SpringUtils';
interface Window {
MediaRecorder: MediaRecorder;
@@ -58,35 +61,6 @@ declare class MediaRecorder {
constructor(e: any); // whatever MediaRecorder has
}
-export enum OpenWhereMod {
- none = '',
- left = 'left',
- right = 'right',
- top = 'top',
- bottom = 'bottom',
- keyvalue = 'keyValue',
-}
-export enum OpenWhere {
- lightbox = 'lightbox',
- add = 'add',
- addLeft = 'add:left',
- addRight = 'add:right',
- addBottom = 'add:bottom',
- close = 'close',
- toggle = 'toggle',
- toggleRight = 'toggle:right',
- replace = 'replace',
- replaceRight = 'replace:right',
- replaceLeft = 'replace:left',
- inParent = 'inParent',
- inParentFromScreen = 'inParentFromScreen',
- overlay = 'overlay',
- addRightKeyvalue = 'add:right:keyValue',
-}
-
-export function returnEmptyDocViewList() {
- return [] as DocumentView[];
-}
export interface DocumentViewProps extends FieldViewSharedProps {
hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected
hideResizeHandles?: boolean; // whether to suppress resized handles on doc decorations when this document is selected
@@ -105,26 +79,28 @@ export interface DocumentViewProps extends FieldViewSharedProps {
childDragAction?: dropActionType; // allows child documents to be dragged out of collection without holding the embedKey or dragging the doc decorations title bar.
dragWhenActive?: boolean;
dontHideOnDrag?: boolean;
- suppressSetHeight?: boolean;
onClickScriptDisable?: 'never' | 'always'; // undefined = only when selected
DataTransition?: () => string | undefined;
NativeWidth?: () => number;
NativeHeight?: () => number;
- contextMenuItems?: () => { script: ScriptField; filter?: ScriptField; label: string; icon: string }[];
+ contextMenuItems?: () => { script?: ScriptField; method?: () => void; filter?: ScriptField; label: string; icon: string }[];
dragConfig?: (data: DragManager.DocumentDragData) => void;
dragStarting?: () => void;
dragEnding?: () => void;
+
+ parent?: any; // parent React component view (see CollectionFreeFormDocumentView)
}
@observer
export class DocumentViewInternal extends DocComponent<FieldViewProps & DocumentViewProps>() {
// this makes mobx trace() statements more descriptive
public get displayName() { return 'DocumentViewInternal(' + this.Document.title + ')'; } // prettier-ignore
public static SelectAfterContextMenu = true; // whether a document should be selected after it's contextmenu is triggered.
+
/**
* This function is filled in by MainView to allow non-viewBox views to add Docs as tabs without
* needing to know about/reference MainView
*/
- public static addDocTabFunc: (doc: Doc, location: OpenWhere) => boolean = returnFalse;
+ public static addDocTabFunc: (doc: Doc | Doc[], location: OpenWhere) => boolean = returnFalse;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _doubleClickTimeout: NodeJS.Timeout | undefined;
@@ -148,7 +124,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
@observable _mounted = false; // turn off all pointer events if component isn't yet mounted (enables nested Docs in alternate UI textboxes that appear on hover which otherwise would grab focus from the text box, reverting to the original UI )
@observable _isContentActive: boolean | undefined = undefined;
@observable _pointerEvents: 'none' | 'all' | 'visiblePainted' | undefined = undefined;
- @observable _componentView: Opt<ViewBoxInterface> = undefined; // needs to be accessed from DocumentView wrapper class
+ @observable _componentView: Opt<ViewBoxInterface<FieldViewProps>> = undefined; // needs to be accessed from DocumentView wrapper class
@observable _animateScaleTime: Opt<number> = undefined; // milliseconds for animating between views. defaults to 300 if not uset
@observable _animateScalingTo = 0;
@@ -157,51 +133,41 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
animateScaleTime = () => this._animateScaleTime ?? 100;
style = (doc: Doc, sprop: StyleProp | string) => this._props.styleProvider?.(doc, this._props, sprop);
- @computed get layout_showTitle() { return this.style(this.layoutDoc, StyleProp.ShowTitle) as Opt<string>; } // prettier-ignore
- @computed get opacity() { return this.style(this.layoutDoc, StyleProp.Opacity); } // prettier-ignore
- @computed get boxShadow() { return this.style(this.layoutDoc, StyleProp.BoxShadow); } // prettier-ignore
- @computed get borderRounding() { return this.style(this.layoutDoc, StyleProp.BorderRounding); } // prettier-ignore
- @computed get widgetDecorations() { return this.style(this.layoutDoc, StyleProp.Decorations); } // prettier-ignore
- @computed get backgroundBoxColor() { return this.style(this.layoutDoc, StyleProp.BackgroundColor + ':box'); } // prettier-ignore
- @computed get headerMargin() { return this.style(this.layoutDoc, StyleProp.HeaderMargin) ?? 0; } // prettier-ignore
- @computed get layout_showCaption() { return this.style(this.layoutDoc, StyleProp.ShowCaption) ?? 0; } // prettier-ignore
- @computed get titleHeight() { return this.style(this.layoutDoc, StyleProp.TitleHeight) ?? 0; } // prettier-ignore
- @computed get docContents() { return this.style(this.Document, StyleProp.DocContents); } // prettier-ignore
- @computed get highlighting() { return this.style(this.Document, StyleProp.Highlighting); } // prettier-ignore
- @computed get borderPath() { return this.style(this.Document, StyleProp.BorderPath); } // prettier-ignore
-
- @computed get onClickHandler() {
- return this._props.onClickScript?.() ?? this._props.onBrowseClickScript?.() ?? ScriptCast(this.Document.onClick, ScriptCast(this.layoutDoc.onClick));
- }
- @computed get onDoubleClickHandler() {
- return this._props.onDoubleClickScript?.() ?? ScriptCast(this.layoutDoc.onDoubleClick, ScriptCast(this.Document.onDoubleClick));
- }
- @computed get onPointerDownHandler() {
- return this._props.onPointerDownScript?.() ?? ScriptCast(this.layoutDoc.onPointerDown, ScriptCast(this.Document.onPointerDown));
- }
- @computed get onPointerUpHandler() {
- return this._props.onPointerUpScript?.() ?? ScriptCast(this.layoutDoc.onPointerUp, ScriptCast(this.Document.onPointerUp));
- }
+ @computed get opacity() { return this.style(this.layoutDoc, StyleProp.Opacity); } // prettier-ignore
+ @computed get boxShadow() { return this.style(this.layoutDoc, StyleProp.BoxShadow); } // prettier-ignore
+ @computed get borderRounding() { return this.style(this.layoutDoc, StyleProp.BorderRounding); } // prettier-ignore
+ @computed get widgetDecorations() { return this.style(this.layoutDoc, StyleProp.Decorations); } // prettier-ignore
+ @computed get backgroundBoxColor(){ return this.style(this.layoutDoc, StyleProp.BackgroundColor + ':docView'); } // prettier-ignore
+ @computed get showTitle() { return this.style(this.layoutDoc, StyleProp.ShowTitle) as Opt<string>; } // prettier-ignore
+ @computed get showCaption() { return this.style(this.layoutDoc, StyleProp.ShowCaption) ?? 0; } // prettier-ignore
+ @computed get headerMargin() { return this.style(this.layoutDoc, StyleProp.HeaderMargin) ?? 0; } // prettier-ignore
+ @computed get titleHeight() { return this.style(this.layoutDoc, StyleProp.TitleHeight) ?? 0; } // prettier-ignore
+ @computed get docContents() { return this.style(this.Document, StyleProp.DocContents); } // prettier-ignore
+ @computed get highlighting() { return this.style(this.Document, StyleProp.Highlighting); } // prettier-ignore
+ @computed get borderPath() { return this.style(this.Document, StyleProp.BorderPath); } // prettier-ignore
+
+ @computed get onClickHdlr() { return this._props.onClickScript?.() ?? ScriptCast(this.layoutDoc.onClick ?? this.Document.onClick); } // prettier-ignore
+ @computed get onDoubleClickHdlr() { return this._props.onDoubleClickScript?.() ?? ScriptCast(this.layoutDoc.onDoubleClick ?? this.Document.onDoubleClick); } // prettier-ignore
+ @computed get onPointerDownHdlr() { return this._props.onPointerDownScript?.() ?? ScriptCast(this.layoutDoc.onPointerDown ?? this.Document.onPointerDown); } // prettier-ignore
+ @computed get onPointerUpHdlr() { return this._props.onPointerUpScript?.() ?? ScriptCast(this.layoutDoc.onPointerUp ?? this.Document.onPointerUp); } // prettier-ignore
@computed get disableClickScriptFunc() {
const onScriptDisable = this._props.onClickScriptDisable ?? this._componentView?.onClickScriptDisable?.() ?? this.layoutDoc.onClickScriptDisable;
- // prettier-ignore
- return (
- DocumentView.LongPress ||
- onScriptDisable === 'always' ||
- (onScriptDisable !== 'never' && (this.rootSelected() || this._componentView?.isAnyChildContentActive?.()))
- );
+ return (DocumentView.LongPress ||
+ onScriptDisable === 'always' ||
+ (onScriptDisable !== 'never' && (this.rootSelected() || this._componentView?.isAnyChildContentActive?.()))); // prettier-ignore
}
@computed get _rootSelected() {
return this._props.isSelected() || BoolCast(this._props.TemplateDataDocument && this._props.rootSelected?.());
}
- /// disable pointer events on content when there's an enabled onClick script (but not the browse script) and the contents aren't forced active, or if contents are marked inactive
+ /// disable pointer events on content when there's an enabled onClick script (and not in explore mode) and the contents aren't forced active, or if contents are marked inactive
@computed get _contentPointerEvents() {
TraceMobx();
return this._props.contentPointerEvents ??
((!this.disableClickScriptFunc && //
- this.onClickHandler &&
- !this._props.onBrowseClickScript?.() &&
+ this.onClickHdlr &&
+ !SnappingManager.ExploreMode &&
+ !this.layoutDoc.layout_isSvg &&
this.isContentActive() !== true) ||
this.isContentActive() === false)
? 'none'
@@ -212,11 +178,10 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
// anchors that are not rendered as DocumentViews (marked as 'layout_unrendered' with their 'annotationOn' set to this document). e.g.,
// - PDF text regions are rendered as an Annotations without generating a DocumentView, '
// - RTF selections are rendered via Prosemirror and have a mark which contains the Document ID for the annotation link
- // - and links to PDF/Web docs at a certain scroll location never create an explicit view.
- // For each of these, we create LinkAnchorBox's on the border of the DocumentView.
+ // - and links to PDF/Web docs at a certain scroll location never create an explicit anchor view.
@computed get directLinks() {
TraceMobx();
- return LinkManager.Instance.getAllRelatedLinks(this.Document).filter(
+ return Doc.Links(this.Document).filter(
link =>
(link.link_matchEmbeddings ? link.link_anchor_1 === this.Document : Doc.AreProtosEqual(link.link_anchor_1 as Doc, this.Document)) ||
(link.link_matchEmbeddings ? link.link_anchor_2 === this.Document : Doc.AreProtosEqual(link.link_anchor_2 as Doc, this.Document)) ||
@@ -224,13 +189,13 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
((link.link_anchor_2 as Doc)?.layout_unrendered && Doc.AreProtosEqual((link.link_anchor_2 as Doc)?.annotationOn as Doc, this.Document))
);
}
- @computed get _allLinks() {
+ @computed get _allLinks(): Doc[] {
TraceMobx();
- return LinkManager.Instance.getAllRelatedLinks(this.Document).filter(link => !link.link_matchEmbeddings || link.link_anchor_1 === this.Document || link.link_anchor_2 === this.Document);
+ return Doc.Links(this.Document).filter(link => !link.link_matchEmbeddings || link.link_anchor_1 === this.Document || link.link_anchor_2 === this.Document);
}
@computed get filteredLinks() {
- return DocUtils.FilterDocs(this.directLinks, this._props.childFilters?.() ?? [], []).filter(d => d.link_displayLine || Doc.UserDoc().showLinkLines);
+ return DocUtils.FilterDocs(this.directLinks, this._props.childFilters?.() ?? [], []);
}
componentWillUnmount() {
@@ -238,7 +203,9 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
}
componentDidMount() {
- runInAction(() => (this._mounted = true));
+ runInAction(() => {
+ this._mounted = true;
+ });
this.setupHandlers();
this._disposers.contentActive = reaction(
() =>
@@ -250,19 +217,23 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
: Doc.ActiveTool !== InkTool.None || SnappingManager.CanEmbed || this.rootSelected() || this.Document.forceActive || this._componentView?.isAnyChildContentActive?.() || this._props.isContentActive()
? true
: undefined,
- active => (this._isContentActive = active),
+ active => {
+ this._isContentActive = active;
+ },
{ fireImmediately: true }
);
this._disposers.pointerevents = reaction(
() => this.style(this.Document, StyleProp.PointerEvents),
- pointerevents => (this._pointerEvents = pointerevents),
+ pointerevents => {
+ this._pointerEvents = pointerevents;
+ },
{ fireImmediately: true }
);
}
preDrop = (e: Event, de: DragManager.DropEvent, dropAction: dropActionType) => {
const dragData = de.complete.docDragData;
if (dragData && this.isContentActive() && !this.props.dontRegisterView) {
- dragData.dropAction = dropAction ? dropAction : dragData.dropAction;
+ dragData.dropAction = dropAction || dragData.dropAction;
e.stopPropagation();
}
};
@@ -282,7 +253,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
startDragging(x: number, y: number, dropAction: dropActionType, hideSource = false) {
const docView = this._docView;
if (this._mainCont.current && docView) {
- const views = SelectionManager.Views.filter(dv => dv.ContentDiv);
+ const views = DocumentView.Selected().filter(dv => dv.ContentDiv);
const selected = views.length > 1 && views.some(dv => dv.Document === this.Document) ? views : [docView];
const dragData = new DragManager.DocumentDragData(selected.map(dv => dv.Document));
const screenXf = docView.screenToViewTransform();
@@ -291,8 +262,9 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
dragData.dropAction = dropAction;
dragData.removeDocument = this._props.removeDocument;
dragData.moveDocument = this._props.moveDocument;
- dragData.draggedViews = [docView];
- dragData.canEmbed = this.Document.dragAction ?? this._props.dragAction ? true : false;
+ dragData.dragEnding = () => docView.props.dragEnding?.();
+ dragData.dragStarting = () => docView.props.dragStarting?.();
+ dragData.canEmbed = !!(this.Document.dragAction ?? this._props.dragAction);
(this._props.dragConfig ?? this._componentView?.dragConfig)?.(dragData);
DragManager.StartDocumentDrag(
selected.map(dv => dv.ContentDiv!),
@@ -309,10 +281,25 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (!StrCast(this.layoutDoc._layout_showTitle)) this.layoutDoc._layout_showTitle = 'title';
setTimeout(() => this._titleRef.current?.setIsFocused(true)); // use timeout in case title wasn't shown to allow re-render so that titleref will be defined
};
+ onBrowseClick = (e: React.MouseEvent) => {
+ const browseTransitionTime = 500;
+ DocumentView.DeselectAll();
+ DocumentView.showDocument(this.Document, { zoomScale: 0.8, willZoomCentered: true }, (focused: boolean) => {
+ const options: FocusViewOptions = { pointFocus: { X: e.clientX, Y: e.clientY }, zoomTime: browseTransitionTime };
+ if (!focused && this._docView) {
+ this._docView
+ .docViewPath()
+ .reverse()
+ .forEach(cont => cont.ComponentView?.focus?.(cont.Document, options));
+ Doc.linkFollowHighlight(this.Document, false);
+ }
+ });
+ e.stopPropagation();
+ };
onClick = action((e: React.MouseEvent | React.PointerEvent) => {
if (this._props.isGroupActive?.() === 'child' && !this._props.isDocumentActive?.()) return;
const documentView = this._docView;
- if (documentView && !this.Document.ignoreClick && this._props.renderDepth >= 0 && Utils.isClick(e.clientX, e.clientY, this._downX, this._downY, this._downTime)) {
+ if (documentView && !this.Document.ignoreClick && this._props.renderDepth >= 0 && ClientUtils.isClick(e.clientX, e.clientY, this._downX, this._downY, this._downTime)) {
let stopPropagate = true;
let preventDefault = true;
!this.layoutDoc._keepZWhenDragged && this._props.bringToFront?.(this.Document);
@@ -330,11 +317,11 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
};
if (this._doubleTap) {
const defaultDblclick = this._props.defaultDoubleClick?.() || this.Document.defaultDoubleClick;
- if (this.onDoubleClickHandler?.script) {
- UndoManager.RunInBatch(() => this.onDoubleClickHandler.script.run(scriptProps, console.log).result?.select && this._props.select(false), 'on double click: ' + this.Document.title);
+ if (this.onDoubleClickHdlr?.script) {
+ UndoManager.RunInBatch(() => this.onDoubleClickHdlr.script.run(scriptProps, console.log).result?.select && this._props.select(false), 'on double click: ' + this.Document.title);
} else if (!Doc.IsSystem(this.Document) && defaultDblclick !== 'ignore') {
- UndoManager.RunInBatch(() => LightboxView.Instance.AddDocTab(this.Document, OpenWhere.lightbox), 'double tap');
- SelectionManager.DeselectAll();
+ UndoManager.RunInBatch(() => this._props.addDocTab(this.Document, OpenWhere.lightboxAlways), 'double tap');
+ DocumentView.DeselectAll();
Doc.UnBrushDoc(this.Document);
} else {
this._singleClickFunc?.();
@@ -344,31 +331,29 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
this._singleClickFunc = undefined;
} else {
let clickFunc: undefined | (() => any);
- if (!this.disableClickScriptFunc && this.onClickHandler?.script) {
+ if (!this.disableClickScriptFunc && this.onClickHdlr?.script) {
clickFunc = undoable(() => {
- // use this view's add doc func to override method for following links to undisplayed documents.
- // e.g., if this document is part of a labeled 'lightbox' container, then documents will be shown in this container of in the global lightbox
- const oldFunc = DocumentViewInternal.addDocTabFunc;
- DocumentViewInternal.addDocTabFunc = this._props.addDocTab;
- this.onClickHandler?.script.run(scriptProps, console.log).result?.select && this._props.select(false);
- DocumentViewInternal.addDocTabFunc = oldFunc;
+ this.onClickHdlr?.script.run(scriptProps, console.log).result?.select && this._props.select(false);
}, 'click ' + this.Document.title);
} else {
// onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplateForField implies we're clicking on part of a template instance and we want to select the whole template, not the part
- if ((this.layoutDoc.onDragStart || this._props.TemplateDataDocument) && !(e.ctrlKey || e.button > 0)) {
- stopPropagate = false; // don't stop propagation for field templates -- want the selection to propagate up to the root document of the template
+ if (this.layoutDoc.onDragStart && !(e.ctrlKey || e.button > 0)) {
+ stopPropagate = false;
}
preventDefault = false;
}
- const sendToBack = e.altKey;
- this._singleClickFunc =
- // prettier-ignore
- clickFunc ?? (() => (sendToBack ? documentView._props.bringToFront?.(this.Document, true) :
- this._props.select(e.ctrlKey||e.shiftKey, e.metaKey)));
+ const sendToBack = e.altKey ? () => documentView._props.bringToFront?.(this.Document, true) : undefined;
+ const selectFunc = () => {
+ // selecting a view that is part of a template proxies the selection back to the root of the template
+ const templateRoot = !(e.ctrlKey || e.button > 0) && this._props.docViewPath?.().reverse().find(dv => !dv._props.TemplateDataDocument); // prettier-ignore
+ (templateRoot || this._docView)?.select(e.ctrlKey || e.shiftKey, e.metaKey);
+ };
+ this._singleClickFunc = clickFunc ?? sendToBack ?? selectFunc;
const waitFordblclick = this._props.waitForDoubleClickToClick?.() ?? this.Document.waitForDoubleClickToClick;
if ((clickFunc && waitFordblclick !== 'never') || waitFordblclick === 'always') {
this._doubleClickTimeout && clearTimeout(this._doubleClickTimeout);
this._doubleClickTimeout = setTimeout(this._singleClickFunc, 300);
+ // eslint-disable-next-line no-use-before-define
} else if (!DocumentView.LongPress) {
this._singleClickFunc();
this._singleClickFunc = undefined;
@@ -381,31 +366,28 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
onPointerDown = (e: React.PointerEvent): void => {
if (this._props.isGroupActive?.() === 'child' && !this._props.isDocumentActive?.()) return;
+ // eslint-disable-next-line no-use-before-define
this._longPressSelector = setTimeout(() => DocumentView.LongPress && this._props.select(false), 1000);
- if (!GestureOverlay.DownDocView) GestureOverlay.DownDocView = this._docView;
+ if (!DocumentView.DownDocView) DocumentView.DownDocView = this._docView;
this._downX = e.clientX;
this._downY = e.clientY;
this._downTime = Date.now();
- if ((Doc.ActiveTool === InkTool.None || this._props.addDocTab === returnFalse) && !(this._props.TemplateDataDocument && !(e.ctrlKey || e.button > 0))) {
- // click events stop here if the document is active and no modes are overriding it
- // if this is part of a template, let the event go up to the template root unless right/ctrl clicking
- if (
- // prettier-ignore
- (this._props.isDocumentActive?.() || this._props.isContentActive?.()) &&
- !this._props.onBrowseClickScript?.() &&
+ // click events stop here if the document is active and no modes are overriding it
+ if (Doc.ActiveTool === InkTool.None || this._props.addDocTab === returnFalse) {
+ if ((this._props.isDocumentActive?.() || this._props.isContentActive?.()) &&
+ !SnappingManager.ExploreMode &&
!this.Document.ignoreClick &&
e.button === 0 &&
!Doc.IsInMyOverlay(this.layoutDoc)
) {
- e.stopPropagation();
- // don't preventDefault. Goldenlayout, PDF text selection and RTF text selection all need it to go though
+ e.stopPropagation(); // don't preventDefault. Goldenlayout, PDF text selection and RTF text selection all need it to go though
// listen to move events when document content isn't active or document is always draggable
if (!this.layoutDoc._lockedPosition && (!this.isContentActive() || BoolCast(this.layoutDoc._dragWhenActive, this._props.dragWhenActive))) {
document.addEventListener('pointermove', this.onPointerMove);
}
- }
+ } // prettier-ignore
document.addEventListener('pointerup', this.onPointerUp);
}
};
@@ -413,7 +395,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
onPointerMove = (e: PointerEvent): void => {
if (e.buttons !== 1 || [InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) return;
- if (!Utils.isClick(e.clientX, e.clientY, this._downX, this._downY, Date.now())) {
+ if (!ClientUtils.isClick(e.clientX, e.clientY, this._downX, this._downY, Date.now())) {
this.cleanupPointerEvents();
this._longPressSelector && clearTimeout(this._longPressSelector);
this.startDragging(this._downX, this._downY, ((e.ctrlKey || e.altKey) && dropActionType.embed) || ((this.Document.dragAction || this._props.dragAction || undefined) as dropActionType));
@@ -429,16 +411,17 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
this.cleanupPointerEvents();
this._longPressSelector && clearTimeout(this._longPressSelector);
- if (this.onPointerUpHandler?.script) {
- this.onPointerUpHandler.script.run({ this: this.Document }, console.log);
- } else if (e.button === 0 && Utils.isClick(e.clientX, e.clientY, this._downX, this._downY, this._downTime)) {
- this._doubleTap = (this.onDoubleClickHandler?.script || this.Document.defaultDoubleClick !== 'ignore') && Date.now() - this._lastTap < Utils.CLICK_TIME;
+ if (this.onPointerUpHdlr?.script) {
+ this.onPointerUpHdlr.script.run({ this: this.Document }, console.log);
+ } else if (e.button === 0 && ClientUtils.isClick(e.clientX, e.clientY, this._downX, this._downY, this._downTime)) {
+ this._doubleTap = (this.onDoubleClickHdlr?.script || this.Document.defaultDoubleClick !== 'ignore') && Date.now() - this._lastTap < ClientUtils.CLICK_TIME;
if (!this.isContentActive()) this._lastTap = Date.now(); // don't want to process the start of a double tap if the doucment is selected
}
+ // eslint-disable-next-line no-use-before-define
if (DocumentView.LongPress) e.preventDefault();
};
- toggleFollowLink = undoable((zoom?: boolean, setTargetToggle?: boolean): void => {
+ toggleFollowLink = undoable((): void => {
const hadOnClick = this.Document.onClick;
this.noOnClick();
this.Document.onClick = hadOnClick ? undefined : FollowLinkScript();
@@ -459,19 +442,17 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
}, 'default on click');
deleteClicked = undoable(() => this._props.removeDocument?.(this.Document), 'delete doc');
- setToggleDetail = undoable(
- (scriptFieldKey: 'onClick') =>
- (this.Document[scriptFieldKey] = ScriptField.MakeScript(
- `toggleDetail(documentView, "${StrCast(this.Document.layout_fieldKey)
- .replace('layout_', '')
- .replace(/^layout$/, 'detail')}")`,
- { documentView: 'any' }
- )),
- 'set toggle detail'
- );
+ setToggleDetail = undoable((scriptFieldKey: 'onClick') => {
+ this.Document[scriptFieldKey] = ScriptField.MakeScript(
+ `toggleDetail(documentView, "${StrCast(this.Document.layout_fieldKey)
+ .replace('layout_', '')
+ .replace(/^layout$/, 'detail')}")`,
+ { documentView: 'any' }
+ );
+ }, 'set toggle detail');
drop = undoable((e: Event, de: DragManager.DropEvent) => {
- if (this._props.dontRegisterView || this._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) return false;
+ if (this._props.dontRegisterView) return false;
if (this.Document === Doc.ActiveDashboard) {
e.stopPropagation();
e.preventDefault();
@@ -492,7 +473,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (linkDoc) {
de.complete.linkDocument = linkDoc;
linkDoc.layout_isSvg = true;
- DocumentManager.LinkCommonAncestor(linkDoc)?.ComponentView?.addDocument?.(linkDoc);
+ DocumentView.linkCommonAncestor(linkDoc)?.ComponentView?.addDocument?.(linkDoc);
}
}
e.stopPropagation();
@@ -506,7 +487,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
const input = document.createElement('input');
input.type = 'file';
input.accept = '.zip';
- input.onchange = _e => {
+ input.onchange = () => {
if (input.files) {
const batch = UndoManager.StartBatch('importing');
Doc.importDocument(input.files[0]).then(doc => {
@@ -539,7 +520,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (e && this.layoutDoc.layout_hideContextMenu && Doc.noviceMode) {
e.preventDefault();
e.stopPropagation();
- //!this._props.isSelected(true) && SelectionManager.SelectView(this.DocumentView(), false);
+ // !this._props.isSelected(true) && DocumentView.SelectView(this.DocumentView(), false);
}
// the touch onContextMenu is button 0, the pointer onContextMenu is button 2
if (e) {
@@ -551,7 +532,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
e.stopPropagation();
e.persist();
- if (!navigator.userAgent.includes('Mozilla') && (Math.abs(this._downX - e?.clientX) > 3 || Math.abs(this._downY - e?.clientY) > 3)) {
+ if (!navigator.userAgent.includes('Mozilla') && (Math.abs(this._downX - (e?.clientX ?? 0)) > 3 || Math.abs(this._downY - (e?.clientY ?? 0)) > 3)) {
return;
}
}
@@ -576,7 +557,13 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
StrListCast(this.Document.contextMenuLabels).forEach((label, i) =>
cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ documentView: this, this: this.Document, scriptContext: this._props.scriptContext }), icon: 'sticky-note' })
);
- this._props.contextMenuItems?.().forEach(item => item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.Document, scriptContext: this._props.scriptContext }), icon: item.icon as IconProp }));
+ this._props
+ .contextMenuItems?.()
+ .forEach(
+ item =>
+ item.label &&
+ cm.addItem({ description: item.label, event: () => (item.method ? item.method() : item.script?.script.run({ this: this.Document, documentView: this, scriptContext: this._props.scriptContext })), icon: item.icon as IconProp })
+ );
if (!this.Document.isFolder) {
const templateDoc = Cast(this.Document[StrCast(this.Document.layout_fieldKey)], Doc, null);
@@ -584,7 +571,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
const appearanceItems: ContextMenuProps[] = appearance && 'subitems' in appearance ? appearance.subitems : [];
if (this._props.renderDepth === 0) {
- appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => LightboxView.Instance.SetLightboxDoc(this.Document), icon: 'external-link-alt' });
+ appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => DocumentView.SetLightboxDoc(this.Document), icon: 'external-link-alt' });
}
appearanceItems.push({ description: 'Pin', event: () => this._props.pinToPres(this.Document, {}), icon: 'eye' });
if (this.Document._layout_isFlashcard) {
@@ -606,11 +593,15 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (this._props.bringToFront) {
const zorders = cm.findByDescription('ZOrder...');
const zorderItems: ContextMenuProps[] = zorders && 'subitems' in zorders ? zorders.subitems : [];
- zorderItems.push({ description: 'Bring to Front', event: () => SelectionManager.Views.forEach(dv => dv._props.bringToFront?.(dv.Document, false)), icon: 'arrow-up' });
- zorderItems.push({ description: 'Send to Back', event: () => SelectionManager.Views.forEach(dv => dv._props.bringToFront?.(dv.Document, true)), icon: 'arrow-down' });
+ zorderItems.push({ description: 'Bring to Front', event: () => 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(action(() => (this.layoutDoc._keepZWhenDragged = !this.layoutDoc._keepZWhenDragged))),
+ event: undoBatch(
+ action(() => {
+ this.layoutDoc._keepZWhenDragged = !this.layoutDoc._keepZWhenDragged;
+ })
+ ),
icon: 'hand-point-up',
});
!zorders && cm.addItem({ description: 'Z Order...', addDivider: true, noexpand: true, subitems: zorderItems, icon: 'layer-group' });
@@ -620,14 +611,14 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
const existingOnClick = cm.findByDescription('OnClick...');
const onClicks: ContextMenuProps[] = existingOnClick && 'subitems' in existingOnClick ? existingOnClick.subitems : [];
- onClicks.push({ description: 'Enter Portal', event: undoable(e => DocUtils.makeIntoPortal(this.Document, this.layoutDoc, this._allLinks), 'make into portal'), icon: 'window-restore' });
+ onClicks.push({ description: 'Enter Portal', event: undoable(() => 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' });
if (!this.Document.annotationOn) {
- onClicks.push({ description: this.onClickHandler ? 'Remove Click Behavior' : 'Follow Link', event: () => this.toggleFollowLink(false, false), icon: 'link' });
+ onClicks.push({ description: this.onClickHdlr ? 'Remove Click Behavior' : 'Follow Link', event: () => this.toggleFollowLink(false, false), icon: 'link' });
!Doc.noviceMode && onClicks.push({ description: 'Edit onClick Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.Document, undefined, 'onClick'), 'edit onClick'), icon: 'terminal' });
- cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
- } else if (LinkManager.Links(this.Document).length) {
+ !existingOnClick && cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
+ } else if (Doc.Links(this.Document).length) {
onClicks.push({ description: 'Restore On Click default', event: () => this.noOnClick(), icon: 'link' });
onClicks.push({ description: 'Follow Link on Click', event: () => this.followLinkOnClick(), icon: 'link' });
!existingOnClick && cm.addItem({ description: 'OnClick...', subitems: onClicks, icon: 'mouse-pointer' });
@@ -636,9 +627,9 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
const funcs: ContextMenuProps[] = [];
if (!Doc.noviceMode && this.layoutDoc.onDragStart) {
- funcs.push({ description: 'Drag an Embedding', icon: 'edit', event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getEmbedding(this.dragFactory)')) });
- funcs.push({ description: 'Drag a Copy', icon: 'edit', event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) });
- funcs.push({ description: 'Drag Document', icon: 'edit', event: () => (this.layoutDoc.onDragStart = undefined) });
+ funcs.push({ description: 'Drag an Embedding', icon: 'edit', event: () => { this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getEmbedding(this.dragFactory)')); } }); // prettier-ignore
+ funcs.push({ description: 'Drag a Copy', icon: 'edit', event: () => { this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')); } }); // prettier-ignore
+ funcs.push({ description: 'Drag Document', icon: 'edit', event: () => { this.layoutDoc.onDragStart = undefined; } }); // prettier-ignore
cm.addItem({ description: 'OnDrag...', noexpand: true, subitems: funcs, icon: 'asterisk' });
}
@@ -647,14 +638,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (!Doc.IsSystem(this.Document)) {
if (!Doc.noviceMode) {
moreItems.push({ description: 'Make View of Metadata Field', event: () => Doc.MakeMetadataFieldTemplate(this.Document, this._props.TemplateDataDocument), icon: 'concierge-bell' });
- moreItems.push({ description: `${this.Document._chromeHidden ? 'Show' : 'Hide'} Chrome`, event: () => (this.Document._chromeHidden = !this.Document._chromeHidden), icon: 'project-diagram' });
-
- if (Cast(Doc.GetProto(this.Document).data, listSpec(Doc))) {
- moreItems.push({ description: 'Export to Google Photos Album', event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this.Document }).then(console.log), icon: 'caret-square-right' });
- moreItems.push({ description: 'Tag Child Images via Google Photos', event: () => GooglePhotos.Query.TagChildImages(this.Document), icon: 'caret-square-right' });
- moreItems.push({ description: 'Write Back Link to Album', event: () => GooglePhotos.Transactions.AddTextEnrichment(this.Document), icon: 'caret-square-right' });
- }
- moreItems.push({ description: 'Copy ID', event: () => Utils.CopyText(Doc.globalServerPath(this.Document)), icon: 'fingerprint' });
+ moreItems.push({ description: `${this.Document._chromeHidden ? 'Show' : 'Hide'} Chrome`, event: () => { this.Document._chromeHidden = !this.Document._chromeHidden; }, icon: 'project-diagram' }); // prettier-ignore
+ moreItems.push({ description: 'Copy ID', event: () => ClientUtils.CopyText(Doc.globalServerPath(this.Document)), icon: 'fingerprint' });
}
}
@@ -662,8 +647,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
}
const constantItems: ContextMenuProps[] = [];
if (!Doc.IsSystem(this.Document) && this.Document._type_collection !== CollectionViewType.Docking) {
- constantItems.push({ description: 'Zip Export', icon: 'download', event: async () => Doc.Zip(this.Document) });
- (this.Document._type_collection !== CollectionViewType.Docking || !Doc.noviceMode) && constantItems.push({ description: 'Share', event: () => SharingManager.Instance.open(this._docView), icon: 'users' });
+ constantItems.push({ description: 'Zip Export', icon: 'download', event: async () => DocUtils.Zip(this.Document) });
+ constantItems.push({ description: 'Share', event: () => DocumentView.ShareOpen(this._docView), icon: 'users' });
if (this._props.removeDocument && Doc.ActiveDashboard !== this.Document) {
// need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions)
constantItems.push({ description: 'Close', event: this.deleteClicked, icon: 'times' });
@@ -678,8 +663,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
!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' });
- let documentationDescription: string | undefined = undefined;
- let documentationLink: string | undefined = undefined;
+ let documentationDescription: string | undefined;
+ let documentationLink: string | undefined;
switch (this.Document.type) {
case DocumentType.COL:
documentationDescription = 'See collection documentation';
@@ -713,6 +698,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
documentationDescription = 'See DataViz node documentation';
documentationLink = 'https://brown-dash.github.io/Dash-Documentation/documents/dataViz/';
break;
+ default:
}
// Add link to help documentation (unless the doc contents have been overriden in which case the documentation isn't relevant)
if (!this.docContents && documentationDescription && documentationLink) {
@@ -732,9 +718,9 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
rootSelected = () => this._rootSelected;
panelHeight = () => this._props.PanelHeight() - this.headerMargin;
screenToLocalContent = () => this._props.ScreenToLocalTransform().translate(0, -this.headerMargin);
- onClickFunc = this.disableClickScriptFunc ? undefined : () => this.onClickHandler;
- setHeight = (height: number) => !this._props.suppressSetHeight && (this.layoutDoc._height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), height));
- setContentView = action((view: ViewBoxInterface) => (this._componentView = view));
+ onClickFunc = this.disableClickScriptFunc ? undefined : () => this.onClickHdlr;
+ setHeight = (height: number) => { !this._props.suppressSetHeight && (this.layoutDoc._height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), height)); } // prettier-ignore
+ setContentView = action((view: ViewBoxInterface<FieldViewProps>) => { this._componentView = view; }); // prettier-ignore
isContentActive = (): boolean | undefined => this._isContentActive;
childFilters = () => [...this._props.childFilters(), ...StrListCast(this.layoutDoc.childFilters)];
@@ -749,44 +735,18 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
case StyleProp.PointerEvents: return 'none';
case StyleProp.Highlighting: return undefined;
case StyleProp.Opacity: {
- const filtered = DocUtils.FilterDocs(this.directLinks, this._props.childFilters?.() ?? [], []).filter(d => d.link_displayLine || Doc.UserDoc().showLinkLines);
+ const filtered = DocUtils.FilterDocs(this.directLinks, this._props.childFilters?.() ?? [], []);
return filtered.some(link => link._link_displayArrow) ? 0 : undefined;
}
+ default:
}
return this._props.styleProvider?.(doc, props, property);
};
- removeLinkByHiding = (link: Doc) => () => (link.link_displayLine = false);
- @computed get allLinkEndpoints() {
- // the small blue dots that mark the endpoints of links
- if (this._componentView instanceof KeyValueBox || this._props.hideLinkAnchors || this.layoutDoc.layout_hideLinkAnchors || this._props.dontRegisterView || this.layoutDoc.layout_unrendered) return null;
- return this.filteredLinks.map(link => (
- <div className="documentView-anchorCont" key={link[Id]}>
- <DocumentView
- {...this._props}
- isContentActive={returnFalse}
- Document={link}
- containerViewPath={this._props.docViewPath}
- PanelWidth={this.anchorPanelWidth}
- PanelHeight={this.anchorPanelHeight}
- dontRegisterView={false}
- layout_showTitle={returnEmptyString}
- hideCaptions={true}
- hideLinkAnchors={true}
- layout_fitWidth={returnTrue}
- removeDocument={this.removeLinkByHiding(link)}
- styleProvider={this.anchorStyleProvider}
- LayoutTemplate={undefined}
- LayoutTemplateString={LinkAnchorBox.LayoutString(`link_anchor_${LinkManager.anchorIndex(link, this.Document)}`)}
- />
- </div>
- ));
- }
-
@computed get viewBoxContents() {
TraceMobx();
const isInk = this.layoutDoc._layout_isSvg && !this._props.LayoutTemplateString;
- const noBackground = this.Document.isGroup && !this._props.LayoutTemplateString?.includes(KeyValueBox.name) && (!this.layoutDoc.backgroundColor || this.layoutDoc.backgroundColor === 'transparent');
+ const noBackground = this.Document.isGroup && !this._componentView?.isUnstyledView?.() && (!this.layoutDoc.backgroundColor || this.layoutDoc.backgroundColor === 'transparent');
return (
<div
className="documentView-contentsView"
@@ -809,47 +769,45 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
setTitleFocus={this.setTitleFocus}
hideClickBehaviors={BoolCast(this.Document.hideClickBehaviors)}
/>
- {this.layoutDoc.layout_hideAllLinks ? null : this.allLinkEndpoints}
</div>
);
}
captionStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => this._props?.styleProvider?.(doc, props, property + ':caption');
- fieldsDropdown = (placeholder: string) => {
- return (
- <div
- ref={action((r: any) => r && (this._titleDropDownInnerWidth = DivWidth(r)))}
- onPointerDown={action(e => (this._changingTitleField = true))}
- style={{ width: 'max-content', background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor, transformOrigin: 'left', transform: `scale(${this.titleHeight / 30 /* height of Dropdown */})` }}>
- <FieldsDropdown
- Document={this.Document}
- placeholder={placeholder}
- selectFunc={action((field: string | number) => {
- if (this.layoutDoc.layout_showTitle) {
- this.layoutDoc._layout_showTitle = field;
- } else if (!this._props.layout_showTitle) {
- Doc.UserDoc().layout_showTitle = field;
- }
- this._changingTitleField = false;
- })}
- menuClose={action(() => (this._changingTitleField = false))}
- />
- </div>
- );
- };
+ fieldsDropdown = (placeholder: string) => (
+ <div
+ ref={action((r: any) => { r && (this._titleDropDownInnerWidth = DivWidth(r));} )} // prettier-ignore
+ onPointerDown={action(() => { this._changingTitleField = true; })} // prettier-ignore
+ style={{ width: 'max-content', background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, transformOrigin: 'left', transform: `scale(${this.titleHeight / 30 /* height of Dropdown */})` }}>
+ <FieldsDropdown
+ Document={this.Document}
+ placeholder={placeholder}
+ selectFunc={action((field: string | number) => {
+ if (this.layoutDoc.layout_showTitle) {
+ this.layoutDoc._layout_showTitle = field;
+ } else if (!this._props.showTitle) {
+ Doc.UserDoc().layout_showTitle = field;
+ }
+ this._changingTitleField = false;
+ })}
+ menuClose={action(() => { this._changingTitleField = false; })} // prettier-ignore
+ />
+ </div>
+ );
/**
* displays a 'title' at the top of a document. The title contents default to the 'title' field, but can be changed to one or more fields by
- * setting layout_showTitle using the format: field1[;field2[...][:hover]]
- * from the UI, this is done by clicking the title field and prefixin the format with '#'. eg., #field1[;field2;...][:hover]
- **/
+ * setting layout_showTitle using the format: field1[:hover]
+ * */
@computed get titleView() {
- const showTitle = this.layout_showTitle?.split(':')[0];
- const showTitleHover = this.layout_showTitle?.includes(':hover');
+ const showTitle = this.showTitle?.split(':')[0];
+ const showTitleHover = this.showTitle?.includes(':hover');
const targetDoc = showTitle?.startsWith('_') ? this.layoutDoc : this.Document;
const background = StrCast(
this.layoutDoc.layout_headingColor,
- StrCast(SharingManager.Instance.users.find(u => u.user.email === this.dataDoc.author)?.sharingDoc.headingColor, StrCast(Doc.SharingDoc().headingColor, SettingsManager.userBackgroundColor))
+ // StrCast(SharingManager.Instance.users.find(u => u.user.email === this.dataDoc.author)?.sharingDoc.headingColor,
+ StrCast(Doc.SharingDoc().headingColor, SnappingManager.userBackgroundColor)
+ // )
);
const dropdownWidth = this._titleRef.current?._editing || this._changingTitleField ? Math.max(10, (this._titleDropDownInnerWidth * this.titleHeight) / 30) : 0;
const sidebarWidthPercent = +StrCast(this.layoutDoc.layout_sidebarWidthPercent).replace('%', '');
@@ -863,11 +821,15 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
position: this.headerMargin ? 'relative' : 'absolute',
height: this.titleHeight,
width: 100 - sidebarWidthPercent + '%',
- color: background === 'transparent' ? SettingsManager.userColor : lightOrDark(background),
+ color: background === 'transparent' ? SnappingManager.userColor : lightOrDark(background),
background,
- pointerEvents: (!this.disableClickScriptFunc && this.onClickHandler) || this.Document.ignoreClick ? 'none' : this.isContentActive() || this._props.isDocumentActive?.() ? 'all' : undefined,
+ pointerEvents: (!this.disableClickScriptFunc && this.onClickHdlr) || this.Document.ignoreClick ? 'none' : this.isContentActive() || this._props.isDocumentActive?.() ? 'all' : undefined,
}}>
- {!dropdownWidth ? null : <div style={{ width: dropdownWidth }}>{this.fieldsDropdown(showTitle)}</div>}
+ {!dropdownWidth ? null : (
+ <div className="documntViewInternal-dropdown" style={{ width: dropdownWidth }}>
+ {this.fieldsDropdown(showTitle)}
+ </div>
+ )}
<div
style={{
width: `calc(100% - ${dropdownWidth}px)`,
@@ -880,22 +842,27 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
contents={
showTitle
.split(';')
- .map(field => Field.toString(targetDoc[field.trim()] as Field))
+ .map(field => Field.toJavascriptString(this.Document[field] as FieldType))
.join(' \\ ') || '-unset-'
}
display="block"
- oneLine={true}
+ oneLine
fontSize={(this.titleHeight / 15) * 10}
- GetValue={() => (showTitle.split(';').length !== 1 ? '#' + showTitle : Field.toKeyValueString(this.Document, showTitle.split(';')[0]))}
+ GetValue={() =>
+ showTitle
+ .split(';')
+ .map(field => Field.toKeyValueString(this.Document, field))
+ .join('\\')
+ }
SetValue={undoBatch((input: string) => {
- if (input?.startsWith('#')) {
+ if (input?.startsWith('$')) {
if (this.layoutDoc.layout_showTitle) {
- this.layoutDoc._layout_showTitle = input?.substring(1);
- } else if (!this._props.layout_showTitle) {
- Doc.UserDoc().layout_showTitle = input?.substring(1) ?? 'author_date';
+ this.layoutDoc._layout_showTitle = input?.substring(1) ? input.substring(1) : undefined;
+ } else if (!this._props.showTitle) {
+ Doc.UserDoc().layout_showTitle = input?.substring(1) ? input.substring(1) : 'title';
}
- } else if (showTitle && !showTitle.includes('Date') && showTitle !== 'author') {
- KeyValueBox.SetField(targetDoc, showTitle, input);
+ } else if (showTitle && !showTitle.includes(';') && !showTitle.includes('Date') && showTitle !== 'author') {
+ Doc.SetField(targetDoc, showTitle, input);
}
return true;
})}
@@ -906,7 +873,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
}
@computed get captionView() {
- return !this.layout_showCaption ? null : (
+ return !this.showCaption ? null : (
<div
className="documentView-captionWrapper"
style={{
@@ -918,11 +885,12 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
{...this._props}
yPadding={10}
xPadding={10}
- fieldKey={this.layout_showCaption}
+ fieldKey={this.showCaption}
styleProvider={this.captionStyleProvider}
- dontRegisterView={true}
- noSidebar={true}
- dontScale={true}
+ dontRegisterView
+ rootSelected={this.rootSelected}
+ noSidebar
+ dontScale
renderDepth={this._props.renderDepth}
isContentActive={this.isContentActive}
/>
@@ -932,13 +900,13 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
renderDoc = (style: object) => {
TraceMobx();
- const showTitle = this.layout_showTitle?.split(':')[0];
+ const showTitle = this.showTitle?.split(':')[0];
return !DocCast(this.Document) || GetEffectiveAcl(this.dataDoc) === AclPrivate
? null
: this.docContents ?? (
<div
className="documentView-node"
- id={this.Document[Id]}
+ id={this.Document.type !== DocumentType.LINK ? this._docView?.DocUniqueId : undefined}
style={{
...style,
background: this.backgroundBoxColor,
@@ -950,7 +918,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
transform: this._animateScalingTo ? `scale(${this._animateScalingTo})` : undefined,
transition: !this._animateScalingTo ? this._props.DataTransition?.() : `transform ${this.animateScaleTime() / 1000}s ease-${this._animateScalingTo < 1 ? 'in' : 'out'}`,
}}>
- {this._props.hideTitle || (!showTitle && !this.layout_showCaption) ? (
+ {this._props.hideTitle || (!showTitle && !this.showCaption) ? (
this.viewBoxContents
) : (
<div className="documentView-styleWrapper">
@@ -966,8 +934,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
render() {
TraceMobx();
- const highlighting = this.highlighting;
- const borderPath = this.borderPath;
+ const { highlighting, borderPath } = this;
const boxShadow = !highlighting
? this.boxShadow
: highlighting && this.borderRounding && highlighting.highlightStyle !== 'dashed'
@@ -982,23 +949,22 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
});
return (
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events
<div
className={`${DocumentView.ROOT_DIV} docView-hack`}
ref={this._mainCont}
onContextMenu={this.onContextMenu}
onPointerDown={this.onPointerDown}
- onClick={this.onClick}
- onPointerEnter={e => (!SnappingManager.IsDragging || SnappingManager.CanEmbed) && Doc.BrushDoc(this.Document)}
- onPointerOver={e => (!SnappingManager.IsDragging || SnappingManager.CanEmbed) && Doc.BrushDoc(this.Document)}
+ onClick={SnappingManager.ExploreMode ? this.onBrowseClick : this.onClick}
+ onPointerEnter={() => (!SnappingManager.IsDragging || SnappingManager.CanEmbed) && Doc.BrushDoc(this.Document)}
+ onPointerOver={() => (!SnappingManager.IsDragging || SnappingManager.CanEmbed) && Doc.BrushDoc(this.Document)}
onPointerLeave={e => !isParentOf(this._contentDiv, document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y)) && Doc.UnBrushDoc(this.Document)}
style={{
borderRadius: this.borderRounding,
pointerEvents: this._pointerEvents === 'visiblePainted' ? 'none' : this._pointerEvents, // visible painted means that the underlying doc contents are irregular and will process their own pointer events (otherwise, the contents are expected to fill the entire doc view box so we can handle pointer events here)
}}>
- <>
- {this._componentView instanceof KeyValueBox ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)}
- {borderPath?.jsx}
- </>
+ {this._componentView?.isUnstyledView?.() || this.Document.type === DocumentType.CONFIG ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)}
+ {borderPath?.jsx}
</div>
);
}
@@ -1009,7 +975,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
* @returns a function that will wrap a JSX animation element wrapping any JSX element
*/
public static AnimationEffect(renderDoc: JSX.Element, presEffectDoc: Opt<Doc>, root: Doc) {
- const dir = presEffectDoc?.presentation_effectDirection ?? presEffectDoc?.followLinkAnimDirection;
+ let dir = (presEffectDoc?.presentation_effectDirection ?? presEffectDoc?.followLinkAnimDirection) as PresEffectDirection;
+ const transitionTime = presEffectDoc?.presentation_transition ? NumCast(presEffectDoc?.presentation_transition) : 500;
const effectProps = {
left: dir === PresEffectDirection.Left,
right: dir === PresEffectDirection.Right,
@@ -1019,82 +986,130 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
delay: 0,
duration: Cast(presEffectDoc?.presentation_transition, 'number', Cast(presEffectDoc?.followLinkTransitionTime, 'number', null)),
};
- //prettier-ignore
- switch (StrCast(presEffectDoc?.presentation_effect, StrCast(presEffectDoc?.followLinkAnimEffect))) {
- default:
- case PresEffect.None: return renderDoc;
- case PresEffect.Zoom: return <Zoom {...effectProps}>{renderDoc}</Zoom>;
- case PresEffect.Fade: return <Fade {...effectProps}>{renderDoc}</Fade>;
- case PresEffect.Flip: return <Flip {...effectProps}>{renderDoc}</Flip>;
- case PresEffect.Rotate: return <Rotate {...effectProps}>{renderDoc}</Rotate>;
- case PresEffect.Bounce: return <Bounce {...effectProps}>{renderDoc}</Bounce>;
- case PresEffect.Roll: return <Roll {...effectProps}>{renderDoc}</Roll>;
- case PresEffect.Lightspeed: return <JackInTheBox {...effectProps}>{renderDoc}</JackInTheBox>;
+
+ const timing = StrCast(presEffectDoc?.presentation_effectTiming);
+ let timingConfig: SpringSettings | undefined;
+ if (timing) {
+ timingConfig = JSON.parse(timing);
}
- }
- public static recordAudioAnnotation(dataDoc: Doc, field: string, onRecording?: (stop: () => void) => void, onEnd?: () => void) {
- let gumStream: any;
- let recorder: any;
- navigator.mediaDevices
- .getUserMedia({
- audio: true,
- })
- .then(function (stream) {
- let audioTextAnnos = Cast(dataDoc[field + '_audioAnnotations_text'], listSpec('string'), null);
- if (audioTextAnnos) audioTextAnnos.push('');
- else audioTextAnnos = dataDoc[field + '_audioAnnotations_text'] = new List<string>(['']);
- DictationManager.Controls.listen({
- interimHandler: value => (audioTextAnnos[audioTextAnnos.length - 1] = value),
- continuous: { indefinite: false },
- }).then(results => {
- if (results && [DictationManager.Controls.Infringed].includes(results)) {
- DictationManager.Controls.stop();
- }
- onEnd?.();
- });
- gumStream = stream;
- recorder = new MediaRecorder(stream);
- recorder.ondataavailable = async (e: any) => {
- const [{ result }] = await Networking.UploadFilesToServer({ file: e.data });
- if (!(result instanceof Error)) {
- const audioField = new AudioField(result.accessPaths.agnostic.client);
- const audioAnnos = Cast(dataDoc[field + '_audioAnnotations'], listSpec(AudioField), null);
- if (audioAnnos === undefined) {
- dataDoc[field + '_audioAnnotations'] = new List([audioField]);
- } else {
- audioAnnos.push(audioField);
- }
- }
- };
- //runInAction(() => (dataDoc.audioAnnoState = 'recording'));
- recorder.start();
- const stopFunc = () => {
- recorder.stop();
- DictationManager.Controls.stop(false);
- runInAction(() => (dataDoc.audioAnnoState = 'stopped'));
- gumStream.getAudioTracks()[0].stop();
- };
- if (onRecording) onRecording(stopFunc);
- else setTimeout(stopFunc, 5000);
- });
+ if (!timingConfig) {
+ timingConfig = {
+ type: SpringType.GENTLE,
+ ...springMappings.gentle,
+ };
+ }
+
+ if (!dir) {
+ dir = PresEffectDirection.Center;
+ }
+
+ switch (StrCast(presEffectDoc?.presentation_effect, StrCast(presEffectDoc?.followLinkAnimEffect))) {
+ case PresEffect.Expand: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Expand} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ case PresEffect.Flip: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Flip} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ case PresEffect.Rotate: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Rotate} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ case PresEffect.Bounce: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Bounce} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ case PresEffect.Roll: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Roll} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ // case PresEffect.Fade: return <SlideEffect doc={root} dir={dir} presEffect={PresEffect.Fade} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect>
+ case PresEffect.Fade: return <Fade {...effectProps}>{renderDoc}</Fade>
+ // keep as preset, doesn't really make sense with spring config
+ case PresEffect.Lightspeed: return <JackInTheBox {...effectProps}>{renderDoc}</JackInTheBox>;
+ case PresEffect.None:
+ default: return renderDoc;
+ } // prettier-ignore
}
}
@observer
export class DocumentView extends DocComponent<DocumentViewProps>() {
public static ROOT_DIV = 'documentView-effectsWrapper';
- public get displayName() { return 'DocumentView(' + this.Document?.title + ')'; } // prettier-ignore
+ /**
+ * Opens a new Tab for the doc in the specified location (or in the lightbox)
+ */
+ public static addSplit: (Doc: Doc, where: OpenWhereMod) => void;
+ // Lightbox
+ public static _lightboxDoc: () => Doc | undefined;
+ public static _lightboxContains: (view?: DocumentView) => boolean | undefined;
+ public static _setLightboxDoc: (doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) => boolean;
+ /**
+ * @returns The Doc, if any, being displayed in the lightbox
+ */
+ public static readonly LightboxDoc = () => DocumentView._lightboxDoc?.();
+ /**
+ * @param view
+ * @returns whether 'view' is anywhere in the rendering hierarchy of the lightbox
+ */
+ public static readonly LightboxContains = (view?: DocumentView) => DocumentView._lightboxContains?.(view);
+ /**
+ * Sets the root Doc to render in the lightbox view.
+ * @param doc
+ * @param target a Doc within 'doc' to focus on (useful for freeform collections)
+ * @param future a list of Docs to step through with the arrow buttons of the lightbox
+ * @param layoutTemplate a template to apply to 'doc' to render it.
+ * @returns success flag which is currently always true
+ */
+ public static readonly SetLightboxDoc = (doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) => DocumentView._setLightboxDoc(doc, target, future, layoutTemplate);
+ // Sharing Manager
+ public static ShareOpen: (target?: DocumentView, targetDoc?: Doc) => void;
+ // LinkFollower
+ public static FollowLink: (linkDoc: Opt<Doc>, sourceDoc: Doc, altKey: boolean) => boolean;
+ // selection funcs
+ public static DeselectAll: (except?: Doc) => void | undefined;
+ public static DeselectView: (dv: DocumentView | undefined) => void | undefined;
+ public static SelectView: (dv: DocumentView | undefined, extendSelection: boolean) => void | undefined;
+ /**
+ * returns a list of all currently selected DocumentViews
+ */
+ public static Selected: () => DocumentView[];
+ /**
+ * returns a list of all currently selected Docs
+ */
+ public static SelectedDocs: () => Doc[];
+ public static SelectSchemaDoc: (doc: Doc, deselectAllFirst?: boolean) => void;
+ public static SelectedSchemaDoc: () => Opt<Doc>;
+ // view mgr funcs
+ public static activateTabView: (tabDoc: Doc) => boolean;
+ public static allViews: () => DocumentView[];
+ public static addView: (dv: DocumentView) => void | undefined;
+ public static removeView: (dv: DocumentView) => void | undefined;
+ public static addViewRenderedCb: (doc: Opt<Doc>, func: (dv: DocumentView) => any) => boolean;
+ public static getViews = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []) as DocumentView[];
+ public static getFirstDocumentView: (toFind: Doc) => DocumentView | undefined;
+ public static getDocumentView: (target: Doc | undefined, preferredCollection?: DocumentView) => Opt<DocumentView>;
+ public static getContextPath: (doc: Opt<Doc>, includeExistingViews?: boolean) => Doc[];
+ public static getLightboxDocumentView: (toFind: Doc) => Opt<DocumentView>;
+ public static showDocumentView: (targetDocView: DocumentView, options: FocusViewOptions) => Promise<void>;
+ public static showDocument: (
+ targetDoc: Doc, // document to display
+ optionsIn: FocusViewOptions, // options for how to navigate to target
+ finished?: (changed: boolean) => void // func called after focusing on target with flag indicating whether anything needed to be done.
+ ) => Promise<void>;
+ public static linkCommonAncestor: (link: Doc) => DocumentView | undefined;
+ // pin func
+ public static PinDoc: (docIn: Doc | Doc[], pinProps: PinProps) => void;
+ // gesture
+ public static DownDocView: DocumentView | undefined; // the first DocView that receives a pointerdown event. used by GestureOverlay to determine the doc a gesture should apply to.
+ // media playing
+ @observable public static CurrentlyPlaying: DocumentView[] = [];
+
+ public get displayName() { return 'DocumentView(' + (this.Document?.title??"") + ')'; } // prettier-ignore
public ContentRef = React.createRef<HTMLDivElement>();
private _htmlOverlayEffect: Opt<Doc>;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _viewTimer: NodeJS.Timeout | undefined;
private _animEffectTimer: NodeJS.Timeout | undefined;
- public Guid = Utils.GenerateGuid(); // a unique id associated with the main <div>. used by LinkBox's Xanchor to find the arrowhead locations.
-
- @computed public static get exploreMode() {
- return () => (SnappingManager.ExploreMode ? ScriptField.MakeScript('CollectionBrowseClick(documentView, clientX, clientY)', { documentView: 'any', clientX: 'number', clientY: 'number' })! : undefined);
+ /**
+ * This is used to create an id for tracking a Doc. Since the Doc can be in a regular view and in the lightbox at
+ * the same time, this creates a different version of the id depending on whether the search scope will be in the lightbox or not.
+ * @param inLightbox is the id scoped to the lightbox
+ * @param id the id
+ * @returns
+ */
+ public static UniquifyId(inLightbox: boolean | undefined, id: string) {
+ return (inLightbox ? 'lightbox-' : '') + id;
}
+ public ViewGuid = DocumentView.UniquifyId(DocumentView.LightboxContains(this), Utils.GenerateGuid()); // a unique id associated with the main <div>. used by LinkBox's Xanchor to find the arrowhead locations.
+ public DocUniqueId = DocumentView.UniquifyId(DocumentView.LightboxContains(this), this.Document[Id]);
constructor(props: DocumentViewProps) {
super(props);
@@ -1112,7 +1127,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
@observable public static LongPress = false;
@computed private get shouldNotScale() {
- return (this.layout_fitWidth && !this.nativeWidth) || this._props.LayoutTemplateString?.includes(KeyValueBox.name) || [CollectionViewType.Docking].includes(this.Document._type_collection as any);
+ return (this.layout_fitWidth && !this.nativeWidth) || this.ComponentView?.isUnstyledView?.();
}
@computed private get effectiveNativeWidth() {
return this.shouldNotScale ? 0 : this.nativeWidth || NumCast(this.layoutDoc.width);
@@ -1163,17 +1178,17 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
componentDidMount() {
runInAction(() => this.Document[DocViews].add(this));
this._disposers.onViewMounted = reaction(() => ScriptCast(this.Document.onViewMounted)?.script?.run({ this: this.Document }).result, emptyFunction);
- !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentManager.Instance.AddView(this);
+ !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentView.addView(this);
}
componentWillUnmount() {
this._viewTimer && clearTimeout(this._viewTimer);
runInAction(() => this.Document[DocViews].delete(this));
Object.values(this._disposers).forEach(disposer => disposer?.());
- !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentManager.Instance.RemoveView(this);
+ !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentView.removeView(this);
}
- public set IsSelected(val) { runInAction(() => (this._selected = val)); } // prettier-ignore
+ public set IsSelected(val) { runInAction(() => { this._selected = val; }); } // prettier-ignore
public get IsSelected() { return this._selected; } // prettier-ignore
public get topMost() { return this._props.renderDepth === 0; } // prettier-ignore
public get ContentDiv() { return this._docViewInternal?._contentDiv; } // prettier-ignore
@@ -1185,10 +1200,10 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
}
@computed get layout_fitWidth() {
- return this._props.layout_fitWidth?.(this.layoutDoc) ?? this.layoutDoc?.layout_fitWidth;
+ return this._props.fitWidth?.(this.layoutDoc) ?? this.layoutDoc?.layout_fitWidth;
}
@computed get anchorViewDoc() {
- return this._props.LayoutTemplateString?.includes('link_anchor_2') ? DocCast(this.Document['link_anchor_2']) : this._props.LayoutTemplateString?.includes('link_anchor_1') ? DocCast(this.Document['link_anchor_1']) : undefined;
+ return this._props.LayoutTemplateString?.includes('link_anchor_2') ? DocCast(this.Document.link_anchor_2) : this._props.LayoutTemplateString?.includes('link_anchor_1') ? DocCast(this.Document.link_anchor_1) : undefined;
}
@computed get getBounds(): Opt<{ left: number; top: number; right: number; bottom: number; transition?: string }> {
@@ -1201,20 +1216,16 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
const xf = this.screenToContentsTransform().scale(this.nativeScaling).inverse();
const [[left, top], [right, bottom]] = [xf.transformPoint(0, 0), xf.transformPoint(this.panelWidth, this.panelHeight)];
- if (this._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- const docuBox = this.ContentDiv.getElementsByClassName('linkAnchorBox-cont');
- if (docuBox.length) return { ...docuBox[0].getBoundingClientRect(), transition: undefined };
- }
// transition is returned so that the bounds will 'update' at the end of an animated transition. This is needed by xAnchor in LinkBox
const transition = this.docViewPath().find((parent: DocumentView) => parent.DataTransition?.() || parent.ComponentView?.viewTransition?.());
return { left, top, right, bottom, transition: transition?.DataTransition?.() || transition?.ComponentView?.viewTransition?.() };
}
@computed get nativeWidth() {
- return this._props.LayoutTemplateString?.includes(KeyValueBox.name) ? 0 : returnVal(this._props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this._props.TemplateDataDocument, !this.layout_fitWidth));
+ return returnVal(this._props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this._props.TemplateDataDocument, !this.layout_fitWidth));
}
@computed get nativeHeight() {
- return this._props.LayoutTemplateString?.includes(KeyValueBox.name) ? 0 : returnVal(this._props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this._props.TemplateDataDocument, !this.layout_fitWidth));
+ return returnVal(this._props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this._props.TemplateDataDocument, !this.layout_fitWidth));
}
@computed public get centeringX() { return this._props.dontCenter?.includes('x') ? 0 : this.Xshift; } // prettier-ignore
@computed public get centeringY() { return this._props.dontCenter?.includes('y') ? 0 : this.Yshift; } // prettier-ignore
@@ -1223,8 +1234,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
* path of DocumentViews hat contains this DocumentView (does not includes this DocumentView thouhg)
*/
public get containerViewPath() { return this._props.containerViewPath; } // prettier-ignore
- public get CollectionFreeFormView() { return this.CollectionFreeFormDocumentView?.CollectionFreeFormView; } // prettier-ignore
- public get CollectionFreeFormDocumentView() { return this._props.CollectionFreeFormDocumentView?.(); } // prettier-ignore
+ public get LocalRotation() { return this._props.LocalRotation?.(); } // prettier-ignore
public clearViewTransition = () => {
this._viewTimer && clearTimeout(this._viewTimer);
@@ -1243,18 +1253,18 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
public iconify(finished?: () => void, animateTime?: number) {
this.ComponentView?.updateIcon?.();
const animTime = this._docViewInternal?.animateScaleTime();
- runInAction(() => this._docViewInternal && animateTime !== undefined && (this._docViewInternal._animateScaleTime = animateTime));
+ runInAction(() => { this._docViewInternal && animateTime !== undefined && (this._docViewInternal._animateScaleTime = animateTime); }); // prettier-ignore
const finalFinished = action(() => {
finished?.();
this._docViewInternal && (this._docViewInternal._animateScaleTime = animTime);
});
- const layout_fieldKey = Cast(this.Document.layout_fieldKey, 'string', null);
- if (layout_fieldKey !== 'layout_icon') {
+ const layoutFieldKey = Cast(this.Document.layout_fieldKey, 'string', null);
+ if (layoutFieldKey !== 'layout_icon') {
this.switchViews(true, 'icon', finalFinished);
- if (layout_fieldKey && layout_fieldKey !== 'layout' && layout_fieldKey !== 'layout_icon') this.Document.deiconifyLayout = layout_fieldKey.replace('layout_', '');
+ if (layoutFieldKey && layoutFieldKey !== 'layout' && layoutFieldKey !== 'layout_icon') this.Document.deiconifyLayout = layoutFieldKey.replace('layout_', '');
} else {
const deiconifyLayout = Cast(this.Document.deiconifyLayout, 'string', null);
- this.switchViews(deiconifyLayout ? true : false, deiconifyLayout, finalFinished);
+ this.switchViews(!!deiconifyLayout, deiconifyLayout, finalFinished, true);
this.Document.deiconifyLayout = undefined;
this._props.bringToFront?.(this.Document);
}
@@ -1262,26 +1272,27 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
public playAnnotation = () => {
const self = this;
- const audioAnnoState = this.dataDoc.audioAnnoState ?? 'stopped';
+ const audioAnnoState = this.dataDoc.audioAnnoState ?? AudioAnnoState.stopped;
const audioAnnos = Cast(this.dataDoc[this.LayoutFieldKey + '_audioAnnotations'], listSpec(AudioField), null);
const anno = audioAnnos?.lastElement();
if (anno instanceof AudioField) {
switch (audioAnnoState) {
- case 'stopped':
+ case AudioAnnoState.stopped:
this.dataDoc[AudioPlay] = new Howl({
src: [anno.url.href],
format: ['mp3'],
autoplay: true,
loop: false,
volume: 0.5,
- onend: action(() => (self.dataDoc.audioAnnoState = 'stopped')),
+ onend: action(() => { self.dataDoc.audioAnnoState = AudioAnnoState.stopped; }), // prettier-ignore
});
- this.dataDoc.audioAnnoState = 'playing';
+ this.dataDoc.audioAnnoState = AudioAnnoState.playing;
break;
- case 'playing':
+ case AudioAnnoState.playing:
this.dataDoc[AudioPlay]?.stop();
- this.dataDoc.audioAnnoState = 'stopped';
+ this.dataDoc.audioAnnoState = AudioAnnoState.stopped;
break;
+ default:
}
}
};
@@ -1296,10 +1307,10 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
this._docViewInternal._animateScaleTime = time;
}
});
- public setAnimEffect = (presEffect: Doc, timeInMs: number, afterTrans?: () => void) => {
+ public setAnimEffect = (presEffect: Doc, timeInMs: number /* , afterTrans?: () => void */) => {
this._animEffectTimer && clearTimeout(this._animEffectTimer);
this.Document[Animation] = presEffect;
- this._animEffectTimer = setTimeout(() => (this.Document[Animation] = undefined), timeInMs);
+ this._animEffectTimer = setTimeout(() => { this.Document[Animation] = undefined; }, timeInMs); // prettier-ignore
};
public setViewTransition = (transProp: string, timeInMs: number, afterTrans?: () => void, dataTrans = false) => {
this._viewTimer = DocumentView.SetViewTransition([this.layoutDoc], transProp, timeInMs, this._viewTimer, afterTrans, dataTrans);
@@ -1310,6 +1321,33 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
custom && DocUtils.makeCustomViewClicked(this.Document, Docs.Create.StackingDocument, layout, undefined);
}, 'set custom view');
+ public static setDefaultTemplate(checkResult?: boolean) {
+ if (checkResult) {
+ return Doc.UserDoc().defaultTextLayout;
+ }
+ const view = DocumentView.Selected()[0]?._props.renderDepth > 0 ? DocumentView.Selected()[0] : undefined;
+ undoable(() => {
+ let tempDoc: Opt<Doc>;
+ if (view) {
+ if (!view.layoutDoc.isTemplateDoc) {
+ tempDoc = view.Document;
+ MakeTemplate(tempDoc);
+ Doc.AddDocToList(Doc.UserDoc(), 'template_user', tempDoc);
+ Doc.AddDocToList(DocListCast(Doc.MyTools.data)[1], 'data', makeUserTemplateButton(tempDoc));
+ tempDoc && Doc.AddDocToList(Cast(Doc.UserDoc().template_user, Doc, null), 'data', tempDoc);
+ } else {
+ tempDoc = DocCast(view.Document[StrCast(view.Document.layout_fieldKey)]);
+ if (!tempDoc) {
+ tempDoc = view.Document;
+ while (tempDoc && !Doc.isTemplateDoc(tempDoc)) tempDoc = DocCast(tempDoc.proto);
+ }
+ }
+ }
+ Doc.UserDoc().defaultTextLayout = tempDoc ? new PrefetchProxy(tempDoc) : undefined;
+ }, 'set default template')();
+ return undefined;
+ }
+
/**
* This switches between the current view of a Doc and a specified alternate layout view.
* The current view of the Doc is stored in the layout_default field so that it can be restored.
@@ -1321,12 +1359,13 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
const curLayout = StrCast(this.Document.layout_fieldKey).replace('layout_', '').replace('layout', '');
if (!this.Document.layout_default && curLayout !== detailLayoutKeySuffix) this.Document.layout_default = curLayout;
const defaultLayout = StrCast(this.Document.layout_default);
- if (this.Document.layout_fieldKey === 'layout_' + detailLayoutKeySuffix) this.switchViews(defaultLayout ? true : false, defaultLayout, undefined, true);
+ if (this.Document.layout_fieldKey === 'layout_' + detailLayoutKeySuffix) this.switchViews(!!defaultLayout, defaultLayout, undefined, true);
else this.switchViews(true, detailLayoutKeySuffix, undefined, true);
};
public switchViews = (custom: boolean, view: string, finished?: () => void, useExistingLayout = false) => {
const batch = UndoManager.StartBatch('switchView:' + view);
- runInAction(() => this._docViewInternal && (this._docViewInternal._animateScalingTo = 0.1)); // shrink doc
+ // shrink doc first..
+ runInAction(() => { this._docViewInternal && (this._docViewInternal._animateScalingTo = 0.1); }); // prettier-ignore
setTimeout(
action(() => {
if (useExistingLayout && custom && this.Document['layout_' + view]) {
@@ -1334,7 +1373,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
} else {
this.setCustomView(custom, view);
}
- this._docViewInternal && (this._docViewInternal._animateScalingTo = 1); // expand it
+ this._docViewInternal && (this._docViewInternal._animateScalingTo = 1); // now expand it
setTimeout(
action(() => {
this._docViewInternal && (this._docViewInternal._animateScalingTo = 0);
@@ -1352,22 +1391,20 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
*/
public docViewPath = () => (this.containerViewPath ? [...this.containerViewPath(), this] : [this]);
- layout_fitWidthFunc = (doc: Doc) => BoolCast(this.layout_fitWidth);
+ layout_fitWidthFunc = (/* doc: Doc */) => BoolCast(this.layout_fitWidth);
screenToLocalScale = () => this._props.ScreenToLocalTransform().Scale;
isSelected = () => this.IsSelected;
select = (extendSelection: boolean, focusSelection?: boolean) => {
- if (this.IsSelected && SelectionManager.Views.length > 1) SelectionManager.DeselectView(this);
- else {
- SelectionManager.SelectView(this, extendSelection);
- if (focusSelection) {
- DocumentManager.Instance.showDocument(this.Document, {
- willZoomCentered: true,
- zoomScale: 0.9,
- zoomTime: 500,
- });
- }
+ DocumentView.SelectView(this, extendSelection);
+ if (focusSelection) {
+ DocumentView.showDocument(this.Document, {
+ willZoomCentered: true,
+ zoomScale: 0.9,
+ zoomTime: 500,
+ });
}
};
+ backgroundColor = () => this._docViewInternal?.backgroundBoxColor;
DataTransition = () => this._props.DataTransition?.() || StrCast(this.Document.dataTransition);
ShouldNotScale = () => this.shouldNotScale;
NativeWidth = () => this.effectiveNativeWidth;
@@ -1375,7 +1412,8 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
PanelWidth = () => this.panelWidth;
PanelHeight = () => this.panelHeight;
NativeDimScaling = () => this.nativeScaling;
- hideLinkCount = () => (this.hideLinkButton ? true : false);
+ hideLinkCount = () => !!this.hideLinkButton;
+ isHovering = () => this._isHovering;
selfView = () => this;
/**
* @returns Transform to the document view (in the coordinate system of whatever contains the DocumentView)
@@ -1398,16 +1436,16 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
ref={r => {
const val = r?.style.display !== 'none'; // if the outer overlay has been displayed, trigger the innner div to start it's opacity fade in transition
if (r && val !== this._enableHtmlOverlayTransitions) {
- setTimeout(action(() => (this._enableHtmlOverlayTransitions = val)));
+ setTimeout(action(() => { this._enableHtmlOverlayTransitions = val; })); // prettier-ignore
}
}}
style={{ display: !this._htmlOverlayText ? 'none' : undefined }}>
<div className="documentView-htmlOverlayInner" style={{ transition: `all 500ms`, opacity: this._enableHtmlOverlayTransitions ? 0.9 : 0 }}>
{DocumentViewInternal.AnimationEffect(
<div className="webBox-textHighlight">
- <ObserverJsxParser autoCloseVoidElements={true} key={42} onError={(e: any) => console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} />
+ <ObserverJsxParser autoCloseVoidElements key={42} onError={(e: any) => console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} />
</div>,
- { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Zoom } as any as Doc,
+ { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Expand } as any as Doc,
this.Document
)}
</div>
@@ -1421,7 +1459,15 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
const yshift = Math.abs(this.Yshift) <= 0.001 ? this._props.PanelHeight() : undefined;
return (
- <div id={this.Guid} className="contentFittingDocumentView" onPointerEnter={action(() => (this._isHovering = true))} onPointerLeave={action(() => (this._isHovering = false))}>
+ <div
+ id={this.ViewGuid}
+ className="contentFittingDocumentView"
+ onPointerEnter={action(() => {
+ this._isHovering = true;
+ })}
+ onPointerLeave={action(() => {
+ this._isHovering = false;
+ })}>
{!this.Document || !this._props.PanelWidth() ? null : (
<div
className="contentFittingDocumentView-previewDoc"
@@ -1433,6 +1479,8 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
}}>
<DocumentViewInternal
{...this._props}
+ parent={undefined}
+ isHovering={this.isHovering}
fieldKey={this.LayoutFieldKey}
DataTransition={this.DataTransition}
DocumentView={this.selfView}
@@ -1444,17 +1492,19 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
NativeDimScaling={this.NativeDimScaling}
isSelected={this.isSelected}
select={this.select}
- layout_fitWidth={this.layout_fitWidthFunc}
+ fitWidth={this.layout_fitWidthFunc}
ScreenToLocalTransform={this.screenToContentsTransform}
focus={this._props.focus || emptyFunction}
- ref={action((r: DocumentViewInternal | null) => r && (this._docViewInternal = r))}
+ ref={action((r: DocumentViewInternal | null) => {
+ r && (this._docViewInternal = r);
+ })}
/>
{this.htmlOverlay()}
{this.ComponentView?.infoUI?.()}
</div>
)}
{/* display link count button */}
- <DocumentLinksButton hideCount={this.hideLinkCount} View={this} scaling={this.screenToLocalScale} OnHover={true} Bottom={this.topMost} ShowCount={true} />
+ <DocumentLinksButton hideCount={this.hideLinkCount} View={this} scaling={this.screenToLocalScale} OnHover Bottom={this.topMost} ShowCount />
</div>
);
}
@@ -1478,37 +1528,70 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
// shows a stacking view collection (by default, but the user can change) of all documents linked to the source
public static showBackLinks(linkAnchor: Doc) {
- const docId = Doc.CurrentUserEmail + Doc.GetProto(linkAnchor)[Id] + '-pivotish';
+ const docId = ClientUtils.CurrentUserEmail() + Doc.GetProto(linkAnchor)[Id] + '-pivotish';
// prettier-ignore
DocServer.GetRefField(docId).then(docx =>
- LightboxView.Instance.SetLightboxDoc(
+ DocumentView.SetLightboxDoc(
(docx as Doc) ?? // reuse existing pivot view of documents, or else create a new collection
Docs.Create.StackingDocument([], { title: linkAnchor.title + '-pivot', _width: 500, _height: 500, target: linkAnchor, onViewMounted: ScriptField.MakeScript('updateLinkCollection(this, this.target)') }, docId)
)
);
}
+ // eslint-disable-next-line default-param-last
+ public static FocusOrOpen(docIn: Doc, optionsIn: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) {
+ let doc = docIn;
+ const options = optionsIn;
+ const func = () => {
+ const cv = DocumentView.getDocumentView(containingDoc);
+ const dv = DocumentView.getDocumentView(doc, cv);
+ if (dv && (!containingDoc || dv.containerViewPath?.().lastElement()?.Document === containingDoc)) {
+ DocumentView.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.Document));
+ } else {
+ const container = DocCast(containingDoc ?? doc.embedContainer ?? Doc.BestEmbedding(doc));
+ const showDoc = !Doc.IsSystem(container) && !cv ? container : doc;
+ options.toggleTarget = undefined;
+ DocumentView.showDocument(showDoc, options, () => DocumentView.showDocument(doc, { ...options, openLocation: undefined })).then(() => {
+ const cvFound = DocumentView.getDocumentView(containingDoc);
+ const dvFound = DocumentView.getDocumentView(doc, cvFound);
+ dvFound && Doc.linkFollowHighlight(dvFound.Document);
+ });
+ }
+ };
+ if (Doc.IsDataProto(doc) && Doc.GetEmbeddings(doc).some(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))) {
+ doc = Doc.GetEmbeddings(doc).find(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))!;
+ }
+ if (doc.hidden) {
+ doc.hidden = false;
+ options.toggleTarget = false;
+ setTimeout(func);
+ } else func();
+ }
}
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function DocFocusOrOpen(docIn: Doc, optionsIn?: FocusViewOptions, containingDoc?: Doc) {
+ return DocumentView.FocusOrOpen(docIn, optionsIn, containingDoc);
+});
+
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function deiconifyView(documentView: DocumentView) {
documentView.iconify();
documentView.select(false);
});
-ScriptingGlobals.add(function deiconifyViewToLightbox(documentView: DocumentView) {
- LightboxView.Instance.AddDocTab(documentView.Document, OpenWhere.lightbox, 'layout'); //, 0);
-});
-
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function toggleDetail(dv: DocumentView, detailLayoutKeySuffix: string) {
dv.toggleDetail(detailLayoutKeySuffix);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function updateLinkCollection(linkCollection: Doc, linkSource: Doc) {
const collectedLinks = DocListCast(linkCollection[DocData].data);
let wid = NumCast(linkSource._width);
let embedding: Doc | undefined;
- const links = LinkManager.Links(linkSource);
+ const links = Doc.Links(linkSource);
links.forEach(link => {
- const other = LinkManager.getOppositeAnchor(link, linkSource);
+ const other = Doc.getOppositeAnchor(link, linkSource);
const otherdoc = DocCast(other?.annotationOn ?? other);
if (otherdoc && !collectedLinks?.some(d => Doc.AreProtosEqual(d, otherdoc))) {
embedding = Doc.MakeEmbedding(otherdoc);
@@ -1519,9 +1602,10 @@ ScriptingGlobals.add(function updateLinkCollection(linkCollection: Doc, linkSour
Doc.AddDocToList(Doc.GetProto(linkCollection), 'data', embedding);
}
});
- embedding && DocServer.UPDATE_SERVER_CACHE(); // if a new embedding was made, update the client's server cache so that it will not come back as a promise
+ embedding && UPDATE_SERVER_CACHE(); // if a new embedding was made, update the client's server cache so that it will not come back as a promise
return links;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function updateTagsCollection(collection: Doc) {
const tag = StrCast(collection.title).split('-->')[1];
const matchedTags = Array.from(SearchUtil.SearchCollection(Doc.MyFilesystem, tag, false, ['tags']).keys());
@@ -1545,6 +1629,6 @@ ScriptingGlobals.add(function updateTagsCollection(collection: Doc) {
return aset;
}, new Set<Doc>());
- created && (collection[DocData].data = new List<Doc>(matchedDocs));
+ created && (collection[DocData].data = new List<Doc>(Array.from(matchedDocs)));
return true;
});
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index 50d4c7c78..1f5c9b84b 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -1,24 +1,26 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import { action, makeObservable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Id } from '../../../fields/FieldSymbols';
+import { DivHeight, DivWidth } from '../../../ClientUtils';
+import { Doc } from '../../../fields/Doc';
import { NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
+import { DocUtils } from '../../documents/DocUtils';
+import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
import { undoBatch } from '../../util/UndoManager';
import { ViewBoxBaseComponent } from '../DocComponent';
-import { LightboxView } from '../LightboxView';
+import { DocumentView } from './DocumentView';
import './EquationBox.scss';
import { FieldView, FieldViewProps } from './FieldView';
import EquationEditor from './formattedText/EquationEditor';
-import { DivHeight, DivWidth } from '../../../Utils';
@observer
export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(EquationBox, fieldKey);
}
- public static SelectOnLoad: string = '';
_ref: React.RefObject<EquationEditor> = React.createRef();
constructor(props: FieldViewProps) {
@@ -28,12 +30,12 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
componentDidMount() {
this._props.setContentViewBox?.(this);
- if (EquationBox.SelectOnLoad === this.Document[Id] && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()))) {
+ if (Doc.SelectOnLoad === this.Document && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.()))) {
this._props.select(false);
this._ref.current!.mathField.focus();
this.dataDoc.text === 'x' && this._ref.current!.mathField.select();
- EquationBox.SelectOnLoad = '';
+ Doc.SetSelectOnLoad(undefined);
}
reaction(
() => StrCast(this.dataDoc.text),
@@ -42,7 +44,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._ref.current!.mathField.latex(text);
}
}
- //{ fireImmediately: true }
+ // { fireImmediately: true }
);
reaction(
() => this._props.isSelected(),
@@ -68,7 +70,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
x: NumCast(this.layoutDoc.x),
y: NumCast(this.layoutDoc.y) + _height + 10,
});
- EquationBox.SelectOnLoad = nextEq[Id];
+ Doc.SetSelectOnLoad(nextEq);
this._props.addDocument?.(nextEq);
e.stopPropagation();
}
@@ -80,13 +82,17 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
_height: 300,
backgroundColor: 'white',
});
+ const link = DocUtils.MakeLink(this.Document, graph, { link_relationship: 'function', link_description: 'input' });
this._props.addDocument?.(graph);
+ link && this._props.addDocument?.(link);
e.stopPropagation();
}
if (e.key === 'Backspace' && !this.dataDoc.text) this._props.removeDocument?.(this.Document);
};
@undoBatch
- onChange = (str: string) => (this.dataDoc.text = str);
+ onChange = (str: string) => {
+ this.dataDoc.text = str;
+ };
updateSize = () => {
const style = this._ref.current && getComputedStyle(this._ref.current.element.current);
@@ -94,11 +100,10 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (this.layoutDoc._nativeWidth) {
// if equation has been scaled then editing the expression must also edit the native dimensions to keep the aspect ratio
const prevNwidth = NumCast(this.layoutDoc._nativeWidth);
- const prevNheight = NumCast(this.layoutDoc._nativeHeight);
- this.layoutDoc._nativeWidth = Math.max(35, Number(style.width.replace('px', '')));
- this.layoutDoc._nativeHeight = Math.max(25, Number(style.height.replace('px', '')));
+ const newNwidth = (this.layoutDoc._nativeWidth = Math.max(35, Number(style.width.replace('px', ''))));
+ const newNheight = (this.layoutDoc._nativeHeight = Math.max(25, Number(style.height.replace('px', ''))));
this.layoutDoc._width = (NumCast(this.layoutDoc._width) * NumCast(this.layoutDoc._nativeWidth)) / prevNwidth;
- this.layoutDoc._height = (NumCast(this.layoutDoc._height) * NumCast(this.layoutDoc._nativeHeight)) / prevNheight;
+ this.layoutDoc._height = (NumCast(this.layoutDoc._width) * newNheight) / newNwidth;
} else {
this.layoutDoc._width = Math.max(35, Number(style.width.replace('px', '')));
this.layoutDoc._height = Math.max(25, Number(style.height.replace('px', '')));
@@ -110,7 +115,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
const scale = (this._props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1);
return (
<div
- ref={r => this.updateSize()}
+ ref={() => this.updateSize()}
className="equationBox-cont"
onPointerDown={e => !e.ctrlKey && e.stopPropagation()}
style={{
@@ -121,8 +126,13 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
fontSize: StrCast(this.layoutDoc._text_fontSize),
}}
onKeyDown={e => e.stopPropagation()}>
- <EquationEditor ref={this._ref} value={StrCast(this.dataDoc.text, 'x')} spaceBehavesLikeTab={true} onChange={this.onChange} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" />
+ <EquationEditor ref={this._ref} value={StrCast(this.dataDoc.text, 'x')} spaceBehavesLikeTab onChange={this.onChange} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" />
</div>
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.EQUATION, {
+ layout: { view: EquationBox, dataField: 'text' },
+ options: { acl: '', fontSize: '14px', _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true, layout_hideDecorationTitle: true, systemIcon: 'BsCalculatorFill' }, // systemIcon: 'BsSuperscript' + BsSubscript
+});
diff --git a/src/client/views/nodes/FaceRectangle.tsx b/src/client/views/nodes/FaceRectangle.tsx
index 46bc6eb03..2b66b83fe 100644
--- a/src/client/views/nodes/FaceRectangle.tsx
+++ b/src/client/views/nodes/FaceRectangle.tsx
@@ -8,11 +8,17 @@ export default class FaceRectangle extends React.Component<{ rectangle: Rectangl
@observable private opacity = 0;
componentDidMount() {
- setTimeout(() => runInAction(() => (this.opacity = 1)), 500);
+ setTimeout(
+ () =>
+ runInAction(() => {
+ this.opacity = 1;
+ }),
+ 500
+ );
}
render() {
- const rectangle = this.props.rectangle;
+ const { rectangle } = this.props;
return (
<div
style={{
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 8a49b4757..818d26956 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -1,3 +1,6 @@
+/* eslint-disable react/no-unused-prop-types */
+/* eslint-disable react/require-default-props */
+import { computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { DateField } from '../../../fields/DateField';
@@ -5,33 +8,16 @@ import { Doc, Field, Opt } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { ScriptField } from '../../../fields/ScriptField';
import { WebField } from '../../../fields/URLField';
-import { dropActionType } from '../../util/DragManager';
+import { dropActionType } from '../../util/DropActionTypes';
import { Transform } from '../../util/Transform';
-import { ViewBoxInterface } from '../DocComponent';
-import { CollectionFreeFormDocumentView } from './CollectionFreeFormDocumentView';
-import { DocumentView, OpenWhere } from './DocumentView';
-import { PinProps } from './trails';
+import { PinProps } from '../PinFuncs';
+import { ViewBoxInterface } from '../ViewBoxInterface';
+import { DocumentView } from './DocumentView';
+import { FocusViewOptions } from './FocusViewOptions';
+import { OpenWhere } from './OpenWhere';
-export interface FocusViewOptions {
- willPan?: boolean; // determines whether to pan to target document
- willZoomCentered?: boolean; // determines whether to zoom in on target document. if zoomScale is 0, this just centers the document
- zoomScale?: number; // percent of containing frame to zoom into document
- zoomTime?: number;
- didMove?: boolean; // whether a document was changed during the showDocument process
- docTransform?: Transform; // when a document can't be panned and zoomed within its own container (say a group), then we need to continue to move up the render hierarchy to find something that can pan and zoom. when this happens the docTransform must accumulate all the transforms of each level of the hierarchy
- instant?: boolean; // whether focus should happen instantly (as opposed to smooth zoom)
- preview?: boolean; // whether changes should be previewed by the componentView or written to the document
- effect?: Doc; // animation effect for focus
- noSelect?: boolean; // whether target should be selected after focusing
- playAudio?: boolean; // whether to play audio annotation on focus
- playMedia?: boolean; // whether to play start target videos
- openLocation?: OpenWhere; // where to open a missing document
- zoomTextSelections?: boolean; // whether to display a zoomed overlay of anchor text selections
- toggleTarget?: boolean; // whether to toggle target on and off
- anchorDoc?: Doc; // doc containing anchor info to apply at end of focus to target doc
- easeFunc?: 'linear' | 'ease'; // transition method for scrolling
-}
export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt<number>;
+// eslint-disable-next-line no-use-before-define
export type StyleProviderFuncType = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => any;
//
// these properties get assigned through the render() method of the DocumentView when it creates this node.
@@ -54,11 +40,12 @@ export interface FieldViewSharedProps {
ignoreAutoHeight?: boolean;
disableBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over.
hideClickBehaviors?: boolean; // whether to suppress menu item options for changing click behaviors
- CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView;
+ ignoreUsePath?: boolean; // ignore the usePath field for selecting the fieldKey (eg., on text docs)
+ LocalRotation?: () => number | undefined; // amount of rotation applied to freeformdocumentview containing document view
containerViewPath?: () => DocumentView[];
fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
isGroupActive?: () => string | undefined; // is this document part of a group that is active
- setContentViewBox?: (view: ViewBoxInterface) => any; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox
+ setContentViewBox?: (view: ViewBoxInterface<any>) => any; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox
PanelWidth: () => number;
PanelHeight: () => number;
isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events
@@ -72,14 +59,14 @@ export interface FieldViewSharedProps {
onDoubleClickScript?: () => ScriptField;
onPointerDownScript?: () => ScriptField;
onPointerUpScript?: () => ScriptField;
- onBrowseClickScript?: () => ScriptField | undefined;
+ // eslint-disable-next-line no-use-before-define
onKey?: (e: React.KeyboardEvent, fieldProps: FieldViewProps) => boolean | undefined;
- layout_fitWidth?: (doc: Doc) => boolean | undefined;
+ fitWidth?: (doc: Doc) => boolean | undefined;
searchFilterDocs: () => Doc[];
- layout_showTitle?: () => string;
+ showTitle?: () => string;
whenChildContentsActiveChanged: (isActive: boolean) => void;
rootSelected?: () => boolean; // whether the root of a template has been selected
- addDocTab: (doc: Doc, where: OpenWhere) => boolean;
+ addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean;
filterAddDocument?: (doc: Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean;
removeDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean;
@@ -90,6 +77,7 @@ export interface FieldViewSharedProps {
waitForDoubleClickToClick?: () => 'never' | 'always' | undefined;
defaultDoubleClick?: () => 'default' | 'ignore' | undefined;
pointerEvents?: () => Opt<string>;
+ suppressSetHeight?: boolean;
}
/**
@@ -103,6 +91,7 @@ export interface FieldViewProps extends FieldViewSharedProps {
docViewPath: () => DocumentView[];
setHeight?: (height: number) => void;
NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal
+ isHovering?: () => boolean;
// properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React)
// See currentUserUtils headerTemplate for examples of creating text boxes from html which set some of these fields
@@ -119,11 +108,14 @@ export interface FieldViewProps extends FieldViewSharedProps {
@observer
export class FieldView extends React.Component<FieldViewProps> {
public static LayoutString(fieldType: { name: string }, fieldStr: string) {
- return `<${fieldType.name} {...props} fieldKey={'${fieldStr}'}/>`; //e.g., "<ImageBox {...props} fieldKey={'data'} />"
+ return `<${fieldType.name} {...props} fieldKey={'${fieldStr}'}/>`; // e.g., "<ImageBox {...props} fieldKey={'data'} />"
+ }
+ @computed get fieldval() {
+ return this.props.Document[this.props.fieldKey];
}
render() {
- const field = this.props.Document[this.props.fieldKey];
+ const field = this.fieldval;
// prettier-ignore
if (field instanceof Doc) return <p> <b>{field.title?.toString()}</b></p>;
if (field === undefined) return <p>{'<null>'}</p>;
@@ -131,6 +123,6 @@ export class FieldView extends React.Component<FieldViewProps> {
if (field instanceof List) return <div> {field.map(f => Field.toString(f)).join(', ')} </div>;
if (field instanceof WebField) return <p>{Field.toString(field.url.href)}</p>;
if (!(field instanceof Promise)) return <p>{Field.toString(field)}</p>;
- return <p> {'Waiting for server...'} </p>;
+ return <p> Waiting for server... </p>;
}
}
diff --git a/src/client/views/nodes/FocusViewOptions.ts b/src/client/views/nodes/FocusViewOptions.ts
new file mode 100644
index 000000000..bb0d2b03c
--- /dev/null
+++ b/src/client/views/nodes/FocusViewOptions.ts
@@ -0,0 +1,24 @@
+import { Doc } from '../../../fields/Doc';
+import { Transform } from '../../util/Transform';
+import { OpenWhere } from './OpenWhere';
+
+export interface FocusViewOptions {
+ willPan?: boolean; // determines whether to pan to target document
+ willZoomCentered?: boolean; // determines whether to zoom in on target document. if zoomScale is 0, this just centers the document
+ zoomScale?: number; // percent of containing frame to zoom into document
+ zoomTime?: number;
+ didMove?: boolean; // whether a document was changed during the showDocument process
+ docTransform?: Transform; // when a document can't be panned and zoomed within its own container (say a group), then we need to continue to move up the render hierarchy to find something that can pan and zoom. when this happens the docTransform must accumulate all the transforms of each level of the hierarchy
+ instant?: boolean; // whether focus should happen instantly (as opposed to smooth zoom)
+ preview?: boolean; // whether changes should be previewed by the componentView or written to the document
+ effect?: Doc; // animation effect for focus // bcz: needs to be changed to something more generic than a Doc
+ noSelect?: boolean; // whether target should be selected after focusing
+ playAudio?: boolean; // whether to play audio annotation on focus
+ playMedia?: boolean; // whether to play start target videos
+ openLocation?: OpenWhere; // where to open a missing document
+ zoomTextSelections?: boolean; // whether to display a zoomed overlay of anchor text selections
+ toggleTarget?: boolean; // whether to toggle target on and off
+ easeFunc?: 'linear' | 'ease'; // transition method for scrolling
+ pointFocus?: { X: number; Y: number }; // clientX and clientY coordinates to focus on instead of a document target (used by explore mode)
+ contextPath?: Doc[]; // path of inner documents that will also be focused
+}
diff --git a/src/client/views/nodes/FontIconBox/ButtonInterface.ts b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
index 1c034bfbe..0d0d7b1c3 100644
--- a/src/client/views/nodes/FontIconBox/ButtonInterface.ts
+++ b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
@@ -1,5 +1,5 @@
-import { Doc } from '../../../../fields/Doc';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { Doc } from '../../../../fields/Doc';
import { ButtonType } from './FontIconBox';
export interface IButtonProps {
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index f02ad7300..5e3bb9fec 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -1,24 +1,25 @@
+/* eslint-disable react/jsx-props-no-spreading */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, ColorPicker, Dropdown, DropdownType, EditableText, IconButton, IListItemProps, MultiToggle, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
+import { Button, ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, MultiToggle, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { ClientUtils, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils';
import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
-import { ScriptField } from '../../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnTrue, setupMoveUpEvents, Utils } from '../../../../Utils';
+import { BoolCast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { emptyFunction } from '../../../../Utils';
+import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
-import { SelectionManager } from '../../../util/SelectionManager';
-import { SettingsManager } from '../../../util/SettingsManager';
+import { SnappingManager } from '../../../util/SnappingManager';
import { undoable, UndoManager } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { EditableView } from '../../EditableView';
import { SelectedDocView } from '../../selectedDoc';
-import { StyleProp } from '../../StyleProvider';
-import { OpenWhere } from '../DocumentView';
+import { StyleProp } from '../../StyleProp';
import { FieldView, FieldViewProps } from '../FieldView';
+import { OpenWhere } from '../OpenWhere';
import './FontIconBox.scss';
import TrailsIcon from './TrailsIcon';
@@ -34,7 +35,7 @@ export enum ButtonType {
NumberSliderButton = 'numSliderBtn',
NumberDropdownButton = 'numDropdownBtn',
NumberInlineButton = 'numInlineBtn',
- EditableText = 'editableText',
+ EditText = 'editableText',
}
export interface ButtonProps extends FieldViewProps {
@@ -50,34 +51,14 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
super(props);
makeObservable(this);
}
- //
- // This controls whether fontIconButtons will display labels under their icons or not
- //
- public static get ShowIconLabels() {
- return BoolCast(Doc.UserDoc()._showLabel);
- }
- public static set ShowIconLabels(show: boolean) {
- Doc.UserDoc()._showLabel = show;
- }
@observable noTooltip = false;
- showTemplate = (): void => {
- const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
- dragFactory && this._props.addDocTab(dragFactory, OpenWhere.addRight);
- };
- dragAsTemplate = (): void => {
- this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)');
- };
- useAsPrototype = (): void => {
- this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)');
- };
+ showTemplate = (dragFactory: Doc) => this._props.addDocTab(dragFactory, OpenWhere.addRight);
specificContextMenu = (): void => {
- if (!Doc.noviceMode && Cast(this.layoutDoc.dragFactory, Doc, null)) {
- const cm = ContextMenu.Instance;
- cm.addItem({ description: 'Show Template', event: this.showTemplate, icon: 'tag' });
- cm.addItem({ description: 'Use as Render Template', event: this.dragAsTemplate, icon: 'tag' });
- cm.addItem({ description: 'Use as Prototype', event: this.useAsPrototype, icon: 'tag' });
+ const dragFactory = DocCast(this.layoutDoc.dragFactory);
+ if (!Doc.noviceMode && dragFactory) {
+ ContextMenu.Instance.addItem({ description: 'Show Template', event: () => this.showTemplate(dragFactory), icon: 'tag' });
}
};
@@ -94,7 +75,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
if (iconFalse) {
icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as any;
if (icon) return <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />;
- else return null;
+ return null;
}
icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as any;
return !icon ? null : icon === 'pres-trail' ? TrailsIcon(color) : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />;
@@ -120,7 +101,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
* - Color button
* - Dropdown list
* - Number button
- **/
+ * */
_batch: UndoManager.Batch | undefined = undefined;
/**
@@ -129,18 +110,13 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
@computed get numberDropdown() {
let type: NumberDropdownType;
switch (this.type) {
- case ButtonType.NumberDropdownButton:
- type = 'dropdown';
- break;
- case ButtonType.NumberInlineButton:
- type = 'input';
- break;
+ case ButtonType.NumberDropdownButton: type = 'dropdown'; break;
+ case ButtonType.NumberInlineButton: type = 'input'; break;
case ButtonType.NumberSliderButton:
- default:
- type = 'slider';
+ default: type = 'slider';
break;
- }
- const numScript = (value?: number) => ScriptCast(this.Document.script).script.run({ this: this.Document, self: this.Document, value, _readOnly_: value === undefined });
+ } // 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);
// Script for checking the outcome of the toggle
const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3)));
@@ -148,7 +124,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
return (
<NumberDropdown
color={color}
- background={SettingsManager.userBackgroundColor}
+ background={SnappingManager.userBackgroundColor}
numberDropdownType={type}
showPlusMinus={false}
tooltip={this.label}
@@ -166,12 +142,10 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
setupMoveUpEvents(
this,
e,
- (e: PointerEvent) => {
- return ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, self: this.Document, value: { doc: value, e } }).result;
- },
+ () => ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, value: { doc: value, e } }).result,
emptyFunction,
emptyFunction
- );
+ ); // prettier-ignore
return false;
};
@@ -185,9 +159,10 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
let text: string | undefined;
let getStyle: (val: string) => any = () => {};
let icon: IconProp = 'caret-down';
- const isViewDropdown = script?.script.originalScript.startsWith('setView');
+ const isViewDropdown = script?.script.originalScript.startsWith('{ return setView');
if (isViewDropdown) {
- const selected = SelectionManager.Docs;
+ 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) {
text = StrCast(selected.lastElement()._type_collection);
@@ -195,27 +170,27 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
if (selected.length > 1) {
text = selected.length + ' selected';
} else {
- text = Utils.cleanDocumentType(StrCast(selected.lastElement().type) as DocumentType);
+ text = ClientUtils.cleanDocumentType(StrCast(selected.lastElement().type) as DocumentType, '' as CollectionViewType);
icon = Doc.toIcon(selected.lastElement());
}
return (
<Popup
- icon={<FontAwesomeIcon size={'1x'} icon={icon} />}
+ icon={<FontAwesomeIcon size="1x" icon={icon} />}
text={text}
type={Type.TERT}
- color={SettingsManager.userColor}
- background={SettingsManager.userVariantColor}
+ color={SnappingManager.userColor}
+ background={SnappingManager.userVariantColor}
popup={<SelectedDocView selectedDocs={selected} />}
fillWidth
/>
);
}
} else {
- return <Button text="None Selected" type={Type.TERT} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} fillWidth inactive />;
+ return <Button text="None Selected" type={Type.TERT} color={SnappingManager.userColor} background={SnappingManager.userVariantColor} fillWidth inactive />;
}
noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Carousel3D, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
} else {
- text = script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result;
+ text = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result;
// text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
getStyle = (val: string) => ({ fontFamily: val });
}
@@ -233,9 +208,9 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
return (
<Dropdown
selectedVal={text}
- setSelectedVal={undoable(value => script.script.run({ this: this.Document, self: this.Document, value }), `dropdown select ${this.label}`)}
- color={SettingsManager.userColor}
- background={SettingsManager.userVariantColor}
+ setSelectedVal={undoable(value => script.script.run({ this: this.Document, value }), `dropdown select ${this.label}`)}
+ color={SnappingManager.userColor}
+ background={SnappingManager.userVariantColor}
type={Type.TERT}
closeOnSelect={false}
dropdownType={DropdownType.SELECT}
@@ -257,17 +232,17 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
*/
@computed get colorButton() {
const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
- const curColor = this.colorScript?.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result ?? 'transparent';
+ const curColor = this.colorScript?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result ?? 'transparent';
const tooltip: string = StrCast(this.Document.toolTip);
return (
<ColorPicker
setSelectedColor={value => {
if (!this.colorBatch) this.colorBatch = UndoManager.StartBatch(`Set ${tooltip} color`);
- this.colorScript?.script.run({ this: this.Document, self: this.Document, value: value, _readOnly_: false });
+ this.colorScript?.script.run({ this: this.Document, value: value, _readOnly_: false });
}}
setFinalColor={value => {
- this.colorScript?.script.run({ this: this.Document, self: this.Document, value: value, _readOnly_: false });
+ this.colorScript?.script.run({ this: this.Document, value: value, _readOnly_: false });
this.colorBatch?.end();
this.colorBatch = undefined;
}}
@@ -275,7 +250,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
selectedColor={curColor}
type={Type.PRIM}
color={color}
- background={SettingsManager.userBackgroundColor}
+ background={SnappingManager.userBackgroundColor}
icon={this.Icon(color)!}
tooltip={tooltip}
label={this.label}
@@ -286,8 +261,8 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
// Determine the type of toggle button
const tooltip: string = StrCast(this.Document.toolTip);
- const script = ScriptCast(this.Document.onClick);
- const toggleStatus = script ? script.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result : false;
+ // const script = ScriptCast(this.Document.onClick);
+ // const toggleStatus = script ? script.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result : false;
// Colors
const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
const items = DocListCast(this.dataDoc.data);
@@ -296,17 +271,17 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
tooltip={`Toggle ${tooltip}`}
type={Type.PRIM}
color={color}
- background={SettingsManager.userBackgroundColor}
+ background={SnappingManager.userBackgroundColor}
label={this.label}
items={DocListCast(this.dataDoc.data).map(item => ({
icon: <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={StrCast(item.icon) as any} color={color} />,
tooltip: StrCast(item.toolTip),
val: StrCast(item.toolType),
}))}
- selectedVal={StrCast(items.find(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, self: itemDoc, value: undefined, _readOnly_: true }).result)?.toolType)}
+ selectedVal={StrCast(items.find(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, value: undefined, _readOnly_: true }).result)?.toolType)}
setSelectedVal={(val: string | number) => {
const itemDoc = items.find(item => item.toolType === val);
- itemDoc && ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, self: itemDoc, value: val, _readOnly_: false });
+ itemDoc && ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, value: val, _readOnly_: false });
}}
/>
);
@@ -321,10 +296,10 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
const script = ScriptCast(this.Document.onClick);
const double = ScriptCast(this.Document.onDoubleClick);
- const toggleStatus = script?.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result ?? false;
+ const toggleStatus = script?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result ?? false;
// Colors
const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
- const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor);
+ // const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor);
return (
<Toggle
@@ -334,7 +309,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
toggleStatus={toggleStatus}
text={buttonText}
color={color}
- //background={SettingsManager.userBackgroundColor}
+ // background={SnappingManager.userBackgroundColor}
icon={this.Icon(color)!}
label={this.label}
onPointerDown={e =>
@@ -343,10 +318,10 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
e,
returnTrue,
emptyFunction,
- action((e, doubleTap) => {
- (!doubleTap || !double) && script?.script.run({ this: this.Document, self: this.Document, value: !toggleStatus, _readOnly_: false });
- doubleTap && double?.script.run({ this: this.Document, self: this.Document, value: !toggleStatus, _readOnly_: false });
- this._hackToRecompute = this._hackToRecompute + 1;
+ action((clickEv, doubleTap) => {
+ (!doubleTap || !double) && script?.script.run({ this: this.Document, value: !toggleStatus, _readOnly_: false });
+ doubleTap && double?.script.run({ this: this.Document, value: !toggleStatus, _readOnly_: false });
+ this._hackToRecompute += 1;
})
)
}
@@ -359,27 +334,22 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
*/
@computed get defaultButton() {
const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
- const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor);
const tooltip: string = StrCast(this.Document.toolTip);
return <IconButton tooltip={tooltip} icon={this.Icon(color)!} label={this.label} />;
}
@computed get editableText() {
- // Script for running the toggle
const script = ScriptCast(this.Document.script);
- // Function to run the script
- const checkResult = script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result;
-
- const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ this: this.Document, self: this.Document, value, _readOnly_: false }).result;
+ const checkResult = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result;
- return <EditableText editing={false} setEditing={(editing: boolean) => {}} />;
+ const setValue = (value: string): boolean => script?.script.run({ this: this.Document, value, _readOnly_: false }).result;
return (
<div className="menuButton editableText">
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'lock'} />
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon="lock" />
<div style={{ width: 'calc(100% - .875em)', paddingLeft: '4px' }}>
- <EditableView GetValue={() => script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} />
+ <EditableView GetValue={() => script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine contents={checkResult} />
</div>
</div>
);
@@ -388,14 +358,14 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
renderButton = () => {
const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
const tooltip = StrCast(this.Document.toolTip);
- const scriptFunc = () => ScriptCast(this.Document.onClick)?.script.run({ this: this.Document, self: this.Document, _readOnly_: false });
+ const scriptFunc = () => ScriptCast(this.Document.onClick)?.script.run({ this: this.Document, _readOnly_: false });
const btnProps = { tooltip, icon: this.Icon(color)!, label: this.label };
// prettier-ignore
switch (this.type) {
case ButtonType.NumberDropdownButton:
case ButtonType.NumberInlineButton:
case ButtonType.NumberSliderButton: return this.numberDropdown;
- case ButtonType.EditableText: return this.editableText;
+ case ButtonType.EditText: return this.editableText;
case ButtonType.DropdownList: return this.dropdownListButton;
case ButtonType.ColorButton: return this.colorButton;
case ButtonType.MultiToggleButton: return this.multiToggleButton;
@@ -403,9 +373,10 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
case ButtonType.ClickButton:return <IconButton {...btnProps} size={Size.MEDIUM} color={color} />;
case ButtonType.ToolButton: return <IconButton {...btnProps} size={Size.LARGE} color={color} />;
case ButtonType.TextButton: return <Button {...btnProps} color={color}
- background={SettingsManager.userBackgroundColor} text={StrCast(this.dataDoc.buttonText)}/>;
+ background={SnappingManager.userBackgroundColor} text={StrCast(this.dataDoc.buttonText)}/>;
case ButtonType.MenuButton: return <IconButton {...btnProps} color={color}
- background={SettingsManager.userBackgroundColor} size={Size.LARGE} tooltipPlacement='right' onPointerDown={scriptFunc} />;
+ background={SnappingManager.userBackgroundColor} size={Size.LARGE} tooltipPlacement='right' onPointerDown={scriptFunc} />;
+ default:
}
return this.defaultButton;
};
@@ -418,3 +389,8 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.FONTICON, {
+ layout: { view: FontIconBox, dataField: 'icon' },
+ options: { acl: '', defaultDoubleClick: 'ignore', waitForDoubleClickToClick: 'never', layout_hideContextMenu: true, layout_hideLinkButton: true, _width: 40, _height: 40 },
+});
diff --git a/src/client/views/nodes/FontIconBox/TrailsIcon.tsx b/src/client/views/nodes/FontIconBox/TrailsIcon.tsx
index 09fd6e3ae..76f00b2f4 100644
--- a/src/client/views/nodes/FontIconBox/TrailsIcon.tsx
+++ b/src/client/views/nodes/FontIconBox/TrailsIcon.tsx
@@ -1,10 +1,11 @@
import * as React from 'react';
-const TrailsIcon = (fill: string) => (
- <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 1080.000000 1080.000000" preserveAspectRatio="xMidYMid meet">
- <g transform="translate(0.000000,1080.000000) scale(0.100000,-0.100000)" fill={fill} stroke="none">
- <path
- d="M665 9253 c-74 -10 -157 -38 -240 -81 -74 -37 -107 -63 -186 -141
+function TrailsIcon(fill: string) {
+ return (
+ <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 1080.000000 1080.000000" preserveAspectRatio="xMidYMid meet">
+ <g transform="translate(0.000000,1080.000000) scale(0.100000,-0.100000)" fill={fill} stroke="none">
+ <path
+ d="M665 9253 c-74 -10 -157 -38 -240 -81 -74 -37 -107 -63 -186 -141
-104 -104 -156 -191 -201 -334 l-23 -72 0 -3215 c0 -3072 1 -3218 18 -3280 10
-36 39 -108 64 -160 40 -82 59 -107 142 -190 81 -81 111 -103 191 -143 52 -26
122 -55 155 -65 57 -16 322 -17 4775 -20 3250 -2 4736 1 4784 8 256 39 486
@@ -14,68 +15,69 @@ const TrailsIcon = (fill: string) => (
-62 -101 -108 -126 l-42 -22 -4435 -3 c-3954 -2 -4440 0 -4481 13 -26 9 -63
33 -87 56 -79 79 -72 -205 -72 3012 0 2156 3 2889 12 2918 20 70 91 136 168
160 14 4 2010 8 4436 8 3710 1 4418 -1 4456 -13z"
- />
- <path
- d="M7692 7839 c-46 -14 -109 -80 -122 -128 -7 -27 -9 -472 -8 -1443 l3
+ />
+ <path
+ d="M7692 7839 c-46 -14 -109 -80 -122 -128 -7 -27 -9 -472 -8 -1443 l3
-1403 24 -38 c13 -21 42 -50 64 -65 l41 -27 816 0 816 0 41 27 c22 15 51 44
64 65 l24 38 0 1425 0 1425 -24 38 c-13 21 -42 50 -64 65 l-41 27 -800 2
c-488 1 -814 -2 -834 -8z"
- />
- <path
- d="M1982 7699 c-46 -14 -109 -80 -122 -128 -7 -27 -10 -308 -8 -893 l3
+ />
+ <path
+ d="M1982 7699 c-46 -14 -109 -80 -122 -128 -7 -27 -10 -308 -8 -893 l3
-853 24 -38 c13 -21 42 -50 64 -65 l41 -27 1386 0 1386 0 41 27 c22 15 51 44
64 65 l24 38 0 876 0 875 -27 41 c-15 22 -44 51 -65 64 l-38 24 -1370 2 c-847
1 -1383 -2 -1403 -8z"
- />
- <path
- d="M6413 7093 c-13 -2 -23 -9 -23 -15 0 -24 21 -307 26 -343 l5 -40 182
+ />
+ <path
+ d="M6413 7093 c-13 -2 -23 -9 -23 -15 0 -24 21 -307 26 -343 l5 -40 182
-1 c200 -1 307 -15 484 -65 57 -16 107 -29 112 -29 5 0 36 75 69 168 33 92 63
175 67 184 6 14 -10 22 -92 48 -126 39 -308 76 -447 89 -106 11 -337 13 -383
4z"
- />
- <path
- d="M5840 7033 c-63 -8 -238 -29 -388 -47 -150 -18 -274 -35 -276 -37 -2
+ />
+ <path
+ d="M5840 7033 c-63 -8 -238 -29 -388 -47 -150 -18 -274 -35 -276 -37 -2
-2 8 -89 23 -194 22 -163 29 -190 44 -193 10 -2 91 6 180 17 89 12 258 32 376
46 118 14 216 27 218 28 7 8 -43 391 -52 392 -5 1 -62 -4 -125 -12z"
- />
- <path
- d="M4762 4789 c-46 -14 -109 -80 -122 -128 -7 -27 -10 -323 -8 -943 l3
+ />
+ <path
+ d="M4762 4789 c-46 -14 -109 -80 -122 -128 -7 -27 -10 -323 -8 -943 l3
-903 24 -38 c13 -21 42 -50 64 -65 l41 -27 926 0 926 0 41 27 c22 15 51 44 64
65 l24 38 0 926 0 925 -27 41 c-15 22 -44 51 -65 64 l-38 24 -910 2 c-557 1
-923 -2 -943 -8z"
- />
- <path
- d="M8487 4297 c-26 -215 -161 -474 -307 -585 -27 -20 -49 -40 -49 -44
+ />
+ <path
+ d="M8487 4297 c-26 -215 -161 -474 -307 -585 -27 -20 -49 -40 -49 -44
-1 -3 49 -79 110 -167 l110 -161 44 31 c176 126 333 350 418 594 30 86 77 282
77 320 0 8 -57 19 -167 34 -93 13 -182 25 -199 28 -31 5 -31 5 -37 -50z"
- />
- <path
- d="M3965 4233 c-106 -9 -348 -36 -415 -47 -55 -8 -75 -15 -74 -26 1 -20
+ />
+ <path
+ d="M3965 4233 c-106 -9 -348 -36 -415 -47 -55 -8 -75 -15 -74 -26 1 -20
56 -374 59 -377 1 -2 46 4 101 12 159 24 409 45 526 45 l108 0 0 200 0 200
-132 -2 c-73 -1 -151 -3 -173 -5z"
- />
- <path
- d="M3020 4079 c-85 -23 -292 -94 -368 -125 -97 -40 -298 -140 -305 -151
+ />
+ <path
+ d="M3020 4079 c-85 -23 -292 -94 -368 -125 -97 -40 -298 -140 -305 -151
-5 -7 172 -315 192 -336 4 -4 41 10 82 32 103 55 272 123 414 165 66 20 125
38 132 41 11 4 -4 70 -78 348 -10 39 -14 41 -69 26z"
- />
- <path
- d="M6955 3538 c-21 -91 -74 -362 -72 -364 7 -7 260 -44 367 -54 146 -13
+ />
+ <path
+ d="M6955 3538 c-21 -91 -74 -362 -72 -364 7 -7 260 -44 367 -54 146 -13
359 -13 475 0 49 6 90 12 91 13 2 1 -12 90 -29 197 -26 155 -36 194 -47 192
-8 -2 -85 -6 -170 -9 -160 -6 -357 7 -505 33 -103 18 -104 18 -110 -8z"
- />
- <path
- d="M1993 3513 c-52 -67 -71 -106 -98 -198 -35 -122 -44 -284 -21 -415 9
+ />
+ <path
+ d="M1993 3513 c-52 -67 -71 -106 -98 -198 -35 -122 -44 -284 -21 -415 9
-51 18 -96 21 -98 4 -5 360 79 375 88 7 4 7 24 0 60 -21 109 -7 244 31 307
l20 31 -146 131 c-80 72 -147 131 -149 131 -2 0 -17 -17 -33 -37z"
- />
- <path
- d="M2210 2519 c-91 -50 -166 -92 -168 -94 -2 -1 11 -26 28 -54 l32 -51
+ />
+ <path
+ d="M2210 2519 c-91 -50 -166 -92 -168 -94 -2 -1 11 -26 28 -54 l32 -51
244 0 c134 0 244 2 244 5 0 3 -23 33 -51 67 -28 35 -72 98 -97 140 -26 43 -51
77 -57 77 -5 0 -84 -41 -175 -90z"
- />
- </g>
- </svg>
-);
+ />
+ </g>
+ </svg>
+ );
+}
export default TrailsIcon;
diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx
index 2e7a2120e..3d1bd7563 100644
--- a/src/client/views/nodes/FunctionPlotBox.tsx
+++ b/src/client/views/nodes/FunctionPlotBox.tsx
@@ -7,12 +7,14 @@ import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { Cast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
+import { DocUtils } from '../../documents/DocUtils';
+import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { undoBatch } from '../../util/UndoManager';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { PinDocView, PinProps } from '../PinFuncs';
import { FieldView, FieldViewProps } from './FieldView';
-import { PinProps, PresBox } from './trails';
@observer
export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@@ -33,23 +35,38 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>
componentDidMount() {
this._props.setContentViewBox?.(this);
reaction(
- () => [DocListCast(this.dataDoc[this.fieldKey]).map(doc => doc?.text), this.layoutDoc.width, this.layoutDoc.height, this.layoutDoc.xRange, this.layoutDoc.yRange],
+ () => [this.graphFuncs, this.layoutDoc.width, this.layoutDoc.height, this.layoutDoc.xRange, this.layoutDoc.yRange],
() => this.createGraph()
);
}
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
const anchor = Docs.Create.ConfigDocument({ annotationOn: this.Document });
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), datarange: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), datarange: true } }, this.Document);
anchor.config_xRange = new List<number>(Array.from(this._plot.options.xAxis.domain));
anchor.config_yRange = new List<number>(Array.from(this._plot.options.yAxis.domain));
if (addAsAnnotation) this.addDocument(anchor);
return anchor;
};
+ @computed get graphFuncs() {
+ const links = Doc.Links(this.Document)
+ .map(d => Doc.getOppositeAnchor(d, this.Document))
+ .filter(d => d)
+ .map(d => d!);
+ const funcs = links.concat(DocListCast(this.dataDoc[this.fieldKey])).map(doc =>
+ StrCast(doc.text, 'x^2')
+ .replace(/\\sqrt/g, 'sqrt')
+ .replace(/\\frac\{(.*)\}\{(.*)\}/g, '($1/$2)')
+ .replace(/\\left/g, '')
+ .replace(/\\right/g, '')
+ .replace(/\{/g, '')
+ .replace(/\}/g, '')
+ );
+ return funcs;
+ }
createGraph = (ele?: HTMLDivElement) => {
this._plotEle = ele || this._plotEle;
const width = this._props.PanelWidth();
const height = this._props.PanelHeight();
- const fns = DocListCast(this.dataDoc.data).map(doc => StrCast(doc.text, 'x^2').replace(/\\frac\{(.*)\}\{(.*)\}/, '($1/$2)'));
try {
this._plotEle.children.length && this._plotEle.removeChild(this._plotEle.children[0]);
this._plot = functionPlot({
@@ -59,7 +76,7 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>
xAxis: { domain: Cast(this.layoutDoc.xRange, listSpec('number'), [-10, 10]) },
yAxis: { domain: Cast(this.layoutDoc.yRange, listSpec('number'), [-1, 9]) },
grid: true,
- data: fns.map(fn => ({
+ data: this.graphFuncs.map(fn => ({
fn,
// derivative: { fn: "2 * x", updateOnMouseMove: true }
})),
@@ -72,7 +89,14 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>
@undoBatch
drop = (e: Event, de: DragManager.DropEvent) => {
if (de.complete.docDragData?.droppedDocuments.length) {
- const added = de.complete.docDragData.droppedDocuments.reduce((res, doc) => res && Doc.AddDocToList(this.dataDoc, this._props.fieldKey, doc), true);
+ const added = de.complete.docDragData.droppedDocuments.reduce((res, doc) => {
+ // const ret = res && Doc.AddDocToList(this.dataDoc, this._props.fieldKey, doc);
+ if (res) {
+ const link = DocUtils.MakeLink(doc, this.Document, { link_relationship: 'function', link_description: 'input' });
+ link && this._props.addDocument?.(link);
+ }
+ return res;
+ }, true);
!added && e.preventDefault();
e.stopPropagation(); // prevent parent Doc from registering new position so that it snaps back into place
return added;
@@ -104,7 +128,7 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>
{this.theGraph}
<div
style={{
- display: this._props.isSelected() ? 'none' : undefined,
+ display: this._props.isContentActive() ? 'none' : undefined,
position: 'absolute',
width: '100%',
height: '100%',
@@ -115,3 +139,8 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.FUNCPLOT, {
+ layout: { view: FunctionPlotBox, dataField: 'data' },
+ options: { acl: '', _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true },
+});
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 251235b93..e4b3a1b9b 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -1,51 +1,69 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
+import { Colors } from 'browndash-components';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { extname } from 'path';
import * as React from 'react';
+import { ClientUtils, DashColor, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents } from '../../../ClientUtils';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { ObjectField } from '../../../fields/ObjectField';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { DashColor, emptyFunction, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { emptyFunction } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
-import { DocumentManager } from '../../util/DocumentManager';
+import { DocUtils } from '../../documents/DocUtils';
+import { Networking } from '../../Network';
import { DragManager } from '../../util/DragManager';
import { undoBatch } from '../../util/UndoManager';
-import { ContextMenu } from '../../views/ContextMenu';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
+import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
+import { OverlayView } from '../OverlayView';
import { AnchorMenu } from '../pdf/AnchorMenu';
-import { StyleProp } from '../StyleProvider';
-import { OpenWhere } from './DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView';
+import { PinDocView, PinProps } from '../PinFuncs';
+import { StyleProp } from '../StyleProp';
+import { DocumentView } from './DocumentView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import './ImageBox.scss';
-import { PinProps, PresBox } from './trails';
+import { OpenWhere } from './OpenWhere';
+export class ImageEditorData {
+ // eslint-disable-next-line no-use-before-define
+ private static _instance: ImageEditorData;
+ private static get imageData() { return (ImageEditorData._instance ?? new ImageEditorData()).imageData; } // prettier-ignore
+ @observable imageData: { rootDoc: Doc | undefined; open: boolean; source: string; addDoc: Opt<(doc: Doc | Doc[], annotationKey?: string) => boolean> } = observable({ rootDoc: undefined, open: false, source: '', addDoc: undefined });
+ @action private static set = (open: boolean, rootDoc: Doc | undefined, source: string, addDoc: Opt<(doc: Doc | Doc[], annotationKey?: string) => boolean>) => {
+ this._instance.imageData = { open, rootDoc, source, addDoc };
+ };
+
+ constructor() {
+ makeObservable(this);
+ ImageEditorData._instance = this;
+ }
+
+ public static get Open() { return ImageEditorData.imageData.open; } // prettier-ignore
+ public static set Open(open: boolean) { ImageEditorData.set(open, this.imageData.rootDoc, this.imageData.source, this.imageData.addDoc); } // prettier-ignore
+ public static get Source() { return ImageEditorData.imageData.source; } // prettier-ignore
+ public static set Source(source: string) { ImageEditorData.set(this.imageData.open, this.imageData.rootDoc, source, this.imageData.addDoc); } // prettier-ignore
+ public static get RootDoc() { return ImageEditorData.imageData.rootDoc; } // prettier-ignore
+ public static set RootDoc(rootDoc: Opt<Doc>) { ImageEditorData.set(this.imageData.open, rootDoc, this.imageData.source, this.imageData.addDoc); } // prettier-ignore
+ public static get AddDoc() { return ImageEditorData.imageData.addDoc; } // prettier-ignore
+ public static set AddDoc(addDoc: Opt<(doc: Doc | Doc[], annotationKey?: string) => boolean>) { ImageEditorData.set(this.imageData.open, this.imageData.rootDoc, this.imageData.source, addDoc); } // prettier-ignore
+}
@observer
-export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(ImageBox, fieldKey);
}
-
- @observable public static imageRootDoc: Doc | undefined = undefined;
- @observable public static imageEditorOpen: boolean = false;
- @observable public static imageEditorSource: string = '';
- @observable public static addDoc: ((doc: Doc | Doc[], annotationKey?: string) => boolean) | undefined = undefined;
- @action public static setImageEditorOpen(open: boolean) {
- ImageBox.imageEditorOpen = open;
- }
- @action public static setImageEditorSource(source: string) {
- ImageBox.imageEditorSource = source;
- }
private _ignoreScroll = false;
private _forcedScroll = false;
private _dropDisposer?: DragManager.DragDropDisposer;
@@ -53,7 +71,13 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
private _getAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
private _overlayIconRef = React.createRef<HTMLDivElement>();
private _marqueeref = React.createRef<MarqueeAnnotator>();
+ private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
+ private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
+ @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
@observable _curSuffix = '';
+ @observable _error = '';
+ @observable _isHovering = false; // flag to switch between primary and alternate images on hover
+ _ffref = React.createRef<CollectionFreeFormView>();
constructor(props: FieldViewProps) {
super(props);
@@ -80,7 +104,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
if (anchor) {
if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
addAsAnnotation && this.addDocument(anchor);
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: visibleAnchor ? false : true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: !visibleAnchor } }, this.Document);
return anchor;
}
return this.Document;
@@ -93,10 +117,12 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
scrSize: (this.ScreenToLocalBoxXf().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight)[0] / this.nativeSize.nativeWidth) * NumCast(this.layoutDoc._freeform_scale, 1),
selected: this._props.isSelected(),
}),
- ({ forceFull, scrSize, selected }) => (this._curSuffix = selected ? '_o' : this.fieldKey === 'icon' ? '_m' : forceFull ? '_o' : scrSize < 0.25 ? '_s' : scrSize < 0.5 ? '_m' : scrSize < 0.8 ? '_l' : '_o'),
+ ({ forceFull, scrSize, selected }) => {
+ this._curSuffix = selected ? '_o' : this.fieldKey === 'icon' ? '_m' : forceFull ? '_o' : scrSize < 0.25 ? '_s' : scrSize < 0.5 ? '_m' : scrSize < 0.8 ? '_l' : '_o';
+ },
{ fireImmediately: true, delay: 1000 }
);
- const layoutDoc = this.layoutDoc;
+ const { layoutDoc } = this;
this._disposers.path = reaction(
() => ({ nativeSize: this.nativeSize, width: NumCast(this.layoutDoc._width) }),
({ nativeSize, width }) => {
@@ -108,10 +134,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
);
this._disposers.scroll = reaction(
() => this.layoutDoc.layout_scrollTop,
- s_top => {
+ sTop => {
this._forcedScroll = true;
- !this._ignoreScroll && this._mainCont.current && (this._mainCont.current.scrollTop = NumCast(s_top));
- this._mainCont.current?.scrollTo({ top: NumCast(s_top) });
+ !this._ignoreScroll && this._mainCont.current && (this._mainCont.current.scrollTop = NumCast(sTop));
+ this._mainCont.current?.scrollTo({ top: NumCast(sTop) });
this._forcedScroll = false;
},
{ fireImmediately: true }
@@ -125,7 +151,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
@undoBatch
drop = (e: Event, de: DragManager.DropEvent) => {
if (de.complete.docDragData) {
- let added: boolean | undefined = undefined;
+ let added: boolean | undefined;
const targetIsBullseye = (ele: HTMLElement): boolean => {
if (!ele) return false;
if (ele === this._overlayIconRef.current) return true;
@@ -134,7 +160,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
if (de.metaKey || targetIsBullseye(e.target as HTMLElement)) {
added = de.complete.docDragData.droppedDocuments.reduce((last: boolean, drop: Doc) => {
this.layoutDoc[this.fieldKey + '_usePath'] = 'alternate:hover';
- return last && Doc.AddDocToList(this.dataDoc, this.fieldKey + '-alternates', drop);
+ return last && Doc.AddDocToList(this.dataDoc, this.fieldKey + '_alternates', drop);
}, true);
} else if (de.altKey || !this.dataDoc[this.fieldKey]) {
const layoutDoc = de.complete.docDragData?.draggedDocuments[0];
@@ -155,21 +181,22 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
};
@undoBatch
- resolution = () => (this.layoutDoc._showFullRes = !this.layoutDoc._showFullRes);
+ resolution = () => {
+ this.layoutDoc._showFullRes = !this.layoutDoc._showFullRes;
+ };
@undoBatch
setNativeSize = action(() => {
- const scaling = (this.DocumentView?.().screenToViewTransform().Scale || 1) / NumCast(this.layoutDoc._freeform_scale, 1);
- const nscale = NumCast(this._props.PanelWidth()) / scaling;
+ const nscale = NumCast(this._props.PanelWidth()) * NumCast(this.layoutDoc._freeform_scale, 1);
const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']);
this.dataDoc[this.fieldKey + '_nativeHeight'] = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']) * nw;
this.dataDoc[this.fieldKey + '_nativeWidth'] = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']) * nw;
- this.layoutDoc._freeform_panX = nw * NumCast(this.layoutDoc._freeform_panX);
- this.layoutDoc._freeform_panY = nw * NumCast(this.layoutDoc._freeform_panY);
- this.dataDoc._freeform_panXMax = this.dataDoc._freeform_panXMax ? nw * NumCast(this.dataDoc._freeform_panXMax) : undefined;
- this.dataDoc._freeform_panXMin = this.dataDoc._freeform_panXMin ? nw * NumCast(this.dataDoc._freeform_panXMin) : undefined;
- this.dataDoc._freeform_panYMax = this.dataDoc._freeform_panYMax ? nw * NumCast(this.dataDoc._freeform_panYMax) : undefined;
- this.dataDoc._freeform_panYMin = this.dataDoc._freeform_panYMin ? nw * NumCast(this.dataDoc._freeform_panYMin) : undefined;
+ this.dataDoc._freeform_panX = nw * NumCast(this.dataDoc._freeform_panX);
+ this.dataDoc._freeform_panY = nw * NumCast(this.dataDoc._freeform_panY);
+ this.dataDoc._freeform_panX_max = this.dataDoc._freeform_panX_max ? nw * NumCast(this.dataDoc._freeform_panX_max) : undefined;
+ this.dataDoc._freeform_panX_min = this.dataDoc._freeform_panX_min ? nw * NumCast(this.dataDoc._freeform_panX_min) : undefined;
+ this.dataDoc._freeform_panY_max = this.dataDoc._freeform_panY_max ? nw * NumCast(this.dataDoc._freeform_panY_max) : undefined;
+ this.dataDoc._freeform_panY_min = this.dataDoc._freeform_panY_min ? nw * NumCast(this.dataDoc._freeform_panY_min) : undefined;
});
@undoBatch
rotate = action(() => {
@@ -177,7 +204,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
const nh = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']);
const w = this.layoutDoc._width;
const h = this.layoutDoc._height;
- this.dataDoc[this.fieldKey + '-rotation'] = (NumCast(this.dataDoc[this.fieldKey + '-rotation']) + 90) % 360;
+ this.dataDoc[this.fieldKey + '_rotation'] = (NumCast(this.dataDoc[this.fieldKey + '_rotation']) + 90) % 360;
this.dataDoc[this.fieldKey + '_nativeWidth'] = nh;
this.dataDoc[this.fieldKey + '_nativeHeight'] = nw;
this.layoutDoc._width = h;
@@ -185,7 +212,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
});
crop = (region: Doc | undefined, addCrop?: boolean) => {
- if (!region) return;
+ if (!region) return undefined;
const cropping = Doc.MakeCopy(region, true);
const regionData = region[DocData];
regionData.lockedPosition = true;
@@ -211,8 +238,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
croppingProto.type = DocumentType.IMG;
croppingProto.layout = ImageBox.LayoutString('data');
croppingProto.data = ObjectField.MakeCopy(this.dataDoc[this.fieldKey] as ObjectField);
- croppingProto['data_nativeWidth'] = anchw;
- croppingProto['data_nativeHeight'] = anchh;
+ croppingProto.data_nativeWidth = anchw;
+ croppingProto.data_nativeHeight = anchh;
croppingProto.freeform_scale = viewScale;
croppingProto.freeform_scale_min = viewScale;
croppingProto.freeform_panX = anchx / viewScale;
@@ -227,26 +254,26 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
cropping.y = NumCast(this.Document.y);
this._props.addDocTab(cropping, OpenWhere.inParent);
}
- DocumentManager.Instance.AddViewRenderedCb(cropping, dv => setTimeout(() => (dv.ComponentView as ImageBox).setNativeSize(), 200));
+ DocumentView.addViewRenderedCb(cropping, dv => setTimeout(() => (dv.ComponentView as ImageBox).setNativeSize(), 200));
this._props.bringToFront?.(cropping);
return cropping;
};
- specificContextMenu = (e: React.MouseEvent): void => {
+ specificContextMenu = (): void => {
const field = Cast(this.dataDoc[this.fieldKey], ImageField);
if (field) {
const funcs: ContextMenuProps[] = [];
funcs.push({ description: 'Rotate Clockwise 90', event: this.rotate, icon: 'redo-alt' });
funcs.push({ description: `Show ${this.layoutDoc._showFullRes ? 'Dynamic Res' : 'Full Res'}`, event: this.resolution, icon: 'expand' });
funcs.push({ description: 'Set Native Pixel Size', event: this.setNativeSize, icon: 'expand-arrows-alt' });
- funcs.push({ description: 'Copy path', event: () => Utils.CopyText(this.choosePath(field.url)), icon: 'copy' });
+ funcs.push({ description: 'Copy path', event: () => ClientUtils.CopyText(this.choosePath(field.url)), icon: 'copy' });
funcs.push({
description: 'Open Image Editor',
event: action(() => {
- ImageBox.setImageEditorOpen(true);
- ImageBox.setImageEditorSource(this.choosePath(field.url));
- ImageBox.addDoc = this._props.addDocument;
- ImageBox.imageRootDoc = this.Document;
+ ImageEditorData.Open = true;
+ ImageEditorData.Source = this.choosePath(field.url);
+ ImageEditorData.AddDoc = this._props.addDocument;
+ ImageEditorData.RootDoc = this.Document;
}),
icon: 'pencil-alt',
});
@@ -254,23 +281,23 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
}
};
- choosePath(url: URL) {
+ choosePath = (url: URL) => {
if (!url?.href) return '';
const lower = url.href.toLowerCase();
if (url.protocol === 'data') return url.href;
- if (url.href.indexOf(window.location.origin) === -1 && url.href.indexOf('dashblobstore') === -1) return Utils.CorsProxy(url.href);
- if (!/\.(png|jpg|jpeg|gif|webp)$/.test(lower)) return `/assets/unknown-file-icon-hi.png`;
+ if (url.href.indexOf(window.location.origin) === -1 && url.href.indexOf('dashblobstore') === -1) return ClientUtils.CorsProxy(url.href);
+ if (!/\.(png|jpg|jpeg|gif|webp)$/.test(lower) || lower.endsWith('/assets/unknown-file-icon-hi.png')) return `/assets/unknown-file-icon-hi.png`;
const ext = extname(url.href);
return url.href.replace(ext, (this._error ? '_o' : this._curSuffix) + ext);
- }
- getScrollHeight = () => (this._props.layout_fitWidth?.(this.Document) !== false && NumCast(this.layoutDoc._freeform_scale, 1) === NumCast(this.dataDoc._freeform_scaleMin, 1) ? this.nativeSize.nativeHeight : undefined);
+ };
+ getScrollHeight = () => (this._props.fitWidth?.(this.Document) !== false && NumCast(this.layoutDoc._freeform_scale, 1) === NumCast(this.dataDoc._freeform_scaleMin, 1) ? this.nativeSize.nativeHeight : undefined);
@computed get nativeSize() {
TraceMobx();
const nativeWidth = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth'], 500));
const nativeHeight = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], NumCast(this.layoutDoc[this.fieldKey + '_nativeHeight'], 500));
- const nativeOrientation = NumCast(this.dataDoc[this.fieldKey + '-nativeOrientation'], 1);
+ const nativeOrientation = NumCast(this.dataDoc[this.fieldKey + '_nativeOrientation'], 1);
return { nativeWidth, nativeHeight, nativeOrientation };
}
@computed get overlayImageIcon() {
@@ -295,15 +322,19 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
<div
className="imageBox-alternateDropTarget"
ref={this._overlayIconRef}
- onPointerDown={e => setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, e => (this.layoutDoc[`_${this.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined))}
+ onPointerDown={e =>
+ setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, () => {
+ this.layoutDoc[`_${this.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined;
+ })
+ }
style={{
- display: (this._props.isContentActive() !== false && DragManager.DocDragData?.canEmbed) || DocListCast(this.dataDoc[this.fieldKey + '-alternates']).length ? 'block' : 'none',
+ display: (this._props.isContentActive() !== false && DragManager.DocDragData?.canEmbed) || this.dataDoc[this.fieldKey + '_alternates'] ? 'block' : 'none',
width: 'min(10%, 25px)',
height: 'min(10%, 25px)',
background: usePath === undefined ? 'white' : usePath === 'alternate' ? 'black' : 'gray',
color: usePath === undefined ? 'black' : 'white',
}}>
- <FontAwesomeIcon icon="turn-up" size="lg" />
+ <FontAwesomeIcon icon="circle-half-stroke" size="lg" />
</div>
</Tooltip>
);
@@ -311,27 +342,26 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
@computed get paths() {
const field = Cast(this.dataDoc[this.fieldKey], ImageField, null); // retrieve the primary image URL that is being rendered from the data doc
- const alts = DocListCast(this.dataDoc[this.fieldKey + '-alternates']); // retrieve alternate documents that may be rendered as alternate images
- const altpaths = alts
- .map(doc => Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url)
- .filter(url => url)
- .map(url => this.choosePath(url)); // access the primary layout data of the alternate documents
+ const alts = DocListCast(this.dataDoc[this.fieldKey + '_alternates']); // retrieve alternate documents that may be rendered as alternate images
+ 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))
+ .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;
- return paths.length ? paths : [Utils.CorsProxy('https://cs.brown.edu/~bcz/noImage.png')];
+ return paths.length ? paths : [defaultUrl.href];
}
- @observable _error = '';
-
- @observable _isHovering = false; // flag to switch between primary and alternate images on hover
@computed get content() {
TraceMobx();
- const backColor = DashColor(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor));
+ const backColor = DashColor(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) ?? 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();
- const { nativeWidth, nativeHeight, nativeOrientation } = this.nativeSize;
- const rotation = NumCast(this.dataDoc[this.fieldKey + '-rotation']);
+ const { nativeWidth, nativeHeight /* , nativeOrientation */ } = this.nativeSize;
+ const rotation = NumCast(this.dataDoc[this.fieldKey + '_rotation']);
const aspect = rotation % 180 ? nativeHeight / nativeWidth : 1;
let transformOrigin = 'center center';
let transform = `translate(0%, 0%) rotate(${rotation}deg) scale(${aspect})`;
@@ -347,12 +377,32 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
const usePath = this.layoutDoc[`_${this.fieldKey}_usePath`];
return (
- <div className="imageBox-cont" onPointerEnter={action(() => (this._isHovering = true))} onPointerLeave={action(() => (this._isHovering = false))} key={this.layoutDoc[Id]} ref={this.createDropTarget} onPointerDown={this.marqueeDown}>
+ <div
+ className="imageBox-cont"
+ onPointerEnter={action(() => {
+ this._isHovering = true;
+ })}
+ onPointerLeave={action(() => {
+ this._isHovering = false;
+ })}
+ key={this.layoutDoc[Id]}
+ ref={this.createDropTarget}
+ onPointerDown={this.marqueeDown}>
<div className="imageBox-fader" style={{ opacity: backAlpha }}>
- <img key="paths" src={srcpath} style={{ transform, transformOrigin }} onError={action(e => (this._error = e.toString()))} draggable={false} width={nativeWidth} />
+ <img
+ alt=""
+ key="paths"
+ src={srcpath}
+ style={{ transform, transformOrigin }}
+ onError={action(e => {
+ this._error = e.toString();
+ })}
+ draggable={false}
+ width={nativeWidth}
+ />
{fadepath === srcpath ? null : (
<div className={`imageBox-fadeBlocker${(this._isHovering && usePath === 'alternate:hover') || usePath === 'alternate' ? '-hover' : ''}`} style={{ transition: StrCast(this.layoutDoc.viewTransition, 'opacity 1000ms') }}>
- <img className="imageBox-fadeaway" key="fadeaway" src={fadepath} style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} />
+ <img alt="" className="imageBox-fadeaway" key="fadeaway" src={fadepath} style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} />
</div>
)}
</div>
@@ -361,22 +411,27 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
);
}
- private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
- private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
- @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
@computed get annotationLayer() {
TraceMobx();
return <div className="imageBox-annotationLayer" style={{ height: this._props.PanelHeight() }} ref={this._annotationLayer} />;
}
screenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop) * this.ScreenToLocalBoxXf().Scale);
marqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._freeform_scale, 1) <= NumCast(this.dataDoc.freeform_scaleMin, 1) && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
+ if (!this.dataDoc[this.fieldKey]) {
+ this.chooseImage();
+ } else if (
+ !e.altKey &&
+ e.button === 0 &&
+ NumCast(this.layoutDoc._freeform_scale, 1) <= NumCast(this.dataDoc.freeform_scaleMin, 1) &&
+ this._props.isContentActive() &&
+ ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)
+ ) {
setupMoveUpEvents(
this,
e,
- action(e => {
+ action(moveEv => {
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
- this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]);
+ this._marqueeref.current?.onInitiateSelection([moveEv.clientX, moveEv.clientY]);
return true;
}),
returnFalse,
@@ -393,7 +448,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
};
focus = (anchor: Doc, options: FocusViewOptions) => (anchor.type === DocumentType.CONFIG ? undefined : this._ffref.current?.focus(anchor, options));
- _ffref = React.createRef<CollectionFreeFormView>();
savedAnnotations = () => this._savedAnnotations;
render() {
TraceMobx();
@@ -404,7 +458,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
className="imageBox"
onContextMenu={this.specificContextMenu}
ref={this._mainCont}
- onScroll={action(e => {
+ onScroll={action(() => {
if (!this._forcedScroll) {
if (this.layoutDoc._layout_scrollTop || this._mainCont.current?.scrollTop) {
this._ignoreScroll = true;
@@ -418,10 +472,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
height: this._props.PanelWidth() ? undefined : `100%`,
pointerEvents: this.layoutDoc._lockedPosition ? 'none' : undefined,
borderRadius,
- overflow: this.layoutDoc.layout_fitWidth || this._props.layout_fitWidth?.(this.Document) ? 'auto' : undefined,
+ overflow: this.layoutDoc.layout_fitWidth || this._props.fitWidth?.(this.Document) ? 'auto' : undefined,
}}>
<CollectionFreeFormView
ref={this._ffref}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setContentViewBox={emptyFunction}
NativeWidth={returnZero}
@@ -429,8 +484,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
renderDepth={this._props.renderDepth + 1}
fieldKey={this.annotationKey}
styleProvider={this._props.styleProvider}
- isAnnotationOverlay={true}
- annotationLayerHostsContent={true}
+ isAnnotationOverlay
+ annotationLayerHostsContent
PanelWidth={this._props.PanelWidth}
PanelHeight={this._props.PanelHeight}
ScreenToLocalTransform={this.screenToLocalTransform}
@@ -461,11 +516,40 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
selectionText={returnEmptyString}
annotationLayer={this._annotationLayer.current}
marqueeContainer={this._mainCont.current}
- highlightDragSrcColor={''}
+ highlightDragSrcColor=""
anchorMenuCrop={this.crop}
/>
)}
</div>
);
}
+
+ public chooseImage = () => {
+ const input = document.createElement('input');
+ input.type = 'file';
+ input.multiple = true;
+ input.accept = 'image/*';
+ input.onchange = async () => {
+ const file = input.files?.[0];
+ if (file) {
+ const disposer = OverlayView.ShowSpinner();
+ const [{ result }] = await Networking.UploadFilesToServer({ file });
+ if (result instanceof Error) {
+ alert('Error uploading files - possibly due to unsupported file types');
+ } else {
+ this.dataDoc[this.fieldKey] = new ImageField(result.accessPaths.agnostic.client);
+ !(result instanceof Error) && DocUtils.assignImageInfo(result, this.dataDoc);
+ }
+ disposer();
+ } else {
+ console.log('No file selected');
+ }
+ };
+ input.click();
+ };
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.IMG, {
+ layout: { view: ImageBox, dataField: 'data' },
+ options: { acl: '', freeform: '', systemIcon: 'BsFileEarmarkImageFill' },
+});
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 89a5ac0b8..66e210c03 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -1,26 +1,28 @@
+/* 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';
-import { returnAlways, returnTrue } from '../../../Utils';
-import { Doc, Field, FieldResult } from '../../../fields/Doc';
+import { returnAlways, returnTrue } from '../../../ClientUtils';
+import { Doc, Field, FieldResult, FieldType } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { RichTextField } from '../../../fields/RichTextField';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { DocCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
+import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
import { SetupDrag } from '../../util/DragManager';
-import { CompileScript, CompiledScript, ScriptOptions } from '../../util/Scripting';
-import { undoBatch } from '../../util/UndoManager';
+import { CompiledScript } from '../../util/Scripting';
+import { undoable } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ObservableReactComponent } from '../ObservableReactComponent';
+import { ViewBoxBaseComponent } from '../DocComponent';
import { DocumentIconContainer } from './DocumentIcon';
-import { OpenWhere } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { ImageBox } from './ImageBox';
import './KeyValueBox.scss';
import { KeyValuePair } from './KeyValuePair';
+import { OpenWhere } from './OpenWhere';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
export type KVPScript = {
@@ -29,7 +31,7 @@ export type KVPScript = {
onDelegate: boolean;
};
@observer
-export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
+export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
public static LayoutString() {
return FieldView.LayoutString(KeyValueBox, 'data');
}
@@ -46,16 +48,16 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
componentDidMount() {
this._props.setContentViewBox?.(this);
}
- isKeyValueBox = returnTrue;
- able = returnAlways;
- layout_fitWidth = returnTrue;
- onClickScriptDisable = returnAlways;
+ // ViewBoxInterface overrides
+ override isUnstyledView = returnTrue; // used by style provider via ViewBoxInterface - ignore opacity, anim effects, titles
+ override dontRegisterView = returnTrue; // don't want to follow links to this view
+ override onClickScriptDisable = returnAlways;
@observable private rows: KeyValuePair[] = [];
@observable _splitPercentage = 50;
get fieldDocToLayout() {
- return this._props.fieldKey ? DocCast(this._props.Document[this._props.fieldKey], DocCast(this._props.Document)) : this._props.Document;
+ return DocCast(this.Document);
}
@action
@@ -71,47 +73,65 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
}
}
};
- public static CompileKVPScript(value: string): KVPScript | undefined {
- const eq = value.startsWith('=');
- value = eq ? value.substring(1) : value;
- const dubEq = value.startsWith(':=') ? 'computed' : value.startsWith('$=') ? 'script' : false;
- value = dubEq ? value.substring(2) : value;
- const options: ScriptOptions = { addReturn: true, typecheck: false, params: { this: Doc.name, self: Doc.name, documentView: 'any', _last_: 'any', _readOnly_: 'boolean' }, editable: true };
- if (dubEq) options.typecheck = false;
- const script = CompileScript(value, { ...options, transformer: DocumentIconContainer.getTransformer() });
- return !script.compiled ? undefined : { script, type: dubEq, onDelegate: eq };
- }
+ /**
+ * this compiles a string as a script after parsing off initial characters that determine script parameters
+ * if the script starts with '=', then it will be stored on the delegate of the Doc, otherise on the data doc
+ * if the script then starts with a ':=', then it will be treated as ComputedField,
+ * '$=', then it will just be a Script
+ * @param value
+ * @returns
+ */
+ public static CompileKVPScript = (rawvalueIn: string): KVPScript | undefined => {
+ let rawvalue = rawvalueIn;
+ const onDelegate = rawvalue.startsWith('=');
+ rawvalue = onDelegate ? rawvalue.substring(1) : rawvalue;
+ 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 + '`';
- public static ApplyKVPScript(doc: Doc, key: string, kvpScript: KVPScript, forceOnDelegate?: boolean): boolean {
+ let script = ScriptField.CompileScript(rawvalue, {}, true, undefined, DocumentIconContainer.getTransformer());
+ if (!script.compiled) {
+ script = ScriptField.CompileScript(value, {}, true, undefined, DocumentIconContainer.getTransformer());
+ }
+ return !script.compiled ? undefined : { script, type, onDelegate };
+ };
+
+ public static ApplyKVPScript = (doc: Doc, key: string, kvpScript: KVPScript, forceOnDelegate?: boolean, setResult?: (value: FieldResult) => void) => {
const { script, type, onDelegate } = kvpScript;
- //const target = onDelegate ? Doc.Layout(doc.layout) : Doc.GetProto(doc); // bcz: TODO need to be able to set fields on layout templates
+ // const target = onDelegate ? Doc.Layout(doc.layout) : Doc.GetProto(doc); // bcz: TODO need to be able to set fields on layout templates
const target = forceOnDelegate || onDelegate || key.startsWith('_') ? doc : DocCast(doc.proto, doc);
- let field: Field;
- if (type === 'computed') {
- field = new ComputedField(script);
- } else if (type === 'script') {
- field = new ScriptField(script);
- } else {
- const res = script.run({ this: Doc.Layout(doc), self: doc }, console.log);
- if (!res.success) {
- target[key] = script.originalScript;
- return true;
+ let field: FieldType | undefined;
+ switch (type) {
+ case 'computed': field = new ComputedField(script); break; // prettier-ignore
+ case 'script': field = new ScriptField(script); break; // prettier-ignore
+ default: {
+ const _setCacheResult_ = (value: FieldResult) => {
+ field = value as FieldType;
+ if (setResult) setResult?.(value);
+ else target[key] = field;
+ };
+ const res = script.run({ this: Doc.Layout(doc), _setCacheResult_ }, console.log);
+ if (!res.success) {
+ if (key) target[key] = script.originalScript;
+ return false;
+ }
+ field === undefined && (field = res.result instanceof Array ? new List<any>(res.result) : res.result);
}
- field = res.result;
}
+ if (!key) return false;
if (Field.IsField(field, true) && (key !== 'proto' || field !== target)) {
target[key] = field;
return true;
}
return false;
- }
+ };
- @undoBatch
- public static SetField(doc: Doc, key: string, value: string, forceOnDelegate?: boolean) {
- const script = this.CompileKVPScript(value);
+ public static SetField = undoable((doc: Doc, key: string, value: string, forceOnDelegate?: boolean, setResult?: (value: FieldResult) => void) => {
+ const script = KeyValueBox.CompileKVPScript(value);
if (!script) return false;
- return this.ApplyKVPScript(doc, key, script, forceOnDelegate);
- }
+ return KeyValueBox.ApplyKVPScript(doc, key, script, forceOnDelegate, setResult);
+ }, 'Set Doc Field');
onPointerDown = (e: React.PointerEvent): void => {
if (e.buttons === 1 && this._props.isSelected()) {
@@ -135,20 +155,20 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
const ids: { [key: string]: string } = {};
const protos = Doc.GetAllPrototypes(doc);
- for (const proto of protos) {
+ protos.forEach(proto => {
Object.keys(proto).forEach(key => {
if (!(key in ids) && realDoc[key] !== ComputedField.undefined) {
ids[key] = key;
}
});
- }
+ });
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()]) {
- for (const key of keys.sort((a: string, b: string) => {
+ // 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) => {
const a_ = a.split('_')[0];
const b_ = b.split('_')[0];
if (a_ < b_) return -1;
@@ -156,7 +176,8 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
if (a === a_) return -1;
if (b === b_) return 1;
return a === b ? 0 : a < b ? -1 : 1;
- })) {
+ });
+ sortedKeys.forEach(key => {
rows.push(
<KeyValuePair
doc={realDoc}
@@ -177,7 +198,7 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
keyName={key}
/>
);
- }
+ });
return rows;
}
@computed get newKeyValue() {
@@ -211,7 +232,7 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
this._splitPercentage = Math.max(0, 100 - Math.round(((e.clientX - nativeWidth.left) / nativeWidth.width) * 100));
};
@action
- onDividerUp = (e: PointerEvent): void => {
+ onDividerUp = (): void => {
document.removeEventListener('pointermove', this.onDividerMove);
document.removeEventListener('pointerup', this.onDividerUp);
};
@@ -225,35 +246,36 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
getFieldView = () => {
const rows = this.rows.filter(row => row.isChecked);
if (rows.length > 1) {
- const parent = Docs.Create.StackingDocument([], { _layout_autoHeight: true, _width: 300, title: `field views for ${DocCast(this._props.Document).title}`, _chromeHidden: true });
- for (const row of rows) {
- const field = this.createFieldView(DocCast(this._props.Document), row);
+ const parent = Docs.Create.StackingDocument([], { _layout_autoHeight: true, _width: 300, title: `field views for ${DocCast(this.Document).title}`, _chromeHidden: true });
+ rows.forEach(row => {
+ const field = this.createFieldView(DocCast(this.Document), row);
field && Doc.AddDocToList(parent, 'data', field);
row.uncheck();
- }
+ });
return parent;
}
- return rows.length ? this.createFieldView(DocCast(this._props.Document), rows.lastElement()) : undefined;
+ return rows.length ? this.createFieldView(DocCast(this.Document), rows.lastElement()) : undefined;
};
createFieldView = (templateDoc: Doc, row: KeyValuePair) => {
const metaKey = row._props.keyName;
- const fieldTemplate = Doc.IsDelegateField(templateDoc, metaKey) ? Doc.MakeDelegate(templateDoc) : Doc.MakeEmbedding(templateDoc);
- fieldTemplate.title = metaKey;
- fieldTemplate.layout_fitWidth = true;
- fieldTemplate._xMargin = 10;
- fieldTemplate._yMargin = 10;
- fieldTemplate._width = 100;
- fieldTemplate._height = 40;
- fieldTemplate.layout = this.inferType(templateDoc[metaKey], metaKey);
- return fieldTemplate;
+ const fieldTempDoc = Doc.IsDelegateField(templateDoc, metaKey) ? Doc.MakeDelegate(templateDoc) : Doc.MakeEmbedding(templateDoc);
+ fieldTempDoc.title = metaKey;
+ fieldTempDoc.layout_fitWidth = true;
+ fieldTempDoc._xMargin = 10;
+ fieldTempDoc._yMargin = 10;
+ fieldTempDoc._width = 100;
+ fieldTempDoc._height = 40;
+ fieldTempDoc.layout = this.inferType(templateDoc[metaKey], metaKey);
+ return fieldTempDoc;
};
inferType = (data: FieldResult, metaKey: string) => {
const options = { _width: 300, _height: 300, title: metaKey };
if (data instanceof RichTextField || typeof data === 'string' || typeof data === 'number') {
return FormattedTextBox.LayoutString(metaKey);
- } else if (data instanceof List) {
+ }
+ if (data instanceof List) {
if (data.length === 0) {
return Docs.Create.StackingDocument([], options);
}
@@ -262,28 +284,25 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
return Docs.Create.StackingDocument([], options);
}
switch (first.data.constructor) {
- case RichTextField:
- return Docs.Create.TreeDocument([], options);
- case ImageField:
- return Docs.Create.MasonryDocument([], options);
- default:
- console.log(`Template for ${first.data.constructor} not supported!`);
- return undefined;
- }
+ case RichTextField: return Docs.Create.TreeDocument([], options);
+ case ImageField: return Docs.Create.MasonryDocument([], options);
+ default: console.log(`Template for ${first.data.constructor} not supported!`);
+ return undefined;
+ } // prettier-ignore
} else if (data instanceof ImageField) {
return ImageBox.LayoutString(metaKey);
}
return new Doc();
};
- specificContextMenu = (e: React.MouseEvent): void => {
+ specificContextMenu = (): void => {
const cm = ContextMenu.Instance;
const open = cm.findByDescription('Change Perspective...');
const openItems: ContextMenuProps[] = open && 'subitems' in open ? open.subitems : [];
openItems.push({
description: 'Default Perspective',
event: () => {
- this._props.addDocTab(this._props.Document, OpenWhere.close);
+ this._props.addDocTab(this.Document, OpenWhere.close);
this._props.addDocTab(this.fieldDocToLayout, OpenWhere.addRight);
},
icon: 'image',
@@ -319,4 +338,12 @@ export class KeyValueBox extends ObservableReactComponent<FieldViewProps> {
</div>
);
}
+ public static Init() {
+ Doc.SetField = KeyValueBox.SetField;
+ }
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.KVP, {
+ layout: { view: KeyValueBox, dataField: 'data' },
+ options: { acl: '', _layout_fitWidth: true, _height: 150 },
+});
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index f9e8ce4f3..0956be3e9 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -1,8 +1,10 @@
+/* eslint-disable jsx-a11y/control-has-associated-label */
import { Tooltip } from '@mui/material';
import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../Utils';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { Doc, Field } from '../../../fields/Doc';
import { DocCast } from '../../../fields/Types';
import { DocumentOptions, FInfo } from '../../documents/Documents';
@@ -11,11 +13,10 @@ import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { EditableView } from '../EditableView';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { DefaultStyleProvider } from '../StyleProvider';
-import { OpenWhere, returnEmptyDocViewList } from './DocumentView';
-import { KeyValueBox } from './KeyValueBox';
+import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider';
import './KeyValueBox.scss';
import './KeyValuePair.scss';
+import { OpenWhere } from './OpenWhere';
// Represents one row in a key value plane
@@ -62,7 +63,7 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
render() {
// let fieldKey = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? props.fieldKey : "(" + props.fieldKey + ")";
let protoCount = 0;
- let doc = this._props.doc;
+ let { doc } = this._props;
while (doc) {
if (Object.keys(doc).includes(this._props.keyName)) {
break;
@@ -76,10 +77,18 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
const hover = { transition: '0.3s ease opacity', opacity: this.isPointerOver || this.isChecked ? 1 : 0 };
return (
- <tr className={this._props.rowStyle} onPointerEnter={action(() => (this.isPointerOver = true))} onPointerLeave={action(() => (this.isPointerOver = false))}>
+ <tr
+ className={this._props.rowStyle}
+ onPointerEnter={action(() => {
+ this.isPointerOver = true;
+ })}
+ onPointerLeave={action(() => {
+ this.isPointerOver = false;
+ })}>
<td className="keyValuePair-td-key" style={{ width: `${this._props.keyWidth}%` }}>
<div className="keyValuePair-td-key-container">
<button
+ type="button"
style={hover}
className="keyValuePair-td-key-delete"
onClick={undoBatch(() => {
@@ -91,7 +100,7 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
</button>
<input className="keyValuePair-td-key-check" type="checkbox" style={hover} onChange={this.handleCheck} ref={this.checkbox} />
<Tooltip title={Object.entries(new DocumentOptions()).find((pair: [string, FInfo]) => pair[0].replace(/^_/, '') === this._props.keyName)?.[1].description ?? ''}>
- <div className="keyValuePair-keyField" style={{ marginLeft: 20 * (this._props.keyName.match(/_/g)?.length || 0), color: keyStyle }}>
+ <div className="keyValuePair-keyField" style={{ marginLeft: 20 * (this._props.keyName.replace(/__/g, '').match(/_/g)?.length || 0), color: keyStyle }}>
{'('.repeat(parenCount)}
{this._props.keyName}
{')'.repeat(parenCount)}
@@ -125,7 +134,7 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
pinToPres: returnZero,
}}
GetValue={() => Field.toKeyValueString(this._props.doc, this._props.keyName)}
- SetValue={(value: string) => KeyValueBox.SetField(this._props.doc, this._props.keyName, value)}
+ SetValue={(value: string) => Doc.SetField(this._props.doc, this._props.keyName, value)}
/>
</div>
</td>
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index be20b5934..f80ff5f94 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -1,21 +1,22 @@
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, Field } from '../../../fields/Doc';
+import { Doc, DocListCast, Field, FieldType } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxBaseComponent } from '../DocComponent';
-import { StyleProp } from '../StyleProvider';
+import { PinDocView, PinProps } from '../PinFuncs';
+import { StyleProp } from '../StyleProp';
import { FieldView, FieldViewProps } from './FieldView';
import BigText from './LabelBigText';
import './LabelBox.scss';
-import { PinProps, PresBox } from './trails';
-import { Docs } from '../../documents/Documents';
@observer
export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
@@ -23,7 +24,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
return FieldView.LayoutString(LabelBox, fieldKey);
}
public static LayoutStringWithTitle(fieldStr: string, label?: string) {
- return !label ? LabelBox.LayoutString(fieldStr) : `<LabelBox fieldKey={'${fieldStr}'} label={'${label}'} {...props} />`; //e.g., "<ImageBox {...props} fieldKey={"data} />"
+ return !label ? LabelBox.LayoutString(fieldStr) : `<LabelBox fieldKey={'${fieldStr}'} label={'${label}'} {...props} />`; // e.g., "<ImageBox {...props} fieldKey={"data} />"
}
private dropDisposer?: DragManager.DragDropDisposer;
private _timeout: any;
@@ -41,7 +42,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
@computed get Title() {
- return Field.toString(this.dataDoc[this.fieldKey] as Field);
+ return Field.toString(this.dataDoc[this.fieldKey] as FieldType) || StrCast(this.Document.title);
}
protected createDropTarget = (ele: HTMLDivElement) => {
@@ -54,14 +55,16 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
get paramsDoc() {
return Doc.AreProtosEqual(this.layoutDoc, this.dataDoc) ? this.dataDoc : this.layoutDoc;
}
- specificContextMenu = (e: React.MouseEvent): void => {
+ specificContextMenu = (): void => {
const funcs: ContextMenuProps[] = [];
!Doc.noviceMode &&
funcs.push({
description: 'Clear Script Params',
event: () => {
const params = Cast(this.paramsDoc['onClick-paramFieldKeys'], listSpec('string'), []);
- params?.map(p => (this.paramsDoc[p] = undefined));
+ params?.forEach(p => {
+ this.paramsDoc[p] = undefined;
+ });
},
icon: 'trash',
});
@@ -71,7 +74,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
@undoBatch
drop = (e: Event, de: DragManager.DropEvent) => {
- const docDragData = de.complete.docDragData;
+ const { docDragData } = de.complete;
const params = Cast(this.paramsDoc['onClick-paramFieldKeys'], listSpec('string'), []);
const missingParams = params?.filter(p => !this.paramsDoc[p]);
if (docDragData && missingParams?.includes((e.target as any).textContent)) {
@@ -94,7 +97,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (anchor) {
if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
// addAsAnnotation && this.addDocument(anchor);
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}) } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}) } }, this.Document);
return anchor;
}
return anchor;
@@ -131,7 +134,10 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
this._timeout = undefined;
if (!r) return params;
- if (!r.offsetHeight || !r.offsetWidth) return (this._timeout = setTimeout(() => this.fitTextToBox(r)));
+ if (!r.offsetHeight || !r.offsetWidth) {
+ this._timeout = setTimeout(() => this.fitTextToBox(r));
+ return this._timeout;
+ }
const parent = r.parentNode;
const parentStyle = parent.style;
parentStyle.display = '';
@@ -154,8 +160,13 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
return (
<div
className="labelBox-outerDiv"
- onMouseLeave={action(() => (this._mouseOver = false))}
- onMouseOver={action(() => (this._mouseOver = true))}
+ onMouseLeave={action(() => {
+ this._mouseOver = false;
+ })}
+ // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
+ onMouseOver={action(() => {
+ this._mouseOver = true;
+ })}
ref={this.createDropTarget}
onContextMenu={this.specificContextMenu}
style={{ boxShadow: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BoxShadow) }}>
@@ -193,3 +204,12 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.LABEL, {
+ layout: { view: LabelBox, dataField: 'title' },
+ options: { acl: '', _singleLine: true, _layout_nativeDimEditable: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true },
+});
+Docs.Prototypes.TemplateMap.set(DocumentType.BUTTON, {
+ layout: { view: LabelBox, dataField: 'title' },
+ options: { acl: '', _layout_nativeDimEditable: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true },
+});
diff --git a/src/client/views/nodes/LinkAnchorBox.scss b/src/client/views/nodes/LinkAnchorBox.scss
deleted file mode 100644
index caff369df..000000000
--- a/src/client/views/nodes/LinkAnchorBox.scss
+++ /dev/null
@@ -1,34 +0,0 @@
-.linkAnchorBox-cont,
-.linkAnchorBox-cont-small {
- cursor: default;
- position: absolute;
- width: 15;
- height: 15;
- border-radius: 20px;
- user-select: none;
- pointer-events: all;
-
- .linkAnchorBox-linkCloser {
- position: absolute;
- width: 18;
- height: 18;
- background: rgb(219, 21, 21);
- top: -1px;
- left: -1px;
- border-radius: 5px;
- display: flex;
- justify-content: center;
- align-items: center;
- padding-left: 2px;
- padding-top: 1px;
- }
- .linkAnchorBox-button {
- position: relative;
- display: inline-block;
- }
-}
-
-.linkAnchorBox-cont-small {
- width: 5px;
- height: 5px;
-} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
deleted file mode 100644
index 0a4325d8c..000000000
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import { action, computed, makeObservable } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { Utils, emptyFunction, setupMoveUpEvents } from '../../../Utils';
-import { Doc } from '../../../fields/Doc';
-import { NumCast, StrCast } from '../../../fields/Types';
-import { TraceMobx } from '../../../fields/util';
-import { DragManager, dropActionType } from '../../util/DragManager';
-import { LinkFollower } from '../../util/LinkFollower';
-import { SelectionManager } from '../../util/SelectionManager';
-import { ViewBoxBaseComponent } from '../DocComponent';
-import { StyleProp } from '../StyleProvider';
-import { FieldView, FieldViewProps } from './FieldView';
-import './LinkAnchorBox.scss';
-import { LinkInfo } from './LinkDocPreview';
-const { default: { MEDIUM_GRAY }, } = require('../global/globalCssVariables.module.scss'); // prettier-ignore
-@observer
-export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
- public static LayoutString(fieldKey: string) {
- return FieldView.LayoutString(LinkAnchorBox, fieldKey);
- }
- _doubleTap = false;
- _lastTap: number = 0;
- _ref = React.createRef<HTMLDivElement>();
- _isOpen = false;
- _timeout: NodeJS.Timeout | undefined;
-
- constructor(props: FieldViewProps) {
- super(props);
- makeObservable(this);
- }
-
- componentDidMount() {
- this._props.setContentViewBox?.(this);
- }
-
- @computed get linkSource() {
- return this.DocumentView?.().containerViewPath?.().lastElement().Document; // this._props.styleProvider?.(this.dataDoc, this._props, StyleProp.LinkSource);
- }
-
- onPointerDown = (e: React.PointerEvent) => {
- const linkSource = this.linkSource;
- linkSource &&
- setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, (e, doubleTap) => {
- if (doubleTap) LinkFollower.FollowLink(this.Document, linkSource, false);
- else this._props.select(false);
- });
- };
- onPointerMove = action((e: PointerEvent, down: number[], delta: number[]) => {
- const cdiv = this._ref?.current?.parentElement;
- if (!this._isOpen && cdiv) {
- const bounds = cdiv.getBoundingClientRect();
- const pt = Utils.getNearestPointInPerimeter(bounds.left, bounds.top, bounds.width, bounds.height, e.clientX, e.clientY);
- const separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY));
- if (separation > 100) {
- const dragData = new DragManager.DocumentDragData([this.Document]);
- dragData.dropAction = dropActionType.embed;
- dragData.dropPropertiesToRemove = ['link_anchor_1_x', 'link_anchor_1_y', 'link_anchor_2_x', 'link_anchor_2_y', 'onClick'];
- DragManager.StartDocumentDrag([this._ref.current!], dragData, pt[0], pt[1]);
- return true;
- } else {
- this.layoutDoc[this.fieldKey + '_x'] = ((pt[0] - bounds.left) / bounds.width) * 100;
- this.layoutDoc[this.fieldKey + '_y'] = ((pt[1] - bounds.top) / bounds.height) * 100;
- this.layoutDoc.link_autoMoveAnchors = false;
- }
- }
- return false;
- });
-
- specificContextMenu = (e: React.MouseEvent): void => {};
-
- render() {
- TraceMobx();
- const small = this._props.PanelWidth() <= 1; // this happens when rendered in a treeView
- const x = NumCast(this.layoutDoc[this.fieldKey + '_x'], 100);
- const y = NumCast(this.layoutDoc[this.fieldKey + '_y'], 100);
- const background = this._props.styleProvider?.(this.dataDoc, this._props, StyleProp.BackgroundColor + ':anchor');
- const anchor = this.fieldKey === 'link_anchor_1' ? 'link_anchor_2' : 'link_anchor_1';
- const anchorScale = !this.dataDoc[this.fieldKey + '_useSmallAnchor'] && (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : 0.25;
- const targetTitle = StrCast((this.dataDoc[anchor] as Doc)?.title);
- const selView = SelectionManager.Views.lastElement()?._props.LayoutTemplateString?.includes('link_anchor_1')
- ? 'link_anchor_1'
- : SelectionManager.Views.lastElement()?._props.LayoutTemplateString?.includes('link_anchor_2')
- ? 'link_anchor_2'
- : '';
- return (
- <div
- ref={this._ref}
- title={targetTitle}
- className={`linkAnchorBox-cont${small ? '-small' : ''}`}
- onPointerEnter={e =>
- LinkInfo.SetLinkInfo({
- DocumentView: this.DocumentView,
- styleProvider: this._props.styleProvider,
- linkSrc: this.linkSource,
- linkDoc: this.Document,
- showHeader: true,
- location: [e.clientX, e.clientY + 20],
- noPreview: false,
- })
- }
- onPointerDown={this.onPointerDown}
- onContextMenu={this.specificContextMenu}
- style={{
- border: selView && this.dataDoc[selView] === this.dataDoc[this.fieldKey] ? `solid ${MEDIUM_GRAY} 2px` : undefined,
- background,
- left: `calc(${x}% - ${small ? 2.5 : 7.5}px)`,
- top: `calc(${y}% - ${small ? 2.5 : 7.5}px)`,
- transform: `scale(${anchorScale})`,
- cursor: 'grab',
- }}
- />
- );
- }
-}
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 6e4d0e92a..8d6ae9f73 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -1,19 +1,24 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import Xarrow from 'react-xarrows';
+import { DashColor, lightOrDark, returnFalse } from '../../../ClientUtils';
+import { FieldResult } from '../../../fields/Doc';
import { DocCss, DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
import { DocCast, NumCast, StrCast } from '../../../fields/Types';
-import { DashColor, emptyFunction, lightOrDark, returnFalse } from '../../../Utils';
-import { DocumentManager } from '../../util/DocumentManager';
-import { LinkManager } from '../../util/LinkManager';
+import { TraceMobx } from '../../../fields/util';
+import { emptyFunction } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
import { SnappingManager } from '../../util/SnappingManager';
import { ViewBoxBaseComponent } from '../DocComponent';
import { EditableView } from '../EditableView';
-import { LightboxView } from '../LightboxView';
-import { StyleProp } from '../StyleProvider';
+import { StyleProp } from '../StyleProp';
import { ComparisonBox } from './ComparisonBox';
+import { DocumentView } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import './LinkBox.scss';
@@ -22,8 +27,8 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string = 'link') {
return FieldView.LayoutString(LinkBox, fieldKey);
}
- disposer: IReactionDisposer | undefined;
- @observable _forceAnimate = 0; // forces xArrow to animate when a transition animation is detected on something that affects an anchor
+ _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
constructor(props: FieldViewProps) {
@@ -36,47 +41,54 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
anchor = (which: number) => {
const anch = DocCast(this.dataDoc['link_anchor_' + which]);
const anchor = anch?.layout_unrendered ? DocCast(anch.annotationOn) : anch;
- return DocumentManager.Instance.getDocumentView(anchor, this.DocumentView?.().containerViewPath?.().lastElement());
+ return DocumentView.getDocumentView(anchor, this.DocumentView?.().containerViewPath?.().lastElement());
};
+ _hackToSeeIfDeleted: any;
componentWillUnmount() {
- this.disposer?.();
+ this._hackToSeeIfDeleted && clearTimeout(this._hackToSeeIfDeleted);
+ Object.keys(this._disposers).forEach(key => this._disposers[key]());
}
componentDidMount() {
this._props.setContentViewBox?.(this);
- this.disposer = reaction(
- () => ({ drag: SnappingManager.IsDragging }),
- ({ drag }) => {
- !LightboxView.Contains(this.DocumentView?.()) &&
- setTimeout(
- // need to wait for drag manager to set 'hidden' flag on dragged DOM elements
- action(() => {
- const a = this.anchor1,
- b = this.anchor2;
- let a1 = a && document.getElementById(a.Guid);
- let a2 = b && document.getElementById(b.Guid);
- // test whether the anchors themselves are hidden,...
- if (!a1 || !a2 || (a?.ContentDiv as any)?.hidden || (b?.ContentDiv as any)?.hidden) this._hide = true;
- else {
- // .. or whether and of their DOM parents are hidden
- for (; a1 && !a1.hidden; a1 = a1.parentElement);
- for (; a2 && !a2.hidden; a2 = a2.parentElement);
- this._hide = a1 || a2 ? true : false;
- }
- })
- );
- },
- { fireImmediately: true }
+ this._disposers.deleting = reaction(
+ () => !this.anchor1 && !this.anchor2 && this.DocumentView?.() && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView!())),
+ empty => {
+ if (empty) {
+ this._hackToSeeIfDeleted = setTimeout(() => {
+ !this.anchor1 && !this.anchor2 && this._props.removeDocument?.(this.Document);
+ }, 1000);
+ }
+ }
+ );
+ this._disposers.dragging = reaction(
+ () => SnappingManager.IsDragging,
+ () => setTimeout( action(() => {// need to wait for drag manager to set 'hidden' flag on dragged DOM elements
+ const a = this.anchor1;
+ const b = this.anchor2;
+ 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;
+ else {
+ // .. or whether any of their DOM parents are hidden
+ for (; a1 && !a1.hidden; a1 = a1.parentElement);
+ for (; a2 && !a2.hidden; a2 = a2.parentElement);
+ this._hide = !!(a1 || a2);
+ }
+ })) // prettier-ignore
);
}
render() {
+ TraceMobx();
+
if (this._hide) return null;
const a = this.anchor1;
const b = this.anchor2;
this._forceAnimate;
const docView = this._props.docViewPath().lastElement();
- if (a && b && !LightboxView.Contains(docView)) {
+ if (a && b) {
// text selection bounds are not directly observable, so we have to
// force an update when anything that could affect them changes (text edits causing reflow, scrolling)
a.Document[a.LayoutFieldKey];
@@ -86,35 +98,69 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
a.Document[DocCss];
b.Document[DocCss];
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
const axf = a.screenToViewTransform(); // these force re-render when a or b moves (so do NOT remove)
const bxf = b.screenToViewTransform();
const scale = docView?.screenToViewTransform().Scale ?? 1;
const at = a.getBounds?.transition; // these force re-render when a or b change size and at the end of an animated transition
const bt = b.getBounds?.transition; // inquring getBounds() also causes text anchors to update whether or not they reflow (any size change triggers an invalidation)
+ let foundParent = false;
+ const getAnchor = (field: FieldResult): Element[] => {
+ const docField = DocCast(field);
+ const doc = docField?.layout_unrendered ? DocCast(docField.annotationOn, docField) : docField;
+ const ele = document.getElementById(DocumentView.UniquifyId(DocumentView.LightboxContains(this.DocumentView?.()), doc[Id]));
+ if (ele?.className === 'linkBox-label') foundParent = true;
+ if (ele?.getBoundingClientRect().width) return [ele];
+ const eles = Array.from(document.getElementsByClassName(doc[Id])).filter(el => el?.getBoundingClientRect().width);
+ const annoOn = DocCast(doc.annotationOn);
+ if (eles.length || !annoOn) return eles;
+ const pareles = getAnchor(annoOn);
+ foundParent = !!pareles.length;
+ return pareles;
+ };
// if there's an element in the DOM with a classname containing a link anchor's id (eg a hypertext <a>),
// then that DOM element is a hyperlink source for the current anchor and we want to place our link box at it's top right
// otherwise, we just use the computed nearest point on the document boundary to the target Document
- const targetAhyperlink = Array.from(document.getElementsByClassName(DocCast(this.dataDoc.link_anchor_1)[Id])).lastElement();
- const targetBhyperlink = Array.from(document.getElementsByClassName(DocCast(this.dataDoc.link_anchor_2)[Id])).lastElement();
+ const targetAhyperlinks = getAnchor(this.dataDoc.link_anchor_1);
+ const targetBhyperlinks = getAnchor(this.dataDoc.link_anchor_2);
- const aid = targetAhyperlink?.id || a.Document[Id];
- const bid = targetBhyperlink?.id || b.Document[Id];
- if (!document.getElementById(aid) || !document.getElementById(bid)) {
- setTimeout(action(() => (this._forceAnimate = this._forceAnimate + 0.01)));
+ const container = this.DocumentView?.().containerViewPath?.().lastElement()?.ContentDiv;
+ const aid = targetAhyperlinks?.find(alink => container?.contains(alink))?.id ?? targetAhyperlinks?.lastElement()?.id;
+ const bid = targetBhyperlinks?.find(blink => container?.contains(blink))?.id ?? targetBhyperlinks?.lastElement()?.id;
+ if (!aid || !bid) {
+ setTimeout(
+ action(() => {
+ this._forceAnimate += 0.01;
+ })
+ );
return null;
}
+ if (foundParent) {
+ setTimeout(
+ action(() => {
+ this._forceAnimate += 0.01;
+ }),
+ 1
+ );
+ }
- if (at || bt) setTimeout(action(() => (this._forceAnimate = this._forceAnimate + 0.01))); // this forces an update during a transition animation
+ if (at || bt)
+ setTimeout(
+ action(() => {
+ this._forceAnimate += 0.01;
+ })
+ ); // this forces an update during a transition animation
const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting);
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 fontColor = (c => (c !== 'transparent' ? c : undefined))(StrCast(this.layoutDoc.link_fontColor));
- const { stroke_markerScale, stroke_width, stroke_startMarker, stroke_endMarker, stroke_dash } = this.Document;
+ // eslint-disable-next-line camelcase
+ const { stroke_markerScale: strokeMarkerScale, stroke_width: strokeRawWidth, stroke_startMarker: strokeStartMarker, stroke_endMarker: strokeEndMarker, stroke_dash: strokeDash } = this.Document;
- const strokeWidth = NumCast(stroke_width, 4);
+ const strokeWidth = NumCast(strokeRawWidth, 4);
const linkDesc = StrCast(this.dataDoc.link_description) || ' ';
const labelText = linkDesc.substring(0, 50) + (linkDesc.length > 50 ? '...' : '');
return (
@@ -125,12 +171,12 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
start={aid}
end={bid} //
strokeWidth={strokeWidth + Math.max(2, strokeWidth * 0.1)}
- showHead={stroke_startMarker ? true : false}
- showTail={stroke_endMarker ? true : false}
- headSize={NumCast(stroke_markerScale, 3)}
- tailSize={NumCast(stroke_markerScale, 3)}
- tailShape={stroke_endMarker === 'dot' ? 'circle' : 'arrow1'}
- headShape={stroke_startMarker === 'dot' ? 'circle' : 'arrow1'}
+ showHead={!!strokeStartMarker}
+ showTail={!!strokeEndMarker}
+ headSize={NumCast(strokeMarkerScale, 3)}
+ tailSize={NumCast(strokeMarkerScale, 3)}
+ tailShape={strokeEndMarker === 'dot' ? 'circle' : 'arrow1'}
+ headShape={strokeStartMarker === 'dot' ? 'circle' : 'arrow1'}
color={highlightColor}
/>
)}
@@ -139,21 +185,23 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
start={aid}
end={bid} //
strokeWidth={strokeWidth}
- dashness={Number(stroke_dash) ? true : false}
- showHead={stroke_startMarker ? true : false}
- showTail={stroke_endMarker ? true : false}
- headSize={NumCast(stroke_markerScale, 3)}
- tailSize={NumCast(stroke_markerScale, 3)}
- tailShape={stroke_endMarker === 'dot' ? 'circle' : 'arrow1'}
- headShape={stroke_startMarker === 'dot' ? 'circle' : 'arrow1'}
+ dashness={!!Number(strokeDash)}
+ showHead={!!strokeStartMarker}
+ showTail={!!strokeEndMarker}
+ headSize={NumCast(strokeMarkerScale, 3)}
+ tailSize={NumCast(strokeMarkerScale, 3)}
+ tailShape={strokeEndMarker === 'dot' ? 'circle' : 'arrow1'}
+ headShape={strokeStartMarker === 'dot' ? 'circle' : 'arrow1'}
color={color}
labels={
<div
+ id={this.DocumentView?.().DocUniqueId}
+ className="linkBox-label"
style={{
borderRadius: '8px',
pointerEvents: this._props.isDocumentActive?.() ? 'all' : undefined,
fontSize,
- fontFamily /*, fontStyle: 'italic'*/,
+ fontFamily /* , fontStyle: 'italic' */,
color: fontColor || lightOrDark(DashColor(color).fade(0.5).toString()),
paddingLeft: 4,
paddingRight: 4,
@@ -192,13 +240,21 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
</>
);
}
+
+ setTimeout(
+ action(() => {
+ this._forceAnimate += 1;
+ }),
+ 2
+ );
return (
<div className={`linkBox-container${this._props.isContentActive() ? '-interactive' : ''}`} style={{ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) }}>
<ComparisonBox
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this.props} //
fieldKey="link_anchor"
setHeight={emptyFunction}
- dontRegisterView={true}
+ dontRegisterView
renderDepth={this._props.renderDepth + 1}
addDocument={returnFalse}
removeDocument={returnFalse}
@@ -208,3 +264,18 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.LINK, {
+ layout: { view: LinkBox, dataField: 'link' },
+ options: {
+ acl: '',
+ childDontRegisterViews: true,
+ layout_hideLinkAnchors: true,
+ _height: 1,
+ _width: 1,
+ link: '',
+ link_description: '',
+ color: 'lightBlue', // lightblue is default color for linking dot and link documents text comment area
+ _dropPropertiesToRemove: new List(['onClick']),
+ },
+});
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx
index 1645d0813..ff95f8547 100644
--- a/src/client/views/nodes/LinkDescriptionPopup.tsx
+++ b/src/client/views/nodes/LinkDescriptionPopup.tsx
@@ -2,15 +2,17 @@ import { action, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { DocData } from '../../../fields/DocSymbols';
+import { StrCast } from '../../../fields/Types';
import { LinkManager } from '../../util/LinkManager';
import './LinkDescriptionPopup.scss';
import { TaskCompletionBox } from './TaskCompletedBox';
-import { StrCast } from '../../../fields/Types';
@observer
export class LinkDescriptionPopup extends React.Component<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: LinkDescriptionPopup;
@observable public display: boolean = false;
+ // eslint-disable-next-line react/no-unused-class-component-methods
@observable public showDescriptions: string = 'ON';
@observable public popupX: number = 700;
@observable public popupY: number = 350;
@@ -23,6 +25,20 @@ export class LinkDescriptionPopup extends React.Component<{}> {
LinkDescriptionPopup.Instance = this;
}
+ componentDidMount() {
+ document.addEventListener('pointerdown', this.onClick, true);
+ reaction(
+ () => this.display,
+ display => {
+ display && (this.description = StrCast(LinkManager.Instance.currentLink?.link_description));
+ }
+ );
+ }
+
+ componentWillUnmount() {
+ document.removeEventListener('pointerdown', this.onClick, true);
+ }
+
@action
descriptionChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
this.description = e.currentTarget.value;
@@ -39,25 +55,13 @@ export class LinkDescriptionPopup extends React.Component<{}> {
@action
onClick = (e: PointerEvent) => {
- if (this.popupRef && !!!this.popupRef.current?.contains(e.target as any)) {
+ if (this.popupRef && !this.popupRef.current?.contains(e.target as any)) {
this.display = false;
this.description = '';
TaskCompletionBox.taskCompleted = false;
}
};
- componentDidMount() {
- document.addEventListener('pointerdown', this.onClick, true);
- reaction(
- () => this.display,
- display => display && (this.description = StrCast(LinkManager.Instance.currentLink?.link_description))
- );
- }
-
- componentWillUnmount() {
- document.removeEventListener('pointerdown', this.onClick, true);
- }
-
render() {
return !this.display ? null : (
<div
@@ -69,18 +73,20 @@ export class LinkDescriptionPopup extends React.Component<{}> {
}}>
<input
className="linkDescriptionPopup-input"
- onKeyDown={e => e.stopPropagation()}
- onKeyPress={e => e.key === 'Enter' && this.onDismiss(true)}
+ onKeyDown={e => {
+ e.key === 'Enter' && this.onDismiss(true);
+ e.stopPropagation();
+ }}
value={this.description}
placeholder={this.description || '(Optional) Enter link description...'}
onChange={e => this.descriptionChanged(e)}
/>
<div className="linkDescriptionPopup-btn">
- <div className="linkDescriptionPopup-btn-dismiss" onPointerDown={e => this.onDismiss(false)}>
+ <div className="linkDescriptionPopup-btn-dismiss" onPointerDown={() => this.onDismiss(false)}>
{' '}
Dismiss{' '}
</div>
- <div className="linkDescriptionPopup-btn-add" onPointerDown={e => this.onDismiss(true)}>
+ <div className="linkDescriptionPopup-btn-add" onPointerDown={() => this.onDismiss(true)}>
{' '}
Add{' '}
</div>
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index ae25ff179..8f29600f6 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -4,53 +4,59 @@ import { action, computed, makeObservable, observable, runInAction } from 'mobx'
import { observer } from 'mobx-react';
import * as React from 'react';
import wiki from 'wikijs';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils';
+import { returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
import { Cast, DocCast, NumCast, PromiseValue, StrCast } from '../../../fields/Types';
import { DocServer } from '../../DocServer';
import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
-import { LinkFollower } from '../../util/LinkFollower';
import { LinkManager } from '../../util/LinkManager';
import { SearchUtil } from '../../util/SearchUtil';
-import { SettingsManager } from '../../util/SettingsManager';
+import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { DocumentView, OpenWhere } from './DocumentView';
+import { DocumentView } from './DocumentView';
import { StyleProviderFuncType } from './FieldView';
import './LinkDocPreview.scss';
+import { OpenWhere } from './OpenWhere';
+interface LinkDocPreviewProps {
+ linkDoc?: Doc;
+ linkSrc?: Doc;
+ DocumentView?: () => DocumentView;
+ styleProvider?: StyleProviderFuncType;
+ location: number[];
+ hrefs?: string[];
+ showHeader?: boolean;
+ noPreview?: boolean;
+}
export class LinkInfo {
+ // eslint-disable-next-line no-use-before-define
private static _instance: Opt<LinkInfo>;
constructor() {
LinkInfo._instance = this;
makeObservable(this);
}
+ // eslint-disable-next-line no-use-before-define
@observable public LinkInfo: Opt<LinkDocPreviewProps> = undefined;
public static get Instance() {
return LinkInfo._instance ?? new LinkInfo();
}
public static Clear() {
- runInAction(() => LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = undefined));
+ runInAction(() => {
+ LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = undefined);
+ });
}
public static SetLinkInfo(info?: LinkDocPreviewProps) {
- runInAction(() => LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = info));
+ runInAction(() => {
+ LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = info);
+ });
}
}
-interface LinkDocPreviewProps {
- linkDoc?: Doc;
- linkSrc?: Doc;
- DocumentView?: () => DocumentView;
- styleProvider?: StyleProviderFuncType;
- location: number[];
- hrefs?: string[];
- showHeader?: boolean;
- noPreview?: boolean;
-}
@observer
export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps> {
_infoRef = React.createRef<HTMLDivElement>();
@@ -68,13 +74,13 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
@action
init() {
- var linkTarget = this._props.linkDoc;
+ let linkTarget = this._props.linkDoc;
this._linkSrc = this._props.linkSrc;
this._linkDoc = this._props.linkDoc;
- const link_anchor_1 = DocCast(this._linkDoc?.link_anchor_1);
- const link_anchor_2 = DocCast(this._linkDoc?.link_anchor_2);
- if (link_anchor_1 && link_anchor_2) {
- linkTarget = Doc.AreProtosEqual(link_anchor_1, this._linkSrc) || Doc.AreProtosEqual(link_anchor_1?.annotationOn as Doc, this._linkSrc) ? link_anchor_2 : link_anchor_1;
+ const linkAnchor1 = DocCast(this._linkDoc?.link_anchor_1);
+ const linkAnchor2 = DocCast(this._linkDoc?.link_anchor_2);
+ if (linkAnchor1 && linkAnchor2) {
+ linkTarget = Doc.AreProtosEqual(linkAnchor1, this._linkSrc) || Doc.AreProtosEqual(linkAnchor1?.annotationOn as Doc, this._linkSrc) ? linkAnchor2 : linkAnchor1;
}
if (linkTarget?.annotationOn && linkTarget?.type !== DocumentType.RTF) {
linkTarget = DocCast(linkTarget.annotationOn); // want to show annotation embedContainer document if annotation is not text
@@ -110,7 +116,13 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
if (href.startsWith('https://en.wikipedia.org/wiki/')) {
wiki()
.page(href.replace('https://en.wikipedia.org/wiki/', ''))
- .then(page => page.summary().then(action(summary => (this._toolTipText = summary.substring(0, 500)))));
+ .then(page =>
+ page.summary().then(
+ action(summary => {
+ this._toolTipText = summary.substring(0, 500);
+ })
+ )
+ );
} else {
this._toolTipText = 'url => ' + href;
}
@@ -120,19 +132,19 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
const anchorDoc = anchorDocId ? PromiseValue(DocCast(DocServer.GetCachedRefField(anchorDocId) ?? DocServer.GetRefField(anchorDocId))) : undefined;
anchorDoc?.then?.(
action(anchor => {
- if (anchor instanceof Doc && LinkManager.Links(anchor).length) {
- this._linkDoc = this._linkDoc ?? LinkManager.Links(anchor)[0];
+ if (anchor instanceof Doc && Doc.Links(anchor).length) {
+ this._linkDoc = this._linkDoc ?? Doc.Links(anchor)[0];
const automaticLink = this._linkDoc.link_relationship === LinkManager.AutoKeywords;
if (automaticLink) {
// automatic links specify the target in the link info, not the source
const linkTarget = anchor;
- this._linkSrc = LinkManager.getOppositeAnchor(this._linkDoc, linkTarget);
+ this._linkSrc = Doc.getOppositeAnchor(this._linkDoc, linkTarget);
this._markerTargetDoc = this._targetDoc = linkTarget;
} else {
this._linkSrc = anchor;
- const linkTarget = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
+ const linkTarget = Doc.getOppositeAnchor(this._linkDoc, this._linkSrc);
this._markerTargetDoc = linkTarget;
- this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
+ this._targetDoc = /* linkTarget?.type === DocumentType.MARKER && */ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
}
if (LinkInfo.Instance?.LinkInfo?.noPreview || this._linkSrc?.followLinkToggle || this._markerTargetDoc?.type === DocumentType.PRES) this.followLink();
}
@@ -155,8 +167,8 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
LinkManager.Instance.currentLink = this._linkDoc;
LinkManager.Instance.currentLinkAnchor = this._linkSrc;
this._props.DocumentView?.().select(false);
- if ((SettingsManager.Instance.propertiesWidth ?? 0) < 100) {
- SettingsManager.Instance.propertiesWidth = 250;
+ if ((SnappingManager.PropertiesWidth ?? 0) < 100) {
+ SnappingManager.SetPropertiesWidth(250);
}
})
);
@@ -172,6 +184,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
if (nextHrefInd !== this._hrefInd) {
this._linkDoc = undefined;
this._hrefInd = nextHrefInd;
+ this.updateHref();
}
}),
true
@@ -181,17 +194,18 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
followLink = () => {
LinkInfo.Clear();
if (this._linkDoc && this._linkSrc) {
- LinkFollower.FollowLink(this._linkDoc, this._linkSrc, false);
+ DocumentView.FollowLink(this._linkDoc, this._linkSrc, false);
} else if (this._props.hrefs?.length) {
const webDoc =
- Array.from(SearchUtil.SearchCollection(Doc.MyFilesystem, this._props.hrefs[0], false).keys()).lastElement() ??
- Docs.Create.WebDocument(this._props.hrefs[0], { title: this._props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, data_useCors: true });
- DocumentManager.Instance.showDocument(webDoc, {
+ Array.from(SearchUtil.SearchCollection(Doc.MyFilesystem, this._props.hrefs[0], false).keys())
+ .filter(doc => doc.type === DocumentType.WEB)
+ .lastElement() ?? Docs.Create.WebDocument(this._props.hrefs[0], { title: this._props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, data_useCors: true });
+ DocumentView.showDocument(webDoc, {
openLocation: OpenWhere.lightbox,
willPan: true,
zoomTime: 500,
});
- //this._props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
+ // this._props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
}
};
@@ -213,7 +227,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
};
@computed get previewHeader() {
return !this._linkDoc || !this._markerTargetDoc || !this._targetDoc || !this._linkSrc ? null : (
- <div className="linkDocPreview-info" style={{ background: SettingsManager.userBackgroundColor }}>
+ <div className="linkDocPreview-info" style={{ background: SnappingManager.userBackgroundColor }}>
<div className="linkDocPreview-buttonBar" style={{ float: 'left' }}>
<Tooltip title={<div className="dash-tooltip">Edit Link</div>} placement="top">
<div className="linkDocPreview-button" onPointerDown={this.editLink}>
@@ -246,9 +260,9 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
setupMoveUpEvents(
this,
e,
- (e, down, delta) => {
- if (Math.abs(e.clientX - down[0]) + Math.abs(e.clientY - down[1]) > 100) {
- DragManager.StartDocumentDrag([this._infoRef.current!], new DragManager.DocumentDragData([this._targetDoc!]), e.pageX, e.pageY);
+ (moveEv, down) => {
+ if (Math.abs(moveEv.clientX - down[0]) + Math.abs(moveEv.clientY - down[1]) > 100) {
+ DragManager.StartDocumentDrag([this._infoRef.current!], new DragManager.DocumentDragData([this._targetDoc!]), moveEv.pageX, moveEv.pageY);
LinkInfo.Clear();
return true;
}
@@ -266,7 +280,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
) : (
<DocumentView
ref={r => {
- const targetanchor = this._linkDoc && this._linkSrc && LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
+ const targetanchor = this._linkDoc && this._linkSrc && Doc.getOppositeAnchor(this._linkDoc, this._linkSrc);
targetanchor && this._targetDoc !== targetanchor && r?._props.focus?.(targetanchor, {});
}}
Document={this._targetDoc!}
@@ -277,22 +291,22 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
isDocumentActive={returnFalse}
isContentActive={returnFalse}
addDocument={returnFalse}
- layout_showTitle={returnEmptyString}
+ showTitle={returnEmptyString}
removeDocument={returnFalse}
addDocTab={returnFalse}
pinToPres={returnFalse}
- dontRegisterView={true}
+ dontRegisterView
childFilters={returnEmptyFilter}
childFiltersByRanges={returnEmptyFilter}
searchFilterDocs={returnEmptyDoclist}
renderDepth={0}
- suppressSetHeight={true}
+ suppressSetHeight
PanelWidth={this.width}
PanelHeight={this.height}
pointerEvents={returnNone}
focus={emptyFunction}
whenChildContentsActiveChanged={returnFalse}
- ignoreAutoHeight={true} // need to ignore layout_autoHeight otherwise layout_autoHeight text boxes will expand beyond the preview panel size.
+ ignoreAutoHeight // need to ignore layout_autoHeight otherwise layout_autoHeight text boxes will expand beyond the preview panel size.
NativeWidth={Doc.NativeWidth(this._targetDoc) ? () => Doc.NativeWidth(this._targetDoc) : undefined}
NativeHeight={Doc.NativeHeight(this._targetDoc) ? () => Doc.NativeHeight(this._targetDoc) : undefined}
/>
@@ -309,7 +323,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
className="linkDocPreview"
ref={this._linkDocRef}
onPointerDown={this.followLinkPointerDown}
- style={{ borderColor: SettingsManager.userColor, left: this._props.location[0], top: this._props.location[1], width: this.width() + borders, height: this.height() + borders + (this._props.showHeader ? 37 : 0) }}>
+ style={{ borderColor: SnappingManager.userColor, left: this._props.location[0], top: this._props.location[1], width: this.width() + borders, height: this.height() + borders + (this._props.showHeader ? 37 : 0) }}>
{this.docPreview}
</div>
);
diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx
index adccc9db6..5f343bdfe 100644
--- a/src/client/views/nodes/LoadingBox.tsx
+++ b/src/client/views/nodes/LoadingBox.tsx
@@ -6,7 +6,8 @@ import { Doc } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { StrCast } from '../../../fields/Types';
import { Networking } from '../../Network';
-import { DocumentManager } from '../../util/DocumentManager';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { FieldView, FieldViewProps } from './FieldView';
import './LoadingBox.scss';
@@ -37,30 +38,18 @@ export class LoadingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(LoadingBox, fieldKey);
}
- // removes from currently loading display
- public static removeCurrentlyLoading(doc: Doc) {
- if (DocumentManager.Instance.CurrentlyLoading) {
- const index = DocumentManager.Instance.CurrentlyLoading.indexOf(doc);
- runInAction(() => index !== -1 && DocumentManager.Instance.CurrentlyLoading.splice(index, 1));
- }
- }
-
- // adds doc to currently loading display
- public static addCurrentlyLoading(doc: Doc) {
- if (DocumentManager.Instance.CurrentlyLoading.indexOf(doc) === -1) {
- runInAction(() => DocumentManager.Instance.CurrentlyLoading.push(doc));
- }
- }
_timer: any;
@observable progress = '';
componentDidMount() {
- if (!DocumentManager.Instance.CurrentlyLoading?.includes(this.Document)) {
+ if (!Doc.CurrentlyLoading?.includes(this.Document)) {
this.Document.loadingError = 'Upload interrupted, please try again';
} else {
const updateFunc = async () => {
const result = await Networking.QueryYoutubeProgress(StrCast(this.Document[Id])); // We use the guid of the overwriteDoc to track file uploads.
- runInAction(() => (this.progress = result.progress));
+ runInAction(() => {
+ this.progress = result.progress;
+ });
!this.Document.loadingError && this._timer && (this._timer = setTimeout(updateFunc, 1000));
};
this._timer = setTimeout(updateFunc, 1000);
@@ -87,3 +76,7 @@ export class LoadingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
);
}
}
+Docs.Prototypes.TemplateMap.set(DocumentType.LOADING, {
+ layout: { view: LoadingBox, dataField: '' },
+ options: { acl: '', _layout_fitWidth: true, _layout_nativeDimEditable: true },
+});
diff --git a/src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx b/src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx
index d54a175b2..f4ece627f 100644
--- a/src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx
+++ b/src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx
@@ -1,35 +1,44 @@
-import * as React from "react";
+import * as React from 'react';
export const slowSpeedIcon: JSX.Element = (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 435.62">
<defs>
- <style type="text/css">
- {`
+ <style type="text/css">
+ {`
.fil0 { fill: black; fill-rule: nonzero; }
.fil1 { fill: #FE0000; fill-rule: nonzero; }
`}
- </style>
+ </style>
</defs>
- <path className="fil0" d="M174.84 343.06c-7.31,-13.12 -13.03,-27.28 -16.89,-42.18 -3.76,-14.56 -5.77,-29.71 -5.77,-45.17 0,-11.94 1.19,-23.66 3.43,-35.03 2.29,-11.57 5.74,-22.83 10.2,-33.63 13.7,-33.14 37.01,-61.29 66.42,-80.96 25.38,-16.96 55.28,-27.66 87.45,-29.87l0 -30.17c0,-0.46 0.02,-0.92 0.06,-1.37l-33.7 0c-5.53,0 -10.05,-4.52 -10.05,-10.04l0 -24.59c0,-5.53 4.52,-10.05 10.05,-10.05l101.27 0c5.53,0 10.05,4.52 10.05,10.05l0 24.59c0,5.52 -4.52,10.04 -10.05,10.04l-33.69 0c0.03,0.45 0.05,0.91 0.05,1.37l0 31.03 -0.1 0c41.1,4.89 77.94,23.63 105.73,51.42 32.56,32.55 52.7,77.54 52.7,127.21 0,49.67 -20.14,94.66 -52.7,127.21 -32.55,32.55 -77.54,52.7 -127.21,52.7 -33.16,0 -64.29,-9.04 -91.05,-24.78 -27.66,-16.27 -50.59,-39.73 -66.2,-67.78zm148.42 -36.62l-80.33 0 0 -25.71 28.6 0 0 -42.57 -28.6 1.93 0 -25.71 36.95 -8.35 25.38 0 0 74.7 18 0 0 25.71zm44.34 -100.41l11.08 26.83 1.61 0 11.09 -26.83 34.86 0 -22.33 48.52 22.33 51.89 -35.67 0 -12.05 -28.92 -1.44 0 -11.89 28.92 -34.06 0 21.85 -50.93 -21.85 -49.48 36.47 0zm126.08 -74.6c6.98,-16.66 6.15,-34.13 -3.84,-45.82 -12,-14.03 -33.67,-15.64 -53.8,-5.77 21.32,14.62 40.68,31.63 57.64,51.59zm-323.17 0c-6.98,-16.66 -6.16,-34.13 3.84,-45.82 11.99,-14.03 33.67,-15.64 53.79,-5.77 -21.32,14.62 -40.68,31.63 -57.63,51.59zm15.31 162.23c3.23,12.5 8.04,24.39 14.18,35.42 13.13,23.58 32.39,43.29 55.6,56.94 22.37,13.16 48.52,20.71 76.49,20.71 41.71,0 79.47,-16.9 106.8,-44.23 27.32,-27.32 44.23,-65.08 44.23,-106.79 0,-41.71 -16.91,-79.47 -44.23,-106.8 -27.33,-27.32 -65.09,-44.23 -106.8,-44.23 -31.07,0 -59.91,9.34 -83.84,25.33 -24.74,16.54 -44.33,40.19 -55.82,67.98 -3.68,8.91 -6.56,18.35 -8.5,28.22 -1.87,9.49 -2.86,19.36 -2.86,29.5 0,13.24 1.65,25.96 4.75,37.95z"/>
- <path className="fil1" d="M55.23 188.52c-7.98,0 -14.45,-6.47 -14.45,-14.44 0,-7.98 6.47,-14.45 14.45,-14.45l63.94 0c7.98,0 14.45,6.47 14.45,14.45 0,7.97 -6.47,14.44 -14.45,14.44l-63.94 0zm0.72 167.68c-7.97,0 -14.44,-6.47 -14.44,-14.45 0,-7.97 6.47,-14.45 14.44,-14.45l64.58 0c7.97,0 14.45,6.48 14.45,14.45 0,7.98 -6.48,14.45 -14.45,14.45l-64.58 0zm-41.5 -84.94c-7.98,0 -14.45,-6.47 -14.45,-14.45 0,-7.97 6.47,-14.44 14.45,-14.44l89.12 0c7.98,0 14.45,6.47 14.45,14.44 0,7.98 -6.47,14.45 -14.45,14.45l-89.12 0z"/>
+ <path
+ className="fil0"
+ d="M174.84 343.06c-7.31,-13.12 -13.03,-27.28 -16.89,-42.18 -3.76,-14.56 -5.77,-29.71 -5.77,-45.17 0,-11.94 1.19,-23.66 3.43,-35.03 2.29,-11.57 5.74,-22.83 10.2,-33.63 13.7,-33.14 37.01,-61.29 66.42,-80.96 25.38,-16.96 55.28,-27.66 87.45,-29.87l0 -30.17c0,-0.46 0.02,-0.92 0.06,-1.37l-33.7 0c-5.53,0 -10.05,-4.52 -10.05,-10.04l0 -24.59c0,-5.53 4.52,-10.05 10.05,-10.05l101.27 0c5.53,0 10.05,4.52 10.05,10.05l0 24.59c0,5.52 -4.52,10.04 -10.05,10.04l-33.69 0c0.03,0.45 0.05,0.91 0.05,1.37l0 31.03 -0.1 0c41.1,4.89 77.94,23.63 105.73,51.42 32.56,32.55 52.7,77.54 52.7,127.21 0,49.67 -20.14,94.66 -52.7,127.21 -32.55,32.55 -77.54,52.7 -127.21,52.7 -33.16,0 -64.29,-9.04 -91.05,-24.78 -27.66,-16.27 -50.59,-39.73 -66.2,-67.78zm148.42 -36.62l-80.33 0 0 -25.71 28.6 0 0 -42.57 -28.6 1.93 0 -25.71 36.95 -8.35 25.38 0 0 74.7 18 0 0 25.71zm44.34 -100.41l11.08 26.83 1.61 0 11.09 -26.83 34.86 0 -22.33 48.52 22.33 51.89 -35.67 0 -12.05 -28.92 -1.44 0 -11.89 28.92 -34.06 0 21.85 -50.93 -21.85 -49.48 36.47 0zm126.08 -74.6c6.98,-16.66 6.15,-34.13 -3.84,-45.82 -12,-14.03 -33.67,-15.64 -53.8,-5.77 21.32,14.62 40.68,31.63 57.64,51.59zm-323.17 0c-6.98,-16.66 -6.16,-34.13 3.84,-45.82 11.99,-14.03 33.67,-15.64 53.79,-5.77 -21.32,14.62 -40.68,31.63 -57.63,51.59zm15.31 162.23c3.23,12.5 8.04,24.39 14.18,35.42 13.13,23.58 32.39,43.29 55.6,56.94 22.37,13.16 48.52,20.71 76.49,20.71 41.71,0 79.47,-16.9 106.8,-44.23 27.32,-27.32 44.23,-65.08 44.23,-106.79 0,-41.71 -16.91,-79.47 -44.23,-106.8 -27.33,-27.32 -65.09,-44.23 -106.8,-44.23 -31.07,0 -59.91,9.34 -83.84,25.33 -24.74,16.54 -44.33,40.19 -55.82,67.98 -3.68,8.91 -6.56,18.35 -8.5,28.22 -1.87,9.49 -2.86,19.36 -2.86,29.5 0,13.24 1.65,25.96 4.75,37.95z"
+ />
+ <path
+ className="fil1"
+ d="M55.23 188.52c-7.98,0 -14.45,-6.47 -14.45,-14.44 0,-7.98 6.47,-14.45 14.45,-14.45l63.94 0c7.98,0 14.45,6.47 14.45,14.45 0,7.97 -6.47,14.44 -14.45,14.44l-63.94 0zm0.72 167.68c-7.97,0 -14.44,-6.47 -14.44,-14.45 0,-7.97 6.47,-14.45 14.44,-14.45l64.58 0c7.97,0 14.45,6.48 14.45,14.45 0,7.98 -6.48,14.45 -14.45,14.45l-64.58 0zm-41.5 -84.94c-7.98,0 -14.45,-6.47 -14.45,-14.45 0,-7.97 6.47,-14.44 14.45,-14.44l89.12 0c7.98,0 14.45,6.47 14.45,14.44 0,7.98 -6.47,14.45 -14.45,14.45l-89.12 0z"
+ />
</svg>
);
export const mediumSpeedIcon: JSX.Element = (
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 122.88 104.55">
- <defs><style>{`.cls-1{fill:#fe0000;}`}</style></defs>
- <path d="M42,82.34a42.82,42.82,0,0,1-4.05-10.13A43.2,43.2,0,0,1,76.72,18.29V11.05c0-.11,0-.22,0-.33H68.65a2.41,2.41,0,0,1-2.41-2.41V2.41A2.41,2.41,0,0,1,68.65,0H93a2.42,2.42,0,0,1,2.42,2.41v5.9A2.42,2.42,0,0,1,93,10.72H84.87c0,.11,0,.22,0,.33V18.5h0A43.17,43.17,0,1,1,42,82.34ZM88.22,49.45l2.66,6.44h.39l2.66-6.44h8.37L96.94,61.09l5.36,12.45H93.74L90.85,66.6H90.5l-2.85,6.94H79.47l5.25-12.22L79.47,49.45ZM58.65,56.08l-1-5.75a33.58,33.58,0,0,1,9.68-1.46c1.28,0,2.35,0,3.22.11a11.77,11.77,0,0,1,2.67.58,5.41,5.41,0,0,1,2.2,1.28c1.24,1.23,1.85,3.12,1.85,5.66s-.72,4.42-2.16,5.63S70.64,64.73,66,66.3v1.08H76.89v6.16H57.11V68.72a10.73,10.73,0,0,1,.81-4.12,8.4,8.4,0,0,1,2.43-2.7,12.13,12.13,0,0,1,2.79-1.7l3.32-1.52c1-.47,1.88-.87,2.52-1.17V55.42a28.59,28.59,0,0,0-3.2-.19,30.66,30.66,0,0,0-7.13.85Zm59.83-24.54c1.68-4,1.48-8.19-.92-11-2.88-3.37-8.08-3.76-12.91-1.39a69.74,69.74,0,0,1,13.83,12.38Zm-77.56,0c-1.67-4-1.48-8.19.92-11,2.88-3.37,8.08-3.76,12.91-1.39A70,70,0,0,0,40.92,31.54ZM44.6,70.48A36,36,0,0,0,48,79a35.91,35.91,0,1,0-3.4-8.5Z"/>
- <path className="cls-1" d="M13.25,45.25a3.47,3.47,0,0,1,0-6.94H28.6a3.47,3.47,0,0,1,0,6.94Z"/>
- <path className="cls-1" d="M3.47,65.1a3.47,3.47,0,1,1,0-6.93H24.86a3.47,3.47,0,0,1,0,6.93Z"/>
- <path className="cls-1" d="M13.43,85.49a3.47,3.47,0,1,1,0-6.94h15.5a3.47,3.47,0,0,1,0,6.94Z"/>
+ <defs>
+ <style>{`.cls-1{fill:#fe0000;}`}</style>
+ </defs>
+ <path d="M42,82.34a42.82,42.82,0,0,1-4.05-10.13A43.2,43.2,0,0,1,76.72,18.29V11.05c0-.11,0-.22,0-.33H68.65a2.41,2.41,0,0,1-2.41-2.41V2.41A2.41,2.41,0,0,1,68.65,0H93a2.42,2.42,0,0,1,2.42,2.41v5.9A2.42,2.42,0,0,1,93,10.72H84.87c0,.11,0,.22,0,.33V18.5h0A43.17,43.17,0,1,1,42,82.34ZM88.22,49.45l2.66,6.44h.39l2.66-6.44h8.37L96.94,61.09l5.36,12.45H93.74L90.85,66.6H90.5l-2.85,6.94H79.47l5.25-12.22L79.47,49.45ZM58.65,56.08l-1-5.75a33.58,33.58,0,0,1,9.68-1.46c1.28,0,2.35,0,3.22.11a11.77,11.77,0,0,1,2.67.58,5.41,5.41,0,0,1,2.2,1.28c1.24,1.23,1.85,3.12,1.85,5.66s-.72,4.42-2.16,5.63S70.64,64.73,66,66.3v1.08H76.89v6.16H57.11V68.72a10.73,10.73,0,0,1,.81-4.12,8.4,8.4,0,0,1,2.43-2.7,12.13,12.13,0,0,1,2.79-1.7l3.32-1.52c1-.47,1.88-.87,2.52-1.17V55.42a28.59,28.59,0,0,0-3.2-.19,30.66,30.66,0,0,0-7.13.85Zm59.83-24.54c1.68-4,1.48-8.19-.92-11-2.88-3.37-8.08-3.76-12.91-1.39a69.74,69.74,0,0,1,13.83,12.38Zm-77.56,0c-1.67-4-1.48-8.19.92-11,2.88-3.37,8.08-3.76,12.91-1.39A70,70,0,0,0,40.92,31.54ZM44.6,70.48A36,36,0,0,0,48,79a35.91,35.91,0,1,0-3.4-8.5Z" />
+ <path className="cls-1" d="M13.25,45.25a3.47,3.47,0,0,1,0-6.94H28.6a3.47,3.47,0,0,1,0,6.94Z" />
+ <path className="cls-1" d="M3.47,65.1a3.47,3.47,0,1,1,0-6.93H24.86a3.47,3.47,0,0,1,0,6.93Z" />
+ <path className="cls-1" d="M13.43,85.49a3.47,3.47,0,1,1,0-6.94h15.5a3.47,3.47,0,0,1,0,6.94Z" />
</svg>
);
export const fastSpeedIcon: JSX.Element = (
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 122.88 104.55">
- <defs><style>{`.cls-1{fill:#fe0000;`}</style></defs>
- <path d="M42,82.34a42.82,42.82,0,0,1-4.05-10.13A43.2,43.2,0,0,1,76.72,18.29V11.05c0-.11,0-.22,0-.33H68.65a2.41,2.41,0,0,1-2.41-2.41V2.41A2.41,2.41,0,0,1,68.65,0H93a2.42,2.42,0,0,1,2.42,2.41v5.9A2.42,2.42,0,0,1,93,10.72H84.87c0,.11,0,.22,0,.33V18.5h0A43.17,43.17,0,1,1,42,82.34ZM88.22,49.61l2.66,6.44h.39l2.66-6.44h8.37L96.94,61.26l5.36,12.45H93.74l-2.9-6.94H90.5l-2.86,6.94H79.47l5.24-12.22L79.47,49.61Zm-19,8.48v-2.5a24.92,24.92,0,0,0-3.74-.2A33.25,33.25,0,0,0,59,56.2l-1-5.7A30.47,30.47,0,0,1,67.13,49a22.86,22.86,0,0,1,5.48.47,6.91,6.91,0,0,1,2.5,1.11,5.62,5.62,0,0,1,1.78,4.55,5.84,5.84,0,0,1-3.2,5.56v.19a5.73,5.73,0,0,1,3.81,5.74,8.67,8.67,0,0,1-.63,3.49,6,6,0,0,1-1.6,2.24,7.15,7.15,0,0,1-2.55,1.25,25.64,25.64,0,0,1-6.61.66,37.78,37.78,0,0,1-8.54-1l1.08-6.37a27.22,27.22,0,0,0,6.21.89,35.79,35.79,0,0,0,4.35-.23V65.11l-6.63-.65V58.87l6.63-.78Zm49.27-26.55c1.68-4,1.48-8.19-.92-11-2.88-3.37-8.08-3.76-12.91-1.39a69.74,69.74,0,0,1,13.83,12.38Zm-77.56,0c-1.67-4-1.48-8.19.92-11,2.88-3.37,8.08-3.76,12.91-1.39A70,70,0,0,0,40.92,31.54ZM44.6,70.48A36,36,0,0,0,48,79a35.91,35.91,0,1,0-3.4-8.5Z"/>
- <path className="cls-1" d="M13.25,45.25a3.47,3.47,0,0,1,0-6.94H28.6a3.47,3.47,0,0,1,0,6.94Zm.18,40.24a3.47,3.47,0,1,1,0-6.94h15.5a3.47,3.47,0,0,1,0,6.94ZM3.47,65.1a3.47,3.47,0,1,1,0-6.93H24.86a3.47,3.47,0,0,1,0,6.93Z"/>
+ <defs>
+ <style>{`.cls-1{fill:#fe0000;`}</style>
+ </defs>
+ <path d="M42,82.34a42.82,42.82,0,0,1-4.05-10.13A43.2,43.2,0,0,1,76.72,18.29V11.05c0-.11,0-.22,0-.33H68.65a2.41,2.41,0,0,1-2.41-2.41V2.41A2.41,2.41,0,0,1,68.65,0H93a2.42,2.42,0,0,1,2.42,2.41v5.9A2.42,2.42,0,0,1,93,10.72H84.87c0,.11,0,.22,0,.33V18.5h0A43.17,43.17,0,1,1,42,82.34ZM88.22,49.61l2.66,6.44h.39l2.66-6.44h8.37L96.94,61.26l5.36,12.45H93.74l-2.9-6.94H90.5l-2.86,6.94H79.47l5.24-12.22L79.47,49.61Zm-19,8.48v-2.5a24.92,24.92,0,0,0-3.74-.2A33.25,33.25,0,0,0,59,56.2l-1-5.7A30.47,30.47,0,0,1,67.13,49a22.86,22.86,0,0,1,5.48.47,6.91,6.91,0,0,1,2.5,1.11,5.62,5.62,0,0,1,1.78,4.55,5.84,5.84,0,0,1-3.2,5.56v.19a5.73,5.73,0,0,1,3.81,5.74,8.67,8.67,0,0,1-.63,3.49,6,6,0,0,1-1.6,2.24,7.15,7.15,0,0,1-2.55,1.25,25.64,25.64,0,0,1-6.61.66,37.78,37.78,0,0,1-8.54-1l1.08-6.37a27.22,27.22,0,0,0,6.21.89,35.79,35.79,0,0,0,4.35-.23V65.11l-6.63-.65V58.87l6.63-.78Zm49.27-26.55c1.68-4,1.48-8.19-.92-11-2.88-3.37-8.08-3.76-12.91-1.39a69.74,69.74,0,0,1,13.83,12.38Zm-77.56,0c-1.67-4-1.48-8.19.92-11,2.88-3.37,8.08-3.76,12.91-1.39A70,70,0,0,0,40.92,31.54ZM44.6,70.48A36,36,0,0,0,48,79a35.91,35.91,0,1,0-3.4-8.5Z" />
+ <path className="cls-1" d="M13.25,45.25a3.47,3.47,0,0,1,0-6.94H28.6a3.47,3.47,0,0,1,0,6.94Zm.18,40.24a3.47,3.47,0,1,1,0-6.94h15.5a3.47,3.47,0,0,1,0,6.94ZM3.47,65.1a3.47,3.47,0,1,1,0-6.93H24.86a3.47,3.47,0,0,1,0,6.93Z" />
</svg>
);
-
diff --git a/src/client/views/nodes/MapBox/AnimationUtility.ts b/src/client/views/nodes/MapBox/AnimationUtility.ts
index 35153f439..f4bae66bb 100644
--- a/src/client/views/nodes/MapBox/AnimationUtility.ts
+++ b/src/client/views/nodes/MapBox/AnimationUtility.ts
@@ -87,25 +87,24 @@ export class AnimationUtility {
@computed get currentPitch(): number {
if (!this.isStreetViewAnimation) return 50;
if (!this.terrainDisplayed) return 80;
- else {
- // const groundElevation = 0;
- const heightAboveGround = this.currentAnimationAltitude;
- const horizontalDistance = 500;
-
- let pitch;
- if (heightAboveGround >= 0) {
- pitch = 90 - Math.atan(heightAboveGround / horizontalDistance) * (180 / Math.PI);
- } else {
- pitch = 80;
- }
- console.log(Math.max(50, Math.min(pitch, 85)));
+ // const groundElevation = 0;
+ const heightAboveGround = this.currentAnimationAltitude;
+ const horizontalDistance = 500;
- if (this.previousPitch) {
- return this.lerp(Math.max(50, Math.min(pitch, 85)), this.previousPitch, 0.02);
- }
- return Math.max(50, Math.min(pitch, 85));
+ let pitch;
+ if (heightAboveGround >= 0) {
+ pitch = 90 - Math.atan(heightAboveGround / horizontalDistance) * (180 / Math.PI);
+ } else {
+ pitch = 80;
+ }
+
+ console.log(Math.max(50, Math.min(pitch, 85)));
+
+ if (this.previousPitch) {
+ return this.lerp(Math.max(50, Math.min(pitch, 85)), this.previousPitch, 0.02);
}
+ return Math.max(50, Math.min(pitch, 85));
}
@computed get flyInEndPitch() {
@@ -214,8 +213,9 @@ export class AnimationUtility {
currentAnimationPhase: number;
updateAnimationPhase: (newAnimationPhase: number) => void;
updateFrameId: (newFrameId: number) => void;
- }) => {
- return new Promise<void>(async resolve => {
+ }) =>
+ // eslint-disable-next-line no-async-promise-executor
+ new Promise<void>(async resolve => {
let startTime: number | null = null;
const frame = async (currentTime: number) => {
@@ -257,7 +257,7 @@ export class AnimationUtility {
updateAnimationPhase(animationPhase);
// compute corrected camera ground position, so that he leading edge of the path is in view
- var correctedPosition = this.computeCameraPosition(
+ const correctedPosition = this.computeCameraPosition(
this.isStreetViewAnimation,
this.currentPitch,
bearing,
@@ -277,7 +277,7 @@ export class AnimationUtility {
map.setFreeCameraOptions(camera);
this.previousAltitude = this.currentAnimationAltitude;
- this.previousPitch = this.previousPitch;
+ // this.previousPitch = this.previousPitch;
// repeat!
const innerFrameId = await window.requestAnimationFrame(frame);
@@ -287,15 +287,15 @@ export class AnimationUtility {
const outerFrameId = await window.requestAnimationFrame(frame);
updateFrameId(outerFrameId);
});
- };
- public flyInAndRotate = async ({ map, updateFrameId }: { map: MapRef; updateFrameId: (newFrameId: number) => void }) => {
- return new Promise<{ bearing: number; altitude: number }>(async resolve => {
+ public flyInAndRotate = async ({ map, updateFrameId }: { map: MapRef; updateFrameId: (newFrameId: number) => void }) =>
+ // eslint-disable-next-line no-async-promise-executor
+ new Promise<{ bearing: number; altitude: number }>(async resolve => {
let start: number | null;
- var currentAltitude;
- var currentBearing;
- var currentPitch;
+ let currentAltitude;
+ let currentBearing;
+ let currentPitch;
// the animation frame will run as many times as necessary until the duration has been reached
const frame = async (time: number) => {
@@ -319,7 +319,7 @@ export class AnimationUtility {
currentPitch = this.FLY_IN_START_PITCH + (this.flyInEndPitch - this.FLY_IN_START_PITCH) * d3.easeCubicOut(animationPhase);
// compute corrected camera ground position, so the start of the path is always in view
- var correctedPosition = this.computeCameraPosition(false, currentPitch, currentBearing, this.FIRST_LNG_LAT, currentAltitude);
+ const correctedPosition = this.computeCameraPosition(false, currentPitch, currentBearing, this.FIRST_LNG_LAT, currentAltitude);
// set the pitch and bearing of the camera
const camera = map.getFreeCameraOptions();
@@ -349,13 +349,10 @@ export class AnimationUtility {
const outerFrameId = await window.requestAnimationFrame(frame);
updateFrameId(outerFrameId);
});
- };
previousCameraPosition: { lng: number; lat: number } | null = null;
- lerp = (start: number, end: number, amt: number) => {
- return (1 - amt) * start + amt * end;
- };
+ lerp = (start: number, end: number, amt: number) => (1 - amt) * start + amt * end;
computeCameraPosition = (isStreetViewAnimation: boolean, pitch: number, bearing: number, targetPosition: { lng: number; lat: number }, altitude: number, smooth = false) => {
const bearingInRadian = (bearing * Math.PI) / 180;
diff --git a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
index 7e99795b5..b8fd8ac6a 100644
--- a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
@@ -4,15 +4,17 @@ import { IconButton } from 'browndash-components';
import { IReactionDisposer, ObservableMap, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { returnFalse, unimplementedFunction } from '../../../../Utils';
+import { returnFalse } from '../../../../ClientUtils';
+import { unimplementedFunction } from '../../../../Utils';
import { Doc, Opt } from '../../../../fields/Doc';
import { NumCast, StrCast } from '../../../../fields/Types';
-import { SelectionManager } from '../../../util/SelectionManager';
import { SettingsManager } from '../../../util/SettingsManager';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
+import { DocumentView } from '../DocumentView';
@observer
export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
+ // eslint-disable-next-line no-use-before-define
static Instance: DirectionsAnchorMenu;
private _disposer: IReactionDisposer | undefined;
@@ -23,8 +25,8 @@ export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
public OnClick: (e: PointerEvent) => void = unimplementedFunction;
// public OnAudio: (e: PointerEvent) => void = unimplementedFunction;
public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
- public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
- public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => undefined;
+ public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = () => undefined;
+ public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
public Delete: () => void = unimplementedFunction;
// public MakeTargetToggle: () => void = unimplementedFunction;
// public ShowTargetTrail: () => void = unimplementedFunction;
@@ -54,8 +56,8 @@ export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
componentDidMount() {
this._disposer = reaction(
- () => SelectionManager.Views.slice(),
- sel => DirectionsAnchorMenu.Instance.fadeOut(true)
+ () => DocumentView.Selected().slice(),
+ () => DirectionsAnchorMenu.Instance.fadeOut(true)
);
}
// audioDown = (e: React.PointerEvent) => {
@@ -103,8 +105,8 @@ export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
color={SettingsManager.userColor}
/>
- <IconButton tooltip="Animate route" onPointerDown={this.Delete} /**TODO: fix */ icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} color={SettingsManager.userColor} />
- <IconButton tooltip="Add to calendar" onPointerDown={this.Delete} /**TODO: fix */ icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} />
+ <IconButton tooltip="Animate route" onPointerDown={this.Delete} /* *TODO: fix */ icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} color={SettingsManager.userColor} />
+ <IconButton tooltip="Add to calendar" onPointerDown={this.Delete} /* *TODO: fix */ icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} />
</div>
);
diff --git a/src/client/views/nodes/MapBox/GeocoderControl.tsx b/src/client/views/nodes/MapBox/GeocoderControl.tsx
index e4ba51316..e118c57d9 100644
--- a/src/client/views/nodes/MapBox/GeocoderControl.tsx
+++ b/src/client/views/nodes/MapBox/GeocoderControl.tsx
@@ -3,8 +3,6 @@
// import { ControlPosition, MarkerProps, useControl } from "react-map-gl";
// import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'
-
-
// export type GeocoderControlProps = Omit<GeocoderOptions, 'accessToken' | 'mapboxgl' | 'marker'> & {
// mapboxAccessToken: string;
// marker?: Omit<MarkerProps, 'longitude' | 'latitude'>;
@@ -31,7 +29,6 @@
// ctrl.on('results', props.onResults);
// ctrl.on('result', evt => {
// props.onResult(evt);
-
// // const {result} = evt;
// // const location =
// // result &&
@@ -49,8 +46,6 @@
// position: props.position
// }
// );
-
-
// // @ts-ignore (TS2339) private member
// if (geocoder._map) {
// if (geocoder.getProximity() !== props.proximity && props.proximity !== undefined) {
@@ -104,4 +99,4 @@
// onLoading: noop,
// onResults: noop,
// onError: noop
-// }; \ No newline at end of file
+// };
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
index 08bea5d9d..103a35434 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/button-has-type */
import { IconLookup, faAdd, faArrowDown, faArrowLeft, faArrowsRotate, faBicycle, faCalendarDays, faCar, faDiamondTurnRight, faEdit, faPersonWalking, faRoute } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material';
@@ -7,13 +8,14 @@ import { IReactionDisposer, ObservableMap, action, makeObservable, observable, r
import { observer } from 'mobx-react';
import * as React from 'react';
import { CirclePicker, ColorResult } from 'react-color';
-import { returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../../Utils';
+import { returnFalse, setupMoveUpEvents } from '../../../../ClientUtils';
+import { unimplementedFunction } from '../../../../Utils';
import { Doc, Opt } from '../../../../fields/Doc';
import { NumCast, StrCast } from '../../../../fields/Types';
import { CalendarManager } from '../../../util/CalendarManager';
-import { SelectionManager } from '../../../util/SelectionManager';
import { SettingsManager } from '../../../util/SettingsManager';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
+import { DocumentView } from '../DocumentView';
import './MapAnchorMenu.scss';
import { MapboxApiUtility, TransportationType } from './MapboxApiUtility';
import { MarkerIcons } from './MarkerIcons';
@@ -23,6 +25,7 @@ type MapAnchorMenuType = 'standard' | 'routeCreation' | 'calendar' | 'customize'
@observer
export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
+ // eslint-disable-next-line no-use-before-define
static Instance: MapAnchorMenu;
private _disposer: IReactionDisposer | undefined;
@@ -35,8 +38,8 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
public OnClick: (e: PointerEvent) => void = unimplementedFunction;
// public OnAudio: (e: PointerEvent) => void = unimplementedFunction;
public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
- public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
- public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => undefined;
+ public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = () => undefined;
+ public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
public Delete: () => void = unimplementedFunction;
// public MakeTargetToggle: () => void = unimplementedFunction;
// public ShowTargetTrail: () => void = unimplementedFunction;
@@ -123,8 +126,8 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
componentDidMount() {
this._disposer = reaction(
- () => SelectionManager.Views.slice(),
- sel => MapAnchorMenu.Instance.fadeOut(true)
+ () => DocumentView.Selected().slice(),
+ () => MapAnchorMenu.Instance.fadeOut(true)
);
}
// audioDown = (e: React.PointerEvent) => {
@@ -147,12 +150,12 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
setupMoveUpEvents(
this,
e,
- (e: PointerEvent) => {
- this.StartDrag(e, this._commentRef.current!);
+ moveEv => {
+ this.StartDrag(moveEv, this._commentRef.current!);
return true;
},
returnFalse,
- e => this.OnClick(e)
+ clickEv => this.OnClick(clickEv)
);
};
@@ -274,7 +277,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
HandleAddRouteClick = () => {
if (this.currentRouteInfoMap && this.selectedTransportationType && this.selectedDestinationFeature) {
- const coordinates = this.currentRouteInfoMap[this.selectedTransportationType].coordinates;
+ const { coordinates } = this.currentRouteInfoMap[this.selectedTransportationType];
console.log(coordinates);
console.log(this.selectedDestinationFeature);
this.AddNewRouteToMap(coordinates, this.title ?? '', this.selectedDestinationFeature, this.createPinForDestination);
@@ -293,34 +296,30 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
getDirectionsButton: JSX.Element = (<IconButton tooltip="Get directions" onPointerDown={this.DirectionsClick} icon={<FontAwesomeIcon icon={faDiamondTurnRight as IconLookup} />} color={SettingsManager.userColor} />);
- getAddToCalendarButton = (docType: string): JSX.Element => {
- return (
- <IconButton
- tooltip="Add to calendar"
- onPointerDown={() => {
- CalendarManager.Instance.open(undefined, docType === 'pin' ? this.pinDoc : this.routeDoc);
- }}
- icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />}
- color={SettingsManager.userColor}
- />
- );
- };
+ getAddToCalendarButton = (docType: string): JSX.Element => (
+ <IconButton
+ tooltip="Add to calendar"
+ onPointerDown={() => {
+ CalendarManager.Instance.open(undefined, docType === 'pin' ? this.pinDoc : this.routeDoc);
+ }}
+ icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />}
+ color={SettingsManager.userColor}
+ />
+ );
addToCalendarButton: JSX.Element = (
<IconButton tooltip="Add to calendar" onPointerDown={() => CalendarManager.Instance.open(undefined, this.pinDoc)} icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} />
);
- getLinkNoteToDocButton = (docType: string): JSX.Element => {
- return (
- <div ref={this._commentRef}>
- <IconButton
- tooltip={`Link Note to ${docType === 'pin' ? 'Pin' : 'Route'}`} //
- onPointerDown={this.notePointerDown}
- icon={<FontAwesomeIcon icon="sticky-note" />}
- color={SettingsManager.userColor}
- />
- </div>
- );
- };
+ getLinkNoteToDocButton = (docType: string): JSX.Element => (
+ <div ref={this._commentRef}>
+ <IconButton
+ tooltip={`Link Note to ${docType === 'pin' ? 'Pin' : 'Route'}`} //
+ onPointerDown={this.notePointerDown}
+ icon={<FontAwesomeIcon icon="sticky-note" />}
+ color={SettingsManager.userColor}
+ />
+ </div>
+ );
linkNoteToPinOrRoutenButton: JSX.Element = (
<div ref={this._commentRef}>
@@ -362,16 +361,14 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
/>
);
- getDeleteButton = (type: string) => {
- return (
- <IconButton
- tooltip={`Delete ${type === 'pin' ? 'Pin' : 'Route'}`} //
- onPointerDown={this.Delete}
- icon={<FontAwesomeIcon icon="trash-alt" />}
- color={SettingsManager.userColor}
- />
- );
- };
+ getDeleteButton = (type: string) => (
+ <IconButton
+ tooltip={`Delete ${type === 'pin' ? 'Pin' : 'Route'}`} //
+ onPointerDown={this.Delete}
+ icon={<FontAwesomeIcon icon="trash-alt" />}
+ color={SettingsManager.userColor}
+ />
+ );
animateRouteButton: JSX.Element = (<IconButton tooltip="Animate route" onPointerDown={() => this.OpenAnimationPanel(this.routeDoc)} icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} color={SettingsManager.userColor} />);
@@ -452,18 +449,17 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
}}
options={this.destinationFeatures.filter(feature => feature.place_name).map(feature => feature)}
getOptionLabel={(feature: any) => feature.place_name}
+ // eslint-disable-next-line react/jsx-props-no-spreading
renderInput={(params: any) => <TextField {...params} placeholder="Enter a destination" />}
/>
- {this.selectedDestinationFeature && (
- <>
- {!this.allMapPinDocs.some(pinDoc => pinDoc.title === this.selectedDestinationFeature.place_name) && (
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '5px' }}>
- <FormControlLabel label="Create pin for destination?" control={<Checkbox color="success" checked={this.createPinForDestination} onChange={this.toggleCreatePinForDestinationCheckbox} />} />
- </div>
- )}
- </>
- )}
- <button id="get-routes-button" disabled={this.selectedDestinationFeature ? false : true} onClick={() => this.getRoutes(this.selectedDestinationFeature)}>
+ {!this.selectedDestinationFeature
+ ? null
+ : !this.allMapPinDocs.some(pinDoc => pinDoc.title === this.selectedDestinationFeature.place_name) && (
+ <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '5px' }}>
+ <FormControlLabel label="Create pin for destination?" control={<Checkbox color="success" checked={this.createPinForDestination} onChange={this.toggleCreatePinForDestinationCheckbox} />} />
+ </div>
+ )}
+ <button id="get-routes-button" disabled={!this.selectedDestinationFeature} onClick={() => this.getRoutes(this.selectedDestinationFeature)}>
Get routes
</button>
@@ -516,7 +512,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
</div>
))}
</div>
- <div style={{ width: '100%', height: '3px', color: 'white' }}></div>
+ <div style={{ width: '100%', height: '3px', color: 'white' }} />
</div>
)}
{this.menuType === 'route' && this.routeDoc && <div>{StrCast(this.routeDoc.title)}</div>}
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 927e6fad4..d7687e03e 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -1,3 +1,5 @@
+/* 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';
@@ -5,32 +7,30 @@ import * as turf from '@turf/turf';
import { IconButton, Size, Type } from 'browndash-components';
import * as d3 from 'd3';
import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString, Position } from 'geojson';
-import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl';
-import { IReactionDisposer, ObservableMap, action, autorun, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
+import mapboxgl, { LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl';
+import { IReactionDisposer, ObservableMap, action, autorun, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { CirclePicker, ColorResult } from 'react-color';
import { Layer, MapProvider, MapRef, Map as MapboxMap, Marker, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl';
import { MarkerEvent } from 'react-map-gl/dist/esm/types';
-import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../Utils';
+import { ClientUtils, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc';
-import { DocCss, Highlight } from '../../../../fields/DocSymbols';
-import { DocCast, NumCast, StrCast } from '../../../../fields/Types';
+import { DocCast, NumCast, StrCast, toList } from '../../../../fields/Types';
+import { DocUtils } from '../../../documents/DocUtils';
import { DocumentType } from '../../../documents/DocumentTypes';
-import { DocUtils, Docs } from '../../../documents/Documents';
-import { DocumentManager } from '../../../util/DocumentManager';
+import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
-import { LinkManager } from '../../../util/LinkManager';
-import { SnappingManager } from '../../../util/SnappingManager';
import { UndoManager, undoable } from '../../../util/UndoManager';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../../DocComponent';
+import { PinDocView, PinProps } from '../../PinFuncs';
import { SidebarAnnos } from '../../SidebarAnnos';
import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView';
-import { FormattedTextBox } from '../formattedText/FormattedTextBox';
-import { PinProps, PresBox } from '../trails';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import { fastSpeedIcon, mediumSpeedIcon, slowSpeedIcon } from './AnimationSpeedIcons';
import { AnimationSpeed, AnimationStatus, AnimationUtility } from './AnimationUtility';
import { MapAnchorMenu } from './MapAnchorMenu';
@@ -53,11 +53,7 @@ import { MarkerIcons } from './MarkerIcons';
* A map marker is considered a document that contains a collection with stacking view of documents, it has a lat, lng location, which is passed to Maps API's custom marker (red pin) to be rendered on the google maps
*/
-const bingApiKey = process.env.BING_MAPS; // if you're running local, get a Bing Maps api key here: https://www.bingmapsportal.com/ and then add it to the .env file in the Dash-Web root directory as: _CLIENT_BING_MAPS=<your apikey>
const MAPBOX_ACCESS_TOKEN = 'pk.eyJ1IjoiemF1bHRhdmFuZ2FyIiwiYSI6ImNscHgwNDd1MDA3MXIydm92ODdianp6cGYifQ.WFAqbhwxtMHOWSPtu0l2uQ';
-const MAPBOX_FORWARD_GEOCODE_BASE_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places/';
-
-const MAPBOX_REVERSE_GEOCODE_BASE_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places/';
type PopupInfo = {
longitude: number;
@@ -66,72 +62,69 @@ type PopupInfo = {
description: string;
};
-// export type GeocoderControlProps = Omit<GeocoderOptions, 'accessToken' | 'mapboxgl' | 'marker'> & {
-// mapboxAccessToken: string;
-// marker?: Omit<MarkerProps, 'longitude' | 'latitude'>;
-// position: ControlPosition;
-
-// onResult: (...args: any[]) => void;
-// };
-
-type MapMarker = {
- longitude: number;
- latitude: number;
-};
-
-/**
- * Consider integrating later: allows for drawing, circling, making shapes on map
- */
-// const drawingManager = new window.google.maps.drawing.DrawingManager({
-// drawingControl: true,
-// drawingControlOptions: {
-// position: google.maps.ControlPosition.TOP_RIGHT,
-// drawingModes: [
-// google.maps.drawing.OverlayType.MARKER,
-// // currently we are not supporting the following drawing mode on map, a thought for future development
-// google.maps.drawing.OverlayType.CIRCLE,
-// google.maps.drawing.OverlayType.POLYLINE,
-// ],
-// },
-// });
-
@observer
-export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(MapBox, fieldKey);
}
- private _dragRef = React.createRef<HTMLDivElement>();
+ private _unmounting = false;
private _sidebarRef = React.createRef<SidebarAnnos>();
private _ref: React.RefObject<HTMLDivElement> = React.createRef();
private _mapRef: React.RefObject<MapRef> = React.createRef();
private _disposers: { [key: string]: IReactionDisposer } = {};
- private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void);
constructor(props: FieldViewProps) {
super(props);
makeObservable(this);
}
- @observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
- @computed get allSidebarDocs() {
- return DocListCast(this.dataDoc[this.SidebarKey]);
- }
+ @observable _featuresFromGeocodeResults: any[] = [];
+ @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
+ @observable _selectedPinOrRoute: Doc | undefined = undefined; // The pin that is selected
+ @observable _mapReady = false;
+ @observable _isAnimating: boolean = false;
+ @observable _routeToAnimate: Doc | undefined = undefined;
+ @observable _animationPhase: number = 0;
+ @observable _finishedFlyTo: boolean = false;
+ @observable _frameId: number | null = null;
+ @observable _animationUtility: AnimationUtility | null = null;
+ @observable _settingsOpen: boolean = false;
+ @observable _mapStyle: string = 'mapbox://styles/mapbox/standard';
+ @observable _showTerrain: boolean = true;
+ @observable _currentPopup: PopupInfo | undefined = undefined;
+ @observable _isStreetViewAnimation: boolean = false;
+ @observable _animationSpeed: AnimationSpeed = AnimationSpeed.MEDIUM;
+ @observable _animationLineColor: string = '#ffff00';
+ @observable _temporaryRouteSource: FeatureCollection = { type: 'FeatureCollection', features: [] };
+ @observable _dynamicRouteFeature: Feature<Geometry, GeoJsonProperties> = {
+ type: 'Feature',
+ properties: {},
+ geometry: { type: 'LineString', coordinates: [] },
+ };
+
+ @observable path: turf.helpers.Feature<turf.helpers.LineString, turf.helpers.Properties> = {
+ type: 'Feature',
+ geometry: { type: 'LineString', coordinates: [] },
+ properties: {},
+ };
+
// this list contains pushpins and configs
- @computed get allAnnotations() {
- return DocListCast(this.dataDoc[this.annotationKey]);
- }
- @computed get allPushpins() {
- return this.allAnnotations.filter(anno => anno.type === DocumentType.PUSHPIN);
- }
- @computed get allRoutes() {
- return this.allAnnotations.filter(anno => anno.type === DocumentType.MAPROUTE);
+ @computed get allAnnotations() { return DocListCast(this.dataDoc[this.annotationKey]); } // prettier-ignore
+ @computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.SidebarKey]); } // prettier-ignore
+ @computed get allPushpins() { return this.allAnnotations.filter(anno => anno.type === DocumentType.PUSHPIN); } // prettier-ignore
+ @computed get allRoutes() { return this.allAnnotations.filter(anno => anno.type === DocumentType.MAPROUTE); } // prettier-ignore
+ @computed get SidebarShown() { return !!this.layoutDoc._layout_showSidebar; } // prettier-ignore
+ @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); } // prettier-ignore
+ @computed get SidebarKey() { return this.fieldKey + '_sidebar'; } // prettier-ignore
+ @computed get sidebarColor() {
+ return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this._props.fieldKey + '_backgroundColor'], '#e4e4e4'));
}
@computed get updatedRouteCoordinates(): Feature<Geometry, GeoJsonProperties> {
- if (this.routeToAnimate?.routeCoordinates) {
- const originalCoordinates: Position[] = JSON.parse(StrCast(this.routeToAnimate.routeCoordinates));
+ if (this._routeToAnimate?.routeCoordinates) {
+ const originalCoordinates: Position[] = JSON.parse(StrCast(this._routeToAnimate.routeCoordinates));
// const index = Math.floor(this.animationPhase * originalCoordinates.length);
- const index = this.animationPhase * (originalCoordinates.length - 1); // Calculate the fractional index
- console.log('Animation phase', this.animationPhase);
+ const index = this._animationPhase * (originalCoordinates.length - 1); // Calculate the fractional index
+ console.log('Animation phase', this._animationPhase);
const startIndex = Math.floor(index);
const endIndex = Math.ceil(index);
let feature: Feature<Geometry, GeoJsonProperties>;
@@ -147,7 +140,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
feature = {
type: 'Feature',
properties: {
- routeTitle: StrCast(this.routeToAnimate.title),
+ routeTitle: StrCast(this._routeToAnimate.title),
},
geometry: geometry,
};
@@ -158,9 +151,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const fraction = index - startIndex;
const interpolator = d3.interpolateArray(startCoord, endCoord);
-
const interpolatedCoord = interpolator(fraction);
-
const coordinates = originalCoordinates.slice(0, startIndex + 1).concat([interpolatedCoord]);
geometry = {
@@ -170,14 +161,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
feature = {
type: 'Feature',
properties: {
- routeTitle: StrCast(this.routeToAnimate.title),
+ routeTitle: StrCast(this._routeToAnimate.title),
},
geometry: geometry,
};
}
autorun(() => {
- const animationUtil = this.animationUtility;
+ const animationUtil = this._animationUtility;
const concattedCoordinates = geometry.coordinates.concat(originalCoordinates.slice(endIndex));
const newFeature: Feature<LineString, turf.Properties> = {
type: 'Feature',
@@ -204,11 +195,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
};
}
@computed get selectedRouteCoordinates(): Position[] {
- let coordinates: Position[] = [];
- if (this.routeToAnimate?.routeCoordinates) {
- coordinates = JSON.parse(StrCast(this.routeToAnimate.routeCoordinates));
- }
- return coordinates;
+ return !this._routeToAnimate?.routeCoordinates ? [] : JSON.parse(StrCast(this._routeToAnimate.routeCoordinates));
}
@computed get allRoutesGeoJson(): FeatureCollection {
@@ -233,50 +220,34 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
};
}
- @computed get SidebarShown() {
- return this.layoutDoc._layout_showSidebar ? true : false;
- }
- @computed get sidebarWidthPercent() {
- return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%');
- }
- @computed get sidebarColor() {
- return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this._props.fieldKey + '_backgroundColor'], '#e4e4e4'));
- }
- @computed get SidebarKey() {
- return this.fieldKey + '_sidebar';
- }
-
componentDidMount() {
this._unmounting = false;
this._props.setContentViewBox?.(this);
}
- _unmounting = false;
- componentWillUnmount(): void {
+ componentWillUnmount() {
this._unmounting = true;
this.deselectPinOrRoute();
- this._rerenderTimeout && clearTimeout(this._rerenderTimeout);
Object.keys(this._disposers).forEach(key => this._disposers[key]?.());
}
/**
* Called when dragging documents into map sidebar or directly into infowindow; to create a map marker, ref to MapMarkerDocument in Documents.ts
- * @param doc
+ * @param docs
* @param sidebarKey
* @returns
*/
- sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
+ sidebarAddDocument = (docs: Doc | Doc[], sidebarKey?: string) => {
if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar();
- const docs = doc instanceof Doc ? [doc] : doc;
- docs.forEach(doc => {
- let existingPin = this.allPushpins.find(pin => pin.latitude === doc.latitude && pin.longitude === doc.longitude) ?? this.selectedPinOrRoute;
+ toList(docs).forEach(doc => {
+ let existingPin = this.allPushpins.find(pin => pin.latitude === doc.latitude && pin.longitude === doc.longitude) ?? this._selectedPinOrRoute;
if (doc.latitude !== undefined && doc.longitude !== undefined && !existingPin) {
existingPin = this.createPushpin(NumCast(doc.latitude), NumCast(doc.longitude), StrCast(doc.map));
}
if (existingPin) {
setTimeout(() => {
// we use a timeout in case this is called from the sidebar which may have just added a link that hasn't made its way into th elink manager yet
- if (!LinkManager.Instance.getAllRelatedLinks(doc).some(link => DocCast(link.link_anchor_1)?.mapPin === existingPin || DocCast(link.link_anchor_2)?.mapPin === existingPin)) {
+ if (!Doc.Links(doc).some(link => DocCast(link.link_anchor_1)?.mapPin === existingPin || DocCast(link.link_anchor_2)?.mapPin === existingPin)) {
const anchor = this.getAnchor(true, undefined, existingPin);
anchor && DocUtils.MakeLink(anchor, doc, { link_relationship: 'link to map location' });
doc.latitude = existingPin?.latitude;
@@ -284,14 +255,17 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
});
}
- }); //add to annotation list
+ }); // add to annotation list
- return this.addDocument(doc, sidebarKey); // add to sidebar list
+ return this.addDocument(docs, sidebarKey); // add to sidebar list
};
removeMapDocument = (doc: Doc | Doc[], annotationKey?: string) => {
- const docs = doc instanceof Doc ? [doc] : doc;
- this.allAnnotations.filter(anno => docs.includes(DocCast(anno.mapPin))).forEach(anno => (anno.mapPin = undefined));
+ this.allAnnotations
+ .filter(anno => toList(doc).includes(DocCast(anno.mapPin)))
+ .forEach(anno => {
+ anno.mapPin = undefined;
+ });
return this.removeDocument(doc, annotationKey, undefined);
};
@@ -311,7 +285,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
setupMoveUpEvents(
this,
e,
- (e, down, delta) =>
+ (moveEv, down, delta) =>
runInAction(() => {
const localDelta = this._props
.ScreenToLocalTransform()
@@ -351,7 +325,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={this.sidebarBtnDown}>
- <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" />
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon="comment-alt" size="sm" />
</div>
);
}
@@ -370,26 +344,26 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const sourceAnchorCreator = action(() => {
const note = this.getAnchor(true);
- if (note && this.selectedPinOrRoute) {
- note.latitude = this.selectedPinOrRoute.latitude;
- note.longitude = this.selectedPinOrRoute.longitude;
- note.map = this.selectedPinOrRoute.map;
+ if (note && this._selectedPinOrRoute) {
+ note.latitude = this._selectedPinOrRoute.latitude;
+ note.longitude = this._selectedPinOrRoute.longitude;
+ note.map = this._selectedPinOrRoute.map;
}
return note as Doc;
});
const targetCreator = (annotationOn: Doc | undefined) => {
const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, annotationOn, 'yellow');
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
return target;
};
const docView = this.DocumentView?.();
docView &&
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
- dragComplete: e => {
- if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
- e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.Document;
- e.annoDragData.linkSourceDoc.followLinkZoom = false;
+ dragComplete: dragEv => {
+ if (!dragEv.aborted && dragEv.annoDragData && dragEv.annoDragData.linkSourceDoc && dragEv.annoDragData.dropDocument && dragEv.linkDocument) {
+ dragEv.annoDragData.linkSourceDoc.followLinkToggle = dragEv.annoDragData.dropDocument.annotationOn === this.Document;
+ dragEv.annoDragData.linkSourceDoc.followLinkZoom = false;
}
},
});
@@ -399,10 +373,10 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const createFunc = undoable(
action(() => {
const note = this._sidebarRef.current?.anchorMenuClick(this.getAnchor(true), ['latitude', 'longitude', LinkedTo]);
- if (note && this.selectedPinOrRoute) {
- note.latitude = this.selectedPinOrRoute.latitude;
- note.longitude = this.selectedPinOrRoute.longitude;
- note.map = this.selectedPinOrRoute.map;
+ if (note && this._selectedPinOrRoute) {
+ note.latitude = this._selectedPinOrRoute.latitude;
+ note.longitude = this._selectedPinOrRoute.longitude;
+ note.map = this._selectedPinOrRoute.map;
}
}),
'create note annotation'
@@ -415,7 +389,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
sidebarDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), true);
};
- sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => {
+ sidebarMove = (e: PointerEvent) => {
const bounds = this._ref.current!.getBoundingClientRect();
this.layoutDoc._layout_sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%';
this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%';
@@ -423,68 +397,20 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
return false;
};
- setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => (this._setPreviewCursor = func);
-
- addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => this.addDocument(doc, annotationKey);
-
pointerEvents = () => (this._props.isContentActive() && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : 'none');
-
panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth();
panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
scrollXf = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop));
- transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter];
- opaqueFilter = () => [...this._props.childFilters(), Utils.OpaqueBackgroundFilter];
+ transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter];
+ opaqueFilter = () => [...this._props.childFilters(), ClientUtils.OpaqueBackgroundFilter];
infoWidth = () => this._props.PanelWidth() / 5;
infoHeight = () => this._props.PanelHeight() / 5;
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
savedAnnotations = () => this._savedAnnotations;
- _bingSearchManager: any;
- _bingMap: any;
- get MicrosoftMaps() {
- return (window as any).Microsoft.Maps;
- }
- // uses Bing Search to retrieve lat/lng for a location. eg.,
- // const results = this.geocodeQuery(map.map, 'Philadelphia, PA');
- // to move the map to that location:
- // const location = await this.geocodeQuery(this._bingMap, 'Philadelphia, PA');
- // this._bingMap.current.setView({
- // mapTypeId: this.MicrosoftMaps.MapTypeId.aerial,
- // center: new this.MicrosoftMaps.Location(loc.latitude, loc.longitude),
- // });
- //
- bingGeocode = (map: any, query: string) => {
- return new Promise<{ latitude: number; longitude: number }>((res, reject) => {
- //If search manager is not defined, load the search module.
- if (!this._bingSearchManager) {
- //Create an instance of the search manager and call the geocodeQuery function again.
- this.MicrosoftMaps.loadModule('Microsoft.Maps.Search', () => {
- this._bingSearchManager = new this.MicrosoftMaps.Search.SearchManager(map.current);
- res(this.bingGeocode(map, query));
- });
- } else {
- this._bingSearchManager.geocode({
- where: query,
- callback: action((r: any) => res(r.results[0].location)),
- errorCallback: (e: any) => reject(),
- });
- }
- });
- };
-
- @observable
- bingSearchBarContents: any = this.Document.map; // For Bing Maps: The contents of the Bing search bar (string)
-
- geoDataRequestOptions = {
- entityType: 'PopulatedPlace',
- };
-
- // The pin that is selected
- @observable selectedPinOrRoute: Doc | undefined = undefined;
-
@action
deselectPinOrRoute = () => {
- if (this.selectedPinOrRoute) {
+ if (this._selectedPinOrRoute) {
// // Removes filter
// Doc.setDocFilter(this.Document, 'latitude', this.selectedPin.latitude, 'remove');
// Doc.setDocFilter(this.Document, 'longitude', this.selectedPin.longitude, 'remove');
@@ -509,79 +435,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this.toggleSidebar();
options.didMove = true;
}
- return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
- };
- /*
- * Pushpin onclick
- */
- @action
- pushpinClicked = (pinDoc: Doc) => {
- this.deselectPinOrRoute();
- this.selectedPinOrRoute = pinDoc;
- this.bingSearchBarContents = pinDoc.map;
-
- // Doc.setDocFilter(this.Document, 'latitude', this.selectedPin.latitude, 'match');
- // Doc.setDocFilter(this.Document, 'longitude', this.selectedPin.longitude, 'match');
- Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(this.selectedPinOrRoute)}`, 'check');
-
- this.recolorPin(this.selectedPinOrRoute, 'green');
-
- MapAnchorMenu.Instance.Delete = this.deleteSelectedPinOrRoute;
- MapAnchorMenu.Instance.Center = this.centerOnSelectedPin;
- MapAnchorMenu.Instance.OnClick = this.createNoteAnnotation;
- MapAnchorMenu.Instance.StartDrag = this.startAnchorDrag;
-
- const point = this._bingMap.current.tryLocationToPixel(new this.MicrosoftMaps.Location(this.selectedPinOrRoute.latitude, this.selectedPinOrRoute.longitude));
- const x = point.x + (this._props.PanelWidth() - this.sidebarWidth()) / 2;
- const y = point.y + this._props.PanelHeight() / 2 + 32;
- const cpt = this.ScreenToLocalBoxXf().inverse().transformPoint(x, y);
- MapAnchorMenu.Instance.jumpTo(cpt[0], cpt[1], true);
-
- document.addEventListener('pointerdown', this.tryHideMapAnchorMenu, true);
- };
-
- /**
- * Map OnClick
- */
- @action
- mapOnClick = (e: { location: { latitude: any; longitude: any } }) => {
- this._props.select(false);
- this.deselectPinOrRoute();
- };
- /*
- * Updates values of layout doc to match the current map
- */
- @action
- mapRecentered = () => {
- if (
- Math.abs(NumCast(this.dataDoc.latitude) - this._bingMap.current.getCenter().latitude) > 1e-7 || //
- Math.abs(NumCast(this.dataDoc.longitude) - this._bingMap.current.getCenter().longitude) > 1e-7
- ) {
- this.dataDoc.latitude = this._bingMap.current.getCenter().latitude;
- this.dataDoc.longitude = this._bingMap.current.getCenter().longitude;
- this.dataDoc.map = '';
- this.bingSearchBarContents = '';
- }
- this.dataDoc.map_zoom = this._bingMap.current.getZoom();
- };
- /*
- * Updates maptype
- */
- @action
- updateMapType = () => (this.dataDoc.map_type = this._bingMap.current.getMapTypeId());
-
- /*
- * For Bing Maps
- * Called by search button's onClick
- * Finds the geocode of the searched contents and sets location to that location
- **/
- @action
- bingSearch = () => {
- return this.bingGeocode(this._bingMap, this.bingSearchBarContents).then(location => {
- this.dataDoc.latitude = location.latitude;
- this.dataDoc.longitude = location.longitude;
- this.dataDoc.map_zoom = this._bingMap.current.getZoom();
- this.dataDoc.map = this.bingSearchBarContents;
+ return new Promise<Opt<DocumentView>>(res => {
+ DocumentView.addViewRenderedCb(doc, dv => res(dv));
});
};
@@ -592,20 +447,20 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
/// this should use SELECTED pushpin for lat/long if there is a selection, otherwise CENTER
const anchor = Docs.Create.ConfigDocument({
title: 'MapAnchor:' + this.Document.title,
- text: (StrCast(this.selectedPinOrRoute?.map) || StrCast(this.Document.map) || 'map location') as any,
- config_latitude: NumCast((existingPin ?? this.selectedPinOrRoute)?.latitude ?? this.dataDoc.latitude),
- config_longitude: NumCast((existingPin ?? this.selectedPinOrRoute)?.longitude ?? this.dataDoc.longitude),
+ text: (StrCast(this._selectedPinOrRoute?.map) || StrCast(this.Document.map) || 'map location') as any,
+ config_latitude: NumCast((existingPin ?? this._selectedPinOrRoute)?.latitude ?? this.dataDoc.latitude),
+ config_longitude: NumCast((existingPin ?? this._selectedPinOrRoute)?.longitude ?? this.dataDoc.longitude),
config_map_zoom: NumCast(this.dataDoc.map_zoom),
// config_map_type: StrCast(this.dataDoc.map_type),
- config_map: StrCast((existingPin ?? this.selectedPinOrRoute)?.map) || StrCast(this.dataDoc.map),
+ config_map: StrCast((existingPin ?? this._selectedPinOrRoute)?.map) || StrCast(this.dataDoc.map),
layout_unrendered: true,
- mapPin: existingPin ?? this.selectedPinOrRoute,
+ mapPin: existingPin ?? this._selectedPinOrRoute,
annotationOn: this.Document,
});
if (anchor) {
if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
addAsAnnotation && this.addDocument(anchor);
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), map: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), map: true } }, this.Document);
return anchor;
}
return this.Document;
@@ -613,25 +468,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
map_docToPinMap = new Map<Doc, any>();
map_pinHighlighted = new Map<Doc, boolean>();
- /*
- * Input: pin doc
- * Adds MicrosoftMaps Pushpin to the map (render)
- */
- @action
- addPushpin = (pin: Doc) => {
- const pushPin = pin.infoWindowOpen
- ? new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.latitude, pin.longitude), {})
- : new this.MicrosoftMaps.Pushpin(
- new this.MicrosoftMaps.Location(pin.latitude, pin.longitude)
- // {icon: 'http://icons.iconarchive.com/icons/icons-land/vista-map-markers/24/Map-Marker-Marker-Outside-Chartreuse-icon.png'}
- );
-
- this._bingMap.current.entities.push(pushPin);
-
- this.MicrosoftMaps.Events.addHandler(pushPin, 'click', (e: any) => this.pushpinClicked(pin));
- // this.MicrosoftMaps.Events.addHandler(pushPin, 'dblclick', (e: any) => this.pushpinDblClicked(pushPin, pin));
- this.map_docToPinMap.set(pin, pushPin);
- };
/*
* Input: pin doc
@@ -640,27 +476,16 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
@action
removePushpinOrRoute = (pinOrRouteDoc: Doc) => this.removeMapDocument(pinOrRouteDoc, this.annotationKey);
- /*
- * Removes pushpin from map render
- */
- deletePushpin = (pinDoc: Doc) => {
- if (!this._unmounting) {
- this._bingMap.current.entities.remove(this.map_docToPinMap.get(pinDoc));
- }
- this.map_docToPinMap.delete(pinDoc);
- this.selectedPinOrRoute = undefined;
- };
-
@action
deleteSelectedPinOrRoute = undoable(() => {
console.log('deleting');
- if (this.selectedPinOrRoute) {
+ 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, LinkedTo, `mapPin=${Field.toScriptString(DocCast(this.selectedPinOrRoute))}`, 'remove');
+ Doc.setDocFilter(this.Document, 'latitude', this._selectedPinOrRoute.latitude, 'remove');
+ Doc.setDocFilter(this.Document, 'longitude', this._selectedPinOrRoute.longitude, 'remove');
+ Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(DocCast(this._selectedPinOrRoute))}`, 'remove');
- this.removePushpinOrRoute(this.selectedPinOrRoute);
+ this.removePushpinOrRoute(this._selectedPinOrRoute);
}
MapAnchorMenu.Instance.fadeOut(true);
document.removeEventListener('pointerdown', this.tryHideMapAnchorMenu, true);
@@ -677,7 +502,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
e.preventDefault();
MapAnchorMenu.Instance.fadeOut(true);
runInAction(() => {
- this.temporaryRouteSource = {
+ this._temporaryRouteSource = {
type: 'FeatureCollection',
features: [],
};
@@ -688,9 +513,9 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
@action
centerOnSelectedPin = () => {
- if (this.selectedPinOrRoute) {
+ if (this._selectedPinOrRoute) {
this._mapRef.current?.flyTo({
- center: [NumCast(this.selectedPinOrRoute.longitude), NumCast(this.selectedPinOrRoute.latitude)],
+ center: [NumCast(this._selectedPinOrRoute.longitude), NumCast(this._selectedPinOrRoute.latitude)],
});
}
// if (this.selectedPin) {
@@ -703,33 +528,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
document.removeEventListener('pointerdown', this.tryHideMapAnchorMenu);
};
- /**
- * View options for bing maps
- */
- bingViewOptions = {
- // center: { latitude: this.dataDoc.latitude ?? defaultCenter.lat, longitude: this.dataDoc.longitude ?? defaultCenter.lng },
- zoom: this.dataDoc.latitude ?? 10,
- mapTypeId: 'grayscale',
- };
-
- /**
- * Map options
- */
- bingMapOptions = {
- navigationBarMode: 'square',
- backgroundColor: '#f1f3f4',
- enableInertia: true,
- supportedMapTypes: ['grayscale', 'canvasLight'],
- disableMapTypeSelectorMouseOver: true,
- // showScalebar:true
- // disableRoadView:true,
- // disableBirdseye:true
- streetsideOptions: {
- showProblemReporting: false,
- showCurrentAddress: false,
- },
- };
-
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
recolorPin = (pin: Doc, color?: string) => {
// this._bingMap.current.entities.remove(this.map_docToPinMap.get(pin));
// this.map_docToPinMap.delete(pin);
@@ -739,109 +538,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
// this.map_docToPinMap.set(pin, newpin);
};
- /*
- * Called when BingMap is first rendered
- * Initializes starting values
- */
- @observable _mapReady = false;
- @action
- bingMapReady = (map: any) => {
- this._mapReady = true;
- this._bingMap = map.map;
- if (!this._bingMap.current) {
- alert('NO Map!?');
- }
- this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'click', this.mapOnClick);
- this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'viewchangeend', undoable(this.mapRecentered, 'Map Layout Change'));
- this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'maptypechanged', undoable(this.updateMapType, 'Map ViewType Change'));
-
- this._disposers.mapLocation = reaction(
- () => this.Document.map,
- mapLoc => (this.bingSearchBarContents = mapLoc),
- { fireImmediately: true }
- );
- this._disposers.highlight = reaction(
- () => this.allAnnotations.map(doc => doc[Highlight]),
- () => {
- const allConfigPins = this.allAnnotations.map(doc => ({ doc, pushpin: DocCast(doc.mapPin) })).filter(pair => pair.pushpin);
- allConfigPins.forEach(({ doc, pushpin }) => {
- if (!pushpin[Highlight] && this.map_pinHighlighted.get(pushpin)) {
- this.recolorPin(pushpin);
- this.map_pinHighlighted.delete(pushpin);
- }
- });
- allConfigPins.forEach(({ doc, pushpin }) => {
- if (doc[Highlight] && !this.map_pinHighlighted.get(pushpin)) {
- this.recolorPin(pushpin, 'orange');
- this.map_pinHighlighted.set(pushpin, true);
- }
- });
- },
- { fireImmediately: true }
- );
-
- this._disposers.location = reaction(
- () => ({ lat: this.Document.latitude, lng: this.Document.longitude, zoom: this.Document.map_zoom, mapType: this.Document.map_type }),
- locationObject => {
- // if (this._bingMap.current)
- try {
- locationObject?.zoom &&
- this._bingMap.current?.setView({
- mapTypeId: locationObject.mapType,
- zoom: locationObject.zoom,
- center: new this.MicrosoftMaps.Location(locationObject.lat, locationObject.lng),
- });
- } catch (e) {
- console.log(e);
- }
- },
- { fireImmediately: true }
- );
- };
-
- dragToggle = (e: React.PointerEvent) => {
- let dragClone: HTMLDivElement | undefined;
-
- setupMoveUpEvents(
- e,
- e,
- e => {
- // move event
- if (!dragClone) {
- dragClone = this._dragRef.current?.cloneNode(true) as HTMLDivElement; // copy draggable pin
- dragClone.style.position = 'absolute';
- dragClone.style.zIndex = '10000';
- DragManager.Root().appendChild(dragClone); // add clone to root
- }
- dragClone.style.transform = `translate(${e.clientX - 15}px, ${e.clientY - 15}px)`;
- return false;
- },
- e => {
- // up event
- if (!dragClone) return;
- DragManager.Root().removeChild(dragClone);
- let target = document.elementFromPoint(e.x, e.y); // element for specified x and y coordinates
- while (target) {
- if (target === this._ref.current) {
- const cpt = this.ScreenToLocalBoxXf().transformPoint(e.clientX, e.clientY);
- const x = cpt[0] - (this._props.PanelWidth() - this.sidebarWidth()) / 2;
- const y = cpt[1] - 20 /* height of search bar */ - this._props.PanelHeight() / 2;
- const location = this._bingMap.current.tryPixelToLocation(new this.MicrosoftMaps.Point(x, y));
- this.createPushpin(location.latitude, location.longitude);
- break;
- }
- target = target.parentElement;
- }
- },
- e => {
- const createPin = () => this.createPushpin(this.Document.latitude, this.Document.longitude, this.Document.map);
- if (this.bingSearchBarContents) {
- this.bingSearch().then(createPin);
- } else createPin();
- }
- );
- };
-
// incrementer: number = 0;
/*
* Creates Pushpin doc and adds it to the list of annotations
@@ -880,20 +576,25 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
if (createPinForDestination) {
this.createPushpin(destination.center[1], destination.center[0], destination.place_name);
}
- this.temporaryRouteSource = {
+ this._temporaryRouteSource = {
type: 'FeatureCollection',
features: [],
};
MapAnchorMenu.Instance.fadeOut(true);
return mapRoute;
}
+ return undefined;
// TODO: Display error that can't create route to same location
}, 'createmaproute');
- searchbarKeyDown = (e: any) => e.key === 'Enter' && this.bingSearch();
-
- @observable
- featuresFromGeocodeResults: any[] = [];
+ @action
+ searchbarKeyDown = (e: any) => {
+ if (e.key === 'Enter' && this._featuresFromGeocodeResults) {
+ const center = this._featuresFromGeocodeResults[0]?.center;
+ this._featuresFromGeocodeResults = [];
+ setTimeout(() => center && this._mapRef.current?.flyTo({ center }));
+ }
+ };
@action
addMarkerForFeature = (feature: any) => {
@@ -910,7 +611,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
center: feature.center,
});
}
- this.featuresFromGeocodeResults = [];
+ this._featuresFromGeocodeResults = [];
} else {
// TODO: handle error
}
@@ -922,11 +623,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
*/
handleSearchChange = async (searchText: string) => {
const features = await MapboxApiUtility.forwardGeocodeForFeatures(searchText);
- if (features && !this.isAnimating) {
+ if (features && !this._isAnimating) {
runInAction(() => {
- this.settingsOpen = false;
- this.featuresFromGeocodeResults = features;
- this.routeToAnimate = undefined;
+ this._settingsOpen = false;
+ this._featuresFromGeocodeResults = features;
+ this._routeToAnimate = undefined;
});
}
// try {
@@ -946,8 +647,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
@action
handleMapClick = (e: MapLayerMouseEvent) => {
- this.featuresFromGeocodeResults = [];
- this.settingsOpen = false;
+ this._featuresFromGeocodeResults = [];
+ this._settingsOpen = false;
if (this._mapRef.current) {
const features = this._mapRef.current.queryRenderedFeatures(e.point, {
layers: ['map-routes-layer'],
@@ -955,13 +656,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
console.error(features);
if (features && features.length > 0 && features[0].properties && features[0].geometry) {
- const geometry = features[0].geometry as LineString;
- const routeTitle: string = features[0].properties['routeTitle'];
- const routeDoc: Doc | undefined = this.allRoutes.find(routeDoc => routeDoc.title === routeTitle);
+ const { routeTitle } = features[0].properties;
+ const routeDoc: Doc | undefined = this.allRoutes.find(rtDoc => rtDoc.title === routeTitle);
this.deselectPinOrRoute(); // TODO: Also deselect route if selected
if (routeDoc) {
- this.selectedPinOrRoute = routeDoc;
- Doc.setDocFilter(this.Document, LinkedTo, `mapRoute=${Field.toScriptString(this.selectedPinOrRoute)}`, 'check');
+ this._selectedPinOrRoute = routeDoc;
+ Doc.setDocFilter(this.Document, LinkedTo, `mapRoute=${Field.toScriptString(this._selectedPinOrRoute)}`, 'check');
// TODO: Recolor route
@@ -1001,14 +701,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
*/
handleMapDblClick = async (e: MapLayerMouseEvent) => {
e.preventDefault();
- const lngLat: LngLat = e.lngLat;
+ const { lngLat } = e;
const longitude: number = lngLat.lng;
const latitude: number = lngLat.lat;
const features = await MapboxApiUtility.reverseGeocodeForFeatures(longitude, latitude);
if (features) {
runInAction(() => {
- this.featuresFromGeocodeResults = features;
+ this._featuresFromGeocodeResults = features;
});
}
@@ -1028,21 +728,18 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
// }
};
- @observable
- currentPopup: PopupInfo | undefined = undefined;
-
@action
handleMarkerClick = (e: MarkerEvent<mapboxgl.Marker, MouseEvent>, pinDoc: Doc) => {
- this.featuresFromGeocodeResults = [];
+ this._featuresFromGeocodeResults = [];
this.deselectPinOrRoute(); // TODO: check this method
- this.selectedPinOrRoute = pinDoc;
+ this._selectedPinOrRoute = pinDoc;
// this.bingSearchBarContents = pinDoc.map;
// Doc.setDocFilter(this.Document, 'latitude', this.selectedPin.latitude, 'match');
// Doc.setDocFilter(this.Document, 'longitude', this.selectedPin.longitude, 'match');
- Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(this.selectedPinOrRoute)}`, 'check');
+ Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(this._selectedPinOrRoute)}`, 'check');
- this.recolorPin(this.selectedPinOrRoute, 'green'); // TODO: check this method
+ this.recolorPin(this._selectedPinOrRoute, 'green'); // TODO: check this method
MapAnchorMenu.Instance.Delete = this.deleteSelectedPinOrRoute;
MapAnchorMenu.Instance.Center = this.centerOnSelectedPin;
@@ -1072,12 +769,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
// })
};
- @observable
- temporaryRouteSource: FeatureCollection = {
- type: 'FeatureCollection',
- features: [],
- };
-
@action
displayRoute = (routeInfoMap: Record<TransportationType, any> | undefined, type: TransportationType) => {
if (routeInfoMap) {
@@ -1096,41 +787,23 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
};
// TODO: Create pin for destination
// TODO: Fly to point where full route will be shown
- this.temporaryRouteSource = newTempRouteSource;
+ this._temporaryRouteSource = newTempRouteSource;
}
};
- @observable
- isAnimating: boolean = false;
-
- @observable
- routeToAnimate: Doc | undefined = undefined;
-
- @observable
- animationPhase: number = 0;
-
- @observable
- finishedFlyTo: boolean = false;
-
@action
setAnimationPhase = (newValue: number) => {
- this.animationPhase = newValue;
+ this._animationPhase = newValue;
};
- @observable
- frameId: number | null = null;
-
@action
setFrameId = (frameId: number) => {
- this.frameId = frameId;
+ this._frameId = frameId;
};
- @observable
- animationUtility: AnimationUtility | null = null;
-
@action
setAnimationUtility = (util: AnimationUtility) => {
- this.animationUtility = util;
+ this._animationUtility = util;
};
@action
@@ -1138,8 +811,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
if (routeDoc) {
MapAnchorMenu.Instance.fadeOut(true);
document.removeEventListener('pointerdown', this.tryHideMapAnchorMenu, true);
- this.featuresFromGeocodeResults = [];
- this.routeToAnimate = routeDoc;
+ this._featuresFromGeocodeResults = [];
+ this._routeToAnimate = routeDoc;
}
};
@@ -1161,29 +834,21 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
@computed
get preAnimationViewState() {
- if (!this.isAnimating) {
+ if (!this._isAnimating) {
return this.mapboxMapViewState;
}
+ return undefined;
}
- @observable
- isStreetViewAnimation: boolean = false;
-
- @observable
- animationSpeed: AnimationSpeed = AnimationSpeed.MEDIUM;
-
- @observable
- animationLineColor: string = '#ffff00';
-
@action
setAnimationLineColor = (color: ColorResult) => {
- this.animationLineColor = color.hex;
+ this._animationLineColor = color.hex;
};
@action
updateAnimationSpeed = () => {
let newAnimationSpeed: AnimationSpeed;
- switch (this.animationSpeed) {
+ switch (this._animationSpeed) {
case AnimationSpeed.SLOW:
newAnimationSpeed = AnimationSpeed.MEDIUM;
break;
@@ -1197,63 +862,33 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
newAnimationSpeed = AnimationSpeed.MEDIUM;
break;
}
- this.animationSpeed = newAnimationSpeed;
- if (this.animationUtility) {
- this.animationUtility.updateAnimationSpeed(newAnimationSpeed);
+ this._animationSpeed = newAnimationSpeed;
+ if (this._animationUtility) {
+ this._animationUtility.updateAnimationSpeed(newAnimationSpeed);
}
};
@computed get animationSpeedTooltipText(): string {
- switch (this.animationSpeed) {
- case AnimationSpeed.SLOW:
- return '1x speed';
- case AnimationSpeed.MEDIUM:
- return '2x speed';
- case AnimationSpeed.FAST:
- return '3x speed';
- default:
- return '2x speed';
- }
+ switch (this._animationSpeed) {
+ case AnimationSpeed.SLOW: return '1x speed';
+ case AnimationSpeed.MEDIUM: return '2x speed';
+ case AnimationSpeed.FAST: return '3x speed';
+ default: return '2x speed';
+ } // prettier-ignore
}
@computed get animationSpeedIcon(): JSX.Element {
- switch (this.animationSpeed) {
- case AnimationSpeed.SLOW:
- return slowSpeedIcon;
- case AnimationSpeed.MEDIUM:
- return mediumSpeedIcon;
- case AnimationSpeed.FAST:
- return fastSpeedIcon;
- default:
- return mediumSpeedIcon;
- }
+ switch (this._animationSpeed) {
+ case AnimationSpeed.SLOW: return slowSpeedIcon;
+ case AnimationSpeed.MEDIUM: return mediumSpeedIcon;
+ case AnimationSpeed.FAST: return fastSpeedIcon;
+ default: return mediumSpeedIcon;
+ } // prettier-ignore
}
@action
toggleIsStreetViewAnimation = () => {
- const newVal = !this.isStreetViewAnimation;
- this.isStreetViewAnimation = newVal;
- if (this.animationUtility) {
- this.animationUtility.updateIsStreetViewAnimation(newVal);
- }
- };
-
- @observable
- dynamicRouteFeature: Feature<Geometry, GeoJsonProperties> = {
- type: 'Feature',
- properties: {},
- geometry: {
- type: 'LineString',
- coordinates: [],
- },
- };
-
- @observable
- path: turf.helpers.Feature<turf.helpers.LineString, turf.helpers.Properties> = {
- type: 'Feature',
- geometry: {
- type: 'LineString',
- coordinates: [],
- },
- properties: {},
+ const newVal = !this._isStreetViewAnimation;
+ this._isStreetViewAnimation = newVal;
+ this._animationUtility?.updateIsStreetViewAnimation(newVal);
};
getFeatureFromRouteDoc = (routeDoc: Doc): Feature<Geometry, GeoJsonProperties> => {
@@ -1272,190 +907,172 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
@action
playAnimation = (status: AnimationStatus) => {
- if (!this._mapRef.current || !this.routeToAnimate) {
+ if (!this._mapRef.current || !this._routeToAnimate) {
return;
}
- this.animationPhase = status === AnimationStatus.RESUME ? this.animationPhase : 0;
- this.frameId = AnimationStatus.RESUME ? this.frameId : null;
- this.finishedFlyTo = AnimationStatus.RESUME ? this.finishedFlyTo : false;
+ this._animationPhase = status === AnimationStatus.RESUME ? this._animationPhase : 0;
+ this._frameId = AnimationStatus.RESUME ? this._frameId : null;
+ this._finishedFlyTo = AnimationStatus.RESUME ? this._finishedFlyTo : false;
const path = turf.lineString(this.selectedRouteCoordinates);
- this.settingsOpen = false;
+ this._settingsOpen = false;
this.path = path;
- this.isAnimating = true;
-
- runInAction(() => {
- return new Promise<void>(async resolve => {
- const targetLngLat = {
- lng: this.selectedRouteCoordinates[0][0],
- lat: this.selectedRouteCoordinates[0][1],
- };
-
- const animationUtil = new AnimationUtility(targetLngLat, this.selectedRouteCoordinates, this.isStreetViewAnimation, this.animationSpeed, this.showTerrain, this._mapRef.current);
- runInAction(() => {
- this.setAnimationUtility(animationUtil);
- });
+ this._isAnimating = true;
+
+ runInAction(
+ () =>
+ // eslint-disable-next-line no-async-promise-executor
+ new Promise<void>(async resolve => {
+ const targetLngLat = {
+ lng: this.selectedRouteCoordinates[0][0],
+ lat: this.selectedRouteCoordinates[0][1],
+ };
+
+ const animationUtil = new AnimationUtility(targetLngLat, this.selectedRouteCoordinates, this._isStreetViewAnimation, this._animationSpeed, this._showTerrain, this._mapRef.current);
+ runInAction(() => this.setAnimationUtility(animationUtil));
+
+ const updateFrameId = (newFrameId: number) => this.setFrameId(newFrameId);
+ const updateAnimationPhase = (newAnimationPhase: number) => this.setAnimationPhase(newAnimationPhase);
+
+ if (status !== AnimationStatus.RESUME) {
+ const result = await animationUtil.flyInAndRotate({
+ map: this._mapRef.current!,
+ // targetLngLat,
+ // duration 3000
+ // startAltitude: 3000000,
+ // endAltitude: this.isStreetViewAnimation ? 80 : 12000,
+ // startBearing: 0,
+ // endBearing: -20,
+ // startPitch: 40,
+ // endPitch: this.isStreetViewAnimation ? 80 : 50,
+ updateFrameId,
+ });
- const updateFrameId = (newFrameId: number) => {
- this.setFrameId(newFrameId);
- };
+ console.log('Bearing: ', result.bearing);
+ console.log('Altitude: ', result.altitude);
+ }
- const updateAnimationPhase = (newAnimationPhase: number) => {
- this.setAnimationPhase(newAnimationPhase);
- };
+ runInAction(() => {
+ this._finishedFlyTo = true;
+ });
- if (status !== AnimationStatus.RESUME) {
- const result = await animationUtil.flyInAndRotate({
+ // follow the path while slowly rotating the camera, passing in the camera bearing and altitude from the previous animation
+ await animationUtil.animatePath({
map: this._mapRef.current!,
- // targetLngLat,
- // duration 3000
- // startAltitude: 3000000,
- // endAltitude: this.isStreetViewAnimation ? 80 : 12000,
- // startBearing: 0,
- // endBearing: -20,
- // startPitch: 40,
- // endPitch: this.isStreetViewAnimation ? 80 : 50,
+ // path: this.path,
+ // startBearing: -20,
+ // startAltitude: this.isStreetViewAnimation ? 80 : 12000,
+ // pitch: this.isStreetViewAnimation ? 80: 50,
+ currentAnimationPhase: this._animationPhase,
+ updateAnimationPhase,
updateFrameId,
});
- console.log('Bearing: ', result.bearing);
- console.log('Altitude: ', result.altitude);
- }
-
- runInAction(() => {
- this.finishedFlyTo = true;
- });
-
- // follow the path while slowly rotating the camera, passing in the camera bearing and altitude from the previous animation
- await animationUtil.animatePath({
- map: this._mapRef.current!,
- // path: this.path,
- // startBearing: -20,
- // startAltitude: this.isStreetViewAnimation ? 80 : 12000,
- // pitch: this.isStreetViewAnimation ? 80: 50,
- currentAnimationPhase: this.animationPhase,
- updateAnimationPhase,
- updateFrameId,
- });
-
- // get the bounds of the linestring, use fitBounds() to animate to a final view
- const bbox3d = turf.bbox(this.path);
+ // get the bounds of the linestring, use fitBounds() to animate to a final view
+ const bbox3d = turf.bbox(this.path);
- const bbox2d: LngLatBoundsLike = [bbox3d[0], bbox3d[1], bbox3d[2], bbox3d[3]];
+ const bbox2d: LngLatBoundsLike = [bbox3d[0], bbox3d[1], bbox3d[2], bbox3d[3]];
- this._mapRef.current!.fitBounds(bbox2d, {
- duration: 3000,
- pitch: 30,
- bearing: 0,
- padding: 120,
- });
+ this._mapRef.current!.fitBounds(bbox2d, {
+ duration: 3000,
+ pitch: 30,
+ bearing: 0,
+ padding: 120,
+ });
- setTimeout(() => {
- this.isStreetViewAnimation = false;
- resolve();
- }, 10000);
- });
- });
+ setTimeout(() => {
+ this._isStreetViewAnimation = false;
+ resolve();
+ }, 10000);
+ })
+ );
};
@action
pauseAnimation = () => {
- if (this.frameId && this.animationPhase > 0) {
- window.cancelAnimationFrame(this.frameId);
- this.frameId = null;
- this.isAnimating = false;
+ if (this._frameId && this._animationPhase > 0) {
+ window.cancelAnimationFrame(this._frameId);
+ this._frameId = null;
+ this._isAnimating = false;
}
};
@action
stopAnimation = (close: boolean) => {
- if (this.frameId) {
- window.cancelAnimationFrame(this.frameId);
+ if (this._frameId) {
+ window.cancelAnimationFrame(this._frameId);
}
- this.animationPhase = 0;
- this.frameId = null;
- this.finishedFlyTo = false;
- this.isAnimating = false;
+ this._animationPhase = 0;
+ this._frameId = null;
+ this._finishedFlyTo = false;
+ this._isAnimating = false;
if (close) {
- this.animationSpeed = AnimationSpeed.MEDIUM;
- this.isStreetViewAnimation = false;
- this.routeToAnimate = undefined;
- this.animationUtility = null;
+ this._animationSpeed = AnimationSpeed.MEDIUM;
+ this._isStreetViewAnimation = false;
+ this._routeToAnimate = undefined;
+ this._animationUtility = null;
}
};
- getRouteAnimationOptions = (): JSX.Element => {
- return (
- <>
+ getRouteAnimationOptions = (): JSX.Element => (
+ <>
+ <IconButton
+ tooltip={this._isAnimating && this._finishedFlyTo ? 'Pause Animation' : 'Play Animation'}
+ onPointerDown={() => {
+ if (this._isAnimating && this._finishedFlyTo) {
+ this.pauseAnimation();
+ } else if (this._animationPhase > 0) {
+ this.playAnimation(AnimationStatus.RESUME); // Resume from the current phase
+ } else {
+ this.playAnimation(AnimationStatus.START); // Play from the beginning
+ }
+ }}
+ icon={this._isAnimating && this._finishedFlyTo ? <FontAwesomeIcon icon={faPause as IconLookup} /> : <FontAwesomeIcon icon={faPlay as IconLookup} />}
+ color="black"
+ size={Size.MEDIUM}
+ />
+ {this._isAnimating && this._finishedFlyTo && (
<IconButton
- tooltip={this.isAnimating && this.finishedFlyTo ? 'Pause Animation' : 'Play Animation'}
+ tooltip="Restart animation"
onPointerDown={() => {
- if (this.isAnimating && this.finishedFlyTo) {
- this.pauseAnimation();
- } else if (this.animationPhase > 0) {
- this.playAnimation(AnimationStatus.RESUME); // Resume from the current phase
- } else {
- this.playAnimation(AnimationStatus.START); // Play from the beginning
- }
+ this.stopAnimation(false);
+ this.playAnimation(AnimationStatus.START);
}}
- icon={this.isAnimating && this.finishedFlyTo ? <FontAwesomeIcon icon={faPause as IconLookup} /> : <FontAwesomeIcon icon={faPlay as IconLookup} />}
+ icon={<FontAwesomeIcon icon={faRotate as IconLookup} />}
color="black"
size={Size.MEDIUM}
/>
- {this.isAnimating && this.finishedFlyTo && (
- <IconButton
- tooltip="Restart animation"
- onPointerDown={() => {
- this.stopAnimation(false);
- this.playAnimation(AnimationStatus.START);
- }}
- icon={<FontAwesomeIcon icon={faRotate as IconLookup} />}
- color="black"
- size={Size.MEDIUM}
- />
- )}
- <IconButton style={{ marginRight: '10px' }} tooltip="Stop and close animation" onPointerDown={() => this.stopAnimation(true)} icon={<FontAwesomeIcon icon={faCircleXmark as IconLookup} />} color="black" size={Size.MEDIUM} />
- <>
- <div className="animation-suboptions">
- <div>|</div>
- <FormControlLabel className="first-person-label" label="1st person animation:" labelPlacement="start" control={<Checkbox color="success" checked={this.isStreetViewAnimation} onChange={this.toggleIsStreetViewAnimation} />} />
- <div id="divider">|</div>
- <IconButton tooltip={this.animationSpeedTooltipText} onPointerDown={this.updateAnimationSpeed} icon={this.animationSpeedIcon} size={Size.MEDIUM} />
- <div id="divider">|</div>
- <div style={{ display: 'flex', alignItems: 'center' }}>
- <div>Select Line Color: </div>
- <CirclePicker circleSize={12} circleSpacing={5} width="100%" colors={['#ffff00', '#03a9f4', '#ff0000', '#ff5722', '#000000', '#673ab7']} onChange={(color: any) => this.setAnimationLineColor(color)} />
- </div>
- </div>
- </>
- </>
- );
- };
+ )}
+ <IconButton style={{ marginRight: '10px' }} tooltip="Stop and close animation" onPointerDown={() => this.stopAnimation(true)} icon={<FontAwesomeIcon icon={faCircleXmark as IconLookup} />} color="black" size={Size.MEDIUM} />
+ <div className="animation-suboptions">
+ <div>|</div>
+ <FormControlLabel className="first-person-label" label="1st person animation:" labelPlacement="start" control={<Checkbox color="success" checked={this._isStreetViewAnimation} onChange={this.toggleIsStreetViewAnimation} />} />
+ <div id="divider">|</div>
+ <IconButton tooltip={this.animationSpeedTooltipText} onPointerDown={this.updateAnimationSpeed} icon={this.animationSpeedIcon} size={Size.MEDIUM} />
+ <div id="divider">|</div>
+ <div style={{ display: 'flex', alignItems: 'center' }}>
+ <div>Select Line Color: </div>
+ <CirclePicker circleSize={12} circleSpacing={5} width="100%" colors={['#ffff00', '#03a9f4', '#ff0000', '#ff5722', '#000000', '#673ab7']} onChange={(color: any) => this.setAnimationLineColor(color)} />
+ </div>
+ </div>
+ </>
+ );
@action
hideRoute = () => {
- this.temporaryRouteSource = {
+ this._temporaryRouteSource = {
type: 'FeatureCollection',
features: [],
};
};
- @observable
- settingsOpen: boolean = false;
-
- @observable
- mapStyle: string = 'mapbox://styles/mapbox/standard';
-
- @observable
- showTerrain: boolean = true;
-
@action
toggleSettings = () => {
- if (!this.isAnimating && this.animationPhase == 0) {
- this.featuresFromGeocodeResults = [];
- this.settingsOpen = !this.settingsOpen;
+ if (!this._isAnimating && this._animationPhase === 0) {
+ this._featuresFromGeocodeResults = [];
+ this._settingsOpen = !this._settingsOpen;
}
};
@@ -1500,21 +1117,19 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
@action
onStepZoomChange = (increment: boolean) => {
if (this._mapRef.current) {
- let newZoom: number;
- if (increment) {
- console.log('inc');
- newZoom = Math.min(16, this.mapboxMapViewState.zoom + 1);
- } else {
- console.log('dec');
- newZoom = Math.max(0, this.mapboxMapViewState.zoom - 1);
- }
+ const newZoom = increment //
+ ? Math.min(16, this.mapboxMapViewState.zoom + 1)
+ : Math.max(0, this.mapboxMapViewState.zoom - 1);
+
this._mapRef.current.setZoom(newZoom);
this.dataDoc.map_zoom = newZoom;
}
};
@action
- onMapZoom = (e: ViewStateChangeEvent) => (this.dataDoc.map_zoom = e.viewState.zoom);
+ onMapZoom = (e: ViewStateChangeEvent) => {
+ this.dataDoc.map_zoom = e.viewState.zoom;
+ };
@action
onMapMove = (e: ViewStateChangeEvent) => {
@@ -1523,7 +1138,9 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
};
@action
- toggleShowTerrain = () => (this.showTerrain = !this.showTerrain);
+ toggleShowTerrain = () => {
+ this._showTerrain = !this._showTerrain;
+ };
getMarkerIcon = (pinDoc: Doc): JSX.Element | null => {
const markerType = StrCast(pinDoc.markerType);
@@ -1532,48 +1149,28 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
return MarkerIcons.getFontAwesomeIcon(markerType, '2x', markerColor) ?? null;
};
- static _firstRender = true;
- static _rerenderDelay = 500;
- _rerenderTimeout: any;
+ _textRef = React.createRef<any>();
render() {
- // bcz: no idea what's going on here, but bings maps have some kind of bug
- // such that we need to delay rendering a second map on startup until the first map is rendered.
- this.Document[DocCss];
- if (MapBox._rerenderDelay) {
- // prettier-ignore
- this._rerenderTimeout = this._rerenderTimeout ??
- setTimeout(action(() => {
- if ((window as any).Microsoft?.Maps?.Internal._WorkDispatcher) {
- MapBox._rerenderDelay = 0;
- }
- this._rerenderTimeout = undefined;
- this.Document[DocCss] = this.Document[DocCss] + 1;
- }), MapBox._rerenderDelay);
- return null;
- }
const scale = this._props.NativeDimScaling?.() || 1;
const parscale = scale === 1 ? 1 : this.ScreenToLocalBoxXf().Scale ?? 1;
- const renderAnnotations = (childFilters?: () => string[]) => null;
return (
<div className="mapBox" ref={this._ref}>
<div
className="mapBox-wrapper"
onWheel={e => e.stopPropagation()}
- onPointerDown={async e => {
- e.button === 0 && !e.ctrlKey && e.stopPropagation();
- }}
+ onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()}
style={{ transformOrigin: 'top left', transform: `scale(${scale})`, width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}>
- <div style={{ mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>
- {renderAnnotations(this.opaqueFilter)}
- {SnappingManager.IsDragging ? null : renderAnnotations()}
- {!this.routeToAnimate && (
+ {!this._routeToAnimate && (
<div className="mapBox-searchbar" style={{ width: `${100 / scale}%`, zIndex: 1, position: 'relative', background: 'lightGray' }}>
- <TextField fullWidth placeholder="Enter a location" onChange={(e: any) => this.handleSearchChange(e.target.value)} />
- <IconButton icon={<FontAwesomeIcon icon={faGear as IconLookup} size="1x" />} type={Type.TERT} onClick={e => this.toggleSettings()} />
+ <TextField ref={this._textRef} fullWidth placeholder="Enter a location" onKeyDown={this.searchbarKeyDown} onChange={(e: any) => this.handleSearchChange(e.target.value)} />
+ <IconButton icon={<FontAwesomeIcon icon={faGear as IconLookup} size="1x" />} type={Type.TERT} onClick={() => this.toggleSettings()} />
+ <div style={{ opacity: 0 }}>
+ <IconButton icon={<FontAwesomeIcon icon={faGear as IconLookup} size="1x" />} type={Type.TERT} onClick={() => this.toggleSettings()} />
+ </div>
</div>
)}
- {this.settingsOpen && !this.routeToAnimate && (
+ {this._settingsOpen && !this._routeToAnimate && (
<div className="mapbox-settings-panel" style={{ right: `${0 + this.sidebarWidth()}px` }}>
<div className="mapbox-style-select">
<div>Map Style:</div>
@@ -1605,41 +1202,40 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
</div>
<div className="mapbox-terrain-selection">
<div>Show terrain: </div>
- <input type="checkbox" checked={this.showTerrain} onChange={this.toggleShowTerrain} />
+ <input type="checkbox" checked={this._showTerrain} onChange={this.toggleShowTerrain} />
</div>
</div>
)}
- {this.routeToAnimate && (
+ {this._routeToAnimate && (
<div className="animation-panel" style={{ width: this.sidebarWidth() === 0 ? '100%' : `calc(100% - ${this.sidebarWidth()}px)` }}>
- <div id="route-to-animate-title">{StrCast(this.routeToAnimate.title)}</div>
+ <div id="route-to-animate-title">{StrCast(this._routeToAnimate.title)}</div>
<div className="route-animation-options">{this.getRouteAnimationOptions()}</div>
</div>
)}
- {this.featuresFromGeocodeResults.length > 0 && (
+ {this._featuresFromGeocodeResults.length > 0 && (
<div className="mapbox-geocoding-search-results">
- <React.Fragment>
- <h4>Choose a location for your pin: </h4>
- {this.featuresFromGeocodeResults
- .filter(feature => feature.place_name)
- .map((feature, idx) => (
- <div
- key={idx}
- className="search-result-container"
- onClick={() => {
- this.handleSearchChange('');
- this.addMarkerForFeature(feature);
- }}>
- <div className="search-result-place-name">{feature.place_name}</div>
- </div>
- ))}
- </React.Fragment>
+ <h4>Choose a location for your pin: </h4>
+ {this._featuresFromGeocodeResults
+ .filter(feature => feature.place_name)
+ .map((feature, idx) => (
+ <div
+ // eslint-disable-next-line react/no-array-index-key
+ key={idx}
+ className="search-result-container"
+ onClick={() => {
+ this.handleSearchChange('');
+ this.addMarkerForFeature(feature);
+ }}>
+ <div className="search-result-place-name">{feature.place_name}</div>
+ </div>
+ ))}
</div>
)}
<MapProvider>
<MapboxMap
ref={this._mapRef}
mapboxAccessToken={MAPBOX_ACCESS_TOKEN}
- viewState={this.isAnimating || this.routeToAnimate ? undefined : { ...this.mapboxMapViewState, width: NumCast(this.layoutDoc._width), height: NumCast(this.layoutDoc._height) }}
+ viewState={this._isAnimating || this._routeToAnimate ? undefined : { ...this.mapboxMapViewState, width: NumCast(this.layoutDoc._width), height: NumCast(this.layoutDoc._height) }}
mapStyle={this.dataDoc.map_style ? StrCast(this.dataDoc.map_style) : 'mapbox://styles/mapbox/streets-v11'}
style={{
position: 'absolute',
@@ -1649,20 +1245,22 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
width: NumCast(this.layoutDoc._width) * parscale,
height: NumCast(this.layoutDoc._height) * parscale,
}}
- initialViewState={this.isAnimating ? undefined : this.mapboxMapViewState}
+ initialViewState={this._isAnimating ? undefined : this.mapboxMapViewState}
onZoom={this.onMapZoom}
onMove={this.onMapMove}
onClick={this.handleMapClick}
onDblClick={this.handleMapDblClick}
- terrain={this.showTerrain ? { source: 'mapbox-dem', exaggeration: 2.0 } : undefined}>
+ terrain={this._showTerrain ? { source: 'mapbox-dem', exaggeration: 2.0 } : undefined}>
<Source id="mapbox-dem" type="raster-dem" url="mapbox://mapbox.mapbox-terrain-dem-v1" tileSize={512} maxzoom={14} />
- <Source id="temporary-route" type="geojson" data={this.temporaryRouteSource} />
+ <Source id="temporary-route" type="geojson" data={this._temporaryRouteSource} />
<Source id="map-routes" type="geojson" data={this.allRoutesGeoJson} />
<Layer id="temporary-route-layer" type="line" source="temporary-route" layout={{ 'line-join': 'round', 'line-cap': 'round' }} paint={{ 'line-color': '#36454F', 'line-width': 4, 'line-dasharray': [1, 1] }} />
- {!this.isAnimating && this.animationPhase == 0 && <Layer id="map-routes-layer" type="line" source="map-routes" layout={{ 'line-join': 'round', 'line-cap': 'round' }} paint={{ 'line-color': '#FF0000', 'line-width': 4 }} />}
- {this.routeToAnimate && (this.isAnimating || this.animationPhase > 0) && (
+ {!this._isAnimating && this._animationPhase === 0 && (
+ <Layer id="map-routes-layer" type="line" source="map-routes" layout={{ 'line-join': 'round', 'line-cap': 'round' }} paint={{ 'line-color': '#FF0000', 'line-width': 4 }} />
+ )}
+ {this._routeToAnimate && (this._isAnimating || this._animationPhase > 0) && (
<>
- {!this.isStreetViewAnimation && (
+ {!this._isStreetViewAnimation && (
<>
<Source id="animated-route" type="geojson" data={this.updatedRouteCoordinates} />
<Layer
@@ -1670,7 +1268,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
type="line"
source="animated-route"
paint={{
- 'line-color': this.animationLineColor,
+ 'line-color': this._animationLineColor,
'line-width': 5,
}}
/>
@@ -1721,17 +1319,15 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
</>
)}
- <>
- {!this.isAnimating &&
- this.animationPhase == 0 &&
- this.allPushpins
- // .filter(anno => !anno.layout_unrendered)
- .map((pushpin, idx) => (
- <Marker key={idx} longitude={NumCast(pushpin.longitude)} latitude={NumCast(pushpin.latitude)} anchor="bottom" onClick={(e: MarkerEvent<mapboxgl.Marker, MouseEvent>) => this.handleMarkerClick(e, pushpin)}>
- {this.getMarkerIcon(pushpin)}
- </Marker>
- ))}
- </>
+ {!this._isAnimating &&
+ this._animationPhase === 0 &&
+ this.allPushpins // .filter(anno => !anno.layout_unrendered)
+ .map((pushpin, idx) => (
+ // eslint-disable-next-line react/no-array-index-key
+ <Marker key={idx} longitude={NumCast(pushpin.longitude)} latitude={NumCast(pushpin.latitude)} anchor="bottom" onClick={(e: MarkerEvent<mapboxgl.Marker, MouseEvent>) => this.handleMarkerClick(e, pushpin)}>
+ {this.getMarkerIcon(pushpin)}
+ </Marker>
+ ))}
{/* {this.mapMarkers.length > 0 && this.mapMarkers.map((marker, idx) => (
<Marker key={idx} longitude={marker.longitude} latitude={marker.latitude}/>
@@ -1742,12 +1338,13 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
<div className="mapBox-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
<SidebarAnnos
ref={this._sidebarRef}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
fieldKey={this.fieldKey}
Document={this.Document}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
- usePanelWidth={true}
+ usePanelWidth
showSidebar={this.SidebarShown}
nativeWidth={NumCast(this.layoutDoc._nativeWidth)}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
@@ -1762,3 +1359,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.MAP, {
+ layout: { view: MapBox, dataField: 'data' },
+ options: { acl: '', map: '', _height: 600, _width: 800, _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true, systemIcon: 'BsFillPinMapFill' },
+});
diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx
index 9825824bd..7697fd295 100644
--- a/src/client/views/nodes/MapBox/MapBox2.tsx
+++ b/src/client/views/nodes/MapBox/MapBox2.tsx
@@ -509,9 +509,9 @@
// // TODO: auto center on select a document in the sidebar
// private handleMapCenter = (map: google.maps.Map) => {
-// // console.log("print the selected views in selectionManager:")
-// // if (SelectionManager.Views.lastElement()) {
-// // console.log(SelectionManager.Views.lastElement());
+// // console.log("print the selected views in Document.Selected:")
+// // if (DocumentView.Selected().lastElement()) {
+// // console.log(DocumentView.Selected().lastElement());
// // }
// };
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index 6ccbbbe1c..c69cd8e89 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -32,7 +32,7 @@
// addNoteClick = (e: React.PointerEvent) => {
// setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => {
// const newDoc = Docs.Create.TextDocument('Note', { _layout_autoHeight: true });
-// FormattedTextBox.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+// Doc.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
// Doc.AddDocToList(this.props.place, 'data', newDoc);
// this._stack?.scrollToBottom();
// e.stopPropagation();
diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx
index fc5b4dd18..f3dc44755 100644
--- a/src/client/views/nodes/MapBox/MapPushpinBox.tsx
+++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx
@@ -1,7 +1,9 @@
import * as React from 'react';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { FieldView, FieldViewProps } from '../FieldView';
-import { MapBox } from './MapBox';
+import { MapBoxContainer } from '../MapboxMapBox/MapboxContainer';
+import { Docs } from '../../../documents/Documents';
+import { DocumentType } from '../../../documents/DocumentTypes';
/**
* Map Pushpin doc class
@@ -18,7 +20,7 @@ export class MapPushpinBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
get mapBoxView() {
- return this.DocumentView?.()?.containerViewPath?.().lastElement()?.ComponentView as MapBox;
+ return this.DocumentView?.()?.containerViewPath?.().lastElement()?.ComponentView as MapBoxContainer;
}
get mapBox() {
return this.DocumentView?.().containerViewPath?.().lastElement()?.Document;
@@ -28,3 +30,8 @@ export class MapPushpinBox extends ViewBoxBaseComponent<FieldViewProps>() {
return <div />;
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.PUSHPIN, {
+ layout: { view: MapPushpinBox, dataField: 'data' },
+ options: { acl: '' },
+});
diff --git a/src/client/views/nodes/MapBox/MapboxApiUtility.ts b/src/client/views/nodes/MapBox/MapboxApiUtility.ts
index 592330ac2..5c5192372 100644
--- a/src/client/views/nodes/MapBox/MapboxApiUtility.ts
+++ b/src/client/views/nodes/MapBox/MapboxApiUtility.ts
@@ -1,4 +1,3 @@
-
const MAPBOX_FORWARD_GEOCODE_BASE_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places/';
const MAPBOX_REVERSE_GEOCODE_BASE_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places/';
const MAPBOX_DIRECTIONS_BASE_URL = 'https://api.mapbox.com/directions/v5/mapbox';
@@ -7,92 +6,79 @@ const MAPBOX_ACCESS_TOKEN = 'pk.eyJ1IjoiemF1bHRhdmFuZ2FyIiwiYSI6ImNscHgwNDd1MDA3
export type TransportationType = 'driving' | 'cycling' | 'walking';
export class MapboxApiUtility {
-
static forwardGeocodeForFeatures = async (searchText: string) => {
try {
- const url = MAPBOX_FORWARD_GEOCODE_BASE_URL + encodeURI(searchText) +'.json' +`?access_token=${MAPBOX_ACCESS_TOKEN}`;
+ const url = MAPBOX_FORWARD_GEOCODE_BASE_URL + encodeURI(searchText) + `.json?access_token=${MAPBOX_ACCESS_TOKEN}`;
const response = await fetch(url);
const data = await response.json();
return data.features;
- } catch (error: any){
- // TODO: handle error in better way
+ } catch (error: any) {
+ // TODO: handle error in better way
return null;
}
- }
+ };
static reverseGeocodeForFeatures = async (longitude: number, latitude: number) => {
try {
- const url = MAPBOX_REVERSE_GEOCODE_BASE_URL + encodeURI(longitude.toString() + "," + latitude.toString()) + '.json' +
- `?access_token=${MAPBOX_ACCESS_TOKEN}`;
+ const url = MAPBOX_REVERSE_GEOCODE_BASE_URL + encodeURI(longitude.toString() + ',' + latitude.toString()) + `.json?access_token=${MAPBOX_ACCESS_TOKEN}`;
const response = await fetch(url);
const data = await response.json();
return data.features;
- } catch (error: any){
+ } catch (error: any) {
return null;
}
- }
+ };
static getDirections = async (origin: number[], destination: number[]): Promise<Record<TransportationType, any> | undefined> => {
try {
-
const directionsPromises: Promise<any>[] = [];
const transportationTypes: TransportationType[] = ['driving', 'cycling', 'walking'];
- transportationTypes.forEach((type) => {
- directionsPromises.push(
- fetch(
- `${MAPBOX_DIRECTIONS_BASE_URL}/${type}/${origin[0]},${origin[1]};${destination[0]},${destination[1]}?steps=true&geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}`
- ).then((response) => response.json())
- );
- });
+ transportationTypes.forEach(type => {
+ directionsPromises.push(fetch(`${MAPBOX_DIRECTIONS_BASE_URL}/${type}/${origin[0]},${origin[1]};${destination[0]},${destination[1]}?steps=true&geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}`).then(response => response.json()));
+ });
const results = await Promise.all(directionsPromises);
const routeInfoMap: Record<TransportationType, any> = {
- 'driving': {},
- 'cycling': {},
- 'walking': {},
+ driving: {},
+ cycling: {},
+ walking: {},
};
transportationTypes.forEach((type, index) => {
const routeData = results[index].routes[0];
if (routeData) {
- const geometry = routeData.geometry;
- const coordinates = geometry.coordinates;
-
- routeInfoMap[type] = {
- duration: this.secondsToMinutesHours(routeData.duration),
- distance: this.metersToMiles(routeData.distance),
- coordinates: coordinates,
- };
+ const { geometry } = routeData;
+ const { coordinates } = geometry;
+
+ routeInfoMap[type] = {
+ duration: this.secondsToMinutesHours(routeData.duration),
+ distance: this.metersToMiles(routeData.distance),
+ coordinates: coordinates,
+ };
}
- });
+ });
return routeInfoMap;
- // return current route info, and the temporary route
-
- } catch (error: any){
+ // return current route info, and the temporary route
+ } catch (error: any) {
return undefined;
- console.log("Error: ", error);
}
- }
+ };
private static secondsToMinutesHours = (seconds: number) => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60).toFixed(2);
- if (hours === 0){
- return `${minutes} min`
- } else {
- return `${hours} hr ${minutes} min`
+ if (hours === 0) {
+ return `${minutes} min`;
}
- }
-
- private static metersToMiles = (meters: number) => {
- return `${parseFloat((meters/1609.34).toFixed(2))} mi`;
- }
+ return `${hours} hr ${minutes} min`;
+ };
+ private static metersToMiles = (meters: number) => `${parseFloat((meters / 1609.34).toFixed(2))} mi`;
}
// const drivingQuery = await fetch(
@@ -136,4 +122,4 @@ export class MapboxApiUtility {
// distance: this.metersToMiles(routeData.distance),
// coordinates: coordinates
// }
-// }) \ No newline at end of file
+// })
diff --git a/src/client/views/nodes/MapBox/MarkerIcons.tsx b/src/client/views/nodes/MapBox/MarkerIcons.tsx
index a580fcaa0..087472112 100644
--- a/src/client/views/nodes/MapBox/MarkerIcons.tsx
+++ b/src/client/views/nodes/MapBox/MarkerIcons.tsx
@@ -17,8 +17,6 @@ import {
faHouse,
faLandmark,
faLocationDot,
- faLocationPin,
- faMapPin,
faMasksTheater,
faMugSaucer,
faPersonHiking,
@@ -65,6 +63,7 @@ export class MarkerIcons {
iconProps.color = color;
}
+ // eslint-disable-next-line react/jsx-props-no-spreading
return <FontAwesomeIcon {...iconProps} size={size} />;
}
diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
index 3eb051dbf..bfd40692b 100644
--- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
+++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
@@ -4,28 +4,28 @@ import { IReactionDisposer, ObservableMap, action, computed, makeObservable, obs
import { observer } from 'mobx-react';
import * as React from 'react';
import { MapProvider, Map as MapboxMap } from 'react-map-gl';
-import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils';
+import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc';
import { DocCss, Highlight } from '../../../../fields/DocSymbols';
-import { DocCast, NumCast, StrCast } from '../../../../fields/Types';
+import { Id } from '../../../../fields/FieldSymbols';
+import { DocCast, NumCast, StrCast, toList } from '../../../../fields/Types';
+import { DocUtils } from '../../../documents/DocUtils';
import { DocumentType } from '../../../documents/DocumentTypes';
-import { DocUtils, Docs } from '../../../documents/Documents';
-import { DocumentManager } from '../../../util/DocumentManager';
+import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
-import { LinkManager } from '../../../util/LinkManager';
-import { SnappingManager } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
import { UndoManager, undoable } from '../../../util/UndoManager';
import { ViewBoxAnnotatableComponent } from '../../DocComponent';
+import { PinDocView, PinProps } from '../../PinFuncs';
import { SidebarAnnos } from '../../SidebarAnnos';
import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import { MapAnchorMenu } from '../MapBox/MapAnchorMenu';
-import { FormattedTextBox } from '../formattedText/FormattedTextBox';
-import { PinProps, PresBox } from '../trails';
-import './MapBox.scss';
+import '../MapBox/MapBox.scss';
/**
* MapBox architecture:
@@ -41,7 +41,6 @@ import './MapBox.scss';
*/
const mapboxApiKey = 'pk.eyJ1IjoiemF1bHRhdmFuZ2FyIiwiYSI6ImNsbnc2eHJpbTA1ZTUyam85aGx4Z2FhbGwifQ.2Kqw9mk-9wAAg9kmHmKzcg';
-const bingApiKey = process.env.BING_MAPS; // if you're running local, get a Bing Maps api key here: https://www.bingmapsportal.com/ and then add it to the .env file in the Dash-Web root directory as: _CLIENT_BING_MAPS=<your apikey>
/**
* Consider integrating later: allows for drawing, circling, making shapes on map
@@ -87,7 +86,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
return this.allAnnotations.filter(anno => anno.type === DocumentType.PUSHPIN);
}
@computed get SidebarShown() {
- return this.layoutDoc._layout_showSidebar ? true : false;
+ return !!this.layoutDoc._layout_showSidebar;
}
@computed get sidebarWidthPercent() {
return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%');
@@ -118,9 +117,9 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
* @param sidebarKey
* @returns
*/
- sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
+ sidebarAddDocument = (docsIn: Doc | Doc[], sidebarKey?: string) => {
if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar();
- const docs = doc instanceof Doc ? [doc] : doc;
+ const docs = toList(docsIn);
docs.forEach(doc => {
let existingPin = this.allPushpins.find(pin => pin.latitude === doc.latitude && pin.longitude === doc.longitude) ?? this.selectedPin;
if (doc.latitude !== undefined && doc.longitude !== undefined && !existingPin) {
@@ -129,7 +128,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
if (existingPin) {
setTimeout(() => {
// we use a timeout in case this is called from the sidebar which may have just added a link that hasn't made its way into th elink manager yet
- if (!LinkManager.Instance.getAllRelatedLinks(doc).some(link => DocCast(link.link_anchor_1)?.mapPin === existingPin || DocCast(link.link_anchor_2)?.mapPin === existingPin)) {
+ if (!Doc.Links(doc).some(link => DocCast(link.link_anchor_1)?.mapPin === existingPin || DocCast(link.link_anchor_2)?.mapPin === existingPin)) {
const anchor = this.getAnchor(true, undefined, existingPin);
anchor && DocUtils.MakeLink(anchor, doc, { link_relationship: 'link to map location' });
doc.latitude = existingPin?.latitude;
@@ -137,15 +136,19 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
}
});
}
- }); //add to annotation list
+ }); // add to annotation list
- return this.addDocument(doc, sidebarKey); // add to sidebar list
+ return this.addDocument(docs, sidebarKey); // add to sidebar list
};
- removeMapDocument = (doc: Doc | Doc[], annotationKey?: string) => {
- const docs = doc instanceof Doc ? [doc] : doc;
- this.allAnnotations.filter(anno => docs.includes(DocCast(anno.mapPin))).forEach(anno => (anno.mapPin = undefined));
- return this.removeDocument(doc, annotationKey, undefined);
+ removeMapDocument = (docsIn: Doc | Doc[], annotationKey?: string) => {
+ const docs = toList(docsIn);
+ this.allAnnotations
+ .filter(anno => docs.includes(DocCast(anno.mapPin)))
+ .forEach(anno => {
+ anno.mapPin = undefined;
+ });
+ return this.removeDocument(docsIn, annotationKey, undefined);
};
/**
@@ -164,7 +167,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
setupMoveUpEvents(
this,
e,
- (e, down, delta) =>
+ (moveEv, down, delta) =>
runInAction(() => {
const localDelta = this._props
.ScreenToLocalTransform()
@@ -204,7 +207,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={this.sidebarBtnDown}>
- <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" />
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon="comment-alt" size="sm" />
</div>
);
}
@@ -233,16 +236,16 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
const targetCreator = (annotationOn: Doc | undefined) => {
const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, annotationOn, 'yellow');
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
return target;
};
const docView = this.DocumentView?.();
docView &&
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
- dragComplete: e => {
- if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
- e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.Document;
- e.annoDragData.linkSourceDoc.followLinkZoom = false;
+ dragComplete: dragEv => {
+ if (!dragEv.aborted && dragEv.annoDragData && dragEv.annoDragData.linkSourceDoc && dragEv.annoDragData.dropDocument && dragEv.linkDocument) {
+ dragEv.annoDragData.linkSourceDoc.followLinkToggle = dragEv.annoDragData.dropDocument.annotationOn === this.Document;
+ dragEv.annoDragData.linkSourceDoc.followLinkZoom = false;
}
},
});
@@ -268,7 +271,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
sidebarDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), true);
};
- sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => {
+ sidebarMove = (e: PointerEvent) => {
const bounds = this._ref.current!.getBoundingClientRect();
this.layoutDoc._layout_sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%';
this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%';
@@ -276,7 +279,9 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
return false;
};
- setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => (this._setPreviewCursor = func);
+ setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => {
+ this._setPreviewCursor = func;
+ };
addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => this.addDocument(doc, annotationKey);
@@ -285,8 +290,8 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth();
panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
scrollXf = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop));
- transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter];
- opaqueFilter = () => [...this._props.childFilters(), Utils.OpaqueBackgroundFilter];
+ transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter];
+ opaqueFilter = () => [...this._props.childFilters(), ClientUtils.OpaqueBackgroundFilter];
infoWidth = () => this._props.PanelWidth() / 5;
infoHeight = () => this._props.PanelHeight() / 5;
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
@@ -306,11 +311,11 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
// center: new this.MicrosoftMaps.Location(loc.latitude, loc.longitude),
// });
//
- bingGeocode = (map: any, query: string) => {
- return new Promise<{ latitude: number; longitude: number }>((res, reject) => {
- //If search manager is not defined, load the search module.
+ bingGeocode = (map: any, query: string) =>
+ new Promise<{ latitude: number; longitude: number }>((res, reject) => {
+ // If search manager is not defined, load the search module.
if (!this._bingSearchManager) {
- //Create an instance of the search manager and call the geocodeQuery function again.
+ // Create an instance of the search manager and call the geocodeQuery function again.
this.MicrosoftMaps.loadModule('Microsoft.Maps.Search', () => {
this._bingSearchManager = new this.MicrosoftMaps.Search.SearchManager(map.current);
res(this.bingGeocode(map, query));
@@ -319,11 +324,10 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
this._bingSearchManager.geocode({
where: query,
callback: action((r: any) => res(r.results[0].location)),
- errorCallback: (e: any) => reject(),
+ errorCallback: () => reject(),
});
}
});
- };
@observable
bingSearchBarContents: any = this.Document.map; // For Bing Maps: The contents of the Bing search bar (string)
@@ -368,7 +372,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
this._bingMap.current.entities.remove(this.map_docToPinMap.get(temp));
}
const newpin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(temp.latitude, temp.longitude));
- this.MicrosoftMaps.Events.addHandler(newpin, 'click', (e: any) => this.pushpinClicked(temp as Doc));
+ this.MicrosoftMaps.Events.addHandler(newpin, 'click', () => this.pushpinClicked(temp as Doc));
if (!this._unmounting) {
this._bingMap.current.entities.push(newpin);
}
@@ -383,7 +387,9 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
this.toggleSidebar();
options.didMove = true;
}
- return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
+ return new Promise<Opt<DocumentView>>(res => {
+ DocumentView.addViewRenderedCb(doc, dv => res(dv));
+ });
};
/*
* Pushpin onclick
@@ -418,7 +424,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
* Map OnClick
*/
@action
- mapOnClick = (e: { location: { latitude: any; longitude: any } }) => {
+ mapOnClick = (/* e: { location: { latitude: any; longitude: any } } */) => {
this._props.select(false);
this.deselectPin();
};
@@ -442,22 +448,23 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
* Updates maptype
*/
@action
- updateMapType = () => (this.dataDoc.map_type = this._bingMap.current.getMapTypeId());
+ updateMapType = () => {
+ this.dataDoc.map_type = this._bingMap.current.getMapTypeId();
+ };
/*
* For Bing Maps
* Called by search button's onClick
* Finds the geocode of the searched contents and sets location to that location
- **/
+ * */
@action
- bingSearch = () => {
- return this.bingGeocode(this._bingMap, this.bingSearchBarContents).then(location => {
+ bingSearch = () =>
+ this.bingGeocode(this._bingMap, this.bingSearchBarContents).then(location => {
this.dataDoc.latitude = location.latitude;
this.dataDoc.longitude = location.longitude;
this.dataDoc.map_zoom = this._bingMap.current.getZoom();
this.dataDoc.map = this.bingSearchBarContents;
});
- };
/*
* Returns doc w/ relevant info
@@ -479,7 +486,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
if (anchor) {
if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
addAsAnnotation && this.addDocument(anchor);
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), map: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), map: true } }, this.Document);
return anchor;
}
return this.Document;
@@ -502,7 +509,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
this._bingMap.current.entities.push(pushPin);
- this.MicrosoftMaps.Events.addHandler(pushPin, 'click', (e: any) => this.pushpinClicked(pin));
+ this.MicrosoftMaps.Events.addHandler(pushPin, 'click', () => this.pushpinClicked(pin));
// this.MicrosoftMaps.Events.addHandler(pushPin, 'dblclick', (e: any) => this.pushpinDblClicked(pushPin, pin));
this.map_docToPinMap.set(pin, pushPin);
};
@@ -591,13 +598,15 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
};
@action
- searchbarOnEdit = (newText: string) => (this.bingSearchBarContents = newText);
+ searchbarOnEdit = (newText: string) => {
+ this.bingSearchBarContents = newText;
+ };
recolorPin = (pin: Doc, color?: string) => {
this._bingMap.current.entities.remove(this.map_docToPinMap.get(pin));
this.map_docToPinMap.delete(pin);
const newpin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.latitude, pin.longitude), color ? { color } : {});
- this.MicrosoftMaps.Events.addHandler(newpin, 'click', (e: any) => this.pushpinClicked(pin));
+ this.MicrosoftMaps.Events.addHandler(newpin, 'click', () => this.pushpinClicked(pin));
this._bingMap.current.entities.push(newpin);
this.map_docToPinMap.set(pin, newpin);
};
@@ -620,14 +629,16 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
this._disposers.mapLocation = reaction(
() => this.Document.map,
- mapLoc => (this.bingSearchBarContents = mapLoc),
+ mapLoc => {
+ this.bingSearchBarContents = mapLoc;
+ },
{ fireImmediately: true }
);
this._disposers.highlight = reaction(
() => this.allAnnotations.map(doc => doc[Highlight]),
() => {
const allConfigPins = this.allAnnotations.map(doc => ({ doc, pushpin: DocCast(doc.mapPin) })).filter(pair => pair.pushpin);
- allConfigPins.forEach(({ doc, pushpin }) => {
+ allConfigPins.forEach(({ pushpin }) => {
if (!pushpin[Highlight] && this.map_pinHighlighted.get(pushpin)) {
this.recolorPin(pushpin);
this.map_pinHighlighted.delete(pushpin);
@@ -668,23 +679,23 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
setupMoveUpEvents(
e,
e,
- e => {
+ moveEv => {
if (!dragClone) {
dragClone = this._dragRef.current?.cloneNode(true) as HTMLDivElement;
dragClone.style.position = 'absolute';
dragClone.style.zIndex = '10000';
DragManager.Root().appendChild(dragClone);
}
- dragClone.style.transform = `translate(${e.clientX - 15}px, ${e.clientY - 15}px)`;
+ dragClone.style.transform = `translate(${moveEv.clientX - 15}px, ${moveEv.clientY - 15}px)`;
return false;
},
- e => {
+ upEv => {
if (!dragClone) return;
DragManager.Root().removeChild(dragClone);
- let target = document.elementFromPoint(e.x, e.y);
+ let target = document.elementFromPoint(upEv.x, upEv.y);
while (target) {
if (target === this._ref.current) {
- const cpt = this.ScreenToLocalBoxXf().transformPoint(e.clientX, e.clientY);
+ const cpt = this.ScreenToLocalBoxXf().transformPoint(upEv.clientX, upEv.clientY);
const x = cpt[0] - (this._props.PanelWidth() - this.sidebarWidth()) / 2;
const y = cpt[1] - 32 /* height of search bar */ - this._props.PanelHeight() / 2;
const location = this._bingMap.current.tryPixelToLocation(new this.MicrosoftMaps.Point(x, y));
@@ -694,7 +705,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
target = target.parentElement;
}
},
- e => {
+ () => {
const createPin = () => this.createPushpin(this.Document.latitude, this.Document.longitude, this.Document.map);
if (this.bingSearchBarContents) {
this.bingSearch().then(createPin);
@@ -720,12 +731,12 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
MapBoxContainer._rerenderDelay = 0;
}
this._rerenderTimeout = undefined;
+ // eslint-disable-next-line operator-assignment
this.Document[DocCss] = this.Document[DocCss] + 1;
}), MapBoxContainer._rerenderDelay);
return null;
}
- const renderAnnotations = (childFilters?: () => string[]) => null;
return (
<div className="mapBox" ref={this._ref}>
<div
@@ -735,15 +746,11 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
e.button === 0 && !e.ctrlKey && e.stopPropagation();
}}
style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}>
- <div style={{ mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>
- {renderAnnotations(this.opaqueFilter)}
- {SnappingManager.IsDragging ? null : renderAnnotations()}
-
<div className="mapBox-searchbar">
<EditableText
// editing
setVal={(newText: string | number) => typeof newText === 'string' && this.searchbarOnEdit(newText)}
- onEnter={e => this.bingSearch()}
+ onEnter={() => this.bingSearch()}
placeholder={this.bingSearchBarContents || 'enter city/zip/...'}
textAlign="center"
/>
@@ -752,18 +759,19 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="magnifying-glass" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" color="#DFDFDF">
<path
fill="currentColor"
- d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"></path>
+ d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"
+ />
</svg>
}
onClick={this.bingSearch}
type={Type.TERT}
/>
<div style={{ width: 30, height: 30 }} ref={this._dragRef} onPointerDown={this.dragToggle}>
- <Button tooltip="drag to place a pushpin" icon={<FontAwesomeIcon size={'lg'} icon={'bullseye'} />} />
+ <Button tooltip="drag to place a pushpin" icon={<FontAwesomeIcon size="lg" icon="bullseye" />} />
</div>
</div>
<MapProvider>
- <MapboxMap id="mabox-map" mapStyle={`mapbox://styles/mapbox/streets-v9`} mapboxAccessToken={mapboxApiKey} />
+ <MapboxMap id="mabox-map" mapStyle="mapbox://styles/mapbox/streets-v9" mapboxAccessToken={mapboxApiKey} />
</MapProvider>
{/*
@@ -780,9 +788,10 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
? null
: this.allAnnotations
.filter(anno => !anno.layout_unrendered)
- .map((pushpin, i) => (
+ .map(pushpin => (
<DocumentView
- key={i}
+ key={pushpin[Id]}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
renderDepth={this._props.renderDepth + 1}
Document={pushpin}
@@ -792,7 +801,6 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
NativeHeight={returnOne}
onKey={undefined}
onDoubleClickScript={undefined}
- onBrowseClickScript={undefined}
childFilters={returnEmptyFilter}
childFiltersByRanges={returnEmptyFilter}
searchFilterDocs={returnEmptyDoclist}
@@ -821,12 +829,13 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
<div className="mapBox-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
<SidebarAnnos
ref={this._sidebarRef}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
fieldKey={this.fieldKey}
Document={this.Document}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
- usePanelWidth={true}
+ usePanelWidth
showSidebar={this.SidebarShown}
nativeWidth={NumCast(this.layoutDoc._nativeWidth)}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
diff --git a/src/client/views/nodes/OpenWhere.ts b/src/client/views/nodes/OpenWhere.ts
new file mode 100644
index 000000000..f7101b103
--- /dev/null
+++ b/src/client/views/nodes/OpenWhere.ts
@@ -0,0 +1,27 @@
+export enum OpenWhereMod {
+ none = '',
+ left = 'left',
+ right = 'right',
+ top = 'top',
+ bottom = 'bottom',
+ keyvalue = 'keyValue',
+ always = 'always', // forces the open location (lightbox) instead of using an existing open view (see DocumentDecorations)
+}
+export enum OpenWhere {
+ lightbox = 'lightbox',
+ lightboxAlways = 'lightbox:always',
+ add = 'add',
+ addLeft = 'add:left',
+ addRight = 'add:right',
+ addBottom = 'add:bottom',
+ close = 'close',
+ toggle = 'toggle',
+ toggleRight = 'toggle:right',
+ replace = 'replace',
+ replaceRight = 'replace:right',
+ replaceLeft = 'replace:left',
+ inParent = 'inParent',
+ inParentFromScreen = 'inParentFromScreen',
+ overlay = 'overlay',
+ addRightKeyvalue = 'add:right:keyValue',
+}
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 0f5e25a0c..7bca1230f 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -236,7 +236,7 @@
//pointer-events: none;
.pdfViewerDash-text {
.textLayer {
- display: none;
+ // display: none; // this makes search highlights not show up
span {
user-select: none;
}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 1274220b6..7a89b143b 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -1,41 +1,45 @@
+/* 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';
import * as Pdfjs from 'pdfjs-dist';
import 'pdfjs-dist/web/pdf_viewer.css';
import * as React from 'react';
+import { ClientUtils, returnFalse, setupMoveUpEvents, UpdateIcon } from '../../../ClientUtils';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { ComputedField } from '../../../fields/ScriptField';
-import { Cast, FieldValue, ImageCast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, FieldValue, ImageCast, NumCast, StrCast, toList } from '../../../fields/Types';
import { ImageField, PdfField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnFalse, setupMoveUpEvents, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { emptyFunction } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
-import { DocumentManager } from '../../util/DocumentManager';
+import { DocUtils } from '../../documents/DocUtils';
import { KeyCodes } from '../../util/KeyCodes';
-import { SelectionManager } from '../../util/SelectionManager';
import { undoBatch, UndoManager } from '../../util/UndoManager';
import { CollectionFreeFormView } from '../collections/collectionFreeForm';
import { CollectionStackingView } from '../collections/CollectionStackingView';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { Colors } from '../global/globalEnums';
-import { CreateImage } from '../nodes/WebBoxRenderer';
import { PDFViewer } from '../pdf/PDFViewer';
+import { PinDocView, PinProps } from '../PinFuncs';
import { SidebarAnnos } from '../SidebarAnnos';
-import { DocumentView, OpenWhere } from './DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView';
+import { DocumentView } from './DocumentView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import { ImageBox } from './ImageBox';
+import { OpenWhere } from './OpenWhere';
import './PDFBox.scss';
-import { PinProps, PresBox } from './trails';
+import { CreateImage } from './WebBoxRenderer';
@observer
-export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(PDFBox, fieldKey);
}
@@ -66,8 +70,16 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200;
!this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw));
if (this.pdfUrl) {
- if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) runInAction(() => (this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href)));
- else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action((pdf: any) => (this._pdf = pdf)));
+ if (PDFBox.pdfcache.get(this.pdfUrl.url.href))
+ runInAction(() => {
+ this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href);
+ });
+ else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href))
+ PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(
+ action((pdf: any) => {
+ this._pdf = pdf;
+ })
+ );
}
}
@@ -85,7 +97,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
if (oldDiv instanceof HTMLCanvasElement) {
const canvas = oldDiv;
const img = document.createElement('img'); // create a Image Element
- img.src = canvas.toDataURL(); //image sourcez
+ img.src = canvas.toDataURL(); // image sourcez
img.style.width = canvas.style.width;
img.style.height = canvas.style.height;
const newCan = newDiv as HTMLCanvasElement;
@@ -96,8 +108,12 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
};
crop = (region: Doc | undefined, addCrop?: boolean) => {
- if (!region) return;
+ if (!region) 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.
+ cropping.backgroundColor = undefined; // text selections have this -- it causes images to be fully transparent
+ cropping.opacity = undefined; // text selections have this -- it causes images to be fully transparent
const regionData = region[DocData];
regionData.lockedPosition = true;
regionData.title = 'region:' + this.Document.title;
@@ -111,11 +127,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this.replaceCanvases(docViewContent, newDiv);
const htmlString = this._pdfViewer?._mainCont.current && new XMLSerializer().serializeToString(newDiv);
- const anchx = NumCast(cropping.x);
- const anchy = NumCast(cropping.y);
+ // const anchx = NumCast(cropping.x);
+ // const anchy = NumCast(cropping.y);
const anchw = NumCast(cropping._width) * (this._props.NativeDimScaling?.() || 1);
const anchh = NumCast(cropping._height) * (this._props.NativeDimScaling?.() || 1);
- const viewScale = 1;
+ // const viewScale = 1;
cropping.title = 'crop: ' + this.Document.title;
cropping.x = NumCast(this.Document.x) + NumCast(this.layoutDoc._width);
cropping.y = NumCast(this.Document.y);
@@ -128,9 +144,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
croppingProto.proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO
croppingProto.type = DocumentType.IMG;
croppingProto.layout = ImageBox.LayoutString('data');
- croppingProto.data = new ImageField(Utils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png'));
- croppingProto['data_nativeWidth'] = anchw;
- croppingProto['data_nativeHeight'] = anchh;
+ croppingProto.data = new ImageField(ClientUtils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png'));
+ croppingProto.data_nativeWidth = anchw;
+ croppingProto.data_nativeHeight = anchh;
if (addCrop) {
DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' });
}
@@ -146,8 +162,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
(NumCast(region.x) * this._props.PanelWidth()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']),
4
)
- .then((data_url: any) => {
- Utils.convertDataUri(data_url, region[Id]).then(returnedfilename =>
+ .then((dataUrl: any) => {
+ ClientUtils.convertDataUri(dataUrl, region[Id]).then(returnedfilename =>
setTimeout(
action(() => {
croppingProto.data = new ImageField(returnedfilename);
@@ -156,7 +172,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
)
);
})
- .catch(function (error: any) {
+ .catch((error: any) => {
console.error('oops, something went wrong!', error);
});
@@ -168,7 +184,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const docViewContent = this.DocumentView?.().ContentDiv!;
const filename = this.layoutDoc[Id] + '-icon' + new Date().getTime();
this._pdfViewer?._mainCont.current &&
- CollectionFreeFormView.UpdateIcon(
+ UpdateIcon(
filename,
docViewContent,
NumCast(this.layoutDoc._width),
@@ -182,8 +198,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
(iconFile: string, nativeWidth: number, nativeHeight: number) => {
setTimeout(() => {
this.dataDoc.icon = new ImageField(iconFile);
- this.dataDoc['icon_nativeWidth'] = nativeWidth;
- this.dataDoc['icon_nativeHeight'] = nativeHeight;
+ this.dataDoc.icon_nativeWidth = nativeWidth;
+ this.dataDoc.icon_nativeHeight = nativeHeight;
}, 500);
}
);
@@ -214,12 +230,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
);
}
- sidebarAddDocTab = (doc: Doc, where: OpenWhere) => {
- if (DocListCast(this.Document[this._props.fieldKey + '_sidebar']).includes(doc) && !this.SidebarShown) {
+ sidebarAddDocTab = (docIn: Doc | Doc[], where: OpenWhere) => {
+ const docs = toList(docIn);
+ if (docs.some(doc => DocListCast(this.Document[this._props.fieldKey + '_sidebar']).includes(doc)) && !this.SidebarShown) {
this.toggleSidebar(false);
return true;
}
- return this._props.addDocTab(doc, where);
+ return this._props.addDocTab(docs, where);
};
focus = (anchor: Doc, options: FocusViewOptions) => {
this._initialScrollTarget = anchor;
@@ -231,23 +248,25 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
options.didMove = true;
this.toggleSidebar(false);
}
- return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
+ return new Promise<Opt<DocumentView>>(res => {
+ DocumentView.addViewRenderedCb(doc, dv => res(dv));
+ });
};
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
- let ele: Opt<HTMLDivElement> = undefined;
+ let ele: Opt<HTMLDivElement>;
if (this._pdfViewer?.selectionContent()) {
ele = document.createElement('div');
ele.append(this._pdfViewer.selectionContent()!);
}
const docAnchor = () =>
Docs.Create.ConfigDocument({
- title: StrCast(this.Document.title + '@' + NumCast(this.layoutDoc._layout_scrollTop)?.toFixed(0)),
+ title: StrCast(this.Document.title + '@' + (NumCast(this.layoutDoc._layout_scrollTop) ?? 0).toFixed(0)),
annotationOn: this.Document,
});
const visibleAnchor = this._pdfViewer?._getAnchor?.(this._pdfViewer.savedAnnotations(), true);
const anchor = visibleAnchor ?? docAnchor();
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.Document);
anchor.text = ele?.textContent ?? '';
anchor.text_html = ele?.innerHTML;
addAsAnnotation && this.addDocument(anchor);
@@ -264,7 +283,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
!this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw));
};
- public search = action((searchString: string, bwd?: boolean, clear: boolean = false) => {
+ override search = action((searchString: string, bwd?: boolean, clear: boolean = false) => {
if (!this._searching && !clear) {
this._searching = true;
setTimeout(() => {
@@ -285,7 +304,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this.Document._layout_curPage = Math.min(NumCast(this.dataDoc[this._props.fieldKey + '_numPages']), (NumCast(this.Document._layout_curPage) || 1) + 1);
return true;
};
- public gotoPage = (p: number) => (this.Document._layout_curPage = p);
+ public gotoPage = (p: number) => {
+ this.Document._layout_curPage = p;
+ };
@undoBatch
onKeyDown = action((e: KeyboardEvent) => {
@@ -297,6 +318,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
case 'PageUp':
processed = this.backPage();
break;
+ default:
}
if (processed) {
e.stopImmediatePropagation();
@@ -306,13 +328,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
setPdfViewer = (pdfViewer: PDFViewer) => {
this._pdfViewer = pdfViewer;
- const docView = this.DocumentView?.();
- if (this._initialScrollTarget && docView) {
+ if (this._initialScrollTarget) {
this.focus(this._initialScrollTarget, { instant: true });
this._initialScrollTarget = undefined;
}
};
- searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => (this._searchString = e.currentTarget.value);
+ searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this._searchString = e.currentTarget.value;
+ };
// adding external documents; to sidebar key
// if (doc.Geolocation) this.addDocument(doc, this.fieldkey+"_annotation")
@@ -326,7 +349,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
setupMoveUpEvents(
this,
e,
- (e, down, delta) => {
+ (moveEv, down, delta) => {
const localDelta = this._props
.ScreenToLocalTransform()
.scale(this._props.NativeDimScaling?.() || 1)
@@ -341,7 +364,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
return false;
},
- (e, movement, isClick) => !isClick && batch.end(),
+ (clickEv, movement, isClick) => !isClick && batch.end(),
() => {
onButton && this.toggleSidebar();
batch.end();
@@ -368,11 +391,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
settingsPanel() {
const pageBtns = (
<>
- <button className="pdfBox-backBtn" key="back" title="Page Back" onPointerDown={e => e.stopPropagation()} onClick={this.backPage}>
- <FontAwesomeIcon style={{ color: 'white' }} icon={'arrow-left'} size="sm" />
+ <button type="button" className="pdfBox-backBtn" key="back" title="Page Back" onPointerDown={e => e.stopPropagation()} onClick={this.backPage}>
+ <FontAwesomeIcon style={{ color: 'white' }} icon="arrow-left" size="sm" />
</button>
- <button className="pdfBox-fwdBtn" key="fwd" title="Page Forward" onPointerDown={e => e.stopPropagation()} onClick={this.forwardPage}>
- <FontAwesomeIcon style={{ color: 'white' }} icon={'arrow-right'} size="sm" />
+ <button type="button" className="pdfBox-fwdBtn" key="fwd" title="Page Forward" onPointerDown={e => e.stopPropagation()} onClick={this.forwardPage}>
+ <FontAwesomeIcon style={{ color: 'white' }} icon="arrow-right" size="sm" />
</button>
</>
);
@@ -385,7 +408,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
onPointerDown={e => e.stopPropagation()}
style={{ display: this._props.isContentActive() ? 'flex' : 'none' }}>
<div className="pdfBox-overlayCont" onPointerDown={e => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
- <button className="pdfBox-overlayButton" title={searchTitle} />
+ <button type="button" className="pdfBox-overlayButton" title={searchTitle} />
<input
className="pdfBox-searchBar"
placeholder="Search"
@@ -396,17 +419,18 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
e.keyCode === KeyCodes.ENTER && this.search(this._searchString, e.shiftKey);
}}
/>
- <button className="pdfBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}>
+ <button type="button" className="pdfBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}>
<FontAwesomeIcon icon="search" size="sm" />
</button>
- <button className="pdfBox-prevIcon" title="Previous Annotation" onClick={this.prevAnnotation}>
- <FontAwesomeIcon icon={'arrow-up'} size="lg" />
+ <button type="button" className="pdfBox-prevIcon" title="Previous Annotation" onClick={this.prevAnnotation}>
+ <FontAwesomeIcon icon="arrow-up" size="lg" />
</button>
- <button className="pdfBox-nextIcon" title="Next Annotation" onClick={this.nextAnnotation}>
- <FontAwesomeIcon icon={'arrow-down'} size="lg" />
+ <button type="button" className="pdfBox-nextIcon" title="Next Annotation" onClick={this.nextAnnotation}>
+ <FontAwesomeIcon icon="arrow-down" size="lg" />
</button>
</div>
<button
+ type="button"
className="pdfBox-overlayButton"
title={searchTitle}
onClick={action(() => {
@@ -423,9 +447,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
<input
value={curPage}
style={{ width: `${curPage > 99 ? 4 : 3}ch`, pointerEvents: 'all' }}
- onChange={e => (this.Document._layout_curPage = Number(e.currentTarget.value))}
+ onChange={e => {
+ this.Document._layout_curPage = Number(e.currentTarget.value);
+ }}
onKeyDown={e => e.stopPropagation()}
- onClick={action(() => (this._pageControls = !this._pageControls))}
+ onClick={action(() => {
+ this._pageControls = !this._pageControls;
+ })}
/>
{this._pageControls ? pageBtns : null}
</div>
@@ -440,18 +468,20 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
return PDFBox.sidebarResizerWidth + nativeDiff * (this._props.NativeDimScaling?.() || 1);
};
@undoBatch
- toggleSidebarType = () => (this.dataDoc[this.SidebarKey + '_type_collection'] = this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform ? CollectionViewType.Stacking : CollectionViewType.Freeform);
- specificContextMenu = (e: React.MouseEvent): void => {
+ toggleSidebarType = () => {
+ this.dataDoc[this.SidebarKey + '_type_collection'] = this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform ? CollectionViewType.Stacking : CollectionViewType.Freeform;
+ };
+ specificContextMenu = (): void => {
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" });
+ // 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 : [];
- helpItems.push({ description: 'Copy path', event: () => this.pdfUrl && Utils.CopyText(Utils.prepend('') + this.pdfUrl.url.pathname), icon: 'expand-arrows-alt' });
+ 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' });
};
@@ -469,7 +499,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
@observable _showSidebar = false;
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._show_sidebar ? true : false;
+ return !!(this._showSidebar || this.layoutDoc._show_sidebar);
}
@computed get sidebarHandle() {
return (
@@ -483,7 +513,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={e => this.sidebarBtnDown(e, true)}>
- <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" />
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon="comment-alt" size="sm" />
</div>
);
}
@@ -514,6 +544,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
return ComponentTag === CollectionStackingView ? (
<SidebarAnnos
ref={this._sidebarRef}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
Document={this.Document}
layoutDoc={this.layoutDoc}
@@ -527,8 +558,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
removeDocument={this.removeDocument}
/>
) : (
- <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.DocumentView?.()!, false), true)}>
+ <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this._props.select(false), true)}>
<ComponentTag
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setContentViewBox={emptyFunction} // override setContentView to do nothing
NativeWidth={this.sidebarNativeWidthFunc}
@@ -539,7 +571,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
yPadding={0}
viewField={this.SidebarKey}
isAnnotationOverlay={false}
- originTopLeft={true}
+ originTopLeft
isAnyChildContentActive={this.isAnyChildContentActive}
select={emptyFunction}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
@@ -548,7 +580,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
addDocument={this.sidebarAddDocument}
ScreenToLocalTransform={this.sidebarScreenToLocal}
renderDepth={this._props.renderDepth + 1}
- noSidebar={true}
+ noSidebar
fieldKey={this.SidebarKey}
/>
</div>
@@ -582,6 +614,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
top: 0,
}}>
<PDFViewer
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
pdfBox={this}
sidebarAddDoc={this.sidebarAddDocument}
@@ -614,12 +647,24 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const pdfView = !this._pdf ? null : this.renderPdfView;
const href = this.pdfUrl?.url.href;
if (!pdfView && href) {
- if (PDFBox.pdfcache.get(href)) setTimeout(action(() => (this._pdf = PDFBox.pdfcache.get(href))));
+ if (PDFBox.pdfcache.get(href))
+ setTimeout(
+ action(() => {
+ this._pdf = PDFBox.pdfcache.get(href);
+ })
+ );
else {
if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise);
- PDFBox.pdfpromise.get(href)?.then(action((pdf: any) => PDFBox.pdfcache.set(href, (this._pdf = pdf))));
+ PDFBox.pdfpromise.get(href)?.then((pdf: any) => {
+ PDFBox.pdfcache.set(href, (this._pdf = pdf));
+ });
}
}
return pdfView ?? this.renderTitleBox;
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.PDF, {
+ layout: { view: PDFBox, dataField: 'data' },
+ options: { acl: '', _layout_curPage: 1, _layout_fitWidth: true, _layout_nativeDimEditable: true, _layout_reflowVertical: true, systemIcon: 'BsFileEarmarkPdfFill' },
+});
diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
index ae674d604..f88eb3bca 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
@@ -1,3 +1,11 @@
+/* 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 */
import ArrowLeftIcon from '@mui/icons-material/ArrowLeft';
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
import PauseIcon from '@mui/icons-material/Pause';
@@ -13,13 +21,15 @@ import { NumListCast } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
import { BoolCast, NumCast, StrCast } from '../../../../fields/Types';
import { ViewBoxAnnotatableComponent } from '../../DocComponent';
-import { FieldView, FieldViewProps } from './../FieldView';
+import { FieldView, FieldViewProps } from '../FieldView';
import './PhysicsSimulationBox.scss';
import InputField from './PhysicsSimulationInputField';
import questions from './PhysicsSimulationQuestions.json';
import tutorials from './PhysicsSimulationTutorial.json';
import Wall from './PhysicsSimulationWall';
import Weight from './PhysicsSimulationWeight';
+import { Docs } from '../../../documents/Documents';
+import { DocumentType } from '../../../documents/DocumentTypes';
interface IWallProps {
length: number;
@@ -204,7 +214,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
componentDidUpdate(prevProps: Readonly<FieldViewProps>) {
super.componentDidUpdate(prevProps);
- if (this.xMax !== this._props.PanelWidth() * 0.6 || this.yMax != this._props.PanelHeight()) {
+ if (this.xMax !== this._props.PanelWidth() * 0.6 || this.yMax !== this._props.PanelHeight()) {
this.xMax = this._props.PanelWidth() * 0.6;
this.yMax = this._props.PanelHeight();
this.setupSimulation();
@@ -219,16 +229,16 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
@action
setupSimulation = () => {
- const simulationType = this.simulationType;
+ const { simulationType } = this;
const mode = this.simulationMode;
this.dataDoc.simulation_paused = true;
- if (simulationType != 'Circular Motion') {
+ if (simulationType !== 'Circular Motion') {
this.dataDoc.mass1_velocityXstart = 0;
this.dataDoc.mass1_velocityYstart = 0;
this.dataDoc.mass1_velocityX = 0;
this.dataDoc.mass1_velocityY = 0;
}
- if (mode == 'Freeform') {
+ if (mode === 'Freeform') {
this.dataDoc.simulation_showForceMagnitudes = true;
// prettier-ignore
switch (simulationType) {
@@ -247,9 +257,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
case 'Circular Motion': this.setupCircular(20); break;
case 'Pulley': this.setupPulley(); break;
case 'Suspension': this.setupSuspension();break;
+ default:
}
this._simReset++;
- } else if (mode == 'Review') {
+ } else if (mode === 'Review') {
this.dataDoc.simulation_showComponentForces = false;
this.dataDoc.simulation_showForceMagnitudes = true;
this.dataDoc.simulation_showAcceleration = false;
@@ -265,12 +276,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
case 'Circular Motion': this.setupCircular(0); break; // TODO - circular motion review problems
case 'Pulley': this.setupPulley(); break; // TODO - pulley tutorial review problems
case 'Suspension': this.setupSuspension(); break; // TODO - suspension tutorial review problems
+ default:
}
- } else if (mode == 'Tutorial') {
+ } else if (mode === 'Tutorial') {
this.dataDoc.simulation_showComponentForces = false;
this.dataDoc.tutorial_stepNumber = 0;
this.dataDoc.simulation_showAcceleration = false;
- if (this.simulationType != 'Circular Motion') {
+ if (this.simulationType !== 'Circular Motion') {
this.dataDoc.mass1_velocityX = 0;
this.dataDoc.mass1_velocityY = 0;
this.dataDoc.simulation_showVelocity = false;
@@ -333,6 +345,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this.dataDoc.mass1_forcesStart = JSON.stringify(tutorials.suspension.steps[0].forces);
this.dataDoc.simulation_showForceMagnitudes = tutorials.suspension.steps[0].showMagnitude;
break;
+ default:
}
this._simReset++;
}
@@ -349,7 +362,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
magnitude: Math.abs(this.gravity) * Math.cos(Math.atan(height / width)) * this.mass1,
directionInDegrees: 180 - 90 - (Math.atan(height / width) * 180) / Math.PI,
};
- let frictionForce: IForce = {
+ const frictionForce: IForce = {
description: 'Static Friction Force',
magnitude: coefficient * Math.abs(this.gravity) * Math.cos(Math.atan(height / width)) * this.mass1,
directionInDegrees: 180 - (Math.atan(height / width) * 180) / Math.PI,
@@ -378,7 +391,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
directionInDegrees: 360 - (Math.atan(height / width) * 180) / Math.PI,
};
const gravityForce = this.gravityForce(this.mass1);
- if (coefficient != 0) {
+ if (coefficient !== 0) {
this.dataDoc.mass1_forcesStart = JSON.stringify([gravityForce, normalForce, frictionForce]);
this.dataDoc.mass1_forcesUpdated = JSON.stringify([gravityForce, normalForce, frictionForce]);
this.dataDoc.mass1_componentForces = JSON.stringify([frictionForce, normalForceComponent, gravityParallel, gravityPerpendicular]);
@@ -396,12 +409,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this.dataDoc.wedge_height = Math.tan(radAng) * this.dataDoc.wedge_width;
// update weight position based on updated wedge width/height
- let yPos = this.yMax - this.dataDoc.wedge_height - this.mass1Radius * Math.cos(radAng) - this.mass1Radius;
- let xPos = this.xMax * 0.25 + this.mass1Radius * Math.sin(radAng) - this.mass1Radius;
+ const yPos = this.yMax - this.dataDoc.wedge_height - this.mass1Radius * Math.cos(radAng) - this.mass1Radius;
+ const xPos = this.xMax * 0.25 + this.mass1Radius * Math.sin(radAng) - this.mass1Radius;
this.dataDoc.mass1_positionXstart = xPos;
this.dataDoc.mass1_positionYstart = yPos;
- if (this.simulationMode == 'Freeform') {
+ if (this.simulationMode === 'Freeform') {
this.updateForcesWithFriction(NumCast(this.dataDoc.coefficientOfStaticFriction), this.dataDoc.wedge_width, Math.tan(radAng) * this.dataDoc.wedge_width);
}
};
@@ -409,7 +422,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
// In review mode, update forces when coefficient of static friction changed
updateReviewForcesBasedOnCoefficient = (coefficient: number) => {
let theta = this.wedgeAngle;
- let index = this.selectedQuestion.variablesForQuestionSetup.indexOf('theta - max 45');
+ const index = this.selectedQuestion.variablesForQuestionSetup.indexOf('theta - max 45');
if (index >= 0) {
theta = NumListCast(this.dataDoc.questionVariables)[index];
}
@@ -467,26 +480,26 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
const description = question.answerSolutionDescriptions[i];
if (!isNaN(NumCast(description))) {
solutions.push(NumCast(description));
- } else if (description == 'solve normal force angle from wedge angle') {
+ } else if (description === 'solve normal force angle from wedge angle') {
solutions.push(90 - theta);
- } else if (description == 'solve normal force magnitude from wedge angle') {
+ } else if (description === 'solve normal force magnitude from wedge angle') {
solutions.push(Math.abs(this.gravity) * Math.cos((theta / 180) * Math.PI));
- } else if (description == 'solve static force magnitude from wedge angle given equilibrium') {
- let normalForceMagnitude = Math.abs(this.gravity) * Math.cos((theta / 180) * Math.PI);
- let normalForceAngle = 90 - theta;
- let frictionForceAngle = 180 - theta;
- let frictionForceMagnitude = (-normalForceMagnitude * Math.sin((normalForceAngle * Math.PI) / 180) + Math.abs(this.gravity)) / Math.sin((frictionForceAngle * Math.PI) / 180);
+ } else if (description === 'solve static force magnitude from wedge angle given equilibrium') {
+ const normalForceMagnitude = Math.abs(this.gravity) * Math.cos((theta / 180) * Math.PI);
+ const normalForceAngle = 90 - theta;
+ const frictionForceAngle = 180 - theta;
+ const frictionForceMagnitude = (-normalForceMagnitude * Math.sin((normalForceAngle * Math.PI) / 180) + Math.abs(this.gravity)) / Math.sin((frictionForceAngle * Math.PI) / 180);
solutions.push(frictionForceMagnitude);
- } else if (description == 'solve static force angle from wedge angle given equilibrium') {
+ } else if (description === 'solve static force angle from wedge angle given equilibrium') {
solutions.push(180 - theta);
- } else if (description == 'solve minimum static coefficient from wedge angle given equilibrium') {
- let normalForceMagnitude = Math.abs(this.gravity) * Math.cos((theta / 180) * Math.PI);
- let normalForceAngle = 90 - theta;
- let frictionForceAngle = 180 - theta;
- let frictionForceMagnitude = (-normalForceMagnitude * Math.sin((normalForceAngle * Math.PI) / 180) + Math.abs(this.gravity)) / Math.sin((frictionForceAngle * Math.PI) / 180);
- let frictionCoefficient = frictionForceMagnitude / normalForceMagnitude;
+ } else if (description === 'solve minimum static coefficient from wedge angle given equilibrium') {
+ const normalForceMagnitude = Math.abs(this.gravity) * Math.cos((theta / 180) * Math.PI);
+ const normalForceAngle = 90 - theta;
+ const frictionForceAngle = 180 - theta;
+ const frictionForceMagnitude = (-normalForceMagnitude * Math.sin((normalForceAngle * Math.PI) / 180) + Math.abs(this.gravity)) / Math.sin((frictionForceAngle * Math.PI) / 180);
+ const frictionCoefficient = frictionForceMagnitude / normalForceMagnitude;
solutions.push(frictionCoefficient);
- } else if (description == 'solve maximum wedge angle from coefficient of static friction given equilibrium') {
+ } else if (description === 'solve maximum wedge angle from coefficient of static friction given equilibrium') {
solutions.push((Math.atan(muS) * 180) / Math.PI);
}
}
@@ -497,38 +510,38 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
// In review mode, check if input answers match correct answers and optionally generate alert
checkAnswers = (showAlert: boolean = true) => {
let error: boolean = false;
- let epsilon: number = 0.01;
+ const epsilon: number = 0.01;
if (this.selectedQuestion) {
for (let i = 0; i < this.selectedQuestion.answerParts.length; i++) {
- if (this.selectedQuestion.answerParts[i] == 'force of gravity') {
+ if (this.selectedQuestion.answerParts[i] === 'force of gravity') {
if (Math.abs(NumCast(this.dataDoc.review_GravityMagnitude) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'angle of gravity') {
+ } else if (this.selectedQuestion.answerParts[i] === 'angle of gravity') {
if (Math.abs(NumCast(this.dataDoc.review_GravityAngle) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'normal force') {
+ } else if (this.selectedQuestion.answerParts[i] === 'normal force') {
if (Math.abs(NumCast(this.dataDoc.review_NormalMagnitude) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'angle of normal force') {
+ } else if (this.selectedQuestion.answerParts[i] === 'angle of normal force') {
if (Math.abs(NumCast(this.dataDoc.review_NormalAngle) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'force of static friction') {
+ } else if (this.selectedQuestion.answerParts[i] === 'force of static friction') {
if (Math.abs(NumCast(this.dataDoc.review_StaticMagnitude) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'angle of static friction') {
+ } else if (this.selectedQuestion.answerParts[i] === 'angle of static friction') {
if (Math.abs(NumCast(this.dataDoc.review_StaticAngle) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'coefficient of static friction') {
+ } else if (this.selectedQuestion.answerParts[i] === 'coefficient of static friction') {
if (Math.abs(NumCast(this.dataDoc.coefficientOfStaticFriction) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'wedge angle') {
+ } else if (this.selectedQuestion.answerParts[i] === 'wedge angle') {
if (Math.abs(this.wedgeAngle - this.selectedSolutions[i]) > epsilon) {
error = true;
}
@@ -539,7 +552,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this.dataDoc.simulation_paused = false;
setTimeout(() => (this.dataDoc.simulation_paused = true), 3000);
}
- if (this.selectedQuestion.goal == 'noMovement') {
+ if (this.selectedQuestion.goal === 'noMovement') {
this.dataDoc.noMovement = !error;
}
};
@@ -571,12 +584,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
let wedge_angle = 0;
for (let i = 0; i < question.variablesForQuestionSetup.length; i++) {
- if (question.variablesForQuestionSetup[i] == 'theta - max 45') {
- let randValue = Math.floor(Math.random() * 44 + 1);
+ if (question.variablesForQuestionSetup[i] === 'theta - max 45') {
+ const randValue = Math.floor(Math.random() * 44 + 1);
vars.push(randValue);
wedge_angle = randValue;
- } else if (question.variablesForQuestionSetup[i] == 'coefficient of static friction') {
- let randValue = Math.round(Math.random() * 1000) / 1000;
+ } else if (question.variablesForQuestionSetup[i] === 'coefficient of static friction') {
+ const randValue = Math.round(Math.random() * 1000) / 1000;
vars.push(randValue);
coefficient = randValue;
}
@@ -589,7 +602,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
let q = '';
for (let i = 0; i < question.questionSetup.length; i++) {
q += question.questionSetup[i];
- if (i != question.questionSetup.length - 1) {
+ if (i !== question.questionSetup.length - 1) {
q += vars[i];
if (question.variablesForQuestionSetup[i].includes('theta')) {
q += ' degree (≈' + Math.round((1000 * (vars[i] * Math.PI)) / 180) / 1000 + ' rad)';
@@ -601,7 +614,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this.dataDoc.questionPartOne = q;
this.dataDoc.questionPartTwo = question.question;
this.dataDoc.answers = new List<number>(this.getAnswersToQuestion(question, vars));
- //this.dataDoc.simulation_reset = (!this.dataDoc.simulation_reset);
+ // this.dataDoc.simulation_reset = (!this.dataDoc.simulation_reset);
};
// Default setup for uniform circular motion simulation
@@ -610,8 +623,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this.dataDoc.simulation_showComponentForces = false;
this.dataDoc.mass1_velocityYstart = 0;
this.dataDoc.mass1_velocityXstart = value;
- let xPos = (this.xMax + this.xMin) / 2 - this.mass1Radius;
- let yPos = (this.yMax + this.yMin) / 2 + this.circularMotionRadius - this.mass1Radius;
+ const xPos = (this.xMax + this.xMin) / 2 - this.mass1Radius;
+ const yPos = (this.yMax + this.yMin) / 2 + this.circularMotionRadius - this.mass1Radius;
this.dataDoc.mass1_positionYstart = yPos;
this.dataDoc.mass1_positionXstart = xPos;
const tensionForce: IForce = {
@@ -680,13 +693,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
// Default setup for suspension simulation
@action
setupSuspension = () => {
- let xPos = (this.xMax + this.xMin) / 2 - this.mass1Radius;
- let yPos = this.yMin + 200;
+ const xPos = (this.xMax + this.xMin) / 2 - this.mass1Radius;
+ const yPos = this.yMin + 200;
this.dataDoc.mass1_positionYstart = yPos;
this.dataDoc.mass1_positionXstart = xPos;
this.dataDoc.mass1_positionY = this.getDisplayYPos(yPos);
this.dataDoc.mass1_positionX = xPos;
- let tensionMag = (this.mass1 * Math.abs(this.gravity)) / (2 * Math.sin(Math.PI / 4));
+ const tensionMag = (this.mass1 * Math.abs(this.gravity)) / (2 * Math.sin(Math.PI / 4));
const tensionForce1: IForce = {
description: 'Tension',
magnitude: tensionMag,
@@ -891,7 +904,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
setVelocity={this.setVelocity1}
setAcceleration={this.setAcceleration1}
/>
- {this.simulationType == 'Pulley' && (
+ {this.simulationType === 'Pulley' && (
<Weight
{...commonWeightProps}
color="green"
@@ -916,7 +929,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
)}
</div>
<div style={{ position: 'absolute', transformOrigin: 'top left', top: 0, left: 0, width: '100%', height: '100%' }}>
- {(this.simulationType == 'One Weight' || this.simulationType == 'Inclined Plane') &&
+ {(this.simulationType === 'One Weight' || this.simulationType === 'Inclined Plane') &&
this.wallPositions?.map((element, index) => <Wall key={index} length={element.length} xPos={element.xPos} yPos={element.yPos} angleInDegrees={element.angleInDegrees} />)}
</div>
</div>
@@ -927,17 +940,17 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
style={{ overflow: 'auto', height: `${Math.max(1, 800 / this._props.PanelWidth()) * 100}%`, transform: `scale(${Math.min(1, this._props.PanelWidth() / 850)})` }}>
<div className="mechanicsSimulationControls">
<Stack direction="row" spacing={1}>
- {this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && (
+ {this.dataDoc.simulation_paused && this.simulationMode !== 'Tutorial' && (
<IconButton onClick={() => (this.dataDoc.simulation_paused = false)}>
<PlayArrowIcon />
</IconButton>
)}
- {!this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && (
+ {!this.dataDoc.simulation_paused && this.simulationMode !== 'Tutorial' && (
<IconButton onClick={() => (this.dataDoc.simulation_paused = true)}>
<PauseIcon />
</IconButton>
)}
- {this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && (
+ {this.dataDoc.simulation_paused && this.simulationMode !== 'Tutorial' && (
<IconButton onClick={action(() => this._simReset++)}>
<ReplayIcon />
</IconButton>
@@ -974,15 +987,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</select>
</div>
</div>
- {this.simulationMode == 'Review' && this.simulationType != 'Inclined Plane' && (
+ {this.simulationMode === 'Review' && this.simulationType !== 'Inclined Plane' && (
<div className="wordProblemBox">
- <p>
- <>{this.simulationType} review problems in progress!</>
- </p>
+ <p>{this.simulationType} review problems in progress!</p>
<hr />
</div>
)}
- {this.simulationMode == 'Review' && this.simulationType == 'Inclined Plane' && (
+ {this.simulationMode === 'Review' && this.simulationType === 'Inclined Plane' && (
<div>
{!this.dataDoc.hintDialogueOpen && (
<IconButton
@@ -995,7 +1006,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
<QuestionMarkIcon />
</IconButton>
)}
- <Dialog maxWidth={'sm'} fullWidth={true} open={BoolCast(this.dataDoc.hintDialogueOpen)} onClose={() => (this.dataDoc.hintDialogueOpen = false)}>
+ <Dialog maxWidth="sm" fullWidth open={BoolCast(this.dataDoc.hintDialogueOpen)} onClose={() => (this.dataDoc.hintDialogueOpen = false)}>
<DialogTitle>Hints</DialogTitle>
<DialogContent>
{this.selectedQuestion.hints?.map((hint: any, index: number) => (
@@ -1030,12 +1041,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="review_GravityMagnitude"
step={0.1}
- unit={'N'}
+ unit="N"
upperBound={50}
value={NumCast(this.dataDoc.review_GravityMagnitude)}
showIcon={BoolCast(this.dataDoc.simulation_showIcon)}
correctValue={NumListCast(this.dataDoc.answers)[this.selectedQuestion.answerParts.indexOf('force of gravity')]}
- labelWidth={'7em'}
+ labelWidth="7em"
/>
)}
{this.selectedQuestion.answerParts.includes('angle of gravity') && (
@@ -1045,13 +1056,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="review_GravityAngle"
step={1}
- unit={'°'}
+ unit="°"
upperBound={360}
value={NumCast(this.dataDoc.review_GravityAngle)}
- radianEquivalent={true}
+ radianEquivalent
showIcon={BoolCast(this.dataDoc.simulation_showIcon)}
correctValue={NumListCast(this.dataDoc.answers)[this.selectedQuestion.answerParts.indexOf('angle of gravity')]}
- labelWidth={'7em'}
+ labelWidth="7em"
/>
)}
{this.selectedQuestion.answerParts.includes('normal force') && (
@@ -1061,12 +1072,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="review_NormalMagnitude"
step={0.1}
- unit={'N'}
+ unit="N"
upperBound={50}
value={NumCast(this.dataDoc.review_NormalMagnitude)}
showIcon={BoolCast(this.dataDoc.simulation_showIcon)}
correctValue={NumListCast(this.dataDoc.answers)[this.selectedQuestion.answerParts.indexOf('normal force')]}
- labelWidth={'7em'}
+ labelWidth="7em"
/>
)}
{this.selectedQuestion.answerParts.includes('angle of normal force') && (
@@ -1076,13 +1087,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="review_NormalAngle"
step={1}
- unit={'°'}
+ unit="°"
upperBound={360}
value={NumCast(this.dataDoc.review_NormalAngle)}
- radianEquivalent={true}
+ radianEquivalent
showIcon={BoolCast(this.dataDoc.simulation_showIcon)}
correctValue={NumListCast(this.dataDoc.answers)[this.selectedQuestion.answerParts.indexOf('angle of normal force')]}
- labelWidth={'7em'}
+ labelWidth="7em"
/>
)}
{this.selectedQuestion.answerParts.includes('force of static friction') && (
@@ -1092,12 +1103,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="review_StaticMagnitude"
step={0.1}
- unit={'N'}
+ unit="N"
upperBound={50}
value={NumCast(this.dataDoc.review_StaticMagnitude)}
showIcon={BoolCast(this.dataDoc.simulation_showIcon)}
correctValue={NumListCast(this.dataDoc.answers)[this.selectedQuestion.answerParts.indexOf('force of static friction')]}
- labelWidth={'7em'}
+ labelWidth="7em"
/>
)}
{this.selectedQuestion.answerParts.includes('angle of static friction') && (
@@ -1107,13 +1118,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="review_StaticAngle"
step={1}
- unit={'°'}
+ unit="°"
upperBound={360}
value={NumCast(this.dataDoc.review_StaticAngle)}
- radianEquivalent={true}
+ radianEquivalent
showIcon={BoolCast(this.dataDoc.simulation_showIcon)}
correctValue={NumListCast(this.dataDoc.answers)[this.selectedQuestion.answerParts.indexOf('angle of static friction')]}
- labelWidth={'7em'}
+ labelWidth="7em"
/>
)}
{this.selectedQuestion.answerParts.includes('coefficient of static friction') && (
@@ -1127,7 +1138,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="coefficientOfStaticFriction"
step={0.1}
- unit={''}
+ unit=""
upperBound={1}
value={NumCast(this.dataDoc.coefficientOfStaticFriction)}
effect={this.updateReviewForcesBasedOnCoefficient}
@@ -1142,14 +1153,14 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="wedge_angle"
step={1}
- unit={'°'}
+ unit="°"
upperBound={49}
value={this.wedgeAngle}
effect={(val: number) => {
this.changeWedgeBasedOnNewAngle(val);
this.updateReviewForcesBasedOnAngle(val);
}}
- radianEquivalent={true}
+ radianEquivalent
showIcon={BoolCast(this.dataDoc.simulation_showIcon)}
correctValue={NumListCast(this.dataDoc.answers)[this.selectedQuestion.answerParts.indexOf('wedge angle')]}
/>
@@ -1158,7 +1169,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</div>
</div>
)}
- {this.simulationMode == 'Tutorial' && (
+ {this.simulationMode === 'Tutorial' && (
<div className="wordProblemBox">
<div className="question">
<h2>Problem</h2>
@@ -1180,7 +1191,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this.dataDoc.mass1_forcesUpdated = JSON.stringify(this.tutorial.steps[step].forces);
this.dataDoc.simulation_showForceMagnitudes = this.tutorial.steps[step].showMagnitude;
}}
- disabled={this.dataDoc.tutorial_stepNumber == 0}>
+ disabled={this.dataDoc.tutorial_stepNumber === 0}>
<ArrowLeftIcon />
</IconButton>
<div>
@@ -1204,8 +1215,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</IconButton>
</div>
<div>
- {(this.simulationType == 'One Weight' || this.simulationType == 'Inclined Plane' || this.simulationType == 'Pendulum') && <p>Resources</p>}
- {this.simulationType == 'One Weight' && (
+ {(this.simulationType === 'One Weight' || this.simulationType === 'Inclined Plane' || this.simulationType === 'Pendulum') && <p>Resources</p>}
+ {this.simulationType === 'One Weight' && (
<ul>
<li>
<a
@@ -1233,7 +1244,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</li>
</ul>
)}
- {this.simulationType == 'Inclined Plane' && (
+ {this.simulationType === 'Inclined Plane' && (
<ul>
<li>
<a
@@ -1261,7 +1272,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</li>
</ul>
)}
- {this.simulationType == 'Pendulum' && (
+ {this.simulationType === 'Pendulum' && (
<ul>
<li>
<a
@@ -1280,7 +1291,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</div>
</div>
)}
- {this.simulationMode == 'Review' && this.simulationType == 'Inclined Plane' && (
+ {this.simulationMode === 'Review' && this.simulationType === 'Inclined Plane' && (
<div
style={{
display: 'flex',
@@ -1318,11 +1329,11 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</div>
</div>
)}
- {this.simulationMode == 'Freeform' && (
+ {this.simulationMode === 'Freeform' && (
<div className="vars">
<FormControl component="fieldset">
<FormGroup>
- {this.simulationType == 'One Weight' && (
+ {this.simulationType === 'One Weight' && (
<FormControlLabel
control={<Checkbox checked={BoolCast(this.dataDoc.elasticCollisions)} onChange={() => (this.dataDoc.elasticCollisions = !this.dataDoc.elasticCollisions)} />}
label="Make collisions elastic"
@@ -1334,7 +1345,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
label="Show force vectors"
labelPlacement="start"
/>
- {(this.simulationType == 'Inclined Plane' || this.simulationType == 'Pendulum') && (
+ {(this.simulationType === 'Inclined Plane' || this.simulationType === 'Pendulum') && (
<FormControlLabel
control={<Checkbox checked={BoolCast(this.dataDoc.simulation_showComponentForces)} onChange={() => (this.dataDoc.simulation_showComponentForces = !this.dataDoc.simulation_showComponentForces)} />}
label="Show component force vectors"
@@ -1351,80 +1362,80 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
label="Show velocity vector"
labelPlacement="start"
/>
- <InputField label={<Box>Speed</Box>} lowerBound={1} dataDoc={this.dataDoc} prop="simulation_speed" step={1} unit={'x'} upperBound={10} value={NumCast(this.dataDoc.simulation_speed, 2)} labelWidth={'5em'} />
- {this.dataDoc.simulation_paused && this.simulationType != 'Circular Motion' && (
+ <InputField label={<Box>Speed</Box>} lowerBound={1} dataDoc={this.dataDoc} prop="simulation_speed" step={1} unit="x" upperBound={10} value={NumCast(this.dataDoc.simulation_speed, 2)} labelWidth="5em" />
+ {this.dataDoc.simulation_paused && this.simulationType !== 'Circular Motion' && (
<InputField
label={<Box>Gravity</Box>}
lowerBound={-30}
dataDoc={this.dataDoc}
prop="gravity"
step={0.01}
- unit={'m/s2'}
+ unit="m/s2"
upperBound={0}
value={NumCast(this.dataDoc.simulation_gravity, -9.81)}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.dataDoc.simulation_paused && this.simulationType != 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType !== 'Pulley' && (
<InputField
label={<Box>Mass</Box>}
lowerBound={1}
dataDoc={this.dataDoc}
prop="mass1"
step={0.1}
- unit={'kg'}
+ unit="kg"
upperBound={5}
value={this.mass1 ?? 1}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.dataDoc.simulation_paused && this.simulationType == 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType === 'Pulley' && (
<InputField
label={<Box>Red mass</Box>}
lowerBound={1}
dataDoc={this.dataDoc}
prop="mass1"
step={0.1}
- unit={'kg'}
+ unit="kg"
upperBound={5}
value={this.mass1 ?? 1}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.dataDoc.simulation_paused && this.simulationType == 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType === 'Pulley' && (
<InputField
label={<Box>Blue mass</Box>}
lowerBound={1}
dataDoc={this.dataDoc}
prop="mass2"
step={0.1}
- unit={'kg'}
+ unit="kg"
upperBound={5}
value={this.mass2 ?? 1}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.dataDoc.simulation_paused && this.simulationType == 'Circular Motion' && (
+ {this.dataDoc.simulation_paused && this.simulationType === 'Circular Motion' && (
<InputField
label={<Box>Rod length</Box>}
lowerBound={100}
dataDoc={this.dataDoc}
prop="circularMotionRadius"
step={5}
- unit={'m'}
+ unit="m"
upperBound={250}
value={this.circularMotionRadius}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
</FormGroup>
</FormControl>
- {this.simulationType == 'Spring' && this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Spring' && this.dataDoc.simulation_paused && (
<div>
<InputField
label={<Typography color="inherit">Spring stiffness</Typography>}
@@ -1432,13 +1443,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="spring_constant"
step={1}
- unit={'N/m'}
+ unit="N/m"
upperBound={500}
value={this.springConstant}
effect={action(() => this._simReset++)}
radianEquivalent={false}
- mode={'Freeform'}
- labelWidth={'7em'}
+ mode="Freeform"
+ labelWidth="7em"
/>
<InputField
label={<Typography color="inherit">Rest length</Typography>}
@@ -1452,7 +1463,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
effect={action(() => this._simReset++)}
radianEquivalent={false}
mode="Freeform"
- labelWidth={'7em'}
+ labelWidth="7em"
/>
<InputField
label={<Typography color="inherit">Starting displacement</Typography>}
@@ -1470,11 +1481,11 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
})}
radianEquivalent={false}
mode="Freeform"
- labelWidth={'7em'}
+ labelWidth="7em"
/>
</div>
)}
- {this.simulationType == 'Inclined Plane' && this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Inclined Plane' && this.dataDoc.simulation_paused && (
<div>
<InputField
label={<Box>&theta;</Box>}
@@ -1482,16 +1493,16 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="wedge_angle"
step={1}
- unit={'°'}
+ unit="°"
upperBound={49}
value={this.wedgeAngle}
effect={action((val: number) => {
this.changeWedgeBasedOnNewAngle(val);
this._simReset++;
})}
- radianEquivalent={true}
- mode={'Freeform'}
- labelWidth={'2em'}
+ radianEquivalent
+ mode="Freeform"
+ labelWidth="2em"
/>
<InputField
label={
@@ -1503,7 +1514,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="coefficientOfStaticFriction"
step={0.1}
- unit={''}
+ unit=""
upperBound={1}
value={NumCast(this.dataDoc.coefficientOfStaticFriction) ?? 0}
effect={action((val: number) => {
@@ -1513,8 +1524,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
}
this._simReset++;
})}
- mode={'Freeform'}
- labelWidth={'2em'}
+ mode="Freeform"
+ labelWidth="2em"
/>
<InputField
label={
@@ -1526,16 +1537,16 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="coefficientOfKineticFriction"
step={0.1}
- unit={''}
+ unit=""
upperBound={NumCast(this.dataDoc.coefficientOfStaticFriction)}
value={NumCast(this.dataDoc.coefficientOfKineticFriction) ?? 0}
effect={action(() => this._simReset++)}
- mode={'Freeform'}
- labelWidth={'2em'}
+ mode="Freeform"
+ labelWidth="2em"
/>
</div>
)}
- {this.simulationType == 'Inclined Plane' && !this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Inclined Plane' && !this.dataDoc.simulation_paused && (
<Typography>
<>
&theta;: {Math.round(this.wedgeAngle * 100) / 100}° ≈ {Math.round(((this.wedgeAngle * Math.PI) / 180) * 100) / 100} rad
@@ -1546,12 +1557,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</>
</Typography>
)}
- {this.simulationType == 'Pendulum' && !this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Pendulum' && !this.dataDoc.simulation_paused && (
<Typography>
&theta;: {Math.round(this.pendulumAngle * 100) / 100}° ≈ {Math.round(((this.pendulumAngle * Math.PI) / 180) * 100) / 100} rad
</Typography>
)}
- {this.simulationType == 'Pendulum' && this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Pendulum' && this.dataDoc.simulation_paused && (
<div>
<InputField
label={<Box>Angle</Box>}
@@ -1559,13 +1570,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="pendulum_angle"
step={1}
- unit={'°'}
+ unit="°"
upperBound={59}
value={NumCast(this.dataDoc.pendulum_angle, 30)}
effect={action(value => {
this.dataDoc.pendulum_angleStart = value;
this.dataDoc.pendulum_lengthStart = this.dataDoc.pendulum_length;
- if (this.simulationType == 'Pendulum') {
+ if (this.simulationType === 'Pendulum') {
const mag = this.mass1 * Math.abs(this.gravity) * Math.cos((value * Math.PI) / 180);
const forceOfTension: IForce = {
@@ -1598,7 +1609,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this._simReset++;
}
})}
- radianEquivalent={true}
+ radianEquivalent
mode="Freeform"
labelWidth="5em"
/>
@@ -1612,7 +1623,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
upperBound={400}
value={Math.round(this.pendulumLength)}
effect={action(value => {
- if (this.simulationType == 'Pendulum') {
+ if (this.simulationType === 'Pendulum') {
this.dataDoc.pendulum_angleStart = this.pendulumAngle;
this.dataDoc.pendulum_lengthStart = value;
this._simReset++;
@@ -1627,11 +1638,11 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</div>
)}
<div className="mechanicsSimulationEquation">
- {this.simulationMode == 'Freeform' && (
+ {this.simulationMode === 'Freeform' && (
<table>
<tbody>
<tr>
- <td>{this.simulationType == 'Pulley' ? 'Red Weight' : ''}</td>
+ <td>{this.simulationType === 'Pulley' ? 'Red Weight' : ''}</td>
<td>X</td>
<td>Y</td>
</tr>
@@ -1646,36 +1657,34 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
>
<Box>Position</Box>
</td>
- {(!this.dataDoc.simulation_paused || this.simulationType == 'Inclined Plane' || this.simulationType == 'Circular Motion' || this.simulationType == 'Pulley') && (
- <td style={{ cursor: 'default' }}>
- <>{this.dataDoc.mass1_positionX} m</>
- </td>
+ {(!this.dataDoc.simulation_paused || this.simulationType === 'Inclined Plane' || this.simulationType === 'Circular Motion' || this.simulationType === 'Pulley') && (
+ <td style={{ cursor: 'default' }}>{this.dataDoc.mass1_positionX + ''} m</td>
)}{' '}
- {this.dataDoc.simulation_paused && this.simulationType != 'Inclined Plane' && this.simulationType != 'Circular Motion' && this.simulationType != 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType !== 'Inclined Plane' && this.simulationType !== 'Circular Motion' && this.simulationType !== 'Pulley' && (
<td
style={{
cursor: 'default',
}}>
<InputField
- lowerBound={this.simulationType == 'Projectile' ? 1 : (this.xMax + this.xMin) / 4 - this.radius - 15}
+ lowerBound={this.simulationType === 'Projectile' ? 1 : (this.xMax + this.xMin) / 4 - this.radius - 15}
dataDoc={this.dataDoc}
prop="mass1_positionX"
step={1}
- unit={'m'}
- upperBound={this.simulationType == 'Projectile' ? this.xMax - 110 : (3 * (this.xMax + this.xMin)) / 4 - this.radius / 2 - 15}
+ unit="m"
+ upperBound={this.simulationType === 'Projectile' ? this.xMax - 110 : (3 * (this.xMax + this.xMin)) / 4 - this.radius / 2 - 15}
value={NumCast(this.dataDoc.mass1_positionX)}
effect={value => {
this.dataDoc.mass1_xChange = value;
- if (this.simulationType == 'Suspension') {
- let x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200;
- let x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius;
- let deltaX1 = value + this.radius - x1rod;
- let deltaX2 = x2rod - (value + this.radius);
- let deltaY = this.getYPosFromDisplay(NumCast(this.dataDoc.mass1_positionY)) + this.radius;
+ if (this.simulationType === 'Suspension') {
+ const x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200;
+ const x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius;
+ const deltaX1 = value + this.radius - x1rod;
+ const deltaX2 = x2rod - (value + this.radius);
+ const deltaY = this.getYPosFromDisplay(NumCast(this.dataDoc.mass1_positionY)) + this.radius;
let dir1T = Math.PI - Math.atan(deltaY / deltaX1);
let dir2T = Math.atan(deltaY / deltaX2);
- let tensionMag2 = (this.mass1 * Math.abs(this.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T));
- let tensionMag1 = (-tensionMag2 * Math.cos(dir2T)) / Math.cos(dir1T);
+ const tensionMag2 = (this.mass1 * Math.abs(this.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T));
+ const tensionMag1 = (-tensionMag2 * Math.cos(dir2T)) / Math.cos(dir1T);
dir1T = (dir1T * 180) / Math.PI;
dir2T = (dir2T * 180) / Math.PI;
const tensionForce1: IForce = {
@@ -1692,15 +1701,15 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this.dataDoc.mass1_forcesUpdated = JSON.stringify([tensionForce1, tensionForce2, gravity]);
}
}}
- small={true}
+ small
mode="Freeform"
/>
</td>
)}{' '}
- {(!this.dataDoc.simulation_paused || this.simulationType == 'Inclined Plane' || this.simulationType == 'Circular Motion' || this.simulationType == 'Pulley') && (
+ {(!this.dataDoc.simulation_paused || this.simulationType === 'Inclined Plane' || this.simulationType === 'Circular Motion' || this.simulationType === 'Pulley') && (
<td style={{ cursor: 'default' }}>{`${NumCast(this.dataDoc.mass1_positionY)} m`}</td>
)}{' '}
- {this.dataDoc.simulation_paused && this.simulationType != 'Inclined Plane' && this.simulationType != 'Circular Motion' && this.simulationType != 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType !== 'Inclined Plane' && this.simulationType !== 'Circular Motion' && this.simulationType !== 'Pulley' && (
<td
style={{
cursor: 'default',
@@ -1715,16 +1724,16 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
value={NumCast(this.dataDoc.mass1_positionY)}
effect={value => {
this.dataDoc.mass1_yChange = value;
- if (this.simulationType == 'Suspension') {
- let x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200;
- let x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius;
- let deltaX1 = NumCast(this.dataDoc.mass1_positionX) + this.radius - x1rod;
- let deltaX2 = x2rod - (NumCast(this.dataDoc.mass1_positionX) + this.radius);
- let deltaY = this.getYPosFromDisplay(value) + this.radius;
+ if (this.simulationType === 'Suspension') {
+ const x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200;
+ const x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius;
+ const deltaX1 = NumCast(this.dataDoc.mass1_positionX) + this.radius - x1rod;
+ const deltaX2 = x2rod - (NumCast(this.dataDoc.mass1_positionX) + this.radius);
+ const deltaY = this.getYPosFromDisplay(value) + this.radius;
let dir1T = Math.PI - Math.atan(deltaY / deltaX1);
let dir2T = Math.atan(deltaY / deltaX2);
- let tensionMag2 = (this.mass1 * Math.abs(this.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T));
- let tensionMag1 = (-tensionMag2 * Math.cos(dir2T)) / Math.cos(dir1T);
+ const tensionMag2 = (this.mass1 * Math.abs(this.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T));
+ const tensionMag1 = (-tensionMag2 * Math.cos(dir2T)) / Math.cos(dir1T);
dir1T = (dir1T * 180) / Math.PI;
dir2T = (dir2T * 180) / Math.PI;
const tensionForce1: IForce = {
@@ -1741,7 +1750,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
this.dataDoc.mass1_forcesUpdated = JSON.stringify([tensionForce1, tensionForce2, gravity]);
}
}}
- small={true}
+ small
mode="Freeform"
/>
</td>
@@ -1758,10 +1767,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
>
<Box>Velocity</Box>
</td>
- {(!this.dataDoc.simulation_paused || (this.simulationType != 'One Weight' && this.simulationType != 'Circular Motion')) && (
+ {(!this.dataDoc.simulation_paused || (this.simulationType !== 'One Weight' && this.simulationType !== 'Circular Motion')) && (
<td style={{ cursor: 'default' }}>{`${NumCast(this.dataDoc.mass1_velocityX)} m/s`}</td>
)}{' '}
- {this.dataDoc.simulation_paused && (this.simulationType == 'One Weight' || this.simulationType == 'Circular Motion') && (
+ {this.dataDoc.simulation_paused && (this.simulationType === 'One Weight' || this.simulationType === 'Circular Motion') && (
<td
style={{
cursor: 'default',
@@ -1771,24 +1780,20 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
dataDoc={this.dataDoc}
prop="mass1_velocityX"
step={1}
- unit={'m/s'}
+ unit="m/s"
upperBound={50}
value={NumCast(this.dataDoc.mass1_velocityX)}
effect={action(value => {
this.dataDoc.mass1_velocityXstart = value;
this._simReset++;
})}
- small={true}
+ small
mode="Freeform"
/>
</td>
)}{' '}
- {(!this.dataDoc.simulation_paused || this.simulationType != 'One Weight') && (
- <td style={{ cursor: 'default' }}>
- <>{this.dataDoc.mass1_velocityY} m/s</>
- </td>
- )}{' '}
- {this.dataDoc.simulation_paused && this.simulationType == 'One Weight' && (
+ {(!this.dataDoc.simulation_paused || this.simulationType !== 'One Weight') && <td style={{ cursor: 'default' }}>{this.dataDoc.mass1_velocityY + ''} m/s</td>}{' '}
+ {this.dataDoc.simulation_paused && this.simulationType === 'One Weight' && (
<td
style={{
cursor: 'default',
@@ -1804,7 +1809,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
effect={value => {
this.dataDoc.mass1_velocityYstart = -value;
}}
- small={true}
+ small
mode="Freeform"
/>
</td>
@@ -1822,14 +1827,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
<Box>Acceleration</Box>
</td>
<td style={{ cursor: 'default' }}>
- <>
- {this.dataDoc.mass1_accelerationX} m/s<sup>2</sup>
- </>
+ {this.dataDoc.mass1_accelerationX + ''} m/s<sup>2</sup>
</td>
<td style={{ cursor: 'default' }}>
- <>
- {this.dataDoc.mass1_accelerationY} m/s<sup>2</sup>
- </>
+ {this.dataDoc.mass1_accelerationY + ''} m/s<sup>2</sup>
</td>
</tr>
<tr>
@@ -1842,7 +1843,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</tbody>
</table>
)}
- {this.simulationMode == 'Freeform' && this.simulationType == 'Pulley' && (
+ {this.simulationMode === 'Freeform' && this.simulationType === 'Pulley' && (
<table>
<tbody>
<tr>
@@ -1869,14 +1870,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
<Box>Acceleration</Box>
</td>
<td style={{ cursor: 'default' }}>
- <>
- {this.dataDoc.mass2_accelerationX} m/s<sup>2</sup>
- </>
+ {this.dataDoc.mass2_accelerationX + ''} m/s<sup>2</sup>
</td>
<td style={{ cursor: 'default' }}>
- <>
- {this.dataDoc.mass2_accelerationY} m/s<sup>2</sup>
- </>
+ {this.dataDoc.mass2_accelerationY + ''} m/s<sup>2</sup>
</td>
</tr>
<tr>
@@ -1890,7 +1887,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</table>
)}
</div>
- {this.simulationType != 'Pendulum' && this.simulationType != 'Spring' && (
+ {this.simulationType !== 'Pendulum' && this.simulationType !== 'Spring' && (
<div>
<p>Kinematic Equations</p>
<ul>
@@ -1907,7 +1904,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</ul>
</div>
)}
- {this.simulationType == 'Spring' && (
+ {this.simulationType === 'Spring' && (
<div>
<p>Harmonic Motion Equations: Spring</p>
<ul>
@@ -1936,7 +1933,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
</ul>
</div>
)}
- {this.simulationType == 'Pendulum' && (
+ {this.simulationType === 'Pendulum' && (
<div>
<p>Harmonic Motion Equations: Pendulum</p>
<ul>
@@ -1959,11 +1956,11 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
<svg width={100 + 'px'} height={100 + 'px'}>
<defs>
<marker id="miniArrow" markerWidth="20" markerHeight="20" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
- <path d="M0,0 L0,6 L9,3 z" fill={'#000000'} />
+ <path d="M0,0 L0,6 L9,3 z" fill="#000000" />
</marker>
</defs>
- <line x1={20} y1={70} x2={70} y2={70} stroke={'#000000'} strokeWidth="2" markerEnd="url(#miniArrow)" />
- <line x1={20} y1={70} x2={20} y2={20} stroke={'#000000'} strokeWidth="2" markerEnd="url(#miniArrow)" />
+ <line x1={20} y1={70} x2={70} y2={70} stroke="#000000" strokeWidth="2" markerEnd="url(#miniArrow)" />
+ <line x1={20} y1={70} x2={20} y2={20} stroke="#000000" strokeWidth="2" markerEnd="url(#miniArrow)" />
</svg>
<p
style={{
@@ -1971,7 +1968,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
top: this.yMax - 120 + 40 + 'px',
left: this.xMin + 90 - 80 + 'px',
}}>
- {this.simulationType == 'Circular Motion' ? 'Z' : 'Y'}
+ {this.simulationType === 'Circular Motion' ? 'Z' : 'Y'}
</p>
<p
style={{
@@ -1986,3 +1983,9 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.SIMULATION, {
+ data: '',
+ layout: { view: PhysicsSimulationBox, dataField: 'data' },
+ options: { acl: '', _width: 1000, _height: 800, mass1: '', mass2: '', layout_nativeDimEditable: true, position: '', acceleration: '', pendulum: '', spring: '', wedge: '', simulation: '', review: '', systemIcon: 'BsShareFill' },
+});
diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx
index 16450c359..48da4937a 100644
--- a/src/client/views/nodes/RadialMenu.tsx
+++ b/src/client/views/nodes/RadialMenu.tsx
@@ -6,22 +6,57 @@ import { RadialMenuItem, RadialMenuProps } from './RadialMenuItem';
@observer
export class RadialMenu extends React.Component {
+ // eslint-disable-next-line no-use-before-define
static Instance: RadialMenu;
static readonly buffer = 20;
+ @observable private _mouseX: number = -1;
+ @observable private _mouseY: number = -1;
+ @observable private _shouldDisplay: boolean = false;
+ @observable private _mouseDown: boolean = false;
+ @observable private _closest: number = -1;
+ @observable private _pageX: number = 0;
+ @observable private _pageY: number = 0;
+ @observable _display: boolean = false;
+ @observable private _yRelativeToTop: boolean = true;
+ @observable private _items: Array<RadialMenuProps> = [];
+ private _reactionDisposer?: IReactionDisposer;
+
constructor(props: any) {
super(props);
makeObservable(this);
RadialMenu.Instance = this;
}
- @observable private _mouseX: number = -1;
- @observable private _mouseY: number = -1;
- @observable private _shouldDisplay: boolean = false;
- @observable private _mouseDown: boolean = false;
- private _reactionDisposer?: IReactionDisposer;
+ componentDidMount() {
+ document.addEventListener('pointerdown', this.onPointerDown);
+ document.addEventListener('pointerup', this.onPointerUp);
+ this.previewcircle();
+ this._reactionDisposer = reaction(
+ () => this._shouldDisplay,
+ () =>
+ this._shouldDisplay &&
+ !this._mouseDown &&
+ runInAction(() => {
+ this._display = true;
+ })
+ );
+ }
- public used: boolean = false;
+ componentDidUpdate() {
+ this.previewcircle();
+ }
+ componentWillUnmount() {
+ document.removeEventListener('pointerdown', this.onPointerDown);
+
+ document.removeEventListener('pointerup', this.onPointerUp);
+ this._reactionDisposer && this._reactionDisposer();
+ }
+
+ @computed get menuItems() {
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ return this._items.map((item, index) => <RadialMenuItem {...item} key={item.description} closeMenu={this.closeMenu} max={this._items.length} min={index} selected={this._closest} />);
+ }
catchTouch = (te: React.TouchEvent) => {
te.stopPropagation();
@@ -33,13 +68,9 @@ export class RadialMenu extends React.Component {
this._mouseDown = true;
this._mouseX = e.clientX;
this._mouseY = e.clientY;
- this.used = false;
document.addEventListener('pointermove', this.onPointerMove);
};
- @observable
- private _closest: number = -1;
-
@action
onPointerMove = (e: PointerEvent) => {
const curX = e.clientX;
@@ -65,7 +96,6 @@ export class RadialMenu extends React.Component {
};
@action
onPointerUp = (e: PointerEvent) => {
- this.used = true;
this._mouseDown = false;
const curX = e.clientX;
const curY = e.clientY;
@@ -78,86 +108,6 @@ export class RadialMenu extends React.Component {
this._items[this._closest].event();
}
};
- componentWillUnmount() {
- document.removeEventListener('pointerdown', this.onPointerDown);
-
- document.removeEventListener('pointerup', this.onPointerUp);
- this._reactionDisposer && this._reactionDisposer();
- }
-
- @action
- componentDidMount() {
- document.addEventListener('pointerdown', this.onPointerDown);
- document.addEventListener('pointerup', this.onPointerUp);
- this.previewcircle();
- this._reactionDisposer = reaction(
- () => this._shouldDisplay,
- () => this._shouldDisplay && !this._mouseDown && runInAction(() => (this._display = true))
- );
- }
-
- componentDidUpdate = () => {
- this.previewcircle();
- };
-
- @observable private _pageX: number = 0;
- @observable private _pageY: number = 0;
- @observable _display: boolean = false;
- @observable private _yRelativeToTop: boolean = true;
-
- @observable private _width: number = 0;
- @observable private _height: number = 0;
-
- getItems() {
- return this._items;
- }
-
- @action
- addItem(item: RadialMenuProps) {
- if (this._items.indexOf(item) === -1) {
- this._items.push(item);
- }
- }
-
- @observable
- private _items: Array<RadialMenuProps> = [];
-
- @action
- displayMenu = (x: number, y: number) => {
- //maxX and maxY will change if the UI/font size changes, but will work for any amount
- //of items added to the menu
- this._mouseX = x;
- this._mouseY = y;
- this._shouldDisplay = true;
- };
- // @computed
- // get pageX() {
- // const x = this._pageX;
- // if (x < 0) {
- // return 0;
- // }
- // const width = this._width;
- // if (x + width > window.innerWidth - RadialMenu.buffer) {
- // return window.innerWidth - RadialMenu.buffer - width;
- // }
- // return x;
- // }
- // @computed
- // get pageY() {
- // const y = this._pageY;
- // if (y < 0) {
- // return 0;
- // }
- // const height = this._height;
- // if (y + height > window.innerHeight - RadialMenu.buffer) {
- // return window.innerHeight - RadialMenu.buffer - height;
- // }
- // return y;
- // }
-
- @computed get menuItems() {
- return this._items.map((item, index) => <RadialMenuItem {...item} key={item.description} closeMenu={this.closeMenu} max={this._items.length} min={index} selected={this._closest} />);
- }
@action
closeMenu = () => {
@@ -167,14 +117,6 @@ export class RadialMenu extends React.Component {
};
@action
- openMenu = (x: number, y: number) => {
- this._pageX = x;
- this._pageY = y;
- this._shouldDisplay;
- this._display = true;
- };
-
- @action
clearItems() {
this._items = [];
}
diff --git a/src/client/views/nodes/RadialMenuItem.tsx b/src/client/views/nodes/RadialMenuItem.tsx
index 91dc37d34..6f10e7b65 100644
--- a/src/client/views/nodes/RadialMenuItem.tsx
+++ b/src/client/views/nodes/RadialMenuItem.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { observer } from 'mobx-react';
@@ -53,6 +54,7 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> {
case 2:
color = 'lightgray';
break;
+ default:
}
if (circlemax % 3 === 1 && circlemin === circlemax - 1) {
color = '#c2c2c5';
@@ -80,7 +82,6 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> {
const avg = (circlemin / circlemax + (circlemin + 1) / circlemax) / 2;
const degrees = 360 * avg;
const x = 100 * Math.cos((degrees * Math.PI) / 180);
- const y = -125 * Math.sin((degrees * Math.PI) / 180);
return x;
}
@@ -91,7 +92,6 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> {
this.props.max ? (circlemax = this.props.max) : null;
const avg = (circlemin / circlemax + (circlemin + 1) / circlemax) / 2;
const degrees = 360 * avg;
- const x = 125 * Math.cos((degrees * Math.PI) / 180);
const y = -100 * Math.sin((degrees * Math.PI) / 180);
return y;
}
diff --git a/src/client/views/nodes/RecordingBox/ProgressBar.tsx b/src/client/views/nodes/RecordingBox/ProgressBar.tsx
index 1bb2b7c84..62798bc2f 100644
--- a/src/client/views/nodes/RecordingBox/ProgressBar.tsx
+++ b/src/client/views/nodes/RecordingBox/ProgressBar.tsx
@@ -1,31 +1,33 @@
+/* eslint-disable react/no-array-index-key */
+/* eslint-disable react/require-default-props */
import * as React from 'react';
-import { useEffect, useState, useCallback, useRef } from "react"
-import "./ProgressBar.scss"
+import { useEffect, useState, useRef } from 'react';
+import './ProgressBar.scss';
import { MediaSegment } from './RecordingView';
interface ProgressBarProps {
- videos: MediaSegment[],
- setVideos: React.Dispatch<React.SetStateAction<MediaSegment[]>>,
- orderVideos: boolean,
- progress: number,
- recording: boolean,
- doUndo: boolean,
- setCanUndo?: React.Dispatch<React.SetStateAction<boolean>>,
+ videos: MediaSegment[];
+ setVideos: React.Dispatch<React.SetStateAction<MediaSegment[]>>;
+ orderVideos: boolean;
+ progress: number;
+ recording: boolean;
+ doUndo: boolean;
+ setCanUndo?: React.Dispatch<React.SetStateAction<boolean>>;
}
interface SegmentBox {
- endTime: number,
- startTime: number,
- order: number,
+ endTime: number;
+ startTime: number;
+ order: number;
}
interface CurrentHover {
- index: number,
- minX: number,
- maxX: number
+ index: number;
+ minX: number;
+ maxX: number;
}
export function ProgressBar(props: ProgressBarProps) {
- const progressBarRef = useRef<HTMLDivElement | null>(null)
+ const progressBarRef = useRef<HTMLDivElement | null>(null);
// the actual list of JSX elements rendered as segments
const [segments, setSegments] = useState<JSX.Element[]>([]);
@@ -47,8 +49,6 @@ export function ProgressBar(props: ProgressBarProps) {
// update the canUndo props based on undo stack
useEffect(() => props.setCanUndo?.(undoStack.length > 0), [undoStack.length]);
- // useEffect for undo - brings back the most recently deleted segment
- useEffect(() => handleUndo(), [props.doUndo])
const handleUndo = () => {
// get the last element from the undo if it exists
if (undoStack.length === 0) return;
@@ -59,27 +59,36 @@ export function ProgressBar(props: ProgressBarProps) {
// update the removed time and place element back into ordered
setTotalRemovedTime(prevRemoved => prevRemoved - (last.endTime - last.startTime));
setOrdered(prevOrdered => [...prevOrdered, last]);
- }
+ };
+ // useEffect for undo - brings back the most recently deleted segment
+ useEffect(() => handleUndo(), [props.doUndo]);
// useEffect for recording changes - changes style to disabled and adds the "expanding-segment"
useEffect(() => {
// get segments segment's html using it's id -> make them appeared disabled (or enabled)
- segments.forEach((seg) => document.getElementById(seg.props.id)?.classList.toggle('segment-disabled', props.recording));
+ segments.forEach(seg => document.getElementById(seg.props.id)?.classList.toggle('segment-disabled', props.recording));
progressBarRef.current?.classList.toggle('progressbar-disabled', props.recording);
if (props.recording)
- setSegments(prevSegments => [...prevSegments, <div key='segment-expanding' id='segment-expanding' className='segment segment-expanding blink' style={{ width: 'fit-content' }}>{props.videos.length + 1}</div>]);
- }, [props.recording])
-
+ setSegments(prevSegments => [
+ ...prevSegments,
+ <div key="segment-expanding" id="segment-expanding" className="segment segment-expanding blink" style={{ width: 'fit-content' }}>
+ {props.videos.length + 1}
+ </div>,
+ ]);
+ }, [props.recording]);
// useEffect that updates the segmentsJSX, which is rendered
// only updated when ordered is updated or if the user is dragging around a segment
useEffect(() => {
const totalTime = props.progress * 1000 - totalRemovedTime;
- const segmentsJSX = ordered.map((seg, i) =>
- <div key={`segment-${i}`} id={`segment-${i}`} className={dragged === i ? 'segment-hide' : 'segment'} style={{ width: `${((seg.endTime - seg.startTime) / totalTime) * 100}%` }}>{seg.order + 1}</div>);
+ const segmentsJSX = ordered.map((seg, i) => (
+ <div key={`segment-${i}`} id={`segment-${i}`} className={dragged === i ? 'segment-hide' : 'segment'} style={{ width: `${((seg.endTime - seg.startTime) / totalTime) * 100}%` }}>
+ {seg.order + 1}
+ </div>
+ ));
- setSegments(segmentsJSX)
+ setSegments(segmentsJSX);
}, [dragged, ordered]);
// useEffect for dragged - update the cursor to be grabbing while grabbing
@@ -89,14 +98,14 @@ export function ProgressBar(props: ProgressBarProps) {
// to imporve performance, only want to update the CSS width, not re-render the whole JSXList
useEffect(() => {
- if (!props.recording) return
+ if (!props.recording) return;
const totalTime = props.progress * 1000 - totalRemovedTime;
let remainingTime = totalTime;
segments.forEach((seg, i) => {
// for the last segment, we need to set that directly
if (i === segments.length - 1) return;
// update remaining time
- remainingTime -= (ordered[i].endTime - ordered[i].startTime);
+ remainingTime -= ordered[i].endTime - ordered[i].startTime;
// update the width for this segment
const htmlId = seg.props.id;
@@ -106,8 +115,7 @@ export function ProgressBar(props: ProgressBarProps) {
// update the width of the expanding segment using the remaining time
const segExapandHtml = document.getElementById('segment-expanding');
- if (segExapandHtml)
- segExapandHtml.style.width = ordered.length === 0 ? '100%' : `${(remainingTime / totalTime) * 100}%`;
+ if (segExapandHtml) segExapandHtml.style.width = ordered.length === 0 ? '100%' : `${(remainingTime / totalTime) * 100}%`;
}, [props.progress]);
// useEffect for props.videos - update the ordered array when a new video is added
@@ -120,9 +128,7 @@ export function ProgressBar(props: ProgressBarProps) {
// in this case, a new video is added -> push it onto ordered
if (order >= ordered.length) {
const { endTime, startTime } = props.videos.lastElement();
- setOrdered(prevOrdered => {
- return [...prevOrdered, { endTime, startTime, order }];
- });
+ setOrdered(prevOrdered => [...prevOrdered, { endTime, startTime, order }]);
}
// in this case, a video is removed
@@ -132,7 +138,7 @@ export function ProgressBar(props: ProgressBarProps) {
}, [props.videos]);
// useEffect for props.orderVideos - matched the order array with the videos array before the export
- useEffect(() => props.setVideos(vids => ordered.map((seg) => vids[seg.order])), [props.orderVideos]);
+ useEffect(() => props.setVideos(vids => ordered.map(seg => vids[seg.order])), [props.orderVideos]);
// useEffect for removed - handles logic for removing a segment
useEffect(() => {
@@ -151,36 +157,68 @@ export function ProgressBar(props: ProgressBarProps) {
// returns the new currentHover based on the new index
const updateCurrentHover = (segId: number): CurrentHover | null => {
// get the segId of the segment that will become the new bounding area
- const rect = progressBarRef.current?.children[segId].getBoundingClientRect()
- if (rect == null) return null
+ const rect = progressBarRef.current?.children[segId].getBoundingClientRect();
+ if (rect == null) return null;
return {
index: segId,
minX: rect.x,
maxX: rect.x + rect.width,
- }
- }
+ };
+ };
+
+ const swapSegments = (oldIndex: number, newIndex: number) => {
+ if (newIndex == null) return;
+ setOrdered(prevOrdered => {
+ const temp = { ...prevOrdered[oldIndex] };
+ prevOrdered[oldIndex] = prevOrdered[newIndex];
+ prevOrdered[newIndex] = temp;
+ return prevOrdered;
+ });
+ // update visually where the segment is hovering over
+ setDragged(newIndex);
+ };
+
+ // functions for the floating segment that tracks the cursor while grabbing it
+ const initDetachSegment = (dot: HTMLDivElement, rect: DOMRect) => {
+ dot.classList.add('segment-selected');
+ dot.style.transitionDuration = '0s';
+ dot.style.position = 'absolute';
+ dot.style.zIndex = '999';
+ dot.style.width = `${rect.width}px`;
+ dot.style.height = `${rect.height}px`;
+ dot.style.left = `${rect.x}px`;
+ dot.style.top = `${rect.y}px`;
+ dot.draggable = false;
+ document.body.append(dot);
+ };
+ const followCursor = (event: PointerEvent, dot: HTMLDivElement): void => {
+ // event.stopPropagation()
+ const { width, height } = dot.getBoundingClientRect();
+ dot.style.left = `${event.clientX - width / 2}px`;
+ dot.style.top = `${event.clientY - height / 2}px`;
+ };
// pointerdown event for the progress bar
- const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
- // don't move the videobox element
- e.stopPropagation();
+ const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+ // don't move the videobox element
+ e.stopPropagation();
// if recording, do nothing
- if (props.recording) return;
+ if (props.recording) return;
// get the segment the user clicked on to be dragged
- const clickedSegment = e.target as HTMLDivElement & EventTarget
+ const clickedSegment = e.target as HTMLDivElement & EventTarget;
// get the profess bar ro add event listeners
// don't do anything if null
- const progressBar = progressBarRef.current
- if (progressBar == null || clickedSegment.id === progressBar.id) return
+ const progressBar = progressBarRef.current;
+ if (progressBar == null || clickedSegment.id === progressBar.id) return;
// if holding shift key, let's remove that segment
if (e.shiftKey) {
const segId = parseInt(clickedSegment.id.split('-')[1]);
setRemoved(segId);
- return
+ return;
}
// if holding ctrl key and click, let's undo that segment #hiddenfeature lol
@@ -192,26 +230,26 @@ export function ProgressBar(props: ProgressBarProps) {
// if we're here, the user is dragging a segment around
// let the progress bar capture all the pointer events until the user releases (pointerUp)
const ptrId = e.pointerId;
- progressBar.setPointerCapture(ptrId)
+ progressBar.setPointerCapture(ptrId);
- const rect = clickedSegment.getBoundingClientRect()
- // id for segment is like 'segment-1' or 'segment-10',
+ const rect = clickedSegment.getBoundingClientRect();
+ // id for segment is like 'segment-1' or 'segment-10',
// so this works to get the id
- const segId = parseInt(clickedSegment.id.split('-')[1])
+ const segId = parseInt(clickedSegment.id.split('-')[1]);
// set the selected segment to be the one dragged
- setDragged(segId)
+ setDragged(segId);
- // this is the logic for storing the lower X bound and upper X bound to know
+ // this is the logic for storing the lower X bound and upper X bound to know
// whether a swap is needed between two segments
let currentHover: CurrentHover = {
index: segId,
minX: rect.x,
maxX: rect.x + rect.width,
- }
+ };
// create the floating segment that tracks the cursor
- const detchedSegment = document.createElement("div")
- initDeatchSegment(detchedSegment, rect);
+ const detchedSegment = document.createElement('div');
+ initDetachSegment(detchedSegment, rect);
const updateSegmentOrder = (event: PointerEvent): void => {
event.stopPropagation();
@@ -219,6 +257,7 @@ export function ProgressBar(props: ProgressBarProps) {
// this fixes a bug where pointerup doesn't fire while cursor is upped while being dragged
if (!progressBar.hasPointerCapture(ptrId)) {
+ // eslint-disable-next-line no-use-before-define
placeSegmentandCleanup();
return;
}
@@ -228,24 +267,23 @@ export function ProgressBar(props: ProgressBarProps) {
const curX = event.clientX;
// handle the left bound
if (curX < currentHover.minX && currentHover.index > 0) {
- swapSegments(currentHover.index, currentHover.index - 1)
- currentHover = updateCurrentHover(currentHover.index - 1) ?? currentHover
+ swapSegments(currentHover.index, currentHover.index - 1);
+ currentHover = updateCurrentHover(currentHover.index - 1) ?? currentHover;
}
// handle the right bound
else if (curX > currentHover.maxX && currentHover.index < segments.length - 1) {
- swapSegments(currentHover.index, currentHover.index + 1)
- currentHover = updateCurrentHover(currentHover.index + 1) ?? currentHover
+ swapSegments(currentHover.index, currentHover.index + 1);
+ currentHover = updateCurrentHover(currentHover.index + 1) ?? currentHover;
}
- }
+ };
// handles when the user is done dragging the segment (pointerUp)
const placeSegmentandCleanup = (event?: PointerEvent): void => {
event?.stopPropagation();
event?.preventDefault();
// if they put the segment outside of the bounds, remove it
- if (event && (event.clientX < 0 || event.clientX > document.body.clientWidth || event.clientY < 0 || event.clientY > document.body.clientHeight))
- setRemoved(currentHover.index);
-
+ if (event && (event.clientX < 0 || event.clientX > document.body.clientWidth || event.clientY < 0 || event.clientY > document.body.clientHeight)) setRemoved(currentHover.index);
+
// remove the update event listener for pointermove
progressBar.removeEventListener('pointermove', updateSegmentOrder);
// remove the floating segment from the DOM
@@ -253,49 +291,16 @@ export function ProgressBar(props: ProgressBarProps) {
// dragged is -1 is equiv to nothing being dragged, so the normal state
// so this will place the segment in it's location and update the segment bar
setDragged(-1);
- }
+ };
// event listeners that allow the user to drag and release the floating segment
progressBar.addEventListener('pointermove', updateSegmentOrder);
progressBar.addEventListener('pointerup', placeSegmentandCleanup, { once: true });
- }
-
- const swapSegments = (oldIndex: number, newIndex: number) => {
- if (newIndex == null) return;
- setOrdered(prevOrdered => {
- const temp = { ...prevOrdered[oldIndex] }
- prevOrdered[oldIndex] = prevOrdered[newIndex]
- prevOrdered[newIndex] = temp
- return prevOrdered
- });
- // update visually where the segment is hovering over
- setDragged(newIndex);
- }
-
- // functions for the floating segment that tracks the cursor while grabbing it
- const initDeatchSegment = (dot: HTMLDivElement, rect: DOMRect) => {
- dot.classList.add("segment-selected");
- dot.style.transitionDuration = '0s';
- dot.style.position = 'absolute';
- dot.style.zIndex = '999';
- dot.style.width = `${rect.width}px`;
- dot.style.height = `${rect.height}px`;
- dot.style.left = `${rect.x}px`;
- dot.style.top = `${rect.y}px`;
- dot.draggable = false;
- document.body.append(dot);
- }
- const followCursor = (event: PointerEvent, dot: HTMLDivElement): void => {
- // event.stopPropagation()
- const { width, height } = dot.getBoundingClientRect();
- dot.style.left = `${event.clientX - width / 2}px`;
- dot.style.top = `${event.clientY - height / 2}px`;
- }
-
+ };
return (
<div className="progressbar" id="progressbar" onPointerDown={onPointerDown} ref={progressBarRef}>
{segments}
</div>
- )
-} \ No newline at end of file
+ );
+}
diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
index e38a42b29..07381c7d0 100644
--- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { DateField } from '../../../../fields/DateField';
import { Doc, DocListCast } from '../../../../fields/Doc';
+import { DocData } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { List } from '../../../../fields/List';
import { BoolCast, DocCast } from '../../../../fields/Types';
@@ -10,18 +11,18 @@ import { VideoField } from '../../../../fields/URLField';
import { Upload } from '../../../../server/SharedMediaTypes';
import { DocumentType } from '../../../documents/DocumentTypes';
import { Docs } from '../../../documents/Documents';
-import { DocumentManager } from '../../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../../util/DragManager';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
import { Presentation } from '../../../util/TrackMovements';
import { undoBatch } from '../../../util/UndoManager';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView';
-import { media_state } from '../AudioBox';
+import { mediaState } from '../AudioBox';
+import { DocumentView } from '../DocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
import { VideoBox } from '../VideoBox';
import { RecordingView } from './RecordingView';
-import { DocData } from '../../../../fields/DocSymbols';
@observer
export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
@@ -43,20 +44,15 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
@observable result: Upload.AccessPathInfo | undefined = undefined;
- @observable videoDuration: number | undefined = undefined;
-
- @action
- setVideoDuration = (duration: number) => (this.videoDuration = duration);
@action
setResult = (info: Upload.AccessPathInfo, presentation?: Presentation) => {
this.result = info;
this.dataDoc.type = DocumentType.VID;
- this.dataDoc[this.fieldKey + '_duration'] = this.videoDuration;
- this.dataDoc.layout = VideoBox.LayoutString(this.fieldKey);
+ this.dataDoc[this.fieldKey + '_recorded'] = this.dataDoc.layout; // save the recording layout to allow re-recording later
+ this.dataDoc.layout = VideoBox.LayoutString(this.fieldKey); // then convert the recording box to a video
this.dataDoc[this._props.fieldKey] = new VideoField(this.result.accessPaths.client);
- this.dataDoc[this.fieldKey + '_recorded'] = true;
// stringify the presentation and store it
if (presentation?.movements) {
const presCopy = { ...presentation };
@@ -65,21 +61,20 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
};
@undoBatch
- @action
public static WorkspaceStopRecording() {
const remDoc = RecordingBox.screengrabber?.Document;
if (remDoc) {
- //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening
+ // if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening
RecordingBox.screengrabber?.Pause?.();
setTimeout(() => {
RecordingBox.screengrabber?.Finish?.();
- remDoc.overlayX = 70; //was 100
+ remDoc.overlayX = 70; // was 100
remDoc.overlayY = 590;
RecordingBox.screengrabber = undefined;
}, 100);
- //could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this
+ // could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this
setTimeout(() => Doc.RemFromMyOverlay(remDoc), 1000);
- Doc.UserDoc().workspaceRecordingState = media_state.Paused;
+ Doc.UserDoc().workspaceRecordingState = mediaState.Paused;
Doc.AddDocToList(Doc.UserDoc(), 'workspaceRecordings', remDoc);
}
}
@@ -90,7 +85,6 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
* @returns
*/
@undoBatch
- @action
public static WorkspaceStartRecording(value: string) {
const screengrabber =
value === 'Record Workspace'
@@ -104,15 +98,15 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
_width: 205,
_height: 115,
});
- screengrabber.overlayX = 70; //was -400
- screengrabber.overlayY = 590; //was 0
+ screengrabber.overlayX = 70; // was -400
+ screengrabber.overlayY = 590; // was 0
screengrabber[DocData][Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true;
- Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay
- DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => {
+ Doc.AddToMyOverlay(screengrabber); // just adds doc to overlay
+ DocumentView.addViewRenderedCb(screengrabber, docView => {
RecordingBox.screengrabber = docView.ComponentView as RecordingBox;
RecordingBox.screengrabber.Record?.();
});
- Doc.UserDoc().workspaceRecordingState = media_state.Recording;
+ Doc.UserDoc().workspaceRecordingState = mediaState.Recording;
}
/**
@@ -120,13 +114,12 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
* @param value RecordingBox rootdoc
*/
@undoBatch
- @action
public static replayWorkspace(value: Doc) {
Doc.UserDoc().currentRecording = value;
value.overlayX = 70;
value.overlayY = window.innerHeight - 180;
Doc.AddToMyOverlay(value);
- DocumentManager.Instance.AddViewRenderedCb(value, docView => {
+ DocumentView.addViewRenderedCb(value, docView => {
Doc.UserDoc().currentRecording = docView.Document;
docView.select(false);
RecordingBox.resumeWorkspaceReplaying(value);
@@ -138,9 +131,8 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
* @param value current recordingbox
*/
@undoBatch
- @action
public static addRecToWorkspace(value: RecordingBox) {
- let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView);
+ const ffView = DocumentView.allViews().find(view => view.ComponentView instanceof CollectionFreeFormView);
(ffView?.ComponentView as CollectionFreeFormView)._props.addDocument?.(value.Document);
Doc.RemoveDocFromList(Doc.UserDoc(), 'workspaceRecordings', value.Document);
Doc.RemFromMyOverlay(value.Document);
@@ -149,26 +141,18 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
Doc.UserDoc().workspaceRecordingState = undefined;
}
- @action
public static resumeWorkspaceReplaying(doc: Doc) {
- const docView = DocumentManager.Instance.getDocumentView(doc);
- if (docView?.ComponentView instanceof VideoBox) {
- docView.ComponentView.Play();
- }
- Doc.UserDoc().workspaceReplayingState = media_state.Playing;
+ const docView = DocumentView.getDocumentView(doc);
+ docView?.ComponentView?.Play?.();
+ Doc.UserDoc().workspaceReplayingState = mediaState.Playing;
}
- @action
public static pauseWorkspaceReplaying(doc: Doc) {
- const docView = DocumentManager.Instance.getDocumentView(doc);
- const videoBox = docView?.ComponentView as VideoBox;
- if (videoBox) {
- videoBox.Pause();
- }
- Doc.UserDoc().workspaceReplayingState = media_state.Paused;
+ const docView = DocumentView.getDocumentView(doc);
+ docView?.ComponentView?.Pause?.();
+ Doc.UserDoc().workspaceReplayingState = mediaState.Paused;
}
- @action
public static stopWorkspaceReplaying(value: Doc) {
Doc.RemFromMyOverlay(value);
Doc.UserDoc().currentRecording = undefined;
@@ -178,7 +162,6 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
@undoBatch
- @action
public static removeWorkspaceReplaying(value: Doc) {
Doc.RemoveDocFromList(Doc.UserDoc(), 'workspaceRecordings', value);
Doc.RemFromMyOverlay(value);
@@ -199,66 +182,78 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
render() {
return (
<div className="recordingBox" style={{ width: '100%' }} ref={this._ref}>
- {!this.result && (
- <RecordingView
- forceTrackScreen={BoolCast(this.layoutDoc[this.fieldKey + '_trackScreen'])}
- getControls={this.getControls}
- setResult={this.setResult}
- setDuration={this.setVideoDuration}
- id={DocCast(this.Document.proto)?.[Id] || ''}
- />
- )}
+ {!this.result && <RecordingView forceTrackScreen={BoolCast(this.layoutDoc[this.fieldKey + '_trackScreen'])} getControls={this.getControls} setResult={this.setResult} id={DocCast(this.Document.proto)?.[Id] || ''} />}
</div>
);
}
+ // eslint-disable-next-line no-use-before-define
static screengrabber: RecordingBox | undefined;
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function stopWorkspaceRecording() {
RecordingBox.WorkspaceStopRecording();
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function stopWorkspaceReplaying(value: Doc) {
RecordingBox.stopWorkspaceReplaying(value);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function removeWorkspaceReplaying(value: Doc) {
RecordingBox.removeWorkspaceReplaying(value);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function getCurrentRecording() {
return Doc.UserDoc().currentRecording;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function getWorkspaceRecordings() {
return new List<any>(['Record Workspace', `Record Webcam`, ...DocListCast(Doc.UserDoc().workspaceRecordings)]);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function isWorkspaceRecording() {
- return Doc.UserDoc().workspaceRecordingState === media_state.Recording;
+ return Doc.UserDoc().workspaceRecordingState === mediaState.Recording;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function isWorkspaceReplaying() {
return Doc.UserDoc().workspaceReplayingState;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function replayWorkspace(value: Doc | string, _readOnly_: boolean) {
if (_readOnly_) return DocCast(Doc.UserDoc().currentRecording) ?? 'Record Workspace';
if (typeof value === 'string') RecordingBox.WorkspaceStartRecording(value);
else RecordingBox.replayWorkspace(value);
+ return undefined;
});
-ScriptingGlobals.add(function pauseWorkspaceReplaying(value: Doc, _readOnly_: boolean) {
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function pauseWorkspaceReplaying(value: Doc) {
RecordingBox.pauseWorkspaceReplaying(value);
});
-ScriptingGlobals.add(function resumeWorkspaceReplaying(value: Doc, _readOnly_: boolean) {
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function resumeWorkspaceReplaying(value: Doc) {
RecordingBox.resumeWorkspaceReplaying(value);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function startRecordingDrag(value: { doc: Doc | string; e: React.PointerEvent }) {
if (DocCast(value.doc)) {
DragManager.StartDocumentDrag([value.e.target as HTMLElement], new DragManager.DocumentDragData([DocCast(value.doc)], dropActionType.embed), value.e.clientX, value.e.clientY);
value.e.preventDefault();
return true;
}
+ return undefined;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function renderDropdown() {
if (!Doc.UserDoc().workspaceRecordings || DocListCast(Doc.UserDoc().workspaceRecordings).length === 0) {
return true;
}
return false;
});
+
+Docs.Prototypes.TemplateMap.set(DocumentType.WEBCAM, {
+ layout: { view: RecordingBox, dataField: 'data' },
+ options: { acl: '', systemIcon: 'BsFillCameraVideoFill' },
+});
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.scss b/src/client/views/nodes/RecordingBox/RecordingView.scss
index 287cccd8f..f2d5a980d 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.scss
+++ b/src/client/views/nodes/RecordingBox/RecordingView.scss
@@ -1,208 +1,200 @@
video {
- // flex: 100%;
- width: 100%;
- // min-height: 400px;
- //height: auto;
- height: 100%;
- //display: block;
- object-fit: cover;
- background-color: black;
-}
-
-button {
- margin: 0 .5rem
+ // flex: 100%;
+ width: 100%;
+ // min-height: 400px;
+ //height: auto;
+ height: 100%;
+ //display: block;
+ object-fit: cover;
+ background-color: black;
}
.recording-container {
- height: 100%;
- width: 100%;
- // display: flex;
- pointer-events: all;
- background-color: black;
+ height: 100%;
+ width: 100%;
+ // display: flex;
+ pointer-events: all;
+ background-color: black;
+ button {
+ margin: 0 0.5rem;
+ }
}
.video-wrapper {
- // max-width: 600px;
- // max-width: 700px;
- // position: relative;
- display: flex;
- justify-content: center;
- // overflow: hidden;
- border-radius: 10px;
- margin: 0;
+ // max-width: 600px;
+ // max-width: 700px;
+ // position: relative;
+ display: flex;
+ justify-content: center;
+ // overflow: hidden;
+ border-radius: 10px;
+ margin: 0;
}
.video-wrapper:hover .controls {
- bottom: 34.5px;
- transform: translateY(0%);
- opacity: 100%;
+ bottom: 34.5px;
+ transform: translateY(0%);
+ opacity: 100%;
}
.controls {
- display: flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- width: 100%;
- flex-wrap: wrap;
- background: rgba(255, 255, 255, 0.25);
- box-shadow: 0 8px 32px 0 rgba(255, 255, 255, 0.1);
- // backdrop-filter: blur(4px);
- border-radius: 10px;
- border: 1px solid rgba(255, 255, 255, 0.18);
- transition: all 0.3s ease-in-out;
- bottom: 34.5px;
- height: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ width: 100%;
+ flex-wrap: wrap;
+ background: rgba(255, 255, 255, 0.25);
+ box-shadow: 0 8px 32px 0 rgba(255, 255, 255, 0.1);
+ // backdrop-filter: blur(4px);
+ border-radius: 10px;
+ border: 1px solid rgba(255, 255, 255, 0.18);
+ transition: all 0.3s ease-in-out;
+ bottom: 34.5px;
+ height: 60px;
}
.controls:active {
- bottom: 40px;
+ bottom: 40px;
}
.actions button {
- background: none;
- border: none;
- outline: none;
- cursor: pointer;
+ background: none;
+ border: none;
+ outline: none;
+ cursor: pointer;
}
.actions button i {
- background-color: none;
- color: white;
- font-size: 30px;
+ background-color: none;
+ color: white;
+ font-size: 30px;
}
-
.velocity {
- appearance: none;
- background: none;
- color: white;
- outline: none;
- border: none;
- text-align: center;
- font-size: 16px;
+ appearance: none;
+ background: none;
+ color: white;
+ outline: none;
+ border: none;
+ text-align: center;
+ font-size: 16px;
}
.mute-btn {
- background: none;
- border: none;
- outline: none;
- cursor: pointer;
+ background: none;
+ border: none;
+ outline: none;
+ cursor: pointer;
}
.mute-btn i {
- background-color: none;
- color: white;
- font-size: 20px;
+ background-color: none;
+ color: white;
+ font-size: 20px;
}
.recording-sign {
- height: 20px;
- width: auto;
- display: flex;
- flex-direction: row;
- position: absolute;
- top: 10px;
- right: 15px;
- align-items: center;
- justify-content: center;
-
- .timer {
- font-size: 15px;
- color: white;
- margin: 0;
- }
-
- .dot {
- height: 15px;
- width: 15px;
- margin: 5px;
- background-color: red;
- border-radius: 50%;
- display: inline-block;
- }
+ height: 20px;
+ width: auto;
+ display: flex;
+ flex-direction: row;
+ position: absolute;
+ top: 10px;
+ right: 15px;
+ align-items: center;
+ justify-content: center;
+
+ .timer {
+ font-size: 15px;
+ color: white;
+ margin: 0;
+ }
+
+ .dot {
+ height: 15px;
+ width: 15px;
+ margin: 5px;
+ background-color: red;
+ border-radius: 50%;
+ display: inline-block;
+ }
}
.controls-inner-container {
- display: flex;
- flex-direction: row;
- position: relative;
- width: 100%;
- align-items: center;
- justify-content: center;
+ display: flex;
+ flex-direction: row;
+ position: relative;
+ width: 100%;
+ align-items: center;
+ justify-content: center;
}
.record-button-wrapper {
- width: 35px;
- height: 35px;
- font-size: 0;
- background-color: grey;
- border: 0px;
- border-radius: 35px;
- margin: 10px;
- display: flex;
- justify-content: center;
-
- .record-button {
- background-color: red;
- border: 0px;
- border-radius: 50%;
- height: 80%;
- width: 80%;
- align-self: center;
- margin: 0;
-
- &:hover {
- height: 85%;
- width: 85%;
- }
- }
-
- .stop-button {
- background-color: red;
- border: 0px;
- border-radius: 10%;
- height: 70%;
- width: 70%;
- align-self: center;
- margin: 0;
-
-
- // &:hover {
- // width: 40px;
- // height: 40px
- // }
- }
-
+ width: 35px;
+ height: 35px;
+ font-size: 0;
+ background-color: grey;
+ border: 0px;
+ border-radius: 35px;
+ margin: 10px;
+ display: flex;
+ justify-content: center;
+
+ .record-button {
+ background-color: red;
+ border: 0px;
+ border-radius: 50%;
+ height: 80%;
+ width: 80%;
+ align-self: center;
+ margin: 0;
+
+ &:hover {
+ height: 85%;
+ width: 85%;
+ }
+ }
+
+ .stop-button {
+ background-color: red;
+ border: 0px;
+ border-radius: 10%;
+ height: 70%;
+ width: 70%;
+ align-self: center;
+ margin: 0;
+
+ // &:hover {
+ // width: 40px;
+ // height: 40px
+ // }
+ }
}
.options-wrapper {
- height: 100%;
- display: flex;
- flex-direction: row;
- align-content: center;
- position: relative;
- top: 0;
- bottom: 0;
-
- &.video-edit-wrapper {
-
- // right: 50% - 15;
-
- .track-screen {
- font-weight: 200;
- }
-
- }
-
- &.track-screen-wrapper {
-
- // right: 50% - 30;
-
- .track-screen {
- font-weight: 200;
- color: aqua;
- }
-
- }
-} \ No newline at end of file
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-content: center;
+ position: relative;
+ top: 0;
+ bottom: 0;
+
+ &.video-edit-wrapper {
+ // right: 50% - 15;
+
+ .track-screen {
+ font-weight: 200;
+ }
+ }
+
+ &.track-screen-wrapper {
+ // right: 50% - 30;
+
+ .track-screen {
+ font-weight: 200;
+ color: aqua;
+ }
+ }
+}
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index f7ed82643..b8451fe60 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -1,10 +1,13 @@
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* eslint-disable react/button-has-type */
+/* eslint-disable jsx-a11y/control-has-associated-label */
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { IconContext } from 'react-icons';
import { FaCheckCircle } from 'react-icons/fa';
import { MdBackspace } from 'react-icons/md';
import { Upload } from '../../../../server/SharedMediaTypes';
-import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils';
+import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils';
import { Networking } from '../../../Network';
import { Presentation, TrackMovements } from '../../../util/TrackMovements';
import { ProgressBar } from './ProgressBar';
@@ -19,19 +22,18 @@ export interface MediaSegment {
interface IRecordingViewProps {
setResult: (info: Upload.AccessPathInfo, presentation?: Presentation) => void;
- setDuration: (seconds: number) => void;
id: string;
getControls: (record: () => void, pause: () => void, finish: () => void) => void;
forceTrackScreen: boolean;
}
const MAXTIME = 100000;
+const iconVals = { color: '#cc1c08', className: 'video-edit-buttons' };
export function RecordingView(props: IRecordingViewProps) {
const [recording, setRecording] = useState(false);
const recordingTimerRef = useRef<number>(0);
const [recordingTimer, setRecordingTimer] = useState(0); // unit is 0.01 second
- const [playing, setPlaying] = useState(false);
const [progress, setProgress] = useState(0);
// acts as a "refresh state" to tell progressBar when to undo
@@ -62,7 +64,7 @@ export function RecordingView(props: IRecordingViewProps) {
useEffect(() => {
if (finished) {
// make the total presentation that'll match the concatted video
- let concatPres = (trackScreen || props.forceTrackScreen) && TrackMovements.Instance.concatPresentations(videos.map(v => v.presentation as Presentation));
+ const concatPres = (trackScreen || props.forceTrackScreen) && TrackMovements.Instance.concatPresentations(videos.map(v => v.presentation as Presentation));
// this async function uses the server to create the concatted video and then sets the result to it's accessPaths
(async () => {
@@ -100,16 +102,16 @@ export function RecordingView(props: IRecordingViewProps) {
return () => clearInterval(interval);
}, [recording]);
+ const setVideoProgressHelper = (curProgrss: number) => {
+ const newProgress = (curProgrss / MAXTIME) * 100;
+ setProgress(newProgress);
+ };
+
useEffect(() => {
setVideoProgressHelper(recordingTimer);
recordingTimerRef.current = recordingTimer;
}, [recordingTimer]);
- const setVideoProgressHelper = (progress: number) => {
- const newProgress = (progress / MAXTIME) * 100;
- setProgress(newProgress);
- };
-
const startShowingStream = async (mediaConstraints = DEFAULT_MEDIA_CONSTRAINTS) => {
const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
@@ -131,7 +133,7 @@ export function RecordingView(props: IRecordingViewProps) {
if (event.data.size > 0) videoChunks.push(event.data);
};
- videoRecorder.current.onstart = (event: any) => {
+ videoRecorder.current.onstart = () => {
setRecording(true);
// start the recording api when the video recorder starts
(trackScreen || props.forceTrackScreen) && TrackMovements.Instance.start();
@@ -149,7 +151,7 @@ export function RecordingView(props: IRecordingViewProps) {
// depending on if a presenation exists, add it to the video
const presentation = TrackMovements.Instance.yieldPresentation();
- setVideos(videos => [...videos, presentation != null && (trackScreen || props.forceTrackScreen) ? { ...nextVideo, presentation } : nextVideo]);
+ setVideos(theVideos => [...theVideos, presentation != null && (trackScreen || props.forceTrackScreen) ? { ...nextVideo, presentation } : nextVideo]);
}
// reset the temporary chunks
@@ -186,7 +188,7 @@ export function RecordingView(props: IRecordingViewProps) {
e,
returnTrue,
returnFalse,
- e => {
+ () => {
// start recording if not already recording
if (!videoRecorder.current || videoRecorder.current.state === 'inactive') record();
@@ -202,14 +204,8 @@ export function RecordingView(props: IRecordingViewProps) {
setDoUndo(prev => !prev);
};
- const handleOnTimeUpdate = () => {
- playing && setVideoProgressHelper(videoElementRef.current!.currentTime);
- };
-
const millisecondToMinuteSecond = (milliseconds: number) => {
- const toTwoDigit = (digit: number) => {
- return String(digit).length == 1 ? '0' + digit : digit;
- };
+ const toTwoDigit = (digit: number) => (String(digit).length === 1 ? '0' + digit : digit);
const minutes = Math.floor((milliseconds % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((milliseconds % (1000 * 60)) / 1000);
return toTwoDigit(minutes) + ' : ' + toTwoDigit(seconds);
@@ -219,10 +215,11 @@ export function RecordingView(props: IRecordingViewProps) {
props.getControls(record, pause, finish);
}, []);
+ const iconUndoVals = React.useMemo(() => ({ color: 'grey', className: 'video-edit-buttons', style: { display: canUndo ? 'inherit' : 'none' } }), []);
return (
<div className="recording-container">
<div className="video-wrapper">
- <video id={`video-${props.id}`} autoPlay muted onTimeUpdate={() => handleOnTimeUpdate()} ref={videoElementRef} />
+ <video id={`video-${props.id}`} autoPlay muted ref={videoElementRef} />
<div className="recording-sign">
<span className="dot" />
<p className="timer">{millisecondToMinuteSecond(recordingTimer * 10)}</p>
@@ -246,10 +243,10 @@ export function RecordingView(props: IRecordingViewProps) {
{!recording &&
(videos.length > 0 ? (
<div className="options-wrapper video-edit-wrapper">
- <IconContext.Provider value={{ color: 'grey', className: 'video-edit-buttons', style: { display: canUndo ? 'inherit' : 'none' } }}>
+ <IconContext.Provider value={iconUndoVals}>
<MdBackspace onPointerDown={undoPrevious} />
</IconContext.Provider>
- <IconContext.Provider value={{ color: '#cc1c08', className: 'video-edit-buttons' }}>
+ <IconContext.Provider value={iconVals}>
<FaCheckCircle
onPointerDown={e => {
e.stopPropagation();
@@ -268,7 +265,7 @@ export function RecordingView(props: IRecordingViewProps) {
setTrackScreen(e.target.checked);
}}
/>
- <span className="checkmark"></span>
+ <span className="checkmark" />
Track Screen
</label>
</div>
diff --git a/src/client/views/nodes/RecordingBox/index.ts b/src/client/views/nodes/RecordingBox/index.ts
index ff21eaed6..e4f9b5e55 100644
--- a/src/client/views/nodes/RecordingBox/index.ts
+++ b/src/client/views/nodes/RecordingBox/index.ts
@@ -1,2 +1,2 @@
-export * from './RecordingView'
-export * from './RecordingBox' \ No newline at end of file
+export * from './RecordingView';
+export * from './RecordingBox';
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 1e3933ac3..3be50f5e6 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -1,33 +1,37 @@
+/* eslint-disable jsx-a11y/media-has-caption */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as React from 'react';
// import { Canvas } from '@react-three/fiber';
import { computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
// import { BufferAttribute, Camera, Vector2, Vector3 } from 'three';
+import { returnFalse, returnOne, returnZero } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
import { DateField } from '../../../fields/DateField';
import { Doc } from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { ComputedField } from '../../../fields/ScriptField';
import { Cast, DocCast, NumCast } from '../../../fields/Types';
import { AudioField, VideoField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnFalse, returnOne, returnZero } from '../../../Utils';
-import { DocUtils } from '../../documents/Documents';
-import { DocumentType } from '../../documents/DocumentTypes';
import { Networking } from '../../Network';
+import { DocUtils } from '../../documents/DocUtils';
+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 { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
-import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline';
import { ContextMenu } from '../ContextMenu';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
-import { media_state } from './AudioBox';
+import { DocViewUtils } from '../DocViewUtils';
+import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline';
+import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
+import { mediaState } from './AudioBox';
import { FieldView, FieldViewProps } from './FieldView';
-import { FormattedTextBox } from './formattedText/FormattedTextBox';
import './ScreenshotBox.scss';
import { VideoBox } from './VideoBox';
-import { DocData } from '../../../fields/DocSymbols';
+import { FormattedTextBox } from './formattedText/FormattedTextBox';
declare class MediaRecorder {
constructor(e: any, options?: any); // whatever MediaRecorder has
@@ -158,11 +162,11 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
// });
}
componentWillUnmount() {
- const ind = DocUtils.ActiveRecordings.indexOf(this);
- ind !== -1 && DocUtils.ActiveRecordings.splice(ind, 1);
+ const ind = DocViewUtils.ActiveRecordings.indexOf(this);
+ ind !== -1 && DocViewUtils.ActiveRecordings.splice(ind, 1);
}
- specificContextMenu = (e: React.MouseEvent): void => {
+ specificContextMenu = (): void => {
const subitems = [{ description: 'Screen Capture', event: this.toggleRecording, icon: 'expand-arrows-alt' as any }];
ContextMenu.Instance.addItem({ description: 'Options...', subitems, icon: 'video' });
};
@@ -170,12 +174,12 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@computed get content() {
return (
<video
- className={'videoBox-content'}
+ className="videoBox-content"
key="video"
ref={r => {
this._videoRef = r;
setTimeout(() => {
- if (this.layoutDoc.mediaState === media_state.PendingRecording && this._videoRef) {
+ if (this.layoutDoc.mediaState === mediaState.PendingRecording && this._videoRef) {
this.toggleRecording();
}
}, 100);
@@ -183,7 +187,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
autoPlay={this._screenCapture}
style={{ width: this._screenCapture ? '100%' : undefined, height: this._screenCapture ? '100%' : undefined }}
onCanPlay={this.videoLoad}
- controls={true}
+ controls
onClick={e => e.preventDefault()}>
<source type="video/mp4" />
Not supported.
@@ -220,23 +224,23 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
toggleRecording = async () => {
if (!this._screenCapture) {
this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true }));
- const aud_chunks: any = [];
- this._audioRec.ondataavailable = (e: any) => aud_chunks.push(e.data);
- this._audioRec.onstop = async (e: any) => {
- const [{ result }] = await Networking.UploadFilesToServer(aud_chunks.map((file: any) => ({ file })));
+ const audChunks: any = [];
+ this._audioRec.ondataavailable = (e: any) => audChunks.push(e.data);
+ this._audioRec.onstop = async () => {
+ const [{ result }] = await Networking.UploadFilesToServer(audChunks.map((file: any) => ({ 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 vid_chunks: any = [];
+ const vidChunks: any = [];
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) => vid_chunks.push(e.data);
- this._videoRec.onstop = async (e: any) => {
+ this._videoRec.ondataavailable = (e: any) => vidChunks.push(e.data);
+ this._videoRec.onstop = async () => {
const presentation = TrackMovements.Instance.yieldPresentation();
if (presentation?.movements) {
const presCopy = { ...presentation };
@@ -244,7 +248,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this.dataDoc[this.fieldKey + '_presentation'] = JSON.stringify(presCopy);
}
TrackMovements.Instance.finish();
- const file = new File(vid_chunks, `${this.Document[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() });
+ const file = new File(vidChunks, `${this.Document[Id]}.mkv`, { type: vidChunks[0].type, lastModified: Date.now() });
const [{ result }] = await Networking.UploadFilesToServer({ file });
this.dataDoc[this.fieldKey + '_duration'] = (new Date().getTime() - this.recordingStart!) / 1000;
if (!(result instanceof Error)) {
@@ -262,7 +266,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this._screenCapture = true;
this.dataDoc.mediaState = 'recording';
});
- DocUtils.ActiveRecordings.push(this);
+ DocViewUtils.ActiveRecordings.push(this);
} else {
this._audioRec?.stop();
this._videoRec?.stop();
@@ -270,8 +274,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this._screenCapture = false;
this.dataDoc.mediaState = 'paused';
});
- const ind = DocUtils.ActiveRecordings.indexOf(this);
- ind !== -1 && DocUtils.ActiveRecordings.splice(ind, 1);
+ const ind = DocViewUtils.ActiveRecordings.indexOf(this);
+ ind !== -1 && DocViewUtils.ActiveRecordings.splice(ind, 1);
CaptureManager.Instance.open(this.Document);
}
@@ -297,6 +301,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<div className="videoBox-viewer">
<div style={{ position: 'relative', height: this.videoPanelHeight() }}>
<CollectionFreeFormView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setContentViewBox={emptyFunction}
NativeWidth={returnZero}
@@ -305,7 +310,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
PanelWidth={this._props.PanelWidth}
focus={this._props.focus}
isSelected={this._props.isSelected}
- isAnnotationOverlay={true}
+ isAnnotationOverlay
select={emptyFunction}
isContentActive={returnFalse}
NativeDimScaling={returnOne}
@@ -324,9 +329,10 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<div style={{ background: SettingsManager.userColor, position: 'relative', height: this.formattedPanelHeight() }}>
{!(this.dataDoc[this.fieldKey + '_dictation'] instanceof Doc) ? null : (
<FormattedTextBox
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
Document={DocCast(this.dataDoc[this.fieldKey + '_dictation'])}
- fieldKey={'text'}
+ fieldKey="text"
PanelHeight={this.formattedPanelHeight}
select={emptyFunction}
isContentActive={emptyFunction}
@@ -353,3 +359,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.SCREENSHOT, {
+ layout: { view: ScreenshotBox, dataField: 'data' },
+ options: { acl: '', _layout_nativeDimEditable: true, systemIcon: 'BsCameraFill' },
+});
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index d9d0dbe3e..bc19d7ad1 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -1,8 +1,9 @@
-let ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default;
+/* 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 { returnAlways, returnEmptyString } from '../../../Utils';
+import { returnAlways, returnEmptyString } from '../../../ClientUtils';
import { Doc } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
@@ -17,10 +18,14 @@ import { ContextMenu } from '../ContextMenu';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { EditableView } from '../EditableView';
import { OverlayView } from '../OverlayView';
-import { FieldView, FieldViewProps } from '../nodes/FieldView';
+import { FieldView, FieldViewProps } from './FieldView';
import { DocumentIconContainer } from './DocumentIcon';
import './ScriptingBox.scss';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
+
const _global = (window /* browser */ || global) /* node */ as any;
+const ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default;
@observer
export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@@ -79,26 +84,24 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@computed({ keepAlive: true }) get rawScript() {
return ScriptCast(this.dataDoc[this.fieldKey])?.script.originalScript ?? '';
}
- @computed({ keepAlive: true }) get functionName() {
- return StrCast(this.dataDoc[this.fieldKey + '-functionName'], '');
- }
- @computed({ keepAlive: true }) get functionDescription() {
- return StrCast(this.dataDoc[this.fieldKey + '-functionDescription'], '');
- }
- @computed({ keepAlive: true }) get compileParams() {
- return Cast(this.dataDoc[this.fieldKey + '-params'], listSpec('string'), []);
- }
-
set rawScript(value) {
this.dataDoc[this.fieldKey] = new ScriptField(undefined, undefined, value);
}
+ @computed({ keepAlive: true }) get functionName() {
+ return StrCast(this.dataDoc[this.fieldKey + '-functionName'], '');
+ }
set functionName(value) {
this.dataDoc[this.fieldKey + '-functionName'] = value;
}
+ @computed({ keepAlive: true }) get functionDescription() {
+ return StrCast(this.dataDoc[this.fieldKey + '-functionDescription'], '');
+ }
set functionDescription(value) {
this.dataDoc[this.fieldKey + '-functionDescription'] = value;
}
-
+ @computed({ keepAlive: true }) get compileParams() {
+ return Cast(this.dataDoc[this.fieldKey + '-params'], listSpec('string'), []);
+ }
set compileParams(value) {
this.dataDoc[this.fieldKey + '-params'] = new List<string>(value);
}
@@ -107,9 +110,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
if (typeof result === 'object') {
const text = descrip ? result[1] : result[2];
return text !== undefined ? text : '';
- } else {
- return '';
}
+ return '';
}
onClickScriptDisable = returnAlways;
@@ -118,19 +120,18 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
componentDidMount() {
this._props.setContentViewBox?.(this);
this.rawText = this.rawScript;
- const observer = new _global.ResizeObserver(
- action((entries: any) => {
+ const resizeObserver = new _global.ResizeObserver(
+ action(() => {
const area = document.querySelector('textarea');
if (area) {
- for (const {} of entries) {
- const getCaretCoordinates = require('textarea-caret');
- const caret = getCaretCoordinates(area, this._selection);
- this.resetSuggestionPos(caret);
- }
+ // eslint-disable-next-line global-require
+ const getCaretCoordinates = require('textarea-caret');
+ const caret = getCaretCoordinates(area, this._selection);
+ this.resetSuggestionPos(caret);
}
})
);
- observer.observe(document.getElementsByClassName('scriptingBox-outerDiv')[0]);
+ resizeObserver.observe(document.getElementsByClassName('scriptingBox-outerDiv')[0]);
}
@action
@@ -138,12 +139,12 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
if (!this._suggestionRef.current || !this._scriptTextRef.current) return;
const suggestionWidth = this._suggestionRef.current.offsetWidth;
const scriptWidth = this._scriptTextRef.current.offsetWidth;
- const top = caret.top;
- const x = this.dataDoc.x;
- let left = caret.left;
+ const { top } = caret;
+ const { x } = this.dataDoc;
+ let { left } = caret;
if (left + suggestionWidth > x + scriptWidth) {
const diff = left + suggestionWidth - (x + scriptWidth);
- left = left - diff;
+ left -= diff;
}
this._suggestionBoxX = left;
@@ -155,7 +156,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
}
protected createDashEventsTarget = (ele: HTMLDivElement, dropFunc: (e: Event, de: DragManager.DropEvent) => void) => {
- //used for stacking and masonry view
+ // used for stacking and masonry view
if (ele) {
this.dropDisposer?.();
this.dropDisposer = DragManager.MakeDropTarget(ele, dropFunc, this.layoutDoc);
@@ -164,7 +165,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
// only included in buttons, transforms scripting UI to a button
@action
- onFinish = () => (this.layoutDoc.layout_fieldKey = 'layout');
+ onFinish = () => {
+ this.layoutDoc.layout_fieldKey = 'layout';
+ };
// displays error message
@action
@@ -176,7 +179,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@action
onCompile = () => {
const params: ScriptParam = {};
- this.compileParams.forEach(p => (params[p.split(':')[0].trim()] = p.split(':')[1].trim()));
+ this.compileParams.forEach(p => {
+ params[p.split(':')[0].trim()] = p.split(':')[1].trim();
+ });
const result = !this.rawText.trim()
? ({ compiled: false, errors: undefined } as any)
@@ -196,7 +201,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
onRun = () => {
if (this.onCompile()) {
const bindings: { [name: string]: any } = {};
- this.paramsNames.forEach(key => (bindings[key] = this.dataDoc[key]));
+ this.paramsNames.forEach(key => {
+ bindings[key] = this.dataDoc[key];
+ });
// binds vars so user doesnt have to refer to everything as this.<var>
ScriptCast(this.dataDoc[this.fieldKey], null)?.script.run({ ...bindings, this: this.Document }, this.onError);
}
@@ -247,7 +254,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this.dataDoc.name = this.functionName;
this.dataDoc.description = this.functionDescription;
- //this.dataDoc.parameters = this.compileParams;
+ // this.dataDoc.parameters = this.compileParams;
this.dataDoc.script = this.rawScript;
ScriptManager.Instance.addScript(this.dataDoc);
@@ -255,6 +262,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this._scriptKeys = ScriptingGlobals.getGlobals();
this._scriptingDescriptions = ScriptingGlobals.getDescriptions();
this._scriptingParams = ScriptingGlobals.getParameters();
+ return undefined;
};
// overlays document numbers (ex. d32) over all documents when clicked on
@@ -267,7 +275,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@action
onDrop = (e: Event, de: DragManager.DropEvent, fieldKey: string) => {
if (de.complete.docDragData) {
- de.complete.docDragData.droppedDocuments.forEach(doc => (this.dataDoc[fieldKey] = doc));
+ de.complete.docDragData.droppedDocuments.forEach(doc => {
+ this.dataDoc[fieldKey] = doc;
+ });
e.stopPropagation();
return true;
}
@@ -285,8 +295,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
// sets field of the param name to the selected value in drop down box
@action
viewChanged = (e: React.ChangeEvent, name: string) => {
- //@ts-ignore
- const val = e.target.selectedOptions[0].value;
+ const val = (e.target as any).selectedOptions[0].value;
this.dataDoc[name] = val[0] === 'S' ? val.substring(1) : val[0] === 'N' ? parseInt(val.substring(1)) : val.substring(1) === 'true';
};
@@ -306,8 +315,26 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
};
renderFunctionInputs() {
- const descriptionInput = <textarea className="scriptingBox-textarea-inputs" onChange={e => (this.functionDescription = e.target.value)} placeholder="enter description here" value={this.functionDescription} />;
- const nameInput = <textarea className="scriptingBox-textarea-inputs" onChange={e => (this.functionName = e.target.value)} placeholder="enter name here" value={this.functionName} />;
+ const descriptionInput = (
+ <textarea
+ className="scriptingBox-textarea-inputs"
+ onChange={e => {
+ this.functionDescription = e.target.value;
+ }}
+ placeholder="enter description here"
+ value={this.functionDescription}
+ />
+ );
+ const nameInput = (
+ <textarea
+ className="scriptingBox-textarea-inputs"
+ onChange={e => {
+ this.functionName = e.target.value;
+ }}
+ placeholder="enter name here"
+ value={this.functionName}
+ />
+ );
return (
<div className="scriptingBox-inputDiv" onPointerDown={e => this._props.isSelected() && e.stopPropagation()}>
@@ -339,7 +366,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
return (
<div className="scriptingBox-paramInputs" onFocus={this.onFocus} onBlur={() => this._overlayDisposer?.()} ref={ele => ele && this.createDashEventsTarget(ele, (e, de) => this.onDrop(e, de, parameter))}>
<EditableView
- display={'block'}
+ display="block"
maxHeight={72}
height={35}
fontSize={14}
@@ -371,7 +398,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
return (
<div className="scriptingBox-paramInputs" style={{ overflowY: 'hidden' }}>
<EditableView
- display={'block'}
+ display="block"
maxHeight={72}
height={35}
fontSize={14}
@@ -404,6 +431,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
onChange={e => this.viewChanged(e, parameter)}
value={typeof this.dataDoc[parameter] === 'string' ? 'S' + StrCast(this.dataDoc[parameter]) : typeof this.dataDoc[parameter] === 'number' ? 'N' + NumCast(this.dataDoc[parameter]) : 'B' + BoolCast(this.dataDoc[parameter])}>
{types.map((type, i) => (
+ // eslint-disable-next-line react/no-array-index-key
<option key={i} className="scriptingBox-viewOption" value={(typeof type === 'string' ? 'S' : typeof type === 'number' ? 'N' : 'B') + type}>
{' '}
{type.toString()}{' '}
@@ -496,6 +524,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@action
suggestionPos = () => {
+ // eslint-disable-next-line global-require
const getCaretCoordinates = require('textarea-caret');
const This = this;
document.querySelector('textarea')?.addEventListener('input', function () {
@@ -509,7 +538,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
keyHandler(e: any, pos: number) {
e.stopPropagation();
if (this._lastChar === 'Enter') {
- this.rawText = this.rawText + ' ';
+ this.rawText += ' ';
}
if (e.key === '(') {
this.suggestionPos();
@@ -524,20 +553,18 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
}
} else if (e.key === ')') {
this._paramSuggestion = false;
- } else {
- if (e.key === 'Backspace') {
- if (this._lastChar === '(') {
- this._paramSuggestion = false;
- } else if (this._lastChar === ')') {
- if (this.rawText.slice(0, this.rawText.length - 1).split('(').length - 1 > this.rawText.slice(0, this.rawText.length - 1).split(')').length - 1) {
- if (this._scriptParamsText.length > 0) {
- this._paramSuggestion = true;
- }
+ } else if (e.key === 'Backspace') {
+ if (this._lastChar === '(') {
+ this._paramSuggestion = false;
+ } else if (this._lastChar === ')') {
+ if (this.rawText.slice(0, this.rawText.length - 1).split('(').length - 1 > this.rawText.slice(0, this.rawText.length - 1).split(')').length - 1) {
+ if (this._scriptParamsText.length > 0) {
+ this._paramSuggestion = true;
}
}
- } else if (this.rawText.split('(').length - 1 <= this.rawText.split(')').length - 1) {
- this._paramSuggestion = false;
}
+ } else if (this.rawText.split('(').length - 1 <= this.rawText.split(')').length - 1) {
+ this._paramSuggestion = false;
}
this._lastChar = e.key === 'Backspace' ? this.rawText[this.rawText.length - 2] : e.key;
@@ -559,9 +586,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
parameters.forEach((element: string, i: number) => {
if (i < numEntered - 1) {
- first = first + element;
+ first += element;
} else if (i > numEntered - 1) {
- last = last + element;
+ last += element;
}
});
@@ -598,16 +625,16 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
placeholder="write your script here"
onFocus={this.onFocus}
onBlur={() => this._overlayDisposer?.()}
- onChange={action((e: any) => (this.rawText = e.target.value))}
+ onChange={action((e: any) => {
+ this.rawText = e.target.value;
+ })}
value={this.rawText}
- movePopupAsYouType={true}
+ movePopupAsYouType
loadingComponent={() => <span>Loading</span>}
trigger={{
' ': {
dataProvider: (token: any) => this.handleToken(token),
- component: (blob: any) => {
- return this.renderFuncListElement(blob.entity);
- },
+ component: (blob: any) => this.renderFuncListElement(blob.entity),
output: (item: any, trigger: any) => {
this._spaced = true;
return trigger + item.trim();
@@ -615,9 +642,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
},
'.': {
dataProvider: (token: any) => this.handleToken(token),
- component: (blob: any) => {
- return this.renderFuncListElement(blob.entity);
- },
+ component: (blob: any) => this.renderFuncListElement(blob.entity),
output: (item: any, trigger: any) => {
this._spaced = true;
return trigger + item.trim();
@@ -653,16 +678,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
// params box on bottom
const parameterInput = (
<div className="scriptingBox-params">
- <EditableView
- display={'block'}
- maxHeight={72}
- height={35}
- fontSize={22}
- contents={''}
- GetValue={returnEmptyString}
- SetValue={value => (value && value !== ' ' ? this.compileParam(value) : false)}
- placeholder={'enter parameters here'}
- />
+ <EditableView display="block" maxHeight={72} height={35} fontSize={22} contents="" GetValue={returnEmptyString} SetValue={value => (value && value !== ' ' ? this.compileParam(value) : false)} placeholder="enter parameters here" />
</div>
);
@@ -670,13 +686,14 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
const definedParameters = !this.compileParams.length ? null : (
<div className="scriptingBox-plist" style={{ width: '30%' }}>
{this.compileParams.map((parameter, i) => (
- <div key={i} className="scriptingBox-pborder" onKeyPress={e => e.key === 'Enter' && this._overlayDisposer?.()}>
+ // eslint-disable-next-line react/no-array-index-key
+ <div key={i} className="scriptingBox-pborder" onKeyDown={e => e.key === 'Enter' && this._overlayDisposer?.()}>
<EditableView
- display={'block'}
+ display="block"
maxHeight={72}
height={35}
fontSize={12}
- background-color={'beige'}
+ background-color="beige"
contents={parameter}
GetValue={() => parameter}
SetValue={value => (value && value !== ' ' ? this.compileParam(value, i) : this.onDelete(i))}
@@ -749,7 +766,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
{!this.compileParams.length || !this.paramsNames ? null : (
<div className="scriptingBox-plist">
{this.paramsNames.map((parameter: string, i: number) => (
- <div key={i} className="scriptingBox-pborder" onKeyPress={e => e.key === 'Enter' && this._overlayDisposer?.()}>
+ // eslint-disable-next-line react/no-array-index-key
+ <div key={i} className="scriptingBox-pborder" onKeyDown={e => e.key === 'Enter' && this._overlayDisposer?.()}>
<div className="scriptingBox-wrapper" style={{ maxHeight: '40px' }}>
<div className="scriptingBox-paramNames"> {`${parameter}:${this.paramsTypes[i]} = `} </div>
{this.paramsTypes[i] === 'boolean' ? this.renderEnum(parameter, [true, false]) : null}
@@ -829,3 +847,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.SCRIPTING, {
+ layout: { view: ScriptingBox, dataField: 'data' },
+ options: { acl: '', systemIcon: 'BsFileEarmarkCodeFill' },
+});
diff --git a/src/client/views/nodes/SliderBox-components.tsx b/src/client/views/nodes/SliderBox-components.tsx
index e19f28f08..04efaac8e 100644
--- a/src/client/views/nodes/SliderBox-components.tsx
+++ b/src/client/views/nodes/SliderBox-components.tsx
@@ -1,6 +1,6 @@
-import * as React from "react";
-import { SliderItem } from "react-compound-slider";
-import "./SliderBox-tooltip.css";
+import * as React from 'react';
+import { SliderItem } from 'react-compound-slider';
+import './SliderBox-tooltip.css';
const { Component, Fragment } = React;
@@ -8,24 +8,24 @@ const { Component, Fragment } = React;
// TOOLTIP RAIL
// *******************************************************
const railStyle: React.CSSProperties = {
- position: "absolute",
- width: "100%",
+ position: 'absolute',
+ width: '100%',
height: 40,
borderRadius: 7,
- cursor: "pointer",
+ cursor: 'pointer',
opacity: 0.3,
zIndex: 300,
- border: "1px solid grey"
+ border: '1px solid grey',
};
const railCenterStyle: React.CSSProperties = {
- position: "absolute",
- width: "100%",
+ position: 'absolute',
+ width: '100%',
height: 14,
borderRadius: 7,
- cursor: "pointer",
- pointerEvents: "none",
- backgroundColor: "rgb(155,155,155)"
+ cursor: 'pointer',
+ pointerEvents: 'none',
+ backgroundColor: 'rgb(155,155,155)',
};
interface TooltipRailProps {
@@ -37,21 +37,21 @@ interface TooltipRailProps {
export class TooltipRail extends Component<TooltipRailProps> {
state = {
value: null,
- percent: null
+ percent: null,
};
static defaultProps = {
- disabled: false
+ disabled: false,
};
onMouseEnter = () => {
- document.addEventListener("mousemove", this.onMouseMove);
- }
+ document.addEventListener('mousemove', this.onMouseMove);
+ };
onMouseLeave = () => {
this.setState({ value: null, percent: null });
- document.removeEventListener("mousemove", this.onMouseMove);
- }
+ document.removeEventListener('mousemove', this.onMouseMove);
+ };
onMouseMove = (e: Event) => {
const { activeHandleID, getEventData } = this.props;
@@ -61,7 +61,7 @@ export class TooltipRail extends Component<TooltipRailProps> {
} else {
this.setState(getEventData(e));
}
- }
+ };
render() {
const { value, percent } = this.state;
@@ -73,11 +73,10 @@ export class TooltipRail extends Component<TooltipRailProps> {
<div
style={{
left: `${percent}%`,
- position: "absolute",
- marginLeft: "-11px",
- marginTop: "-35px"
- }}
- >
+ position: 'absolute',
+ marginLeft: '-11px',
+ marginTop: '-35px',
+ }}>
<div className="tooltip">
<span className="tooltiptext">Value: {value}</span>
</div>
@@ -87,7 +86,7 @@ export class TooltipRail extends Component<TooltipRailProps> {
style={railStyle}
{...getRailProps({
onMouseEnter: this.onMouseEnter,
- onMouseLeave: this.onMouseLeave
+ onMouseLeave: this.onMouseLeave,
})}
/>
<div style={railCenterStyle} />
@@ -102,28 +101,28 @@ export class TooltipRail extends Component<TooltipRailProps> {
interface HandleProps {
key: string;
handle: SliderItem;
- isActive: Boolean;
- disabled?: Boolean;
+ isActive: boolean;
+ disabled?: boolean;
domain: number[];
getHandleProps: (id: string, config: object) => object;
}
export class Handle extends Component<HandleProps> {
static defaultProps = {
- disabled: false
+ disabled: false,
};
state = {
- mouseOver: false
+ mouseOver: false,
};
onMouseEnter = () => {
this.setState({ mouseOver: true });
- }
+ };
onMouseLeave = () => {
this.setState({ mouseOver: false });
- }
+ };
render() {
const {
@@ -131,7 +130,7 @@ export class Handle extends Component<HandleProps> {
handle: { id, value, percent },
isActive,
disabled,
- getHandleProps
+ getHandleProps,
} = this.props;
const { mouseOver } = this.state;
@@ -141,11 +140,10 @@ export class Handle extends Component<HandleProps> {
<div
style={{
left: `${percent}%`,
- position: "absolute",
- marginLeft: "-11px",
- marginTop: "-35px"
- }}
- >
+ position: 'absolute',
+ marginLeft: '-11px',
+ marginTop: '-35px',
+ }}>
<div className="tooltip">
<span className="tooltiptext">Value: {value}</span>
</div>
@@ -158,21 +156,21 @@ export class Handle extends Component<HandleProps> {
aria-valuenow={value}
style={{
left: `${percent}%`,
- position: "absolute",
- marginLeft: "-11px",
- marginTop: "-6px",
+ position: 'absolute',
+ marginLeft: '-11px',
+ marginTop: '-6px',
zIndex: 400,
width: 24,
height: 24,
- cursor: "pointer",
+ cursor: 'pointer',
border: 0,
- borderRadius: "50%",
- boxShadow: "1px 1px 1px 1px rgba(0, 0, 0, 0.4)",
- backgroundColor: disabled ? "#666" : "#3e1db3"
+ borderRadius: '50%',
+ boxShadow: '1px 1px 1px 1px rgba(0, 0, 0, 0.4)',
+ backgroundColor: disabled ? '#666' : '#3e1db3',
}}
{...getHandleProps(id, {
onMouseEnter: this.onMouseEnter,
- onMouseLeave: this.onMouseLeave
+ onMouseLeave: this.onMouseLeave,
})}
/>
</Fragment>
@@ -186,27 +184,22 @@ export class Handle extends Component<HandleProps> {
interface TrackProps {
source: SliderItem;
target: SliderItem;
- disabled: Boolean;
+ disabled: boolean;
getTrackProps: () => object;
}
-export function Track({
- source,
- target,
- getTrackProps,
- disabled = false
-}: TrackProps) {
+export function Track({ source, target, getTrackProps, disabled = false }: TrackProps) {
return (
<div
style={{
- position: "absolute",
+ position: 'absolute',
height: 14,
zIndex: 1,
- backgroundColor: disabled ? "#999" : "#3e1db3",
+ backgroundColor: disabled ? '#999' : '#3e1db3',
borderRadius: 7,
- cursor: "pointer",
+ cursor: 'pointer',
left: `${source.percent}%`,
- width: `${target.percent - source.percent}%`
+ width: `${target.percent - source.percent}%`,
}}
{...getTrackProps()}
/>
@@ -222,32 +215,31 @@ interface TickProps {
format: (val: number) => string;
}
-const defaultFormat = (d: number) => `d`;
+const defaultFormat = () => `d`;
export function Tick({ tick, count, format = defaultFormat }: TickProps) {
return (
<div>
<div
style={{
- position: "absolute",
+ position: 'absolute',
marginTop: 20,
width: 1,
height: 5,
- backgroundColor: "rgb(200,200,200)",
- left: `${tick.percent}%`
+ backgroundColor: 'rgb(200,200,200)',
+ left: `${tick.percent}%`,
}}
/>
<div
style={{
- position: "absolute",
+ position: 'absolute',
marginTop: 25,
fontSize: 10,
- textAlign: "center",
+ textAlign: 'center',
marginLeft: `${-(100 / count) / 2}%`,
width: `${100 / count}%`,
- left: `${tick.percent}%`
- }}
- >
+ left: `${tick.percent}%`,
+ }}>
{format(tick.value)}
</div>
</div>
diff --git a/src/client/views/nodes/TaskCompletedBox.tsx b/src/client/views/nodes/TaskCompletedBox.tsx
index c9e15d314..6f11cd73a 100644
--- a/src/client/views/nodes/TaskCompletedBox.tsx
+++ b/src/client/views/nodes/TaskCompletedBox.tsx
@@ -5,7 +5,7 @@ import * as React from 'react';
import './TaskCompletedBox.scss';
@observer
-export class TaskCompletionBox extends React.Component<{}> {
+export class TaskCompletionBox extends React.Component {
@observable public static taskCompleted: boolean = false;
@observable public static popupX: number = 500;
@observable public static popupY: number = 150;
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index b2ae7201c..fe7600fa3 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -1,37 +1,37 @@
+/* eslint-disable jsx-a11y/media-has-caption */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { basename } from 'path';
import * as React from 'react';
+import { ClientUtils, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents } from '../../../ClientUtils';
import { Doc, Opt, StrListCast } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
-import { Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, NumCast, StrCast, toList } from '../../../fields/Types';
import { AudioField, ImageField, VideoField } from '../../../fields/URLField';
-import { emptyFunction, formatTime, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { emptyFunction, formatTime } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
-import { DocumentManager } from '../../util/DocumentManager';
-import { FollowLinkScript } from '../../util/LinkFollower';
-import { LinkManager } from '../../util/LinkManager';
-import { ReplayMovements } from '../../util/ReplayMovements';
+import { DocUtils, FollowLinkScript } from '../../documents/DocUtils';
+import { dropActionType } from '../../util/DropActionTypes';
import { undoBatch } from '../../util/UndoManager';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { CollectionStackedTimeline, TrimScope } from '../collections/CollectionStackedTimeline';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { VideoThumbnails } from '../global/globalEnums';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
import { AnchorMenu } from '../pdf/AnchorMenu';
-import { StyleProp } from '../StyleProvider';
+import { PinDocView, PinProps } from '../PinFuncs';
+import { StyleProp } from '../StyleProp';
import { DocumentView } from './DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView';
-import { RecordingBox } from './RecordingBox';
-import { PinProps, PresBox } from './trails';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import './VideoBox.scss';
-import { dropActionType } from '../../util/DragManager';
/**
* VideoBox
@@ -46,12 +46,11 @@ import { dropActionType } from '../../util/DragManager';
*/
@observer
-export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(VideoBox, fieldKey);
}
static heightPercent = 80; // height of video relative to videoBox when timeline is open
- static numThumbnails = 20;
private unmounting = false;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _videoRef: HTMLVideoElement | null = null; // <video> ref
@@ -62,6 +61,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
private _playRegionTimer: any = null; // timeout for playback
private _controlsFadeTimer: any = null; // timeout for controls fade
+ private _ffref = React.createRef<CollectionFreeFormView>();
constructor(props: FieldViewProps) {
super(props);
@@ -84,7 +84,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
@observable _scrubbing: boolean = false;
@computed get links() {
- return LinkManager.Links(this.dataDoc);
+ return Doc.Links(this.dataDoc);
}
@computed get heightPercent() {
return NumCast(this.layoutDoc._layout_timelineHeightPercent, 100);
@@ -99,18 +99,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
return field?.url.href ?? vfield?.url.href ?? '';
}
- // returns the presentation data if it exists, null otherwise
- @computed get presentation() {
- const data = this.dataDoc[this.fieldKey + '_presentation'];
- return data ? JSON.parse(StrCast(data)) : null;
- }
-
@computed private get timeline() {
return this._stackedTimeline;
}
private get transition() {
return this._clicking ? 'left 0.5s, width 0.5s, height 0.5s' : '';
} // css transition for hiding/showing timeline
+
public get player(): HTMLVideoElement | null {
return this._videoRef;
}
@@ -120,10 +115,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
this._props.setContentViewBox?.(this); // this tells the DocumentView that this VideoBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the VideoBox when making a link.
this.player && this.setPlayheadTime(this.timeline?.clipStart || 0);
document.addEventListener('keydown', this.keyEvents, true);
-
- if (this.presentation) {
- ReplayMovements.Instance.setVideoBox(this);
- }
}
componentWillUnmount() {
@@ -132,12 +123,14 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
this.Pause();
Object.keys(this._disposers).forEach(d => this._disposers[d]?.());
document.removeEventListener('keydown', this.keyEvents, true);
-
- if (this.presentation) {
- ReplayMovements.Instance.removeVideoBox();
- }
}
+ override PlayerTime = () => this.player?.currentTime;
+ override Pause = (update: boolean = true) => {
+ this.pause(update);
+ !this._keepCurrentlyPlaying && this.removeCurrentlyPlaying();
+ };
+
// handles key events, when timeline scrubs fade controls
@action
keyEvents = (e: KeyboardEvent) => {
@@ -152,11 +145,14 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
clearTimeout(this._controlsFadeTimer);
this._scrubbing = true;
this._controlsFadeTimer = setTimeout(
- action(() => (this._scrubbing = false)),
+ action(() => {
+ this._scrubbing = false;
+ }),
500
);
e.stopPropagation();
break;
+ default:
}
}
};
@@ -203,7 +199,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
else {
this._keepCurrentlyPlaying = true;
this.pause();
- setTimeout(() => (this._keepCurrentlyPlaying = false));
+ setTimeout(() => {
+ this._keepCurrentlyPlaying = false;
+ });
}
};
@@ -223,10 +221,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
}
this._playRegionTimer = undefined;
};
- @action Pause = (update: boolean = true) => {
- this.pause(update);
- !this._keepCurrentlyPlaying && this.removeCurrentlyPlaying();
- };
// toggles video full screen
@action public FullScreen = () => {
@@ -246,7 +240,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
clearTimeout(this._controlsFadeTimer);
this._controlsVisible = true;
this._controlsFadeTimer = setTimeout(
- action(() => (this._controlsVisible = false)),
+ action(() => {
+ this._controlsVisible = false;
+ }),
3000
);
}
@@ -262,7 +258,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
setupMoveUpEvents(
e.target,
e,
- action((e, down, delta) => {
+ action((moveEv, down, delta) => {
if (this._controlsTransform) {
this._controlsTransform.X = Math.max(0, Math.min(delta[0] + this._controlsTransform.X, window.innerWidth));
this._controlsTransform.Y = Math.max(0, Math.min(delta[1] + this._controlsTransform.Y, window.innerHeight));
@@ -280,7 +276,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
const canvas = document.createElement('canvas');
canvas.width = 640;
canvas.height = (640 * Doc.NativeHeight(this.layoutDoc)) / (Doc.NativeWidth(this.layoutDoc) || 1);
- const ctx = canvas.getContext('2d'); //draw image to canvas. scale to target dimensions
+ const ctx = canvas.getContext('2d'); // draw image to canvas. scale to target dimensions
if (ctx) {
this._videoRef && ctx.drawImage(this._videoRef, 0, 0, canvas.width, canvas.height);
}
@@ -297,13 +293,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
this._props.addDocument?.(b);
DocUtils.MakeLink(b, this.Document, { link_relationship: 'video snapshot' });
} else {
- //convert to desired file format
+ // convert to desired file format
const dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
// if you want to preview the captured image,
- const retitled = StrCast(this.Document.title).replace(/[ -\.:]/g, '');
- const encodedFilename = encodeURIComponent(('snapshot' + retitled + '_' + (this.layoutDoc._layout_currentTimecode || 0).toString()).replace(/[\.\/\?\=]/g, '_'));
+ const retitled = StrCast(this.Document.title).replace(/[ -.:]/g, '');
+ const encodedFilename = encodeURIComponent(('snapshot' + retitled + '_' + (this.layoutDoc._layout_currentTimecode || 0).toString()).replace(/[./?=]/g, '_'));
const filename = basename(encodedFilename);
- Utils.convertDataUri(dataUrl, filename).then((returnedFilename: string) => returnedFilename && (cb ?? this.createSnapshotLink)(returnedFilename, downX, downY));
+ ClientUtils.convertDataUri(dataUrl, filename).then((returnedFilename: string) => returnedFilename && (cb ?? this.createSnapshotLink)(returnedFilename, downX, downY));
}
};
@@ -318,7 +314,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
// creates link for snapshot
createSnapshotLink = (imagePath: string, downX?: number, downY?: number) => {
- const url = !imagePath.startsWith('/') ? Utils.CorsProxy(imagePath) : imagePath;
+ const url = !imagePath.startsWith('/') ? ClientUtils.CorsProxy(imagePath) : imagePath;
const width = NumCast(this.layoutDoc._width) || 1;
const height = NumCast(this.layoutDoc._height);
const imageSnapshot = Docs.Create.ImageDocument(url, {
@@ -334,19 +330,20 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
Doc.SetNativeWidth(imageSnapshot[DocData], Doc.NativeWidth(this.layoutDoc));
Doc.SetNativeHeight(imageSnapshot[DocData], Doc.NativeHeight(this.layoutDoc));
this._props.addDocument?.(imageSnapshot);
- const link = DocUtils.MakeLink(imageSnapshot, this.getAnchor(true), { link_relationship: 'video snapshot' });
- link && (DocCast(link.link_anchor_2)[DocData].timecodeToHide = NumCast(DocCast(link.link_anchor_2).timecodeToShow) + 3);
- setTimeout(() => downX !== undefined && downY !== undefined && DocumentManager.Instance.getFirstDocumentView(imageSnapshot)?.startDragging(downX, downY, dropActionType.move, true));
+ DocUtils.MakeLink(imageSnapshot, this.getAnchor(true), { link_relationship: 'video snapshot' });
+ // link && (DocCast(link.link_anchor_2)[DocData].timecodeToHide = NumCast(DocCast(link.link_anchor_2).timecodeToShow) + 3); // do we need to set an end time? should default to +0.1
+ setTimeout(() => downX !== undefined && downY !== undefined && DocumentView.getFirstDocumentView(imageSnapshot)?.startDragging(downX, downY, dropActionType.move, true));
};
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
const timecode = Cast(this.layoutDoc._layout_currentTimecode, 'number', null);
const marquee = AnchorMenu.Instance.GetAnchor?.(undefined, addAsAnnotation);
if (!addAsAnnotation && marquee) marquee.backgroundColor = 'transparent';
- const anchor = addAsAnnotation
- ? CollectionStackedTimeline.createAnchor(this.Document, this.dataDoc, this.annotationKey, timecode ? timecode : undefined, undefined, marquee, addAsAnnotation) || this.Document
- : Docs.Create.ConfigDocument({ title: '#' + timecode, _timecodeToShow: timecode, annotationOn: this.Document });
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), temporal: true } }, this.Document);
+ const anchor =
+ addAsAnnotation && marquee
+ ? CollectionStackedTimeline.createAnchor(this.Document, this.dataDoc, this.annotationKey, timecode || undefined, undefined, marquee, addAsAnnotation) || this.Document
+ : Docs.Create.ConfigDocument({ title: '#' + timecode, _timecodeToShow: timecode, annotationOn: this.Document });
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), temporal: true, pannable: true } }, this.Document);
return anchor;
};
@@ -373,12 +370,15 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
getView = (doc: Doc, options: FocusViewOptions) => {
if (this._stackedTimeline?.makeDocUnfiltered(doc)) {
if (this.heightPercent === 100) {
- this.layoutDoc._layout_timelineHeightPercent = VideoBox.heightPercent;
+ // do we want to always open up the timeline when followin a link? kind of clunky visually
+ // this.layoutDoc._layout_timelineHeightPercent = VideoBox.heightPercent;
options.didMove = true;
}
return this._stackedTimeline.getView(doc, options);
}
- return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
+ return new Promise<Opt<DocumentView>>(res => {
+ DocumentView.addViewRenderedCb(doc, dv => res(dv));
+ });
};
// extracts video thumbnails and saves them as field of doc
@@ -388,21 +388,25 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
const thumbnailPromises: Promise<any>[] = [];
const video = document.createElement('video');
- video.onloadedmetadata = () => (video.currentTime = 0);
+ video.onloadedmetadata = () => {
+ video.currentTime = 0;
+ };
video.onseeked = () => {
const canvas = document.createElement('canvas');
canvas.height = 100;
canvas.width = 100;
canvas.getContext('2d')?.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, 100, 100);
- const retitled = StrCast(this.Document.title).replace(/[ -\.:]/g, '');
+ const retitled = StrCast(this.Document.title).replace(/[ -.:]/g, '');
const encodedFilename = encodeURIComponent('thumbnail' + retitled + '_' + video.currentTime.toString().replace(/\./, '_'));
- thumbnailPromises?.push(Utils.convertDataUri(canvas.toDataURL(), basename(encodedFilename), true));
- const newTime = video.currentTime + video.duration / (VideoBox.numThumbnails - 1);
+ thumbnailPromises?.push(ClientUtils.convertDataUri(canvas.toDataURL(), basename(encodedFilename), true));
+ const newTime = video.currentTime + video.duration / (VideoThumbnails.DENSE - 1);
if (newTime < video.duration) {
video.currentTime = newTime;
} else {
- Promise.all(thumbnailPromises).then(thumbnails => (this.dataDoc[this.fieldKey + '_thumbnails'] = new List<string>(thumbnails)));
+ Promise.all(thumbnailPromises).then(thumbnails => {
+ this.dataDoc[this.fieldKey + '_thumbnails'] = new List<string>(thumbnails);
+ });
}
};
@@ -421,11 +425,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
this._disposers.reactionDisposer?.();
this._disposers.reactionDisposer = reaction(
() => NumCast(this.layoutDoc._layout_currentTimecode),
- time => !this._playing && (vref.currentTime = time),
+ time => {
+ !this._playing && (vref.currentTime = time);
+ },
{ fireImmediately: true }
);
- (!this.dataDoc[this.fieldKey + '_thumbnails'] || StrListCast(this.dataDoc[this.fieldKey + '_thumbnails']).length != VideoBox.numThumbnails) && this.getVideoThumbnails();
+ (!this.dataDoc[this.fieldKey + '_thumbnails'] || StrListCast(this.dataDoc[this.fieldKey + '_thumbnails']).length !== VideoThumbnails.DENSE) && this.getVideoThumbnails();
}
};
@@ -434,7 +440,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
setContentRef = (cref: HTMLDivElement | null) => {
this._contentRef = cref;
if (cref) {
- cref.onfullscreenchange = action(e => {
+ cref.onfullscreenchange = action(() => {
this._fullScreen = document.fullscreenElement === cref;
this._controlsVisible = true;
this._scrubbing = false;
@@ -449,7 +455,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
};
// context menu
- specificContextMenu = (e: React.MouseEvent): void => {
+ specificContextMenu = (): void => {
const field = Cast(this.dataDoc[this._props.fieldKey], VideoField);
if (field) {
const url = field.url.href;
@@ -460,34 +466,50 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
subitems.push({
description: 'Screen Capture',
event: async () => {
- runInAction(() => (this._screenCapture = !this._screenCapture));
+ runInAction(() => {
+ this._screenCapture = !this._screenCapture;
+ });
this._videoRef!.srcObject = !this._screenCapture ? undefined : await (navigator.mediaDevices as any).getDisplayMedia({ video: true });
},
icon: 'expand-arrows-alt',
});
- subitems.push({ description: (this.layoutDoc.dontAutoFollowLinks ? '' : "Don't") + ' follow links when encountered', event: () => (this.layoutDoc.dontAutoFollowLinks = !this.layoutDoc.dontAutoFollowLinks), icon: 'expand-arrows-alt' });
+ subitems.push({
+ description: (this.layoutDoc.dontAutoFollowLinks ? '' : "Don't") + ' follow links when encountered',
+ event: () => {
+ this.layoutDoc.dontAutoFollowLinks = !this.layoutDoc.dontAutoFollowLinks;
+ },
+ icon: 'expand-arrows-alt',
+ });
subitems.push({
description: (this.layoutDoc.dontAutoPlayFollowedLinks ? '' : "Don't") + ' play when link is selected',
- event: () => (this.layoutDoc.dontAutoPlayFollowedLinks = !this.layoutDoc.dontAutoPlayFollowedLinks),
+ event: () => {
+ this.layoutDoc.dontAutoPlayFollowedLinks = !this.layoutDoc.dontAutoPlayFollowedLinks;
+ },
+ icon: 'expand-arrows-alt',
+ });
+ subitems.push({
+ description: (this.layoutDoc.autoPlayAnchors ? "Don't auto play" : 'Auto play') + ' anchors onClick',
+ event: () => {
+ this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors;
+ },
icon: 'expand-arrows-alt',
});
- subitems.push({ description: (this.layoutDoc.autoPlayAnchors ? "Don't auto play" : 'Auto play') + ' anchors onClick', event: () => (this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors), icon: 'expand-arrows-alt' });
// subitems.push({ description: "Start Trim All", event: () => this.startTrim(TrimScope.All), icon: "expand-arrows-alt" });
// subitems.push({ description: "Start Trim Clip", event: () => this.startTrim(TrimScope.Clip), icon: "expand-arrows-alt" });
// subitems.push({ description: "Stop Trim", event: () => this.finishTrim(), icon: "expand-arrows-alt" });
subitems.push({
description: 'Copy path',
event: () => {
- Utils.CopyText(url);
+ ClientUtils.CopyText(url);
},
icon: 'expand-arrows-alt',
});
// if the videobox was turned from a recording box
- if (this.dataDoc[this.fieldKey + '_recorded'] === true) {
+ if (this.dataDoc[this.fieldKey + '_recorded']) {
subitems.push({
description: 'Recreate recording',
event: () => {
- this.dataDoc.layout = RecordingBox.LayoutString(this.fieldKey);
+ this.dataDoc.layout = StrCast(this.dataDoc[this.fieldKey + '_recorded']); // restore the saed recording layout
// delete assoicated video data
this.dataDoc[this._props.fieldKey] = '';
this.dataDoc[this.fieldKey + '_duration'] = '';
@@ -502,7 +524,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
};
// ref for updating time
- setAudioRef = (e: HTMLAudioElement | null) => (this._audioPlayer = e);
+ setAudioRef = (e: HTMLAudioElement | null) => {
+ this._audioPlayer = e;
+ };
// renders the video and audio
@computed get content() {
@@ -568,8 +592,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
setupMoveUpEvents(
this,
e,
- e => {
- this.Snapshot(e.clientX, e.clientY);
+ moveEv => {
+ this.Snapshot(moveEv.clientX, moveEv.clientY);
return true;
},
emptyFunction,
@@ -584,7 +608,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
setupMoveUpEvents(
this,
e,
- action(encodeURIComponent => {
+ action(() => {
this._clicking = false;
if (this._props.isContentActive()) {
// const local = this.ScreenToLocalTransform().scale(this._props.scaling?.() || 1).transformPoint(e.clientX, e.clientY);
@@ -598,7 +622,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
() => {
this.layoutDoc._layout_timelineHeightPercent = this.heightPercent !== 100 ? 100 : VideoBox.heightPercent;
setTimeout(
- action(() => (this._clicking = false)),
+ action(() => {
+ this._clicking = false;
+ }),
500
);
},
@@ -611,30 +637,32 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
@action
removeCurrentlyPlaying = () => {
const docView = this.DocumentView?.();
- if (CollectionStackedTimeline.CurrentlyPlaying && docView) {
- const index = CollectionStackedTimeline.CurrentlyPlaying.indexOf(docView);
- index !== -1 && CollectionStackedTimeline.CurrentlyPlaying.splice(index, 1);
+ if (DocumentView.CurrentlyPlaying && docView) {
+ const index = DocumentView.CurrentlyPlaying.indexOf(docView);
+ index !== -1 && DocumentView.CurrentlyPlaying.splice(index, 1);
}
};
// adds doc to currently playing display
@action
addCurrentlyPlaying = () => {
const docView = this.DocumentView?.();
- if (!CollectionStackedTimeline.CurrentlyPlaying) {
- CollectionStackedTimeline.CurrentlyPlaying = [];
+ if (!DocumentView.CurrentlyPlaying) {
+ DocumentView.CurrentlyPlaying = [];
}
- if (docView && CollectionStackedTimeline.CurrentlyPlaying.indexOf(docView) === -1) {
- CollectionStackedTimeline.CurrentlyPlaying.push(docView);
+ if (docView && DocumentView.CurrentlyPlaying.indexOf(docView) === -1) {
+ DocumentView.CurrentlyPlaying.push(docView);
}
};
// for annotating, adds doc with time info
@action.bound
- addDocWithTimecode(doc: Doc | Doc[]): boolean {
- const docs = doc instanceof Doc ? [doc] : doc;
+ addDocWithTimecode(docIn: Doc | Doc[]): boolean {
+ const docs = toList(docIn);
const curTime = NumCast(this.layoutDoc._layout_currentTimecode);
- docs.forEach(doc => (doc._timecodeToHide = (doc._timecodeToShow = curTime) + 1));
- return this.addDocument(doc);
+ docs.forEach(doc => {
+ doc._timecodeToHide = (doc._timecodeToShow = curTime) + 1;
+ });
+ return this.addDocument(docs);
}
// play back the audio from seekTimeInSeconds, fullPlay tells whether clip is being played to end vs link range
@@ -642,7 +670,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
playFrom = (seekTimeInSeconds: number, endTime?: number, fullPlay: boolean = false) => {
clearTimeout(this._playRegionTimer);
this._playRegionTimer = undefined;
- if (Number.isNaN(this.player?.duration)) {
+ if (this.player?.duration === undefined || isNaN(this.player.duration)) {
setTimeout(() => this.playFrom(seekTimeInSeconds, endTime), 500);
} else if (this.player) {
// trimBounds override requested playback bounds
@@ -694,7 +722,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
e,
returnFalse,
returnFalse,
- action((e: PointerEvent, doubleTap?: boolean) => {
+ action((clickEv: PointerEvent, doubleTap?: boolean) => {
if (doubleTap) {
this.startTrim(TrimScope.All);
} else if (this.timeline) {
@@ -729,11 +757,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
// stretches vertically or horizontally depending on video orientation so video fits full screen
fullScreenSize() {
if (this._videoRef && this._videoRef.videoHeight / this._videoRef.videoWidth > 1) {
- //prettier-ignore
- return ({ height: '100%' });
+ return { height: '100%' };
}
- //prettier-ignore
- return ({ width: '100%' });
+ return ({ width: '100%' }); // prettier-ignore
}
// for zoom slider, sets timeline waveform zoom
@@ -755,9 +781,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
setupMoveUpEvents(
this,
e,
- action(e => {
+ action(moveEv => {
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
- this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]);
+ this._marqueeref.current?.onInitiateSelection([moveEv.clientX, moveEv.clientY]);
return true;
}),
returnFalse,
@@ -775,7 +801,10 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
this._props.select(true);
};
- timelineWhenChildContentsActiveChanged = action((isActive: boolean) => this._props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive)));
+ timelineWhenChildContentsActiveChanged = action((isActive: boolean) => {
+ this._isAnyChildContentActive = isActive;
+ this._props.whenChildContentsActiveChanged(isActive);
+ });
timelineScreenToLocal = () =>
this._props
@@ -783,7 +812,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
.scale(this.scaling())
.translate(0, (-this.heightPercent / 100) * this._props.PanelHeight());
- setPlayheadTime = (time: number) => (this.player!.currentTime = this.layoutDoc._layout_currentTimecode = time);
+ setPlayheadTime = (time: number) => {
+ this.player!.currentTime = this.layoutDoc._layout_currentTimecode = time;
+ };
timelineHeight = () => (this._props.PanelHeight() * (100 - this.heightPercent)) / 100;
@@ -804,7 +835,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
marqueeOffset = () => [((this.panelWidth() / 2) * (1 - this.heightPercent / 100)) / (this.heightPercent / 100), 0];
- timelineDocFilter = () => [`_isTimelineLabel:true,${Utils.noRecursionHack}:x`];
+ timelineDocFilter = () => [`_isTimelineLabel:true,${ClientUtils.noRecursionHack}:x`];
// renders video controls
componentUI = (boundsLeft: number, boundsTop: number) => {
@@ -846,7 +877,10 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
return (
<div className="videoBox-stackPanel" style={{ transition: this.transition, height: `${100 - this.heightPercent}%`, display: this.heightPercent === 100 ? 'none' : '' }}>
<CollectionStackedTimeline
- ref={action((r: any) => (this._stackedTimeline = r))}
+ ref={action((r: any) => {
+ this._stackedTimeline = r;
+ })}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
dataFieldKey={this.fieldKey}
fieldKey={this.annotationKey}
@@ -884,7 +918,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
}
crop = (region: Doc | undefined, addCrop?: boolean) => {
- if (!region) return;
+ if (!region) return undefined;
const cropping = Doc.MakeCopy(region, true);
const regionData = region[DocData];
regionData.backgroundColor = 'transparent';
@@ -913,8 +947,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
croppingProto.type = DocumentType.VID;
croppingProto.layout = VideoBox.LayoutString('data');
croppingProto.data = ObjectField.MakeCopy(this.dataDoc[this.fieldKey] as ObjectField);
- croppingProto['data_nativeWidth'] = anchw;
- croppingProto['data_nativeHeight'] = anchh;
+ croppingProto.data_nativeWidth = anchw;
+ croppingProto.data_nativeHeight = anchh;
croppingProto.videoCrop = true;
croppingProto.layout_currentTimecode = this.layoutDoc._layout_currentTimecode;
croppingProto.freeform_scale = viewScale;
@@ -931,6 +965,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
this._props.bringToFront?.(cropping);
return cropping;
};
+ 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);
@@ -956,14 +991,16 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
left: (this._props.PanelWidth() - this.panelWidth()) / 2,
}}>
<CollectionFreeFormView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
+ ref={this._ffref}
setContentViewBox={emptyFunction}
NativeWidth={returnZero}
NativeHeight={returnZero}
renderDepth={this._props.renderDepth + 1}
fieldKey={this.annotationKey}
- isAnnotationOverlay={true}
- annotationLayerHostsContent={true}
+ isAnnotationOverlay
+ annotationLayerHostsContent
PanelWidth={this._props.PanelWidth}
PanelHeight={this._props.PanelHeight}
isAnyChildContentActive={returnFalse}
@@ -1047,12 +1084,12 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
</div>
)}
- <div className="videobox-button" title={'full screen'} onPointerDown={this.onFullDown}>
+ <div className="videobox-button" title="full screen" onPointerDown={this.onFullDown}>
<FontAwesomeIcon icon="expand" />
</div>
{!this._fullScreen && width > 300 && (
- <div className="videobox-button" title={'show timeline'} onPointerDown={this.onTimelineHdlDown}>
+ <div className="videobox-button" title="show timeline" onPointerDown={this.onTimelineHdlDown}>
<FontAwesomeIcon icon="eye" />
</div>
)}
@@ -1111,3 +1148,12 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.VID, {
+ layout: { view: VideoBox, dataField: 'data' },
+ options: { acl: '', _layout_currentTimecode: 0, systemIcon: 'BsFileEarmarkPlayFill' },
+});
+Docs.Prototypes.TemplateMap.set(DocumentType.REC, {
+ layout: { view: VideoBox, dataField: 'data' },
+ options: { acl: '', _height: 100, backgroundColor: 'pink', systemIcon: 'BsFillMicFill' },
+});
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index c9340edc0..8835ea5e7 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,22 +1,26 @@
+/* eslint-disable jsx-a11y/control-has-associated-label */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { htmlToText } from 'html-to-text';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import * as WebRequest from 'web-request';
-import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivHeight, getWordAtPoint, lightOrDark, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll } from '../../../ClientUtils';
+import { Doc, DocListCast, Field, FieldType, Opt } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { HtmlField } from '../../../fields/HtmlField';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { RefField } from '../../../fields/RefField';
import { listSpec } from '../../../fields/Schema';
-import { Cast, NumCast, StrCast, WebCast } from '../../../fields/Types';
+import { Cast, NumCast, StrCast, toList, WebCast } from '../../../fields/Types';
import { ImageField, WebField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, emptyFunction, getWordAtPoint, lightOrDark, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll, stringHash, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
+import { emptyFunction, stringHash } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
+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';
@@ -24,24 +28,27 @@ import { MarqueeOptionsMenu } from '../collections/collectionFreeForm';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { Colors } from '../global/globalEnums';
-import { LightboxView } from '../LightboxView';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
import { AnchorMenu } from '../pdf/AnchorMenu';
import { Annotation } from '../pdf/Annotation';
import { GPTPopup } from '../pdf/GPTPopup/GPTPopup';
+import { PinDocView, PinProps } from '../PinFuncs';
import { SidebarAnnos } from '../SidebarAnnos';
-import { StyleProp } from '../StyleProvider';
-import { DocumentView, OpenWhere } from './DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView';
+import { StyleProp } from '../StyleProp';
+import { ViewBoxInterface } from '../ViewBoxInterface';
+import { DocumentView } from './DocumentView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import { LinkInfo } from './LinkDocPreview';
-import { PinProps, PresBox } from './trails';
+import { OpenWhere } from './OpenWhere';
import './WebBox.scss';
+
const { CreateImage } = require('./WebBoxRenderer');
-const _global = (window /* browser */ || global) /* node */ as any;
+
@observer
-export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(WebBox, fieldKey);
}
@@ -105,7 +112,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
@action
- search = (searchString: string, bwd?: boolean, clear: boolean = false) => {
+ override search = (searchString: string, bwd?: boolean, clear: boolean = false) => {
if (!this._searching && !clear) {
this._searching = true;
setTimeout(() => {
@@ -141,19 +148,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const scrollTop = NumCast(this.layoutDoc._layout_scrollTop);
const nativeWidth = NumCast(this.layoutDoc.nativeWidth);
const nativeHeight = (nativeWidth * this._props.PanelHeight()) / this._props.PanelWidth();
- var htmlString = this._iframe.contentDocument && new XMLSerializer().serializeToString(this._iframe.contentDocument);
+ let htmlString = this._iframe.contentDocument && new XMLSerializer().serializeToString(this._iframe.contentDocument);
if (!htmlString) {
- htmlString = await (await fetch(Utils.CorsProxy(this.webField!.href))).text();
+ htmlString = await (await fetch(ClientUtils.CorsProxy(this.webField!.href))).text();
}
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((data_url: any) => {
- if (data_url.includes('<!DOCTYPE')) {
+ .then((dataUrl: any) => {
+ if (dataUrl.includes('<!DOCTYPE')) {
console.log('BAD DATA IN THUMB CREATION');
return;
}
- Utils.convertDataUri(data_url, this.layoutDoc[Id] + '-icon' + new Date().getTime(), true, this.layoutDoc[Id] + '-icon').then(returnedfilename =>
+ ClientUtils.convertDataUri(dataUrl, this.layoutDoc[Id] + '-icon' + new Date().getTime(), true, this.layoutDoc[Id] + '-icon').then(returnedfilename =>
setTimeout(
action(() => {
this.Document.thumbLockout = false;
@@ -166,7 +173,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
)
);
})
- .catch(function (error: any) {
+ .catch((error: any) => {
console.error('oops, something went wrong!', error);
});
};
@@ -179,15 +186,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
// bcz: need to make sure that doc.data_annotations points to the currently active web page's annotations (this could/should be when the doc is created)
if (this._url) {
const reqdFuncs: { [key: string]: string } = {};
- reqdFuncs[this.fieldKey + '_annotations'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"annotations"])`;
- reqdFuncs[this.fieldKey + '_annotations-setter'] = `this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"annotations"] = value`;
- reqdFuncs[this.fieldKey + '_sidebar'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"sidebar"])`;
+ reqdFuncs[this.fieldKey + '_annotations'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_annotations"])`;
+ reqdFuncs[this.fieldKey + '_annotations-setter'] = `this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_annotations"] = value`;
+ reqdFuncs[this.fieldKey + '_sidebar'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_sidebar"])`;
DocUtils.AssignScripts(this.dataDoc, {}, reqdFuncs);
}
});
this._disposers.urlchange = reaction(
() => WebCast(this.dataDoc.data),
- url => this.submitURL(false, false)
+ () => this.submitURL(false, false)
);
this._disposers.titling = reaction(
() => StrCast(this.Document.title),
@@ -199,8 +206,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this._disposers.layout_autoHeight = reaction(
() => this.layoutDoc._layout_autoHeight,
- layout_autoHeight => {
- if (layout_autoHeight) {
+ layoutAutoHeight => {
+ if (layoutAutoHeight) {
this.layoutDoc._nativeHeight = NumCast(this.Document[this._props.fieldKey + '_nativeHeight']);
this._props.setHeight?.(NumCast(this.Document[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1));
}
@@ -219,8 +226,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
} // else it's an HTMLfield
} else if (this.webField && !this.dataDoc.text) {
- WebRequest.get(Utils.CorsProxy(this.webField.href)) //
- .then(result => result && (this.dataDoc.text = htmlToText(result.content)));
+ WebRequest.get(ClientUtils.CorsProxy(this.webField.href)) //
+ .then(result => {
+ result && (this.dataDoc.text = htmlToText(result.content));
+ });
}
this._disposers.scrollReaction = reaction(
@@ -254,7 +263,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
const rect = clientRects.item(i);
- const mainrect = this._url ? { translateX: 0, translateY: 0, scale: 1 } : Utils.GetScreenTransform(this._mainCont.current);
+ const mainrect = this._url ? { translateX: 0, translateY: 0, scale: 1 } : ClientUtils.GetScreenTransform(this._mainCont.current);
if (rect && rect.width !== this._mainCont.current.clientWidth) {
const annoBox = document.createElement('div');
annoBox.className = 'marqueeAnnotator-annotationBox';
@@ -283,27 +292,39 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
focus = (anchor: Doc, options: FocusViewOptions) => {
if (anchor !== this.Document && this._outerRef.current) {
const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(NumCast(anchor.y), NumCast(anchor._height), NumCast(this.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(anchor.y) + NumCast(anchor._height), this._scrollHeight));
+ const scrollTo = ClientUtils.scrollIntoView(
+ NumCast(anchor.y),
+ NumCast(anchor._height),
+ NumCast(this.layoutDoc._layout_scrollTop),
+ windowHeight,
+ windowHeight * 0.1,
+ Math.max(NumCast(anchor.y) + NumCast(anchor._height), this._scrollHeight)
+ );
if (scrollTo !== undefined) {
if (this._initialScroll === undefined) {
const focusTime = options.zoomTime ?? 500;
this.goTo(scrollTo, focusTime, options.easeFunc);
return focusTime;
- } else {
- this._initialScroll = scrollTo;
}
+ this._initialScroll = scrollTo;
}
}
+ return undefined;
};
@action
- getView = (doc: Doc, options: FocusViewOptions) => {
- if (Doc.AreProtosEqual(doc, this.Document)) return new Promise<Opt<DocumentView>>(res => res(this.DocumentView?.()));
+ getView = (doc: Doc /* , options: FocusViewOptions */) => {
+ if (Doc.AreProtosEqual(doc, this.Document))
+ return new Promise<Opt<DocumentView>>(res => {
+ res(this.DocumentView?.());
+ });
if (this.Document.layout_fieldKey === 'layout_icon') this.DocumentView?.().iconify();
const webUrl = WebCast(doc.config_data)?.url;
if (this._url && webUrl && webUrl.href !== this._url) this.setData(webUrl.href);
if (this._sidebarRef?.current?.makeDocUnfiltered(doc) && !this.SidebarShown) this.toggleSidebar(false);
- return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
+ return new Promise<Opt<DocumentView>>(res => {
+ DocumentView.addViewRenderedCb(doc, dv => res(dv));
+ });
};
sidebarAddDocTab = (doc: Doc, where: OpenWhere) => {
@@ -314,14 +335,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
return this._props.addDocTab(doc, where);
};
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
- let ele: Opt<HTMLDivElement> = undefined;
+ let ele: Opt<HTMLDivElement>;
try {
const contents = this._iframe?.contentWindow?.getSelection()?.getRangeAt(0).cloneContents();
if (contents) {
ele = document.createElement('div');
ele.append(contents);
}
- } catch (e) {}
+ } catch (e) {
+ /* empty */
+ }
const visibleAnchor = this._getAnchor(this._savedAnnotations, true);
const anchor =
visibleAnchor ??
@@ -330,7 +353,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
y: NumCast(this.layoutDoc._layout_scrollTop),
annotationOn: this.Document,
});
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: pinProps?.pinData ? true : false, pannable: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: !!pinProps?.pinData, pannable: true } }, this.Document);
anchor.text = ele?.textContent ?? '';
anchor.text_html = ele?.innerHTML ?? this._selectionText;
addAsAnnotation && this.addDocumentWrapper(anchor);
@@ -341,12 +364,22 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
savedAnnotationsCreator: () => ObservableMap<number, HTMLDivElement[]> = () => this._textAnnotationCreator?.() || this._savedAnnotations;
@action
+ iframeMove = (e: PointerEvent) => {
+ const theclick = this.props
+ .ScreenToLocalTransform()
+ .inverse()
+ .transformPoint(e.clientX, e.clientY - NumCast(this.layoutDoc.layout_scrollTop));
+ this._marqueeref.current?.onMove(theclick);
+ };
+ @action
iframeUp = (e: PointerEvent) => {
+ this._iframe?.contentDocument?.removeEventListener('pointermove', this.iframeMove);
+ this.marqueeing = undefined;
this._getAnchor = AnchorMenu.Instance?.GetAnchor; // need to save AnchorMenu's getAnchor since a subsequent selection on another doc will overwrite this value
this._textAnnotationCreator = undefined;
this.DocumentView?.()?.cleanupPointerEvents(); // pointerup events aren't generated on containing document view, so we have to invoke it here.
if (this._iframe?.contentWindow && this._iframe.contentDocument && !this._iframe.contentWindow.getSelection()?.isCollapsed) {
- const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!);
+ const mainContBounds = ClientUtils.GetScreenTransform(this._mainCont.current!);
const scale = (this._props.NativeDimScaling?.() || 1) * mainContBounds.scale;
const sel = this._iframe.contentWindow.getSelection();
if (sel) {
@@ -358,6 +391,29 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
GPTPopup.Instance.setSidebarId(`${this._props.fieldKey}_${this._urlHash ? this._urlHash + '_' : ''}sidebar`);
GPTPopup.Instance.addDoc = this.sidebarAddDocument;
}
+ } else {
+ const theclick = this.props
+ .ScreenToLocalTransform()
+ .inverse()
+ .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]);
+ this._getAnchor = AnchorMenu.Instance?.GetAnchor;
+ this.marqueeing = undefined;
+ }
+
+ ContextMenu.Instance.closeMenu();
+ ContextMenu.Instance.setIgnoreEvents(false);
+ if (e?.button === 2 || e?.altKey) {
+ e?.preventDefault();
+ e?.stopPropagation();
+ setTimeout(() => {
+ // if menu comes up right away, the down event can still be active causing a menu item to be selected
+ this.specificContextMenu();
+ this.DocumentView?.().onContextMenu(undefined, theclick[0], theclick[1]);
+ });
+ }
}
};
@action
@@ -400,6 +456,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
};
@action
iframeDown = (e: PointerEvent) => {
+ this._textAnnotationCreator = undefined;
+ const sel = this._url ? this._iframe?.contentDocument?.getSelection() : window.document.getSelection();
+ if (sel?.empty)
+ sel.empty(); // Chrome
+ else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
+
this._props.select(false);
const theclick = this.props
.ScreenToLocalTransform()
@@ -409,6 +471,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
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) {
this.marqueeing = theclick;
+ this._marqueeref.current?.onInitiateSelection(this.marqueeing);
+ this._iframe?.contentDocument?.addEventListener('pointermove', this.iframeMove);
e.preventDefault();
}
};
@@ -421,6 +485,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const sheets = document.head.appendChild(style);
return (sheets as any).sheet;
}
+ return undefined;
}
addWebStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') {
const propText =
@@ -435,7 +500,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
_iframetimeout: any = undefined;
@observable _warning = 0;
@action
- iframeLoaded = (e: any) => {
+ iframeLoaded = () => {
const iframe = this._iframe;
if (this._initialScroll !== undefined) {
this.setScrollPos(this._initialScroll);
@@ -450,7 +515,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
runInAction(() => this._warning++);
href = undefined;
}
- let requrlraw = decodeURIComponent(href?.replace(Utils.prepend('') + '/corsProxy/', '') ?? this._url.toString());
+ let requrlraw = decodeURIComponent(href?.replace(ClientUtils.prepend('') + '/corsProxy/', '') ?? this._url.toString());
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);
@@ -503,16 +568,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
'click',
undoBatch(
action((e: MouseEvent) => {
- let href = '';
+ let eleHref = '';
for (let ele = e.target as any; ele; ele = ele.parentElement) {
- href = (typeof ele.href === 'string' ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || href;
+ eleHref = (typeof ele.href === 'string' ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || eleHref;
}
const origin = this.webField?.origin;
- if (href && origin) {
+ if (eleHref && origin) {
const batch = UndoManager.StartBatch('webclick');
e.stopPropagation();
setTimeout(() => {
- this.setData(href.replace(Utils.prepend(''), origin));
+ this.setData(eleHref.replace(ClientUtils.prepend(''), origin));
batch.end();
});
if (this._outerRef.current) {
@@ -558,7 +623,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
clearStyleSheetRules(WebBox.webStyleSheet);
this._scrollTimer = undefined;
const newScrollTop = scrollTop > iframeHeight ? iframeHeight : scrollTop;
- if (!LinkInfo.Instance?.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()))) {
+ if (!LinkInfo.Instance?.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.()))) {
this.layoutDoc.thumb = undefined;
this.layoutDoc.thumbScrollTop = undefined;
this.layoutDoc.thumbNativeWidth = undefined;
@@ -591,12 +656,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this._scrollHeight = 0;
if (this._webUrl === this._url) {
this._webUrl = curUrl;
- setTimeout(action(() => (this._webUrl = this._url)));
+ setTimeout(
+ action(() => {
+ this._webUrl = this._url;
+ })
+ );
} else {
this._webUrl = this._url;
}
return true;
}
+ return undefined;
});
return false;
};
@@ -614,12 +684,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this._scrollHeight = 0;
if (this._webUrl === this._url) {
this._webUrl = curUrl;
- setTimeout(action(() => (this._webUrl = this._url)));
+ setTimeout(
+ action(() => {
+ this._webUrl = this._url;
+ })
+ );
} else {
this._webUrl = this._url;
}
return true;
}
+ return undefined;
});
return false;
};
@@ -651,13 +726,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const html = dataTransfer.getData('text/html');
const uri = dataTransfer.getData('text/uri-list');
const url = uri || html || this._url || '';
- const newurl = url.startsWith(window.location.origin) ? url.replace(window.location.origin, this._url?.match(/http[s]?:\/\/[^\/]*/)?.[0] || '') : url;
+ const newurl = url.startsWith(window.location.origin) ? url.replace(window.location.origin, this._url?.match(/http[s]?:\/\/[^/]*/)?.[0] || '') : url;
this.setData(newurl);
e.stopPropagation();
};
@action
- setData = (data: Field | Promise<RefField | undefined>) => {
+ setData = (data: FieldType | Promise<RefField | undefined>) => {
if (!(typeof data === 'string') && !(data instanceof WebField)) return false;
if (Field.toString(data) === this._url) return false;
this._scrollHeight = 0;
@@ -674,19 +749,31 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
e.stopPropagation();
};
- specificContextMenu = (e: React.MouseEvent | PointerEvent): void => {
+ specificContextMenu = (): void => {
const cm = ContextMenu.Instance;
const funcs: ContextMenuProps[] = [];
if (!cm.findByDescription('Options...')) {
!Doc.noviceMode &&
- funcs.push({ description: (this.layoutDoc[this.fieldKey + '_useCors'] ? "Don't Use" : 'Use') + ' Cors', event: () => (this.layoutDoc[this.fieldKey + '_useCors'] = !this.layoutDoc[this.fieldKey + '_useCors']), icon: 'snowflake' });
+ funcs.push({
+ description: (this.layoutDoc[this.fieldKey + '_useCors'] ? "Don't Use" : 'Use') + ' Cors',
+ event: () => {
+ this.layoutDoc[this.fieldKey + '_useCors'] = !this.layoutDoc[this.fieldKey + '_useCors'];
+ },
+ icon: 'snowflake',
+ });
funcs.push({
description: (this.dataDoc[this.fieldKey + '_allowScripts'] ? 'Prevent' : 'Allow') + ' Scripts',
event: () => {
this.dataDoc[this.fieldKey + '_allowScripts'] = !this.dataDoc[this.fieldKey + '_allowScripts'];
if (this._iframe) {
- runInAction(() => (this._hackHide = true));
- setTimeout(action(() => (this._hackHide = false)));
+ runInAction(() => {
+ this._hackHide = true;
+ });
+ setTimeout(
+ action(() => {
+ this._hackHide = false;
+ })
+ );
}
},
icon: 'snowflake',
@@ -724,7 +811,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
setupMoveUpEvents(
this,
e,
- action(e => {
+ action(() => {
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
return true;
}),
@@ -739,34 +826,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this.marqueeing = undefined;
}
};
- @action finishMarquee = (x?: number, y?: number, e?: PointerEvent) => {
+ @action finishMarquee = (x?: number, y?: number) => {
this._getAnchor = AnchorMenu.Instance?.GetAnchor;
this.marqueeing = undefined;
- this._textAnnotationCreator = undefined;
- const sel = this._url ? this._iframe?.contentDocument?.getSelection() : window.document.getSelection();
- if (sel?.empty)
- sel.empty(); // Chrome
- else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
this._setPreviewCursor?.(x ?? 0, y ?? 0, false, !this._marqueeref.current?.isEmpty, this.Document);
- if (x !== undefined && y !== undefined) {
- ContextMenu.Instance.closeMenu();
- ContextMenu.Instance.setIgnoreEvents(false);
- if (e?.button === 2 || e?.altKey) {
- e?.preventDefault();
- e?.stopPropagation();
- setTimeout(() => {
- // if menu comes up right away, the down event can still be active causing a menu item to be selected
- this.specificContextMenu(undefined as any);
- this.DocumentView?.().onContextMenu(undefined, x, y);
- });
- }
- }
};
@observable lighttext = false;
@computed get urlContent() {
- if (this.ScreenToLocalBoxXf().Scale > 25) return <div></div>;
+ if (this.ScreenToLocalBoxXf().Scale > 25) return <div />;
setTimeout(
action(() => {
if (this._initialScroll === undefined && !this._webPageHasBeenRendered) {
@@ -788,19 +857,23 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
})}
contentEditable
onPointerDown={this.webClipDown}
+ // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: field.html }}
/>
);
}
if (field instanceof WebField) {
- const url = this.layoutDoc[this.fieldKey + '_useCors'] ? Utils.CorsProxy(this._webUrl) : this._webUrl;
+ const url = this.layoutDoc[this.fieldKey + '_useCors'] ? ClientUtils.CorsProxy(this._webUrl) : this._webUrl;
const scripts = this.dataDoc[this.fieldKey + '_allowScripts'] || this._webUrl.includes('wikipedia.org') || this._webUrl.includes('google.com') || this._webUrl.startsWith('https://bing');
- //if (!scripts) console.log('No scripts for: ' + url);
+ // if (!scripts) console.log('No scripts for: ' + url);
return (
<iframe
+ title="web iframe"
key={this._warning}
className="webBox-iframe"
- ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))}
+ ref={action((r: HTMLIFrameElement | null) => {
+ this._iframe = r;
+ })}
style={{ pointerEvents: SnappingManager.IsResizing ? 'none' : undefined }}
src={url}
onLoad={this.iframeLoaded}
@@ -811,12 +884,24 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
/>
);
}
- return <iframe className="webBox-iframe" ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))} src={'https://crossorigin.me/https://cs.brown.edu'} />;
+ return (
+ <iframe
+ title="web frame"
+ className="webBox-iframe"
+ ref={action((r: HTMLIFrameElement | null) => {
+ this._iframe = r;
+ })}
+ src="https://crossorigin.me/https://cs.brown.edu"
+ />
+ );
}
- addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => {
- this._url && (doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.config_data = new WebField(this._url)));
- return this.addDocument(doc, annotationKey);
+ addDocumentWrapper = (docs: Doc | Doc[], annotationKey?: string) => {
+ this._url &&
+ toList(docs).forEach(doc => {
+ doc.config_data = new WebField(this._url);
+ });
+ return this.addDocument(docs, annotationKey);
};
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
@@ -830,7 +915,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
setupMoveUpEvents(
this,
e,
- action((e, down, delta) => {
+ action((moveEv, down, delta) => {
this._draggingSidebar = true;
const localDelta = this._props
.ScreenToLocalTransform()
@@ -848,7 +933,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
return false;
}),
- action((e, movement, isClick) => {
+ action((upEv, movement, isClick) => {
this._draggingSidebar = false;
!isClick && batch.end();
}),
@@ -869,14 +954,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={e => this.sidebarBtnDown(e, true)}>
- <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" />
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon="comment-alt" size="sm" />
</div>
);
}
@observable _previewNativeWidth: Opt<number> = undefined;
@observable _previewWidth: Opt<number> = undefined;
toggleSidebar = action((preview: boolean = false) => {
- var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
+ let nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
if (!nativeWidth) {
const defaultNativeWidth = NumCast(this.Document.nativeWidth, this.dataDoc[this.fieldKey] instanceof WebField ? 850 : NumCast(this.Document._width));
Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || defaultNativeWidth);
@@ -915,7 +1000,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
};
_innerCollectionView: CollectionFreeFormView | undefined;
zoomScaling = () => this._innerCollectionView?.zoomScaling() ?? 1;
- setInnerContent = (component: ViewBoxInterface) => (this._innerCollectionView = component as CollectionFreeFormView);
+ setInnerContent = (component: ViewBoxInterface<any>) => {
+ this._innerCollectionView = component as CollectionFreeFormView;
+ };
@computed get content() {
const interactive = this._props.isContentActive() && this._props.pointerEvents?.() !== 'none' && Doc.ActiveTool === InkTool.None;
@@ -946,24 +1033,25 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
{this.inlineTextAnnotations
.sort((a, b) => NumCast(a.y) - NumCast(b.y))
.map(anno => (
- <Annotation {...this._props} fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} dataDoc={this.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ <Annotation {...this._props} fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} containerDataDoc={this.dataDoc} annoDoc={anno} key={`${anno[Id]}-annotation`} />
))}
</div>
);
}
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false;
+ return !!(this._showSidebar || this.layoutDoc._layout_showSidebar);
}
renderAnnotations = (childFilters: () => string[]) => (
<CollectionFreeFormView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setContentViewBox={this.setInnerContent}
NativeWidth={returnZero}
NativeHeight={returnZero}
- originTopLeft={false}
- isAnnotationOverlayScrollable={true}
+ isAnnotationOverlayScrollable
renderDepth={this._props.renderDepth + 1}
- isAnnotationOverlay={true}
+ isAnnotationOverlay
fieldKey={this.annotationKey}
setPreviewCursor={this.setPreviewCursor}
PanelWidth={this.panelWidth}
@@ -992,6 +1080,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
childPointerEvents = () => (this._props.isContentActive() ? 'all' : undefined);
@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 scale = previewScale * (this._props.NativeDimScaling?.() || 1);
@@ -1005,7 +1094,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}}
// when active, block wheel events from propagating since they're handled by the iframe
onWheel={this.onZoomWheel}
- onScroll={e => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0)}
+ onScroll={() => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0)}
onPointerDown={this.onMarqueeDown}>
<div className="webBox-innerContent" style={{ height: (this._webPageHasBeenRendered && this._scrollHeight > this._props.PanelHeight() && this._scrollHeight) || '100%', pointerEvents }}>
{this.content}
@@ -1021,7 +1110,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
return (
<div className="webBox-ui" onPointerDown={e => e.stopPropagation()} style={{ display: this._props.isContentActive() ? 'flex' : 'none' }}>
<div className="webBox-overlayCont" onPointerDown={e => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
- <button className="webBox-overlayButton" title={'search'} />
+ <button type="button" className="webBox-overlayButton" title="search" />
<input
className="webBox-searchBar"
placeholder="Search"
@@ -1032,13 +1121,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
e.stopPropagation();
}}
/>
- <button className="webBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}>
+ <button type="button" className="webBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}>
<FontAwesomeIcon icon="search" size="sm" />
</button>
</div>
<button
+ type="button"
className="webBox-overlayButton"
- title={'search'}
+ title="search"
onClick={action(() => {
this._searching = !this._searching;
this.search('', false, true);
@@ -1051,14 +1141,18 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
</div>
);
}
- searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => (this._searchString = e.currentTarget.value);
- setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => (this._setPreviewCursor = func);
+ searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this._searchString = e.currentTarget.value;
+ };
+ setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => {
+ this._setPreviewCursor = func;
+ };
panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth() + WebBox.sidebarResizerWidth;
panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
scrollXf = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop));
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
- transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter];
- opaqueFilter = () => [...this._props.childFilters(), Utils.noDragDocsFilter, ...(SnappingManager.CanEmbed ? [] : [Utils.OpaqueBackgroundFilter])];
+ transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter];
+ opaqueFilter = () => [...this._props.childFilters(), ClientUtils.noDragDocsFilter, ...(SnappingManager.CanEmbed ? [] : [ClientUtils.OpaqueBackgroundFilter])];
childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
if (doc instanceof Doc && property === StyleProp.PointerEvents) {
if (this.inlineTextAnnotations.includes(doc)) return 'none';
@@ -1071,6 +1165,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
: 'none';
annotationPointerEvents = () => (this._props.isContentActive() && (SnappingManager.IsDragging || Doc.ActiveTool !== InkTool.None) ? 'all' : 'none');
render() {
+ TraceMobx();
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as any);
const scale = previewScale * (this._props.NativeDimScaling?.() || 1);
@@ -1124,6 +1219,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
<div style={{ position: 'absolute', height: '100%', right: 0, top: 0, width: `calc(100 * ${this.sidebarWidth() / this._props.PanelWidth()}%` }}>
<SidebarAnnos
ref={this._sidebarRef}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
fieldKey={this.fieldKey + '_' + this._urlHash}
@@ -1144,6 +1240,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
);
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function urlHash(url: string) {
return stringHash(url);
});
+
+Docs.Prototypes.TemplateMap.set(DocumentType.WEB, {
+ layout: { view: WebBox, dataField: 'data' },
+ options: { acl: '', _height: 300, _layout_fitWidth: true, _layout_nativeDimEditable: true, _layout_reflowVertical: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' },
+});
diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js
index 914adb404..6fb8f4957 100644
--- a/src/client/views/nodes/WebBoxRenderer.js
+++ b/src/client/views/nodes/WebBoxRenderer.js
@@ -1,3 +1,4 @@
+/* eslint-disable no-undef */
/**
*
* @param {StyleSheetList} styleSheets
@@ -9,15 +10,14 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @param {String} binStr
*/
- const binaryStringToBase64 = function (binStr) {
- return new Promise(resolve => {
+ const binaryStringToBase64 = binStr =>
+ new Promise(resolve => {
const reader = new FileReader();
reader.readAsDataURL(binStr);
reader.onloadend = function () {
resolve(reader.result);
};
});
- };
function prepend(extension) {
return window.location.origin + extension;
@@ -30,8 +30,8 @@ const ForeignHtmlRenderer = function (styleSheets) {
* @param {String} url
* @returns {Promise}
*/
- const getResourceAsBase64 = function (webUrl, inurl) {
- return new Promise((resolve, reject) => {
+ const getResourceAsBase64 = (webUrl, inurl) =>
+ new Promise(resolve => {
const xhr = new XMLHttpRequest();
// const url = inurl.startsWith("/") && !inurl.startsWith("//") ? webUrl + inurl : inurl;
// const url = CorsProxy(inurl.startsWith("/") && !inurl.startsWith("//") ? webUrl + inurl : inurl);// inurl.startsWith("http") ? CorsProxy(inurl) : inurl;
@@ -67,16 +67,15 @@ const ForeignHtmlRenderer = function (styleSheets) {
xhr.send(null);
});
- };
/**
*
* @param {String[]} urls
* @returns {Promise}
*/
- const getMultipleResourcesAsBase64 = function (webUrl, urls) {
+ const getMultipleResourcesAsBase64 = (webUrl, urls) => {
const promises = [];
- for (let i = 0; i < urls.length; i += 1) {
+ for (let i = 0; webUrl && i < urls.length; i += 1) {
promises.push(getResourceAsBase64(webUrl, urls[i]));
}
return Promise.all(promises);
@@ -130,6 +129,7 @@ const ForeignHtmlRenderer = function (styleSheets) {
const urlsFound = [];
let searchStartIndex = 0;
+ // eslint-disable-next-line no-constant-condition
while (true) {
const url = parseValue(cssRuleStr, searchStartIndex, selector, delimiters);
if (url === null) {
@@ -155,9 +155,6 @@ const ForeignHtmlRenderer = function (styleSheets) {
const getImageUrlsFromFromHtml = function (html) {
return getUrlsFromCssString(html, 'src=', [' ', '>', '\t'], true);
};
- const getSourceUrlsFromFromHtml = function (html) {
- return getUrlsFromCssString(html, 'source=', [' ', '>', '\t'], true);
- };
const escapeRegExp = function (string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
@@ -171,46 +168,45 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @returns {Promise<String>}
*/
- const buildSvgDataUri = async function (webUrl, inputContentHtml, width, height, scroll, xoff) {
- return new Promise(async (resolve, reject) => {
- /* !! The problems !!
- * 1. CORS (not really an issue, expect perhaps for images, as this is a general security consideration to begin with)
- * 2. Platform won't wait for external assets to load (fonts, images, etc.)
- */
-
- // copy styles
- let cssStyles = '';
- const urlsFoundInCss = [];
-
- for (let i = 0; i < styleSheets.length; i += 1) {
- try {
- const rules = styleSheets[i].cssRules;
- for (let j = 0; j < rules.length; j += 1) {
- const cssRuleStr = rules[j].cssText;
- urlsFoundInCss.push(...getUrlsFromCssString(cssRuleStr));
- cssStyles += cssRuleStr;
- }
- } catch (e) {
- /* empty */
+ const buildSvgDataUri = (webUrl, inputContentHtml, width, height, scroll, xoff) => {
+ /* !! The problems !!
+ * 1. CORS (not really an issue, expect perhaps for images, as this is a general security consideration to begin with)
+ * 2. Platform won't wait for external assets to load (fonts, images, etc.)
+ */
+
+ // copy styles
+ let cssStyles = '';
+ const urlsFoundInCss = [];
+
+ for (let i = 0; i < styleSheets.length; i += 1) {
+ try {
+ const rules = styleSheets[i].cssRules;
+ for (let j = 0; j < rules.length; j += 1) {
+ const cssRuleStr = rules[j].cssText;
+ urlsFoundInCss.push(...getUrlsFromCssString(cssRuleStr));
+ cssStyles += cssRuleStr;
}
+ } catch (e) {
+ /* empty */
}
+ }
- // const fetchedResourcesFromStylesheets = await getMultipleResourcesAsBase64(webUrl, urlsFoundInCss);
- // for (let i = 0; i < fetchedResourcesFromStylesheets.length; i++) {
- // const r = fetchedResourcesFromStylesheets[i];
- // if (r.resourceUrl) {
- // cssStyles = cssStyles.replace(new RegExp(escapeRegExp(r.resourceUrl), "g"), r.resourceBase64);
- // }
- // }
-
- let contentHtml = inputContentHtml
- .replace(/<source[^>]*>/g, '') // <picture> tags have a <source> which has a srcset field of image refs. instead of converting each, just use the default <img> of the picture
- .replace(/noscript/g, 'div')
- .replace(/<div class="mediaset"><\/div>/g, '') // when scripting isn't available (ie, rendering web pages here), <noscript> tags should become <div>'s. But for Brown CS, there's a layout problem if you leave the empty <mediaset> tag
- .replace(/<link[^>]*>/g, '') // don't need to keep any linked style sheets because we've already processed all style sheets above
- .replace(/srcset="([^ "]*)[^"]*"/g, 'src="$1"'); // instead of converting each item in the srcset to a data url, just convert the first one and use that
- const urlsFoundInHtml = getImageUrlsFromFromHtml(contentHtml).filter(url => !url.startsWith('data:'));
- const fetchedResources = webUrl ? await getMultipleResourcesAsBase64(webUrl, urlsFoundInHtml) : [];
+ // const fetchedResourcesFromStylesheets = await getMultipleResourcesAsBase64(webUrl, urlsFoundInCss);
+ // for (let i = 0; i < fetchedResourcesFromStylesheets.length; i++) {
+ // const r = fetchedResourcesFromStylesheets[i];
+ // if (r.resourceUrl) {
+ // cssStyles = cssStyles.replace(new RegExp(escapeRegExp(r.resourceUrl), "g"), r.resourceBase64);
+ // }
+ // }
+
+ let contentHtml = inputContentHtml
+ .replace(/<source[^>]*>/g, '') // <picture> tags have a <source> which has a srcset field of image refs. instead of converting each, just use the default <img> of the picture
+ .replace(/noscript/g, 'div')
+ .replace(/<div class="mediaset"><\/div>/g, '') // when scripting isn't available (ie, rendering web pages here), <noscript> tags should become <div>'s. But for Brown CS, there's a layout problem if you leave the empty <mediaset> tag
+ .replace(/<link[^>]*>/g, '') // don't need to keep any linked style sheets because we've already processed all style sheets above
+ .replace(/srcset="([^ "]*)[^"]*"/g, 'src="$1"'); // instead of converting each item in the srcset to a data url, just convert the first one and use that
+ const urlsFoundInHtml = getImageUrlsFromFromHtml(contentHtml).filter(url => !url.startsWith('data:'));
+ return getMultipleResourcesAsBase64(webUrl, urlsFoundInHtml).then(fetchedResources => {
for (let i = 0; i < fetchedResources.length; i += 1) {
const r = fetchedResources[i];
if (r.resourceUrl) {
@@ -243,9 +239,7 @@ const ForeignHtmlRenderer = function (styleSheets) {
</svg>`;
// convert SVG to data-uri
- const dataUri = `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(svg)))}`;
-
- resolve(dataUri);
+ return `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(svg)))}`;
});
};
@@ -256,18 +250,19 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @return {Promise<Image>}
*/
- this.renderToImage = async function (webUrl, html, width, height, scroll, xoff) {
- return new Promise(async (resolve, reject) => {
+ this.renderToImage = (webUrl, html, width, height, scroll, xoff) =>
+ new Promise(resolve => {
const img = new Image();
- console.log(`BUILDING SVG for: ${webUrl}`);
- img.src = await buildSvgDataUri(webUrl, html, width, height, scroll, xoff);
-
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 => {
+ img.src = uri;
+ return img;
+ });
});
- };
/**
* @param {String} html
@@ -276,20 +271,16 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @return {Promise<Image>}
*/
- this.renderToCanvas = async function (webUrl, html, width, height, scroll, xoff, oversample) {
- return new Promise(async (resolve, reject) => {
- const img = await self.renderToImage(webUrl, html, width, height, scroll, xoff);
-
+ this.renderToCanvas = (webUrl, html, width, height, scroll, xoff, oversample) =>
+ self.renderToImage(webUrl, html, width, height, scroll, xoff).then(img => {
const canvas = document.createElement('canvas');
canvas.width = img.width * oversample;
canvas.height = img.height * oversample;
const canvasCtx = canvas.getContext('2d');
canvasCtx.drawImage(img, 0, 0, img.width * oversample, img.height * oversample);
-
- resolve(canvas);
+ return canvas;
});
- };
/**
* @param {String} html
@@ -298,12 +289,10 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @return {Promise<String>}
*/
- this.renderToBase64Png = async function (webUrl, html, width, height, scroll, xoff, oversample) {
- return new Promise(async (resolve, reject) => {
- const canvas = await self.renderToCanvas(webUrl, html, width, height, scroll, xoff, oversample);
- resolve(canvas.toDataURL('image/png'));
- });
- };
+ this.renderToBase64Png = (webUrl, html, width, height, scroll, xoff, oversample) =>
+ self
+ .renderToCanvas(webUrl, html, width, height, scroll, xoff, oversample) //
+ .then(canvas => canvas.toDataURL('image/png'));
};
export function CreateImage(webUrl, styleSheets, html, width, height, scroll, xoff = 0, oversample = 1) {
@@ -379,11 +368,11 @@ const ClipboardUtils = new (function () {
.then(result => {
loadFile(result, callback);
})
- .catch(error => {
+ .catch(() => {
callback(null, 'Reading clipboard error.');
});
})
- .catch(error => {
+ .catch(() => {
callback(null, 'Reading clipboard error.');
});
} else {
diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx
index 7fd799952..2d1d3d7db 100644
--- a/src/client/views/nodes/audio/AudioWaveform.tsx
+++ b/src/client/views/nodes/audio/AudioWaveform.tsx
@@ -7,8 +7,8 @@ import { List } from '../../../../fields/List';
import { listSpec } from '../../../../fields/Schema';
import { Cast } from '../../../../fields/Types';
import { numberRange } from '../../../../Utils';
+import { Colors } from '../../global/globalEnums';
import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { Colors } from './../../global/globalEnums';
import './AudioWaveform.scss';
import { WaveCanvas } from './WaveCanvas';
@@ -62,7 +62,7 @@ export class AudioWaveform extends ObservableReactComponent<AudioWaveformProps>
return NumListCast(this._props.layoutDoc[this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor)]);
}
- audioBucketField = (start: number, end: number, zoomFactor: number) => this._props.fieldKey + '_audioBuckets/' + '/' + start.toFixed(2).replace('.', '_') + '/' + end.toFixed(2).replace('.', '_') + '/' + zoomFactor * 10;
+ audioBucketField = (start: number, end: number, zoomFactor: number) => this._props.fieldKey + '_audioBuckets//' + start.toFixed(2).replace('.', '_') + '/' + end.toFixed(2).replace('.', '_') + '/' + zoomFactor * 10;
componentWillUnmount() {
this._disposer?.();
@@ -72,7 +72,7 @@ export class AudioWaveform extends ObservableReactComponent<AudioWaveformProps>
this._disposer = reaction(
() => ({ clipStart: this.clipStart, clipEnd: this.clipEnd, fieldKey: this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor), zoomFactor: this._props.zoomFactor }),
({ clipStart, clipEnd, fieldKey, zoomFactor }) => {
- if (!this._props.layoutDoc[fieldKey] && this._props.layoutDoc.layout_fieldKey != 'layout_icon') {
+ if (!this._props.layoutDoc[fieldKey] && this._props.layoutDoc.layout_fieldKey !== 'layout_icon') {
// setting these values here serves as a "lock" to prevent multiple attempts to create the waveform at nerly the same time.
const waveform = Cast(this._props.layoutDoc[this.audioBucketField(0, this._props.rawDuration, 1)], listSpec('number'));
this._props.layoutDoc[fieldKey] = waveform && new List<number>(waveform.slice((clipStart / this._props.rawDuration) * waveform.length, (clipEnd / this._props.rawDuration) * waveform.length));
@@ -109,7 +109,7 @@ export class AudioWaveform extends ObservableReactComponent<AudioWaveformProps>
progressColor={Colors.MEDIUM_BLUE_ALT}
progress={this._props.progress ?? 1}
barWidth={200 / this.audioBuckets.length}
- //gradientColors={this._props.gradientColors}
+ // gradientColors={this._props.gradientColors}
peaks={this.audioBuckets}
width={(this._props.PanelWidth ?? 0) * window.devicePixelRatio}
height={this.waveHeight * window.devicePixelRatio}
diff --git a/src/client/views/nodes/audio/WaveCanvas.tsx b/src/client/views/nodes/audio/WaveCanvas.tsx
index d3f5669a2..eacda2d42 100644
--- a/src/client/views/nodes/audio/WaveCanvas.tsx
+++ b/src/client/views/nodes/audio/WaveCanvas.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
import React from 'react';
interface WaveCanvasProps {
@@ -14,7 +15,7 @@ interface WaveCanvasProps {
export class WaveCanvas extends React.Component<WaveCanvasProps> {
// If the first value of peaks is negative, addToIndices will be 1
- posPeaks = (peaks: number[], addToIndices: number) => peaks.filter((_, index) => (index + addToIndices) % 2 == 0);
+ posPeaks = (peaks: number[], addToIndices: number) => peaks.filter((_, index) => (index + addToIndices) % 2 === 0);
drawBars = (waveCanvasCtx: CanvasRenderingContext2D, width: number, halfH: number, peaks: number[]) => {
// Bar wave draws the bottom only as a reflection of the top,
@@ -47,6 +48,7 @@ export class WaveCanvas extends React.Component<WaveCanvasProps> {
// A half-pixel offset makes lines crisp
const $ = 0.5 / this.props.pixelRatio;
+ // eslint-disable-next-line no-bitwise
const length = ~~(allPeaks.length / 2); // ~~ is Math.floor for positive numbers.
const scale = width / length;
@@ -55,14 +57,14 @@ export class WaveCanvas extends React.Component<WaveCanvasProps> {
waveCanvasCtx.beginPath();
waveCanvasCtx.moveTo($, halfH);
- for (var i = 0; i < length; i++) {
- var h = Math.round((allPeaks[2 * i] / absmax) * halfH);
+ for (let i = 0; i < length; i++) {
+ const h = Math.round((allPeaks[2 * i] / absmax) * halfH);
waveCanvasCtx.lineTo(i * scale + $, halfH - h);
}
// Draw the bottom edge going backwards, to make a single closed hull to fill.
- for (var i = length - 1; i >= 0; i--) {
- var h = Math.round((allPeaks[2 * i + 1] / absmax) * halfH);
+ for (let i = length - 1; i >= 0; i--) {
+ const h = Math.round((allPeaks[2 * i + 1] / absmax) * halfH);
waveCanvasCtx.lineTo(i * scale + $, halfH - h);
}
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index 748c3322e..bd66941c3 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -1,12 +1,14 @@
-import { Calendar, EventClickArg, EventSourceInput } from '@fullcalendar/core';
+import { Calendar, EventSourceInput } from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import multiMonthPlugin from '@fullcalendar/multimonth';
import { makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { dateRangeStrToDates } from '../../../../Utils';
+import { dateRangeStrToDates } from '../../../../ClientUtils';
import { Doc } from '../../../../fields/Doc';
import { StrCast } from '../../../../fields/Types';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { FieldView, FieldViewProps } from '../FieldView';
@@ -57,12 +59,13 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>() {
docBackgroundColor(type: string): string {
// TODO: Return a different color based on the event type
+ console.log(type);
return 'blue';
}
get calendarEvents(): EventSourceInput | undefined {
if (this.childDocs.length === 0) return undefined;
- return this.childDocs.map((doc, idx) => {
+ return this.childDocs.map(doc => {
const docTitle = StrCast(doc.title);
const docDateRange = StrCast(doc.date_range);
const [startDate, endDate] = dateRangeStrToDates(docDateRange);
@@ -85,7 +88,7 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>() {
});
}
- handleEventClick = (arg: EventClickArg) => {
+ handleEventClick = (/* arg: EventClickArg */) => {
// TODO: open popover with event description, option to open CalendarManager and change event date, delete event, etc.
};
@@ -113,8 +116,12 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>() {
render() {
return (
<div className="calendar-box-conatiner">
- <div id="calendar-box-v1"></div>
+ <div id="calendar-box-v1" />
</div>
);
}
}
+Docs.Prototypes.TemplateMap.set(DocumentType.CALENDAR, {
+ layout: { view: CalendarBox, dataField: 'data' },
+ options: { acl: '' },
+});
diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
index a72ed1813..3ec49fa27 100644
--- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
@@ -1,60 +1,11 @@
import { TextSelection } from 'prosemirror-state';
import * as ReactDOM from 'react-dom/client';
-import { Doc } from '../../../../fields/Doc';
-import { DocServer } from '../../../DocServer';
import * as React from 'react';
import { IReactionDisposer, computed, reaction } from 'mobx';
+import { Doc } from '../../../../fields/Doc';
+import { DocServer } from '../../../DocServer';
import { NumCast } from '../../../../fields/Types';
-// creates an inline comment in a note when '>>' is typed.
-// the comment sits on the right side of the note and vertically aligns with its anchor in the text.
-// the comment can be toggled on/off with the '<-' text anchor.
-export class DashDocCommentView {
- dom: HTMLDivElement; // container for label and value
- root: any;
- node: any;
-
- constructor(node: any, view: any, getPos: any) {
- this.node = node;
- this.dom = document.createElement('div');
- this.dom.style.width = node.attrs.width;
- this.dom.style.height = node.attrs.height;
- this.dom.style.fontWeight = 'bold';
- this.dom.style.position = 'relative';
- this.dom.style.display = 'inline-block';
- this.dom.onkeypress = function (e: any) {
- e.stopPropagation();
- };
- this.dom.onkeydown = function (e: any) {
- e.stopPropagation();
- };
- this.dom.onkeyup = function (e: any) {
- e.stopPropagation();
- };
- this.dom.onmousedown = function (e: any) {
- e.stopPropagation();
- };
-
- this.root = ReactDOM.createRoot(this.dom);
- this.root.render(<DashDocCommentViewInternal view={view} getPos={getPos} setHeight={this.setHeight} docId={node.attrs.docId} />);
- (this as any).dom = this.dom;
- }
-
- setHeight = (hgt: number) => {
- !this.node.attrs.reflow && DocServer.GetRefField(this.node.attrs.docId).then(doc => doc instanceof Doc && (this.dom.style.height = hgt + ''));
- };
-
- destroy() {
- this.root.unmount();
- }
- deselectNode() {
- this.dom.classList.remove('ProseMirror-selectednode');
- }
- selectNode() {
- this.dom.classList.add('ProseMirror-selectednode');
- }
-}
-
interface IDashDocCommentViewInternal {
docId: string;
view: any;
@@ -65,9 +16,6 @@ interface IDashDocCommentViewInternal {
export class DashDocCommentViewInternal extends React.Component<IDashDocCommentViewInternal> {
_reactionDisposer: IReactionDisposer | undefined;
- @computed get _dashDoc() {
- return DocServer.GetRefField(this.props.docId);
- }
constructor(props: any) {
super(props);
this.onPointerLeaveCollapsed = this.onPointerLeaveCollapsed.bind(this);
@@ -77,58 +25,62 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
}
componentDidMount(): void {
this._reactionDisposer?.();
- this._dashDoc.then(
- doc =>
- doc instanceof Doc &&
- (this._reactionDisposer = reaction(
+ this._dashDoc.then(doc => {
+ if (doc instanceof Doc) {
+ this._reactionDisposer = reaction(
() => NumCast((doc as Doc)._height),
hgt => this.props.setHeight(hgt),
- {
- fireImmediately: true,
- }
- ))
- );
+ { fireImmediately: true }
+ );
+ }
+ });
}
componentWillUnmount(): void {
this._reactionDisposer?.();
}
- onPointerLeaveCollapsed(e: any) {
+ @computed get _dashDoc() {
+ return DocServer.GetRefField(this.props.docId);
+ }
+
+ onPointerLeaveCollapsed = (e: any) => {
this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight());
e.preventDefault();
e.stopPropagation();
- }
+ };
- onPointerEnterCollapsed(e: any) {
+ onPointerEnterCollapsed = (e: any) => {
this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false));
e.preventDefault();
e.stopPropagation();
- }
+ };
- onPointerUpCollapsed(e: any) {
+ onPointerUpCollapsed = (e: any) => {
const target = this.targetNode();
if (target) {
const expand = target.hidden;
- const tr = this.props.view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true });
+ const tr = this.props.view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: !target.node.attrs.hidden });
this.props.view.dispatch(tr.setSelection(TextSelection.create(tr.doc, this.props.getPos() + (expand ? 2 : 1)))); // update the attrs
setTimeout(() => {
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))));
- } catch (e) {}
+ } catch (err) {
+ /* empty */
+ }
}, 0);
}
e.stopPropagation();
- }
+ };
- onPointerDownCollapsed(e: any) {
+ onPointerDownCollapsed = (e: any) => {
e.stopPropagation();
- }
+ };
targetNode = () => {
// search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor
- const state = this.props.view.state;
+ const { state } = this.props.view;
for (let i = this.props.getPos() + 1; i < state.doc.content.size; i++) {
const m = state.doc.nodeAt(i);
if (m && m.type === state.schema.nodes.dashDoc && m.attrs.docId === this.props.docId) {
@@ -141,7 +93,9 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
setTimeout(() => {
try {
this.props.view.dispatch(state.tr.setSelection(TextSelection.create(state.tr.doc, this.props.getPos() + 2)));
- } catch (e) {}
+ } catch (err) {
+ /* empty */
+ }
}, 0);
return undefined;
};
@@ -154,7 +108,60 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
onPointerLeave={this.onPointerLeaveCollapsed}
onPointerEnter={this.onPointerEnterCollapsed}
onPointerUp={this.onPointerUpCollapsed}
- onPointerDown={this.onPointerDownCollapsed}></span>
+ onPointerDown={this.onPointerDownCollapsed}
+ />
);
}
}
+
+// creates an inline comment in a note when '>>' is typed.
+// the comment sits on the right side of the note and vertically aligns with its anchor in the text.
+// the comment can be toggled on/off with the '<-' text anchor.
+export class DashDocCommentView {
+ dom: HTMLDivElement; // container for label and value
+ root: any;
+ node: any;
+
+ constructor(node: any, view: any, getPos: any) {
+ this.node = node;
+ this.dom = document.createElement('div');
+ this.dom.style.width = node.attrs.width;
+ this.dom.style.height = node.attrs.height;
+ this.dom.style.fontWeight = 'bold';
+ this.dom.style.position = 'relative';
+ this.dom.style.display = 'inline-block';
+ this.dom.onkeypress = function (e: any) {
+ e.stopPropagation();
+ };
+ this.dom.onkeydown = function (e: any) {
+ e.stopPropagation();
+ };
+ this.dom.onkeyup = function (e: any) {
+ e.stopPropagation();
+ };
+ this.dom.onmousedown = function (e: any) {
+ e.stopPropagation();
+ };
+
+ this.root = ReactDOM.createRoot(this.dom);
+ this.root.render(<DashDocCommentViewInternal view={view} getPos={getPos} setHeight={this.setHeight} docId={node.attrs.docId} />);
+ (this as any).dom = this.dom;
+ }
+
+ setHeight = (hgt: number) => {
+ !this.node.attrs.reflow &&
+ DocServer.GetRefField(this.node.attrs.docId).then(doc => {
+ doc instanceof Doc && (this.dom.style.height = hgt + '');
+ });
+ };
+
+ destroy() {
+ this.root.unmount();
+ }
+ deselectNode() {
+ this.dom.classList.remove('ProseMirror-selectednode');
+ }
+ selectNode() {
+ this.dom.classList.add('ProseMirror-selectednode');
+ }
+}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 7335c9286..93371685d 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -1,77 +1,23 @@
+/* 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';
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
+import { ClientUtils, returnFalse } from '../../../../ClientUtils';
import { Doc } from '../../../../fields/Doc';
import { Height, Width } from '../../../../fields/DocSymbols';
import { NumCast } from '../../../../fields/Types';
-import { emptyFunction, returnFalse, Utils } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
-import { Docs, DocUtils } from '../../../documents/Documents';
+import { Docs } from '../../../documents/Documents';
+import { DocUtils } from '../../../documents/DocUtils';
import { Transform } from '../../../util/Transform';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DocumentView } from '../DocumentView';
-import { FocusViewOptions } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import { FormattedTextBox } from './FormattedTextBox';
-var horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side.
-export class DashDocView {
- dom: HTMLSpanElement; // container for label and value
- root: any;
-
- constructor(node: any, view: any, getPos: any, 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) {
- e.stopPropagation();
- };
- this.dom.onkeydown = function (e: any) {
- e.stopPropagation();
- };
- this.dom.onkeyup = function (e: any) {
- e.stopPropagation();
- };
- this.dom.onmousedown = function (e: any) {
- e.stopPropagation();
- };
-
- this.root = ReactDOM.createRoot(this.dom);
- this.root.render(
- <DashDocViewInternal
- docId={node.attrs.docId}
- embedding={node.attrs.embedding}
- width={node.attrs.width}
- height={node.attrs.height}
- hidden={node.attrs.hidden}
- fieldKey={node.attrs.fieldKey}
- tbox={tbox}
- view={view}
- node={node}
- getPos={getPos}
- />
- );
- }
- destroy() {
- setTimeout(() => {
- try {
- this.root.unmount();
- } catch {}
- });
- }
- deselectNode() {
- this.dom.style.backgroundColor = '';
- }
- selectNode() {
- this.dom.style.backgroundColor = 'rgb(141, 182, 247)';
- }
-}
-
+const horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side.
interface IDashDocViewInternal {
docId: string;
embedding: string;
@@ -84,6 +30,7 @@ interface IDashDocViewInternal {
node: any;
getPos: any;
}
+
@observer
export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewInternal> {
_spanRef = React.createRef<HTMLDivElement>();
@@ -157,7 +104,7 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
getDocTransform = () => {
if (!this._spanRef.current) return Transform.Identity();
- const { scale, translateX, translateY } = Utils.GetScreenTransform(this._spanRef.current);
+ const { scale, translateX, translateY } = ClientUtils.GetScreenTransform(this._spanRef.current);
return new Transform(-translateX, -translateY, 1).scale(1 / scale);
};
outerFocus = (target: Doc, options: FocusViewOptions) => this._textBox.focus(target, options); // ideally, this would scroll to show the focus target
@@ -226,3 +173,61 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
);
}
}
+
+export class DashDocView {
+ dom: HTMLSpanElement; // container for label and value
+ root: any;
+
+ constructor(node: any, view: any, getPos: any, 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) {
+ e.stopPropagation();
+ };
+ this.dom.onkeydown = function (e: any) {
+ e.stopPropagation();
+ };
+ this.dom.onkeyup = function (e: any) {
+ e.stopPropagation();
+ };
+ this.dom.onmousedown = function (e: any) {
+ e.stopPropagation();
+ };
+
+ this.root = ReactDOM.createRoot(this.dom);
+ this.root.render(
+ <DashDocViewInternal
+ docId={node.attrs.docId}
+ embedding={node.attrs.embedding}
+ width={node.attrs.width}
+ height={node.attrs.height}
+ hidden={node.attrs.hidden}
+ fieldKey={node.attrs.fieldKey}
+ tbox={tbox}
+ view={view}
+ node={node}
+ getPos={getPos}
+ />
+ );
+ }
+ destroy() {
+ setTimeout(() => {
+ try {
+ this.root.unmount();
+ } catch {
+ /* empty */
+ }
+ });
+ }
+ deselectNode() {
+ this.dom.style.backgroundColor = '';
+ }
+ selectNode() {
+ this.dom.style.backgroundColor = 'rgb(141, 182, 247)';
+ }
+}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.scss b/src/client/views/nodes/formattedText/DashFieldView.scss
index 7a0ff8776..d79df4272 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.scss
+++ b/src/client/views/nodes/formattedText/DashFieldView.scss
@@ -1,20 +1,11 @@
@import '../../global/globalCssVariables.module.scss';
+.dashFieldView-active,
.dashFieldView {
position: relative;
display: inline-flex;
align-items: center;
- select {
- display: none;
- }
-
- &:hover {
- select {
- display: unset;
- }
- }
-
.dashFieldView-enumerables {
width: 10px;
height: 10px;
@@ -35,6 +26,7 @@
display: inline-block;
font-weight: normal;
background: rgba(0, 0, 0, 0.1);
+ cursor: default;
}
.dashFieldView-fieldSpan {
min-width: 8px;
@@ -50,6 +42,27 @@
}
}
}
+
+.dashFieldView,
+.dashFieldView-active {
+ .dashFieldView-select {
+ height: 10p;
+ font-size: 12px;
+ background: transparent;
+ opacity: 0;
+ width: 5px;
+ }
+}
+
+.dashFieldView {
+ &:hover {
+ .dashFieldView-select {
+ opacity: unset;
+ width: 15px !important;
+ }
+ }
+}
+
.ProseMirror-selectedNode {
outline: solid 1px $light-blue !important;
}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 5c4d850ad..9903d0e8a 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -1,94 +1,105 @@
+/* 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 } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
+import { NodeSelection } from 'prosemirror-state';
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
+import { returnFalse, returnZero, setupMoveUpEvents } from '../../../../ClientUtils';
import { Doc, DocListCast, Field } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
import { listSpec } from '../../../../fields/Schema';
import { SchemaHeaderField } from '../../../../fields/SchemaHeaderField';
-import { Cast } from '../../../../fields/Types';
-import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents } from '../../../../Utils';
+import { Cast, DocCast } from '../../../../fields/Types';
+import { emptyFunction } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
import { CollectionViewType } from '../../../documents/DocumentTypes';
import { Transform } from '../../../util/Transform';
-import { undoBatch } from '../../../util/UndoManager';
+import { undoable, undoBatch } from '../../../util/UndoManager';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
import { SchemaTableCell } from '../../collections/collectionSchema/SchemaTableCell';
import { FilterPanel } from '../../FilterPanel';
import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { OpenWhere } from '../DocumentView';
+import { OpenWhere } from '../OpenWhere';
import './DashFieldView.scss';
import { FormattedTextBox } from './FormattedTextBox';
-export class DashFieldView {
- dom: HTMLDivElement; // container for label and value
- root: any;
- node: any;
- tbox: FormattedTextBox;
+@observer
+export class DashFieldViewMenu extends AntimodeMenu<AntimodeMenuProps> {
+ // eslint-disable-next-line no-use-before-define
+ static Instance: DashFieldViewMenu;
+ static createFieldView: (e: React.MouseEvent) => void = emptyFunction;
+ static toggleFieldHide: () => void = emptyFunction;
+ static toggleValueHide: () => void = emptyFunction;
+ constructor(props: any) {
+ super(props);
+ DashFieldViewMenu.Instance = this;
+ }
- 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) {
- this.node = node;
- this.tbox = tbox;
- 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.onkeypress = function (e: any) {
- e.stopPropagation();
- };
- this.dom.onkeydown = function (e: any) {
- e.stopPropagation();
- };
- this.dom.onkeyup = function (e: any) {
- e.stopPropagation();
- };
- this.dom.onmousedown = function (e: any) {
- e.stopPropagation();
- };
+ showFields = (e: React.MouseEvent) => {
+ DashFieldViewMenu.createFieldView(e);
+ DashFieldViewMenu.Instance.fadeOut(true);
+ };
+ toggleFieldHide = () => {
+ DashFieldViewMenu.toggleFieldHide();
+ DashFieldViewMenu.Instance.fadeOut(true);
+ };
+ toggleValueHide = () => {
+ DashFieldViewMenu.toggleValueHide();
+ DashFieldViewMenu.Instance.fadeOut(true);
+ };
- this.root = ReactDOM.createRoot(this.dom);
- this.root.render(
- <DashFieldViewInternal
- node={node}
- unclickable={this.unclickable}
- getPos={getPos}
- fieldKey={node.attrs.fieldKey}
- docId={node.attrs.docId}
- width={node.attrs.width}
- height={node.attrs.height}
- hideKey={node.attrs.hideKey}
- editable={node.attrs.editable}
- tbox={tbox}
- />
+ @observable _fieldKey = '';
+
+ @action
+ public show = (x: number, y: number, fieldKey: string) => {
+ this._fieldKey = fieldKey;
+ this.jumpTo(x, y, true);
+ const hideMenu = () => {
+ this.fadeOut(true);
+ document.removeEventListener('pointerdown', hideMenu, true);
+ };
+ document.addEventListener('pointerdown', hideMenu, true);
+ };
+ render() {
+ return this.getElement(
+ <>
+ <Tooltip key="trash" title={<div className="dash-tooltip">{`Show Pivot Viewer for '${this._fieldKey}'`}</div>}>
+ <button type="button" className="antimodeMenu-button" onPointerDown={this.showFields}>
+ <FontAwesomeIcon icon="eye" size="sm" />
+ </button>
+ </Tooltip>
+ {this._fieldKey.startsWith('#') ? null : (
+ <Tooltip key="key" title={<div className="dash-tooltip">Toggle view of field key</div>}>
+ <button type="button" className="antimodeMenu-button" onPointerDown={this.toggleFieldHide}>
+ <FontAwesomeIcon icon="bullseye" size="sm" />
+ </button>
+ </Tooltip>
+ )}
+ {this._fieldKey.startsWith('#') ? null : (
+ <Tooltip key="val" title={<div className="dash-tooltip">Toggle view of field value</div>}>
+ <button type="button" className="antimodeMenu-button" onPointerDown={this.toggleValueHide}>
+ <FontAwesomeIcon icon="hashtag" size="sm" />
+ </button>
+ </Tooltip>
+ )}
+ </>
);
}
- destroy() {
- setTimeout(() => {
- try {
- this.root.unmount();
- } catch {}
- });
- }
- deselectNode() {
- this.dom.classList.remove('ProseMirror-selectednode');
- }
- selectNode() {
- this.dom.classList.add('ProseMirror-selectednode');
- }
}
-
interface IDashFieldViewInternal {
fieldKey: string;
docId: string;
hideKey: boolean;
+ hideValue: boolean;
tbox: FormattedTextBox;
width: number;
height: number;
editable: boolean;
+ nodeSelected: () => boolean;
node: any;
getPos: any;
unclickable: () => boolean;
@@ -101,18 +112,21 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
_fieldKey: string;
_fieldRef = React.createRef<HTMLDivElement>();
@observable _dashDoc: Doc | undefined = undefined;
- @observable _expanded = false;
+ @observable _expanded = this._props.nodeSelected();
constructor(props: IDashFieldViewInternal) {
super(props);
makeObservable(this);
this._fieldKey = this._props.fieldKey;
- this._textBoxDoc = this._fieldKey.startsWith('_') ? this._props.tbox.Document : this._props.tbox.dataDoc;
+ this._textBoxDoc = this._props.tbox.Document;
+ const setDoc = action((doc: Doc) => {
+ this._dashDoc = doc;
+ });
if (this._props.docId) {
- DocServer.GetRefField(this._props.docId).then(action(dashDoc => dashDoc instanceof Doc && (this._dashDoc = dashDoc)));
+ DocServer.GetRefField(this._props.docId).then(dashDoc => dashDoc instanceof Doc && setDoc(dashDoc));
} else {
- this._dashDoc = this._fieldKey.startsWith('_') ? this._props.tbox.Document : this._props.tbox.dataDoc;
+ setDoc(this._props.tbox.Document);
}
}
@@ -126,38 +140,56 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
componentWillUnmount() {
this._reactionDisposer?.();
}
- return100 = () => 100;
+ isRowActive = () => (this._props.nodeSelected() || this._expanded) && this._props.editable;
+ finishEdit = action(() => {
+ if (this._expanded) {
+ this._expanded = false;
+ // if the edit finishes, then we want to lose focus on the textBox unless something else in the textBox got focus
+ // the timeout allows switching focus from one dashFieldView to another in the same text box
+ setTimeout(() => !this._props.tbox.ProseRef?.contains(document.activeElement) && this._props.tbox._props.onBlur?.());
+ }
+ });
+ selectedCells = () => (this._dashDoc ? [this._dashDoc] : undefined);
+ columnWidth = () => Math.min(this._props.tbox._props.PanelWidth(), Math.max(50, this._props.tbox._props.PanelWidth() - 100)); // try to leave room for the fieldKey
// set the display of the field's value (checkbox for booleans, span of text for strings)
@computed get fieldValueContent() {
return !this._dashDoc ? null : (
- <div onClick={action(e => (this._expanded = !this._props.editable ? !this._expanded : true))} style={{ fontSize: 'smaller', width: this._props.hideKey ? this._props.tbox._props.PanelWidth() - 20 : undefined }}>
+ <div
+ onClick={action(() => {
+ this._expanded = !this._props.editable ? !this._expanded : true;
+ })}
+ style={{ fontSize: 'smaller', width: !this._hideKey && this._expanded ? this.columnWidth() : undefined }}>
<SchemaTableCell
Document={this._dashDoc}
col={0}
deselectCell={emptyFunction}
selectCell={emptyFunction}
- maxWidth={this._props.hideKey ? undefined : this.return100}
- columnWidth={this._props.hideKey ? () => this._props.tbox._props.PanelWidth() - 20 : returnZero}
- selectedCell={() => [this._dashDoc!, 0]}
+ maxWidth={this._props.hideKey || this._hideKey ? undefined : this._props.tbox._props.PanelWidth}
+ columnWidth={this._expanded || this._props.nodeSelected() ? this.columnWidth : returnZero}
+ selectedCells={this.selectedCells}
+ selectedCol={returnZero}
fieldKey={this._fieldKey}
rowHeight={returnZero}
- isRowActive={() => this._expanded && this._props.editable}
+ isRowActive={this.isRowActive}
padding={0}
getFinfo={emptyFunction}
setColumnValues={returnFalse}
- allowCRs={true}
- oneLine={!this._expanded}
- finishEdit={action(() => (this._expanded = false))}
+ setSelectedColumnValues={returnFalse}
+ allowCRs
+ oneLine={!this._expanded && !this._props.nodeSelected()}
+ finishEdit={this.finishEdit}
transform={Transform.Identity}
menuTarget={null}
+ autoFocus
+ rootSelected={this._props.tbox._props.rootSelected}
/>
</div>
);
}
- createPivotForField = (e: React.MouseEvent) => {
- let container = this._props.tbox.DocumentView?.().containerViewPath?.().lastElement();
+ createPivotForField = () => {
+ const container = this._props.tbox.DocumentView?.().containerViewPath?.().lastElement();
if (container) {
const embedding = Doc.MakeEmbedding(container.Document);
embedding._type_collection = CollectionViewType.Time;
@@ -173,21 +205,50 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
}
};
+ toggleFieldHide = undoable(
+ action(() => {
+ const editor = this._props.tbox.EditorView!;
+ editor.dispatch(editor.state.tr.setNodeMarkup(this._props.getPos(), this._props.node.type, { ...this._props.node.attrs, hideKey: this._props.node.attrs.hideValue ? false : !this._props.node.attrs.hideKey }));
+ }),
+ 'hideKey'
+ );
+
+ toggleValueHide = undoable(
+ action(() => {
+ const editor = this._props.tbox.EditorView!;
+ editor.dispatch(editor.state.tr.setNodeMarkup(this._props.getPos(), this._props.node.type, { ...this._props.node.attrs, hideValue: this._props.node.attrs.hideKey ? false : !this._props.node.attrs.hideValue }));
+ }),
+ 'hideValue'
+ );
+
+ @computed get _hideKey() {
+ return this._props.hideKey && !this._expanded;
+ }
+
+ @computed get _hideValue() {
+ return this._props.hideValue && !this._props.nodeSelected();
+ }
+
// clicking on the label creates a pivot view collection of all documents
// in the same collection. The pivot field is the fieldKey of this label
- onPointerDownLabelSpan = (e: any) => {
- setupMoveUpEvents(this, e, returnFalse, returnFalse, e => {
+ onPointerDownLabelSpan = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e, returnFalse, returnFalse, moveEv => {
DashFieldViewMenu.createFieldView = this.createPivotForField;
- DashFieldViewMenu.Instance.show(e.clientX, e.clientY + 16, this._fieldKey);
+ DashFieldViewMenu.toggleFieldHide = this.toggleFieldHide;
+ DashFieldViewMenu.toggleValueHide = this.toggleValueHide;
+ DashFieldViewMenu.Instance.show(moveEv.clientX, moveEv.clientY + 16, this._fieldKey);
+ const editor = this._props.tbox.EditorView!;
+ setTimeout(() => editor.dispatch(editor.state.tr.setSelection(new NodeSelection(editor.state.doc.resolve(this._props.getPos())))), 100);
});
};
@undoBatch
selectVal = (event: React.ChangeEvent<HTMLSelectElement> | undefined) => {
- event && this._dashDoc && (this._dashDoc[this._fieldKey] = event.target.value);
+ event && this._dashDoc && (this._dashDoc[this._fieldKey] = event.target.value === '-unset-' ? undefined : event.target.value);
};
@computed get values() {
+ if (this._props.nodeSelected()) return [];
const vals = FilterPanel.gatherFieldValues(DocListCast(Doc.ActiveDashboard?.data), this._fieldKey, []);
return vals.strings.map(facet => ({ value: facet, label: facet }));
@@ -196,21 +257,22 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
render() {
return (
<div
- className="dashFieldView"
+ className={`dashFieldView${this.isRowActive() ? '-active' : ''}`}
ref={this._fieldRef}
style={{
width: this._props.width,
height: this._props.height,
pointerEvents: this._props.tbox._props.rootSelected?.() || this._props.tbox.isAnyChildContentActive?.() ? undefined : 'none',
}}>
- {this._props.hideKey ? null : (
+ {this._hideKey ? null : (
<span className="dashFieldView-labelSpan" title="click to see related tags" onPointerDown={this.onPointerDownLabelSpan}>
- {(this._textBoxDoc === this._dashDoc ? '' : this._dashDoc?.title + ':') + this._fieldKey}
+ {(Doc.AreProtosEqual(DocCast(this._textBoxDoc.rootDocument) ?? this._textBoxDoc, DocCast(this._dashDoc?.rootDocument) ?? this._dashDoc) ? '' : (this._dashDoc?.title ?? '') + ':') + this._fieldKey}
</span>
)}
- {this._props.fieldKey.startsWith('#') ? null : this.fieldValueContent}
+ {this._props.fieldKey.startsWith('#') || this._hideValue ? null : this.fieldValueContent}
{!this.values.length ? null : (
- <select onChange={this.selectVal} style={{ height: '10px', width: '15px', fontSize: '12px', background: 'transparent' }}>
+ <select className="dashFieldView-select" tabIndex={-1} defaultValue={this._dashDoc && Field.toKeyValueString(this._dashDoc, this._fieldKey)} onChange={this.selectVal}>
+ <option value="-unset-">-unset-</option>
{this.values.map(val => (
<option value={val.value}>{val.label}</option>
))}
@@ -220,39 +282,92 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
);
}
}
-@observer
-export class DashFieldViewMenu extends AntimodeMenu<AntimodeMenuProps> {
- static Instance: DashFieldViewMenu;
- static createFieldView: (e: React.MouseEvent) => void = emptyFunction;
- constructor(props: any) {
- super(props);
- DashFieldViewMenu.Instance = this;
- }
-
- showFields = (e: React.MouseEvent) => {
- DashFieldViewMenu.createFieldView(e);
- DashFieldViewMenu.Instance.fadeOut(true);
- };
-
- @observable _fieldKey = '';
+export class DashFieldView {
+ dom: HTMLDivElement; // container for label and value
+ root: any;
+ node: any;
+ tbox: FormattedTextBox;
+ getpos: any;
+ @observable _nodeSelected = false;
+ NodeSelected = () => this._nodeSelected;
- @action
- public show = (x: number, y: number, fieldKey: string) => {
- this._fieldKey = fieldKey;
- this.jumpTo(x, y, true);
- const hideMenu = () => {
- this.fadeOut(true);
- document.removeEventListener('pointerdown', hideMenu, true);
+ 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) {
+ makeObservable(this);
+ this.node = node;
+ this.tbox = tbox;
+ 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.onkeypress = function (e: KeyboardEvent) {
+ e.stopPropagation();
};
- document.addEventListener('pointerdown', hideMenu, true);
- };
- render() {
- return this.getElement(
- <Tooltip key="trash" title={<div className="dash-tooltip">{`Show Pivot Viewer for '${this._fieldKey}'`}</div>}>
- <button className="antimodeMenu-button" onPointerDown={this.showFields}>
- <FontAwesomeIcon icon="eye" size="lg" />
- </button>
- </Tooltip>
+ this.dom.onkeydown = (e: KeyboardEvent) => {
+ e.stopPropagation();
+ if (e.key === 'Tab') {
+ e.preventDefault();
+ const editor = tbox.EditorView;
+ if (editor) {
+ const { state } = editor;
+ for (let i = this.getpos() + 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;
+ }
+ }
+ }
+ }
+ };
+ this.dom.onkeyup = function (e: any) {
+ e.stopPropagation();
+ };
+ this.dom.onmousedown = function (e: any) {
+ e.stopPropagation();
+ };
+
+ this.root = ReactDOM.createRoot(this.dom);
+ this.root.render(
+ <DashFieldViewInternal
+ node={node}
+ unclickable={this.unclickable}
+ getPos={getPos}
+ fieldKey={node.attrs.fieldKey}
+ docId={node.attrs.docId}
+ width={node.attrs.width}
+ height={node.attrs.height}
+ hideKey={node.attrs.hideKey}
+ hideValue={node.attrs.hideValue}
+ editable={node.attrs.editable}
+ nodeSelected={this.NodeSelected}
+ tbox={tbox}
+ />
);
}
+ destroy() {
+ setTimeout(() => {
+ try {
+ this.root.unmount();
+ } catch {
+ /* empty */
+ }
+ });
+ }
+ deselectNode() {
+ runInAction(() => {
+ this._nodeSelected = false;
+ });
+ this.dom.classList.remove('ProseMirror-selectednode');
+ }
+ selectNode() {
+ setTimeout(
+ action(() => {
+ this._nodeSelected = true;
+ }),
+ 100
+ );
+ this.dom.classList.add('ProseMirror-selectednode');
+ }
}
diff --git a/src/client/views/nodes/formattedText/EquationEditor.tsx b/src/client/views/nodes/formattedText/EquationEditor.tsx
index b4102e08e..d9b1a2cf8 100644
--- a/src/client/views/nodes/formattedText/EquationEditor.tsx
+++ b/src/client/views/nodes/formattedText/EquationEditor.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
import React, { Component, createRef } from 'react';
// Import JQuery, required for the functioning of the equation editor
@@ -5,11 +6,9 @@ import $ from 'jquery';
import './EquationEditor.scss';
-// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
window.jQuery = $;
-// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
require('mathquill/build/mathquill');
diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx
index b786c5ffb..5167c8f2a 100644
--- a/src/client/views/nodes/formattedText/EquationView.tsx
+++ b/src/client/views/nodes/formattedText/EquationView.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import { IReactionDisposer } from 'mobx';
import { observer } from 'mobx-react';
import { TextSelection } from 'prosemirror-state';
@@ -8,44 +9,7 @@ import { StrCast } from '../../../../fields/Types';
import './DashFieldView.scss';
import EquationEditor from './EquationEditor';
import { FormattedTextBox } from './FormattedTextBox';
-
-export class EquationView {
- dom: HTMLDivElement; // container for label and value
- root: any;
- tbox: FormattedTextBox;
- view: any;
- constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
- this.tbox = tbox;
- this.view = view;
- 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) {
- e.stopPropagation();
- };
-
- this.root = ReactDOM.createRoot(this.dom);
- this.root.render(<EquationViewInternal fieldKey={node.attrs.fieldKey} width={node.attrs.width} height={node.attrs.height} getPos={getPos} setEditor={this.setEditor} tbox={tbox} />);
- }
- _editor: EquationEditor | undefined;
- setEditor = (editor?: EquationEditor) => (this._editor = editor);
- destroy() {
- this.root.unmount();
- }
- setSelection() {
- this._editor?.mathField.focus();
- }
- selectNode() {
- 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();
- setTimeout(() => (this.tbox._applyingChange = ''));
- });
- }
- deselectNode() {}
-}
+import { DocData } from '../../../../fields/DocSymbols';
interface IEquationViewInternal {
fieldKey: string;
@@ -69,12 +33,12 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal>
this._textBoxDoc = props.tbox.Document;
}
- componentWillUnmount() {
- this._reactionDisposer?.();
- }
componentDidMount() {
this.props.setEditor(this._ref.current ?? undefined);
}
+ componentWillUnmount() {
+ this._reactionDisposer?.();
+ }
render() {
return (
@@ -88,7 +52,6 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal>
}
e.stopPropagation();
}}
- onKeyPress={e => e.stopPropagation()}
style={{
position: 'relative',
display: 'inline-block',
@@ -96,17 +59,60 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal>
height: this.props.height,
background: 'white',
borderRadius: '10%',
- bottom: 3,
}}>
<EquationEditor
ref={this._ref}
- value={StrCast(this._textBoxDoc[this._fieldKey], 'y=')}
- onChange={(str: any) => (this._textBoxDoc[this._fieldKey] = str)}
+ value={StrCast(this._textBoxDoc[DocData][this._fieldKey])}
+ onChange={(str: any) => {
+ this._textBoxDoc[DocData][this._fieldKey] = str;
+ }}
autoCommands="pi theta sqrt sum prod alpha beta gamma rho"
autoOperatorNames="sin cos tan"
- spaceBehavesLikeTab={true}
+ spaceBehavesLikeTab
/>
</div>
);
}
}
+
+export class EquationView {
+ dom: HTMLDivElement; // container for label and value
+ root: any;
+ tbox: FormattedTextBox;
+ view: any;
+ constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
+ this.tbox = tbox;
+ this.view = view;
+ 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) {
+ e.stopPropagation();
+ };
+
+ this.root = ReactDOM.createRoot(this.dom);
+ this.root.render(<EquationViewInternal fieldKey={node.attrs.fieldKey} width={node.attrs.width} height={node.attrs.height} getPos={getPos} setEditor={this.setEditor} tbox={tbox} />);
+ }
+ _editor: EquationEditor | undefined;
+ setEditor = (editor?: EquationEditor) => {
+ this._editor = editor;
+ };
+ destroy() {
+ this.root.unmount();
+ }
+ setSelection() {
+ this._editor?.mathField.focus();
+ }
+ selectNode() {
+ 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();
+ setTimeout(() => {
+ this.tbox._applyingChange = '';
+ });
+ });
+ }
+ deselectNode() {}
+}
diff --git a/src/client/views/nodes/formattedText/FootnoteView.tsx b/src/client/views/nodes/formattedText/FootnoteView.tsx
index cf48e1250..4641da2e9 100644
--- a/src/client/views/nodes/formattedText/FootnoteView.tsx
+++ b/src/client/views/nodes/formattedText/FootnoteView.tsx
@@ -2,9 +2,9 @@ import { EditorView } from 'prosemirror-view';
import { EditorState } from 'prosemirror-state';
import { keymap } from 'prosemirror-keymap';
import { baseKeymap, toggleMark } from 'prosemirror-commands';
-import { schema } from './schema_rts';
import { redo, undo } from 'prosemirror-history';
import { StepMap } from 'prosemirror-transform';
+import { schema } from './schema_rts';
export class FootnoteView {
innerView: any;
@@ -23,6 +23,7 @@ export class FootnoteView {
this.dom = document.createElement('footnote');
this.dom.addEventListener('pointerup', this.toggle, true);
+ this.dom.addEventListener('mouseup', (e: MouseEvent) => e.stopPropagation(), true);
// These are used when the footnote is selected
this.innerView = null;
}
@@ -82,9 +83,10 @@ export class FootnoteView {
document.removeEventListener('pointerup', this.ignore, true);
};
- toggle = () => {
+ toggle = (e: PointerEvent) => {
if (this.innerView) this.close();
else this.open();
+ e.stopPropagation();
};
close() {
@@ -98,8 +100,8 @@ export class FootnoteView {
this.innerView.updateState(state);
if (!tr.getMeta('fromOutside')) {
- const outerTr = this.outerView.state.tr,
- offsetMap = StepMap.offset(this.getPos() + 1);
+ const outerTr = this.outerView.state.tr;
+ const offsetMap = StepMap.offset(this.getPos() + 1);
for (const transaction of transactions) {
for (const step of transaction.steps) {
outerTr.step(step.map(offsetMap));
@@ -113,7 +115,7 @@ export class FootnoteView {
if (!node.sameMarkup(this.node)) return false;
this.node = node;
if (this.innerView) {
- const state = this.innerView.state;
+ const { state } = this.innerView;
const start = node.content.findDiffStart(state.doc.content);
if (start !== null) {
let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 03ff0436b..99b4a84fc 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -273,6 +273,7 @@ footnote::before {
height: 20px;
&::before {
content: '→';
+ cursor: default;
}
&:hover {
background: orange;
@@ -348,6 +349,9 @@ footnote::before {
touch-action: none;
span {
font-family: inherit;
+ // background-color: inherit; // intended to allow texts to inherit background from list container, but this prevents css highlights e.,g highlight text from others
+ display: inline; // needs to be inline for search highlighting to appear
+ // display: contents; // BUT needs to be 'contents' to avoid Chrome bug where extra space is added above and <ol> lists when inside a prosemirror span
}
blockquote {
@@ -397,6 +401,7 @@ footnote::before {
font-family: inherit;
}
margin-left: 0;
+ background-color: inherit;
}
.decimal2-ol {
counter-reset: deci2;
@@ -406,6 +411,7 @@ footnote::before {
}
font-size: smaller;
padding-left: 2.1em;
+ background-color: inherit;
}
.decimal3-ol {
counter-reset: deci3;
@@ -415,6 +421,7 @@ footnote::before {
}
font-size: smaller;
padding-left: 2.85em;
+ background-color: inherit;
}
.decimal4-ol {
counter-reset: deci4;
@@ -424,6 +431,7 @@ footnote::before {
}
font-size: smaller;
padding-left: 3.85em;
+ background-color: inherit;
}
.decimal5-ol {
counter-reset: deci5;
@@ -432,6 +440,7 @@ footnote::before {
font-family: inherit;
}
font-size: smaller;
+ background-color: inherit;
}
.decimal6-ol {
counter-reset: deci6;
@@ -440,6 +449,7 @@ footnote::before {
font-family: inherit;
}
font-size: smaller;
+ background-color: inherit;
}
.decimal7-ol {
counter-reset: deci7;
@@ -448,6 +458,7 @@ footnote::before {
font-family: inherit;
}
font-size: smaller;
+ background-color: inherit;
}
.multi1-ol {
@@ -458,6 +469,7 @@ footnote::before {
}
margin-left: 0;
padding-left: 1.2em;
+ background-color: inherit;
}
.multi2-ol {
counter-reset: multi2;
@@ -467,6 +479,7 @@ footnote::before {
}
font-size: smaller;
padding-left: 2em;
+ background-color: inherit;
}
.multi3-ol {
counter-reset: multi3;
@@ -476,6 +489,7 @@ footnote::before {
}
font-size: smaller;
padding-left: 2.85em;
+ background-color: inherit;
}
.multi4-ol {
counter-reset: multi4;
@@ -485,6 +499,7 @@ footnote::before {
}
font-size: smaller;
padding-left: 3.85em;
+ background-color: inherit;
}
//.bullet:before, .bullet1:before, .bullet2:before, .bullet3:before, .bullet4:before, .bullet5:before { transition: 0.5s; display: inline-block; vertical-align: top; margin-left: -1em; width: 1em; content:" " }
@@ -788,6 +803,7 @@ footnote::before {
height: 20px;
&::before {
content: '→';
+ cursor: default;
}
&:hover {
background: orange;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 3192ac537..542a68c3b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1,3 +1,5 @@
+/* eslint-disable no-use-before-define */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
@@ -8,12 +10,13 @@ import { history } from 'prosemirror-history';
import { inputRules } from 'prosemirror-inputrules';
import { keymap } from 'prosemirror-keymap';
import { Fragment, Mark, Node, Slice } from 'prosemirror-model';
-import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from 'prosemirror-state';
-import { EditorView } from 'prosemirror-view';
+import { EditorState, NodeSelection, Plugin, Selection, TextSelection, Transaction } from 'prosemirror-state';
+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 { DateField } from '../../../../fields/DateField';
-import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../../fields/Doc';
+import { CreateLinkToActiveAudio, Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
@@ -21,44 +24,40 @@ import { List } from '../../../../fields/List';
import { PrefetchProxy } from '../../../../fields/Proxy';
import { RichTextField } from '../../../../fields/RichTextField';
import { ComputedField } from '../../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { BoolCast, Cast, DateCast, DocCast, FieldValue, NumCast, RTFCast, ScriptCast, StrCast } from '../../../../fields/Types';
import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivWidth, emptyFunction, numberRange, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils';
+import { emptyFunction, numberRange, unimplementedFunction, Utils } from '../../../../Utils';
import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT';
import { DocServer } from '../../../DocServer';
-import { Docs, DocUtils } from '../../../documents/Documents';
-import { CollectionViewType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
+import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
+import { DocUtils } from '../../../documents/DocUtils';
import { DictationManager } from '../../../util/DictationManager';
-import { DocumentManager } from '../../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../../util/DragManager';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
import { MakeTemplate } from '../../../util/DropConverter';
import { LinkManager } from '../../../util/LinkManager';
import { RTFMarkup } from '../../../util/RTFMarkup';
-import { SelectionManager } from '../../../util/SelectionManager';
import { SnappingManager } from '../../../util/SnappingManager';
import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager';
-import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView';
import { CollectionStackingView } from '../../collections/CollectionStackingView';
import { CollectionTreeView } from '../../collections/CollectionTreeView';
import { ContextMenu } from '../../ContextMenu';
import { ContextMenuProps } from '../../ContextMenuItem';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
-import { LightboxView } from '../../LightboxView';
import { AnchorMenu } from '../../pdf/AnchorMenu';
import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup';
+import { PinDocView, PinProps } from '../../PinFuncs';
import { SidebarAnnos } from '../../SidebarAnnos';
-import { StyleProp } from '../../StyleProvider';
-import { media_state } from '../AudioBox';
-import { DocumentView, DocumentViewInternal, OpenWhere } from '../DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView';
+import { StyleProp } from '../../StyleProp';
+import { styleFromLayoutString } from '../../StyleProvider';
+import { mediaState } from '../AudioBox';
+import { DocumentView } from '../DocumentView';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import { LinkInfo } from '../LinkDocPreview';
-import { PinProps, PresBox } from '../trails';
-import { DashDocCommentView } from './DashDocCommentView';
-import { DashDocView } from './DashDocView';
-import { DashFieldView } from './DashFieldView';
-import { EquationView } from './EquationView';
-import { FootnoteView } from './FootnoteView';
+import { OpenWhere } from '../OpenWhere';
import './FormattedTextBox.scss';
import { findLinkMark, FormattedTextBoxComment } from './FormattedTextBoxComment';
import { buildKeymap, updateBullets } from './ProsemirrorExampleTransfer';
@@ -66,16 +65,26 @@ import { removeMarkWithAttrs } from './prosemirrorPatches';
import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu';
import { RichTextRules } from './RichTextRules';
import { schema } from './schema_rts';
-import { SummaryView } from './SummaryView';
// import * as applyDevTools from 'prosemirror-dev-tools';
+
+export interface FormattedTextBoxProps extends FieldViewProps {
+ onBlur?: () => void; // callback when text loses focus
+ autoFocus?: boolean; // whether text should get input focus when created
+}
@observer
-export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextBoxProps>() {
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(FormattedTextBox, fieldStr);
}
- public static blankState = () => EditorState.create(FormattedTextBox.Instance.config);
- public static Instance: FormattedTextBox;
- public static LiveTextUndo: UndoManager.Batch | undefined;
+ private static nodeViews: (self: FormattedTextBox) => { [key: string]: NodeViewConstructor };
+ /**
+ * Initialize the class with all the plugin node view components
+ * @param nodeViews prosemirror plugins that render a custom UI for specific node types
+ */
+ public static Init(nodeViews: (self: FormattedTextBox) => { [key: string]: NodeViewConstructor }) {
+ FormattedTextBox.nodeViews = nodeViews;
+ }
+ public static LiveTextUndo: UndoManager.Batch | undefined; // undo batch when typing a new text note into a collection
static _globalHighlightsCache: string = '';
static _globalHighlights = new ObservableSet<string>(['Audio Tags', 'Text from Others', 'Todo Items', 'Important Items', 'Disagree Items', 'Ignore Items']);
static _highlightStyleSheet: any = addStyleSheet();
@@ -86,28 +95,22 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
private _sidebarRef = React.createRef<SidebarAnnos>();
private _sidebarTagRef = React.createRef<React.Component>();
private _ref: React.RefObject<HTMLDivElement> = React.createRef();
- private _scrollRef: React.RefObject<HTMLDivElement> = React.createRef();
+ private _scrollRef: HTMLDivElement | null = null;
private _editorView: Opt<EditorView>;
public _applyingChange: string = '';
private _inDrop = false;
private _finishingLink = false;
private _searchIndex = 0;
- private _lastTimedMark: Mark | undefined = undefined;
private _cachedLinks: Doc[] = [];
private _undoTyping?: UndoManager.Batch;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _dropDisposer?: DragManager.DragDropDisposer;
private _recordingStart: number = 0;
private _ignoreScroll = false;
- private _hadDownFocus = false;
private _focusSpeed: Opt<number>;
private _keymap: any = 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 _forceDownNode: Node | undefined;
- private _downX = 0;
- private _downY = 0;
- private _downTime = 0;
private _break = true;
public ProseRef?: HTMLDivElement;
public get EditorView() {
@@ -148,10 +151,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return this.titleHeight + NumCast(this.layoutDoc._layout_autoHeightMargins);
}
@computed get _recordingDictation() {
- return this.dataDoc?.mediaState === media_state.Recording;
+ return this.dataDoc?.mediaState === mediaState.Recording;
}
set _recordingDictation(value) {
- !this.dataDoc[`${this.fieldKey}_recordingSource`] && (this.dataDoc.mediaState = value ? media_state.Recording : undefined);
+ !this.dataDoc[`${this.fieldKey}_recordingSource`] && (this.dataDoc.mediaState = value ? mediaState.Recording : undefined);
}
@computed get config() {
this._keymap = buildKeymap(schema, this._props);
@@ -166,8 +169,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
keymap(baseKeymap),
new Plugin({ props: { attributes: { class: 'ProseMirror-example-setup-style' } } }),
new Plugin({
- view(editorView) {
- return new FormattedTextBoxComment(editorView);
+ view(/* editorView */) {
+ return new FormattedTextBoxComment();
},
}),
],
@@ -182,31 +185,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined;
public static PasteOnLoad: ClipboardEvent | undefined;
- private static SelectOnLoad: Doc | undefined;
- public static SetSelectOnLoad(doc: Doc) {
- FormattedTextBox.SelectOnLoad = doc;
- }
public static DontSelectInitialText = false; // whether initial text should be selected or not
public static SelectOnLoadChar = '';
- public static IsFragment(html: string) {
- return html.indexOf('data-pm-slice') !== -1;
- }
- public static GetHref(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;
- }
- return '';
- }
- public static GetDocFromUrl(url: string) {
- return url.startsWith(document.location.origin) ? new URL(url).pathname.split('doc/').lastElement() : ''; // docId
- }
- constructor(props: FieldViewProps) {
+ constructor(props: FormattedTextBoxProps) {
super(props);
makeObservable(this);
- FormattedTextBox.Instance = this;
this._recordingStart = Date.now();
}
@@ -216,13 +200,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
public RemoveLinkFromDoc(linkDoc?: Doc) {
this.unhighlightSearchTerms();
const state = this._editorView?.state;
- const a1 = linkDoc?.link_anchor_1 as Doc;
- const a2 = linkDoc?.link_anchor_2 as Doc;
+ const a1 = DocCast(linkDoc?.link_anchor_1);
+ const a2 = DocCast(linkDoc?.link_anchor_2);
if (state && a1 && a2 && this._editorView) {
this.removeDocument(a1);
this.removeDocument(a2);
- var allFoundLinkAnchors: any[] = [];
- state.doc.nodesBetween(0, state.doc.nodeSize - 2, (node: any, pos: number, parent: any) => {
+ let allFoundLinkAnchors: any[] = [];
+ state.doc.nodesBetween(0, state.doc.nodeSize - 2, (node: any /* , pos: number, parent: any */) => {
const foundLinkAnchors = findLinkMark(node.marks)?.attrs.allAnchors.filter((a: any) => a.anchorId === a1[Id] || a.anchorId === a2[Id]) || [];
allFoundLinkAnchors = foundLinkAnchors.length ? foundLinkAnchors : allFoundLinkAnchors;
return true;
@@ -245,25 +229,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
- if (!pinProps && this._editorView?.state.selection.empty) return this.Document;
- const anchor = Docs.Create.ConfigDocument({ title: StrCast(this.Document.title), annotationOn: this.Document });
+ const rootDoc: Doc = Doc.isTemplateDoc(this._props.docViewPath().lastElement()?.Document) ? this.Document : DocCast(this.Document.rootDocument, this.Document);
+ if (!pinProps && this._editorView?.state.selection.empty) return rootDoc;
+ const anchor = Docs.Create.ConfigDocument({ title: StrCast(rootDoc.title), annotationOn: rootDoc });
this.addDocument(anchor);
this._finishingLink = true;
this.makeLinkAnchor(anchor, OpenWhere.addRight, undefined, 'Anchored Selection', false, addAsAnnotation);
this._finishingLink = false;
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true } }, this.Document);
return anchor;
};
@action
setupAnchorMenu = () => {
AnchorMenu.Instance.Status = 'marquee';
-
- AnchorMenu.Instance.OnClick = (e: PointerEvent) => {
+ AnchorMenu.Instance.OnClick = () => {
!this.layoutDoc.layout_showSidebar && this.toggleSidebar();
setTimeout(() => this._sidebarRef.current?.anchorMenuClick(this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', true))); // give time for sidebarRef to be created
};
- AnchorMenu.Instance.OnAudio = (e: PointerEvent) => {
+ AnchorMenu.Instance.OnAudio = () => {
!this.layoutDoc.layout_showSidebar && this.toggleSidebar();
const anchor = this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', true, true);
@@ -273,30 +257,26 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
anchor.followLinkAudio = true;
let stopFunc: any;
const targetData = target[DocData];
- targetData.mediaState = media_state.Recording;
- targetData.audioAnnoState = 'recording';
- DocumentViewInternal.recordAudioAnnotation(targetData, Doc.LayoutFieldKey(target), stop => (stopFunc = stop));
- let reactionDisposer = reaction(
+ targetData.mediaState = mediaState.Recording;
+ DictationManager.recordAudioAnnotation(targetData, Doc.LayoutFieldKey(target), stop => { stopFunc = stop }); // prettier-ignore
+
+ const reactionDisposer = reaction(
() => target.mediaState,
- action(dictation => {
+ dictation => {
if (!dictation) {
- targetData.audioAnnoState = 'stopped';
stopFunc();
reactionDisposer();
}
- })
+ }
);
- target.title = ComputedField.MakeFunction(`self["text_audioAnnotations_text"].lastElement()`);
+ target.title = ComputedField.MakeFunction(`this.text_audioAnnotations_text.lastElement()`);
}
});
};
- AnchorMenu.Instance.Highlight = undoable(
- action((color: string, isLinkButton: boolean) => {
- this._editorView?.state && RichTextMenu.Instance.setHighlight(color);
- return undefined;
- }),
- 'highlght text'
- );
+ AnchorMenu.Instance.Highlight = undoable((color: string) => {
+ this._editorView?.state && RichTextMenu.Instance?.setFontField(color, 'fontHighlight');
+ return undefined;
+ }, 'highlght text');
AnchorMenu.Instance.onMakeAnchor = () => this.getAnchor(true);
AnchorMenu.Instance.StartCropDrag = unimplementedFunction;
/**
@@ -308,15 +288,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
e.stopPropagation();
const targetCreator = (annotationOn?: Doc) => {
const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, annotationOn);
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
return target;
};
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.DocumentView?.()!, () => this.getAnchor(true), targetCreator), e.pageX, e.pageY);
});
+
+ AnchorMenu.Instance.setSelectedText(window.getSelection()?.toString() ?? '');
const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
this._props.rootSelected?.() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom);
- let ele: Opt<HTMLDivElement> = undefined;
+ let ele: Opt<HTMLDivElement>;
try {
const contents = window.getSelection()?.getRangeAt(0).cloneContents();
if (contents) {
@@ -324,18 +306,24 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
ele.append(contents);
}
this._selectionHTML = ele?.innerHTML;
- } catch (e) {}
+ } catch (e) {
+ /* empty */
+ }
};
leafText = (node: Node) => {
if (node.type === this._editorView?.state.schema.nodes.dashField) {
- const refDoc = !node.attrs.docId ? this.Document : (DocServer.GetCachedRefField(node.attrs.docId as string) as Doc);
- return Field.toJavascriptString(refDoc[node.attrs.fieldKey as string] as Field);
+ const refDoc = !node.attrs.docId ? DocCast(this.Document.rootDocument, this.Document) : (DocServer.GetCachedRefField(node.attrs.docId as string) as Doc);
+ const fieldKey = StrCast(node.attrs.fieldKey);
+ return (
+ (node.attrs.hideKey ? '' : fieldKey + ':') + //
+ (node.attrs.hideValue ? '' : Field.toJavascriptString(refDoc[fieldKey] as FieldType))
+ );
}
return '';
};
dispatchTransaction = (tx: Transaction) => {
- if (this._editorView && (this._editorView as any).docView) {
+ if (this._editorView && !this._editorView.isDestroyed) {
const state = this._editorView.state.apply(tx);
this._editorView.updateState(state);
this.tryUpdateDoc(false);
@@ -343,21 +331,21 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
};
tryUpdateDoc = (force: boolean) => {
- if (this._editorView && (this._editorView as any).docView) {
- const state = this._editorView.state;
- const dataDoc = Doc.IsDelegateField(DocCast(this.layoutDoc.proto), this.fieldKey) ? DocCast(this.layoutDoc.proto) : this.dataDoc;
+ if (this._editorView) {
+ const { state } = this._editorView;
+ const { dataDoc } = this;
const newText = state.doc.textBetween(0, state.doc.content.size, ' \n', this.leafText);
const newJson = JSON.stringify(state.toJSON());
const prevData = Cast(this.layoutDoc[this.fieldKey], RichTextField, null); // the actual text in the text box
- const templateData = this.Document !== this.layoutDoc ? prevData : undefined; // the default text stored in a layout template
const protoData = Cast(Cast(dataDoc.proto, Doc, null)?.[this.fieldKey], RichTextField, null); // the default text inherited from a prototype
+ const layoutData = this.layoutDoc.isTemplateDoc ? Cast(this.layoutDoc[this.fieldKey], RichTextField, null) : undefined; // the default text inherited from a prototype
const effectiveAcl = GetEffectiveAcl(dataDoc);
const removeSelection = (json: string | undefined) => json?.replace(/"selection":.*/, '');
if ([AclEdit, AclAdmin, AclSelfEdit, AclAugment].includes(effectiveAcl)) {
const accumTags = [] as string[];
- state.tr.doc.nodesBetween(0, state.doc.content.size, (node: any, pos: number, parent: any) => {
+ state.tr.doc.nodesBetween(0, state.doc.content.size, (node: any /* , pos: number, parent: any */) => {
if (node.type === schema.nodes.dashField && node.attrs.fieldKey.startsWith('#')) {
accumTags.push(node.attrs.fieldKey);
}
@@ -367,25 +355,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
let unchanged = true;
- if (this._applyingChange !== this.fieldKey && (force || removeSelection(newJson) !== removeSelection(prevData?.Data))) {
+ const textChange = newText !== prevData?.Text; // the Text string can change even if the RichText doesn't because dashFieldViews may return new strings as the data they reference changes
+ const rtField = (layoutData !== prevData ? layoutData : undefined) ?? protoData;
+ if (this._applyingChange !== this.fieldKey && (force || textChange || removeSelection(newJson) !== removeSelection(prevData?.Data))) {
this._applyingChange = this.fieldKey;
- const textChange = newText !== prevData?.Text;
textChange && (dataDoc[this.fieldKey + '_modificationDate'] = new DateField(new Date(Date.now())));
- if ((!prevData && !protoData) || newText || (!newText && !protoData)) {
+ if ((!prevData && !protoData && !layoutData) || newText || (!newText && !protoData && !layoutData)) {
// if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended)
- if (force || ((this._finishingLink || this._props.isContentActive() || this._inDrop) && removeSelection(newJson) !== removeSelection(prevData?.Data))) {
+ if (force || ((this._finishingLink || this._props.isContentActive() || this._inDrop) && (textChange || removeSelection(newJson) !== removeSelection(prevData?.Data)))) {
const numstring = NumCast(dataDoc[this.fieldKey], null);
- dataDoc[this.fieldKey] = numstring !== undefined ? Number(newText) : newText ? new RichTextField(newJson, newText) : undefined;
+ dataDoc[this.fieldKey] =
+ numstring !== undefined ? Number(newText) : newText || (DocCast(dataDoc.proto)?.[this.fieldKey] === undefined && this.layoutDoc[this.fieldKey] === undefined) ? new RichTextField(newJson, newText) : undefined;
textChange && ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.Document, text: newText });
this._applyingChange = ''; // turning this off here allows a Doc to retrieve data from template if noTemplate below is changed to false
- dataDoc[this.fieldKey + '_noTemplate'] = newText ? true : false; // mark the data field as being split from the template if it has been edited
unchanged = false;
}
- } else {
+ } else if (rtField) {
// if we've deleted all the text in a note driven by a template, then restore the template data
dataDoc[this.fieldKey] = undefined;
- this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse((protoData || prevData).Data)));
- dataDoc[this.fieldKey + '_noTemplate'] = undefined; // mark the data field as not being split from any template it might have
+ this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse(rtField.Data)));
ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, text: newText });
unchanged = false;
}
@@ -413,37 +401,22 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
insertTime = () => {
let linkTime;
let linkAnchor;
- let link;
- LinkManager.Links(this.dataDoc).forEach((l, i) => {
- const anchor = (l.link_anchor_1 as Doc).annotationOn ? (l.link_anchor_1 as Doc) : (l.link_anchor_2 as Doc).annotationOn ? (l.link_anchor_2 as Doc) : undefined;
- if (anchor && (anchor.annotationOn as Doc).mediaState === media_state.Recording) {
+ Doc.Links(this.dataDoc).forEach(l => {
+ const anchor = DocCast(l.link_anchor_1)?.annotationOn ? DocCast(l.link_anchor_1) : DocCast(l.link_anchor_2)?.annotationOn ? DocCast(l.link_anchor_2) : undefined;
+ if (anchor && (anchor.annotationOn as Doc).mediaState === mediaState.Recording) {
linkTime = NumCast(anchor._timecodeToShow /* audioStart */);
linkAnchor = anchor;
- link = l;
}
});
if (this._editorView && linkTime) {
- const state = this._editorView.state;
- const now = Date.now();
- let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) });
- if (!this._break && state.selection.to !== state.selection.from) {
- for (let i = state.selection.from; i <= state.selection.to; i++) {
- const pos = state.doc.resolve(i);
- const um = Array.from(pos.marks()).find(m => m.type === schema.marks.user_mark);
- if (um) {
- mark = um;
- break;
- }
- }
- }
-
- const path = (this._editorView.state.selection.$from as any).path;
- if (linkAnchor && path[path.length - 3].type !== this._editorView.state.schema.nodes.code_block) {
+ const { state } = this._editorView;
+ const { path } = state.selection.$from as any;
+ if (linkAnchor && path[path.length - 3].type !== state.schema.nodes.code_block) {
const time = linkTime + Date.now() / 1000 - this._recordingStart / 1000;
this._break = false;
- const from = state.selection.from;
- const value = this._editorView.state.schema.nodes.audiotag.create({ timeCode: time, audioId: linkAnchor[Id] });
- const replaced = this._editorView.state.tr.insert(from - 1, value);
+ const { from } = state.selection;
+ const value = state.schema.nodes.audiotag.create({ timeCode: time, audioId: linkAnchor[Id] });
+ const replaced = state.tr.insert(from - 1, value);
this._editorView.dispatch(replaced.setSelection(new TextSelection(replaced.doc.resolve(from + 1))));
}
}
@@ -451,26 +424,33 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
autoLink = () => {
const newAutoLinks = new Set<Doc>();
- const oldAutoLinks = LinkManager.Links(this.Document).filter(link => link.link_relationship === LinkManager.AutoKeywords);
+ const oldAutoLinks = Doc.Links(this.Document).filter(
+ link =>
+ ((!Doc.isTemplateForField(this.Document) &&
+ (!Doc.isTemplateForField(DocCast(link.link_anchor_1)) || !Doc.AreProtosEqual(DocCast(link.link_anchor_1), this.Document)) &&
+ (!Doc.isTemplateForField(DocCast(link.link_anchor_2)) || !Doc.AreProtosEqual(DocCast(link.link_anchor_2), this.Document))) ||
+ (Doc.isTemplateForField(this.Document) && (link.link_anchor_1 === this.Document || link.link_anchor_2 === this.Document))) &&
+ link.link_relationship === LinkManager.AutoKeywords
+ ); // prettier-ignore
if (this._editorView?.state.doc.textContent) {
- const isNodeSel = this._editorView.state.selection instanceof NodeSelection;
- const f = this._editorView.state.selection.from;
- const t = this._editorView.state.selection.to;
- var tr = this._editorView.state.tr as any;
- const autoAnch = this._editorView.state.schema.marks.autoLinkAnchor;
- tr = tr.removeMark(0, tr.doc.content.size, autoAnch);
- Doc.MyPublishedDocs.forEach(term => (tr = this.hyperlinkTerm(tr, term, newAutoLinks)));
- tr = tr.setSelection(isNodeSel && false ? new NodeSelection(tr.doc.resolve(f)) : new TextSelection(tr.doc.resolve(f), tr.doc.resolve(t)));
+ let { tr } = this._editorView.state;
+ const { from, to } = this._editorView.state.selection;
+ const { autoLinkAnchor } = this._editorView.state.schema.marks;
+ tr = tr.removeMark(0, tr.doc.content.size, autoLinkAnchor);
+ Doc.MyPublishedDocs.filter(term => term.title).forEach(term => {
+ tr = this.hyperlinkTerm(tr, term, newAutoLinks);
+ });
+ tr = tr.setSelection(new TextSelection(tr.doc.resolve(from), tr.doc.resolve(to)));
this._editorView?.dispatch(tr);
}
- oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.Document).forEach(LinkManager.Instance.deleteLink);
+ oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.Document).forEach(doc => Doc.DeleteLink?.(doc));
};
updateTitle = () => {
const title = StrCast(this.dataDoc.title, Cast(this.dataDoc.title, RichTextField, null)?.Text);
if (
!this._props.dontRegisterView && // (this.Document.isTemplateForField === "text" || !this.Document.isTemplateForField) && // only update the title if the data document's data field is changing
- (title.startsWith('-') || title.startsWith('@')) &&
+ title.startsWith('-') &&
this._editorView &&
!this.dataDoc.title_custom &&
(Doc.LayoutFieldKey(this.Document) === this.fieldKey || this.fieldKey === 'text')
@@ -478,14 +458,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
let node = this._editorView.state.doc;
while (node.firstChild && node.firstChild.type.name !== 'text') node = node.firstChild;
const str = node.textContent;
- const prefix = str.startsWith('@') ? '' : '-';
+ const prefix = '-';
const cfield = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc.title));
if (!(cfield instanceof ComputedField)) {
this.dataDoc.title = (prefix + str.substring(0, Math.min(40, str.length)) + (str.length > 40 ? '...' : '')).trim();
- if (str.startsWith('@') && str.length > 1) {
- Doc.AddToMyPublished(this.Document);
- }
}
}
};
@@ -499,11 +476,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
* function of a freeform view that is driven by the text box's text. The include directive will copy the code of the published
* document into the code being evaluated.
*/
- hyperlinkTerm = (tr: any, target: Doc, newAutoLinks: Set<Doc>) => {
+ hyperlinkTerm = (trIn: any, target: Doc, newAutoLinks: Set<Doc>) => {
+ let tr = trIn;
const editorView = this._editorView;
- if (editorView && (editorView as any).docView && !Doc.AreProtosEqual(target, this.Document)) {
- const autoLinkTerm = StrCast(target.title).replace(/^@/, '');
- var alink: Doc | undefined;
+ if (editorView && !Doc.AreProtosEqual(target, this.Document)) {
+ const autoLinkTerm = Field.toString(target.title as FieldType).replace(/^@/, '');
+ let alink: Doc | undefined;
this.findInNode(editorView, editorView.state.doc, autoLinkTerm).forEach(sel => {
if (
!sel.$anchor.pos ||
@@ -515,11 +493,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
) {
const splitter = editorView.state.schema.marks.splitter.create({ id: Utils.GenerateGuid() });
tr = tr.addMark(sel.from, sel.to, splitter);
- tr.doc.nodesBetween(sel.from, sel.to, (node: any, pos: number, parent: any) => {
+ tr.doc.nodesBetween(sel.from, sel.to, (node: any, 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 ??
- (LinkManager.Links(this.Document).find(
+ (Doc.Links(this.Document).find(
link =>
Doc.AreProtosEqual(Cast(link.link_anchor_1, Doc, null), this.Document) && //
Doc.AreProtosEqual(Cast(link.link_anchor_2, Doc, null), target)
@@ -546,12 +524,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return true;
};
highlightSearchTerms = (terms: string[], backward: boolean) => {
- if (this._editorView && (this._editorView as any).docView && terms.some(t => t)) {
- const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
- const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
- const res = terms.filter(t => t).map(term => this.findInNode(this._editorView!, this._editorView!.state.doc, term));
- const length = res[0].length;
- let tr = this._editorView.state.tr;
+ const { _editorView } = this;
+ if (_editorView && terms.some(t => t)) {
+ const { state } = _editorView;
+ let { tr } = state;
+ const mark = state.schema.mark(state.schema.marks.search_highlight);
+ const activeMark = state.schema.mark(state.schema.marks.search_highlight, { selected: true });
+ const res = terms.filter(t => t).map(term => this.findInNode(_editorView, state.doc, term));
+ const { length } = res[0];
const flattened: TextSelection[] = [];
res.map(r => r.map(h => flattened.push(h)));
this._searchIndex = ++this._searchIndex > flattened.length - 1 ? 0 : this._searchIndex;
@@ -566,23 +546,27 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
const lastSel = Math.min(flattened.length - 1, this._searchIndex);
- flattened.forEach((h: TextSelection, ind: number) => (tr = tr.addMark(h.from, h.to, ind === lastSel ? activeMark : mark)));
- flattened[lastSel] && this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(flattened[lastSel].from), tr.doc.resolve(flattened[lastSel].to))).scrollIntoView());
+ flattened.forEach((h: TextSelection, ind: number) => {
+ tr = tr.addMark(h.from, h.to, ind === lastSel ? activeMark : mark);
+ });
+ flattened[lastSel] && _editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(flattened[lastSel].from), tr.doc.resolve(flattened[lastSel].to))).scrollIntoView());
}
};
unhighlightSearchTerms = () => {
- if (window.screen.width < 600) null;
- else if (this._editorView && (this._editorView as any).docView) {
- const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
- const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
- const end = this._editorView.state.doc.nodeSize - 2;
- this._editorView.dispatch(this._editorView.state.tr.removeMark(0, end, mark).removeMark(0, end, activeMark));
+ if (this._editorView) {
+ const { state } = this._editorView;
+ if (state) {
+ const mark = state.schema.mark(state.schema.marks.search_highlight);
+ const activeMark = state.schema.mark(state.schema.marks.search_highlight, { selected: true });
+ const end = state.doc.nodeSize - 2;
+ this._editorView.dispatch(state.tr.removeMark(0, end, mark).removeMark(0, end, activeMark));
+ }
}
};
adoptAnnotation = (start: number, end: number, mark: Mark) => {
const view = this._editorView!;
- const nmark = view.state.schema.marks.user_mark.create({ ...mark.attrs, userid: Doc.CurrentUserEmail });
+ const nmark = view.state.schema.marks.user_mark.create({ ...mark.attrs, userid: ClientUtils.CurrentUserEmail() });
view.dispatch(view.state.tr.removeMark(start, end, nmark).addMark(start, end, nmark));
};
protected createDropTarget = (ele: HTMLDivElement) => {
@@ -625,8 +609,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
docId: draggedDoc[Id],
float: 'unset',
});
- if (![dropActionType.embed, dropActionType.copy].includes(dropAction ?? dropActionType.move)) {
- added = dragData.removeDocument?.(draggedDoc) ? true : false;
+ if (!de.embedKey && ![dropActionType.embed, dropActionType.copy].includes(dropAction ?? dropActionType.move)) {
+ added = !!dragData.removeDocument?.(draggedDoc);
} else {
added = true;
}
@@ -638,9 +622,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this._inDrop = true;
const pos = view.posAtCoords({ left: de.x, top: de.y })?.pos;
pos && view.dispatch(view.state.tr.insert(pos, node));
- added = pos ? true : false; // pos will be null if you don't drop onto an actual text location
- } catch (e) {
- console.log('Drop failed', e);
+ added = !!pos; // pos will be null if you don't drop onto an actual text location
+ } catch (err) {
+ console.log('Drop failed', err);
added = false;
} finally {
this._inDrop = false;
@@ -672,29 +656,28 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
offset += (context.content as any).content[i].nodeSize;
}
- return null;
- } else {
- return null;
}
+ return null;
}
- //Recursively finds matches within a given node
+ // Recursively finds matches within a given node
findInNode(pm: EditorView, node: Node, find: string) {
let ret: TextSelection[] = [];
if (node.isTextblock) {
- let index = 0,
- foundAt;
+ let index = 0;
+ let foundAt;
const ep = this.getNodeEndpoints(pm.state.doc, node);
const regexp = new RegExp(find, 'i');
if (regexp) {
- var blockOffset = 0;
- for (var i = 0; i < node.childCount; i++) {
- var textContent = '';
+ let blockOffset = 0;
+ for (let i = 0; i < node.childCount; i++) {
+ let textContent = '';
while (i < node.childCount && node.child(i).type === pm.state.schema.nodes.text) {
textContent += node.child(i).textContent;
i++;
}
+ // eslint-disable-next-line no-cond-assign
while (ep && (foundAt = textContent.slice(index).search(regexp)) > -1) {
const sel = new TextSelection(pm.state.doc.resolve(ep.from + index + blockOffset + foundAt + 1), pm.state.doc.resolve(ep.from + index + blockOffset + foundAt + find.length + 1));
ret.push(sel);
@@ -705,14 +688,18 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
}
} else {
- node.content.forEach((child, i) => (ret = ret.concat(this.findInNode(pm, child, find))));
+ node.content.forEach(child => {
+ ret = ret.concat(this.findInNode(pm, child, find));
+ });
}
return ret;
}
updateHighlights = (highlights: string[]) => {
if (Array.from(highlights).join('') === FormattedTextBox._globalHighlightsCache) return;
- setTimeout(() => (FormattedTextBox._globalHighlightsCache = Array.from(highlights).join('')));
+ setTimeout(() => {
+ FormattedTextBox._globalHighlightsCache = Array.from(highlights).join('');
+ });
clearStyleSheetRules(FormattedTextBox._userStyleSheet);
if (!highlights.includes('Audio Tags')) {
addStyleSheetRule(FormattedTextBox._userStyleSheet, 'audiotag', { display: 'none' }, '');
@@ -721,7 +708,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-remote', { background: 'yellow' });
}
if (highlights.includes('My Text')) {
- addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-' + Doc.CurrentUserEmail.replace(/\./g, '').replace(/@/g, ''), { background: 'moccasin' });
+ addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-' + ClientUtils.CurrentUserEmail().replace(/\./g, '').replace(/@/g, ''), { background: 'moccasin' });
}
if (highlights.includes('Todo Items')) {
addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UT-todo', { outline: 'black solid 1px' });
@@ -740,21 +727,22 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UT-ignore', { 'font-size': '1' });
}
if (highlights.includes('By Recent Minute')) {
- addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-' + Doc.CurrentUserEmail.replace('.', '').replace('@', ''), { opacity: '0.1' });
+ addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-' + ClientUtils.CurrentUserEmail().replace('.', '').replace('@', ''), { opacity: '0.1' });
const min = Math.round(Date.now() / 1000 / 60);
numberRange(10).map(i => addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-min-' + (min - i), { opacity: ((10 - i - 1) / 10).toString() }));
}
if (highlights.includes('By Recent Hour')) {
- addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-' + Doc.CurrentUserEmail.replace('.', '').replace('@', ''), { opacity: '0.1' });
+ addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-' + ClientUtils.CurrentUserEmail().replace('.', '').replace('@', ''), { opacity: '0.1' });
const hr = Math.round(Date.now() / 1000 / 60 / 60);
numberRange(10).map(i => addStyleSheetRule(FormattedTextBox._userStyleSheet, 'UM-hr-' + (hr - i), { opacity: ((10 - i - 1) / 10).toString() }));
}
+ // eslint-disable-next-line operator-assignment
this.layoutDoc[DocCss] = this.layoutDoc[DocCss] + 1; // css changes happen outside of react/mobx. so we need to set a flag that will notify anyone interested in layout changes triggered by css changes (eg., CollectionLinkView)
};
@observable _showSidebar = false;
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false;
+ return !!(this._showSidebar || this.layoutDoc._layout_showSidebar);
}
@action
@@ -776,7 +764,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this,
e,
this.sidebarMove,
- (e, movement, isClick) => !isClick && batch.end(),
+ (moveEv, movement, isClick) => !isClick && batch.end(),
() => {
this.toggleSidebar();
batch.end();
@@ -800,7 +788,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
deleteAnnotation = (anchor: Doc) => {
const batch = UndoManager.StartBatch('delete link');
- LinkManager.Instance.deleteLink(LinkManager.Links(anchor)[0]);
+ Doc.DeleteLink?.(Doc.Links(anchor)[0]);
// const docAnnotations = DocListCast(this._props.dataDoc[this.fieldKey]);
// this._props.dataDoc[this.fieldKey] = new List<Doc>(docAnnotations.filter(a => a !== this.annoTextRegion));
// AnchorMenu.Instance.fadeOut(true);
@@ -812,7 +800,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
pinToPres = (anchor: Doc) => this._props.pinToPres(anchor, {});
@undoBatch
- makeTargetToggle = (anchor: Doc) => (anchor.followLinkToggle = !anchor.followLinkToggle);
+ makeTargetToggle = (anchor: Doc) => {
+ anchor.followLinkToggle = !anchor.followLinkToggle;
+ };
@undoBatch
showTargetTrail = (anchor: Doc) => {
@@ -828,11 +818,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
specificContextMenu = (e: React.MouseEvent): void => {
const cm = ContextMenu.Instance;
- const editor = this._editorView!;
- const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
let target = e.target as any; // hrefs are stored on the database of the <a> node that wraps the hyerlink <span>
while (target && !target.dataset?.targethrefs) target = target.parentElement;
- if (target && !(e.nativeEvent as any).dash) {
+ const editor = this._editorView;
+ if (editor && target && !(e.nativeEvent as any).dash) {
const hrefs = (target.dataset?.targethrefs as string)
?.trim()
.split(' ')
@@ -842,14 +831,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
.replace(Doc.localServerPath(), '')
.split('?')[0];
const deleteMarkups = undoBatch(() => {
- const sel = editor.state.selection;
- editor.dispatch(editor.state.tr.removeMark(sel.from, sel.to, editor.state.schema.marks.linkAnchor));
+ const { selection } = editor.state;
+ editor.dispatch(editor.state.tr.removeMark(selection.from, selection.to, editor.state.schema.marks.linkAnchor));
});
e.persist();
anchorDoc &&
DocServer.GetRefField(anchorDoc).then(
action(anchor => {
- anchor && SelectionManager.SelectSchemaViewDoc(anchor as Doc);
+ anchor && DocumentView.SelectSchemaDoc(anchor as Doc);
AnchorMenu.Instance.Status = 'annotation';
AnchorMenu.Instance.Delete = !anchor && editor.state.selection.empty ? returnFalse : !anchor ? deleteMarkups : () => this.deleteAnnotation(anchor as Doc);
AnchorMenu.Instance.Pinned = false;
@@ -879,7 +868,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
event: undoBatch(() => {
this.dataDoc.layout_meta = Cast(Doc.UserDoc().emptyHeader, Doc, null)?.layout;
this.Document.layout_fieldKey = 'layout_meta';
- setTimeout(() => (this.layoutDoc._headerHeight = this.layoutDoc._layout_autoHeightMargins = 50), 50);
+ setTimeout(() => {
+ this.layoutDoc._header_height = this.layoutDoc._layout_autoHeightMargins = 50;
+ }, 50);
}),
icon: 'eye',
});
@@ -918,12 +909,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
appearanceItems.push({
description: !this.Document._layout_noSidebar ? 'Hide Sidebar Handle' : 'Show Sidebar Handle',
- event: () => (this.layoutDoc._layout_noSidebar = !this.layoutDoc._layout_noSidebar),
+ event: () => {
+ this.layoutDoc._layout_noSidebar = !this.layoutDoc._layout_noSidebar;
+ },
icon: !this.Document._layout_noSidebar ? 'eye-slash' : 'eye',
});
appearanceItems.push({
description: (this.Document._layout_enableAltContentUI ? 'Hide' : 'Show') + ' Alt Content UI',
- event: () => (this.layoutDoc._layout_enableAltContentUI = !this.layoutDoc._layout_enableAltContentUI),
+ event: () => {
+ this.layoutDoc._layout_enableAltContentUI = !this.layoutDoc._layout_enableAltContentUI;
+ },
icon: !this.Document._layout_enableAltContentUI ? 'eye-slash' : 'eye',
});
if (this.Document._layout_enableAltContentUI) {
@@ -939,7 +934,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
!Doc.noviceMode &&
appearanceItems.push({
description: 'Broadcast Message',
- event: () => DocServer.GetRefField('rtfProto').then(proto => proto instanceof Doc && (proto.BROADCAST_MESSAGE = Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text)),
+ event: () =>
+ DocServer.GetRefField('rtfProto').then(proto => {
+ proto instanceof Doc && (proto.BROADCAST_MESSAGE = Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text);
+ }),
icon: 'expand-arrows-alt',
});
@@ -961,46 +959,63 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
const options = cm.findByDescription('Options...');
const optionItems = options && 'subitems' in options ? options.subitems : [];
+ optionItems.push({
+ description: `Toggle auto update from template`,
+ event: () => {
+ this.dataDoc[this.fieldKey + '_autoUpdate'] = !this.dataDoc[this.fieldKey + '_autoUpdate'];
+ },
+ icon: 'star',
+ });
optionItems.push({ description: `Generate Dall-E Image`, event: () => this.generateImage(), icon: 'star' });
- optionItems.push({ description: `Ask GPT-3`, event: () => this.makeAIFlashcards(), icon: 'lightbulb' });
+ optionItems.push({ description: `Make AI Flashcards`, event: () => this.makeAIFlashcards(), icon: 'lightbulb' });
+ optionItems.push({ description: `Ask GPT-3`, event: this.askGPT, icon: 'lightbulb' });
this._props.renderDepth &&
optionItems.push({
description: !this.Document._createDocOnCR ? 'Create New Doc on Carriage Return' : 'Allow Carriage Returns',
- event: () => (this.layoutDoc._createDocOnCR = !this.layoutDoc._createDocOnCR),
+ event: () => {
+ this.layoutDoc._createDocOnCR = !this.layoutDoc._createDocOnCR;
+ },
icon: !this.Document._createDocOnCR ? 'grip-lines' : 'bars',
});
!Doc.noviceMode &&
optionItems.push({
description: `${this.Document._layout_autoHeight ? 'Lock' : 'Auto'} Height`,
- event: () => (this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight),
+ event: () => {
+ this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight;
+ },
icon: this.Document._layout_autoHeight ? 'lock' : 'unlock',
});
- optionItems.push({ description: `show markdown options`, event: RTFMarkup.Instance.open, icon: <BsMarkdownFill /> });
!options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' });
- this._downX = this._downY = Number.NaN;
+ const help = cm.findByDescription('Help...');
+ const helpItems = help && 'subitems' in help ? help.subitems : [];
+ helpItems.push({ description: `show markdown options`, event: () => RTFMarkup.Instance.setOpen(true), icon: <BsMarkdownFill /> });
+ !help && cm.addItem({ description: 'Help...', subitems: helpItems, icon: 'eye' });
};
animateRes = (resIndex: number, newText: string) => {
if (resIndex < newText.length) {
const marks = this._editorView?.state.storedMarks ?? [];
- this._editorView?.dispatch(this._editorView.state.tr.setStoredMarks(marks).insertText(newText[resIndex]).setStoredMarks(marks));
- setTimeout(() => {
- this.animateRes(resIndex + 1, newText);
- }, 20);
+ this._editorView?.dispatch(this._editorView?.state.tr.insertText(newText[resIndex]).setStoredMarks(marks));
+ setTimeout(() => this.animateRes(resIndex + 1, newText), 20);
}
};
askGPT = action(async () => {
try {
- let res = await gptAPICall((this.dataDoc.text as RichTextField)?.Text, GPTCallType.COMPLETION);
+ GPTPopup.Instance.setSidebarId(this.SidebarKey);
+ GPTPopup.Instance.addDoc = this.sidebarAddDocument;
+ const res = await gptAPICall((this.dataDoc.text as RichTextField)?.Text, GPTCallType.COMPLETION);
if (!res) {
- console.error('GPT call failed');
this.animateRes(0, 'Something went wrong.');
- } else {
- this.animateRes(0, res);
+ } else if (this._editorView) {
+ const { dispatch, state } = this._editorView;
+ // for no animation, use: dispatch(state.tr.insertText(res));
+ // for animted response starting at end of text, use:
+ dispatch(state.tr.setSelection(Selection.atEnd(state.doc)));
+ this.animateRes(0, '\n\n' + res);
}
} catch (err) {
- console.error('GPT call failed');
+ console.error(err);
this.animateRes(0, 'Something went wrong.');
}
});
@@ -1015,12 +1030,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
breakupDictation = () => {
if (this._editorView && this._recordingDictation) {
- this.stopDictation(true);
+ this.stopDictation(/* true */);
this._break = true;
- const state = this._editorView.state;
- const to = state.selection.to;
+ const { state } = this._editorView;
+ const { to } = state.selection;
const updated = TextSelection.create(state.doc, to, to);
- this._editorView.dispatch(state.tr.setSelection(updated).insertText('\n', to));
+ this._editorView.dispatch(state.tr.setSelection(updated).insert(to, state.schema.nodes.paragraph.create({})));
if (this._recordingDictation) {
this.recordDictation();
}
@@ -1036,7 +1051,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
});
};
- stopDictation = (abort: boolean) => DictationManager.Controls.stop(!abort);
+ stopDictation = (/* abort: boolean */) => DictationManager.Controls.stop(/* !abort */);
setDictationContent = (value: string) => {
if (this._editorView && this._recordingStart) {
@@ -1045,7 +1060,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
const tanch = Docs.Create.ConfigDocument({ title: 'dictation anchor' });
return this.addDocument(tanch) ? tanch : undefined;
};
- const link = DocUtils.MakeLinkToActiveAudio(textanchorFunc, false).lastElement();
+ const link = CreateLinkToActiveAudio(textanchorFunc, false).lastElement();
if (link) {
link[DocData].isDictation = true;
const audioanchor = Cast(link.link_anchor_2, Doc, null);
@@ -1064,7 +1079,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
}
}
- const from = this._editorView.state.selection.from;
+ const { from } = this._editorView.state.selection;
this._break = false;
const tr = this._editorView.state.tr.insertText(value);
this._editorView.dispatch(tr.setSelection(TextSelection.create(tr.doc, from, tr.doc.content.size)).scrollIntoView());
@@ -1073,23 +1088,24 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
// TODO: nda -- Look at how link anchors are added
makeLinkAnchor(anchorDoc?: Doc, location?: string, targetHref?: string, title?: string, noPreview?: boolean, addAsAnnotation?: boolean) {
- const state = this._editorView?.state;
- if (state) {
+ const { _editorView } = this;
+ if (_editorView) {
+ const { state } = _editorView;
let selectedText = '';
- const sel = state.selection;
+ const { selection } = state;
const splitter = state.schema.marks.splitter.create({ id: Utils.GenerateGuid() });
- let tr = state.tr.addMark(sel.from, sel.to, splitter);
- if (sel.from !== sel.to) {
+ let tr = state.tr.addMark(selection.from, selection.to, splitter);
+ if (selection.from !== selection.to) {
const anchor =
anchorDoc ??
Docs.Create.ConfigDocument({
//
- title: 'text(' + this._editorView?.state.doc.textBetween(sel.from, sel.to) + ')',
+ title: 'text(' + state.doc.textBetween(selection.from, selection.to) + ')',
annotationOn: this.dataDoc,
});
const href = targetHref ?? Doc.localServerPath(anchor);
if (anchor !== anchorDoc && addAsAnnotation) this.addDocument(anchor);
- tr.doc.nodesBetween(sel.from, sel.to, (node: any, pos: number, parent: any) => {
+ tr.doc.nodesBetween(selection.from, selection.to, (node: any, 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 ?? []));
@@ -1099,7 +1115,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
});
this.dataDoc[ForceServerWrite] = this.dataDoc[UpdatingFromServer] = true; // need to allow permissions for adding links to readonly/augment only documents
- this._editorView!.dispatch(tr.removeMark(sel.from, sel.to, splitter));
+ this._editorView!.dispatch(tr.removeMark(selection.from, selection.to, splitter));
this.dataDoc[UpdatingFromServer] = this.dataDoc[ForceServerWrite] = false;
anchor.text = selectedText;
anchor.text_html = this._selectionHTML ?? selectedText;
@@ -1120,15 +1136,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
setTimeout(() => this._sidebarRef?.current?.makeDocUnfiltered(doc));
}
- return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
+ return new Promise<Opt<DocumentView>>(res => {
+ DocumentView.addViewRenderedCb(doc, dv => res(dv));
+ });
};
focus = (textAnchor: Doc, options: FocusViewOptions) => {
const focusSpeed = options.zoomTime ?? 500;
const textAnchorId = textAnchor[Id];
+ let start = 0;
const findAnchorFrag = (frag: Fragment, editor: EditorView) => {
const nodes: Node[] = [];
let hadStart = start !== 0;
frag.forEach((node, index) => {
+ // eslint-disable-next-line no-use-before-define
const examinedNode = findAnchorNode(node, editor);
if (examinedNode?.node && (examinedNode.node.textContent || examinedNode.node.type === this._editorView?.state.schema.nodes.dashDoc || examinedNode.node.type === this._editorView?.state.schema.nodes.audiotag)) {
nodes.push(examinedNode.node);
@@ -1160,7 +1180,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return linkIndex !== -1 && marks[linkIndex].attrs.allAnchors.find((item: { href: string }) => textAnchorId === item.href.replace(/.*\/doc\//, '')) ? { node, start: 0 } : undefined;
};
- let start = 0;
this._didScroll = false; // assume we don't need to scroll. if we do, this will get set to true in handleScrollToSelextion when we dispatch the setSelection below
if (this._editorView && textAnchorId) {
const editor = this._editorView;
@@ -1176,13 +1195,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
editor.dispatch(editor.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(() => (this._focusSpeed = undefined), this._focusSpeed);
+ setTimeout(() => {
+ this._focusSpeed = undefined;
+ }, this._focusSpeed);
setTimeout(() => clearStyleSheetRules(FormattedTextBox._highlightStyleSheet), Math.max(this._focusSpeed || 0, 3000));
return focusSpeed;
- } else {
- return this._props.focus(this.Document, options);
}
+ return this._props.focus(this.Document, options);
}
+ return undefined;
};
// if the scroll height has changed and we're in layout_autoHeight mode, then we need to update the textHeight component of the doc.
@@ -1198,11 +1219,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
componentDidMount() {
!this._props.dontSelectOnLoad && this._props.setContentViewBox?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
- this._cachedLinks = LinkManager.Links(this.Document);
+ this._cachedLinks = Doc.Links(this.Document);
this._disposers.breakupDictation = reaction(() => Doc.RecordingEvent, this.breakupDictation);
this._disposers.layout_autoHeight = reaction(
() => ({ autoHeight: this.layout_autoHeight, fontSize: this.fontSize, css: this.Document[DocCss] }),
- (autoHeight, fontSize) => setTimeout(() => autoHeight && this.tryUpdateScrollHeight())
+ autoHeight => setTimeout(() => autoHeight && this.tryUpdateScrollHeight())
);
this._disposers.highlights = reaction(
() => Array.from(FormattedTextBox._globalHighlights).slice(),
@@ -1211,21 +1232,21 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
);
this._disposers.width = reaction(
() => this._props.PanelWidth(),
- width => this.tryUpdateScrollHeight()
+ () => this.tryUpdateScrollHeight()
);
this._disposers.scrollHeight = reaction(
- () => ({ scrollHeight: this.scrollHeight, layout_autoHeight: this.layout_autoHeight, width: NumCast(this.layoutDoc._width) }),
- ({ width, scrollHeight, layout_autoHeight }) => width && layout_autoHeight && this.resetNativeHeight(scrollHeight),
+ () => ({ scrollHeight: this.scrollHeight, layoutAutoHeight: this.layout_autoHeight, width: NumCast(this.layoutDoc._width) }),
+ ({ width, scrollHeight, layoutAutoHeight }) => width && layoutAutoHeight && this.resetNativeHeight(scrollHeight),
{ fireImmediately: true }
);
this._disposers.componentHeights = reaction(
// set the document height when one of the component heights changes and layout_autoHeight is on
- () => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, layout_autoHeight: this.layout_autoHeight, marginsHeight: this.layout_autoHeightMargins }),
- ({ sidebarHeight, textHeight, layout_autoHeight, marginsHeight }) => {
+ () => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, layoutAutoHeight: this.layout_autoHeight, marginsHeight: this.layout_autoHeightMargins }),
+ ({ sidebarHeight, textHeight, layoutAutoHeight, marginsHeight }) => {
const newHeight = this.contentScaling * (marginsHeight + Math.max(sidebarHeight, textHeight));
if (
(!Array.from(FormattedTextBox._globalHighlights).includes('Bold Text') || this._props.isSelected()) && //
- layout_autoHeight &&
+ layoutAutoHeight &&
newHeight &&
newHeight !== this.layoutDoc.height &&
!this._props.dontRegisterView
@@ -1236,7 +1257,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
{ fireImmediately: !Array.from(FormattedTextBox._globalHighlights).includes('Bold Text') }
);
this._disposers.links = reaction(
- () => LinkManager.Links(this.dataDoc), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks
+ () => Doc.Links(this.dataDoc), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks
newLinks => {
this._cachedLinks.forEach(l => !newLinks.includes(l) && this.RemoveLinkFromDoc(l));
this._cachedLinks = newLinks;
@@ -1244,9 +1265,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
);
this._disposers.editorState = reaction(
() => {
- const dataDoc = Doc.IsDelegateField(DocCast(this.layoutDoc?.proto), this.fieldKey) ? DocCast(this.layoutDoc?.proto) : this?.dataDoc;
- const whichDoc = !this.dataDoc || !this.layoutDoc ? undefined : dataDoc?.[this.fieldKey + '_noTemplate'] || !this.layoutDoc[this.fieldKey] ? dataDoc : this.layoutDoc;
- return !whichDoc ? undefined : { data: Cast(whichDoc[this.fieldKey], RichTextField, null), str: Field.toString(DocCast(whichDoc[this.fieldKey]) ?? StrCast(whichDoc[this.fieldKey])) };
+ const protoData = DocCast(this.dataDoc.proto)?.[this.fieldKey];
+ const dataData = this.dataDoc[this.fieldKey];
+ const layoutData = Doc.AreProtosEqual(this.layoutDoc, this.dataDoc) ? undefined : this.layoutDoc[this.fieldKey];
+ const dataTime = dataData ? DateCast(this.dataDoc[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0 : 0;
+ const layoutTime = layoutData && this.dataDoc[this.fieldKey + '_autoUpdate'] ? DateCast(DocCast(this.layoutDoc)[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0 : 0;
+ const protoTime = protoData && this.dataDoc[this.fieldKey + '_autoUpdate'] ? DateCast(DocCast(this.dataDoc.proto)[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0 : 0;
+ const recentData = dataTime >= 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)) };
},
incomingValue => {
if (this._editorView && this._applyingChange !== this.fieldKey) {
@@ -1256,24 +1283,26 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this._editorView.updateState(EditorState.fromJSON(this.config, updatedState));
this.tryUpdateScrollHeight();
}
- } else if (incomingValue?.str) {
- selectAll(this._editorView.state, tx => this._editorView?.dispatch(tx.insertText(incomingValue.str)));
+ } else if (this._editorView.state.doc.textContent !== incomingValue?.str) {
+ selectAll(this._editorView.state, tx => this._editorView?.dispatch(tx.insertText(incomingValue?.str ?? '')));
}
}
- }
+ },
+ { fireImmediately: true }
);
this._disposers.search = reaction(
() => Doc.IsSearchMatch(this.Document),
search => (search ? this.highlightSearchTerms([Doc.SearchQuery()], search.searchMatch < 0) : this.unhighlightSearchTerms()),
- { fireImmediately: Doc.IsSearchMatchUnmemoized(this.Document) ? true : false }
+ { fireImmediately: !!Doc.IsSearchMatchUnmemoized(this.Document) }
);
this._disposers.selected = reaction(
() => this._props.rootSelected?.(),
action(selected => {
- //selected && setTimeout(() => this.prepareForTyping());
+ this.prepareForTyping();
if (FormattedTextBox._globalHighlights.has('Bold Text')) {
+ // eslint-disable-next-line operator-assignment
this.layoutDoc[DocCss] = this.layoutDoc[DocCss] + 1; // css change happens outside of mobx/react, so this will notify anyone interested in the layout that it has changed
}
if (RichTextMenu.Instance?.view === this._editorView && !selected) {
@@ -1291,41 +1320,33 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this._disposers.record = reaction(
() => this._recordingDictation,
() => {
- this.stopDictation(true);
+ this.stopDictation(/* true */);
this._recordingDictation && this.recordDictation();
},
{ fireImmediately: true }
);
if (this._recordingDictation) setTimeout(this.recordDictation);
}
- var quickScroll: string | undefined = '';
this._disposers.scroll = reaction(
() => NumCast(this.layoutDoc._layout_scrollTop),
pos => {
- if (!this._ignoreScroll && this._scrollRef.current && !this._props.dontSelectOnLoad) {
- const viewTrans = quickScroll ?? StrCast(this.Document._viewTransition);
- const durationMiliStr = viewTrans.match(/([0-9]*)ms/);
- const durationSecStr = viewTrans.match(/([0-9.]*)s/);
- const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0;
- if (duration) {
- this._scrollStopper = smoothScroll(duration, this._scrollRef.current, Math.abs(pos || 0), 'ease', this._scrollStopper);
- } else {
- this._scrollRef.current.scrollTo({ top: pos });
- }
+ if (!this._ignoreScroll && this._scrollRef) {
+ const durationStr = StrCast(this.Document._viewTransition).match(/([0-9]+)(m?)s/);
+ const duration = Number(durationStr?.[1]) * (durationStr?.[2] ? 1 : 1000);
+ this._scrollStopper = smoothScroll(duration || 0, this._scrollRef, Math.abs(pos || 0), 'ease', this._scrollStopper);
}
},
{ fireImmediately: true }
);
- quickScroll = undefined;
this.tryUpdateScrollHeight();
setTimeout(this.tryUpdateScrollHeight, 250);
}
clipboardTextSerializer = (slice: Slice): string => {
- let text = '',
- separated = true;
- const from = 0,
- to = slice.content.size;
+ let text = '';
+ let separated = true;
+ const from = 0;
+ const to = slice.content.size;
slice.content.nodesBetween(
from,
to,
@@ -1345,9 +1366,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return text;
};
- handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => {
+ handlePaste = (view: EditorView, event: Event /* , slice: Slice */): boolean => {
const pdfAnchorId = (event as ClipboardEvent).clipboardData?.getData('dash/pdfAnchor');
- return pdfAnchorId && this.addPdfReference(pdfAnchorId) ? true : false;
+ return !!(pdfAnchorId && this.addPdfReference(pdfAnchorId));
};
addPdfReference = (pdfAnchorId: string) => {
@@ -1356,15 +1377,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
DocServer.GetRefField(pdfAnchorId).then(pdfAnchor => {
if (pdfAnchor instanceof Doc) {
const dashField = view.state.schema.nodes.paragraph.create({}, [
- view.state.schema.nodes.dashField.create({ fieldKey: 'text', docId: pdfAnchor[Id], hideKey: true, editable: false }, undefined, [
+ view.state.schema.nodes.dashField.create({ fieldKey: 'text', docId: pdfAnchor[Id], hideKey: true, hideValue: false, editable: false }, undefined, [
view.state.schema.marks.linkAnchor.create({
allAnchors: [{ href: `/doc/${this.Document[Id]}`, title: this.Document.title, anchorId: `${this.Document[Id]}` }],
- title: `from: ${DocCast(pdfAnchor.embedContainer).title}`,
+ title: StrCast(pdfAnchor.title),
noPreview: true,
- docref: false,
+ docref: true,
+ fontSize: '8px',
}),
- view.state.schema.marks.pFontSize.create({ fontSize: '8px' }),
- view.state.schema.marks.em.create({}),
]),
]);
@@ -1379,7 +1399,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return false;
};
- isActiveTab(el: Element | null | undefined) {
+ isActiveTab(elIn: Element | null | undefined) {
+ let el = elIn;
while (el && el !== document.body) {
if (getComputedStyle(el).display === 'none') return false;
el = el.parentNode as any;
@@ -1391,7 +1412,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
const self = this;
return new Plugin({
view(newView) {
- runInAction(() => self._props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView));
+ runInAction(() => {
+ self._props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView);
+ });
return new RichTextMenuPlugin({ editorProps: this._props });
},
});
@@ -1409,14 +1432,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
handleScrollToSelection: editorView => {
const docPos = editorView.coordsAtPos(editorView.state.selection.to);
const viewRect = self._ref.current!.getBoundingClientRect();
- const scrollRef = self._scrollRef.current;
+ const scrollRef = self._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;
if (this._focusSpeed !== undefined) {
- scrollPos && (this._scrollStopper = smoothScroll(this._focusSpeed, scrollRef, scrollPos, 'ease', this._scrollStopper));
+ setTimeout(() => {
+ scrollPos && (this._scrollStopper = smoothScroll(this._focusSpeed || 0, scrollRef, scrollPos, 'ease', this._scrollStopper));
+ });
} else {
scrollRef.scrollTo({ top: scrollPos });
}
@@ -1425,34 +1450,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return true;
},
dispatchTransaction: this.dispatchTransaction,
- nodeViews: {
- dashComment(node: any, view: any, getPos: any) {
- return new DashDocCommentView(node, view, getPos);
- },
- dashDoc(node: any, view: any, getPos: any) {
- return new DashDocView(node, view, getPos, self);
- },
- dashField(node: any, view: any, getPos: any) {
- return new DashFieldView(node, view, getPos, self);
- },
- equation(node: any, view: any, getPos: any) {
- return new EquationView(node, view, getPos, self);
- },
- summary(node: any, view: any, getPos: any) {
- return new SummaryView(node, view, getPos);
- },
- //ordered_list(node: any, view: any, getPos: any) { return new OrderedListView(); },
- footnote(node: any, view: any, getPos: any) {
- return new FootnoteView(node, view, getPos);
- },
- },
+ nodeViews: FormattedTextBox.nodeViews(this),
clipboardTextSerializer: this.clipboardTextSerializer,
handlePaste: this.handlePaste,
});
const { state, dispatch } = this._editorView;
if (!rtfField) {
const dataDoc = Doc.IsDelegateField(DocCast(this.layoutDoc.proto), this.fieldKey) ? DocCast(this.layoutDoc.proto) : this.dataDoc;
- const startupText = Field.toString(dataDoc[fieldKey] as Field);
+ const startupText = Field.toString(dataDoc[fieldKey] as FieldType);
if (startupText) {
dispatch(state.tr.insertText(startupText));
}
@@ -1466,17 +1471,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
(this._editorView as any).TextView = this;
}
- const selectOnLoad = Doc.AreProtosEqual(this._props.TemplateDataDocument ?? this.Document, FormattedTextBox.SelectOnLoad) && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()));
+ const selectOnLoad = Doc.AreProtosEqual(this._props.TemplateDataDocument ?? this.Document, Doc.SelectOnLoad) && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.()));
const selLoadChar = FormattedTextBox.SelectOnLoadChar;
if (selectOnLoad) {
- FormattedTextBox.SelectOnLoad = undefined;
+ Doc.SetSelectOnLoad(undefined);
FormattedTextBox.SelectOnLoadChar = '';
}
if (this._editorView && selectOnLoad && !this._props.dontRegisterView && !this._props.dontSelectOnLoad && this.isActiveTab(this.ProseRef)) {
this._props.select(false);
if (selLoadChar) {
const $from = this._editorView.state.selection.anchor ? this._editorView.state.doc.resolve(this._editorView.state.selection.anchor - 1) : undefined;
- const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) });
+ const mark = schema.marks.user_mark.create({ userid: ClientUtils.CurrentUserEmail(), modified: Math.floor(Date.now() / 1000) });
const curMarks = this._editorView.state.storedMarks ?? $from?.marksAcross(this._editorView.state.selection.$head) ?? [];
const storedMarks = [...curMarks.filter(m => m.type !== mark.type), mark];
const tr1 = this._editorView.state.tr.setStoredMarks(storedMarks);
@@ -1484,8 +1489,21 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
const tr = tr2.setStoredMarks(storedMarks);
this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(tr.doc.content.size))));
- } else if (curText && !FormattedTextBox.DontSelectInitialText) {
- selectAll(this._editorView.state, this._editorView?.dispatch);
+ 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 if (!FormattedTextBox.DontSelectInitialText) {
+ const mark = schema.marks.user_mark.create({ userid: ClientUtils.CurrentUserEmail(), modified: Math.floor(Date.now() / 1000) });
+ selectAll(this._editorView.state, (tx: Transaction) => {
+ this._editorView?.dispatch(tx.deleteSelection().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 {
+ const $from = this._editorView.state.selection.anchor ? this._editorView.state.doc.resolve(this._editorView.state.selection.anchor - 1) : undefined;
+ const mark = schema.marks.user_mark.create({ userid: ClientUtils.CurrentUserEmail(), modified: Math.floor(Date.now() / 1000) });
+ const curMarks = this._editorView.state.storedMarks ?? $from?.marksAcross(this._editorView.state.selection.$head) ?? [];
+ const storedMarks = [...curMarks.filter(m => m.type !== mark.type), mark];
+ const { tr } = this._editorView.state;
+ this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(tr.doc.content.size))).setStoredMarks(storedMarks));
+ 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
}
}
if (selectOnLoad) {
@@ -1498,21 +1516,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
FormattedTextBox.PasteOnLoad = undefined;
pdfAnchorId && this.addPdfReference(pdfAnchorId);
}
+ if (this._props.autoFocus) setTimeout(() => this._editorView!.focus()); // not sure why setTimeout is needed but editing dashFieldView's doesn't work without it.
}
// add user mark for any first character that was typed since the user mark that gets set in KeyPress won't have been called yet.
prepareForTyping = () => {
- if (!this._editorView) return;
- const docDefaultMarks = [
- ...(Doc.UserDoc().fontColor !== 'transparent' && Doc.UserDoc().fontColor ? [schema.mark(schema.marks.pFontColor, { color: StrCast(Doc.UserDoc().fontColor) })] : []),
- ...(Doc.UserDoc().fontStyle === 'italics' ? [schema.mark(schema.marks.em)] : []),
- ...(Doc.UserDoc().textDecoration === 'underline' ? [schema.mark(schema.marks.underline)] : []),
- ...(Doc.UserDoc().fontFamily ? [schema.mark(schema.marks.pFontFamily, { family: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily) })] : []),
- ...(Doc.UserDoc().fontSize ? [schema.mark(schema.marks.pFontSize, { fontSize: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize) })] : []),
- ...(Doc.UserDoc().fontWeight === 'bold' ? [schema.mark(schema.marks.strong)] : []),
- ...[schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })],
- ];
- this._editorView?.dispatch(this._editorView?.state.tr.setStoredMarks(docDefaultMarks));
+ if (this._editorView) {
+ const { text, paragraph } = schema.nodes;
+ const selNode = this._editorView.state.selection.$anchor.node();
+ if (this._editorView.state.selection.from === 1 && this._editorView.state.selection.empty && [undefined, text, paragraph].includes(selNode?.type)) {
+ const docDefaultMarks = [schema.marks.user_mark.create({ userid: ClientUtils.CurrentUserEmail(), modified: Math.floor(Date.now() / 1000) })];
+ this._editorView.state.selection.empty && this._editorView.state.selection.from === 1 && this._editorView?.dispatch(this._editorView?.state.tr.setStoredMarks(docDefaultMarks).removeStoredMark(schema.marks.pFontColor));
+ }
+ }
};
componentWillUnmount() {
@@ -1531,8 +1547,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
onPointerDown = (e: React.PointerEvent): void => {
if ((e.nativeEvent as any).handledByInnerReactInstance) {
- return; //e.stopPropagation();
- } else (e.nativeEvent as any).handledByInnerReactInstance = true;
+ 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.
@@ -1545,7 +1562,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
// const timecode = NumCast(anchor.timecodeToShow, 0);
const audiodoc = anchor.annotationOn as Doc;
const func = () => {
- const docView = DocumentManager.Instance.getDocumentView(audiodoc);
+ const docView = DocumentView.getDocumentView(audiodoc);
if (!docView) {
this._props.addDocTab(audiodoc, OpenWhere.addBottom);
setTimeout(func);
@@ -1558,9 +1575,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (this._recordingDictation && !e.ctrlKey && e.button === 0) {
this.breakupDictation();
}
- this._downX = e.clientX;
- this._downY = e.clientY;
- this._downTime = Date.now();
FormattedTextBoxComment.textBox = this;
if (e.button === 0 && this._props.rootSelected?.() && !e.altKey && !e.ctrlKey && !e.metaKey) {
if (e.clientX < this.ProseRef!.getBoundingClientRect().right) {
@@ -1570,32 +1584,23 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
(this.ProseRef?.children?.[0] as any).focus();
}
}
- this._hadDownFocus = this.ProseRef?.children[0].className.includes('focused') ?? false;
if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
e.preventDefault();
}
};
- onSelectEnd = (e: PointerEvent) => {
+ onSelectEnd = () => {
+ GPTPopup.Instance.setSidebarId(this.SidebarKey);
+ GPTPopup.Instance.addDoc = this.sidebarAddDocument;
document.removeEventListener('pointerup', this.onSelectEnd);
};
onPointerUp = (e: React.PointerEvent): void => {
- const editor = this._editorView!;
- const state = editor?.state;
- if (!Utils.isClick(e.clientX, e.clientY, this._downX, this._downY, this._downTime) && !this._hadDownFocus) {
- (this.ProseRef?.children[0] as HTMLElement)?.blur?.();
- }
- if (!state || !editor || !this.ProseRef?.children[0].className.includes('-focused')) return;
- if (!state.selection.empty && !(state.selection instanceof NodeSelection)) this.setupAnchorMenu();
- else if (this._props.isContentActive() && !e.button) {
- const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
- let xpos = pcords?.pos || 0;
- while (xpos > 0 && !state.doc.resolve(xpos).node()?.isTextblock) {
- xpos = xpos - 1;
- }
- editor.dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(xpos))));
- let target = e.target as any; // hrefs are stored on the dataset of the <a> node that wraps the hyerlink <span>
- while (target && !target.dataset?.targethrefs) target = target.parentElement;
- FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc, target?.dataset.nopreview === 'true');
+ const state = this.EditorView?.state;
+ if (state && this.ProseRef?.children[0].className.includes('-focused') && this._props.isContentActive() && !e.button) {
+ if (!state.selection.empty && !(state.selection instanceof NodeSelection)) this.setupAnchorMenu();
+ let clickTarget = e.target as any; // hrefs are stored on the dataset of the <a> node that wraps the hyerlink <span>
+ 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');
}
};
@action
@@ -1616,14 +1621,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
e.stopPropagation();
}
};
- setFocus = () => {
- const pos = this._editorView?.state.selection.$from.pos || 1;
- (this.ProseRef?.children?.[0] as any).focus();
- setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos))));
+ setFocus = (ipos?: number) => {
+ 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);
};
@action
onFocused = (e: React.FocusEvent): void => {
- //applyDevTools.applyDevTools(this._editorView);
+ // 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();
};
@@ -1634,10 +1639,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
e.stopPropagation();
return;
}
- if (Math.abs(e.clientX - this._downX) > 4 || Math.abs(e.clientY - this._downY) > 4) {
- this._forceDownNode = undefined;
- return;
- }
if (!this._forceUncollapse || (this._editorView!.root as any).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 });
@@ -1661,20 +1662,20 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (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, this._forceDownNode, e.shiftKey);
+ this.hitBulletTargets(e.clientX, e.clientY, !this._editorView?.state.selection.empty || this._forceUncollapse, false, e.shiftKey);
}
this._forceUncollapse = !(this._editorView!.root as any).getSelection().isCollapsed;
- this._forceDownNode = (this._editorView!.state.selection as NodeSelection)?.node;
};
// 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, downNode: Node | undefined = undefined, selectOrderedList: boolean = false) {
+ hitBulletTargets(x: number, y: number, collapse: boolean, highlightOnly: boolean, selectOrderedList: boolean = false) {
this._forceUncollapse = false;
clearStyleSheetRules(FormattedTextBox._bulletStyleSheet);
const clickPos = this._editorView!.posAtCoords({ left: x, top: y });
- let olistPos = clickPos?.pos;
+ const clickPosVal = clickPos?.pos || 1;
+ let olistPos = clickPosVal;
if (clickPos && olistPos && this._props.rootSelected?.()) {
- const clickNode = this._editorView?.state.doc.nodeAt(olistPos);
- const nodeBef = this._editorView?.state.doc.nodeAt(Math.max(0, olistPos - 1));
+ const clickNode = this._editorView?.state.doc.resolve(olistPos).node();
+ const nodeBef = this._editorView?.state.doc.resolve(Math.max(0, olistPos - 1)).node();
olistPos = nodeBef?.type === this._editorView?.state.schema.nodes.ordered_list ? olistPos - 1 : olistPos;
let $olistPos = this._editorView?.state.doc.resolve(olistPos);
let olistNode = (nodeBef !== null || clickNode?.type === this._editorView?.state.schema.nodes.list_item) && olistPos === clickPos?.pos ? clickNode : nodeBef;
@@ -1684,18 +1685,22 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
$olistPos = this._editorView?.state.doc.resolve(($olistPos as any).path[($olistPos as any).path.length - 4]);
}
}
- const listPos = this._editorView?.state.doc.resolve(clickPos.pos);
- const listNode = this._editorView?.state.doc.nodeAt(clickPos.pos);
+ const maxSize = this._editorView?.state.doc.content.size ?? 0;
+ const listPos = this._editorView?.state.doc.resolve(Math.min(maxSize, clickPosVal === olistPos ? clickPosVal + 1 : clickPosVal));
+ const listNode = listPos?.node();
if (olistNode && olistNode.type === this._editorView?.state.schema.nodes.ordered_list && listNode) {
if (!highlightOnly) {
if (selectOrderedList) {
this._editorView.dispatch(this._editorView.state.tr.setSelection(new NodeSelection(selectOrderedList ? $olistPos! : listPos!)));
} else {
- const tr = this._editorView.state.tr.setNodeMarkup(clickPos.pos, listNode.type, { ...listNode.attrs, visibility: !listNode.attrs.visibility });
- this._editorView.dispatch(tr.setSelection(TextSelection.create(tr.doc, clickPos.pos)));
+ const nodePos = clickPosVal - (olistPos === clickPosVal ? 0 : 1);
+ if (this._editorView.state.doc.nodeAt(nodePos)) {
+ const tr = this._editorView.state.tr.setNodeMarkup(nodePos, listNode.type, { ...listNode.attrs, visibility: !listNode.attrs.visibility });
+ this._editorView.dispatch(tr.setSelection(TextSelection.create(tr.doc, nodePos)));
+ }
}
}
- addStyleSheetRule(FormattedTextBox._bulletStyleSheet, olistNode.attrs.mapStyle + olistNode.attrs.bulletStyle + ':hover:before', { background: 'lightgray' });
+ addStyleSheetRule(FormattedTextBox._bulletStyleSheet, olistNode.attrs.mapStyle + olistNode.attrs.bulletStyle + ':hover:before', { background: 'gray' });
}
}
}
@@ -1712,57 +1717,61 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
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();
- this.autoLink();
- if (this._editorView?.state.tr) {
- const tr = stordMarks?.reduce((tr, m) => {
- tr.addStoredMark(m);
- return tr;
- }, this._editorView.state.tr);
- tr && this._editorView.dispatch(tr);
+ if (!(this.EditorView?.state.selection instanceof NodeSelection)) {
+ this.autoLink();
+ if (this._editorView?.state.tr) {
+ const tr = stordMarks?.reduce((tr2, m) => {
+ tr2.addStoredMark(m);
+ return tr2;
+ }, this._editorView.state.tr);
+ tr && this._editorView.dispatch(tr);
+ }
}
}
if (RichTextMenu.Instance?.view === this._editorView && !this._props.rootSelected?.()) {
RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, undefined);
}
FormattedTextBox._hadSelection = window.getSelection()?.toString() !== '';
+
+ // this is the markdown for @<published name> document publishing to Doc.myPublishedDocs
+ const match = RTFCast(this.Document[this.fieldKey])?.Text.match(/^(@[a-zA-Z][a-zA-Z_0-9 -]*[a-zA-Z_0-9-]+)/);
+ if (match) {
+ this.dataDoc.title_custom = true;
+ // eslint-disable-next-line prefer-destructuring
+ this.dataDoc.title = match[1]; // this triggers the collectionDockingView to publish this Doc
+ this.EditorView?.dispatch(this.EditorView?.state.tr.deleteRange(0, match[1].length + 1));
+ }
+
this.endUndoTypingBatch();
FormattedTextBox.LiveTextUndo?.end();
FormattedTextBox.LiveTextUndo = undefined;
- const state = this._editorView!.state;
- if (StrCast(this.Document.title).startsWith('@') && !this.dataDoc.title_custom) {
- UndoManager.RunInBatch(() => {
- this.dataDoc.title_custom = true;
- this.dataDoc.layout_showTitle = 'title';
- const tr = this._editorView!.state.tr;
- this._editorView?.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(0), tr.doc.resolve(StrCast(this.Document.title).length + 2))).deleteSelection());
- }, 'titler');
- }
+ // if the text box blurs and none of its contents are focused(), then pass the blur along
+ setTimeout(() => !this.ProseRef?.contains(document.activeElement) && this._props.onBlur?.());
};
onKeyDown = (e: React.KeyboardEvent) => {
+ const { _editorView } = this;
+ if (!_editorView) return;
if ((e.altKey || e.ctrlKey) && e.key === 't') {
- e.preventDefault();
- e.stopPropagation();
this._props.setTitleFocus?.();
+ StopEvent(e);
return;
}
- const state = this._editorView!.state;
+ const { state } = _editorView;
if (!state.selection.empty && e.key === '%') {
this._rules!.EnteringStyle = true;
- e.preventDefault();
- e.stopPropagation();
+ StopEvent(e);
return;
}
if (state.selection.empty || !this._rules!.EnteringStyle) {
this._rules!.EnteringStyle = false;
}
- let stopPropagation = true;
- for (var i = state.selection.from; i <= state.selection.to; i++) {
+ for (let i = state.selection.from; i <= state.selection.to; i++) {
const node = state.doc.resolve(i);
- if (state.doc.content.size - 1 > i && node?.marks?.().some(mark => mark.type === schema.marks.user_mark && mark.attrs.userid !== Doc.CurrentUserEmail) && [AclAugment, AclSelfEdit].includes(GetEffectiveAcl(this.Document))) {
+ if (state.doc.content.size - 1 > i && node?.marks?.().some(mark => mark.type === schema.marks.user_mark && mark.attrs.userid !== ClientUtils.CurrentUserEmail()) && [AclAugment, AclSelfEdit].includes(GetEffectiveAcl(this.Document))) {
e.preventDefault();
}
}
@@ -1770,27 +1779,27 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
case 'Escape':
this._editorView!.dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from)));
(document.activeElement as any).blur?.();
- SelectionManager.DeselectAll();
- RichTextMenu.Instance.updateMenu(undefined, undefined, undefined, undefined);
+ DocumentView.DeselectAll();
+ RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, undefined);
return;
case 'Enter':
this.insertTime();
+ // eslint-disable-next-line no-fallthrough
case 'Tab':
e.preventDefault();
break;
- case 'c':
- this._editorView?.state.selection.empty && (stopPropagation = false);
+ case 'Space':
+ case 'Backspace':
break;
default:
- if (this._lastTimedMark?.attrs.userid === Doc.CurrentUserEmail) break;
- case ' ':
- if (e.code !== 'Space') {
- [AclEdit, AclAugment, AclAdmin].includes(GetEffectiveAcl(this.Document)) &&
- this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark).addStoredMark(schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })));
+ if ([AclEdit, AclAugment, AclAdmin].includes(GetEffectiveAcl(this.Document))) {
+ const modified = Math.floor(Date.now() / 1000);
+ const mark = state.selection.$to.marks().find(m => m.type === schema.marks.user_mark && m.attrs.modified === modified);
+ _editorView.dispatch(state.tr.removeStoredMark(schema.marks.user_mark).addStoredMark(mark ?? schema.marks.user_mark.create({ userid: ClientUtils.CurrentUserEmail(), modified })));
}
break;
}
- if (stopPropagation) e.stopPropagation();
+ e.stopPropagation();
this.startUndoTypingBatch();
};
ondrop = (e: React.DragEvent) => {
@@ -1798,30 +1807,33 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
e.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash.
};
onScroll = (e: React.UIEvent) => {
- if (!LinkInfo.Instance?.LinkInfo && this._scrollRef.current) {
- if (!this._props.dontSelectOnLoad) {
- this._ignoreScroll = true;
- this.layoutDoc._layout_scrollTop = this._scrollRef.current.scrollTop;
- this._ignoreScroll = false;
- e.stopPropagation();
- e.preventDefault();
- }
+ if (!LinkInfo.Instance?.LinkInfo && this._scrollRef) {
+ this._ignoreScroll = true;
+ this.layoutDoc._layout_scrollTop = this._scrollRef.scrollTop;
+ this._ignoreScroll = false;
+ e.stopPropagation();
+ e.preventDefault();
}
};
tryUpdateScrollHeight = () => {
const margins = 2 * NumCast(this.layoutDoc._yMargin, this._props.yPadding || 0);
const children = this.ProseRef?.children.length ? Array.from(this.ProseRef.children[0].children) : undefined;
if (children && !SnappingManager.IsDragging) {
- const toNum = (val: string) => Number(val.replace('px', '').replace('auto', '0'));
- const toHgt = (node: Element) => {
+ // eslint-disable-next-line no-use-before-define
+ const getChildrenHeights = (kids: Element[] | undefined) => kids?.reduce((p, child) => p + toHgt(child), margins) ?? 0;
+ const toNum = (val: string) => Number(val.replace('px', ''));
+ const toHgt = (node: Element): number => {
const { height, marginTop, marginBottom } = getComputedStyle(node);
- return toNum(height) + Math.max(0, toNum(marginTop)) + Math.max(0, toNum(marginBottom));
+ const childHeight = height === 'auto' ? getChildrenHeights(Array.from(node.children)) : toNum(height);
+ return childHeight + Math.max(0, toNum(marginTop)) + Math.max(0, toNum(marginBottom));
};
- const proseHeight = !this.ProseRef ? 0 : children.reduce((p, child) => p + toHgt(child), margins);
+ const proseHeight = !this.ProseRef ? 0 : getChildrenHeights(children);
const scrollHeight = this.ProseRef && proseHeight;
- if (this._props.setHeight && scrollHeight && !this._props.dontRegisterView) {
+ if (this._props.setHeight && !this._props.suppressSetHeight && scrollHeight && !this._props.dontRegisterView) {
// if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
- const setScrollHeight = () => (this.dataDoc[this.fieldKey + '_scrollHeight'] = scrollHeight);
+ const setScrollHeight = () => {
+ this.dataDoc[this.fieldKey + '_scrollHeight'] = scrollHeight;
+ };
if (this.Document === this.layoutDoc || this.layoutDoc.resolvedDataDoc) {
setScrollHeight();
@@ -1839,7 +1851,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
};
sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.SidebarKey);
sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.SidebarKey);
- setSidebarHeight = (height: number) => (this.dataDoc[this.SidebarKey + '_height'] = height);
+ setSidebarHeight = (height: number) => {
+ this.dataDoc[this.SidebarKey + '_height'] = height;
+ };
sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this._props.PanelWidth();
sidebarScreenToLocal = () =>
this._props
@@ -1857,10 +1871,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
e,
returnFalse,
emptyFunction,
- action(e => (this._recordingDictation = !this._recordingDictation))
+ action(() => {
+ this._recordingDictation = !this._recordingDictation;
+ })
)
}>
- <FontAwesomeIcon className="formattedTextBox-audioFont" style={{ color: 'red' }} icon={'microphone'} size="sm" />
+ <FontAwesomeIcon className="formattedTextBox-audioFont" style={{ color: 'red' }} icon="microphone" size="sm" />
</div>
);
}
@@ -1885,15 +1901,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
@computed get sidebarCollection() {
const renderComponent = (tag: string) => {
- const ComponentTag: any = tag === CollectionViewType.Freeform ? CollectionFreeFormView : tag === CollectionViewType.Tree ? CollectionTreeView : tag === 'translation' ? FormattedTextBox : CollectionStackingView;
+ const ComponentTag: any = tag === CollectionViewType.Tree ? CollectionTreeView : tag === 'translation' ? FormattedTextBox : CollectionStackingView;
return ComponentTag === CollectionStackingView ? (
<SidebarAnnos
ref={this._sidebarRef}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
Document={this.Document}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
- usePanelWidth={true}
+ usePanelWidth
nativeWidth={NumCast(this.layoutDoc._nativeWidth)}
showSidebar={this.SidebarShown}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
@@ -1906,8 +1923,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
setHeight={this.setSidebarHeight}
/>
) : (
- <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.DocumentView?.()!, false), true)}>
+ <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => DocumentView.SelectView(this.DocumentView?.()!, false), true)}>
<ComponentTag
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
ref={this._sidebarTagRef as any}
setContentView={emptyFunction}
@@ -1930,8 +1948,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
renderDepth={this._props.renderDepth + 1}
setHeight={this.setSidebarHeight}
fitContentsToBox={this.fitContentsToBox}
- noSidebar={true}
- treeViewHideTitle={true}
+ noSidebar
+ treeViewHideTitle
fieldKey={this.layoutDoc[this.SidebarKey + '_type_collection'] === 'translation' ? `${this.fieldKey}_translation` : `${this.fieldKey}_sidebar`}
/>
</div>
@@ -1949,6 +1967,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this.layoutDoc[`_${this._props.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : undefined;
}
};
+ // cycleAlternateText = (skipHover?: boolean) => {
+ // this.layoutDoc._layout_enableAltContentUI = true;
+ // const usePath = this.layoutDoc[`_${this._props.fieldKey}_usePath`];
+ // this.layoutDoc[`_${this._props.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' && !skipHover ? 'alternate:hover' : undefined;
+ // };
@computed get overlayAlternateIcon() {
const usePath = this.layoutDoc[`_${this._props.fieldKey}_usePath`];
return (
@@ -1973,7 +1996,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}>
<div
className="formattedTextBox-alternateButton"
- onPointerDown={e => setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, e => this.cycleAlternateText())}
+ onPointerDown={e => setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, () => this.cycleAlternateText())}
style={{
display: this._props.isContentActive() && !SnappingManager.IsDragging ? 'flex' : 'none',
background: usePath === undefined ? 'white' : usePath === 'alternate' ? 'black' : 'gray',
@@ -1985,28 +2008,26 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
);
}
get fieldKey() {
- const usePath = StrCast(this.layoutDoc[`${this._props.fieldKey}_usePath`]);
- return this._props.fieldKey + (usePath && (!usePath.includes(':hover') || this._isHovering || this._props.isContentActive()) ? `_${usePath.replace(':hover', '')}` : '');
+ return this._fieldKey;
+ }
+ @computed get _fieldKey() {
+ const usePath = this._props.ignoreUsePath ? '' : StrCast(this.layoutDoc[`${this._props.fieldKey}_usePath`]);
+ return this._props.fieldKey + (usePath && (!usePath.includes(':hover') || this._props.isHovering?.() || this._props.isContentActive()) ? `_${usePath.replace(':hover', '')}` : '');
}
- @observable _isHovering = false;
onPassiveWheel = (e: WheelEvent) => {
if (e.clientX > this.ProseRef!.getBoundingClientRect().right) {
- if (this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform) {
- // if the scrolled freeform is a child of the sidebar component, we need to let the event go through
- // so react can let the freeform view handle it. We prevent default to stop any containing views from scrolling
- e.preventDefault();
- }
return;
}
// if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this)
if (this._props.isContentActive()) {
const scale = this._props.NativeDimScaling?.() || 1;
- const styleFromLayoutString = Doc.styleFromLayoutString(this.Document, this._props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._headerHeight}px' >
- const height = Number(styleFromLayoutString.height?.replace('px', ''));
+ const styleFromLayout = styleFromLayoutString(this.Document, this._props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._header_height}px' >
+ const height = Number(styleFromLayout.height?.replace('px', ''));
// prevent default if selected || child is active but this doc isn't scrollable
if (
- (this._scrollRef.current?.scrollHeight ?? 0) <= Math.ceil((height ? height : this._props.PanelHeight()) / scale) && //
+ !isNaN(height) &&
+ (this._scrollRef?.scrollHeight ?? 0) <= Math.ceil((height || this._props.PanelHeight()) / scale) && //
(this._props.rootSelected?.() || this.isAnyChildContentActive())
) {
e.preventDefault();
@@ -2016,7 +2037,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
};
_oldWheel: any;
@computed get fontColor() {
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
+ return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontColor);
}
@computed get fontSize() {
return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize);
@@ -2029,17 +2050,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
render() {
TraceMobx();
- const scale = this._props.NativeDimScaling?.() || 1; // * NumCast(this.layoutDoc._freeform_scale, 1);
+ const scale = this._props.NativeDimScaling?.() || 1;
const rounded = StrCast(this.layoutDoc.layout_borderRounding) === '100%' ? '-rounded' : '';
setTimeout(() => !this._props.isContentActive() && FormattedTextBoxComment.textBox === this && FormattedTextBoxComment.Hide);
const paddingX = NumCast(this.layoutDoc._xMargin, this._props.xPadding || 0);
const paddingY = NumCast(this.layoutDoc._yMargin, this._props.yPadding || 0);
- const styleFromLayoutString = Doc.styleFromLayoutString(this.Document, this._props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._headerHeight}px' >
- return styleFromLayoutString?.height === '0px' ? null : (
+ const styleFromLayout = styleFromLayoutString(this.Document, this._props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._header_height}px' >
+ return styleFromLayout?.height === '0px' ? null : (
<div
className="formattedTextBox"
- onPointerEnter={action(() => (this._isHovering = true))}
- onPointerLeave={action(() => (this._isHovering = false))}
ref={r => {
this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel);
this._oldWheel = r;
@@ -2059,7 +2078,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
fontSize: this.fontSize,
fontFamily: this.fontFamily,
fontWeight: this.fontWeight,
- ...styleFromLayoutString,
+ ...styleFromLayout,
}}>
<div
className="formattedTextBox-cont"
@@ -2068,7 +2087,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
cursor: this._props.isContentActive() ? 'text' : undefined,
height: this._props.height ? 'max-content' : undefined,
overflow: this.layout_autoHeight ? 'hidden' : undefined,
- pointerEvents: Doc.ActiveTool === InkTool.None && !this._props.onBrowseClickScript?.() ? undefined : 'none',
+ pointerEvents: Doc.ActiveTool === InkTool.None && !SnappingManager.ExploreMode ? undefined : 'none',
}}
onContextMenu={this.specificContextMenu}
onKeyDown={this.onKeyDown}
@@ -2081,9 +2100,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
onDoubleClick={this.onDoubleClick}>
<div
className="formattedTextBox-outer"
- ref={this._scrollRef}
+ ref={r => {
+ this._scrollRef = r;
+ }}
style={{
- width: this._props.dontSelectOnLoad || this.noSidebar ? '100%' : `calc(100% - ${this.layout_sidebarWidthPercent})`,
+ width: this.noSidebar ? '100%' : `calc(100% - ${this.layout_sidebarWidthPercent})`,
overflow: this.layoutDoc._createDocOnCR ? 'hidden' : this.layoutDoc._layout_autoHeight ? 'visible' : undefined,
}}
onScroll={this.onScroll}
@@ -2100,8 +2121,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}}
/>
</div>
- {this.noSidebar || this._props.dontSelectOnLoad || !this.SidebarShown || this.layout_sidebarWidthPercent === '0%' ? null : this.sidebarCollection}
- {this.noSidebar || this.Document._layout_noSidebar || this._props.dontSelectOnLoad || this.Document._createDocOnCR || this.layoutDoc._chromeHidden ? null : this.sidebarHandle}
+ {this.noSidebar || !this.SidebarShown || this.layout_sidebarWidthPercent === '0%' ? null : this.sidebarCollection}
+ {this.noSidebar || this.Document._layout_noSidebar || this.Document._createDocOnCR || this.layoutDoc._chromeHidden ? null : this.sidebarHandle}
{this.audioHandle}
{this.layoutDoc._layout_enableAltContentUI && !this.layoutDoc._chromeHidden ? this.overlayAlternateIcon : null}
</div>
@@ -2109,3 +2130,18 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.RTF, {
+ layout: { view: FormattedTextBox, dataField: 'text' },
+ options: {
+ acl: '',
+ _height: 35,
+ _xMargin: 10,
+ _yMargin: 10,
+ _layout_nativeDimEditable: true,
+ _layout_reflowVertical: true,
+ _layout_reflowHorizontal: true,
+ defaultDoubleClick: 'ignore',
+ systemIcon: 'BsFileEarmarkTextFill',
+ },
+});
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index ce17af6ca..01c46edeb 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -1,15 +1,16 @@
import { Mark, ResolvedPos } from 'prosemirror-model';
-import { EditorState, NodeSelection } from 'prosemirror-state';
+import { EditorState } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
+import { ClientUtils } from '../../../../ClientUtils';
import { Doc } from '../../../../fields/Doc';
import { DocServer } from '../../../DocServer';
-import { LinkDocPreview, LinkInfo } from '../LinkDocPreview';
+import { LinkInfo } from '../LinkDocPreview';
import { FormattedTextBox } from './FormattedTextBox';
import './FormattedTextBoxComment.scss';
import { schema } from './schema_rts';
export function findOtherUserMark(marks: readonly Mark[]): Mark | undefined {
- return marks.find(m => m.attrs.userid && m.attrs.userid !== Doc.CurrentUserEmail);
+ return marks.find(m => m.attrs.userid && m.attrs.userid !== ClientUtils.CurrentUserEmail());
}
export function findUserMark(marks: readonly Mark[]): Mark | undefined {
return marks.find(m => m.attrs.userid);
@@ -18,20 +19,22 @@ export function findLinkMark(marks: readonly Mark[]): Mark | undefined {
return marks.find(m => m.type === schema.marks.autoLinkAnchor || m.type === schema.marks.linkAnchor);
}
export function findStartOfMark(rpos: ResolvedPos, view: EditorView, finder: (marks: readonly Mark[]) => Mark | undefined) {
- let before = 0,
- nbef = rpos.nodeBefore;
+ let before = 0;
+ let nbef = rpos.nodeBefore;
while (nbef && finder(nbef.marks)) {
before += nbef.nodeSize;
+ // eslint-disable-next-line no-param-reassign
rpos = view.state.doc.resolve(rpos.pos - nbef.nodeSize);
rpos && (nbef = rpos.nodeBefore);
}
return before;
}
export function findEndOfMark(rpos: ResolvedPos, view: EditorView, finder: (marks: readonly Mark[]) => Mark | undefined) {
- let after = 0,
- naft = rpos.nodeAfter;
+ let after = 0;
+ let naft = rpos.nodeAfter;
while (naft && finder(naft.marks)) {
after += naft.nodeSize;
+ // eslint-disable-next-line no-param-reassign
rpos = view.state.doc.resolve(rpos.pos + naft.nodeSize);
rpos && (naft = rpos.nodeAfter);
}
@@ -49,7 +52,7 @@ export class FormattedTextBoxComment {
static userMark: Mark;
static textBox: FormattedTextBox | undefined;
- constructor(view: any) {
+ constructor() {
if (!FormattedTextBoxComment.tooltip) {
const tooltip = (FormattedTextBoxComment.tooltip = document.createElement('div'));
const tooltipText = (FormattedTextBoxComment.tooltipText = document.createElement('div'));
@@ -79,10 +82,10 @@ export class FormattedTextBoxComment {
}
static showCommentbox(view: EditorView, nbef: number) {
- const state = view.state;
+ const { state } = view;
// These are in screen coordinates
- const start = view.coordsAtPos(state.selection.from - nbef),
- end = view.coordsAtPos(state.selection.from - nbef);
+ const start = view.coordsAtPos(state.selection.from - nbef);
+ const end = view.coordsAtPos(state.selection.from - nbef);
// The box in which the tooltip is positioned, to use as base
const box = (document.getElementsByClassName('mainView-container') as any)[0].getBoundingClientRect();
// Find a center-ish x position from the selection endpoints (when crossing lines, end may be more to the left)
@@ -109,14 +112,16 @@ export class FormattedTextBoxComment {
}
static setupPreview(view: EditorView, textBox: FormattedTextBox, hrefs?: string[], linkDoc?: string, noPreview?: boolean) {
- const state = view.state;
+ const { state } = view;
// this section checks to see if the insertion point is over text entered by a different user. If so, it sets ths comment text to indicate the user and the modification date
if (state.selection.$from) {
const nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark);
const naft = findEndOfMark(state.selection.$from, view, findOtherUserMark);
const noselection = state.selection.$from === state.selection.$to;
let child: any = null;
- state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
+ state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any /* , pos: number, parent: any */) => {
+ !child && node.marks.length && (child = node);
+ });
const mark = child && findOtherUserMark(child.marks);
if (mark && child && (nbef || naft) && (!mark.attrs.opened || noselection)) {
FormattedTextBoxComment.saveMarkRegion(textBox, state.selection.$from.pos - nbef, state.selection.$from.pos + naft, mark);
@@ -131,7 +136,7 @@ export class FormattedTextBoxComment {
if (state.selection.$from && hrefs?.length) {
const nbef = findStartOfMark(state.selection.$from, view, findLinkMark);
const naft = findEndOfMark(state.selection.$from, view, findLinkMark) || nbef;
- //nbef &&
+ // nbef &&
naft &&
LinkInfo.SetLinkInfo({
DocumentView: textBox.DocumentView,
diff --git a/src/client/views/nodes/formattedText/OrderedListView.tsx b/src/client/views/nodes/formattedText/OrderedListView.tsx
index c3595e59b..dbc60f7bf 100644
--- a/src/client/views/nodes/formattedText/OrderedListView.tsx
+++ b/src/client/views/nodes/formattedText/OrderedListView.tsx
@@ -1,8 +1,7 @@
export class OrderedListView {
-
- update(node: any) {
- // if attr's of an ordered_list (e.g., bulletStyle) change,
+ update() {
+ // if attr's of an ordered_list (e.g., bulletStyle) change,
// return false forces the dom node to be recreated which is necessary for the bullet labels to update
- return false;
+ return false;
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts
index 30da91710..8799964b3 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 clamp from '../../../util/clamp';
import convertToCSSPTValue from '../../../util/convertToCSSPTValue';
import toCSSLineSpacing from '../../../util/toCSSLineSpacing';
-import { Node, DOMOutputSpec } from 'prosemirror-model';
-//import type { NodeSpec } from './Types';
+// import type { NodeSpec } from './Types';
type NodeSpec = {
- attrs?: { [key: string]: any },
- content?: string,
- draggable?: boolean,
- group?: string,
- inline?: boolean,
- name?: string,
- parseDOM?: Array<any>,
- toDOM?: (node: any) => DOMOutputSpec,
+ attrs?: { [key: string]: any };
+ content?: string;
+ draggable?: boolean;
+ group?: string;
+ inline?: boolean;
+ name?: string;
+ parseDOM?: Array<any>;
+ toDOM?: (node: any) => DOMOutputSpec;
};
// This assumes that every 36pt maps to one indent level.
@@ -25,41 +25,18 @@ export const EMPTY_CSS_VALUE = new Set(['', '0%', '0pt', '0px']);
const ALIGN_PATTERN = /(left|right|center|justify)/;
-// https://github.com/ProseMirror/prosemirror-schema-basic/blob/master/src/schema-basic.js
-// :: NodeSpec A plain paragraph textblock. Represented in the DOM
-// as a `<p>` element.
-export const ParagraphNodeSpec: NodeSpec = {
- attrs: {
- align: { default: null },
- color: { default: null },
- id: { default: null },
- indent: { default: null },
- inset: { default: null },
- lineSpacing: { default: null },
- // TODO: Add UI to let user edit / clear padding.
- paddingBottom: { default: null },
- // TODO: Add UI to let user edit / clear padding.
- paddingTop: { default: null },
- },
- content: 'inline*',
- group: 'block',
- parseDOM: [{ tag: 'p', getAttrs }],
- toDOM,
-};
+function convertMarginLeftToIndentValue(marginLeft: string): number {
+ const ptValue = convertToCSSPTValue(marginLeft);
+ return clamp(MIN_INDENT_LEVEL, Math.floor(ptValue / INDENT_MARGIN_PT_SIZE), MAX_INDENT_LEVEL);
+}
function getAttrs(dom: HTMLElement): Object {
- const {
- lineHeight,
- textAlign,
- marginLeft,
- paddingTop,
- paddingBottom,
- } = dom.style;
+ const { lineHeight, textAlign, marginLeft, paddingTop, paddingBottom } = dom.style;
let align = dom.getAttribute('align') || textAlign || '';
- align = ALIGN_PATTERN.test(align) ? align : "";
+ align = ALIGN_PATTERN.test(align) ? align : '';
- let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT) || "", 10);
+ let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT) || '', 10);
if (!indent && marginLeft) {
indent = convertMarginLeftToIndentValue(marginLeft);
@@ -74,15 +51,7 @@ function getAttrs(dom: HTMLElement): Object {
}
function toDOM(node: Node): DOMOutputSpec {
- const {
- align,
- indent,
- inset,
- lineSpacing,
- paddingTop,
- paddingBottom,
- id,
- } = node.attrs;
+ const { align, indent, inset, lineSpacing, paddingTop, paddingBottom, id } = node.attrs;
const attrs: { [key: string]: any } | null = {};
let style = '';
@@ -128,16 +97,29 @@ function toDOM(node: Node): DOMOutputSpec {
return ['p', attrs, 0];
}
+// https://github.com/ProseMirror/prosemirror-schema-basic/blob/master/src/schema-basic.js
+// :: NodeSpec A plain paragraph textblock. Represented in the DOM
+// as a `<p>` element.
+export const ParagraphNodeSpec: NodeSpec = {
+ attrs: {
+ align: { default: null },
+ color: { default: null },
+ id: { default: null },
+ indent: { default: null },
+ inset: { default: null },
+ lineSpacing: { default: null },
+ // TODO: Add UI to let user edit / clear padding.
+ paddingBottom: { default: null },
+ // TODO: Add UI to let user edit / clear padding.
+ paddingTop: { default: null },
+ },
+ content: 'inline*',
+ group: 'block',
+ parseDOM: [{ tag: 'p', getAttrs }],
+ toDOM,
+};
+
export const toParagraphDOM = toDOM;
export const getParagraphNodeAttrs = getAttrs;
-export function convertMarginLeftToIndentValue(marginLeft: string): number {
- const ptValue = convertToCSSPTValue(marginLeft);
- return clamp(
- MIN_INDENT_LEVEL,
- Math.floor(ptValue / INDENT_MARGIN_PT_SIZE),
- MAX_INDENT_LEVEL
- );
-}
-
-export default ParagraphNodeSpec; \ No newline at end of file
+export default ParagraphNodeSpec;
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index 47527847b..7a8b72be0 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -1,29 +1,29 @@
import { chainCommands, deleteSelection, exitCode, joinBackward, joinDown, joinUp, lift, newlineInCode, selectNodeBackward, setBlockType, splitBlockKeepMarks, toggleMark, wrapIn } from 'prosemirror-commands';
import { redo, undo } from 'prosemirror-history';
import { Schema } from 'prosemirror-model';
-import { splitListItem, wrapInList } from 'prosemirror-schema-list';
+import { liftListItem, sinkListItem, splitListItem, wrapInList } from 'prosemirror-schema-list';
import { EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state';
import { liftTarget } from 'prosemirror-transform';
-import { AclAdmin, AclAugment, AclEdit } from '../../../../fields/DocSymbols';
-import { GetEffectiveAcl } from '../../../../fields/util';
+import { EditorView } from 'prosemirror-view';
+import { ClientUtils } from '../../../../ClientUtils';
import { Utils } from '../../../../Utils';
+import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../../fields/DocSymbols';
+import { GetEffectiveAcl } from '../../../../fields/util';
import { Docs } from '../../../documents/Documents';
import { RTFMarkup } from '../../../util/RTFMarkup';
-import { SelectionManager } from '../../../util/SelectionManager';
-import { OpenWhere } from '../DocumentView';
-import { liftListItem, sinkListItem } from './prosemirrorPatches.js';
-import { Doc } from '../../../../fields/Doc';
+import { DocumentView } from '../DocumentView';
+import { OpenWhere } from '../OpenWhere';
const mac = typeof navigator !== 'undefined' ? /Mac/.test(navigator.platform) : false;
export type KeyMap = { [key: string]: any };
-export let updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle?: string, from?: number, to?: number) => {
+export const updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle?: string, from?: number, to?: number) => {
let mapStyle = assignedMapStyle;
- tx2.doc.descendants((node: any, offset: any, index: any) => {
+ tx2.doc.descendants((node: any, offset: any /* , index: any */) => {
if ((from === undefined || to === undefined || (from <= offset + node.nodeSize && to >= offset)) && (node.type === schema.nodes.ordered_list || node.type === schema.nodes.list_item)) {
- const path = (tx2.doc.resolve(offset) as any).path;
- let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty('type') && c.type === schema.nodes.ordered_list ? 1 : 0), 0);
+ const { path } = tx2.doc.resolve(offset) as any;
+ let depth = Array.from(path).reduce((p: number, c: any) => p + (c.type === schema.nodes.ordered_list ? 1 : 0), 0);
if (node.type === schema.nodes.ordered_list) {
if (depth === 0 && !assignedMapStyle) mapStyle = node.attrs.mapStyle;
depth++;
@@ -34,38 +34,44 @@ export let updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle?:
return tx2;
};
-export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKeys?: KeyMap): KeyMap {
+export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMap {
const keys: { [key: string]: any } = {};
function bind(key: string, cmd: any) {
- if (mapKeys) {
- const mapped = mapKeys[key];
- if (mapped === false) return;
- if (mapped) key = mapped;
- }
keys[key] = cmd;
}
+ function onKey(): boolean | undefined {
+ // bcz: this is pretty hacky -- prosemirror doesn't send us the keyboard event, but the 'event' variable is in scope.. so we access it anyway
+ // eslint-disable-next-line no-restricted-globals
+ return props.onKey?.(event, props);
+ }
+
const canEdit = (state: any) => {
- switch (GetEffectiveAcl(props.TemplateDataDocument)) {
+ const permissions = GetEffectiveAcl(props.TemplateDataDocument ?? props.Document[DocData]);
+ switch (permissions) {
case AclAugment:
- const prevNode = state.selection.$cursor.nodeBefore;
- const prevUser = !prevNode ? Doc.CurrentUserEmail : prevNode.marks[prevNode.marks.length - 1].attrs.userid;
- if (prevUser != Doc.CurrentUserEmail) {
- return false;
+ {
+ const prevNode = state.selection.$cursor.nodeBefore;
+ const prevUser = !prevNode ? ClientUtils.CurrentUserEmail() : prevNode.marks.lastElement()?.attrs.userid;
+ if (prevUser !== ClientUtils.CurrentUserEmail()) {
+ return false;
+ }
}
+ break;
+ default:
}
return true;
};
const toggleEditableMark = (mark: any) => (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && toggleMark(mark)(state, dispatch);
- //History commands
+ // History commands
bind('Mod-z', undo);
bind('Shift-Mod-z', redo);
!mac && bind('Mod-y', redo);
- //Commands to modify Mark
+ // Commands to modify Mark
bind('Mod-b', toggleEditableMark(schema.marks.strong));
bind('Mod-B', toggleEditableMark(schema.marks.strong));
@@ -77,19 +83,19 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
bind('Mod-u', toggleEditableMark(schema.marks.underline));
bind('Mod-U', toggleEditableMark(schema.marks.underline));
- //Commands for lists
+ // Commands for lists
bind('Ctrl-i', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state as any, dispatch as any));
- bind('Ctrl-Tab', () => (props.onKey?.(event, props) ? true : true));
- bind('Alt-Tab', () => (props.onKey?.(event, props) ? true : true));
- bind('Meta-Tab', () => (props.onKey?.(event, props) ? true : true));
- bind('Meta-Enter', () => (props.onKey?.(event, props) ? true : true));
+ bind('Ctrl-Tab', () => onKey() || true);
+ bind('Alt-Tab', () => onKey() || true);
+ bind('Meta-Tab', () => onKey() || true);
+ bind('Meta-Enter', () => onKey() || true);
bind('Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => {
- if (props.onKey?.(event, props)) return true;
+ if (onKey()) return true;
if (!canEdit(state)) return true;
const ref = state.selection;
const range = ref.$from.blockRange(ref.$to);
- const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
+ const marks = state.storedMarks || state.selection.$to.parentOffset ? state.selection.$from.marks() : undefined;
if (
!sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
const tx3 = updateBullets(tx2, schema);
@@ -102,25 +108,29 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
const newstate = state.applyTransaction(state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end)));
if (
!wrapInList(schema.nodes.ordered_list)(newstate.state as any, (tx2: Transaction) => {
- const tx3 = updateBullets(tx2, schema);
+ const tx25 = updateBullets(tx2, schema);
+ const olNode = tx25.doc.nodeAt(range!.start)!;
+ const tx3 = tx25.setNodeMarkup(range!.start, olNode.type, olNode.attrs, marks);
// when promoting to a list, assume list will format things so don't copy the stored marks.
marks && tx3.ensureMarks([...marks]);
marks && tx3.setStoredMarks([...marks]);
- dispatch(tx3);
+ const tx4 = tx3.setSelection(TextSelection.near(tx3.doc.resolve(state.selection.to + 2)));
+ dispatch(tx4);
})
) {
console.log('bullet promote fail');
}
}
+ return undefined;
});
bind('Shift-Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => {
- if (props.onKey?.(event, props)) return true;
+ if (onKey()) return true;
if (!canEdit(state)) return true;
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
if (
- !liftListItem(schema.nodes.list_item)(state.tr, (tx2: Transaction) => {
+ !liftListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
const tx3 = updateBullets(tx2, schema);
marks && tx3.ensureMarks([...marks]);
marks && tx3.setStoredMarks([...marks]);
@@ -129,15 +139,16 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
) {
console.log('bullet demote fail');
}
+ return undefined;
});
- //Command to create a new Tab with a PDF of all the command shortcuts
- bind('Mod-/', (state: EditorState, dispatch: (tx: Transaction) => void) => {
- const newDoc = Docs.Create.PdfDocument(Utils.prepend('/assets/cheat-sheet.pdf'), { _width: 300, _height: 300 });
+ // Command to create a new Tab with a PDF of all the command shortcuts
+ bind('Mod-/', () => {
+ const newDoc = Docs.Create.PdfDocument(ClientUtils.prepend('/assets/cheat-sheet.pdf'), { _width: 300, _height: 300 });
props.addDocTab(newDoc, OpenWhere.addRight);
});
- //Commands to modify BlockType
+ // Commands to modify BlockType
bind('Ctrl->', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state && wrapIn(schema.nodes.blockquote)(state as any, dispatch as any)));
bind('Alt-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state as any, dispatch as any));
bind('Shift-Ctrl-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.code_block)(state as any, dispatch as any));
@@ -153,31 +164,25 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
bind('Shift-Ctrl-' + i, (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state as any, dispatch as any));
}
- //Command to create a horizontal break line
+ // Command to create a horizontal break line
const hr = schema.nodes.horizontal_rule;
bind('Mod-_', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()));
- //Command to unselect all
+ // Command to unselect all
bind('Escape', (state: EditorState, dispatch: (tx: Transaction) => void) => {
dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from)));
(document.activeElement as any).blur?.();
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
});
- const splitMetadata = (marks: any, tx: Transaction) => {
- marks && tx.ensureMarks(marks.filter((val: any) => val.type !== schema.marks.metadata && val.type !== schema.marks.metadataKey && val.type !== schema.marks.metadataVal));
- marks && tx.setStoredMarks(marks.filter((val: any) => val.type !== schema.marks.metadata && val.type !== schema.marks.metadataKey && val.type !== schema.marks.metadataVal));
- return tx;
- };
-
- bind('Alt-Enter', () => (props.onKey?.(event, props) ? true : true));
- bind('Ctrl-Enter', () => (props.onKey?.(event, props) ? true : true));
+ bind('Alt-Enter', () => onKey() || true);
+ bind('Ctrl-Enter', () => onKey() || true);
bind('Cmd-a', (state: EditorState, dispatch: (tx: Transaction) => void) => {
dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1))));
return true;
});
- bind('Cmd-?', (state: EditorState, dispatch: (tx: Transaction) => void) => {
- RTFMarkup.Instance.open();
+ bind('Cmd-?', () => {
+ RTFMarkup.Instance.setOpen(true);
return true;
});
bind('Cmd-e', (state: EditorState, dispatch: (tx: Transaction) => void) => {
@@ -192,14 +197,14 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
});
bind('Cmd-]', (state: EditorState, dispatch: (tx: Transaction) => void) => {
const resolved = state.doc.resolve(state.selection.from) as any;
- const tr = state.tr;
+ const { tr } = state;
if (resolved?.parent.type.name === 'paragraph') {
tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks);
} else {
const node = resolved.nodeAfter;
const sm = state.storedMarks || undefined;
if (node) {
- tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'right' })).setStoredMarks([...node.marks, ...(sm ? sm : [])]);
+ tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'right' })).setStoredMarks([...node.marks, ...(sm || [])]);
}
}
dispatch(tr);
@@ -207,14 +212,14 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
});
bind('Cmd-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => {
const resolved = state.doc.resolve(state.selection.from) as any;
- const tr = state.tr;
+ const { tr } = state;
if (resolved?.parent.type.name === 'paragraph') {
tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks);
} else {
const node = resolved.nodeAfter;
const sm = state.storedMarks || undefined;
if (node) {
- tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'center' })).setStoredMarks([...node.marks, ...(sm ? sm : [])]);
+ tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'center' })).setStoredMarks([...node.marks, ...(sm || [])]);
}
}
dispatch(tr);
@@ -222,14 +227,14 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
});
bind('Cmd-[', (state: EditorState, dispatch: (tx: Transaction) => void) => {
const resolved = state.doc.resolve(state.selection.from) as any;
- const tr = state.tr;
+ const { tr } = state;
if (resolved?.parent.type.name === 'paragraph') {
tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks);
} else {
const node = resolved.nodeAfter;
const sm = state.storedMarks || undefined;
if (node) {
- tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'left' })).setStoredMarks([...node.marks, ...(sm ? sm : [])]);
+ tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'left' })).setStoredMarks([...node.marks, ...(sm || [])]);
}
}
dispatch(tr);
@@ -239,7 +244,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
bind('Cmd-f', (state: EditorState, dispatch: (tx: Transaction) => void) => {
const content = state.tr.selection.empty ? undefined : state.tr.selection.content().content.textBetween(0, state.tr.selection.content().size + 1);
const newNode = schema.nodes.footnote.create({}, content ? state.schema.text(content) : undefined);
- const tr = state.tr;
+ const { tr } = state;
tr.replaceSelectionWith(newNode); // replace insertion with a footnote.
dispatch(
tr.setSelection(
@@ -260,8 +265,8 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
});
// backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward);
- bind('Backspace', (state: EditorState, dispatch: (tx: Transaction) => void) => {
- if (props.onKey?.(event, props)) return true;
+ const backspace = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView) => {
+ if (onKey()) return true;
if (!canEdit(state)) return true;
if (
@@ -272,6 +277,10 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
if (
!joinBackward(state, (tx: Transaction) => {
dispatch(updateBullets(tx, schema));
+ if (view.state.selection.$anchor.node(-1)?.type === schema.nodes.list_item) {
+ // gets rid of an extra paragraph when joining two list items together.
+ joinBackward(view.state, (tx2: Transaction) => view.dispatch(tx2));
+ }
})
) {
if (
@@ -284,59 +293,81 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
}
}
return true;
- });
+ };
+ bind('Backspace', backspace);
- //newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock
- //command to break line
- bind('Enter', (state: EditorState, dispatch: (tx: Transaction) => void) => {
- if (props.onKey?.(event, props)) return true;
+ // newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock
+ // command to break line
+
+ const enter = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView, once = true) => {
+ if (onKey()) return true;
if (!canEdit(state)) return true;
const trange = state.selection.$from.blockRange(state.selection.$to);
- const path = (state.selection.$from as any).path;
- const depth = trange ? liftTarget(trange) : undefined;
- const split = path.length > 5 && !path[path.length - 3].textContent && path[path.length - 6].type !== schema.nodes.list_item;
- if (split && trange && depth !== undefined && depth !== null) {
+ const depth = trange ? liftTarget(trange) : null;
+ if (
+ depth !== null &&
+ state.selection.$from.node(-1)?.type === state.schema.nodes.blockquote && //
+ !state.selection.$from.node().content.size &&
+ trange
+ ) {
dispatch(state.tr.lift(trange, depth) as any);
return true;
}
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
- const cr = state.selection.$from.node().textContent.endsWith('\n');
- if (/*cr ||*/ !newlineInCode(state, dispatch as any)) {
- if (
+ if (!newlineInCode(state, dispatch as any)) {
+ const olNode = view.state.selection.$anchor.node(-2);
+ const liNode = view.state.selection.$anchor.node(-1);
+ // prettier-ignore
+ if (liNode?.type === schema.nodes.list_item && !liNode.textContent &&
+ olNode?.type === schema.nodes.ordered_list && once && view.state.selection.$from.depth === 3)
+ {
+ // handles case of hitting enter at then end of a top-level empty list item - the result is to create a paragraph
+ for (let i = 0; i < 10 && view.state.selection.$from.depth > 1 && liftListItem(schema.nodes.list_item)(view.state, view.dispatch); i++);
+ } else if (
!splitListItem(schema.nodes.list_item)(state as any, (tx2: Transaction) => {
const tx3 = updateBullets(tx2, schema);
marks && tx3.ensureMarks([...marks]);
marks && tx3.setStoredMarks([...marks]);
dispatch(tx3);
+ // removes an extra paragraph created when selecting text across two list items or splitting an empty list item
+ !once && view.dispatch(view.state.tr.deleteRange(view.state.selection.from - 5, view.state.selection.from - 2));
})
) {
- const fromattrs = state.selection.$from.node().attrs;
- if (
- !splitBlockKeepMarks(state, (tx3: Transaction) => {
- const tonode = tx3.selection.$to.node();
- if (tx3.selection.to && tx3.doc.nodeAt(tx3.selection.to - 1)) {
- const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks);
- splitMetadata(marks, tx4);
- if (!liftListItem(schema.nodes.list_item)(tx4, dispatch as (tx: Transaction) => void)) {
+ if (once && view.state.selection.$from.node(-2)?.type === schema.nodes.ordered_list && view.state.selection.$from.node(-1)?.type === schema.nodes.list_item && view.state.selection.$from.node(-1)?.textContent === '') {
+ // handles case of hitting enter on an empty list item which needs to create a second empty paragraph, then split it by calling enter() again
+ view.dispatch(view.state.tr.insert(view.state.selection.from, schema.nodes.paragraph.create({})));
+ enter(view.state, view.dispatch, view, false);
+ } else {
+ const fromattrs = state.selection.$from.node().attrs;
+ if (
+ !splitBlockKeepMarks(state, (tx3: Transaction) => {
+ const tonode = tx3.selection.$to.node();
+ if (tx3.selection.to && tx3.doc.nodeAt(tx3.selection.to - 1)) {
+ const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks).setStoredMarks(marks || []);
dispatch(tx4);
}
- } else dispatch(tx3.insertText('\r\n'));
- })
- ) {
- return false;
+
+ if (view.state.selection.$anchor.nodeAfter?.type === schema.nodes.text && once) {
+ // if text is selected across list items, then we need to forcibly insert a new line since the splitBlock code joins the two list items.
+ enter(view.state, dispatch, view, false);
+ }
+ })
+ ) {
+ return false;
+ }
}
}
}
return true;
- });
+ };
+ bind('Enter', enter);
- //Command to create a blank space
- bind('Space', (state: EditorState, dispatch: (tx: Transaction) => void) => {
- if (props.TemplateDataDocument && GetEffectiveAcl(props.TemplateDataDocument) != AclEdit && GetEffectiveAcl(props.TemplateDataDocument) != AclAugment && GetEffectiveAcl(props.TemplateDataDocument) != AclAdmin) return true;
- const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
- dispatch(splitMetadata(marks, state.tr));
+ // Command to create a blank space
+ bind('Space', () => {
+ const editDoc = props.TemplateDataDocument ?? props.Document[DocData];
+ if (editDoc && ![AclAdmin, AclAugment, AclEdit].includes(GetEffectiveAcl(editDoc))) return true;
return false;
});
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index dc2c06701..a612f3c65 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -3,31 +3,34 @@ import { Tooltip } from '@mui/material';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { lift, wrapIn } from 'prosemirror-commands';
-import { Mark, MarkType, Node as ProsNode, ResolvedPos } from 'prosemirror-model';
+import { Mark, MarkType } from 'prosemirror-model';
import { wrapInList } from 'prosemirror-schema-list';
import { EditorState, NodeSelection, TextSelection } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
import * as React from 'react';
import { Doc } from '../../../../fields/Doc';
import { BoolCast, Cast, StrCast } from '../../../../fields/Types';
-import { numberRange } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
-import { LinkManager } from '../../../util/LinkManager';
-import { SelectionManager } from '../../../util/SelectionManager';
import { undoBatch, UndoManager } from '../../../util/UndoManager';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { DocumentView } from '../DocumentView';
import { EquationBox } from '../EquationBox';
import { FieldViewProps } from '../FieldView';
import { FormattedTextBox } from './FormattedTextBox';
import { updateBullets } from './ProsemirrorExampleTransfer';
import './RichTextMenu.scss';
import { schema } from './schema_rts';
+
const { toggleMark } = require('prosemirror-commands');
@observer
export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
- @observable static Instance: RichTextMenu;
+ // eslint-disable-next-line no-use-before-define
+ static _instance: { menu: RichTextMenu | undefined } = observable({ menu: undefined });
+ static get Instance() {
+ return RichTextMenu._instance?.menu;
+ }
public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable
private _linkToRef = React.createRef<HTMLInputElement>();
@@ -48,7 +51,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
@observable private _activeFontSize: string = '13px';
@observable private _activeFontFamily: string = '';
- @observable private activeListType: string = '';
+ @observable private _activeListType: string = '';
@observable private _activeAlignment: string = 'left';
@observable private brushMarks: Set<Mark> = new Set();
@@ -67,7 +70,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
constructor(props: AntimodeMenuProps) {
super(props);
makeObservable(this);
- RichTextMenu.Instance = this;
+ RichTextMenu._instance.menu = this;
this.updateMenu(undefined, undefined, props, this.layoutDoc);
this._canFade = false;
this.Pinned = true;
@@ -100,6 +103,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
@computed get fontSize() {
return this._activeFontSize;
}
+ @computed get listStyle() {
+ return this._activeListType;
+ }
@computed get textAlign() {
return this._activeAlignment;
}
@@ -109,8 +115,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
_disposer: IReactionDisposer | undefined;
componentDidMount() {
this._disposer = reaction(
- () => SelectionManager.Views.slice(),
- views => this.updateMenu(undefined, undefined, undefined, undefined)
+ () => DocumentView.Selected().slice(),
+ () => this.updateMenu(undefined, undefined, undefined, undefined)
);
}
componentWillUnmount() {
@@ -131,24 +137,21 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
if (lastState?.doc.eq(view.state.doc) && lastState.selection.eq(view.state.selection)) return;
}
- // update active marks
- const activeMarks = this.getActiveMarksOnSelection();
- this.setActiveMarkButtons(activeMarks);
-
- // update active font family and size
+ this.setActiveMarkButtons(this.getActiveMarksOnSelection());
const active = this.getActiveFontStylesOnSelection();
- const activeFamilies = active.activeFamilies;
- const activeSizes = active.activeSizes;
- const activeColors = active.activeColors;
- const activeHighlights = active.activeHighlights;
- const refDoc = SelectionManager.Views.lastElement()?.layoutDoc ?? Doc.UserDoc();
- const refField = (pfx => (pfx ? pfx + '_' : ''))(SelectionManager.Views.lastElement()?.LayoutFieldKey);
-
- this.activeListType = this.getActiveListStyle();
+ const { activeFamilies } = active;
+ const { activeSizes } = active;
+ const { activeColors } = active;
+ const { activeHighlights } = active;
+ const refDoc = DocumentView.Selected().lastElement()?.layoutDoc ?? Doc.UserDoc();
+ const refField = (pfx => (pfx ? pfx + '_' : ''))(DocumentView.Selected().lastElement()?.LayoutFieldKey);
+ const refVal = (field: string, dflt: string) => StrCast(refDoc[refField + field], StrCast(Doc.UserDoc()[field], dflt));
+
+ this._activeListType = this.getActiveListStyle();
this._activeAlignment = this.getActiveAlignment();
- this._activeFontFamily = !activeFamilies.length ? StrCast(this.TextView?.Document._text_fontFamily, StrCast(refDoc[refField + 'fontFamily'], 'Arial')) : activeFamilies.length === 1 ? String(activeFamilies[0]) : 'various';
- this._activeFontSize = !activeSizes.length ? StrCast(this.TextView?.Document.fontSize, StrCast(refDoc[refField + 'fontSize'], '10px')) : activeSizes[0];
- this._activeFontColor = !activeColors.length ? StrCast(this.TextView?.Document.fontColor, StrCast(refDoc[refField + 'fontColor'], 'black')) : activeColors.length > 0 ? String(activeColors[0]) : '...';
+ this._activeFontFamily = !activeFamilies.length ? StrCast(this.TextView?.Document._text_fontFamily, refVal('fontFamily', 'Arial')) : activeFamilies.length === 1 ? String(activeFamilies[0]) : 'various';
+ this._activeFontSize = !activeSizes.length ? StrCast(this.TextView?.Document.fontSize, refVal('fontSize', '10px')) : activeSizes[0];
+ this._activeFontColor = !activeColors.length ? StrCast(this.TextView?.Document.fontColor, refVal('fontColor', 'black')) : activeColors.length > 0 ? String(activeColors[0]) : '...';
this._activeHighlightColor = !activeHighlights.length ? '' : activeHighlights.length > 0 ? String(activeHighlights[0]) : '...';
// update link in current selection
@@ -157,39 +160,31 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
setMark = (mark: Mark, state: EditorState, dispatch: any, dontToggle: boolean = false) => {
if (mark) {
- const liFirst = numberRange(state.selection.$from.depth + 1).find(i => state.selection.$from.node(i)?.type === state.schema.nodes.list_item);
- const liTo = numberRange(state.selection.$to.depth + 1).find(i => state.selection.$to.node(i)?.type === state.schema.nodes.list_item);
- const olFirst = numberRange(state.selection.$from.depth + 1).find(i => state.selection.$from.node(i)?.type === state.schema.nodes.ordered_list);
- const nodeOl = (liFirst && liTo && state.selection.$from.node(liFirst) !== state.selection.$to.node(liTo) && olFirst) || (!liFirst && !liTo && olFirst);
- const newPos = nodeOl ? numberRange(state.selection.from).findIndex(i => state.doc.nodeAt(i)?.type === state.schema.nodes.ordered_list) : state.selection.from;
+ 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);
- if (node?.type === schema.nodes.ordered_list) {
- let attrs = node.attrs;
- if (mark.type === schema.marks.pFontFamily) attrs = { ...attrs, fontFamily: mark.attrs.family };
- if (mark.type === schema.marks.pFontSize) attrs = { ...attrs, fontSize: mark.attrs.fontSize };
- if (mark.type === schema.marks.pFontColor) attrs = { ...attrs, fontColor: mark.attrs.color };
- const tr = updateBullets(state.tr.setNodeMarkup(newPos, node.type, attrs), state.schema);
- dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(state.selection.from), tr.doc.resolve(state.selection.to))));
- }
- {
- const state = this.view?.state;
- const tr = this.view?.state.tr;
- if (tr && state) {
- if (dontToggle) {
- tr.addMark(state.selection.from, state.selection.to, mark);
- dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(state.selection.from), tr.doc.resolve(state.selection.to)))); // bcz: need to redo the selection because ctrl-a selections disappear otherwise
- } else {
- toggleMark(mark.type, mark.attrs)(state, dispatch);
- }
+ if (node?.type === schema.nodes.ordered_list || node?.type === schema.nodes.list_item) {
+ const hasMark = node.marks.some(m => m.type === mark.type);
+ const otherMarks = node.marks.filter(m => m.type !== mark.type);
+ const addAnyway = node.marks.filter(m => m.type === mark.type && Object.keys(m.attrs).some(akey => m.attrs[akey] !== mark.attrs[akey]));
+ const markup = state.tr.setNodeMarkup(newPos, node.type, node.attrs, hasMark && !addAnyway ? otherMarks : [...otherMarks, mark]);
+ dispatch(updateBullets(markup, state.schema));
+ } else if (state) {
+ const { tr } = state;
+ if (dontToggle) {
+ tr.addMark(state.selection.from, state.selection.to, mark);
+ dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(state.selection.from), tr.doc.resolve(state.selection.to)))); // bcz: need to redo the selection because ctrl-a selections disappear otherwise
+ } else {
+ toggleMark(mark.type, mark.attrs)(state, dispatch);
}
}
+ this.updateMenu(this.view, undefined, undefined, this.layoutDoc);
}
};
// finds font sizes and families in selection
getActiveAlignment() {
if (this.view && this.TextView?._props.rootSelected?.()) {
- const path = (this.view.state.selection.$from as any).path;
+ 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';
@@ -201,16 +196,15 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
// finds font sizes and families in selection
getActiveListStyle() {
- if (this.view && this.TextView?._props.rootSelected?.()) {
- const path = (this.view.state.selection.$from as any).path;
- for (let i = 0; i < path.length; i += 3) {
- if (path[i].type === this.view.state.schema.nodes.ordered_list) {
- return path[i].attrs.mapStyle;
+ const state = this.view?.state;
+ if (state) {
+ const pos = state.selection.$anchor;
+ for (let i = 0; i < pos.depth; i++) {
+ const node = pos.node(i);
+ if (node.type === schema.nodes.ordered_list) {
+ return node.attrs.mapStyle;
}
}
- if (this.view.state.selection.$from.nodeAfter?.type === this.view.state.schema.nodes.ordered_list) {
- return this.view.state.selection.$from.nodeAfter?.attrs.mapStyle;
- }
}
return '';
}
@@ -222,26 +216,28 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const activeColors = new Set<string>();
const activeHighlights = new Set<string>();
if (this.view && this.TextView?._props.rootSelected?.()) {
- const state = this.view.state;
+ const { state } = this.view;
const pos = this.view.state.selection.$from;
- const marks: Mark[] = [...(state.storedMarks ?? [])];
+ let marks: Mark[] = [...(state.storedMarks ?? [])];
if (state.storedMarks !== null) {
+ /* empty */
} else if (state.selection.empty) {
- const ref_node = this.reference_node(pos);
- marks.push(...(ref_node !== this.view.state.doc && ref_node?.isText ? Array.from(ref_node.marks) : []));
+ for (let i = 0; i <= pos.depth; i++) {
+ marks = [...Array.from(pos.node(i).marks), ...this.view.state.selection.$anchor.marks(), ...marks];
+ }
} else {
- state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
+ state.doc.nodesBetween(state.selection.from, state.selection.to, (node /* , pos, parent, index */) => {
node.marks?.filter(mark => !mark.isInSet(marks)).map(mark => marks.push(mark));
});
}
marks.forEach(m => {
- m.type === state.schema.marks.pFontFamily && activeFamilies.add(m.attrs.family);
- m.type === state.schema.marks.pFontColor && activeColors.add(m.attrs.color);
+ m.type === state.schema.marks.pFontFamily && activeFamilies.add(m.attrs.fontFamily);
+ m.type === state.schema.marks.pFontColor && activeColors.add(m.attrs.fontColor);
m.type === state.schema.marks.pFontSize && activeSizes.add(m.attrs.fontSize);
- m.type === state.schema.marks.marker && activeHighlights.add(String(m.attrs.highlight));
+ m.type === state.schema.marks.pFontHighlight && activeHighlights.add(String(m.attrs.fontHighlight));
});
- } else if (SelectionManager.Views.some(dv => dv.ComponentView instanceof EquationBox)) {
- SelectionManager.Views.forEach(dv => StrCast(dv.Document._text_fontSize) && activeSizes.add(StrCast(dv.Document._text_fontSize)));
+ } else if (DocumentView.Selected().some(dv => dv.ComponentView instanceof EquationBox)) {
+ DocumentView.Selected().forEach(dv => StrCast(dv.Document._text_fontSize) && activeSizes.add(StrCast(dv.Document._text_fontSize)));
}
return { activeFamilies: Array.from(activeFamilies), activeSizes: Array.from(activeSizes), activeColors: Array.from(activeColors), activeHighlights: Array.from(activeHighlights) };
}
@@ -253,43 +249,29 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
return found;
}
- //finds all active marks on selection in given group
+ // finds all active marks on selection in given group
getActiveMarksOnSelection() {
- let activeMarks: MarkType[] = [];
- if (!this.view || !this.TextView?._props.rootSelected?.()) return activeMarks;
-
- const markGroup = [schema.marks.noAutoLinkAnchor, schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript];
- if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type);
- //current selection
- const { empty, ranges, $to } = this.view.state.selection as TextSelection;
- const state = this.view.state;
- if (!empty) {
- activeMarks = markGroup.filter(mark => {
- const has = false;
- for (let i = 0; !has && i < ranges.length; i++) {
- return state.doc.rangeHasMark(ranges[i].$from.pos, ranges[i].$to.pos, mark);
- }
- return false;
- });
- } else {
- const pos = this.view.state.selection.$from;
- const ref_node: ProsNode | null = this.reference_node(pos);
- if (ref_node !== null && ref_node !== this.view.state.doc) {
- if (ref_node.isText) {
- } else {
- return [];
- }
- activeMarks = markGroup.filter(mark_type => {
- // if (mark_type === state.schema.marks.pFontSize) {
- // return mark.isINSet
- // ref_node.marks.some(m => m.type.name === state.schema.marks.pFontSize.name);
- // }
- const mark = state.schema.mark(mark_type);
- return mark.isInSet(ref_node.marks);
- });
+ if (!this.view || !this.TextView?._props.rootSelected?.()) return [] as MarkType[];
+
+ const { state } = this.view;
+ let marks: Mark[] = [...(state.storedMarks ?? [])];
+ const pos = this.view.state.selection.$from;
+ if (state.storedMarks !== null) {
+ /* empty */
+ } else if (state.selection.empty) {
+ for (let i = 0; i <= pos.depth; i++) {
+ marks = [...Array.from(pos.node(i).marks), ...this.view.state.selection.$anchor.marks(), ...marks];
}
+ } else {
+ state.doc.nodesBetween(state.selection.from, state.selection.to, (node /* , pos, parent, index */) => {
+ node.marks?.filter(mark => !mark.isInSet(marks)).map(mark => marks.push(mark));
+ });
}
- return activeMarks;
+ const markGroup = [schema.marks.noAutoLinkAnchor, schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript];
+ return markGroup.filter(markType => {
+ const mark = state.schema.mark(markType);
+ return mark.isInSet(marks);
+ });
}
@action
@@ -305,7 +287,6 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
this._superscriptActive = false;
activeMarks.forEach(mark => {
- // prettier-ignore
switch (mark.name) {
case 'noAutoLinkAnchor': this._noLinkActive = true; break;
case 'strong': this._boldActive = true; break;
@@ -314,10 +295,28 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
case 'strikethrough': this._strikethroughActive = true; break;
case 'subscript': this._subscriptActive = true; break;
case 'superscript': this._superscriptActive = true; break;
- }
+ default:
+ } // prettier-ignore
});
}
+ elideSelection = (txstate: EditorState | undefined = undefined, visibility = false) => {
+ const state = txstate ?? this.view?.state;
+ if (!state || state.selection.empty) return false;
+ const mark = state.schema.marks.summarize.create();
+ const tr = state.tr.addMark(state.tr.selection.from, state.selection.to, mark);
+ const text = tr.selection.content();
+ const elideNode = state.schema.nodes.summary.create({ visibility, text, textslice: text.toJSON() });
+ const summary = tr.replaceSelectionWith(elideNode).removeMark(tr.selection.from - 1, tr.selection.from, mark);
+ const expanded = () => {
+ const endOfElidableText = summary.selection.to + text.content.size;
+ const res = summary.insert(summary.selection.to, text.content).insert(endOfElidableText, state.schema.nodes.paragraph.create({}));
+ return res.setSelection(new TextSelection(res.doc.resolve(endOfElidableText + 1)));
+ };
+ this.view?.dispatch?.(visibility ? expanded() : summary);
+ return true;
+ };
+
toggleNoAutoLinkAnchor = () => {
if (this.view) {
const mark = this.view.state.schema.mark(this.view.state.schema.marks.noAutoLinkAnchor);
@@ -350,90 +349,46 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
};
- setFontSize = (fontSize: string) => {
+ setFontField = (value: string, fontField: 'fontSize' | 'fontFamily' | 'fontColor' | 'fontHighlight') => {
if (this.view) {
- if (this.view.state.selection.from === 1 && this.view.state.selection.empty && (!this.view.state.doc.nodeAt(1) || !this.view.state.doc.nodeAt(1)?.marks.some(m => m.type.name === fontSize))) {
- this.TextView.dataDoc.fontSize = fontSize;
- this.view.focus();
- } else {
- const fmark = this.view.state.schema.marks.pFontSize.create({ fontSize });
- this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true);
+ 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)) {
+ this.TextView.dataDoc[this.TextView.fieldKey + `_${fontField}`] = value;
this.view.focus();
}
- } else if (SelectionManager.Views.length) {
- SelectionManager.Views.forEach(dv => (dv.layoutDoc[dv.LayoutFieldKey + '_fontSize'] = fontSize));
- } else Doc.UserDoc().fontSize = fontSize;
- this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
- };
-
- setFontFamily = (family: string) => {
- if (this.view) {
- const fmark = this.view.state.schema.marks.pFontFamily.create({ family: family });
+ 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.view.focus();
- } else if (SelectionManager.Views.length) {
- SelectionManager.Views.forEach(dv => (dv.layoutDoc[dv.LayoutFieldKey + '_fontFamily'] = family));
- } else Doc.UserDoc().fontFamily = family;
- this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
+ } else {
+ Doc.UserDoc()[fontField] = value;
+ this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
+ }
};
- setHighlight(color: string) {
- if (this.view) {
- const highlightMark = this.view.state.schema.mark(this.view.state.schema.marks.marker, { highlight: color });
- this.setMark(highlightMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(highlightMark)), true);
- this.view.focus();
- } else Doc.UserDoc()._fontHighlight = color;
- this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
- }
-
- setColor(color: string) {
- if (this.view) {
- const colorMark = this.view.state.schema.mark(this.view.state.schema.marks.pFontColor, { color });
- this.setMark(colorMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(colorMark)), true);
- this.view.focus();
- } else if (SelectionManager.Views.length) {
- SelectionManager.Views.forEach(dv => (dv.layoutDoc[dv.LayoutFieldKey + '_fontColor'] = color));
- } else Doc.UserDoc().fontColor = color;
- this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
- }
-
// TODO: remove doesn't work
// remove all node type and apply the passed-in one to the selected text
changeListType = (mapStyle: string) => {
- const active = this.view?.state && RichTextMenu.Instance.getActiveListStyle();
- const nodeType = this.view?.state.schema.nodes.ordered_list.create({ mapStyle: active === mapStyle ? '' : mapStyle });
- if (!this.view || nodeType?.attrs.mapStyle === '') return;
-
- const nextIsOL = this.view.state.selection.$from.nodeAfter?.type === schema.nodes.ordered_list;
- let inList: any = undefined;
- let fromList = -1;
- const path: any = Array.from((this.view.state.selection.$from as any).path);
- for (let i = 0; i < path.length; i++) {
- if (path[i]?.type === schema.nodes.ordered_list) {
- inList = path[i];
- fromList = path[i - 1];
- }
- }
+ const active = this.view?.state && RichTextMenu.Instance?.getActiveListStyle();
+ const newMapStyle = active === mapStyle ? '' : mapStyle;
+ if (!this.view || newMapStyle === '') return;
+ const inList = this.view.state.selection.$anchor.node(1).type === schema.nodes.ordered_list;
const marks = this.view.state.storedMarks || (this.view.state.selection.$to.parentOffset && this.view.state.selection.$from.marks());
- if (
- inList ||
+ if (inList) {
+ const tx2 = updateBullets(this.view.state.tr, schema, newMapStyle, this.view.state.doc.resolve(this.view.state.selection.$anchor.before(1) + 1).pos, this.view.state.doc.resolve(this.view.state.selection.$anchor.after(1)).pos);
+ marks && tx2.ensureMarks([...marks]);
+ marks && tx2.setStoredMarks([...marks]);
+ this.view.dispatch(tx2);
+ } else
!wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: any) => {
- const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle, this.view!.state.selection.from - 1, this.view!.state.selection.to + 1);
- marks && tx3.ensureMarks([...marks]);
- marks && tx3.setStoredMarks([...marks]);
-
- this.view!.dispatch(tx2);
- })
- ) {
- const tx2 = this.view.state.tr;
- if (nodeType && (inList || nextIsOL)) {
- const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle, inList ? fromList : this.view.state.selection.from, inList ? fromList + inList.nodeSize : this.view.state.selection.to);
+ 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!.dispatch(tx3);
+ });
this.view.focus();
this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
};
@@ -441,7 +396,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
insertSummarizer(state: EditorState, dispatch: any) {
if (state.selection.empty) return false;
const mark = state.schema.marks.summarize.create();
- const tr = state.tr;
+ const { tr } = state;
tr.addMark(state.selection.from, state.selection.to, mark);
const content = tr.selection.content();
const newNode = state.schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() });
@@ -449,13 +404,13 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
return true;
}
- vcenterToggle = (view: EditorView, dispatch: any) => {
+ vcenterToggle = () => {
this.layoutDoc && (this.layoutDoc._layout_centered = !this.layoutDoc._layout_centered);
};
align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => {
if (this.TextView?._props.rootSelected?.()) {
- var tr = view.state.tr;
- view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos, parent, index) => {
+ let { tr } = view.state;
+ view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos) => {
if ([schema.nodes.paragraph, schema.nodes.heading].includes(node.type)) {
tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, align: alignment }, node.marks);
return false;
@@ -468,56 +423,14 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
};
- insetParagraph(state: EditorState, dispatch: any) {
- var tr = state.tr;
- state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
- if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
- const inset = (node.attrs.inset ? Number(node.attrs.inset) : 0) + 10;
- tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, inset }, node.marks);
- return false;
- }
- return true;
- });
- dispatch?.(tr);
- return true;
- }
- outsetParagraph(state: EditorState, dispatch: any) {
- var tr = state.tr;
- state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
+ paragraphSetup(state: EditorState, dispatch: any, 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) {
- const inset = Math.max(0, (node.attrs.inset ? Number(node.attrs.inset) : 0) - 10);
- tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, inset }, node.marks);
- return false;
- }
- return true;
- });
- dispatch?.(tr);
- return true;
- }
-
- indentParagraph(state: EditorState, dispatch: any) {
- var tr = state.tr;
- const heading = false;
- state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
- if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
- const nodeval = node.attrs.indent ? Number(node.attrs.indent) : undefined;
- const indent = !nodeval ? 25 : nodeval < 0 ? 0 : nodeval + 25;
- tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, indent }, node.marks);
- return false;
- }
- return true;
- });
- !heading && dispatch?.(tr);
- return true;
- }
-
- hangingIndentParagraph(state: EditorState, dispatch: any) {
- var tr = state.tr;
- state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
- if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
- const nodeval = node.attrs.indent ? Number(node.attrs.indent) : undefined;
- const indent = !nodeval ? -25 : nodeval > 0 ? 0 : nodeval - 10;
- tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, indent }, node.marks);
+ const newValue = !value ?
+ (node.attrs[field] ? 0 : node.attrs[field] + 10) :
+ Math.max(0, value); // prettier-ignore
+ tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, ...(field === 'inset' ? { inset: newValue } : { indent: newValue }) }, node.marks);
return false;
}
return true;
@@ -527,7 +440,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
insertBlockquote(state: EditorState, dispatch: any) {
- const path = (state.selection.$from as any).path;
+ const { path } = state.selection.$from as any;
if (path.length > 6 && path[path.length - 6].type === schema.nodes.blockquote) {
lift(state, dispatch);
} else {
@@ -548,7 +461,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
// todo: add brushes to brushMap to save with a style name
onBrushNameKeyPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
- RichTextMenu.Instance.brushMarks && RichTextMenu.Instance._brushMap.set(this._brushNameRef.current!.value, RichTextMenu.Instance.brushMarks);
+ RichTextMenu.Instance?.brushMarks && RichTextMenu.Instance?._brushMap.set(this._brushNameRef.current!.value, RichTextMenu.Instance.brushMarks);
this._brushNameRef.current!.style.background = 'lightGray';
}
};
@@ -556,17 +469,17 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
@action
clearBrush() {
- RichTextMenu.Instance.brushMarks = new Set();
+ RichTextMenu.Instance && (RichTextMenu.Instance.brushMarks = new Set());
}
@action
- fillBrush(state: EditorState, dispatch: any) {
+ fillBrush() {
if (!this.view) return;
if (!Array.from(this.brushMarks.keys()).length) {
- const selected_marks = this.getMarksInSelection(this.view.state);
- if (selected_marks.size >= 0) {
- this.brushMarks = selected_marks;
+ const selectedMarks = this.getMarksInSelection(this.view.state);
+ if (selectedMarks.size >= 0) {
+ this.brushMarks = selectedMarks;
}
} else {
const { from, to, $from } = this.view.state.selection;
@@ -610,9 +523,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const button = (
<Tooltip title={<div className="dash-tooltip">set hyperlink</div>} placement="bottom">
- <button className="antimodeMenu-button color-preview-button">
- <FontAwesomeIcon icon="link" size="lg" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button type="button" className="antimodeMenu-button color-preview-button">
+ <FontAwesomeIcon icon="link" size="lg" />
+ </button>
+ }
</Tooltip>
);
@@ -620,21 +536,22 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
<div className="dropdown link-menu">
<p>Linked to:</p>
<input value={link} ref={this._linkToRef} placeholder="Enter URL" onChange={onLinkChange} />
- <button className="make-button" onPointerDown={e => this.makeLinkToURL(link, 'add:right')}>
+ <button type="button" className="make-button" onPointerDown={() => this.makeLinkToURL(link)}>
Apply hyperlink
</button>
<div className="divider" />
- <button className="remove-button" onPointerDown={e => this.deleteLink()}>
+ <button type="button" className="remove-button" onPointerDown={() => this.deleteLink()}>
Remove link
</button>
</div>
);
- return <ButtonDropdown view={this.view} key={'link button'} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} link={true} />;
+ // eslint-disable-next-line no-use-before-define
+ return <ButtonDropdown view={this.view} key="link button" button={button} dropdownContent={dropdownContent} openDropdownOnButton link />;
}
async getTextLinkTargetTitle() {
- if (!this.view) return;
+ if (!this.view) return undefined;
const node = this.view.state.selection.$from.nodeAfter;
const link = node && node.marks.find(m => m.type.name === 'link');
@@ -646,15 +563,15 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
if (linkclicked) {
const linkDoc = await DocServer.GetRefField(linkclicked);
if (linkDoc instanceof Doc) {
- const link_anchor_1 = await Cast(linkDoc.link_anchor_1, Doc);
- const link_anchor_2 = await Cast(linkDoc.link_anchor_2, Doc);
- const currentDoc = SelectionManager.Docs.lastElement();
- if (currentDoc && link_anchor_1 && link_anchor_2) {
- if (Doc.AreProtosEqual(currentDoc, link_anchor_1)) {
- return StrCast(link_anchor_2.title);
+ const linkAnchor1 = await Cast(linkDoc.link_anchor_1, Doc);
+ const linkAnchor2 = await Cast(linkDoc.link_anchor_2, Doc);
+ const currentDoc = DocumentView.Selected().lastElement().Document;
+ if (currentDoc && linkAnchor1 && linkAnchor2) {
+ if (Doc.AreProtosEqual(currentDoc, linkAnchor1)) {
+ return StrCast(linkAnchor2.title);
}
- if (Doc.AreProtosEqual(currentDoc, link_anchor_2)) {
- return StrCast(link_anchor_1.title);
+ if (Doc.AreProtosEqual(currentDoc, linkAnchor2)) {
+ return StrCast(linkAnchor1.title);
}
}
}
@@ -666,11 +583,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
return link.attrs.title;
}
}
+ return undefined;
}
// TODO: should check for valid URL
@undoBatch
- makeLinkToURL = (target: string, lcoation: string) => {
+ makeLinkToURL = (target: string) => {
((this.view as any)?.TextView as FormattedTextBox).makeLinkAnchor(undefined, 'onRadd:rightight', target, target);
};
@@ -686,124 +604,14 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
.filter((aref: any) => aref?.href.indexOf(Doc.localServerPath()) === 0)
.forEach((aref: any) => {
const anchorId = aref.href.replace(Doc.localServerPath(), '').split('?')[0];
- anchorId && DocServer.GetRefField(anchorId).then(linkDoc => LinkManager.Instance.deleteLink(linkDoc as Doc));
+ anchorId && DocServer.GetRefField(anchorId).then(linkDoc => Doc.DeleteLink?.(linkDoc as Doc));
});
}
}
};
- linkExtend($start: ResolvedPos, href: string) {
- const mark = this.view!.state.schema.marks.linkAnchor;
-
- let startIndex = $start.index();
- let endIndex = $start.indexAfter();
-
- while (startIndex > 0 && $start.parent.child(startIndex - 1).marks.filter(m => m.type === mark && m.attrs.allAnchors.find((item: { href: string }) => item.href === href)).length) startIndex--;
- while (endIndex < $start.parent.childCount && $start.parent.child(endIndex).marks.filter(m => m.type === mark && m.attrs.allAnchors.find((item: { href: string }) => item.href === href)).length) endIndex++;
-
- let startPos = $start.start();
- let endPos = startPos;
- for (let i = 0; i < endIndex; i++) {
- const size = $start.parent.child(i).nodeSize;
- if (i < startIndex) startPos += size;
- endPos += size;
- }
- return { from: startPos, to: endPos };
- }
-
- reference_node(pos: ResolvedPos): ProsNode | null {
- if (!this.view) return null;
-
- let ref_node: ProsNode = this.view.state.doc;
- if (pos.nodeBefore !== null && pos.nodeBefore !== undefined) {
- ref_node = pos.nodeBefore;
- }
- if (pos.nodeAfter !== null && pos.nodeAfter !== undefined) {
- if (!pos.nodeBefore || this.view.state.selection.$from.pos !== this.view.state.selection.$to.pos) {
- ref_node = pos.nodeAfter;
- }
- }
- if (!ref_node && pos.pos > 0) {
- let skip = false;
- for (let i: number = pos.pos - 1; i > 0; i--) {
- this.view.state.doc.nodesBetween(i, pos.pos, (node: ProsNode) => {
- if (node.isLeaf && !skip) {
- ref_node = node;
- skip = true;
- }
- });
- }
- }
- if (!ref_node.isLeaf && ref_node.childCount > 0) {
- ref_node = ref_node.child(0);
- }
- return ref_node;
- }
-
render() {
return null;
- // TraceMobx();
- // const row1 = <div className="antimodeMenu-row" key="row 1" style={{ display: this.collapsed ? "none" : undefined }}>{[
- // //!this.collapsed ? this.getDragger() : (null),
- // // !this.Pinned ? (null) : <div key="frag1"> {[
- // // this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)),
- // // this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)),
- // // this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)),
- // // this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)),
- // // this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)),
- // // this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)),
- // // <div className="richTextMenu-divider" key="divider" />
- // // ]}</div>,
- // this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)),
- // this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)),
- // this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)),
- // this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)),
- // this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)),
- // this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)),
- // this.createColorButton(),
- // this.createHighlighterButton(),
- // this.createLinkButton(),
- // this.createBrushButton(),
- // <div className="collectionMenu-divider" key="divider 2" />,
- // this.createButton("align-left", "Align Left", this.activeAlignment === "left", this.alignLeft),
- // this.createButton("align-center", "Align Center", this.activeAlignment === "center", this.alignCenter),
- // this.createButton("align-right", "Align Right", this.activeAlignment === "right", this.alignRight),
- // this.createButton("indent", "Inset More", undefined, this.insetParagraph),
- // this.createButton("outdent", "Inset Less", undefined, this.outsetParagraph),
- // this.createButton("hand-point-left", "Hanging Indent", undefined, this.hangingIndentParagraph),
- // this.createButton("hand-point-right", "Indent", undefined, this.indentParagraph),
- // ]}</div>;
-
- // const row2 = <div className="antimodeMenu-row row-2" key="row2">
- // {this.collapsed ? this.getDragger() : (null)}
- // <div key="row 2" style={{ display: this.collapsed ? "none" : undefined }}>
- // <div className="collectionMenu-divider" key="divider 3" />
- // {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => {
- // this.activeFontSize = val;
- // SelectionManager.Views.map(dv => dv.Document._text_fontSize = val);
- // })),
- // this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => {
- // this.activeFontFamily = val;
- // SelectionManager.Views.map(dv => dv.Document._text_fontFamily = val);
- // })),
- // <div className="collectionMenu-divider" key="divider 4" />,
- // this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", () => ({})),
- // this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer),
- // this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote),
- // this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule)
- // ]}
- // </div>
- // {/* <div key="collapser">
- // {<div key="collapser">
- // <button className="antimodeMenu-button" key="collapse menu" title="Collapse menu" onClick={this.toggleCollapse} style={{ backgroundColor: this.collapsed ? "#121212" : "", width: 25 }}>
- // <FontAwesomeIcon icon="chevron-left" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.3s", transform: `rotate(${this.collapsed ? 180 : 0}deg)` }} />
- // </button>
- // </div> }
- // <button className="antimodeMenu-button" key="pin menu" title="Pin menu" onClick={this.toggleMenuPin} style={{ backgroundColor: this.Pinned ? "#121212" : "", display: this.collapsed ? "none" : undefined }}>
- // <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
- // </button>
- // </div> */}
- // </div>;
}
}
@@ -859,7 +667,11 @@ export class ButtonDropdown extends ObservableReactComponent<ButtonDropdownProps
render() {
return (
- <div className="button-dropdown-wrapper" ref={node => (this.ref = node)}>
+ <div
+ className="button-dropdown-wrapper"
+ ref={node => {
+ this.ref = node;
+ }}>
{!this._props.pdf ? (
<div className="antimodeMenu-button dropdown-button-combined" onPointerDown={this._props.openDropdownOnButton ? this.onDropdownClick : undefined}>
{this._props.button}
@@ -870,9 +682,12 @@ export class ButtonDropdown extends ObservableReactComponent<ButtonDropdownProps
) : (
<>
{this._props.button}
- <button className="dropdown-button antimodeMenu-button" key="antimodebutton" onPointerDown={this.onDropdownClick}>
- <FontAwesomeIcon icon="caret-down" size="sm" />
- </button>
+ {
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+ <button type="button" className="dropdown-button antimodeMenu-button" key="antimodebutton" onPointerDown={this.onDropdownClick}>
+ <FontAwesomeIcon icon="caret-down" size="sm" />
+ </button>
+ }
</>
)}
{this.showDropdown ? this._props.dropdownContent : null}
@@ -885,10 +700,11 @@ interface RichTextMenuPluginProps {
editorProps: any;
}
export class RichTextMenuPlugin extends React.Component<RichTextMenuPluginProps> {
- render() {
- return null;
- }
+ // 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);
}
+ render() {
+ return null;
+ }
}
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index d5c91fc09..bf11dfe62 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -1,20 +1,21 @@
import { ellipsis, emDash, InputRule, smartQuotes, textblockTypeInputRule } from 'prosemirror-inputrules';
import { NodeSelection, TextSelection } from 'prosemirror-state';
-import { Doc, StrListCast } from '../../../../fields/Doc';
+import { ClientUtils } from '../../../../ClientUtils';
+import { Doc, DocListCast, FieldResult, StrListCast } from '../../../../fields/Doc';
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 { DocServer } from '../../../DocServer';
-import { Docs, DocUtils } from '../../../documents/Documents';
+import { Docs } from '../../../documents/Documents';
+import { CollectionViewType } from '../../../documents/DocumentTypes';
+import { DocUtils } from '../../../documents/DocUtils';
+import { CollectionView } from '../../collections/CollectionView';
+import { ContextMenu } from '../../ContextMenu';
import { FormattedTextBox } from './FormattedTextBox';
import { wrappingInputRule } from './prosemirrorPatches';
import { RichTextMenu } from './RichTextMenu';
import { schema } from './schema_rts';
-import { CollectionView } from '../../collections/CollectionView';
-import { CollectionViewType } from '../../../documents/DocumentTypes';
-import { ContextMenu } from '../../ContextMenu';
export class RichTextRules {
public Document: Doc;
@@ -47,13 +48,9 @@ export class RichTextRules {
/^A\.\s$/,
schema.nodes.ordered_list,
// match => {
- () => {
- return { mapStyle: 'multi', bulletStyle: 1 };
- // return ({ order: +match[1] })
- },
- (match: any, node: any) => {
- return node.childCount + node.attrs.order === +match[1];
- },
+ () => ({ 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
),
@@ -69,7 +66,7 @@ export class RichTextRules {
// ``` create code block
new InputRule(/^```$/, (state, match, start, end) => {
- let $start = state.doc.resolve(start);
+ const $start = state.doc.resolve(start);
if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), schema.nodes.code_block)) return null;
// this enables text with code blocks to be used as a 'paint' function via a styleprovider button that is added to Docs that have an onPaint script
@@ -85,13 +82,13 @@ export class RichTextRules {
}),
// %<font-size> set the font size
- new InputRule(new RegExp(/%([0-9]+)\s$/), (state, match, start, end) => {
+ new InputRule(/%([0-9]+)\s$/, (state, match, start, end) => {
const size = Number(match[1]);
return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: size }));
}),
- //Create annotation to a field on the text document
- new InputRule(new RegExp(/>::$/), (state, match, start, end) => {
+ // Create annotation to a field on the text document
+ new InputRule(/>::$/, (state, match, start, end) => {
const creator = (doc: Doc) => {
const textDoc = this.Document[DocData];
const numInlines = NumCast(textDoc.inlineTextCount);
@@ -106,7 +103,7 @@ export class RichTextRules {
.insert(start, newNode)
.replaceRangeWith(start + 1, end + 2, dashDoc)
.insertText(' ', start + 2)
- .setStoredMarks([...node.marks, ...(sm ? sm : [])])
+ .setStoredMarks([...node.marks, ...(sm || [])])
: this.TextBox.EditorView.state.tr
);
};
@@ -116,8 +113,8 @@ export class RichTextRules {
return null;
}),
- //Create annotation to a field on the text document
- new InputRule(new RegExp(/>>$/), (state, match, start, end) => {
+ // Create annotation to a field on the text document
+ new InputRule(/>>$/, (state, match, start, end) => {
const textDoc = this.Document[DocData];
const numInlines = NumCast(textDoc.inlineTextCount);
textDoc.inlineTextCount = numInlines + 1;
@@ -136,6 +133,7 @@ export class RichTextRules {
textDocInline.title = inlineFieldKey; // give the annotation its own title
textDocInline.title_custom = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc
textDocInline.isTemplateForField = inlineFieldKey; // this is needed in case the containing text doc is converted to a template at some point
+ textDocInline.isDataDoc = true;
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
@@ -148,13 +146,13 @@ export class RichTextRules {
.insert(start, newNode)
.replaceRangeWith(start + 1, end + 1, dashDoc)
.insertText(' ', start + 2)
- .setStoredMarks([...node.marks, ...(sm ? sm : [])])
+ .setStoredMarks([...node.marks, ...(sm || [])])
: state.tr;
return replaced;
}),
// set the First-line indent node type for the selection's paragraph (assumes % was used to initiate an EnteringStyle mode)
- new InputRule(new RegExp(/(%d|d)$/), (state, match, start, end) => {
+ 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--) {
@@ -169,7 +167,7 @@ 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(new RegExp(/(%h|h)$/), (state, match, start, end) => {
+ 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--) {
@@ -184,11 +182,11 @@ 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(new RegExp(/(%q|q)$/), (state, match, start, end) => {
+ new InputRule(/(%q|q)$/, (state, match, start, end) => {
if (!match[0].startsWith('%') && !this.EnteringStyle) return null;
const pos = state.doc.resolve(start) as any;
if (state.selection instanceof NodeSelection && state.selection.node.type === schema.nodes.ordered_list) {
- const node = state.selection.node;
+ 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--) {
@@ -203,52 +201,58 @@ export class RichTextRules {
}),
// center justify text
- new InputRule(new RegExp(/%\^/), (state, match, start, end) => {
+ new InputRule(/%\^/, (state, match, start, end) => {
const resolved = state.doc.resolve(start) as any;
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);
- } else {
- const node = resolved.nodeAfter;
- const sm = state.storedMarks || undefined;
- const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: 'center' })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
- return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}
+ const node = resolved.nodeAfter;
+ const sm = state.storedMarks || undefined;
+ const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: 'center' })).setStoredMarks([...node.marks, ...(sm || [])]) : state.tr;
+ return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}),
// left justify text
- new InputRule(new RegExp(/%\[/), (state, match, start, end) => {
+ new InputRule(/%\[/, (state, match, start, end) => {
const resolved = state.doc.resolve(start) as any;
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);
- } else {
- const node = resolved.nodeAfter;
- const sm = state.storedMarks || undefined;
- const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: 'left' })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
- return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}
+ const node = resolved.nodeAfter;
+ const sm = state.storedMarks || undefined;
+ const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: 'left' })).setStoredMarks([...node.marks, ...(sm || [])]) : state.tr;
+ return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}),
// right justify text
- new InputRule(new RegExp(/%\]/), (state, match, start, end) => {
+ new InputRule(/%\]/, (state, match, start, end) => {
const resolved = state.doc.resolve(start) as any;
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);
- } else {
- const node = resolved.nodeAfter;
- const sm = state.storedMarks || undefined;
- const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: 'right' })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
- return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}
+ const node = resolved.nodeAfter;
+ const sm = state.storedMarks || undefined;
+ const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: 'right' })).setStoredMarks([...node.marks, ...(sm || [])]) : state.tr;
+ return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}),
// activate a style by name using prefix '%<color name>'
- new InputRule(new RegExp(/%[a-z]+$/), (state, match, start, end) => {
+ new InputRule(/%[a-zA-Z_]+$/, (state, match, start, end) => {
const color = match[0].substring(1, match[0].length);
- const marks = RichTextMenu.Instance._brushMap.get(color);
-
+ const marks = RichTextMenu.Instance?._brushMap.get(color);
+
+ if (
+ DocListCast((Doc.UserDoc().template_notes as Doc).data)
+ .concat(DocListCast((Doc.UserDoc().template_user as Doc).data))
+ .map(d => StrCast(d.title))
+ .includes(color)
+ ) {
+ setTimeout(() => this.TextBox.DocumentView?.().switchViews(true, color, undefined, true));
+ return state.tr.deleteRange(start, end);
+ }
if (marks) {
const tr = state.tr.deleteRange(start, end);
- return marks ? Array.from(marks).reduce((tr, m) => tr.addStoredMark(m), tr) : tr;
+ return marks ? Array.from(marks).reduce((tr2, m) => tr2.addStoredMark(m), tr) : tr;
}
const isValidColor = (strColor: string) => {
@@ -258,118 +262,150 @@ export class RichTextRules {
};
if (isValidColor(color)) {
- return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontColor.create({ color: color }));
+ return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontColor.create({ fontColor: color }));
}
return null;
}),
// toggle alternate text UI %/
- new InputRule(new RegExp(/%\//), (state, match, start, end) => {
- setTimeout(this.TextBox.cycleAlternateText);
+ new InputRule(/%\//, (state, match, start, end) => {
+ setTimeout(() => this.TextBox.cycleAlternateText(true));
return state.tr.deleteRange(start, end);
}),
// stop using active style
- new InputRule(new RegExp(/%%$/), (state, match, start, end) => {
+ new InputRule(/%%$/, (state, match, start, end) => {
const tr = state.tr.deleteRange(start, end);
const marks = state.tr.selection.$anchor.nodeBefore?.marks;
return marks
? Array.from(marks)
.filter(m => m.type !== state.schema.marks.user_mark)
- .reduce((tr, m) => tr.removeStoredMark(m), tr)
+ .reduce((tr2, m) => tr2.removeStoredMark(m), tr)
: tr;
}),
- // create a text display of a metadata field on this or another document, or create a hyperlink portal to another document
- // [[<fieldKey> : <Doc>]]
- // [[:docTitle]] => hyperlink
- // [[fieldKey]] => show field
- // [[fieldKey=value]] => show field and also set its value
- // [[fieldKey:docTitle]] => show field of doc
- new InputRule(
- new RegExp(/\[\[([a-zA-Z_\? \-0-9]*)(=[a-z,A-Z_@\? /\-0-9]*)?(:[a-zA-Z_@:\.\? \-0-9]+)?\]\]$/),
- (state, match, start, end) => {
- const fieldKey = match[1];
- const docTitle = match[3]?.replace(':', '');
- const value = match[2]?.substring(1);
+ // create a hyperlink to a titled document
+ // @(<doctitle>)
+ new InputRule(/@\(([a-zA-Z_@.? \-0-9]+)\)/, (state, match, start, end) => {
+ const docTitle = match[1];
+ const prefixLength = '@('.length;
+ if (docTitle) {
const linkToDoc = (target: Doc) => {
- const rstate = this.TextBox.EditorView?.state;
- const selection = rstate?.selection.$from.pos;
- if (rstate) {
- this.TextBox.EditorView?.dispatch(rstate.tr.setSelection(new TextSelection(rstate.doc.resolve(start), rstate.doc.resolve(end - 3))));
+ const editor = this.TextBox.EditorView;
+ const selection = editor?.state?.selection.$from.pos;
+ if (editor) {
+ const estate = editor.state;
+ editor.dispatch(estate.tr.setSelection(new TextSelection(estate.doc.resolve(start), estate.doc.resolve(end - prefixLength))));
}
DocUtils.MakeLink(this.TextBox.getAnchor(true), target, { link_relationship: 'portal to:portal from' });
- const fstate = this.TextBox.EditorView?.state;
- if (fstate && selection) {
- this.TextBox.EditorView?.dispatch(fstate.tr.setSelection(new TextSelection(fstate.doc.resolve(selection))));
+ const teditor = this.TextBox.EditorView;
+ if (teditor && selection) {
+ const tstate = teditor.state;
+ teditor.dispatch(tstate.tr.setSelection(new TextSelection(tstate.doc.resolve(selection))));
}
};
- const getTitledDoc = (docTitle: string) => {
- if (!DocServer.FindDocByTitle(docTitle)) {
- Doc.AddToMyPublished(Docs.Create.TextDocument('', { title: docTitle, _width: 400, _layout_autoHeight: true }));
+ const getTitledDoc = (title: string) => {
+ if (!Doc.FindDocByTitle(title)) {
+ Docs.Create.TextDocument('', { title: title, _width: 400, _layout_fitWidth: true, _layout_autoHeight: true });
}
- const titledDoc = DocServer.FindDocByTitle(docTitle);
+ const titledDoc = Doc.FindDocByTitle(title);
return titledDoc ? Doc.BestEmbedding(titledDoc) : titledDoc;
};
- if (!fieldKey) {
- if (docTitle) {
- const target = getTitledDoc(docTitle);
- if (target) {
- setTimeout(() => linkToDoc(target));
- return state.tr.deleteRange(end - 1, end).deleteRange(start, start + 3);
- }
- }
- return state.tr;
+ const target = getTitledDoc(docTitle);
+ if (target) {
+ setTimeout(() => linkToDoc(target));
+ return state.tr.insertText(' ').deleteRange(start, start + prefixLength);
}
- if (value?.includes(',')) {
+ }
+ return state.tr;
+ }),
+
+ // create a text display of a metadata field on this or another document, or create a hyperlink portal to another document
+ // [@{this,doctitle,}.fieldKey{:,=,:=,=:=}value]
+ // [@{this,doctitle,}.fieldKey]
+ new InputRule(
+ /\[(@|@this\.|@[a-zA-Z_? \-0-9]+\.)([a-zA-Z_?\-0-9]+)((:|=|:=|=:=)([a-zA-Z,_().@?+\-*/ 0-9()]*))?\]/,
+ (state, match, start, end) => {
+ const docTitle = match[1].substring(1).replace(/\.$/, '');
+ const fieldKey = match[2];
+ const assign = match[4] === ':' ? (match[4] = '') : match[4];
+ const value = match[5];
+ const dataDoc = value === undefined ? !fieldKey.startsWith('_') : !assign?.startsWith('=');
+ const getTitledDoc = (title: string) => Doc.FindDocByTitle(title);
+ // if the value has commas assume its an array (unless it's part of a chat gpt call indicated by '((' )
+ if (value?.includes(',') && !value.startsWith('((')) {
const values = value.split(',');
const strs = values.some(v => !v.match(/^[-]?[0-9.]$/));
this.Document[DocData][fieldKey] = strs ? new List<string>(values) : new List<number>(values.map(v => Number(v)));
- } else if (value !== '' && value !== undefined) {
- const num = value.match(/^[0-9.]$/);
- this.Document[DocData][fieldKey] = value === 'true' ? true : value === 'false' ? false : num ? Number(value) : value;
+ } else if (value) {
+ Doc.SetField(
+ this.Document,
+ fieldKey,
+ assign + value,
+ Doc.IsDataProto(this.Document) ? true : undefined,
+ assign.includes(':=')
+ ? undefined
+ : (gptval: FieldResult) => {
+ (dataDoc ? this.Document[DocData] : this.Document)[fieldKey] = gptval as string;
+ }
+ );
+ if (fieldKey === this.TextBox.fieldKey) return this.TextBox.EditorView!.state.tr;
}
- const target = getTitledDoc(docTitle);
- const fieldView = state.schema.nodes.dashField.create({ fieldKey, docId: target?.[Id], hideKey: false });
+ const target = docTitle ? getTitledDoc(docTitle) : undefined;
+ const fieldView = state.schema.nodes.dashField.create({ fieldKey, docId: target?.[Id], hideKey: false, hideValue: false });
return state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))).replaceSelectionWith(fieldView, true);
},
{ inCode: true }
),
+ // pass the contents between '((' and '))' to chatGPT and append the result
+ new InputRule(/(^|[^=])(\(\(.*\)\))$/, (state, match, start, end) => {
+ let count = 0; // ignore first return value which will be the notation that chat is pending a result
+ Doc.SetField(this.Document, '', match[2], false, (gptval: FieldResult) => {
+ if (count) {
+ const tr = this.TextBox.EditorView?.state.tr.insertText(' ' + (gptval as string));
+ tr && this.TextBox.EditorView?.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(end + 2), tr.doc.resolve(end + 2 + (gptval as string).length))));
+ RichTextMenu.Instance?.elideSelection(this.TextBox.EditorView?.state, true);
+ }
+ count++;
+ });
+ return null;
+ }),
+
// create a text display of a metadata field on this or another document, or create a hyperlink portal to another document
- // wiki:title
- new InputRule(new RegExp(/wiki:([a-zA-Z_@:\.\?\-0-9]+ )$/), (state, match, start, end) => {
- const title = match[1];
+ // @(wiki:title)
+ new InputRule(/@\(wiki:([a-zA-Z_@:.?\-0-9 ]+)\)$/, (state, match, start, end) => {
+ const title = match[1].trim().replace(/ /g, '_');
this.TextBox.EditorView?.dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))));
this.TextBox.makeLinkAnchor(undefined, 'add:right', `https://en.wikipedia.org/wiki/${title.trim()}`, 'wikipedia reference');
const fstate = this.TextBox.EditorView?.state;
if (fstate) {
- const tr = fstate?.tr.deleteRange(start, start + 5);
- return tr.setSelection(new TextSelection(tr.doc.resolve(end - 5))).insertText(' ');
+ const tr = fstate?.tr.deleteRange(start, start + '@(wiki:'.length);
+ return tr.setSelection(new TextSelection(tr.doc.resolve(end - '@(wiki:'.length))).insertText(' ');
}
return state.tr;
}),
// create an inline equation node
- // eq:<equation>>
- new InputRule(new RegExp(/%eq([a-zA-Z-0-9\(\)]*)$/), (state, match, start, end) => {
+ // %eq
+ new InputRule(/%eq/, (state, match, start, end) => {
const fieldKey = 'math' + Utils.GenerateGuid();
- this.TextBox.dataDoc[fieldKey] = match[1];
+ this.TextBox.dataDoc[fieldKey] = 'y=';
const tr = state.tr.setSelection(new TextSelection(state.tr.doc.resolve(end - 3), state.tr.doc.resolve(end))).replaceSelectionWith(schema.nodes.equation.create({ fieldKey }));
return tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1)));
}),
// create an inline view of a tag stored under the '#' field
- new InputRule(new RegExp(/#([a-zA-Z_\-]+[a-zA-Z_\-0-9]*)\s$/), (state, match, start, end) => {
+ new InputRule(/#([a-zA-Z_-]+[a-zA-Z_\-0-9]*)\s$/, (state, match, start, end) => {
const tag = match[1];
if (!tag) return state.tr;
- //this.Document[DocData]['#' + tag] = '#' + tag;
+ // this.Document[DocData]['#' + tag] = '#' + tag;
const tags = StrListCast(this.Document[DocData].tags);
if (!tags.includes(tag)) {
tags.push(tag);
@@ -383,29 +419,25 @@ export class RichTextRules {
}),
// # heading
- textblockTypeInputRule(new RegExp(/^(#{1,6})\s$/), schema.nodes.heading, match => {
- return { level: match[1].length };
- }),
+ textblockTypeInputRule(/^(#{1,6})\s$/, schema.nodes.heading, match => ({ level: match[1].length })),
// set the Todo user-tag on the current selection (assumes % was used to initiate an EnteringStyle mode)
- new InputRule(new RegExp(/[ti!x]$/), (state, match, start, end) => {
+ new InputRule(/[ti!x]$/, (state, match, start, end) => {
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;
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: any) => m.type === schema.marks.user_mark) !== -1) {
- }
return node
? state.tr
.removeMark(start, end, schema.marks.user_mark)
- .addMark(start, end, schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }))
- .addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: tag, modified: Math.round(Date.now() / 1000 / 60) }))
+ .addMark(start, end, schema.marks.user_mark.create({ userid: ClientUtils.CurrentUserEmail(), modified: Math.floor(Date.now() / 1000) }))
+ .addMark(start, end, schema.marks.user_tag.create({ userid: ClientUtils.CurrentUserEmail(), tag: tag, modified: Math.round(Date.now() / 1000 / 60) }))
: state.tr;
}),
- new InputRule(new RegExp(/%\(/), (state, match, start, end) => {
+ new InputRule(/%\(/, (state, match, start, end) => {
const node = (state.doc.resolve(start) as any).nodeAfter;
const sm = state.storedMarks?.slice() || [];
const mark = state.schema.marks.summarizeInclusive.create();
@@ -418,9 +450,7 @@ export class RichTextRules {
return replaced.setSelection(new TextSelection(replaced.doc.resolve(end))).setStoredMarks([...node.marks, ...sm]);
}),
- new InputRule(new RegExp(/%\)/), (state, match, start, end) => {
- return state.tr.deleteRange(start, end).removeStoredMark(state.schema.marks.summarizeInclusive.create());
- }),
+ 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/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx
index 7ec296ed2..238267f6e 100644
--- a/src/client/views/nodes/formattedText/SummaryView.tsx
+++ b/src/client/views/nodes/formattedText/SummaryView.tsx
@@ -3,6 +3,15 @@ import { Fragment, Node, Slice } from 'prosemirror-model';
import * as ReactDOM from 'react-dom/client';
import * as React from 'react';
+interface ISummaryView {}
+// currently nothing needs to be rendered for the internal view of a summary.
+// eslint-disable-next-line react/prefer-stateless-function
+export class SummaryViewInternal extends React.Component<ISummaryView> {
+ render() {
+ return null;
+ }
+}
+
// an elidable textblock that collapses when its '<-' is clicked and expands when its '...' anchor is clicked.
// this node actively edits prosemirror (as opposed to just changing how things are rendered) and thus doesn't
// really need a react view. However, it would be cleaner to figure out how to do this just as a react rendering
@@ -12,11 +21,10 @@ export class SummaryView {
root: any;
constructor(node: any, view: any, getPos: any) {
- const self = this;
this.dom = document.createElement('span');
this.dom.className = this.className(node.attrs.visibility);
- this.dom.onpointerdown = function (e: any) {
- self.onPointerDown(e, node, view, getPos);
+ this.dom.onpointerdown = (e: any) => {
+ this.onPointerDown(e, node, view, getPos);
};
this.dom.onkeypress = function (e: any) {
e.stopPropagation();
@@ -32,8 +40,8 @@ export class SummaryView {
};
const js = node.toJSON;
- node.toJSON = function () {
- return js.apply(this, arguments);
+ node.toJSON = function (...args: any[]) {
+ return js.apply(this, args);
};
this.root = ReactDOM.createRoot(this.dom);
@@ -54,7 +62,8 @@ export class SummaryView {
const visited = new Set();
for (let i: number = start + 1; i < view.state.doc.nodeSize - 1; i++) {
let skip = false;
- view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => {
+ // eslint-disable-next-line no-loop-func
+ view.state.doc.nodesBetween(start, i, (node: Node /* , pos: number, parent: Node, index: number */) => {
if (node.isLeaf && !visited.has(node) && !skip) {
if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) {
visited.add(node);
@@ -87,11 +96,3 @@ export class SummaryView {
this.dom.className = this.className(visible);
};
}
-
-interface ISummaryView {}
-// currently nothing needs to be rendered for the internal view of a summary.
-export class SummaryViewInternal extends React.Component<ISummaryView> {
- render() {
- return <> </>;
- }
-}
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index a141ef041..6e1f325cf 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -1,6 +1,5 @@
-import * as React from 'react';
-import { DOMOutputSpec, Fragment, MarkSpec, Node, NodeSpec, Schema, Slice } from 'prosemirror-model';
-import { Doc } from '../../../../fields/Doc';
+import { DOMOutputSpec, MarkSpec } from 'prosemirror-model';
+import { ClientUtils } from '../../../../ClientUtils';
import { Utils } from '../../../../Utils';
const emDOM: DOMOutputSpec = ['em', 0];
@@ -13,7 +12,7 @@ export const marks: { [index: string]: MarkSpec } = {
attrs: {
id: { default: '' },
},
- toDOM(node: any) {
+ toDOM() {
return ['div', { className: 'dummy' }, 0];
},
},
@@ -45,7 +44,7 @@ export const marks: { [index: string]: MarkSpec } = {
toDOM(node: any) {
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];
+ 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];
},
},
noAutoLinkAnchor: {
@@ -61,7 +60,7 @@ export const marks: { [index: string]: MarkSpec } = {
},
},
],
- toDOM(node: any) {
+ toDOM() {
return ['span', { 'data-noAutoLink': 'true' }, 0];
},
},
@@ -74,6 +73,7 @@ export const marks: { [index: string]: MarkSpec } = {
allAnchors: { default: [] as { href: string; title: string; anchorId: string }[] },
title: { default: null },
noPreview: { default: false },
+ fontSize: { default: null },
docref: { default: false }, // flags whether the linked text comes from a document within Dash. If so, an attribution label is appended after the text
},
inclusive: false,
@@ -93,14 +93,16 @@ export const marks: { [index: string]: MarkSpec } = {
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
? [
- 'div',
+ 'a',
['span', 0],
[
'span',
{
...node.attrs,
class: 'prosemirror-attribution',
+ 'data-targethrefs': targethrefs,
href: node.attrs.allAnchors[0].href,
+ style: `font-size: ${node.attrs.fontSize}`,
},
node.attrs.title,
],
@@ -125,29 +127,29 @@ export const marks: { [index: string]: MarkSpec } = {
/* FONTS */
pFontFamily: {
- attrs: { family: { default: '' } },
+ attrs: { fontFamily: { default: '' } },
parseDOM: [
{
tag: 'span',
getAttrs(dom: any) {
const cstyle = getComputedStyle(dom);
if (cstyle.font) {
- if (cstyle.font.indexOf('Times New Roman') !== -1) return { family: 'Times New Roman' };
- if (cstyle.font.indexOf('Arial') !== -1) return { family: 'Arial' };
- if (cstyle.font.indexOf('Georgia') !== -1) return { family: 'Georgia' };
- if (cstyle.font.indexOf('Comic Sans') !== -1) return { family: 'Comic Sans MS' };
- if (cstyle.font.indexOf('Tahoma') !== -1) return { family: 'Tahoma' };
- if (cstyle.font.indexOf('Crimson') !== -1) return { family: 'Crimson Text' };
+ if (cstyle.font.indexOf('Times New Roman') !== -1) return { fontFamily: 'Times New Roman' };
+ if (cstyle.font.indexOf('Arial') !== -1) return { fontFamily: 'Arial' };
+ if (cstyle.font.indexOf('Georgia') !== -1) return { fontFamily: 'Georgia' };
+ if (cstyle.font.indexOf('Comic Sans') !== -1) return { fontFamily: 'Comic Sans MS' };
+ if (cstyle.font.indexOf('Tahoma') !== -1) return { fontFamily: 'Tahoma' };
+ if (cstyle.font.indexOf('Crimson') !== -1) return { fontFamily: 'Crimson Text' };
}
- return { family: '' };
+ return { fontFamily: '' };
},
},
],
- toDOM: node => (node.attrs.family ? ['span', { style: `font-family: "${node.attrs.family}";` }] : ['span', 0]),
+ toDOM: node => (node.attrs.fontFamily ? ['span', { style: `font-family: "${node.attrs.fontFamily}";` }] : ['span', 0]),
},
// :: MarkSpec Coloring on text. Has `color` attribute that defined the color of the marked text.
pFontColor: {
- attrs: { color: { default: '' } },
+ attrs: { fontColor: { default: '' } },
inclusive: true,
parseDOM: [
{
@@ -157,24 +159,24 @@ export const marks: { [index: string]: MarkSpec } = {
},
},
],
- toDOM: node => (node.attrs.color ? ['span', { style: 'color:' + node.attrs.color }] : ['span', 0]),
+ toDOM: node => (node.attrs.fontColor ? ['span', { style: 'color:' + node.attrs.fontColor }] : ['span', 0]),
},
- marker: {
+ pFontHighlight: {
attrs: {
- highlight: { default: 'transparent' },
+ fontHighlight: { default: 'transparent' },
},
inclusive: true,
parseDOM: [
{
tag: 'span',
getAttrs(dom: any) {
- return { highlight: dom.getAttribute('backgroundColor') };
+ return { fontHighlight: dom.getAttribute('background-color') };
},
},
],
toDOM(node: any) {
- return node.attrs.highlight ? ['span', { style: 'background-color:' + node.attrs.highlight }] : ['span', { style: 'background-color: transparent' }];
+ return node.attrs.fontHighlight ? ['span', { style: 'background-color:' + node.attrs.fontHighlight }] : ['span', { style: 'background-color: transparent' }];
},
},
@@ -232,22 +234,6 @@ export const marks: { [index: string]: MarkSpec } = {
},
},
- metadata: {
- toDOM() {
- return ['span', { style: 'font-size:75%; background:rgba(100, 100, 100, 0.2); ' }];
- },
- },
- metadataKey: {
- toDOM() {
- return ['span', { style: 'font-style:italic; ' }];
- },
- },
- metadataVal: {
- toDOM() {
- return ['span'];
- },
- },
-
summarizeInclusive: {
parseDOM: [
{
@@ -349,7 +335,7 @@ export const marks: { [index: string]: MarkSpec } = {
const min = Math.round(node.attrs.modified / 60);
const hr = Math.round(min / 60);
const day = Math.round(hr / 60 / 24);
- const remote = node.attrs.userid !== Doc.CurrentUserEmail ? ' UM-remote' : '';
+ const remote = node.attrs.userid !== ClientUtils.CurrentUserEmail() ? ' UM-remote' : '';
return ['span', { class: 'UM-' + uid + remote + ' UM-min-' + min + ' UM-hr-' + hr + ' UM-day-' + day }, 0];
},
},
diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts
index 4706a97fa..5bf942218 100644
--- a/src/client/views/nodes/formattedText/nodes_rts.ts
+++ b/src/client/views/nodes/formattedText/nodes_rts.ts
@@ -1,18 +1,18 @@
-import * as React from 'react';
import { DOMOutputSpec, Node, NodeSpec } from 'prosemirror-model';
import { listItem, orderedList } from 'prosemirror-schema-list';
import { ParagraphNodeSpec, toParagraphDOM, getParagraphNodeAttrs } from './ParagraphNodeSpec';
import { DocServer } from '../../../DocServer';
-import { Doc, Field } from '../../../../fields/Doc';
+import { Doc, Field, FieldType } from '../../../../fields/Doc';
+import { schema } from './schema_rts';
-const blockquoteDOM: DOMOutputSpec = ['blockquote', 0],
- hrDOM: DOMOutputSpec = ['hr'],
- preDOM: DOMOutputSpec = ['pre', ['code', 0]],
- brDOM: DOMOutputSpec = ['br'],
- ulDOM: DOMOutputSpec = ['ul', 0];
+const blockquoteDOM: DOMOutputSpec = ['blockquote', 0];
+const hrDOM: DOMOutputSpec = ['hr'];
+const preDOM: DOMOutputSpec = ['pre', ['code', 0]];
+const brDOM: DOMOutputSpec = ['br'];
+// const ulDOM: DOMOutputSpec = ['ul', 0];
-function formatAudioTime(time: number) {
- time = Math.round(time);
+function formatAudioTime(timeIn: number) {
+ const time = Math.round(timeIn);
const hours = Math.floor(time / 60 / 60);
const minutes = Math.floor(time / 60) - hours * 60;
const seconds = time % 60;
@@ -25,6 +25,7 @@ export const nodes: { [index: string]: NodeSpec } = {
// :: NodeSpec The top level document node.
doc: {
content: 'block+',
+ marks: '_',
},
paragraph: ParagraphNodeSpec,
@@ -121,7 +122,6 @@ export const nodes: { [index: string]: NodeSpec } = {
...ParagraphNodeSpec.attrs,
level: { default: 1 },
},
- defining: true,
parseDOM: [
{ tag: 'h1', attrs: { level: 1 } },
{ tag: 'h2', attrs: { level: 2 } },
@@ -132,8 +132,7 @@ export const nodes: { [index: string]: NodeSpec } = {
],
toDOM(node) {
const dom = toParagraphDOM(node) as any;
- const level = node.attrs.level || 1;
- dom[0] = 'h' + level;
+ dom[0] = `h${node.attrs.level || 1}`;
return dom;
},
getAttrs(dom: any) {
@@ -265,9 +264,10 @@ export const nodes: { [index: string]: NodeSpec } = {
fieldKey: { default: '' },
docId: { default: '' },
hideKey: { default: false },
+ hideValue: { default: false },
editable: { default: true },
},
- leafText: node => Field.toString((DocServer.GetCachedRefField(node.attrs.docId as string) as Doc)?.[node.attrs.fieldKey as string] as Field),
+ leafText: node => Field.toString((DocServer.GetCachedRefField(node.attrs.docId as string) as Doc)?.[node.attrs.fieldKey as string] as FieldType),
group: 'inline',
draggable: false,
toDOM(node) {
@@ -331,12 +331,10 @@ export const nodes: { [index: string]: NodeSpec } = {
...orderedList,
content: 'list_item+',
group: 'block',
+ marks: '_',
attrs: {
bulletStyle: { default: 0 },
- mapStyle: { default: 'decimal' }, // "decimal", "multi", "bullet"
- fontColor: { default: 'inherit' },
- fontSize: { default: undefined },
- fontFamily: { default: undefined },
+ mapStyle: { default: 'decimal' }, // "decimal", "multi", "bullet",
visibility: { default: true },
indent: { default: undefined },
},
@@ -356,7 +354,7 @@ export const nodes: { [index: string]: NodeSpec } = {
},
{
style: 'list-style-type=disc',
- getAttrs(dom: any) {
+ getAttrs() {
return { mapStyle: 'bullet' };
},
},
@@ -376,9 +374,10 @@ export const nodes: { [index: string]: NodeSpec } = {
],
toDOM(node: Node) {
const map = node.attrs.bulletStyle ? node.attrs.mapStyle + node.attrs.bulletStyle : '';
- const fsize = node.attrs.fontSize ? `font-size: ${node.attrs.fontSize};` : '';
- const ffam = node.attrs.fontFamily ? `font-family:${node.attrs.fontFamily};` : '';
- const fcol = node.attrs.fontColor ? `color: ${node.attrs.fontColor};` : '';
+ const fhigh = (found => (found ? `background-color: ${found};` : ''))(node.marks.find(m => m.type === schema.marks.pFontHighlight)?.attrs.fontHighlight);
+ const fsize = (found => (found ? `font-size: ${found};` : ''))(node.marks.find(m => m.type === schema.marks.pFontSize)?.attrs.fontSize);
+ const ffam = (found => (found ? `font-family: ${found};` : ''))(node.marks.find(m => m.type === schema.marks.pFontFamily)?.attrs.fontFamily);
+ const fcol = (found => (found ? `color: ${found};` : ''))(node.marks.find(m => m.type === schema.marks.pFontColor)?.attrs.fontColor);
const marg = node.attrs.indent ? `margin-left: ${node.attrs.indent};` : '';
if (node.attrs.mapStyle === 'bullet') {
return [
@@ -386,7 +385,7 @@ export const nodes: { [index: string]: NodeSpec } = {
{
'data-mapStyle': node.attrs.mapStyle,
'data-bulletStyle': node.attrs.bulletStyle,
- style: `${fsize} ${ffam} ${fcol} ${marg}`,
+ style: `${fhigh} ${fsize} ${ffam} ${fcol} ${marg}`,
},
0,
];
@@ -398,7 +397,7 @@ export const nodes: { [index: string]: NodeSpec } = {
class: `${map}-ol`,
'data-mapStyle': node.attrs.mapStyle,
'data-bulletStyle': node.attrs.bulletStyle,
- style: `list-style: none; ${fsize} ${ffam} ${fcol} ${marg}`,
+ style: `list-style: none; ${fhigh} ${fsize} ${ffam} ${fcol} ${marg}`,
},
0,
]
@@ -422,16 +421,22 @@ export const nodes: { [index: string]: NodeSpec } = {
},
},
],
- toDOM(node: any) {
+ toDOM(node: Node) {
+ const fhigh = (found => (found ? `background-color: ${found};` : ''))(node.marks.find(m => m.type === schema.marks.pFontHighlight)?.attrs.fontHighlight);
+ const fsize = (found => (found ? `font-size: ${found};` : ''))(node.marks.find(m => m.type === schema.marks.pFontSize)?.attrs.fontSize);
+ const ffam = (found => (found ? `font-family: ${found};` : ''))(node.marks.find(m => m.type === schema.marks.pFontFamily)?.attrs.fontFamily);
+ const fcol = (found => (found ? `color: ${found};` : ''))(node.marks.find(m => m.type === schema.marks.pFontColor)?.attrs.fontColor);
const map = node.attrs.bulletStyle ? node.attrs.mapStyle + node.attrs.bulletStyle : '';
return [
'li',
- { class: `${map}`, 'data-mapStyle': node.attrs.mapStyle, 'data-bulletStyle': node.attrs.bulletStyle },
+ { class: `${map}`, style: `${fhigh} ${fsize} ${ffam} ${fcol} `, 'data-mapStyle': node.attrs.mapStyle, 'data-bulletStyle': node.attrs.bulletStyle },
node.attrs.visibility
? 0
: [
'span',
- { style: `position: relative; width: 100%; height: 1.5em; overflow: hidden; display: ${node.attrs.mapStyle !== 'bullet' ? 'inline-block' : 'list-item'}; text-overflow: ellipsis; white-space: pre` },
+ {
+ style: `${fhigh} ${fsize} ${ffam} ${fcol} position: relative; width: 100%; height: 1.5em; overflow: hidden; display: ${node.attrs.mapStyle !== 'bullet' ? 'inline-block' : 'list-item'}; text-overflow: ellipsis; white-space: pre`,
+ },
`${node.firstChild?.textContent}...`,
],
];
diff --git a/src/client/views/nodes/generativeFill/GenerativeFill.tsx b/src/client/views/nodes/generativeFill/GenerativeFill.tsx
index 87e1b69c3..6d8ba9222 100644
--- a/src/client/views/nodes/generativeFill/GenerativeFill.tsx
+++ b/src/client/views/nodes/generativeFill/GenerativeFill.tsx
@@ -1,33 +1,39 @@
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
+/* eslint-disable jsx-a11y/img-redundant-alt */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable react/function-component-definition */
import { Checkbox, FormControlLabel, Slider, TextField } from '@mui/material';
import { IconButton } from 'browndash-components';
+import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { CgClose } from 'react-icons/cg';
import { IoMdRedo, IoMdUndo } from 'react-icons/io';
+import { ClientUtils } from '../../../../ClientUtils';
import { Doc, DocListCast } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
import { NumCast } from '../../../../fields/Types';
-import { Utils } from '../../../../Utils';
-import { Docs, DocUtils } from '../../../documents/Documents';
import { Networking } from '../../../Network';
-import { DocumentManager } from '../../../util/DocumentManager';
+import { DocUtils } from '../../../documents/DocUtils';
+import { Docs } from '../../../documents/Documents';
import { CollectionDockingView } from '../../collections/CollectionDockingView';
import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
-import { OpenWhereMod } from '../DocumentView';
-import { ImageBox } from '../ImageBox';
+import { ImageEditorData } from '../ImageBox';
+import { OpenWhereMod } from '../OpenWhere';
import './GenerativeFill.scss';
import Buttons from './GenerativeFillButtons';
import { BrushHandler } from './generativeFillUtils/BrushHandler';
-import { activeColor, canvasSize, eraserColor, freeformRenderSize, newCollectionSize, offsetDistanceY, offsetX } from './generativeFillUtils/generativeFillConstants';
-import { CursorData, ImageDimensions, Point } from './generativeFillUtils/generativeFillInterfaces';
import { APISuccess, ImageUtility } from './generativeFillUtils/ImageHandler';
import { PointerHandler } from './generativeFillUtils/PointerHandler';
-import * as React from 'react';
+import { activeColor, canvasSize, eraserColor, freeformRenderSize, newCollectionSize, offsetDistanceY, offsetX } from './generativeFillUtils/generativeFillConstants';
+import { CursorData, ImageDimensions, Point } from './generativeFillUtils/generativeFillInterfaces';
+import { DocumentView } from '../DocumentView';
-enum BrushStyle {
- ADD,
- SUBTRACT,
- MARQUEE,
-}
+// enum BrushStyle {
+// ADD,
+// SUBTRACT,
+// MARQUEE,
+// }
interface GenerativeFillProps {
imageEditorOpen: boolean;
@@ -50,9 +56,9 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
const [isBrushing, setIsBrushing] = useState(false);
const [canvasScale, setCanvasScale] = useState(0.5);
// format: array of [image source, corresponding image Doc]
- const [edits, setEdits] = useState<(string | Doc)[][]>([]);
+ const [edits, setEdits] = useState<{ url: string; saveRes: Doc | undefined }[]>([]);
const [edited, setEdited] = useState(false);
- const [brushStyle, setBrushStyle] = useState<BrushStyle>(BrushStyle.ADD);
+ // const [brushStyle] = useState<BrushStyle>(BrushStyle.ADD);
const [input, setInput] = useState('');
const [loading, setLoading] = useState(false);
const [canvasDims, setCanvasDims] = useState<ImageDimensions>({
@@ -98,8 +104,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
if (!ctx || !currImg.current || !canvasRef.current) return;
const target = redoStack.current[redoStack.current.length - 1];
- if (!target) {
- } else {
+ if (target) {
undoStack.current = [...undoStack.current, canvasRef.current?.toDataURL()];
const img = new Image();
img.src = target;
@@ -131,11 +136,11 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
setIsBrushing(true);
const { x, y } = PointerHandler.getPointRelativeToElement(canvas, e, canvasScale);
- BrushHandler.brushCircleOverlay(x, y, cursorData.width / 2 / canvasScale, ctx, eraserColor, brushStyle === BrushStyle.SUBTRACT);
+ BrushHandler.brushCircleOverlay(x, y, cursorData.width / 2 / canvasScale, ctx, eraserColor /* , brushStyle === BrushStyle.SUBTRACT */);
};
// stop brushing, push to undo stack
- const handlePointerUp = (e: React.PointerEvent) => {
+ const handlePointerUp = () => {
const ctx = ImageUtility.getCanvasContext(canvasBackgroundRef);
if (!ctx) return;
if (!isBrushing) return;
@@ -144,11 +149,11 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
// handles brushing on pointer movement
useEffect(() => {
- if (!isBrushing) return;
+ if (!isBrushing) return undefined;
const canvas = canvasRef.current;
- if (!canvas) return;
+ if (!canvas) return undefined;
const ctx = ImageUtility.getCanvasContext(canvasRef);
- if (!ctx) return;
+ if (!ctx) return undefined;
const handlePointerMove = (e: PointerEvent) => {
const currPoint = PointerHandler.getPointRelativeToElement(canvas, e, canvasScale);
@@ -156,7 +161,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
x: currPoint.x - e.movementX / canvasScale,
y: currPoint.y - e.movementY / canvasScale,
};
- BrushHandler.createBrushPathOverlay(lastPoint, currPoint, cursorData.width / 2 / canvasScale, ctx, eraserColor, brushStyle === BrushStyle.SUBTRACT);
+ BrushHandler.createBrushPathOverlay(lastPoint, currPoint, cursorData.width / 2 / canvasScale, ctx, eraserColor /* , brushStyle === BrushStyle.SUBTRACT */);
};
drawingAreaRef.current?.addEventListener('pointermove', handlePointerMove);
@@ -290,12 +295,13 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
_height: newCollectionSize,
title: 'Image edit collection',
});
- DocUtils.MakeLink(imageRootDoc, newCollectionRef.current, { link_relationship: 'Image Edit Version History', link_displayLine: false });
+ DocUtils.MakeLink(imageRootDoc, newCollectionRef.current, { link_relationship: 'Image Edit Version History' });
// opening new tab
CollectionDockingView.AddSplit(newCollectionRef.current, OpenWhereMod.right);
// add the doc to the main freeform
+ // eslint-disable-next-line no-use-before-define
await createNewImgDoc(originalImg.current, true);
}
} else {
@@ -309,16 +315,18 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
const imgUrls = await Promise.all(urls.map(url => ImageUtility.convertImgToCanvasUrl(url, canvasDims.width, canvasDims.height)));
const imgRes = await Promise.all(
imgUrls.map(async url => {
+ // eslint-disable-next-line no-use-before-define
const saveRes = await onSave(url);
- return [url, saveRes as Doc];
+ return { url, saveRes };
})
);
setEdits(imgRes);
const image = new Image();
+ // eslint-disable-next-line prefer-destructuring
image.src = imgUrls[0];
ImageUtility.drawImgToCanvas(image, canvasRef, canvasDims.width, canvasDims.height);
currImg.current = image;
- parentDoc.current = imgRes[0][1] as Doc;
+ parentDoc.current = imgRes[0].saveRes ?? null;
}
} catch (err) {
console.log(err);
@@ -332,7 +340,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
const startY = NumCast(parentDoc.current.y);
const children = DocListCast(parentDoc.current.gen_fill_children);
const len = children.length;
- let initialYPositions: number[] = [];
+ const initialYPositions: number[] = [];
for (let i = 0; i < len; i++) {
initialYPositions.push(startY + i * offsetDistanceY);
}
@@ -347,10 +355,10 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
// creates a new image document and returns its reference
const createNewImgDoc = async (img: HTMLImageElement, firstDoc: boolean): Promise<Doc | undefined> => {
- if (!imageRootDoc) return;
- const src = img.src;
+ if (!imageRootDoc) return undefined;
+ const { src } = img;
const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [src] });
- const source = Utils.prepend(result.accessPaths.agnostic.client);
+ const source = ClientUtils.prepend(result.accessPaths.agnostic.client);
if (firstDoc) {
const x = 0;
@@ -370,59 +378,59 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
}
parentDoc.current = newImg;
return newImg;
- } else {
- if (!parentDoc.current) return;
- const x = NumCast(parentDoc.current.x) + freeformRenderSize + offsetX;
- const initialY = 0;
-
- const newImg = Docs.Create.ImageDocument(source, {
- x: x,
- y: initialY,
- _height: freeformRenderSize,
- _width: freeformRenderSize,
- data_nativeWidth: result.nativeWidth,
- data_nativeHeight: result.nativeHeight,
- });
+ }
+ if (!parentDoc.current) return undefined;
+ const x = NumCast(parentDoc.current.x) + freeformRenderSize + offsetX;
+ const initialY = 0;
+
+ const newImg = Docs.Create.ImageDocument(source, {
+ x: x,
+ y: initialY,
+ _height: freeformRenderSize,
+ _width: freeformRenderSize,
+ data_nativeWidth: result.nativeWidth,
+ data_nativeHeight: result.nativeHeight,
+ });
- const parentList = DocListCast(parentDoc.current.gen_fill_children);
- if (parentList.length > 0) {
- parentList.push(newImg);
- parentDoc.current.gen_fill_children = new List<Doc>(parentList);
- } else {
- parentDoc.current.gen_fill_children = new List<Doc>([newImg]);
- }
+ const parentList = DocListCast(parentDoc.current.gen_fill_children);
+ if (parentList.length > 0) {
+ parentList.push(newImg);
+ parentDoc.current.gen_fill_children = new List<Doc>(parentList);
+ } else {
+ parentDoc.current.gen_fill_children = new List<Doc>([newImg]);
+ }
- DocUtils.MakeLink(parentDoc.current, newImg, { link_relationship: `Image edit; Prompt: ${input}`, link_displayLine: true });
- adjustImgPositions();
+ DocUtils.MakeLink(parentDoc.current, newImg, { link_relationship: `Image edit; Prompt: ${input}` });
+ adjustImgPositions();
- if (isNewCollection && newCollectionRef.current) {
- Doc.AddDocToList(newCollectionRef.current, undefined, newImg);
- } else {
- addDoc?.(newImg);
- }
- return newImg;
+ if (isNewCollection && newCollectionRef.current) {
+ Doc.AddDocToList(newCollectionRef.current, undefined, newImg);
+ } else {
+ addDoc?.(newImg);
}
+ return newImg;
};
// Saves an image to the collection
const onSave = async (src: string) => {
const img = new Image();
img.src = src;
- if (!currImg.current || !originalImg.current || !imageRootDoc) return;
+ if (!currImg.current || !originalImg.current || !imageRootDoc) return undefined;
try {
const res = await createNewImgDoc(img, false);
return res;
} catch (err) {
console.log(err);
}
+ return undefined;
};
// Closes the editor view
const handleViewClose = () => {
- ImageBox.setImageEditorOpen(false);
- ImageBox.setImageEditorSource('');
+ ImageEditorData.Open = false;
+ ImageEditorData.Source = '';
if (newCollectionRef.current) {
- DocumentManager.Instance.AddViewRenderedCb(newCollectionRef.current, dv => (dv.ComponentView as CollectionFreeFormView)?.fitContentOnce());
+ DocumentView.addViewRenderedCb(newCollectionRef.current, dv => (dv.ComponentView as CollectionFreeFormView)?.fitContentOnce());
}
setEdits([]);
};
@@ -443,12 +451,12 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
}}
/>
}
- label={'Create New Collection'}
+ label="Create New Collection"
labelPlacement="end"
sx={{ whiteSpace: 'nowrap' }}
/>
<Buttons getEdit={getEdit} loading={loading} onReset={handleReset} />
- <IconButton color={activeColor} tooltip="close" icon={<CgClose size={'16px'} />} onClick={handleViewClose} />
+ <IconButton color={activeColor} tooltip="close" icon={<CgClose size="16px" />} onClick={handleViewClose} />
</div>
</div>
{/* Main canvas for editing */}
@@ -469,7 +477,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
width: cursorData.width,
height: cursorData.width,
}}>
- <div className="innerPointer"></div>
+ <div className="innerPointer" />
</div>
{/* Icons */}
<div className="iconContainer">
@@ -519,20 +527,22 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
/>
</div>
</div>
- {/* Edits thumbnails*/}
+ {/* Edits thumbnails */}
<div className="editsBox">
{edits.map((edit, i) => (
<img
+ // eslint-disable-next-line react/no-array-index-key
key={i}
+ alt="image edits"
width={75}
- src={edit[0] as string}
+ src={edit.url}
style={{ cursor: 'pointer' }}
onClick={async () => {
const img = new Image();
- img.src = edit[0] as string;
+ img.src = edit.url;
ImageUtility.drawImgToCanvas(img, canvasRef, canvasDims.width, canvasDims.height);
currImg.current = img;
- parentDoc.current = edit[1] as Doc;
+ parentDoc.current = edit.saveRes ?? null;
}}
/>
))}
@@ -552,6 +562,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
Original
</label>
<img
+ alt="image stuff"
width={75}
src={originalImg.current?.src}
style={{ cursor: 'pointer' }}
diff --git a/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx b/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx
index 185ba2280..d1f68ee0e 100644
--- a/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx
+++ b/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx
@@ -1,9 +1,9 @@
import './GenerativeFillButtons.scss';
import * as React from 'react';
import ReactLoading from 'react-loading';
-import { activeColor } from './generativeFillUtils/generativeFillConstants';
import { Button, IconButton, Type } from 'browndash-components';
import { AiOutlineInfo } from 'react-icons/ai';
+import { activeColor } from './generativeFillUtils/generativeFillConstants';
interface ButtonContainerProps {
getEdit: () => Promise<void>;
@@ -11,7 +11,7 @@ interface ButtonContainerProps {
onReset: () => void;
}
-const Buttons = ({ loading, getEdit, onReset }: ButtonContainerProps) => {
+function Buttons({ loading, getEdit, onReset }: ButtonContainerProps) {
return (
<div className="generativeFillBtnContainer">
<Button text="RESET" type={Type.PRIM} color={activeColor} onClick={onReset} />
@@ -20,7 +20,7 @@ const Buttons = ({ loading, getEdit, onReset }: ButtonContainerProps) => {
text="GET EDITS"
type={Type.TERT}
color={activeColor}
- icon={<ReactLoading type="spin" color={'#ffffff'} width={20} height={20} />}
+ icon={<ReactLoading type="spin" color="#ffffff" width={20} height={20} />}
iconPlacement="right"
onClick={() => {
if (!loading) getEdit();
@@ -36,9 +36,9 @@ const Buttons = ({ loading, getEdit, onReset }: ButtonContainerProps) => {
}}
/>
)}
- <IconButton type={Type.SEC} color={activeColor} tooltip="Open Documentation" icon={<AiOutlineInfo size={'16px'} />} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/generativeai/#editing', '_blank')} />
+ <IconButton type={Type.SEC} color={activeColor} tooltip="Open Documentation" icon={<AiOutlineInfo size="16px" />} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/generativeai/#editing', '_blank')} />
</div>
);
-};
+}
export default Buttons;
diff --git a/src/client/views/nodes/generativeFill/generativeFillUtils/BrushHandler.ts b/src/client/views/nodes/generativeFill/generativeFillUtils/BrushHandler.ts
index f4ec70fbc..16d529d93 100644
--- a/src/client/views/nodes/generativeFill/generativeFillUtils/BrushHandler.ts
+++ b/src/client/views/nodes/generativeFill/generativeFillUtils/BrushHandler.ts
@@ -3,7 +3,7 @@ import { eraserColor } from './generativeFillConstants';
import { Point } from './generativeFillInterfaces';
export class BrushHandler {
- static brushCircleOverlay = (x: number, y: number, brushRadius: number, ctx: CanvasRenderingContext2D, fillColor: string, erase: boolean) => {
+ static brushCircleOverlay = (x: number, y: number, brushRadius: number, ctx: CanvasRenderingContext2D, fillColor: string /* , erase: boolean */) => {
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = fillColor;
ctx.shadowColor = eraserColor;
@@ -14,12 +14,12 @@ export class BrushHandler {
ctx.closePath();
};
- static createBrushPathOverlay = (startPoint: Point, endPoint: Point, brushRadius: number, ctx: CanvasRenderingContext2D, fillColor: string, erase: boolean) => {
+ static createBrushPathOverlay = (startPoint: Point, endPoint: Point, brushRadius: number, ctx: CanvasRenderingContext2D, fillColor: string /* , erase: boolean */) => {
const dist = GenerativeFillMathHelpers.distanceBetween(startPoint, endPoint);
for (let i = 0; i < dist; i += 5) {
const s = i / dist;
- BrushHandler.brushCircleOverlay(startPoint.x * (1 - s) + endPoint.x * s, startPoint.y * (1 - s) + endPoint.y * s, brushRadius, ctx, fillColor, erase);
+ BrushHandler.brushCircleOverlay(startPoint.x * (1 - s) + endPoint.x * s, startPoint.y * (1 - s) + endPoint.y * s, brushRadius, ctx, fillColor /* , erase */);
}
};
}
diff --git a/src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts b/src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts
index 97e03ff20..6da8c3da0 100644
--- a/src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts
+++ b/src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts
@@ -1,10 +1,6 @@
import { Point } from './generativeFillInterfaces';
export class GenerativeFillMathHelpers {
- static distanceBetween = (p1: Point, p2: Point) => {
- return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
- };
- static angleBetween = (p1: Point, p2: Point) => {
- return Math.atan2(p2.x - p1.x, p2.y - p1.y);
- };
+ static distanceBetween = (p1: Point, p2: Point) => Math.sqrt((p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2);
+ static angleBetween = (p1: Point, p2: Point) => Math.atan2(p2.x - p1.x, p2.y - p1.y);
}
diff --git a/src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts b/src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts
index 47a14135f..24dba1778 100644
--- a/src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts
+++ b/src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts
@@ -17,15 +17,14 @@ export class ImageUtility {
* @param canvas Canvas to convert
* @returns Blob of canvas
*/
- static canvasToBlob = (canvas: HTMLCanvasElement): Promise<Blob> => {
- return new Promise(resolve => {
+ static canvasToBlob = (canvas: HTMLCanvasElement): Promise<Blob> =>
+ new Promise(resolve => {
canvas.toBlob(blob => {
if (blob) {
resolve(blob);
}
}, 'image/png');
});
- };
// given a square api image, get the cropped img
static getCroppedImg = (img: HTMLImageElement, width: number, height: number): HTMLCanvasElement | undefined => {
@@ -48,11 +47,12 @@ export class ImageUtility {
}
return canvas;
}
+ return undefined;
};
// converts an image to a canvas data url
- static convertImgToCanvasUrl = async (imageSrc: string, width: number, height: number): Promise<string> => {
- return new Promise<string>((resolve, reject) => {
+ static convertImgToCanvasUrl = async (imageSrc: string, width: number, height: number): Promise<string> =>
+ new Promise<string>((resolve, reject) => {
const img = new Image();
img.onload = () => {
const canvas = this.getCroppedImg(img, width, height);
@@ -66,7 +66,6 @@ export class ImageUtility {
};
img.src = imageSrc;
});
- };
// calls the openai api to get image edits
static getEdit = async (imgBlob: Blob, maskBlob: Blob, prompt: string, n?: number): Promise<APISuccess | APIError> => {
@@ -91,7 +90,7 @@ export class ImageUtility {
console.log(data.data);
return {
status: 'success',
- urls: (data.data as { b64_json: string }[]).map(data => `data:image/png;base64,${data.b64_json}`),
+ urls: (data.data as { b64_json: string }[]).map(urlData => `data:image/png;base64,${urlData.b64_json}`),
};
} catch (err) {
console.log(err);
@@ -100,12 +99,10 @@ export class ImageUtility {
};
// mock api call
- static mockGetEdit = async (mockSrc: string): Promise<APISuccess | APIError> => {
- return {
- status: 'success',
- urls: [mockSrc, mockSrc, mockSrc],
- };
- };
+ static mockGetEdit = async (mockSrc: string): Promise<APISuccess | APIError> => ({
+ status: 'success',
+ urls: [mockSrc, mockSrc, mockSrc],
+ });
// Gets the canvas rendering context of a canvas
static getCanvasContext = (canvasRef: RefObject<HTMLCanvasElement>): CanvasRenderingContext2D | null => {
@@ -150,12 +147,12 @@ export class ImageUtility {
// Draws the image to the current canvas
static drawImgToCanvas = (img: HTMLImageElement, canvasRef: React.RefObject<HTMLCanvasElement>, width: number, height: number) => {
- const drawImg = (img: HTMLImageElement) => {
+ const drawImg = (htmlImg: HTMLImageElement) => {
const ctx = this.getCanvasContext(canvasRef);
if (!ctx) return;
ctx.globalCompositeOperation = 'source-over';
ctx.clearRect(0, 0, width, height);
- ctx.drawImage(img, 0, 0, width, height);
+ ctx.drawImage(htmlImg, 0, 0, width, height);
};
if (img.complete) {
@@ -173,7 +170,7 @@ export class ImageUtility {
canvas.width = canvasSize;
canvas.height = canvasSize;
const ctx = canvas.getContext('2d');
- if (!ctx) return;
+ if (!ctx) return undefined;
ctx?.clearRect(0, 0, canvasSize, canvasSize);
ctx.drawImage(paddedCanvas, 0, 0);
@@ -195,7 +192,7 @@ export class ImageUtility {
// Fills in the blank areas of the image with an image reflection (to fill in a square-shaped canvas)
static drawHorizontalReflection = (ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, xOffset: number) => {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
- const data = imageData.data;
+ const { data } = imageData;
for (let i = 0; i < canvas.height; i++) {
for (let j = 0; j < xOffset; j++) {
const targetIdx = 4 * (i * canvas.width + j);
@@ -224,7 +221,7 @@ export class ImageUtility {
// Fills in the blank areas of the image with an image reflection (to fill in a square-shaped canvas)
static drawVerticalReflection = (ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, yOffset: number) => {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
- const data = imageData.data;
+ const { data } = imageData;
for (let j = 0; j < canvas.width; j++) {
for (let i = 0; i < yOffset; i++) {
const targetIdx = 4 * (i * canvas.width + j);
@@ -256,7 +253,7 @@ export class ImageUtility {
canvas.width = canvasSize;
canvas.height = canvasSize;
const ctx = canvas.getContext('2d');
- if (!ctx) return;
+ if (!ctx) return undefined;
// fix scaling
const scale = Math.min(canvasSize / img.width, canvasSize / img.height);
const width = Math.floor(img.width * scale);
@@ -310,5 +307,6 @@ export class ImageUtility {
} catch (err) {
console.error(err);
}
+ return undefined;
};
}
diff --git a/src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts b/src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts
index 9e620ad11..260923a64 100644
--- a/src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts
+++ b/src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts
@@ -1,15 +1,11 @@
-import { Point } from "./generativeFillInterfaces";
+import { Point } from './generativeFillInterfaces';
export class PointerHandler {
- static getPointRelativeToElement = (
- element: HTMLElement,
- e: React.PointerEvent | PointerEvent,
- scale: number
- ): Point => {
- const boundingBox = element.getBoundingClientRect();
- return {
- x: (e.clientX - boundingBox.x) / scale,
- y: (e.clientY - boundingBox.y) / scale,
+ static getPointRelativeToElement = (element: HTMLElement, e: React.PointerEvent | PointerEvent, scale: number): Point => {
+ const boundingBox = element.getBoundingClientRect();
+ return {
+ x: (e.clientX - boundingBox.x) / scale,
+ y: (e.clientY - boundingBox.y) / scale,
+ };
};
- };
}
diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx
index 6e7c3e612..317719032 100644
--- a/src/client/views/nodes/importBox/ImportElementBox.tsx
+++ b/src/client/views/nodes/importBox/ImportElementBox.tsx
@@ -1,7 +1,7 @@
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { returnFalse } from '../../../../Utils';
+import { returnFalse } from '../../../../ClientUtils';
import { Doc } from '../../../../fields/Doc';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { DocumentView } from '../DocumentView';
@@ -22,13 +22,14 @@ export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
return (
<div style={{ backgroundColor: 'pink' }}>
<DocumentView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props} //
LayoutTemplateString={undefined}
Document={this.Document}
isContentActive={returnFalse}
addDocument={returnFalse}
ScreenToLocalTransform={this.screenToLocalXf}
- hideResizeHandles={true}
+ hideResizeHandles
/>
</div>
);
diff --git a/src/client/views/nodes/trails/CubicBezierEditor.tsx b/src/client/views/nodes/trails/CubicBezierEditor.tsx
new file mode 100644
index 000000000..e1ad1e6e5
--- /dev/null
+++ b/src/client/views/nodes/trails/CubicBezierEditor.tsx
@@ -0,0 +1,202 @@
+import React, { useEffect, useState } from 'react';
+
+type Props = {
+ setFunc: (newPoints: { p1: number[]; p2: number[] }) => void;
+ currPoints: { p1: number[]; p2: number[] };
+};
+
+const ANIMATION_DURATION = 750;
+
+const CONTAINER_WIDTH = 200;
+const EDITOR_WIDTH = 100;
+const OFFSET = (CONTAINER_WIDTH - EDITOR_WIDTH) / 2;
+
+export const TIMING_DEFAULT_MAPPINGS = {
+ ease: 'cubic-bezier(0.25, 0.1, 0.25, 1.0)',
+ linear: 'cubic-bezier(0.0, 0.0, 1.0, 1.0)',
+ 'ease-in': 'cubic-bezier(0.42, 0, 1.0, 1.0)',
+ 'ease-out': 'cubic-bezier(0, 0, 0.58, 1.0)',
+ 'ease-in-out': 'cubic-bezier(0.42, 0, 0.58, 1.0)',
+};
+
+export function EaseFuncToPoints(func: string) {
+ let strPoints = func || 'ease';
+ if (!strPoints.startsWith('cubic')) {
+ switch (func) {
+ case 'linear':
+ strPoints = 'cubic-bezier(0.0, 0.0, 1.0, 1.0)';
+ break;
+ case 'ease':
+ strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)';
+ break;
+ case 'ease-in':
+ strPoints = 'cubic-bezier(0.42, 0, 1.0, 1.0)';
+ break;
+ case 'ease-out':
+ strPoints = 'cubic-bezier(0, 0, 0.58, 1.0)';
+ break;
+ case 'ease-in-out':
+ strPoints = 'cubic-bezier(0.42, 0, 0.58, 1.0)';
+ break;
+ default:
+ strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)';
+ }
+ }
+ const components = strPoints
+ .split('(')[1]
+ .split(')')[0]
+ .split(',')
+ .map(elem => parseFloat(elem));
+ return {
+ p1: [components[0], components[1]],
+ p2: [components[2], components[3]],
+ };
+}
+
+/**
+ * Visual editor for a bezier curve with draggable control points.
+ * */
+
+function CubicBezierEditor({ setFunc, currPoints }: Props) {
+ const [animating, setAnimating] = useState(false);
+ const [c1Down, setC1Down] = useState(false);
+ const [c2Down, setC2Down] = useState(false);
+
+ const roundToHundredth = (num: number) => Math.round(num * 100) / 100;
+
+ useEffect(() => {
+ if (animating) {
+ setTimeout(() => {
+ setAnimating(false);
+ }, ANIMATION_DURATION * 2);
+ }
+ }, [animating]);
+
+ useEffect(() => {
+ if (!c1Down) return undefined;
+ window.addEventListener('pointerup', () => {
+ setC1Down(false);
+ });
+ const handlePointerMove = (e: PointerEvent) => {
+ const newX = currPoints.p1[0] + e.movementX / EDITOR_WIDTH;
+ if (newX < 0 || newX > 1) {
+ return;
+ }
+
+ setFunc({
+ ...currPoints,
+ p1: [roundToHundredth(currPoints.p1[0] + e.movementX / EDITOR_WIDTH), roundToHundredth(currPoints.p1[1] - e.movementY / EDITOR_WIDTH)],
+ });
+ };
+
+ window.addEventListener('pointermove', handlePointerMove);
+
+ return () => window.removeEventListener('pointermove', handlePointerMove);
+ }, [c1Down, currPoints]);
+
+ // Sets up pointer events for moving the control points
+ useEffect(() => {
+ if (!c2Down) return undefined;
+ window.addEventListener('pointerup', () => {
+ setC2Down(false);
+ });
+ const handlePointerMove = (e: PointerEvent) => {
+ const newX = currPoints.p2[0] + e.movementX / EDITOR_WIDTH;
+ if (newX < 0 || newX > 1) {
+ return;
+ }
+
+ setFunc({
+ ...currPoints,
+ p2: [roundToHundredth(currPoints.p2[0] + e.movementX / EDITOR_WIDTH), roundToHundredth(currPoints.p2[1] - e.movementY / EDITOR_WIDTH)],
+ });
+ };
+
+ window.addEventListener('pointermove', handlePointerMove);
+
+ return () => window.removeEventListener('pointermove', handlePointerMove);
+ }, [c2Down, currPoints]);
+
+ return (
+ <div
+ onPointerMove={e => {
+ e.stopPropagation;
+ }}>
+ <svg className="presBox-bezier-editor" width={`${CONTAINER_WIDTH}`} height={`${CONTAINER_WIDTH}`} xmlns="http://www.w3.org/2000/svg">
+ {/* Outlines */}
+ <line x1={`${0 + OFFSET}`} y1={`${EDITOR_WIDTH + OFFSET}`} x2={`${EDITOR_WIDTH + OFFSET}`} y2={`${0 + OFFSET}`} stroke="#c1c1c1" strokeWidth="1" />
+ {/* Box Outline */}
+ <rect x={`${0 + OFFSET}`} y={`${0 + OFFSET}`} width={EDITOR_WIDTH} height={EDITOR_WIDTH} stroke="#c5c5c5" fill="transparent" strokeWidth="1" />
+ {/* Editor */}
+ <path
+ d={`M ${0 + OFFSET} ${EDITOR_WIDTH + OFFSET} C ${currPoints.p1[0] * EDITOR_WIDTH + OFFSET} ${EDITOR_WIDTH - currPoints.p1[1] * EDITOR_WIDTH + OFFSET}, ${
+ currPoints.p2[0] * EDITOR_WIDTH + OFFSET
+ } ${EDITOR_WIDTH - currPoints.p2[1] * EDITOR_WIDTH + OFFSET}, ${EDITOR_WIDTH + OFFSET} ${0 + OFFSET}`}
+ stroke="#ffffff"
+ fill="transparent"
+ />
+ {/* Bottom left */}
+ <line
+ onPointerDown={() => {
+ setC1Down(true);
+ }}
+ onPointerUp={() => {
+ setC1Down(false);
+ }}
+ x1={`${0 + OFFSET}`}
+ y1={`${EDITOR_WIDTH + OFFSET}`}
+ x2={`${currPoints.p1[0] * EDITOR_WIDTH + OFFSET}`}
+ y2={`${EDITOR_WIDTH - currPoints.p1[1] * EDITOR_WIDTH + OFFSET}`}
+ stroke="#00000000"
+ strokeWidth="5"
+ />
+ <line x1={`${0 + OFFSET}`} y1={`${EDITOR_WIDTH + OFFSET}`} x2={`${currPoints.p1[0] * EDITOR_WIDTH + OFFSET}`} y2={`${EDITOR_WIDTH - currPoints.p1[1] * EDITOR_WIDTH + OFFSET}`} stroke="#ffffff" strokeWidth="1" />
+ <circle
+ cx={`${currPoints.p1[0] * EDITOR_WIDTH + OFFSET}`}
+ cy={`${EDITOR_WIDTH - currPoints.p1[1] * EDITOR_WIDTH + OFFSET}`}
+ r="5"
+ fill={`${c1Down ? '#3fa9ff' : '#ffffff'}`}
+ onPointerDown={e => {
+ e.stopPropagation();
+ setC1Down(true);
+ }}
+ onPointerUp={() => {
+ setC1Down(false);
+ }}
+ />
+ {/* Top right */}
+ <line
+ onPointerDown={e => {
+ e.stopPropagation();
+ setC2Down(true);
+ }}
+ onPointerUp={() => {
+ setC2Down(false);
+ }}
+ x1={`${EDITOR_WIDTH + OFFSET}`}
+ y1={`${0 + OFFSET}`}
+ x2={`${currPoints.p2[0] * EDITOR_WIDTH + OFFSET}`}
+ y2={`${EDITOR_WIDTH - currPoints.p2[1] * EDITOR_WIDTH + OFFSET}`}
+ stroke="#00000000"
+ strokeWidth="5"
+ />
+ <line x1={`${EDITOR_WIDTH + OFFSET}`} y1={`${0 + OFFSET}`} x2={`${currPoints.p2[0] * EDITOR_WIDTH + OFFSET}`} y2={`${EDITOR_WIDTH - currPoints.p2[1] * EDITOR_WIDTH + OFFSET}`} stroke="#ffffff" strokeWidth="1" />
+ <circle
+ cx={`${currPoints.p2[0] * EDITOR_WIDTH + OFFSET}`}
+ cy={`${EDITOR_WIDTH - currPoints.p2[1] * EDITOR_WIDTH + OFFSET}`}
+ r="5"
+ fill={`${c2Down ? '#3fa9ff' : '#ffffff'}`}
+ onPointerDown={e => {
+ e.stopPropagation();
+ setC2Down(true);
+ }}
+ onPointerUp={() => {
+ setC2Down(false);
+ }}
+ />
+ </svg>
+ </div>
+ );
+}
+
+export default CubicBezierEditor;
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss
index 3b34a1f90..60d4e580d 100644
--- a/src/client/views/nodes/trails/PresBox.scss
+++ b/src/client/views/nodes/trails/PresBox.scss
@@ -1,5 +1,101 @@
@import '../../global/globalCssVariables.module.scss';
+.presBox-gpt-chat {
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.pres-chat {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.presBox-icon-list {
+ display: flex;
+ gap: 8px;
+}
+
+.pres-chatbox-container {
+ padding: 16px;
+ outline: 1px solid #999999;
+ border-radius: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.pres-chatbox {
+ outline: none;
+ border: none;
+ resize: none;
+ font-family: Verdana, Geneva, sans-serif;
+ background-color: transparent;
+ overflow-y: hidden;
+}
+
+// Effect Animations
+
+.presBox-effects {
+ display: grid;
+ grid-template-columns: auto auto;
+ gap: 8px;
+}
+
+.presBox-effect-row {
+ display: flex;
+ gap: 8px;
+ margin: 4px;
+}
+
+.presBox-effect-container {
+ cursor: pointer;
+ overflow: hidden;
+ width: 80px;
+ height: 80px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 1px solid rgb(118, 118, 118);
+ border-radius: 8px;
+}
+
+.presBox-effect-demo-box {
+ width: 40px;
+ height: 40px;
+ border-radius: 4px;
+ // default bg
+ background-color: rgb(37, 161, 255);
+}
+
+// Bezier editor
+
+.presBox-show-hide-dropdown {
+ cursor: pointer;
+ padding: 8px 0;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.presBox-bezier-editor {
+ border: 1px solid rgb(221, 221, 221);
+ border-radius: 4px;
+}
+
+.presBox-option-block {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ padding: 16px;
+}
+
+.presBox-option-center {
+ align-items: center;
+}
+
.presBox-cont {
cursor: auto;
position: absolute;
@@ -15,6 +111,29 @@
//overflow: hidden;
transition: 0.7s opacity ease;
+ .presBox-chatbox {
+ position: fixed;
+ bottom: 8px;
+ left: 8px;
+ width: calc(100% - 16px);
+ min-height: 100px;
+ border-radius: 16px;
+ padding: 16px;
+ gap: 8px;
+ z-index: 999;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ background-color: #ffffff;
+ box-shadow: 0 2px 5px #7474748d;
+
+ .pres-chatbox {
+ outline: none;
+ border: none;
+ resize: none;
+ }
+ }
+
.presBox-listCont {
position: relative;
height: calc(100% - 67px);
@@ -150,6 +269,11 @@
}
}
+.presBox-toggles {
+ display: flex;
+ overflow-x: auto;
+}
+
.presBox-ribbon {
position: relative;
display: inline;
@@ -158,7 +282,9 @@
transition: 0.7s;
.ribbon-doubleButton {
- display: inline-flex;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
}
.presBox-reactiveGrid {
@@ -186,16 +312,18 @@
.ribbon-property {
font-size: 11;
font-weight: 200;
- height: 20;
- display: flex;
- margin-left: 5px;
- margin-top: 5px;
- margin-bottom: 5px;
- width: max-content;
- justify-content: center;
- align-items: center;
- padding-right: 10px;
- padding-left: 10px;
+ padding: 8px;
+ border-radius: 4px;
+ // height: 20;
+ // display: flex;
+ // margin-left: 5px;
+ // margin-top: 5px;
+ // margin-bottom: 5px;
+ // width: max-content;
+ // justify-content: center;
+ // align-items: center;
+ // padding-right: 10px;
+ // padding-left: 10px;
}
.ribbon-propertyUpDown {
@@ -392,11 +520,16 @@
}
.presBox-input {
- width: 30;
- height: 100%;
- background: none;
border: none;
- text-align: right;
+ background-color: transparent;
+ width: 40;
+ // padding: 8px;
+ // border-radius: 4px;
+ // width: 30;
+ // height: 100%;
+ // background: none;
+ // border: none;
+ // text-align: right;
}
.presBox-input:focus {
@@ -606,15 +739,14 @@
background-color: $white;
display: flex;
color: $black;
- margin-top: 5px;
- margin-bottom: 5px;
border-radius: 5px;
- margin-right: 5px;
width: max-content;
justify-content: center;
align-items: center;
padding-right: 10px;
padding-left: 10px;
+ margin: 4px;
+ text-wrap: nowrap;
}
.ribbon-toggle.active {
@@ -638,7 +770,7 @@
grid-template-rows: max-content auto;
justify-self: center;
margin-top: 10px;
- padding-right: 10px;
+ // padding-right: 10px;
letter-spacing: normal;
width: 100%;
height: max-content;
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index e34144fae..101f28ae7 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1,82 +1,74 @@
+/* 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';
+import { Button, Dropdown, DropdownType, IconButton, Toggle, ToggleType, Type } from 'browndash-components';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, Field, FieldResult, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
+import { AiOutlineSend } from 'react-icons/ai';
+import { BiMicrophone } from 'react-icons/bi';
+import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp } from 'react-icons/fa';
+import ReactLoading from 'react-loading';
+import ReactTextareaAutosize from 'react-textarea-autosize';
+import { lightOrDark, returnFalse, returnOne, setupMoveUpEvents, StopEvent } from '../../../../ClientUtils';
+import { Doc, DocListCast, Field, FieldResult, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
import { Animation, DocData, TransitionTimer } from '../../../../fields/DocSymbols';
-import { Copy, Id } from '../../../../fields/FieldSymbols';
+import { Copy } from '../../../../fields/FieldSymbols';
import { InkField } from '../../../../fields/InkField';
import { List } from '../../../../fields/List';
import { ObjectField } from '../../../../fields/ObjectField';
import { listSpec } from '../../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { AudioField } from '../../../../fields/URLField';
-import { emptyFunction, emptyPath, lightOrDark, returnFalse, returnOne, setupMoveUpEvents, StopEvent, stringHash } from '../../../../Utils';
+import { BoolCast, Cast, DocCast, NumCast, StrCast, toList } from '../../../../fields/Types';
+import { emptyFunction, emptyPath, stringHash } from '../../../../Utils';
+import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/customization';
import { DocServer } from '../../../DocServer';
import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
-import { DocumentManager } from '../../../util/DocumentManager';
+import { DictationManager } from '../../../util/DictationManager';
+import { dropActionType } from '../../../util/DropActionTypes';
import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
-import { SelectionManager } from '../../../util/SelectionManager';
import { SerializationHelper } from '../../../util/SerializationHelper';
-import { SettingsManager } from '../../../util/SettingsManager';
+import { SnappingManager } from '../../../util/SnappingManager';
import { undoBatch, UndoManager } from '../../../util/UndoManager';
-import { CollectionDockingView } from '../../collections/CollectionDockingView';
-import { CollectionFreeFormView, MarqueeViewBounds } from '../../collections/collectionFreeForm';
-import { CollectionStackedTimeline } from '../../collections/CollectionStackedTimeline';
+import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
+import { CollectionFreeFormPannableContents } from '../../collections/collectionFreeForm/CollectionFreeFormPannableContents';
import { CollectionView } from '../../collections/CollectionView';
import { TreeView } from '../../collections/TreeView';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
-import { LightboxView } from '../../LightboxView';
-import { DocumentView, OpenWhere, OpenWhereMod } from '../DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView';
+import { pinDataTypes as dataTypes } from '../../PinFuncs';
+import { DocumentView } from '../DocumentView';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
+import { OpenWhere, OpenWhereMod } from '../OpenWhere';
import { ScriptingBox } from '../ScriptingBox';
+import CubicBezierEditor, { EaseFuncToPoints, TIMING_DEFAULT_MAPPINGS } from './CubicBezierEditor';
import './PresBox.scss';
import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
-import { dropActionType } from '../../../util/DragManager';
-export interface pinDataTypes {
- scrollable?: boolean;
- dataviz?: number[];
- pannable?: boolean;
- type_collection?: boolean;
- inkable?: boolean;
- filters?: boolean;
- pivot?: boolean;
- temporal?: boolean;
- clippable?: boolean;
- datarange?: boolean;
- dataview?: boolean;
- poslayoutview?: boolean;
- dataannos?: boolean;
- map?: boolean;
-}
-export interface PinProps {
- audioRange?: boolean;
- activeFrame?: number;
- currentFrame?: number;
- hidePresBox?: boolean;
- pinViewport?: MarqueeViewBounds; // pin a specific viewport on a freeform view (use MarqueeView.CurViewBounds to compute if no region has been selected)
- pinDocLayout?: boolean; // pin layout info (width/height/x/y)
- pinAudioPlay?: boolean; // pin audio annotation
- pinData?: pinDataTypes;
-}
+import SlideEffect from './SlideEffect';
+import { AnimationSettings, easeItems, effectItems, effectTimings, movementItems, presEffectDefaultTimings, springMappings, springPreviewColors, SpringSettings, SpringType } from './SpringUtils';
@observer
export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(PresBox, fieldKey);
}
+ private static _getTabDocs: () => Doc[];
+ public static Init(tabDocs: () => Doc[]) {
+ PresBox._getTabDocs = tabDocs;
+ }
static navigateToDocScript: ScriptField;
constructor(props: FieldViewProps) {
super(props);
makeObservable(this);
if (!PresBox.navigateToDocScript) {
- PresBox.navigateToDocScript = ScriptField.MakeFunction('navigateToDoc(this.presentation_targetDoc, self)')!;
+ PresBox.navigateToDocScript = ScriptField.MakeFunction('navigateToDoc(this.presentation_targetDoc, this)')!;
}
+ CollectionFreeFormPannableContents.SetOverlayPlugin((fform: Doc) => PresBox.Instance.pathLines(fform));
}
private _disposers: { [name: string]: IReactionDisposer } = {};
@@ -86,6 +78,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
_unmounting = false; // flag that view is unmounting used to block RemFromMap from deleting things
_presTimer: NodeJS.Timeout | undefined;
+ // eslint-disable-next-line no-use-before-define
@observable public static Instance: PresBox;
@observable _isChildActive = false;
@@ -104,7 +97,100 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable _treeViewMap: Map<Doc, number> = new Map();
@observable _presKeyEvents: boolean = false;
@observable _forceKeyEvents: boolean = false;
- @computed get isTreeOrStack() {
+
+ // GPT
+ private _inputref: HTMLTextAreaElement | null = null;
+ private _inputref2: HTMLTextAreaElement | null = null;
+ @observable chatActive: boolean = false;
+ @observable chatInput: string = '';
+ public slideToModify: Doc | null = null;
+ @observable isRecording: boolean = false;
+ @observable isLoading: boolean = false;
+
+ @observable generatedAnimations: AnimationSettings[] = [
+ // default presets
+ {
+ effect: PresEffect.Bounce,
+ direction: PresEffectDirection.Left,
+ stiffness: 400,
+ damping: 15,
+ mass: 1,
+ },
+ {
+ effect: PresEffect.Fade,
+ direction: PresEffectDirection.Left,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ {
+ effect: PresEffect.Flip,
+ direction: PresEffectDirection.Left,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ {
+ effect: PresEffect.Rotate,
+ direction: PresEffectDirection.Left,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ ];
+
+ @action
+ setGeneratedAnimations = (settings: AnimationSettings[]) => {
+ this.generatedAnimations = settings;
+ };
+
+ @observable animationChat: string = '';
+
+ @action
+ setChatInput = (input: string) => {
+ this.chatInput = input;
+ };
+
+ @action
+ setAnimationChat = (input: string) => {
+ this.animationChat = input;
+ };
+
+ @action
+ setIsLoading = (isLoading: boolean) => {
+ this.isLoading = isLoading;
+ };
+
+ @action
+ public setIsRecording = (isRecording: boolean) => {
+ this.isRecording = isRecording;
+ };
+
+ @observable showBezierEditor = false;
+ @action setBezierEditorVisibility = (visible: boolean) => {
+ this.showBezierEditor = visible;
+ };
+ @observable showSpringEditor = true;
+ @action setSpringEditorVisibility = (visible: boolean) => {
+ this.showSpringEditor = visible;
+ };
+
+ // Easing function variables
+
+ @observable easeDropdownVal = 'ease';
+
+ @action setBezierControlPoints = (newPoints: { p1: number[]; p2: number[] }) => {
+ this.setEaseFunc(this.activeItem, `cubic-bezier(${newPoints.p1[0]}, ${newPoints.p1[1]}, ${newPoints.p2[0]}, ${newPoints.p2[1]})`);
+ };
+
+ @computed
+ get currCPoints() {
+ const strPoints = this.activeItem.presentation_easeFunc ? StrCast(this.activeItem.presentation_easeFunc) : 'ease';
+ return EaseFuncToPoints(strPoints);
+ }
+
+ @computed
+ get isTreeOrStack() {
return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._type_collection) as any);
}
@computed get isTree() {
@@ -126,7 +212,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return DocCast(this.childDocs[NumCast(this.Document._itemIndex)]);
}
@computed get targetDoc() {
- return Cast(this.activeItem?.presentation_targetDoc, Doc, null);
+ return DocCast(this.activeItem?.presentation_targetDoc);
}
public static targetRenderedDoc = (doc: Doc) => {
const targetDoc = Cast(doc?.presentation_targetDoc, Doc, null);
@@ -141,8 +227,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return false;
}
@computed get selectedDocumentView() {
- if (SelectionManager.Views.length) return SelectionManager.Views[0];
- if (this.selectedArray.size) return DocumentManager.Instance.getDocumentView(this.Document);
+ if (DocumentView.Selected().length) return DocumentView.Selected()[0];
+ if (this.selectedArray.size) return DocumentView.getDocumentView(this.Document);
+ return undefined;
}
@computed get isPres() {
return this.selectedDoc === this.Document;
@@ -165,6 +252,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
componentDidMount() {
+ this._disposers.pause = reaction(
+ () => SnappingManager.UserPanned,
+ () => this.pauseAutoPres()
+ );
this._disposers.keyboard = reaction(
() => this.selectedDoc,
selected => {
@@ -189,7 +280,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._unmounting = false;
this.turnOffEdit(true);
this._disposers.selection = reaction(
- () => SelectionManager.Views.slice(),
+ () => DocumentView.Selected().slice(),
views => (!PresBox.Instance || views.some(view => view.Document === this.Document)) && this.updateCurrentPresentation(),
{ fireImmediately: true }
);
@@ -197,7 +288,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
() => this.layoutDoc.presentation_status === PresStatus.Edit,
editing => editing &&
this.childDocs.filter(doc => doc.presentation_indexed !== undefined).forEach(doc => {
- this.progressivizedItems(doc)?.forEach(indexedDoc => (indexedDoc.opacity = undefined));
+ this.progressivizedItems(doc)?.forEach(indexedDoc => { indexedDoc.opacity = undefined; });
doc.presentation_indexed = Math.min(this.progressivizedItems(doc)?.length ?? 0, 1);
}) // prettier-ignore
);
@@ -214,7 +305,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
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)) {
- const targMedia = DocumentManager.Instance.getDocumentView(targetDoc);
+ const targMedia = DocumentView.getDocumentView(targetDoc);
targMedia?.ComponentView?.playFrom?.(NumCast(activeItem.config_clipStart), NumCast(activeItem.config_clipStart) + duration);
}
};
@@ -222,18 +313,97 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
stopTempMedia = (targetDocField: FieldResult) => {
const targetDoc = DocCast(DocCast(targetDocField).annotationOn) ?? DocCast(targetDocField);
if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as any)) {
- const targMedia = DocumentManager.Instance.getDocumentView(targetDoc);
+ const targMedia = DocumentView.getDocumentView(targetDoc);
targMedia?.ComponentView?.Pause?.();
}
};
- //TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time
+ // Recording for GPT customization
+
+ recordDictation = () => {
+ this.setIsRecording(true);
+ this.setChatInput('');
+ DictationManager.Controls.listen({
+ interimHandler: this.setDictationContent,
+ continuous: { indefinite: false },
+ }).then(results => {
+ if (results && [DictationManager.Controls.Infringed].includes(results)) {
+ DictationManager.Controls.stop();
+ }
+ });
+ };
+ stopDictation = () => {
+ this.setIsRecording(false);
+ DictationManager.Controls.stop();
+ };
+
+ setDictationContent = (value: string) => {
+ console.log('Dictation value', value);
+ this.setChatInput(value);
+ };
+
+ @action
+ customizeAnimations = async () => {
+ this.setIsLoading(true);
+ try {
+ const res = await getSlideTransitionSuggestions(this.animationChat);
+ if (typeof res === 'string') {
+ const resObj = JSON.parse(res);
+ console.log('Parsed GPT Result ', resObj);
+ this.setGeneratedAnimations(resObj as AnimationSettings[]);
+ }
+ } catch (err) {
+ console.error(err);
+ }
+ this.setIsLoading(false);
+ };
+
+ @action
+ customizeWithGPT = async (input: string) => {
+ // const testInput = 'change title to Customized Slide, transition for 2.3s with fade in effect';
+ this.setIsRecording(false);
+ this.setIsLoading(true);
+
+ const currSlideProperties: { [key: string]: any } = {};
+ gptSlideProperties.forEach(key => {
+ if (this.activeItem[key]) {
+ currSlideProperties[key] = this.activeItem[key];
+ }
+ // default values
+ else if (key === 'presentation_transition') {
+ currSlideProperties[key] = 500;
+ } else if (key === 'config_zoom') {
+ currSlideProperties[key] = 1.0;
+ }
+ });
+ console.log('current slide props ', currSlideProperties);
+
+ try {
+ const res = await gptTrailSlideCustomization(input, currSlideProperties);
+ if (typeof res === 'string') {
+ const resObj = JSON.parse(res);
+ console.log('Parsed GPT Result ', resObj);
+ // eslint-disable-next-line no-restricted-syntax
+ for (const key in resObj) {
+ if (resObj[key]) {
+ console.log('typeof property', typeof resObj[key]);
+ this.activeItem[key] = resObj[key];
+ }
+ }
+ }
+ } catch (err) {
+ console.error(err);
+ }
+ this.setIsLoading(false);
+ };
+
+ // TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time
// TODO: to handle child slides (entering into subtrail and exiting), also the next() and back() functions
// No more frames in current doc and next slide is defined, therefore move to next slide
nextSlide = (slideNum?: number) => {
const nextSlideInd = slideNum ?? this.itemIndex + 1;
let curSlideInd = nextSlideInd;
- //CollectionStackedTimeline.CurrentlyPlaying?.map(clipView => clipView?.ComponentView?.Pause?.());
+ // CollectionStackedTimeline.CurrentlyPlaying?.map(clipView => clipView?.ComponentView?.Pause?.());
this.clearSelectedArray();
const doGroupWithUp =
(nextSelected: number, force = false) =>
@@ -245,7 +415,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (serial) {
this.gotoDocument(nextSelected, this.activeItem, true, async () => {
const waitTime = NumCast(this.activeItem.presentation_duration);
- await new Promise<void>(res => setTimeout(() => res(), Math.max(0, waitTime)));
+ await new Promise<void>(res => {
+ setTimeout(res, Math.max(0, waitTime));
+ });
doGroupWithUp(nextSelected + 1)();
});
} else {
@@ -264,14 +436,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targetList = PresBox.targetRenderedDoc(doc);
if (doc.presentation_indexed !== undefined && targetList) {
const listItems = (Cast(targetList[Doc.LayoutFieldKey(targetList)], listSpec(Doc), null)?.filter(d => d instanceof Doc) as Doc[]) ?? DocListCast(targetList[Doc.LayoutFieldKey(targetList) + '_annotations']);
- return listItems.filter(doc => !doc.layout_unrendered);
+ return listItems.filter(ldoc => !ldoc.layout_unrendered);
}
+ return undefined;
};
// go to documents chain
runSubroutines = (childrenToRun: Opt<Doc[]>, normallyNextSlide: Doc) => {
if (childrenToRun && childrenToRun[0] !== normallyNextSlide) {
- childrenToRun.forEach(child => DocumentManager.Instance.showDocument(child, {}));
+ childrenToRun.forEach(child => DocumentView.showDocument(child, {}));
}
};
@@ -284,12 +457,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targetRenderedDoc = PresBox.targetRenderedDoc(this.activeItem);
targetRenderedDoc._dataTransition = 'all 1s';
targetRenderedDoc.opacity = 1;
- setTimeout(() => (targetRenderedDoc._dataTransition = 'inherit'), 1000);
+ setTimeout(() => {
+ targetRenderedDoc._dataTransition = 'inherit';
+ }, 1000);
const listItems = this.progressivizedItems(this.activeItem);
if (listItems && presIndexed < listItems.length) {
if (!first) {
const listItemDoc = listItems[presIndexed];
- const targetView = listItems && DocumentManager.Instance.getFirstDocumentView(listItemDoc);
+ const targetView = listItems && DocumentView.getFirstDocumentView(listItemDoc);
Doc.linkFollowUnhighlight();
Doc.HighlightDoc(listItemDoc);
listItemDoc.presentation_effect = this.activeItem.presBulletEffect;
@@ -305,6 +480,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return true;
}
}
+ return undefined;
};
if (progressiveReveal(false)) return true;
if (this.childDocs[this.itemIndex + 1] !== undefined) {
@@ -314,7 +490,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// before moving onto next slide, run the subroutines :)
const currentDoc = this.childDocs[this.itemIndex];
- //could i do this.childDocs[this.itemIndex] for first arg?
+ // could i do this.childDocs[this.itemIndex] for first arg?
this.runSubroutines(TreeView.GetRunningChildren.get(currentDoc)?.(), this.childDocs[this.itemIndex + 1]);
this.nextSlide(curLast + 1 === this.childDocs.length ? (this.layoutDoc.presLoop ? 0 : curLast) : curLast + 1);
@@ -324,8 +500,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// Case 2: Last slide and presLoop is toggled ON or it is in Edit mode
this.nextSlide(0);
progressiveReveal(true); // shows first progressive document, but without a transition effect
+ return 0;
}
- return 0;
+ return false;
}
return this.itemIndex;
};
@@ -333,7 +510,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// Called when the user activates 'back' - to move to the previous part of the pres. trail
@action
back = () => {
- const activeItem: Doc = this.activeItem;
+ const { activeItem } = this;
let prevSelected = this.itemIndex;
// Functionality for group with up
let didZoom = activeItem.presentation_movement;
@@ -352,8 +529,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return this.itemIndex;
};
- //The function that is called when a document is clicked or reached through next or back.
- //it'll also execute the necessary actions if presentation is playing.
+ // The function that is called when a document is clicked or reached through next or back.
+ // it'll also execute the necessary actions if presentation is playing.
@undoBatch
public gotoDocument = action((index: number, from?: Doc, group?: boolean, finished?: () => void) => {
Doc.UnBrushAllDocs();
@@ -370,13 +547,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.startTempMedia(this.targetDoc, this.activeItem);
}
if (!group) this.clearSelectedArray();
- this.childDocs[index] && this.addToSelectedArray(this.childDocs[index]); //Update selected array
+ this.childDocs[index] && this.addToSelectedArray(this.childDocs[index]); // Update selected array
this.turnOffEdit();
- this.navigateToActiveItem(finished); //Handles movement to element only when presentationTrail is list
- this.doHideBeforeAfter(); //Handles hide after/before
+ this.navigateToActiveItem(finished); // Handles movement to element only when presentationTrail is list
+ this.doHideBeforeAfter(); // Handles hide after/before
}
});
- static pinDataTypes(target?: Doc): pinDataTypes {
+ static pinDataTypes(target?: Doc): dataTypes {
const targetType = target?.type as any;
const inkable = [DocumentType.INK].includes(targetType);
const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetType) || target?._type_collection === CollectionViewType.Stacking;
@@ -387,19 +564,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const datarange = [DocumentType.FUNCPLOT].includes(targetType);
const dataview = [DocumentType.INK, DocumentType.COL, DocumentType.IMG, DocumentType.RTF].includes(targetType) && target?.activeFrame === undefined;
const poslayoutview = [DocumentType.COL].includes(targetType) && target?.activeFrame === undefined;
- const type_collection = targetType === DocumentType.COL;
+ const typeCollection = targetType === DocumentType.COL;
const filters = true;
const pivot = true;
const dataannos = false;
- return { scrollable, pannable, inkable, type_collection, pivot, map, filters, temporal, clippable, dataview, datarange, poslayoutview, dataannos };
+ return { scrollable, pannable, inkable, type_collection: typeCollection, pivot, map, filters, temporal, clippable, dataview, datarange, poslayoutview, dataannos };
}
@action
- playAnnotation = (anno: AudioField) => {};
+ playAnnotation = (/* anno: AudioField */) => {
+ /* empty */
+ };
@action
- static restoreTargetDocView(bestTargetView: Opt<DocumentView>, activeItem: Doc, transTime: number, pinDocLayout: boolean = BoolCast(activeItem.config_pinLayout), pinDataTypes?: pinDataTypes, targetDoc?: Doc) {
+ // eslint-disable-next-line default-param-last
+ static restoreTargetDocView(bestTargetView: Opt<DocumentView>, activeItem: Doc, transTime: number, pinDocLayout: boolean = BoolCast(activeItem.config_pinLayout), pinDataTypes?: dataTypes, targetDoc?: Doc) {
const bestTarget = bestTargetView?.Document ?? (targetDoc?.layout_unrendered ? DocCast(targetDoc?.annotationOn) : targetDoc);
- if (!bestTarget) return;
+ if (!bestTarget) return undefined;
let changed = false;
if (pinDocLayout) {
if (
@@ -416,20 +596,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
bestTarget.width = NumCast(activeItem.config_width, NumCast(bestTarget.width));
bestTarget.height = NumCast(activeItem.config_height, NumCast(bestTarget.height));
bestTarget[TransitionTimer] && clearTimeout(bestTarget[TransitionTimer]);
- bestTarget[TransitionTimer] = setTimeout(() => (bestTarget[TransitionTimer] = bestTarget._dataTransition = undefined), transTime + 10);
+ bestTarget[TransitionTimer] = setTimeout(() => {
+ bestTarget[TransitionTimer] = bestTarget._dataTransition = undefined;
+ }, transTime + 10);
changed = true;
}
}
const activeFrame = activeItem.config_activeFrame ?? activeItem.config_currentFrame;
if (activeFrame !== undefined) {
- const transTime = NumCast(activeItem.presentation_transition, 500);
+ const frameTime = NumCast(activeItem.presentation_transition, 500);
const acontext = activeItem.config_activeFrame !== undefined ? DocCast(DocCast(activeItem.presentation_targetDoc).embedContainer) : DocCast(activeItem.presentation_targetDoc);
const context = DocCast(acontext)?.annotationOn ? DocCast(DocCast(acontext).annotationOn) : acontext;
if (context) {
- const ffview = DocumentManager.Instance.getFirstDocumentView(context)?.CollectionFreeFormView;
+ const ffview = CollectionFreeFormView.from(DocumentView.getFirstDocumentView(context));
if (ffview?.childDocs) {
- PresBox.Instance._keyTimer = CollectionFreeFormView.gotoKeyframe(PresBox.Instance._keyTimer, ffview.childDocs, transTime);
+ PresBox.Instance._keyTimer = CollectionFreeFormView.gotoKeyframe(PresBox.Instance._keyTimer, ffview.childDocs, frameTime);
ffview.layoutDoc._currentFrame = NumCast(activeFrame);
}
}
@@ -442,12 +624,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
else {
const bestTargetData = bestTarget[DocData];
const current = bestTargetData[fkey];
- const hash = bestTargetData[fkey] ? stringHash(Field.toString(bestTargetData[fkey] as Field)) : undefined;
+ const hash = bestTargetData[fkey] ? stringHash(Field.toString(bestTargetData[fkey] as FieldType)) : undefined;
if (hash) bestTargetData[fkey + '_' + hash] = current instanceof ObjectField ? current[Copy]() : current;
bestTargetData[fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data;
}
bestTarget[fkey + '_usePath'] = activeItem.config_usePath;
- setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10);
+ setTimeout(() => {
+ bestTarget._dataTransition = undefined;
+ }, transTime + 10);
}
if (pinDataTypes?.datarange || (!pinDataTypes && activeItem.config_xRange !== undefined)) {
if (bestTarget.xRange !== activeItem.config_xRange) {
@@ -589,7 +773,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
Doc.AddDocToList(bestTarget[DocData], layoutField, doc);
}
});
- setTimeout(() => Array.from(transitioned).forEach(action(doc => (doc._dataTransition = undefined))), transTime + 10);
+ setTimeout(
+ () =>
+ Array.from(transitioned).forEach(
+ action(doc => {
+ doc._dataTransition = undefined;
+ })
+ ),
+ transTime + 10
+ );
}
if ((pinDataTypes?.pannable || (!pinDataTypes && (activeItem.config_viewBounds !== undefined || activeItem.config_panX !== undefined || activeItem.config_viewScale !== undefined))) && !bestTarget.isGroup) {
const contentBounds = Cast(activeItem.config_viewBounds, listSpec('number'));
@@ -597,132 +789,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const viewport = { panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] };
bestTarget._freeform_panX = viewport.panX;
bestTarget._freeform_panY = viewport.panY;
- const dv = DocumentManager.Instance.getDocumentView(bestTarget);
+ const dv = DocumentView.getDocumentView(bestTarget);
if (dv) {
changed = true;
const computedScale = NumCast(activeItem.config_zoom, 1) * Math.min(dv._props.PanelWidth() / viewport.width, dv._props.PanelHeight() / viewport.height);
activeItem.presentation_movement === PresMovement.Zoom && (bestTarget._freeform_scale = computedScale);
dv.ComponentView?.brushView?.(viewport, transTime, 2500);
}
- } else {
- if (bestTarget._freeform_panX !== activeItem.config_panX || bestTarget._freeform_panY !== activeItem.config_panY || bestTarget._freeform_scale !== activeItem.config_viewScale) {
- bestTarget._freeform_panX = activeItem.config_panX ?? bestTarget._freeform_panX;
- bestTarget._freeform_panY = activeItem.config_panY ?? bestTarget._freeform_panY;
- bestTarget._freeform_scale = activeItem.config_viewScale ?? bestTarget._freeform_scale;
- changed = true;
- }
+ } else if (bestTarget._freeform_panX !== activeItem.config_panX || bestTarget._freeform_panY !== activeItem.config_panY || bestTarget._freeform_scale !== activeItem.config_viewScale) {
+ bestTarget._freeform_panX = activeItem.config_panX ?? bestTarget._freeform_panX;
+ bestTarget._freeform_panY = activeItem.config_panY ?? bestTarget._freeform_panY;
+ bestTarget._freeform_scale = activeItem.config_viewScale ?? bestTarget._freeform_scale;
+ changed = true;
}
}
if (changed) {
return bestTargetView?.setViewTransition('all', transTime);
}
- }
-
- /// copies values from the targetDoc (which is the prototype of the pinDoc) to
- /// reserved fields on the pinDoc so that those values can be restored to the
- /// target doc when navigating to it.
- @action
- static pinDocView(pinDoc: Doc, pinProps: PinProps, targetDoc: Doc) {
- pinDoc.presentation = true;
- pinDoc.config = '';
- if (pinProps.pinDocLayout) {
- pinDoc.config_pinLayout = true;
- pinDoc.config_x = NumCast(targetDoc.x);
- pinDoc.config_y = NumCast(targetDoc.y);
- pinDoc.config_rotation = NumCast(targetDoc.rotation);
- pinDoc.config_width = NumCast(targetDoc.width);
- pinDoc.config_height = NumCast(targetDoc.height);
- }
- if (pinProps.pinAudioPlay) pinDoc.presPlayAudio = true;
- if (pinProps.pinData) {
- pinDoc.config_pinData =
- pinProps.pinData.scrollable ||
- pinProps.pinData.temporal ||
- pinProps.pinData.pannable ||
- pinProps.pinData.type_collection ||
- pinProps.pinData.clippable ||
- pinProps.pinData.datarange ||
- pinProps.pinData.dataview ||
- pinProps.pinData.poslayoutview ||
- pinProps?.activeFrame !== undefined;
- const fkey = Doc.LayoutFieldKey(targetDoc);
- if (pinProps.pinData.dataview) {
- pinDoc.config_usePath = targetDoc[fkey + '_usePath'];
- pinDoc.config_data = targetDoc[fkey] instanceof ObjectField ? (targetDoc[fkey] as ObjectField)[Copy]() : targetDoc.data;
- }
- if (pinProps.pinData.dataannos) {
- const fkey = Doc.LayoutFieldKey(targetDoc);
- pinDoc.config_annotations = new List<Doc>(DocListCast(targetDoc[DocData][fkey + '_annotations']).filter(doc => !doc.layout_unrendered));
- }
- if (pinProps.pinData.inkable) {
- pinDoc.config_fillColor = targetDoc.fillColor;
- pinDoc.config_color = targetDoc.color;
- pinDoc.config_width = targetDoc._width;
- pinDoc.config_height = targetDoc._height;
- }
- if (pinProps.pinData.scrollable) pinDoc.config_scrollTop = targetDoc._layout_scrollTop;
- if (pinProps.pinData.clippable) {
- const fkey = Doc.LayoutFieldKey(targetDoc);
- pinDoc.config_clipWidth = targetDoc[fkey + '_clipWidth'];
- }
- if (pinProps.pinData.datarange) {
- pinDoc.config_xRange = undefined; //targetDoc?.xrange;
- pinDoc.config_yRange = undefined; //targetDoc?.yrange;
- }
- if (pinProps.pinData.map) {
- // pinDoc.config_latitude = targetDoc?.latitude;
- // pinDoc.config_longitude = targetDoc?.longitude;
- pinDoc.config_map_zoom = targetDoc?.map_zoom;
- pinDoc.config_map_type = targetDoc?.map_type;
- //...
- }
- if (pinProps.pinData.poslayoutview)
- pinDoc.config_pinLayoutData = new List<string>(
- DocListCast(targetDoc[fkey] as ObjectField).map(d =>
- JSON.stringify({
- id: d[Id],
- x: NumCast(d.x),
- y: NumCast(d.y),
- w: NumCast(d._width),
- h: NumCast(d._height),
- fill: StrCast(d._fillColor),
- back: StrCast(d._backgroundColor),
- data: SerializationHelper.Serialize(d.data instanceof ObjectField ? d.data[Copy]() : ''),
- text: SerializationHelper.Serialize(d.text instanceof ObjectField ? d.text[Copy]() : ''),
- })
- )
- );
- if (pinProps.pinData.type_collection) pinDoc.config_viewType = targetDoc._type_collection;
- if (pinProps.pinData.filters) pinDoc.config_docFilters = ObjectField.MakeCopy(targetDoc.childFilters as ObjectField);
- if (pinProps.pinData.pivot) pinDoc.config_pivotField = targetDoc._pivotField;
- if (pinProps.pinData.pannable) {
- pinDoc.config_panX = NumCast(targetDoc._freeform_panX);
- pinDoc.config_panY = NumCast(targetDoc._freeform_panY);
- pinDoc.config_viewScale = NumCast(targetDoc._freeform_scale, 1);
- }
- if (pinProps.pinData.temporal) {
- pinDoc.config_clipStart = targetDoc._layout_currentTimecode;
- const duration = NumCast(pinDoc[`${Doc.LayoutFieldKey(pinDoc)}_duration`], NumCast(targetDoc.config_clipStart) + 0.1);
- pinDoc.config_clipEnd = NumCast(targetDoc.clipEnd, duration);
- }
- }
- if (pinProps?.pinViewport) {
- // If pinWithView option set then update scale and x / y props of slide
- const bounds = pinProps.pinViewport;
- pinDoc.config_pinView = true;
- pinDoc.config_viewScale = NumCast(targetDoc._freeform_scale, 1);
- pinDoc.config_panX = bounds.left + bounds.width / 2;
- pinDoc.config_panY = bounds.top + bounds.height / 2;
- pinDoc.config_viewBounds = new List<number>([bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + bounds.height]);
- }
- }
-
- @action
- static reversePin(pinDoc: Doc, targetDoc: Doc) {
- // const fkey = Doc.LayoutFieldKey(targetDoc);
- pinDoc.config_data = targetDoc.data;
-
- console.log(pinDoc.presData);
+ return undefined;
}
/**
@@ -734,8 +818,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
* on the right.
*/
navigateToActiveItem = (afterNav?: () => void) => {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
+ const { activeItem, targetDoc } = this;
const finished = () => {
afterNav?.();
targetDoc[Animation] = undefined;
@@ -745,8 +828,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const eleViewCache = Array.from(this._eleArray);
const resetSelection = action(() => {
if (!this._props.isSelected()) {
- const presDocView = DocumentManager.Instance.getDocumentView(this.Document);
- if (presDocView) SelectionManager.SelectView(presDocView, false);
+ const presDocView = DocumentView.getDocumentView(this.Document);
+ if (presDocView) DocumentView.SelectView(presDocView, false);
this.clearSelectedArray();
selViewCache.forEach(doc => this.addToSelectedArray(doc));
this._dragArray.splice(0, this._dragArray.length, ...dragViewCache);
@@ -761,10 +844,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
static NavigateToTarget(targetDoc: Doc, activeItem: Doc, finished?: () => void) {
if (activeItem.presentation_movement === PresMovement.None && targetDoc.type === DocumentType.SCRIPTING) {
- (DocumentManager.Instance.getFirstDocumentView(targetDoc)?.ComponentView as ScriptingBox)?.onRun?.();
+ (DocumentView.getFirstDocumentView(targetDoc)?.ComponentView as ScriptingBox)?.onRun?.();
return;
}
const effect = activeItem.presentation_effect && activeItem.presentation_effect !== PresEffect.None ? activeItem.presentation_effect : undefined;
+ // default with effect: 750ms else 500ms
const presTime = NumCast(activeItem.presentation_transition, effect ? 750 : 500);
const options: FocusViewOptions = {
willPan: activeItem.presentation_movement !== PresMovement.None,
@@ -774,27 +858,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
effect: activeItem,
noSelect: true,
openLocation: targetDoc.type === DocumentType.PRES ? ((OpenWhere.replace + ':' + PresBox.PanelName) as OpenWhere) : OpenWhere.addLeft,
- anchorDoc: activeItem,
- easeFunc: StrCast(activeItem.presEaseFunc, 'ease') as any,
+ easeFunc: StrCast(activeItem.presentation_easeFunc, 'ease') as any,
zoomTextSelections: BoolCast(activeItem.presentation_zoomText),
- playAudio: BoolCast(activeItem.presPlayAudio),
+ playAudio: BoolCast(activeItem.presentation_playAudio),
playMedia: activeItem.presentation_mediaStart === 'auto',
};
if (activeItem.presentation_openInLightbox) {
const context = DocCast(targetDoc.annotationOn) ?? targetDoc;
- if (!DocumentManager.Instance.getLightboxDocumentView(context)) {
- LightboxView.Instance.SetLightboxDoc(context);
+ if (!DocumentView.getLightboxDocumentView(context)) {
+ DocumentView.SetLightboxDoc(context);
}
}
if (targetDoc) {
if (activeItem.presentation_targetDoc instanceof Doc) activeItem.presentation_targetDoc[Animation] = undefined;
- DocumentManager.Instance.AddViewRenderedCb(LightboxView.LightboxDoc, dv => {
+ DocumentView.addViewRenderedCb(DocumentView.LightboxDoc(), () => {
// if target or the doc it annotates is not in the lightbox, then close the lightbox
- if (!DocumentManager.Instance.getLightboxDocumentView(DocCast(targetDoc.annotationOn) ?? targetDoc)) {
- LightboxView.Instance.SetLightboxDoc(undefined);
+ if (!DocumentView.getLightboxDocumentView(DocCast(targetDoc.annotationOn) ?? targetDoc)) {
+ DocumentView.SetLightboxDoc(undefined);
}
- DocumentManager.Instance.showDocument(targetDoc, options, finished);
+ DocumentView.showDocument(targetDoc, options, finished);
});
} else finished?.();
}
@@ -821,7 +904,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
opacity = 0;
} else if (index === this.itemIndex || !curDoc.presentation_hideAfter) {
opacity = 1;
- setTimeout(() => (tagDoc._dataTransition = undefined), 1000);
+ setTimeout(() => {
+ tagDoc._dataTransition = undefined;
+ }, 1000);
}
}
const hidingIndAft =
@@ -847,16 +932,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
_exitTrail: Opt<() => void>;
- PlayTrail = (docs: Doc[]) => {
+ playTrail = (docs: Doc[]) => {
const savedStates = docs.map(doc => {
switch (doc.type) {
case DocumentType.COL:
- if (doc._type_collection === CollectionViewType.Freeform) return { type: CollectionViewType.Freeform, doc, x: NumCast(doc.freeform_panX), y: NumCast(doc.freeform_panY), s: NumCast(doc.freeform_scale) };
+ if (doc._type_collection === CollectionViewType.Freeform) {
+ return { type: CollectionViewType.Freeform, doc, x: NumCast(doc.freeform_panX), y: NumCast(doc.freeform_panY), s: NumCast(doc.freeform_scale) };
+ }
break;
case DocumentType.INK:
if (doc.data instanceof InkField) {
return { type: doc.type, doc, data: doc.data?.[Copy](), fillColor: doc.fillColor, color: doc.color, x: NumCast(doc.x), y: NumCast(doc.y) };
}
+ break;
+ default:
}
return undefined;
});
@@ -864,7 +953,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._exitTrail = () => {
savedStates
.filter(savedState => savedState)
- .map(savedState => {
+ .forEach(savedState => {
switch (savedState?.type) {
case CollectionViewType.Freeform:
{
@@ -884,9 +973,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
doc.color = color;
}
break;
+ default:
}
});
- LightboxView.Instance.SetLightboxDoc(undefined);
+ DocumentView.SetLightboxDoc(undefined);
Doc.RemFromMyOverlay(this.Document);
return PresStatus.Edit;
};
@@ -902,8 +992,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
};
- //The function that resets the presentation by removing every action done by it. It also
- //stops the presentaton.
+ // The function that resets the presentation by removing every action done by it. It also
+ // stops the presentaton.
resetPresentation = () => {
this.childDocs
.map(doc => PresBox.targetRenderedDoc(doc))
@@ -920,12 +1010,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// The function allows for viewing the pres path on toggle
@action togglePath = (off?: boolean) => {
this._pathBoolean = off ? false : !this._pathBoolean;
- CollectionFreeFormView.ShowPresPaths = this._pathBoolean;
+ SnappingManager.SetShowPresPaths(this._pathBoolean);
};
// The function allows for expanding the view of pres on toggle
@action toggleExpandMode = () => {
- runInAction(() => (this._expandBoolean = !this._expandBoolean));
+ runInAction(() => {
+ this._expandBoolean = !this._expandBoolean;
+ });
this.Document.expandBoolean = this._expandBoolean;
this.childDocs.forEach(doc => {
doc.presentation_expandInlineButton = this._expandBoolean;
@@ -941,7 +1033,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const startInd = NumCast(doc.presentation_indexedStart);
this.progressivizedItems(doc)
?.slice(startInd)
- .forEach(indexedDoc => (indexedDoc.opacity = 0));
+ .forEach(indexedDoc => {
+ indexedDoc.opacity = 0;
+ });
doc.presentation_indexed = Math.min(this.progressivizedItems(doc)?.length ?? 0, startInd);
}
// if (doc.presentation_hide && this.childDocs.indexOf(doc) === startIndex) tagDoc.opacity = 0;
@@ -963,7 +1057,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const func = () => {
const delay = NumCast(this.activeItem.presentation_duration, this.activeItem.type === DocumentType.SCRIPTING ? 0 : 2500) + NumCast(this.activeItem.presentation_transition);
this._presTimer = setTimeout(() => {
- if (!this.next()) this.layoutDoc.presentation_status = this._exitTrail?.() ?? PresStatus.Manual;
+ if (this.next() === false) this.layoutDoc.presentation_status = this._exitTrail?.() ?? PresStatus.Manual;
this.layoutDoc.presentation_status === PresStatus.Autoplay && func();
}, delay);
};
@@ -985,20 +1079,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
exitMinimize = () => {
if (Doc.IsInMyOverlay(this.layoutDoc)) {
Doc.RemFromMyOverlay(this.Document);
- CollectionDockingView.AddSplit(this.Document, OpenWhereMod.right);
+ DocumentView.addSplit(this.Document, OpenWhereMod.right);
}
return PresStatus.Edit;
};
public static minimizedWidth = 198;
public static OpenPresMinimized(doc: Doc, pt: number[]) {
- doc.overlayX = pt[0];
- doc.overlayY = pt[1];
+ [doc.overlayX, doc.overlayY] = pt;
doc._height = 30;
doc._width = PresBox.minimizedWidth;
Doc.AddToMyOverlay(doc);
PresBox.Instance?.initializePresState(PresBox.Instance.itemIndex);
- return (doc.presentation_status = PresStatus.Manual);
+ doc.presentation_status = PresStatus.Manual;
+ return doc.presentation_status;
}
/**
@@ -1007,12 +1101,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
*/
@undoBatch
viewChanged = action((e: React.ChangeEvent) => {
- //@ts-ignore
- const type_collection = e.target.selectedOptions[0].value as CollectionViewType;
- this.layoutDoc.presFieldKey = this.fieldKey + (type_collection === CollectionViewType.Tree ? '-linearized' : '');
+ const typeCollection = (e.target as any).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(type_collection) && (this.Document._pivotField = undefined);
- this.Document._type_collection = type_collection;
+ [CollectionViewType.Tree || CollectionViewType.Stacking].includes(typeCollection) && (this.Document._pivotField = undefined);
+ this.Document._type_collection = typeCollection;
if (this.isTreeOrStack) {
this.layoutDoc._gridGap = 0;
}
@@ -1024,10 +1117,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
*/
// @undoBatch
mediaStopChanged = action((e: React.ChangeEvent) => {
- const activeItem: Doc = this.activeItem;
- //@ts-ignore
- const stopDoc = e.target.selectedOptions[0].value as string;
- const stopDocIndex: number = Number(stopDoc[0]);
+ 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);
@@ -1048,10 +1140,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return StrCast(activeItem.presentation_movement);
});
- whenChildContentsActiveChanged = action((isActive: boolean) => this._props.whenChildContentsActiveChanged((this._isChildActive = isActive)));
+ whenChildContentsActiveChanged = action((isActive: boolean) => {
+ this._props.whenChildContentsActiveChanged((this._isChildActive = isActive));
+ });
// For dragging documents into the presentation trail
addDocumentFilter = (docs: Doc[]) => {
- docs.forEach((doc, i) => {
+ const results = docs.map(doc => {
if (doc.presentation_targetDoc) return true;
if (doc.type === DocumentType.LABEL) {
const audio = Cast(doc.annotationOn, Doc, null);
@@ -1064,17 +1158,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return false;
}
} else if (doc.type !== DocumentType.PRES) {
+ // eslint-disable-next-line operator-assignment
if (!doc.presentation_targetDoc) doc.title = doc.title + ' - Slide';
- doc.presentation_targetDoc = doc.createdFrom; // dropped document will be a new embedding of an embedded document somewhere else.
+ doc.presentation_targetDoc = doc.createdFrom ?? doc; // dropped document will be a new embedding of an embedded document somewhere else.
doc.presentation_movement = PresMovement.Zoom;
if (this._expandBoolean) doc.presentation_expandInlineButton = true;
}
+ return false;
});
- return true;
+ return !results.some(r => !r);
};
childLayoutTemplate = () => Docs.Create.PresElementBoxDocument();
- removeDocument = (doc: Doc | Doc[]) => !(doc instanceof Doc ? [doc] : doc).map(d => Doc.RemoveDocFromList(this.Document, this.fieldKey, d)).some(p => !p);
+ removeDocument = (doc: Doc | Doc[]) =>
+ !toList(doc)
+ .map(d => Doc.RemoveDocFromList(this.Document, this.fieldKey, d))
+ .some(p => !p);
getTransform = () => this.ScreenToLocalBoxXf().translate(-5, -65); // listBox padding-left and pres-box-cont minHeight
panelHeight = () => this._props.PanelHeight() - 40;
/**
@@ -1091,42 +1190,46 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const tagDoc = Cast(curDoc.presentation_targetDoc, Doc, null);
if (curDoc && curDoc === this.activeItem)
return (
+ // eslint-disable-next-line react/no-array-index-key
<div key={index} className="selectedList-items">
<b>
{index + 1}. {curDoc.title}
</b>
</div>
);
- else if (tagDoc)
+ if (tagDoc)
return (
+ // eslint-disable-next-line react/no-array-index-key
<div key={index} className="selectedList-items">
{index + 1}. {curDoc.title}
</div>
);
- else if (curDoc)
+ if (curDoc)
return (
+ // eslint-disable-next-line react/no-array-index-key
<div key={index} className="selectedList-items">
{index + 1}. {curDoc.title}
</div>
);
+ return null;
});
}
@action
selectPres = () => {
- const presDocView = DocumentManager.Instance.getDocumentView(this.Document);
- presDocView && SelectionManager.SelectView(presDocView, false);
+ const presDocView = DocumentView.getDocumentView(this.Document);
+ presDocView && DocumentView.SelectView(presDocView, false);
};
- focusElement = (doc: Doc, options: FocusViewOptions) => {
+ focusElement = (doc: Doc) => {
this.selectElement(doc);
return undefined;
};
- //Regular click
+ // Regular click
@action
selectElement = (doc: Doc, noNav = false) => {
- CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => clip?.ComponentView?.Pause?.());
+ DocumentView.CurrentlyPlaying?.map(clip => clip?.ComponentView?.Pause?.());
if (noNav) {
const index = this.childDocs.indexOf(doc);
if (index >= 0 && index < this.childDocs.length) {
@@ -1138,7 +1241,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.updateCurrentPresentation(DocCast(doc.embedContainer));
};
- //Command click
+ // Command click
@action
multiSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
if (!this.selectedArray.has(doc)) {
@@ -1153,7 +1256,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.selectPres();
};
- //Shift click
+ // Shift click
@action
shiftSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
this.clearSelectedArray();
@@ -1168,7 +1271,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.selectPres();
};
- //regular click
+ // regular click
@action
regularSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, noNav: boolean, selectPres = true) => {
this.clearSelectedArray();
@@ -1191,6 +1294,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
keyEvents = (e: KeyboardEvent) => {
if (e.target instanceof HTMLInputElement) return;
+ if (e.target instanceof HTMLTextAreaElement) return;
let handled = false;
const anchorNode = document.activeElement as HTMLDivElement;
if (anchorNode && anchorNode.className?.includes('lm_title')) return;
@@ -1199,9 +1303,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (this.layoutDoc.presentation_status === 'edit') {
undoBatch(
action(() => {
- for (const doc of this.selectedArray) {
- this.removeDocument(doc);
- }
+ Array.from(this.selectedArray).forEach(doc => this.removeDocument(doc));
this.clearSelectedArray();
this._eleArray.length = 0;
this._dragArray.length = 0;
@@ -1268,8 +1370,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.childDocs.forEach(doc => this.addToSelectedArray(doc));
handled = true;
}
- default:
break;
+ default:
}
if (handled) {
e.stopPropagation();
@@ -1284,11 +1386,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const order: JSX.Element[] = [];
const docs = new Set<Doc>();
const presCollection = collection;
- const dv = DocumentManager.Instance.getDocumentView(presCollection);
+ const dv = DocumentView.getDocumentView(presCollection);
this.childDocs.forEach((doc, index) => {
const tagDoc = PresBox.targetRenderedDoc(doc);
const srcContext = Cast(tagDoc.embedContainer, Doc, null);
const labelCreator = (top: number, left: number, edge: number, fontSize: number) => (
+ // eslint-disable-next-line react/no-array-index-key
<div className="pathOrder" key={tagDoc.id + 'pres' + index} style={{ top, left, width: edge, height: edge, fontSize }} onClick={() => this.selectElement(doc)}>
<div className="pathOrder-frame">{index + 1}</div>
</div>
@@ -1321,7 +1424,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
order.push(
<>
{labelCreator(top - indEdge / 2, left - indEdge / 2, indEdge, indFontSize)}
- <div className="pathOrder-presPinView" style={{ top, left, width, height, borderWidth: indEdge / 10 }}></div>
+ <div className="pathOrder-presPinView" style={{ top, left, width, height, borderWidth: indEdge / 10 }} />
</>
);
}
@@ -1344,17 +1447,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
.filter(doc => PresBox.targetRenderedDoc(doc)?.embedContainer === collection)
.forEach((doc, index) => {
const tagDoc = PresBox.targetRenderedDoc(doc);
- if (tagDoc) {
- const n1x = NumCast(tagDoc.x) + NumCast(tagDoc._width) / 2;
- const n1y = NumCast(tagDoc.y) + NumCast(tagDoc._height) / 2;
- if ((index = 0)) pathPoints = n1x + ',' + n1y;
- else pathPoints = pathPoints + ' ' + n1x + ',' + n1y;
- } else if (doc.config_pinView) {
- const n1x = NumCast(doc.config_panX);
- const n1y = NumCast(doc.config_panY);
- if ((index = 0)) pathPoints = n1x + ',' + n1y;
- else pathPoints = pathPoints + ' ' + n1x + ',' + n1y;
- }
+ const [n1x, n1y] = tagDoc //
+ ? [NumCast(tagDoc.x) + NumCast(tagDoc._width) / 2, NumCast(tagDoc.y) + NumCast(tagDoc._height) / 2]
+ : [NumCast(doc.config_panX), NumCast(doc.config_panY)];
+
+ if (index === 0) pathPoints = n1x + ',' + n1y;
+ else pathPoints = pathPoints + ' ' + n1x + ',' + n1y;
});
return (
<>
@@ -1400,7 +1498,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@undoBatch
updateTransitionTime = (number: String, change?: number) => {
- PresBox.SetTransitionTime(number, (timeInMS: number) => this.selectedArray.forEach(doc => (doc.presentation_transition = timeInMS)), change);
+ PresBox.SetTransitionTime(
+ number,
+ (timeInMS: number) =>
+ this.selectedArray.forEach(doc => {
+ doc.presentation_transition = timeInMS;
+ }),
+ change
+ );
};
// Converts seconds to ms and updates presentation_transition
@@ -1410,7 +1515,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (change) scale += change;
if (scale < 0.01) scale = 0.01;
if (scale > 1) scale = 1;
- this.selectedArray.forEach(doc => (doc.config_zoom = scale));
+ this.selectedArray.forEach(doc => {
+ doc.config_zoom = scale;
+ });
};
/*
@@ -1422,257 +1529,290 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (change) timeInMS += change;
if (timeInMS < 100) timeInMS = 100;
if (timeInMS > 20000) timeInMS = 20000;
- this.selectedArray.forEach(doc => (doc.presentation_duration = timeInMS));
+ this.selectedArray.forEach(doc => {
+ doc.presentation_duration = timeInMS;
+ });
};
@undoBatch
- updateMovement = action((movement: PresMovement, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (doc.presentation_movement = movement)));
+ updateMovement = action((movement: PresMovement, all?: boolean) =>
+ (all ? this.childDocs : this.selectedArray).forEach(doc => {
+ doc.presentation_movement = movement;
+ })
+ );
@undoBatch
updateHideBefore = (activeItem: Doc) => {
activeItem.presentation_hideBefore = !activeItem.presentation_hideBefore;
- this.selectedArray.forEach(doc => (doc.presentation_hideBefore = activeItem.presentation_hideBefore));
+ this.selectedArray.forEach(doc => {
+ doc.presentation_hideBefore = activeItem.presentation_hideBefore;
+ });
};
@undoBatch
updateHide = (activeItem: Doc) => {
activeItem.presentation_hide = !activeItem.presentation_hide;
- this.selectedArray.forEach(doc => (doc.presentation_hide = activeItem.presentation_hide));
+ this.selectedArray.forEach(doc => {
+ doc.presentation_hide = activeItem.presentation_hide;
+ });
};
@undoBatch
updateHideAfter = (activeItem: Doc) => {
activeItem.presentation_hideAfter = !activeItem.presentation_hideAfter;
- this.selectedArray.forEach(doc => (doc.presentation_hideAfter = activeItem.presentation_hideAfter));
+ this.selectedArray.forEach(doc => {
+ doc.presentation_hideAfter = activeItem.presentation_hideAfter;
+ });
};
@undoBatch
updateOpenDoc = (activeItem: Doc) => {
activeItem.presentation_openInLightbox = !activeItem.presentation_openInLightbox;
- this.selectedArray.forEach(doc => (doc.presentation_openInLightbox = activeItem.presentation_openInLightbox));
+ this.selectedArray.forEach(doc => {
+ doc.presentation_openInLightbox = activeItem.presentation_openInLightbox;
+ });
};
@undoBatch
updateEaseFunc = (activeItem: Doc) => {
- activeItem.presEaseFunc = activeItem.presEaseFunc === 'linear' ? 'ease' : 'linear';
- this.selectedArray.forEach(doc => (doc.presEaseFunc = activeItem.presEaseFunc));
+ activeItem.presentation_easeFunc = activeItem.presentation_easeFunc === 'linear' ? 'ease' : 'linear';
+ this.selectedArray.forEach(doc => {
+ doc.presentation_easeFunc = activeItem.presentation_easeFunc;
+ });
};
+ setEaseFunc = (activeItem: Doc, easeFunc: string) => {
+ activeItem.presentation_easeFunc = easeFunc;
+ this.selectedArray.forEach(doc => {
+ doc.presentation_easeFunc = activeItem.presentation_easeFunc;
+ });
+ };
+
+ @undoBatch
+ updateEffectDirection = (effect: PresEffectDirection, all?: boolean) =>
+ (all ? this.childDocs : this.selectedArray).forEach(doc => {
+ doc.presentation_effectDirection = effect;
+ });
+
@undoBatch
- updateEffectDirection = (effect: PresEffectDirection, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (doc.presentation_effectDirection = effect));
+ updateEffect = (effect: PresEffect, bullet: boolean, all?: boolean) =>
+ (all ? this.childDocs : this.selectedArray).forEach(doc => {
+ bullet ? (doc.presBulletEffect = effect) : (doc.presentation_effect = effect);
+ });
@undoBatch
- updateEffect = (effect: PresEffect, bullet: boolean, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (bullet ? (doc.presBulletEffect = effect) : (doc.presentation_effect = effect)));
+ updateEffectTiming = (activeItem: Doc, timing: SpringSettings) => {
+ activeItem.presentation_effectTiming = JSON.stringify(timing);
+ this.selectedArray.forEach(doc => {
+ doc.presentation_effectTiming = activeItem.presentation_effectTiming;
+ });
+ };
static _sliderBatch: any;
static endBatch = () => {
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) => {
- return (
- <input
- type="range"
- step={step}
- min={min}
- max={max}
- value={value}
- readOnly={true}
- style={{ marginLeft: hmargin, marginRight: hmargin, width: `calc(100% - ${2 * (hmargin ?? 0)}px)`, background: SettingsManager.userColor, color: SettingsManager.userVariantColor }}
- className={`toolbar-slider ${active ? '' : 'none'}`}
- onPointerDown={e => {
- PresBox._sliderBatch = UndoManager.StartBatch('pres slider');
- document.addEventListener('pointerup', PresBox.endBatch, true);
- e.stopPropagation();
- }}
- onChange={e => {
- e.stopPropagation();
- change(e.target.value);
- }}
- />
- );
- };
-
+ public static inputter = (min: string, step: string, max: string, value: number, active: boolean, change: (val: string) => void, hmargin?: number) => (
+ <input
+ type="range"
+ step={step}
+ min={min}
+ max={max}
+ value={value}
+ readOnly
+ style={{ marginLeft: hmargin, marginRight: hmargin, width: `calc(100% - ${2 * (hmargin ?? 0)}px)`, background: SnappingManager.userColor, color: SnappingManager.userVariantColor }}
+ className={`toolbar-slider ${active ? '' : 'none'}`}
+ onPointerDown={e => {
+ PresBox._sliderBatch = UndoManager.StartBatch('pres slider');
+ document.addEventListener('pointerup', PresBox.endBatch, true);
+ e.stopPropagation();
+ }}
+ onChange={e => {
+ e.stopPropagation();
+ change(e.target.value);
+ }}
+ />
+ );
+
+ // Applies the slide transiiton settings to all docs in the array
@undoBatch
applyTo = (array: Doc[]) => {
this.updateMovement(this.activeItem.presentation_movement as PresMovement, true);
this.updateEffect(this.activeItem.presentation_effect as PresEffect, false, true);
this.updateEffect(this.activeItem.presBulletEffect as PresEffect, true, true);
this.updateEffectDirection(this.activeItem.presentation_effectDirection as PresEffectDirection, true);
- const { presentation_transition, presentation_duration, presentation_hideBefore, presentation_hideAfter } = this.activeItem;
+ // eslint-disable-next-line camelcase
+ const { presentation_transition: pt, presentation_duration: pd, presentation_hideBefore: ph, presentation_hideAfter: pa } = this.activeItem;
array.forEach(curDoc => {
- curDoc.presentation_transition = presentation_transition;
- curDoc.presentation_duration = presentation_duration;
- curDoc.presentation_hideBefore = presentation_hideBefore;
- curDoc.presentation_hideAfter = presentation_hideAfter;
+ curDoc.presentation_transition = pt;
+ curDoc.presentation_duration = pd;
+ curDoc.presentation_hideBefore = ph;
+ curDoc.presentation_hideAfter = pa;
});
};
@computed get visibilityDurationDropdown() {
- const activeItem = this.activeItem;
+ const { activeItem } = this;
if (activeItem && this.targetDoc) {
const targetType = this.targetDoc.type;
let duration = activeItem.presentation_duration ? NumCast(activeItem.presentation_duration) / 1000 : 0;
if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
return (
- <div className="presBox-ribbon">
- <div className="ribbon-doubleButton">
- <Tooltip title={<div className="dash-tooltip">Hide before presented</div>}>
- <div
- className={`ribbon-toggle ${activeItem.presentation_hideBefore ? 'active' : ''}`}
- style={{ border: `solid 1px ${SettingsManager.userColor}`, color: SettingsManager.userColor, background: activeItem.presentation_hideBefore ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor }}
- onClick={() => this.updateHideBefore(activeItem)}>
- Hide before
- </div>
- </Tooltip>
- <Tooltip title={<div className="dash-tooltip">{'Hide while presented'}</div>}>
- <div
- className={`ribbon-toggle ${activeItem.presentation_hide ? 'active' : ''}`}
- style={{ border: `solid 1px ${SettingsManager.userColor}`, color: SettingsManager.userColor, background: activeItem.presentation_hide ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor }}
- onClick={() => this.updateHide(activeItem)}>
- Hide
- </div>
- </Tooltip>
-
- <Tooltip title={<div className="dash-tooltip">{'Hide after presented'}</div>}>
- <div
- className={`ribbon-toggle ${activeItem.presentation_hideAfter ? 'active' : ''}`}
- style={{ border: `solid 1px ${SettingsManager.userColor}`, color: SettingsManager.userColor, background: activeItem.presentation_hideAfter ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor }}
- onClick={() => this.updateHideAfter(activeItem)}>
- Hide after
- </div>
- </Tooltip>
-
- <Tooltip title={<div className="dash-tooltip">{'Open in lightbox view'}</div>}>
- <div
- className="ribbon-toggle"
- style={{
- border: `solid 1px ${SettingsManager.userColor}`,
- color: SettingsManager.userColor,
- background: activeItem.presentation_openInLightbox ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor,
- }}
- onClick={() => this.updateOpenDoc(activeItem)}>
- Lightbox
- </div>
- </Tooltip>
- <Tooltip title={<div className="dash-tooltip">Transition movement style</div>}>
- <div
- className="ribbon-toggle"
- style={{ border: `solid 1px ${SettingsManager.userColor}`, color: SettingsManager.userColor, background: activeItem.presEaseFunc === 'ease' ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor }}
- onClick={() => this.updateEaseFunc(activeItem)}>
- {`${StrCast(activeItem.presEaseFunc, 'ease')}`}
- </div>
- </Tooltip>
- </div>
- {[DocumentType.AUDIO, DocumentType.VID].includes(targetType as any as DocumentType) ? null : (
- <>
- <div className="ribbon-doubleButton">
- <div className="presBox-subheading">Slide Duration</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
- <input className="presBox-input" type="number" readOnly={true} value={duration} onKeyDown={e => e.stopPropagation()} onChange={e => this.updateDurationTime(e.target.value)} /> s
+ <div className="presBox-option-block">
+ <div className="presBox-ribbon">
+ <div className="presBox-toggles">
+ <Tooltip title={<div className="dash-tooltip">Hide before presented</div>}>
+ <div
+ className={`ribbon-toggle ${activeItem.presentation_hideBefore ? 'active' : ''}`}
+ style={{
+ border: `solid 1px ${SnappingManager.userColor}`,
+ color: SnappingManager.userColor,
+ background: activeItem.presentation_hideBefore ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}
+ onClick={() => this.updateHideBefore(activeItem)}>
+ Hide before
</div>
- <div className="ribbon-propertyUpDown" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userColor }}>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateDurationTime(String(duration), 1000)}>
- <FontAwesomeIcon icon={'caret-up'} />
- </div>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateDurationTime(String(duration), -1000)}>
- <FontAwesomeIcon icon={'caret-down'} />
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">Hide while presented</div>}>
+ <div
+ className={`ribbon-toggle ${activeItem.presentation_hide ? 'active' : ''}`}
+ style={{ border: `solid 1px ${SnappingManager.userColor}`, color: SnappingManager.userColor, background: activeItem.presentation_hide ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor }}
+ onClick={() => this.updateHide(activeItem)}>
+ Hide
+ </div>
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">Hide after presented</div>}>
+ <div
+ className={`ribbon-toggle ${activeItem.presentation_hideAfter ? 'active' : ''}`}
+ style={{ border: `solid 1px ${SnappingManager.userColor}`, color: SnappingManager.userColor, background: activeItem.presentation_hideAfter ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor }}
+ onClick={() => this.updateHideAfter(activeItem)}>
+ Hide after
+ </div>
+ </Tooltip>
+
+ <Tooltip title={<div className="dash-tooltip">Open in lightbox view</div>}>
+ <div
+ className="ribbon-toggle"
+ style={{
+ border: `solid 1px ${SnappingManager.userColor}`,
+ color: SnappingManager.userColor,
+ background: activeItem.presentation_openInLightbox ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}
+ onClick={() => this.updateOpenDoc(activeItem)}>
+ Lightbox
+ </div>
+ </Tooltip>
+ </div>
+ {[DocumentType.AUDIO, DocumentType.VID].includes(targetType as any as DocumentType) ? null : (
+ <>
+ <div className="ribbon-doubleButton">
+ <div className="presBox-subheading">Slide Duration</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}` }}>
+ <input className="presBox-input" type="number" readOnly value={duration} onKeyDown={e => e.stopPropagation()} onChange={e => this.updateDurationTime(e.target.value)} /> s
</div>
</div>
- </div>
- {PresBox.inputter('0.1', '0.1', '20', duration, targetType !== DocumentType.AUDIO, this.updateDurationTime)}
- <div className={'slider-headers'} style={{ display: targetType === DocumentType.AUDIO ? 'none' : 'grid' }}>
- <div className="slider-text">Short</div>
- <div className="slider-text">Medium</div>
- <div className="slider-text">Long</div>
- </div>
- </>
- )}
+ {PresBox.inputter('0.1', '0.1', '20', duration, targetType !== DocumentType.AUDIO, this.updateDurationTime)}
+ <div className="slider-headers" style={{ display: targetType === DocumentType.AUDIO ? 'none' : 'grid' }}>
+ <div className="slider-text">Short</div>
+ <div className="slider-text">Medium</div>
+ <div className="slider-text">Long</div>
+ </div>
+ </>
+ )}
+ </div>
</div>
);
}
+ return undefined;
}
@computed get progressivizeDropdown() {
- const activeItem = this.activeItem;
+ const { activeItem } = this;
if (activeItem && this.targetDoc) {
const effect = activeItem.presBulletEffect ? activeItem.presBulletEffect : PresMovement.None;
- const bulletEffect = (effect: PresEffect) => (
+ const bulletEffect = (presEffect: PresEffect) => (
<div
- className={`presBox-dropdownOption ${activeItem.presentation_effect === effect || (effect === PresEffect.None && !activeItem.presentation_effect) ? 'active' : ''}`}
+ className={`presBox-dropdownOption ${activeItem.presentation_effect === presEffect || (presEffect === PresEffect.None && !activeItem.presentation_effect) ? 'active' : ''}`}
onPointerDown={StopEvent}
- onClick={() => this.updateEffect(effect, true)}>
- {effect}
+ onClick={() => this.updateEffect(presEffect, true)}>
+ {presEffect}
</div>
);
return (
- <div className="presBox-ribbon">
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Progressivize Collection</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
- type="checkbox"
- onChange={() => {
- activeItem.presentation_indexed = activeItem.presentation_indexed === undefined ? 0 : undefined;
- activeItem.presentation_hideBefore = activeItem.presentation_indexed !== undefined;
- const tagDoc = PresBox.targetRenderedDoc(this.activeItem);
- const type = DocCast(tagDoc?.annotationOn)?.type ?? tagDoc.type;
- activeItem.presentation_indexedStart = type === DocumentType.COL ? 1 : 0;
- // a progressivized slide doesn't have sub-slides, but rather iterates over the data list of the target being progressivized.
- // to avoid creating a new slide to correspond to each of the target's data list, we create a computedField to refernce the target's data list.
- let dataField = Doc.LayoutFieldKey(tagDoc);
- if (Cast(tagDoc[dataField], listSpec(Doc), null)?.filter(d => d instanceof Doc) === undefined) dataField = dataField + '_annotations';
-
- if (DocCast(activeItem.presentation_targetDoc).annotationOn) activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc.annotationOn?.["${dataField}"]`);
- else activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc?.["${dataField}"]`);
- }}
- checked={Cast(activeItem.presentation_indexed, 'number', null) !== undefined ? true : false}
- />
- </div>
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Progressivize First Bullet</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
- type="checkbox"
- onChange={() => (activeItem.presentation_indexedStart = activeItem.presentation_indexedStart ? 0 : 1)}
- checked={!NumCast(activeItem.presentation_indexedStart)}
- />
- </div>
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Expand Current Bullet</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
- type="checkbox"
- onChange={() => (activeItem.presBulletExpand = !activeItem.presBulletExpand)}
- checked={BoolCast(activeItem.presBulletExpand)}
- />
- </div>
+ <div className="presBox-option-block">
+ <div className="presBox-ribbon">
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Progressivize Collection</div>
+ <input
+ className="presBox-checkbox"
+ style={{ margin: 10, border: `solid 1px ${SnappingManager.userColor}` }}
+ type="checkbox"
+ onChange={() => {
+ activeItem.presentation_indexed = activeItem.presentation_indexed === undefined ? 0 : undefined;
+ activeItem.presentation_hideBefore = activeItem.presentation_indexed !== undefined;
+ const tagDoc = PresBox.targetRenderedDoc(this.activeItem);
+ const type = DocCast(tagDoc?.annotationOn)?.type ?? tagDoc.type;
+ activeItem.presentation_indexedStart = type === DocumentType.COL ? 1 : 0;
+ // a progressivized slide doesn't have sub-slides, but rather iterates over the data list of the target being progressivized.
+ // to avoid creating a new slide to correspond to each of the target's data list, we create a computedField to refernce the target's data list.
+ let dataField = Doc.LayoutFieldKey(tagDoc);
+ if (Cast(tagDoc[dataField], listSpec(Doc), null)?.filter(d => d instanceof Doc) === undefined) dataField += '_annotations';
+
+ if (DocCast(activeItem.presentation_targetDoc).annotationOn) activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc.annotationOn?.["${dataField}"]`);
+ else activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc?.["${dataField}"]`);
+ }}
+ checked={Cast(activeItem.presentation_indexed, 'number', null) !== undefined}
+ />
+ </div>
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Progressivize First Bullet</div>
+ <input
+ className="presBox-checkbox"
+ style={{ margin: 10, border: `solid 1px ${SnappingManager.userColor}` }}
+ type="checkbox"
+ onChange={() => {
+ activeItem.presentation_indexedStart = activeItem.presentation_indexedStart ? 0 : 1;
+ }}
+ checked={!NumCast(activeItem.presentation_indexedStart)}
+ />
+ </div>
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Expand Current Bullet</div>
+ <input
+ className="presBox-checkbox"
+ style={{ margin: 10, border: `solid 1px ${SnappingManager.userColor}` }}
+ type="checkbox"
+ onChange={() => {
+ activeItem.presBulletExpand = !activeItem.presBulletExpand;
+ }}
+ checked={BoolCast(activeItem.presBulletExpand)}
+ />
+ </div>
- <div className="ribbon-box">
- Bullet Effect
- <div
- className="presBox-dropdown"
- onClick={action(e => {
- e.stopPropagation();
- this._openBulletEffectDropdown = !this._openBulletEffectDropdown;
- })}
- style={{
- color: SettingsManager.userColor,
- background: SettingsManager.userVariantColor,
- borderBottomLeftRadius: this._openBulletEffectDropdown ? 0 : 5,
- border: this._openBulletEffectDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`,
- }}>
- {effect?.toString()}
- <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openBulletEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
+ <div className="ribbon-box">
+ Bullet Effect
<div
- className={'presBox-dropdownOptions'}
- style={{ display: this._openBulletEffectDropdown ? 'grid' : 'none', color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }}
- onPointerDown={e => e.stopPropagation()}>
- {Object.values(PresEffect)
- .filter(v => isNaN(Number(v)))
- .map(effect => bulletEffect(effect))}
+ className="presBox-dropdown"
+ onClick={action(e => {
+ e.stopPropagation();
+ this._openBulletEffectDropdown = !this._openBulletEffectDropdown;
+ })}
+ style={{
+ color: SnappingManager.userColor,
+ background: SnappingManager.userVariantColor,
+ borderBottomLeftRadius: this._openBulletEffectDropdown ? 0 : 5,
+ border: this._openBulletEffectDropdown ? `solid 2px ${SnappingManager.userVariantColor}` : `solid 1px ${SnappingManager.userColor}`,
+ }}>
+ {effect?.toString()}
+ <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openBulletEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon="angle-down" />
+ <div
+ className="presBox-dropdownOptions"
+ style={{ display: this._openBulletEffectDropdown ? 'grid' : 'none', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}
+ onPointerDown={e => e.stopPropagation()}>
+ {Object.values(PresEffect)
+ .filter(v => isNaN(Number(v)))
+ .map(pEffect => bulletEffect(pEffect))}
+ </div>
</div>
</div>
</div>
@@ -1681,215 +1821,460 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
return null;
}
+
+ @computed get gptDropdown() {
+ return <div />;
+ }
+
@computed get transitionDropdown() {
- const activeItem = this.activeItem;
- const preseEffect = (effect: PresEffect) => (
- <div
- className={`presBox-dropdownOption ${activeItem.presentation_effect === effect || (effect === PresEffect.None && !activeItem.presentation_effect) ? 'active' : ''}`}
- onPointerDown={StopEvent}
- onClick={() => this.updateEffect(effect, false)}>
- {effect}
- </div>
- );
- const presMovement = (movement: PresMovement) => (
- <div className={`presBox-dropdownOption ${activeItem.presentation_movement === movement ? 'active' : ''}`} onPointerDown={StopEvent} onClick={() => this.updateMovement(movement)}>
- {movement}
- </div>
- );
- const presDirection = (direction: PresEffectDirection, icon: string, gridColumn: number, gridRow: number, opts: object) => {
- const color = activeItem.presentation_effectDirection === direction || (direction === PresEffectDirection.Center && !activeItem.presentation_effectDirection) ? SettingsManager.userVariantColor : SettingsManager.userColor;
- return (
- <Tooltip title={<div className="dash-tooltip">{direction}</div>}>
- <div
- style={{ ...opts, border: direction === PresEffectDirection.Center ? `solid 2px ${color}` : undefined, borderRadius: '100%', cursor: 'pointer', gridColumn, gridRow, justifySelf: 'center', color }}
- onClick={() => this.updateEffectDirection(direction)}>
- {icon ? <FontAwesomeIcon icon={icon as any} /> : null}
- </div>
- </Tooltip>
- );
- };
+ const { activeItem } = this;
+ // Retrieving spring timing properties
+ const timing = StrCast(activeItem.presentation_effectTiming);
+ let timingConfig: SpringSettings | undefined;
+ if (timing) {
+ timingConfig = JSON.parse(timing);
+ }
+
+ if (!timingConfig) {
+ timingConfig = {
+ type: SpringType.GENTLE,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ };
+ }
+
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 = activeItem.presentation_effect ? activeItem.presentation_effect : PresMovement.None;
+ const effect = StrCast(activeItem.presentation_effect) ? (StrCast(activeItem.presentation_effect) as any as PresEffect) : PresEffect.None;
+ const direction = StrCast(activeItem.presentation_effectDirection) as PresEffectDirection;
+
return (
- <div
- className={`presBox-ribbon ${this._transitionTools && this.layoutDoc.presentation_status === PresStatus.Edit ? 'active' : ''}`}
- onPointerDown={StopEvent}
- onPointerUp={StopEvent}
- onClick={action(e => {
- e.stopPropagation();
- this._openMovementDropdown = false;
- this._openEffectDropdown = false;
- this._openBulletEffectDropdown = false;
- })}>
- <div className="ribbon-box">
- Movement
- <div
- className="presBox-dropdown"
- onClick={action(e => {
- e.stopPropagation();
- this._openMovementDropdown = !this._openMovementDropdown;
- })}
- style={{
- color: SettingsManager.userColor,
- background: SettingsManager.userVariantColor,
- borderBottomLeftRadius: this._openMovementDropdown ? 0 : 5,
- border: this._openMovementDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`,
- }}>
- {this.movementName(activeItem)}
- <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
- <div
- className="presBox-dropdownOptions"
- id={'presBoxMovementDropdown'}
- onPointerDown={StopEvent}
- style={{
- color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
- display: this._openMovementDropdown ? 'grid' : 'none',
- }}>
- {presMovement(PresMovement.None)}
- {presMovement(PresMovement.Center)}
- {presMovement(PresMovement.Zoom)}
- {presMovement(PresMovement.Pan)}
- {presMovement(PresMovement.Jump)}
+ <>
+ {/* This chatbox is for customizing the properties of trails, like transition time, movement type (zoom, pan) using GPT */}
+ <div className="presBox-gpt-chat">
+ <span style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
+ Customize Slide Properties{' '}
+ <div className="propertiesView-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/trails/#slide-customization')}>
+ <IconButton icon={<FontAwesomeIcon icon="info-circle" />} color={SnappingManager.userColor} />
</div>
- </div>
- <div className="ribbon-doubleButton" style={{ display: activeItem.presentation_movement === PresMovement.Zoom ? 'inline-flex' : 'none' }}>
- <div className="presBox-subheading">Zoom (% screen filled)</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
- <input className="presBox-input" type="number" readOnly={true} value={zoom} onChange={e => this.updateZoom(e.target.value)} />%
+ </span>
+ <div className="pres-chat">
+ <div className="pres-chatbox-container">
+ <ReactTextareaAutosize
+ placeholder="Describe how you would like to modify the slide properties."
+ className="pres-chatbox"
+ value={this.chatInput}
+ onChange={e => {
+ this.setChatInput(e.target.value);
+ }}
+ onKeyDown={e => {
+ this.stopDictation();
+ e.stopPropagation();
+ }}
+ />
+ <IconButton
+ type={Type.TERT}
+ color={this.isRecording ? '#2bcaff' : SnappingManager.userVariantColor}
+ tooltip="Record"
+ icon={<BiMicrophone size="16px" />}
+ onClick={() => {
+ if (!this.isRecording) {
+ this.recordDictation();
+ } else {
+ this.stopDictation();
+ }
+ }}
+ />
</div>
- <div className="ribbon-propertyUpDown" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userColor }}>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateZoom(String(zoom), 0.1)}>
- <FontAwesomeIcon icon={'caret-up'} />
+ <Button
+ style={{ alignSelf: 'flex-end' }}
+ text="Send"
+ type={Type.TERT}
+ icon={this.isLoading ? <ReactLoading type="spin" color="#ffffff" width={20} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ color={SnappingManager.userVariantColor}
+ onClick={() => {
+ this.stopDictation();
+ this.customizeWithGPT(this.chatInput);
+ }}
+ />
+ </div>
+ </div>
+ {/* Movement */}
+ <div
+ className={`presBox-ribbon ${this._transitionTools && this.layoutDoc.presentation_status === PresStatus.Edit ? 'active' : ''}`}
+ onPointerDown={StopEvent}
+ onPointerUp={StopEvent}
+ onClick={action(e => {
+ e.stopPropagation();
+ this._openMovementDropdown = false;
+ this._openEffectDropdown = false;
+ this._openBulletEffectDropdown = false;
+ })}>
+ <div
+ className="presBox-option-block"
+ // style={{ padding: '16px' }}
+ >
+ Movement
+ <Dropdown
+ color={SnappingManager.userColor}
+ formLabel="Movement"
+ closeOnSelect
+ items={movementItems}
+ selectedVal={this.movementName(activeItem)}
+ setSelectedVal={val => {
+ this.updateMovement(val as PresMovement);
+ }}
+ dropdownType={DropdownType.SELECT}
+ type={Type.TERT}
+ />
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presentation_movement === PresMovement.Zoom ? 'inline-flex' : 'none' }}>
+ <div className="presBox-subheading">Zoom (% screen filled)</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}` }}>
+ <input className="presBox-input" readOnly type="number" value={zoom} onChange={e => this.updateZoom(e.target.value)} />%
</div>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateZoom(String(zoom), -0.1)}>
- <FontAwesomeIcon icon={'caret-down'} />
+ </div>
+ {PresBox.inputter('0', '1', '100', zoom, activeItem.presentation_movement === PresMovement.Zoom, this.updateZoom)}
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Transition Time</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}` }}>
+ <input className="presBox-input" type="number" readOnly value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} /> s
</div>
</div>
- </div>
- {PresBox.inputter('0', '1', '100', zoom, activeItem.presentation_movement === PresMovement.Zoom, this.updateZoom)}
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Transition Time</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
- <input className="presBox-input" type="number" readOnly={true} value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} /> s
+ {PresBox.inputter('0.1', '0.1', '10', transitionSpeed, true, this.updateTransitionTime)}
+ <div className="slider-headers">
+ <div className="slider-text">Fast</div>
+ <div className="slider-text">Medium</div>
+ <div className="slider-text">Slow</div>
</div>
- <div className="ribbon-propertyUpDown" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userColor }}>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateTransitionTime(String(transitionSpeed), 1000)}>
- <FontAwesomeIcon icon={'caret-up'} />
- </div>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateTransitionTime(String(transitionSpeed), -1000)}>
- <FontAwesomeIcon icon={'caret-down'} />
- </div>
+ {/* Easing function */}
+ <Dropdown
+ color={SnappingManager.userColor}
+ formLabel="Easing Function"
+ closeOnSelect
+ items={easeItems}
+ selectedVal={this.activeItem.presentation_easeFunc ? (StrCast(this.activeItem.presentation_easeFunc).startsWith('cubic') ? 'custom' : StrCast(this.activeItem.presentation_easeFunc)) : 'ease'}
+ setSelectedVal={val => {
+ if (typeof val === 'string') {
+ if (val !== 'custom') {
+ this.setEaseFunc(this.activeItem, val);
+ } else {
+ this.setBezierEditorVisibility(true);
+ this.setEaseFunc(this.activeItem, TIMING_DEFAULT_MAPPINGS.ease);
+ }
+ }
+ }}
+ dropdownType={DropdownType.SELECT}
+ type={Type.TERT}
+ />
+ {/* Custom */}
+ <div
+ className="presBox-show-hide-dropdown"
+ style={{ alignSelf: 'flex-start' }}
+ onClick={e => {
+ e.stopPropagation();
+ this.setBezierEditorVisibility(!this.showBezierEditor);
+ }}>
+ {`${this.showBezierEditor ? 'Hide' : 'Show'} Timing Editor`}
+ <FontAwesomeIcon icon={this.showBezierEditor ? 'chevron-up' : 'chevron-down'} />
</div>
</div>
- {PresBox.inputter('0.1', '0.1', '100', transitionSpeed, true, this.updateTransitionTime)}
- <div className={'slider-headers'}>
- <div className="slider-text">Fast</div>
- <div className="slider-text">Medium</div>
- <div className="slider-text">Slow</div>
- </div>
</div>
- <div className="ribbon-box">
+
+ {/* Cubic bezier editor */}
+ {this.showBezierEditor && (
+ <div className="presBox-option-block" style={{ paddingTop: 0 }}>
+ <p className="presBox-submenu-label" style={{ alignSelf: 'flex-start' }}>
+ Custom Timing Function
+ </p>
+ <CubicBezierEditor setFunc={this.setBezierControlPoints} currPoints={this.currCPoints} />
+ </div>
+ )}
+
+ {/* This chatbox is for getting slide effect transition suggestions from gpt and visualizing them */}
+ <div className="presBox-gpt-chat">
Effects
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Play Audio Annotation</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
- type="checkbox"
- onChange={() => (activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio))}
- checked={BoolCast(activeItem.presPlayAudio)}
+ <div className="pres-chat">
+ <div className="pres-chatbox-container">
+ <ReactTextareaAutosize
+ placeholder="Customize prompt for effect suggestions. Leave blank for random results."
+ className="pres-chatbox"
+ value={this.animationChat}
+ onChange={e => {
+ this.setAnimationChat(e.target.value);
+ }}
+ onKeyDown={e => {
+ this.stopDictation();
+ e.stopPropagation();
+ }}
+ />
+ </div>
+ <Button
+ style={{ alignSelf: 'flex-end' }}
+ text="Send"
+ type={Type.TERT}
+ icon={this.isLoading ? <ReactLoading type="spin" color="#ffffff" width={20} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ color={SnappingManager.userVariantColor}
+ onClick={this.customizeAnimations}
/>
</div>
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Zoom Text Selections</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
- type="checkbox"
- onChange={() => (activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText))}
- checked={BoolCast(activeItem.presentation_zoomText)}
+ </div>
+
+ <div
+ className={`presBox-ribbon ${this._transitionTools && this.layoutDoc.presentation_status === PresStatus.Edit ? 'active' : ''}`}
+ onPointerDown={StopEvent}
+ onPointerUp={StopEvent}
+ onClick={action(e => {
+ e.stopPropagation();
+ this._openMovementDropdown = false;
+ this._openEffectDropdown = false;
+ this._openBulletEffectDropdown = false;
+ })}>
+ <div className="presBox-option-block">
+ Click on a box to apply the effect.
+ <div className="presBox-option-block presBox-option-center">
+ {/* Preview Animations */}
+ <div className="presBox-effects">
+ {this.generatedAnimations.map((elem, i) => (
+ <div
+ // eslint-disable-next-line react/no-array-index-key
+ key={i}
+ className="presBox-effect-container"
+ onClick={() => {
+ this.updateEffect(elem.effect, false);
+ this.updateEffectDirection(elem.direction);
+ this.updateEffectTiming(this.activeItem, {
+ type: SpringType.CUSTOM,
+ stiffness: elem.stiffness,
+ damping: elem.damping,
+ mass: elem.mass,
+ });
+ }}>
+ <SlideEffect dir={elem.direction} presEffect={elem.effect} springSettings={elem} infinite>
+ <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[i] }} />
+ </SlideEffect>
+ </div>
+ ))}
+ </div>
+ </div>
+ {/* Effect dropdown */}
+ <Dropdown
+ color={SnappingManager.userColor}
+ formLabel="Slide Effect"
+ closeOnSelect
+ items={effectItems}
+ selectedVal={effect?.toString()}
+ setSelectedVal={val => {
+ this.updateEffect(val as PresEffect, false);
+ // set default spring options for that effect
+ this.updateEffectTiming(activeItem, presEffectDefaultTimings[val as keyof typeof presEffectDefaultTimings]);
+ }}
+ dropdownType={DropdownType.SELECT}
+ type={Type.TERT}
/>
+ {/* Effect direction */}
+ {/* Only applies to certain effects */}
+ {(effect === PresEffect.Flip || effect === PresEffect.Bounce || effect === PresEffect.Roll) && (
+ <>
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Effect direction</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}` }}>
+ {StrCast(this.activeItem.presentation_effectDirection)}
+ </div>
+ </div>
+ <div className="presBox-icon-list">
+ <IconButton
+ type={Type.TERT}
+ color={activeItem.presentation_effectDirection === PresEffectDirection.Left ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
+ tooltip="Left"
+ icon={<FaArrowRight size="16px" />}
+ onClick={() => this.updateEffectDirection(PresEffectDirection.Left)}
+ />
+ <IconButton
+ type={Type.TERT}
+ color={activeItem.presentation_effectDirection === PresEffectDirection.Right ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
+ tooltip="Right"
+ icon={<FaArrowLeft size="16px" />}
+ onClick={() => this.updateEffectDirection(PresEffectDirection.Right)}
+ />
+ {effect !== PresEffect.Roll && (
+ <>
+ <IconButton
+ type={Type.TERT}
+ color={activeItem.presentation_effectDirection === PresEffectDirection.Top ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
+ tooltip="Top"
+ icon={<FaArrowDown size="16px" />}
+ onClick={() => this.updateEffectDirection(PresEffectDirection.Top)}
+ />
+ <IconButton
+ type={Type.TERT}
+ color={activeItem.presentation_effectDirection === PresEffectDirection.Bottom ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
+ tooltip="Bottom"
+ icon={<FaArrowUp size="16px" />}
+ onClick={() => this.updateEffectDirection(PresEffectDirection.Bottom)}
+ />
+ </>
+ )}
+ </div>
+ </>
+ )}
+ {/* Spring settings */}
+ {/* No spring settings for jackinthebox (lightspeed) */}
+ {effect !== PresEffect.Lightspeed && (
+ <>
+ <Dropdown
+ color={SnappingManager.userColor}
+ formLabel="Effect Timing"
+ closeOnSelect
+ items={effectTimings}
+ selectedVal={timingConfig.type}
+ setSelectedVal={val => {
+ this.updateEffectTiming(activeItem, {
+ type: val as SpringType,
+ ...springMappings[val],
+ });
+ }}
+ dropdownType={DropdownType.SELECT}
+ type={Type.TERT}
+ />
+ <div
+ className="presBox-show-hide-dropdown"
+ onClick={e => {
+ e.stopPropagation();
+ this.setSpringEditorVisibility(!this.showSpringEditor);
+ }}>
+ {`${this.showSpringEditor ? 'Hide' : 'Show'} Spring Settings`}
+ <FontAwesomeIcon icon={this.showSpringEditor ? 'chevron-up' : 'chevron-down'} />
+ </div>
+ {this.showSpringEditor && (
+ <>
+ <div>Tension</div>
+ <div
+ onPointerDown={e => {
+ e.stopPropagation();
+ }}>
+ <Slider
+ min={1}
+ max={1000}
+ step={5}
+ size="small"
+ value={timingConfig.stiffness}
+ onChange={(e, val) => {
+ if (!timingConfig) return;
+ this.updateEffectTiming(activeItem, { ...timingConfig, type: SpringType.CUSTOM, stiffness: val as number });
+ }}
+ valueLabelDisplay="auto"
+ />
+ </div>
+ <div>Damping</div>
+ <div
+ onPointerDown={e => {
+ e.stopPropagation();
+ }}>
+ <Slider
+ min={1}
+ max={100}
+ step={1}
+ size="small"
+ value={timingConfig.damping}
+ onChange={(e, val) => {
+ if (!timingConfig) return;
+ this.updateEffectTiming(activeItem, { ...timingConfig, type: SpringType.CUSTOM, damping: val as number });
+ }}
+ valueLabelDisplay="auto"
+ />
+ </div>
+ <div>Mass</div>
+ <div
+ onPointerDown={e => {
+ e.stopPropagation();
+ }}>
+ <Slider
+ min={1}
+ max={10}
+ step={1}
+ size="small"
+ value={timingConfig.mass}
+ onChange={(e, val) => {
+ if (!timingConfig) return;
+ this.updateEffectTiming(activeItem, { ...timingConfig, type: SpringType.CUSTOM, mass: val as number });
+ }}
+ valueLabelDisplay="auto"
+ />
+ </div>
+ Preview Effect
+ <div className="presBox-option-block presBox-option-center">
+ <div className="presBox-effect-container">
+ <SlideEffect dir={direction} presEffect={effect} springSettings={timingConfig} infinite>
+ <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[0] }} />
+ </SlideEffect>
+ </div>
+ </div>
+ </>
+ )}
+ </>
+ )}
</div>
- <div
- className="presBox-dropdown"
- onClick={action(e => {
- e.stopPropagation();
- this._openEffectDropdown = !this._openEffectDropdown;
- })}
- style={{
- color: SettingsManager.userColor,
- background: SettingsManager.userVariantColor,
- borderBottomLeftRadius: this._openEffectDropdown ? 0 : 5,
- border: this._openEffectDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`,
- }}>
- {effect?.toString()}
- <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
- <div
- className="presBox-dropdownOptions"
- id={'presBoxMovementDropdown'}
- style={{
- color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
- display: this._openEffectDropdown ? 'grid' : 'none',
+
+ {/* Toggles */}
+ <div className="presBox-option-block">
+ <Toggle
+ formLabel="Play Audio Annotation"
+ toggleType={ToggleType.SWITCH}
+ toggleStatus={BoolCast(activeItem.presentation_playAudio)}
+ onClick={() => {
+ activeItem.presentation_playAudio = !BoolCast(activeItem.presentation_playAudio);
}}
- onPointerDown={e => e.stopPropagation()}>
- {Object.values(PresEffect)
- .filter(v => isNaN(Number(v)))
- .map(effect => preseEffect(effect))}
- </div>
- </div>
- <div className="ribbon-doubleButton" style={{ display: effect === PresEffectDirection.None ? 'none' : 'inline-flex' }}>
- <div className="presBox-subheading">Effect direction</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
- {StrCast(this.activeItem.presentation_effectDirection)}
- </div>
- </div>
- <div className="effectDirection" style={{ display: effect === PresEffectDirection.None ? 'none' : 'grid', width: 40 }}>
- {presDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
- {presDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
- {presDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
- {presDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
- {presDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
- </div>
- </div>
- <div className="ribbon-final-box">
- <div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>
- Apply to all
+ color={SnappingManager.userColor}
+ />
+ <Toggle
+ formLabel="Zoom Text Selections"
+ toggleType={ToggleType.SWITCH}
+ toggleStatus={BoolCast(activeItem.presentation_zoomText)}
+ onClick={() => {
+ activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText);
+ }}
+ color={SnappingManager.userColor}
+ />
+ <Button text="Apply to all" type={Type.TERT} color={SnappingManager.userVariantColor} onClick={() => this.applyTo(this.childDocs)} />
</div>
</div>
- </div>
+ </>
);
}
+ return undefined;
}
@computed get mediaOptionsDropdown() {
- const activeItem = this.activeItem;
+ const { activeItem } = this;
if (activeItem && this.targetDoc) {
const renderTarget = PresBox.targetRenderedDoc(this.activeItem);
const clipStart = NumCast(renderTarget.clipStart);
const clipEnd = NumCast(renderTarget.clipEnd, clipStart + NumCast(renderTarget[Doc.LayoutFieldKey(renderTarget) + '_duration']));
- const config_clipEnd = NumCast(activeItem.config_clipEnd) < NumCast(activeItem.config_clipStart) ? clipEnd - clipStart : NumCast(activeItem.config_clipEnd);
+ const configClipEnd = NumCast(activeItem.config_clipEnd) < NumCast(activeItem.config_clipStart) ? clipEnd - clipStart : NumCast(activeItem.config_clipEnd);
return (
- <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+ <div className="presBox-ribbon" onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
<div>
<div className="ribbon-box">
- Start {'&'} End Time
- <div className={'slider-headers'}>
+ Start & End Time
+ <div className="slider-headers">
<div className="slider-block">
<div className="slider-text" style={{ fontWeight: 500 }}>
Start time (s)
</div>
- <div id="startTime" className="slider-number" style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}>
+ <div id="startTime" className="slider-number" style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }}>
<input
className="presBox-input"
style={{ textAlign: 'center', width: '100%', height: 15, fontSize: 10 }}
type="number"
- readOnly={true}
+ readOnly
value={NumCast(activeItem.config_clipStart).toFixed(2)}
onKeyDown={e => e.stopPropagation()}
- onChange={action(e => (activeItem.config_clipStart = Number(e.target.value)))}
+ onChange={action(e => {
+ activeItem.config_clipStart = Number(e.target.value);
+ })}
/>
</div>
</div>
@@ -1897,23 +2282,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="slider-text" style={{ fontWeight: 500 }}>
Duration (s)
</div>
- <div className="slider-number" style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}>
- {Math.round((config_clipEnd - NumCast(activeItem.config_clipStart)) * 10) / 10}
+ <div className="slider-number" style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }}>
+ {Math.round((configClipEnd - NumCast(activeItem.config_clipStart)) * 10) / 10}
</div>
</div>
<div className="slider-block">
<div className="slider-text" style={{ fontWeight: 500 }}>
End time (s)
</div>
- <div id="endTime" className="slider-number" style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }}>
+ <div id="endTime" className="slider-number" style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }}>
<input
className="presBox-input"
onKeyDown={e => e.stopPropagation()}
style={{ textAlign: 'center', width: '100%', height: 15, fontSize: 10 }}
type="number"
- readOnly={true}
- value={config_clipEnd.toFixed(2)}
- onChange={action(e => (activeItem.config_clipEnd = Number(e.target.value)))}
+ readOnly
+ value={configClipEnd.toFixed(2)}
+ onChange={action(e => {
+ activeItem.config_clipEnd = Number(e.target.value);
+ })}
/>
</div>
</div>
@@ -1924,15 +2311,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
step="0.1"
min={clipStart}
max={clipEnd}
- value={config_clipEnd}
- style={{ gridColumn: 1, gridRow: 1, background: SettingsManager.userColor, color: SettingsManager.userVariantColor }}
+ value={configClipEnd}
+ style={{ gridColumn: 1, gridRow: 1, background: SnappingManager.userColor, color: SnappingManager.userVariantColor }}
className={`toolbar-slider ${'end'}`}
id="toolbar-slider"
onPointerDown={e => {
this._batch = UndoManager.StartBatch('config_clipEnd');
const endBlock = document.getElementById('endTime');
if (endBlock) {
- endBlock.style.backgroundColor = SettingsManager.userVariantColor;
+ endBlock.style.backgroundColor = SnappingManager.userVariantColor ?? '';
}
e.stopPropagation();
}}
@@ -1940,7 +2327,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._batch?.end();
const endBlock = document.getElementById('endTime');
if (endBlock) {
- endBlock.style.backgroundColor = SettingsManager.userBackgroundColor;
+ endBlock.style.backgroundColor = SnappingManager.userBackgroundColor ?? '';
}
}}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
@@ -1961,7 +2348,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._batch = UndoManager.StartBatch('config_clipStart');
const startBlock = document.getElementById('startTime');
if (startBlock) {
- startBlock.style.backgroundColor = SettingsManager.userVariantColor;
+ startBlock.style.backgroundColor = SnappingManager.userVariantColor ?? '';
}
e.stopPropagation();
}}
@@ -1969,7 +2356,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._batch?.end();
const startBlock = document.getElementById('startTime');
if (startBlock) {
- startBlock.style.backgroundColor = SettingsManager.userBackgroundColor;
+ startBlock.style.backgroundColor = SnappingManager.userBackgroundColor ?? '';
}
}}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
@@ -1980,7 +2367,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
<div className="slider-headers">
<div className="slider-text">{clipStart.toFixed(2)} s</div>
- <div className="slider-text"></div>
+ <div className="slider-text" />
<div className="slider-text">{clipEnd.toFixed(2)} s</div>
</div>
</div>
@@ -1992,8 +2379,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<input
className="presBox-checkbox"
type="checkbox"
- style={{ border: `solid 1px ${SettingsManager.userColor}` }}
- onChange={() => (activeItem.presentation_mediaStart = 'manual')}
+ style={{ border: `solid 1px ${SnappingManager.userColor}` }}
+ onChange={() => {
+ activeItem.presentation_mediaStart = 'manual';
+ }}
checked={activeItem.presentation_mediaStart === 'manual'}
/>
<div>On click</div>
@@ -2001,9 +2390,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="checkbox-container">
<input
className="presBox-checkbox"
- style={{ border: `solid 1px ${SettingsManager.userColor}` }}
+ style={{ border: `solid 1px ${SnappingManager.userColor}` }}
type="checkbox"
- onChange={() => (activeItem.presentation_mediaStart = 'auto')}
+ onChange={() => {
+ activeItem.presentation_mediaStart = 'auto';
+ }}
checked={activeItem.presentation_mediaStart === 'auto'}
/>
<div>Automatically</div>
@@ -2015,8 +2406,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<input
className="presBox-checkbox"
type="checkbox"
- style={{ border: `solid 1px ${SettingsManager.userColor}` }}
- onChange={() => (activeItem.presentation_mediaStop = 'manual')}
+ style={{ border: `solid 1px ${SnappingManager.userColor}` }}
+ onChange={() => {
+ activeItem.presentation_mediaStop = 'manual';
+ }}
checked={activeItem.presentation_mediaStop === 'manual'}
/>
<div>At media end time</div>
@@ -2025,35 +2418,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<input
className="presBox-checkbox"
type="checkbox"
- style={{ border: `solid 1px ${SettingsManager.userColor}` }}
- onChange={() => (activeItem.presentation_mediaStop = 'auto')}
+ style={{ border: `solid 1px ${SnappingManager.userColor}` }}
+ onChange={() => {
+ activeItem.presentation_mediaStop = 'auto';
+ }}
checked={activeItem.presentation_mediaStop === 'auto'}
/>
<div>On slide change</div>
</div>
- {/* <div className="checkbox-container">
- <input className="presBox-checkbox"
- type="checkbox"
- onChange={() => activeItem.mediaStop = "afterSlide"}
- checked={activeItem.mediaStop === "afterSlide"}
- />
- <div className="checkbox-dropdown">
- After chosen slide
- <select className="presBox-viewPicker"
- style={{ opacity: activeItem.mediaStop === "afterSlide" && this.itemIndex !== this.childDocs.length - 1 ? 1 : 0.3 }}
- onPointerDown={e => e.stopPropagation()}
- onChange={this.mediaStopChanged}
- value={mediaStopDocStr}>
- {this.mediaStopSlides}
- </select>
- </div>
- </div> */}
</div>
</div>
</div>
</div>
);
}
+ return undefined;
}
@computed get newDocumentToolbarDropdown() {
return (
@@ -2117,9 +2496,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get newDocumentDropdown() {
return (
- <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+ <div className="presBox-ribbon" onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
<div className="ribbon-box">
- Slide Title: <br></br>
+ Slide Title: <br />
<input
className="ribbon-textInput"
placeholder="..."
@@ -2128,16 +2507,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
onChange={e => {
e.stopPropagation();
e.preventDefault();
- runInAction(() => (this.title = e.target.value));
- }}></input>
+ runInAction(() => {
+ this.title = e.target.value;
+ });
+ }}
+ />
</div>
<div className="ribbon-box">
Choose type:
<div className="ribbon-doubleButton">
- <div title="Text" className={'ribbon-toggle'} style={{ background: this.addFreeform ? '' : Colors.LIGHT_BLUE }} onClick={action(() => (this.addFreeform = !this.addFreeform))}>
+ <div
+ title="Text"
+ className="ribbon-toggle"
+ style={{ background: this.addFreeform ? '' : Colors.LIGHT_BLUE }}
+ onClick={action(() => {
+ this.addFreeform = !this.addFreeform;
+ })}>
Text
</div>
- <div title="Freeform" className={'ribbon-toggle'} style={{ background: this.addFreeform ? Colors.LIGHT_BLUE : '' }} onClick={action(() => (this.addFreeform = !this.addFreeform))}>
+ <div
+ title="Freeform"
+ className="ribbon-toggle"
+ style={{ background: this.addFreeform ? Colors.LIGHT_BLUE : '' }}
+ onClick={action(() => {
+ this.addFreeform = !this.addFreeform;
+ })}>
Freeform
</div>
</div>
@@ -2145,23 +2539,49 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="ribbon-box" style={{ display: this.addFreeform ? 'grid' : 'none' }}>
Preset layouts:
<div className="layout-container" style={{ height: this.openLayouts ? 'max-content' : '75px' }}>
- <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'blank'))} />
- <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'title'))}>
+ <div
+ className="layout"
+ style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'blank';
+ })}
+ />
+ <div
+ className="layout"
+ style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'title';
+ })}>
<div className="title">Title</div>
<div className="subtitle">Subtitle</div>
</div>
- <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'header'))}>
+ <div
+ className="layout"
+ style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'header';
+ })}>
<div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>
Section header
</div>
</div>
- <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'content'))}>
+ <div
+ className="layout"
+ style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'content';
+ })}>
<div className="title" style={{ alignSelf: 'center' }}>
Title
</div>
<div className="content">Text goes here</div>
</div>
- <div className="layout" style={{ border: this.layout === 'twoColumns' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'twoColumns'))}>
+ <div
+ className="layout"
+ style={{ border: this.layout === 'twoColumns' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'twoColumns';
+ })}>
<div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>
Title
</div>
@@ -2173,8 +2593,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</div>
</div>
- <div className="open-layout" onClick={action(() => (this.openLayouts = !this.openLayouts))}>
- <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={'caret-down'} size={'lg'} />
+ <div
+ className="open-layout"
+ onClick={action(() => {
+ this.openLayouts = !this.openLayouts;
+ })}>
+ <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon="caret-down" size="lg" />
</div>
</div>
<div className="ribbon-final-box">
@@ -2189,17 +2613,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
createNewSlide = (layout?: string, title?: string, freeform?: boolean) => {
- let doc = undefined;
+ let doc;
if (layout) doc = this.createTemplate(layout);
if (freeform && layout) doc = this.createTemplate(layout, title);
if (!freeform && !layout) doc = Docs.Create.TextDocument('', { _nativeWidth: 400, _width: 225, title: title });
if (doc) {
- const tabMap = CollectionDockingView.Instance?.tabMap;
- const tab = tabMap && Array.from(tabMap).find(tab => tab.DashDoc.type === DocumentType.COL)?.DashDoc;
- const presCollection = DocumentManager.GetContextPath(this.activeItem).reverse().lastElement().presentation_targetDoc ?? tab;
+ const docTab = PresBox._getTabDocs().find(tdoc => tdoc.type === DocumentType.COL);
+ const presCollection = DocCast(DocumentView.getContextPath(this.activeItem).reverse().lastElement().presentation_targetDoc, docTab);
const data = Cast(presCollection?.data, listSpec(Doc));
- const config_data = Cast(this.Document.data, listSpec(Doc));
- if (data && config_data) {
+ const configData = Cast(this.Document.data, listSpec(Doc));
+ if (data && configData) {
data.push(doc);
this._props.pinToPres(doc, {});
this.gotoDocument(this.childDocs.length, this.activeItem);
@@ -2221,12 +2644,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const content2 = () => Docs.Create.TextDocument('Click to change text', { title: 'Column 2', _width: 185, _height: 140, x: 205, y: 80, _text_fontSize: '14pt' });
// prettier-ignore
switch (layout) {
- case 'blank': return Docs.Create.FreeformDocument([], { title: input ? input : 'Blank slide', _width: 400, _height: 225, x, y });
- case 'title': return Docs.Create.FreeformDocument([title(), subtitle()], { title: input ? input : 'Title slide', _width: 400, _height: 225, _freeform_fitContentsToBox: true, x, y });
- case 'header': return Docs.Create.FreeformDocument([header()], { title: input ? input : 'Section header', _width: 400, _height: 225, _freeform_fitContentsToBox: true, x, y });
- case 'content': return Docs.Create.FreeformDocument([contentTitle(), content()], { title: input ? input : 'Title and content', _width: 400, _height: 225, _freeform_fitContentsToBox: true, x, y });
- case 'twoColumns': return Docs.Create.FreeformDocument([contentTitle(), content1(), content2()], { title: input ? input : 'Title and two columns', _width: 400, _height: 225, _freeform_fitContentsToBox: true, x, y })
+ case 'blank': return Docs.Create.FreeformDocument([], { title: input || 'Blank slide', _width: 400, _height: 225, x, y });
+ case 'title': return Docs.Create.FreeformDocument([title(), subtitle()], { title: input || 'Title slide', _width: 400, _height: 225, _freeform_fitContentsToBox: true, x, y });
+ case 'header': return Docs.Create.FreeformDocument([header()], { title: input || 'Section header', _width: 400, _height: 225, _freeform_fitContentsToBox: true, x, y });
+ case 'content': return Docs.Create.FreeformDocument([contentTitle(), content()], { title: input || 'Title and content', _width: 400, _height: 225, _freeform_fitContentsToBox: true, x, y });
+ case 'twoColumns': return Docs.Create.FreeformDocument([contentTitle(), content1(), content2()], { title: input || 'Title and two columns', _width: 400, _height: 225, _freeform_fitContentsToBox: true, x, y })
+ default:
}
+ return undefined;
};
// Dropdown that appears when the user wants to begin presenting (either minimize or sidebar view)
@@ -2269,17 +2694,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
@action
- toggleProperties = () => (SettingsManager.Instance.propertiesWidth = SettingsManager.Instance.propertiesWidth > 0 ? 0 : 250);
+ toggleProperties = () => {
+ SnappingManager.SetPropertiesWidth(SnappingManager.PropertiesWidth > 0 ? 0 : 250);
+ };
+
+ @action
+ openProperties = () => {
+ // need to also focus slide
+ SnappingManager.SetPropertiesWidth(250);
+ };
@computed get toolbar() {
- const propIcon = SettingsManager.Instance.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left';
- const propTitle = SettingsManager.Instance.propertiesWidth > 0 ? 'Close Presentation Panel' : 'Open Presentation Panel';
+ const propIcon = SnappingManager.PropertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left';
+ const propTitle = SnappingManager.PropertiesWidth > 0 ? 'Close Presentation Panel' : 'Open Presentation Panel';
const mode = StrCast(this.Document._type_collection) as CollectionViewType;
const isMini: boolean = this.toolbarWidth <= 100;
- const activeColor = SettingsManager.userVariantColor;
- const inactiveColor = lightOrDark(SettingsManager.userBackgroundColor) === Colors.WHITE ? Colors.WHITE : SettingsManager.userBackgroundColor;
+ const activeColor = SnappingManager.userVariantColor;
+ const inactiveColor = lightOrDark(SnappingManager.userBackgroundColor) === Colors.WHITE ? Colors.WHITE : SnappingManager.userBackgroundColor;
return mode === CollectionViewType.Carousel3D || Doc.IsInMyOverlay(this.Document) ? null : (
- <div id="toolbarContainer" className={'presBox-toolbar'}>
+ <div id="toolbarContainer" className="presBox-toolbar">
{/* <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
<FontAwesomeIcon icon={"plus"} />
<FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
@@ -2289,7 +2722,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
style={{ opacity: this.childDocs.length > 1 ? 1 : 0.3, color: this._pathBoolean ? Colors.MEDIUM_BLUE : 'white', width: isMini ? '100%' : undefined }}
className="toolbar-button"
onClick={this.childDocs.length > 1 ? () => this.togglePath() : undefined}>
- <FontAwesomeIcon icon={'exchange-alt'} />
+ <FontAwesomeIcon icon="exchange-alt" />
</div>
</Tooltip>
{isMini ? null : (
@@ -2297,12 +2730,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="toolbar-divider" />
<Tooltip title={<div className="dash-tooltip">{this._presKeyEvents ? 'Keys are active' : 'Keys are not active - click anywhere on the presentation trail to activate keys'}</div>}>
<div className="toolbar-button" style={{ cursor: this._presKeyEvents ? 'default' : 'pointer', position: 'absolute', right: 30, fontSize: 16 }}>
- <FontAwesomeIcon className={'toolbar-thumbtack'} icon={'keyboard'} style={{ color: this._presKeyEvents ? activeColor : inactiveColor }} />
+ <FontAwesomeIcon className="toolbar-thumbtack" icon="keyboard" style={{ color: this._presKeyEvents ? activeColor : inactiveColor }} />
</div>
</Tooltip>
<Tooltip title={<div className="dash-tooltip">{propTitle}</div>}>
<div className="toolbar-button" style={{ position: 'absolute', right: 4, fontSize: 16 }} onClick={this.toggleProperties}>
- <FontAwesomeIcon className={'toolbar-thumbtack'} icon={propIcon} style={{ color: SettingsManager.Instance.propertiesWidth > 0 ? activeColor : inactiveColor }} />
+ <FontAwesomeIcon className="toolbar-thumbtack" icon={propIcon} style={{ color: SnappingManager.PropertiesWidth > 0 ? activeColor : inactiveColor }} />
</div>
</Tooltip>
</>
@@ -2347,7 +2780,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.gotoDocument(this.itemIndex, this.activeItem);
}
})}>
- <FontAwesomeIcon icon={'play-circle'} />
+ <FontAwesomeIcon icon="play-circle" />
<div style={{ display: this._props.PanelWidth() > 200 ? 'inline-flex' : 'none' }}>&nbsp; Present</div>
</div>
{mode === CollectionViewType.Carousel3D || isMini ? null : (
@@ -2356,7 +2789,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
onClick={action(() => {
if (this.childDocs.length) this._presentTools = !this._presentTools;
})}>
- <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this._presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={'angle-down'} />
+ <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this._presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon="angle-down" />
{this.presentDropdown}
</div>
)}
@@ -2377,12 +2810,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// Case 1: There are still other frames and should go through all frames before going to next slide
return (
<div className="presPanelOverlay" style={{ display: this.layoutDoc.presentation_status !== 'edit' ? 'inline-flex' : 'none' }}>
- <Tooltip title={<div className="dash-tooltip">{'Loop'}</div>}>
+ <Tooltip title={<div className="dash-tooltip">Loop</div>}>
<div
className="presPanel-button"
style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }}
- onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop), false, false)}>
- <FontAwesomeIcon icon={'redo-alt'} />
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ () => {
+ this.layoutDoc.presLoop = !this.layoutDoc.presLoop;
+ },
+ false,
+ false
+ )
+ }>
+ <FontAwesomeIcon icon="redo-alt" />
</div>
</Tooltip>
<div className="presPanel-divider" />
@@ -2407,7 +2852,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
false
)
}>
- <FontAwesomeIcon icon={'arrow-left'} />
+ <FontAwesomeIcon icon="arrow-left" />
</div>
<Tooltip title={<div className="dash-tooltip">{this.layoutDoc.presentation_status === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div>}>
<div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.startOrPause(true), false, false)}>
@@ -2435,10 +2880,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
false
)
}>
- <FontAwesomeIcon icon={'arrow-right'} />
+ <FontAwesomeIcon icon="arrow-right" />
</div>
- <div className="presPanel-divider"></div>
- <Tooltip title={<div className="dash-tooltip">{'Click to return to 1st slide'}</div>}>
+ <div className="presPanel-divider" />
+ <Tooltip title={<div className="dash-tooltip">Click to return to 1st slide</div>}>
<div
className="presPanel-button"
style={{ border: 'solid 1px white' }}
@@ -2462,7 +2907,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
{inOverlay ? '' : 'Slide'} {this.itemIndex + 1}
{this.activeItem?.presentation_indexed !== undefined ? `(${this.activeItem.presentation_indexed}/${this.progressivizedItems(this.activeItem)?.length})` : ''} / {this.childDocs.length}
</div>
- <div className="presPanel-divider"></div>
+ <div className="presPanel-divider" />
{this._props.PanelWidth() > 250 ? (
<div
className="presPanel-button-text"
@@ -2476,7 +2921,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
) : (
<div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.exitClicked, false, false)}>
- <FontAwesomeIcon icon={'times'} />
+ <FontAwesomeIcon icon="times" />
</div>
)}
</div>
@@ -2491,7 +2936,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
@action
- prevClicked = (e: PointerEvent) => {
+ prevClicked = () => {
this.back();
if (this._presTimer) {
clearTimeout(this._presTimer);
@@ -2500,7 +2945,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
@action
- nextClicked = (e: PointerEvent) => {
+ nextClicked = () => {
this.next();
if (this._presTimer) {
clearTimeout(this._presTimer);
@@ -2516,7 +2961,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
AddToMap = (treeViewDoc: Doc, index: number[]) => {
if (!treeViewDoc.presentation_targetDoc) return this.childDocs; // if treeViewDoc is not a pres elements, then it's a sub-bullet of a progressivized slide which isn't added to the linearized list of pres elements since it's not really a pres element.
- var indexNum = 0;
+ let indexNum = 0;
for (let i = 0; i < index.length; i++) {
indexNum += index[i] * 10 ** -i;
}
@@ -2528,19 +2973,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.dataDoc[this.presFieldKey] = new List<Doc>(sorted); // this is a flat array of Docs
}
}
+ return undefined;
};
SlideIndex = (slideDoc: Doc) => DocListCast(this.dataDoc[this.presFieldKey]).indexOf(slideDoc);
- RemFromMap = (treeViewDoc: Doc, index: number[]) => {
+ RemFromMap = (treeViewDoc: Doc) => {
if (!treeViewDoc.presentation_targetDoc) return this.childDocs; // if treeViewDoc is not a pres elements, then it's a sub-bullet of a progressivized slide which isn't added to the linearized list of pres elements since it's not really a pres element.
if (!this._unmounting && this.isTree) {
this._treeViewMap.delete(treeViewDoc);
this.dataDoc[this.presFieldKey] = new List<Doc>(this.sort(this._treeViewMap));
}
+ return undefined;
};
- sort = (treeView_Map: Map<Doc, number>) => [...treeView_Map.entries()].sort((a: [Doc, number], b: [Doc, number]) => (a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0)).map(kv => kv[0]);
+ sort = (treeViewMap: Map<Doc, number>) => [...treeViewMap.entries()].sort((a: [Doc, number], b: [Doc, number]) => (a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0)).map(kv => kv[0]);
render() {
// needed to ensure that the childDocs are loaded for looking up fields
@@ -2552,21 +2999,38 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
(this.activeItem.presentation_indexed === undefined || NumCast(this.activeItem.presentation_indexed) === (this.progressivizedItems(this.activeItem)?.length ?? 0));
const presStart = !this.layoutDoc.presLoop && this.itemIndex === 0;
return this._props.addDocTab === returnFalse ? ( // bcz: hack!! - addDocTab === returnFalse only when this is being rendered by the OverlayView which means the doc is a mini player
- <div className="miniPres" onClick={e => e.stopPropagation()} onPointerEnter={action(e => (this._forceKeyEvents = true))}>
+ <div
+ className="miniPres"
+ onClick={e => e.stopPropagation()}
+ onPointerEnter={action(() => {
+ this._forceKeyEvents = true;
+ })}>
<div
className="presPanelOverlay"
style={{ display: 'inline-flex', height: 30, background: Doc.ActivePresentation === this.Document ? 'green' : '#323232', top: 0, zIndex: 3000000, boxShadow: this._presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}>
- <Tooltip title={<div className="dash-tooltip">{'Loop'}</div>}>
+ <Tooltip title={<div className="dash-tooltip">Loop</div>}>
<div
className="presPanel-button"
style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : undefined }}
- onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop), false, false)}>
- <FontAwesomeIcon icon={'redo-alt'} />
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ returnFalse,
+ () => {
+ this.layoutDoc.presLoop = !this.layoutDoc.presLoop;
+ },
+ false,
+ false
+ )
+ }>
+ <FontAwesomeIcon icon="redo-alt" />
</div>
</Tooltip>
- <div className="presPanel-divider"></div>
+ <div className="presPanel-divider" />
<div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.prevClicked, false, false)}>
- <FontAwesomeIcon icon={'arrow-left'} />
+ <FontAwesomeIcon icon="arrow-left" />
</div>
<Tooltip title={<div className="dash-tooltip">{this.layoutDoc.presentation_status === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div>}>
<div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.startOrPause(true), false, false)}>
@@ -2574,10 +3038,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</Tooltip>
<div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.nextClicked, false, false)}>
- <FontAwesomeIcon icon={'arrow-right'} />
+ <FontAwesomeIcon icon="arrow-right" />
</div>
- <div className="presPanel-divider"></div>
- <Tooltip title={<div className="dash-tooltip">{'Click to return to 1st slide'}</div>}>
+ <div className="presPanel-divider" />
+ <Tooltip title={<div className="dash-tooltip">Click to return to 1st slide</div>}>
<div className="presPanel-button" style={{ border: 'solid 1px white' }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.gotoDocument(0, this.activeItem), false, false)}>
<b>1</b>
</div>
@@ -2601,31 +3065,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="Slide">
{mode !== CollectionViewType.Invalid ? (
<CollectionView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
PanelWidth={this._props.PanelWidth}
PanelHeight={this.panelHeight}
- childIgnoreNativeSize={true}
+ childIgnoreNativeSize
moveDocument={returnFalse}
- ignoreUnrendered={true}
+ ignoreUnrendered
childDragAction={dropActionType.move}
setContentViewBox={emptyFunction}
- //childLayoutFitWidth={returnTrue}
+ // childLayoutFitWidth={returnTrue}
childOpacity={returnOne}
childClickScript={PresBox.navigateToDocScript}
childLayoutTemplate={this.childLayoutTemplate}
childXPadding={Doc.IsComicStyle(this.Document) ? 20 : undefined}
filterAddDocument={this.addDocumentFilter}
removeDocument={returnFalse}
- dontRegisterView={true}
+ dontRegisterView
focus={this.focusElement}
ScreenToLocalTransform={this.getTransform}
AddToMap={this.AddToMap}
RemFromMap={this.RemFromMap}
- hierarchyIndex={emptyPath as any as number[]}
+ hierarchyIndex={emptyPath}
/>
) : null}
</div>
-
{/* {
// if the document type is a presentation, then the collection stacking view has a "+ new slide" button at the bottom of the stack
<Tooltip title={<div className="dash-tooltip">{'Click on document to pin to presentaiton or make a marquee selection to pin your desired view'}</div>}>
@@ -2635,11 +3099,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</Tooltip>
} */}
</div>
+ {/* presbox chatbox */}
+ {this.chatActive && <div className="presBox-chatbox" />}
</div>
);
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function navigateToDoc(bestTarget: Doc, activeItem: Doc) {
PresBox.NavigateToTarget(bestTarget, activeItem);
});
+
+Docs.Prototypes.TemplateMap.set(DocumentType.PRES, {
+ layout: { view: PresBox, dataField: 'data' },
+ options: { acl: '', defaultDoubleClick: 'ignore', hideClickBehaviors: true, layout_hideLinkAnchors: true },
+});
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 5b2aa1cde..25adfba23 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -1,27 +1,30 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils';
import { Doc, DocListCast, Opt } from '../../../../fields/Doc';
import { Id } from '../../../../fields/FieldSymbols';
import { List } from '../../../../fields/List';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils';
+import { emptyFunction } from '../../../../Utils';
import { Docs } from '../../../documents/Documents';
-import { CollectionViewType } from '../../../documents/DocumentTypes';
-import { DocumentManager } from '../../../util/DocumentManager';
+import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
import { DragManager } from '../../../util/DragManager';
-import { SettingsManager } from '../../../util/SettingsManager';
+import { SnappingManager } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
import { undoable, undoBatch } from '../../../util/UndoManager';
import { TreeView } from '../../collections/TreeView';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { EditableView } from '../../EditableView';
import { Colors } from '../../global/globalEnums';
-import { DocumentView } from '../../nodes/DocumentView';
-import { FieldView, FieldViewProps } from '../../nodes/FieldView';
-import { StyleProp } from '../../StyleProvider';
+import { PinDocView } from '../../PinFuncs';
+import { StyleProp } from '../../StyleProp';
+import { DocumentView } from '../DocumentView';
+import { FieldView, FieldViewProps } from '../FieldView';
import { PresBox } from './PresBox';
import './PresElementBox.scss';
import { PresMovement } from './PresEnums';
@@ -61,7 +64,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
// Since this node is being rendered with a template, this method retrieves
// the actual slide being rendered from the auto-generated rendering template
@computed get slideDoc() {
- return this._props.TemplateDataDocument ?? this.Document;
+ return DocCast(this.Document.rootDocument, this.Document);
}
// this is the document in the workspaces that is targeted by the slide
@@ -71,7 +74,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
// computes index of this presentation slide in the presBox list
@computed get indexInPres() {
- return this.presBoxView?.SlideIndex(this.slideDoc);
+ return this.presBoxView?.SlideIndex(this.slideDoc) ?? 0;
}
@computed get selectedArray() {
@@ -86,7 +89,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.layoutDoc.layout_hideLinkButton = true;
this._heightDisposer = reaction(
() => ({ expand: this.slideDoc.presentation_expandInlineButton, height: this.collapsedHeight }),
- ({ expand, height }) => (this.layoutDoc._height = height + (expand ? this.expandViewHeight : 0)),
+ ({ expand, height }) => {
+ this.layoutDoc._height = height + (expand ? this.expandViewHeight : 0);
+ },
{ fireImmediately: true }
);
}
@@ -94,12 +99,14 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._heightDisposer?.();
}
- presExpandDocumentClick = () => (this.slideDoc.presentation_expandInlineButton = !this.slideDoc.presentation_expandInlineButton);
+ presExpandDocumentClick = () => {
+ this.slideDoc.presentation_expandInlineButton = !this.slideDoc.presentation_expandInlineButton;
+ };
embedHeight = () => this.collapsedHeight + this.expandViewHeight;
embedWidth = () => this._props.PanelWidth() / 2;
- styleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
- return property === StyleProp.Opacity ? 1 : this._props.styleProvider?.(doc, props, property);
- };
+ // prettier-ignore
+ styleProvider = ( doc: Doc | undefined, props: Opt<FieldViewProps>, property: string ): any =>
+ (property === StyleProp.Opacity ? 1 : this._props.styleProvider?.(doc, props, property));
/**
* The function that is responsible for rendering a preview or not for this
* presentation element.
@@ -113,7 +120,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
PanelHeight={this.embedHeight}
isContentActive={this._props.isContentActive}
styleProvider={this.styleProvider}
- hideLinkButton={true}
+ hideLinkButton
ScreenToLocalTransform={Transform.Identity}
renderDepth={this._props.renderDepth + 1}
containerViewPath={returnEmptyDoclist}
@@ -150,7 +157,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
ref={this._titleRef}
editing={undefined}
contents={doc.title}
- overflow={'ellipsis'}
+ overflow="ellipsis"
GetValue={() => StrCast(doc.title)}
SetValue={(value: string) => {
doc.title = !value.trim().length ? '-untitled-' : value;
@@ -177,10 +184,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
e.preventDefault();
if (element && !(e.ctrlKey || e.metaKey || e.button === 2)) {
this.presBoxView?.regularSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, true, false);
- setupMoveUpEvents(this, e, this.startDrag, emptyFunction, e => {
- e.stopPropagation();
- e.preventDefault();
- this.presBoxView?.modifierSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, e.shiftKey || e.ctrlKey || e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey);
+ setupMoveUpEvents(this, e, this.startDrag, emptyFunction, clickEv => {
+ clickEv.stopPropagation();
+ clickEv.preventDefault();
+ this.presBoxView?.modifierSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, clickEv.shiftKey || clickEv.ctrlKey || clickEv.metaKey, clickEv.ctrlKey || clickEv.metaKey, clickEv.shiftKey);
this.presBoxView?.activeItem && this.showRecording(this.presBoxView?.activeItem);
});
}
@@ -190,6 +197,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
* Function to drag and drop the pres element to a diferent location
*/
startDrag = (e: PointerEvent) => {
+ this.presBoxView?.regularSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, true, false);
const miniView: boolean = this.toolbarWidth <= 100;
const activeItem = this.slideDoc;
const dragArray = this.presBoxView?._dragArray ?? [];
@@ -209,7 +217,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
} else if (dragArray.length >= 1) {
const doc = document.createElement('div');
doc.className = 'presItem-multiDrag';
- doc.innerText = 'Move ' + this.selectedArray?.size + ' slides';
+ doc.innerText = 'Move ' + (this.selectedArray?.size ?? 0) + ' slides';
doc.style.position = 'absolute';
doc.style.top = e.clientY + 'px';
doc.style.left = e.clientX - 50 + 'px';
@@ -217,7 +225,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
if (activeItem) {
- runInAction(() => (this._dragging = true));
+ runInAction(() => {
+ this._dragging = true;
+ });
DragManager.StartDocumentDrag(
dragItem.map(ele => ele),
dragData,
@@ -225,7 +235,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
e.clientY,
undefined,
action(() => {
- Array.from(classesToRestore).forEach(pair => (pair[0].className = pair[1]));
+ Array.from(classesToRestore).forEach(pair => {
+ // eslint-disable-next-line prefer-destructuring
+ pair[0].className = pair[1];
+ });
this._dragging = false;
})
);
@@ -234,7 +247,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
return false;
};
- onPointerOver = (e: any) => {
+ onPointerOver = () => {
document.removeEventListener('pointermove', this.onPointerMove);
document.addEventListener('pointermove', this.onPointerMove);
};
@@ -244,7 +257,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
const dragIsPresItem = DragManager.docsBeingDragged.some(d => d.presentation_targetDoc);
if (slide && dragIsPresItem) {
const rect = slide.getBoundingClientRect();
- const y = e.clientY - rect.top; //y position within the element.
+ const y = e.clientY - rect.top; // y position within the element.
const height = slide.clientHeight;
const halfLine = height / 2;
if (y <= halfLine) {
@@ -258,7 +271,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
document.removeEventListener('pointermove', this.onPointerMove);
};
- onPointerLeave = (e: any) => {
+ onPointerLeave = () => {
const slide = this._itemRef.current;
if (slide) {
slide.style.borderTop = '0px';
@@ -269,8 +282,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
toggleProperties = () => {
- if (SettingsManager.Instance.propertiesWidth < 5) {
- SettingsManager.Instance.propertiesWidth = 250;
+ if (SnappingManager.PropertiesWidth < 5) {
+ SnappingManager.SetPropertiesWidth(250);
}
};
@@ -323,7 +336,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
updateCapturedViewContents = undoable(
action((presTargetDoc: Doc, activeItem: Doc) => {
const target = DocCast(presTargetDoc.annotationOn) ?? presTargetDoc;
- PresBox.pinDocView(activeItem, { pinData: PresBox.pinDataTypes(target) }, target);
+ PinDocView(activeItem, { pinData: PresBox.pinDataTypes(target) }, target);
}),
'updated captured view contents'
);
@@ -340,7 +353,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
hideRecording = undoable(
- action((e: React.MouseEvent, iconClick: boolean = false) => {
+ action((e: React.MouseEvent) => {
e.stopPropagation();
this.removeAllRecordingInOverlay();
}),
@@ -395,7 +408,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
lfg = (e: React.MouseEvent) => {
e.stopPropagation();
// TODO: fix this bug
- const { toggleChildrenRun } = this.slideDoc;
+ // const { toggleChildrenRun } = this.slideDoc;
TreeView.ToggleChildrenRun.get(this.slideDoc)?.();
// call this.slideDoc.recurChildren() to get all the children
@@ -404,17 +417,15 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed
get toolbarWidth(): number {
- const presBoxDocView = DocumentManager.Instance.getDocumentView(this.presBox);
+ const presBoxDocView = DocumentView.getDocumentView(this.presBox);
const width = NumCast(this.presBox?._width);
- return presBoxDocView ? presBoxDocView._props.PanelWidth() : width ? width : 300;
+ return presBoxDocView ? presBoxDocView._props.PanelWidth() : width || 300;
}
@computed get presButtons() {
- const presBox = this.presBox;
+ const { presBox, targetDoc, slideDoc: activeItem } = this;
const presBoxColor = StrCast(presBox?._backgroundColor);
const presColorBool = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false;
- const targetDoc = this.targetDoc;
- const activeItem = this.slideDoc;
const hasChildren = BoolCast(this.slideDoc?.hasChildren);
const items: JSX.Element[] = [];
@@ -441,7 +452,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
items.push(
<Tooltip key="slash" title={<div className="dash-tooltip">{this.videoRecordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}</div>}>
- <div className="slideButton" onClick={e => (this.videoRecordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}>
+ <div className="slideButton" onClick={e => (this.videoRecordingIsInOverlay ? this.hideRecording(e) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}>
<FontAwesomeIcon icon={`video${this.videoRecordingIsInOverlay ? '-slash' : ''}`} onPointerDown={e => e.stopPropagation()} />
</div>
</Tooltip>
@@ -461,7 +472,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
}>
<div
className="slideButton"
- onClick={() => (activeItem.presentation_groupWithUp = (NumCast(activeItem.presentation_groupWithUp) + 1) % 3)}
+ onClick={() => {
+ activeItem.presentation_groupWithUp = (NumCast(activeItem.presentation_groupWithUp) + 1) % 3;
+ }}
style={{
zIndex: 1000 - this.indexInPres,
fontWeight: 700,
@@ -471,7 +484,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
transform: activeItem.presentation_groupWithUp ? 'translate(0, -17px)' : undefined,
}}>
<div style={{ transform: activeItem.presentation_groupWithUp ? 'rotate(180deg) translate(0, -17.5px)' : 'rotate(0deg)' }}>
- <FontAwesomeIcon icon={'arrow-up'} onPointerDown={e => e.stopPropagation()} />
+ <FontAwesomeIcon icon="arrow-up" onPointerDown={e => e.stopPropagation()} />
</div>
</div>
</Tooltip>
@@ -500,15 +513,29 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.lfg(e);
}}
style={{ fontWeight: 700 }}>
- <FontAwesomeIcon icon={'circle-play'} onPointerDown={e => e.stopPropagation()} />
+ <FontAwesomeIcon icon="circle-play" onPointerDown={e => e.stopPropagation()} />
</div>
</Tooltip>
);
}
items.push(
<Tooltip key="trash" title={<div className="dash-tooltip">Remove from presentation</div>}>
- <div className={'slideButton'} onClick={this.removePresentationItem}>
- <FontAwesomeIcon icon={'trash'} onPointerDown={e => e.stopPropagation()} />
+ <div className="slideButton" onClick={this.removePresentationItem}>
+ <FontAwesomeIcon icon="trash" onPointerDown={e => e.stopPropagation()} />
+ </div>
+ </Tooltip>
+ );
+ items.push(
+ <Tooltip key="customize-slide" title={<div className="dash-tooltip">Customize Slide</div>}>
+ <div
+ className={'slideButton'}
+ onClick={() => {
+ this.presBoxView?.regularSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, true, false);
+ PresBox.Instance.navigateToActiveItem();
+ PresBox.Instance.openProperties();
+ PresBox.Instance.slideToModify = this.Document;
+ }}>
+ <FontAwesomeIcon icon={'edit'} onPointerDown={e => e.stopPropagation()} />
</div>
</Tooltip>
);
@@ -516,18 +543,17 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
@computed get mainItem() {
- const isSelected: boolean = this.selectedArray?.has(this.slideDoc) ? true : false;
+ const { presBox, slideDoc: activeItem } = this;
+ const isSelected: boolean = !!this.selectedArray?.has(activeItem);
const isCurrent: boolean = this.presBox?._itemIndex === this.indexInPres;
const miniView: boolean = this.toolbarWidth <= 110;
- const presBox = this.presBox; //presBox
const presBoxColor: string = StrCast(presBox?._backgroundColor);
const presColorBool: boolean = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false;
- const activeItem: Doc = this.slideDoc;
return (
<div
className="presItem-container"
- key={this.slideDoc[Id] + this.indexInPres}
+ key={activeItem[Id] + this.indexInPres}
ref={this._itemRef}
style={{
backgroundColor: presColorBool ? (isSelected ? 'rgba(250,250,250,0.3)' : 'transparent') : isSelected ? Colors.LIGHT_BLUE : 'transparent',
@@ -537,9 +563,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
paddingTop: NumCast(this.layoutDoc._yPadding, this._props.yPadding),
paddingBottom: NumCast(this.layoutDoc._yPadding, this._props.yPadding),
}}
- onDoubleClick={action(e => {
+ onDoubleClick={action(() => {
this.toggleProperties();
- this.presBoxView?.regularSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, false);
+ this.presBoxView?.regularSelect(activeItem, this._itemRef.current!, this._dragRef.current!, false);
})}
onPointerOver={this.onPointerOver}
onPointerLeave={this.onPointerLeave}
@@ -551,11 +577,11 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
) : (
<div
ref={this._dragRef}
- className={`presItem-slide ${isCurrent ? 'active' : ''}${this.slideDoc.runProcess ? ' testingv2' : ''}`}
+ className={`presItem-slide ${isCurrent ? 'active' : ''}${activeItem.runProcess ? ' testingv2' : ''}`}
style={{
display: 'infline-block',
backgroundColor: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
- //layout_boxShadow: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? '0 0 0px 1.5px' + presBoxColor : undefined) : undefined,
+ // layout_boxShadow: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? '0 0 0px 1.5px' + presBoxColor : undefined) : undefined,
border: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? presBoxColor + ' solid 2.5px' : undefined) : undefined,
}}>
<div
@@ -563,7 +589,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
style={{
display: 'inline-flex',
pointerEvents: isSelected ? undefined : 'none',
- width: `calc(100% ${this.slideDoc.presentation_expandInlineButton ? '- 50%' : ''} - ${this.presButtons.length * 22}px`,
+ width: `calc(100% ${activeItem.presentation_expandInlineButton ? '- 50%' : ''} - ${this.presButtons.length * 22}px`,
cursor: isSelected ? 'text' : 'grab',
}}>
<div
@@ -576,7 +602,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}}
onClick={e => e.stopPropagation()}>{`${this.indexInPres + 1}. `}</div>
- <EditableView ref={this._titleRef} oneLine={true} editing={!isSelected ? false : undefined} contents={activeItem.title} overflow={'ellipsis'} GetValue={() => StrCast(activeItem.title)} SetValue={this.onSetValue} />
+ <EditableView ref={this._titleRef} oneLine editing={!isSelected ? false : undefined} contents={activeItem.title} overflow="ellipsis" GetValue={() => StrCast(activeItem.title)} SetValue={this.onSetValue} />
</div>
{/* <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presItem-time" style={{ display: showMore ? "block" : "none" }}>{this.transition}</div></Tooltip> */}
{/* <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presItem-time" style={{ display: showMore ? "block" : "none" }}>{this.duration}</div></Tooltip> */}
@@ -594,3 +620,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
return !(this.slideDoc instanceof Doc) || this.targetDoc instanceof Promise ? null : this.mainItem;
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.PRESELEMENT, {
+ layout: { view: PresElementBox, dataField: 'data' },
+ options: { acl: '', title: 'pres element template', _layout_fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: 'data' },
+});
diff --git a/src/client/views/nodes/trails/PresEnums.ts b/src/client/views/nodes/trails/PresEnums.ts
index 564829d54..67cad9c5d 100644
--- a/src/client/views/nodes/trails/PresEnums.ts
+++ b/src/client/views/nodes/trails/PresEnums.ts
@@ -7,7 +7,7 @@ export enum PresMovement {
}
export enum PresEffect {
- Zoom = 'Zoom',
+ Expand = 'Expand',
Lightspeed = 'Lightspeed',
Fade = 'Fade in',
Flip = 'Flip',
diff --git a/src/client/views/nodes/trails/SlideEffect.scss b/src/client/views/nodes/trails/SlideEffect.scss
new file mode 100644
index 000000000..aa2e5bbd9
--- /dev/null
+++ b/src/client/views/nodes/trails/SlideEffect.scss
@@ -0,0 +1,19 @@
+.flip-container {
+ display: flex;
+ align-items: center;
+ height: 100%;
+ justify-content: center;
+}
+
+.flip-side {
+ position: absolute;
+ will-change: transform, opacity;
+ // backface-visibility: hidden;
+}
+
+.flip-front {
+}
+
+.flip-back {
+ // background-color: rgb(223, 223, 223);
+}
diff --git a/src/client/views/nodes/trails/SlideEffect.tsx b/src/client/views/nodes/trails/SlideEffect.tsx
new file mode 100644
index 000000000..00039e3cb
--- /dev/null
+++ b/src/client/views/nodes/trails/SlideEffect.tsx
@@ -0,0 +1,120 @@
+/* eslint-disable react/require-default-props */
+import { animated, to, useInView, useSpring } from '@react-spring/web';
+import React, { useEffect } from 'react';
+import { Doc } from '../../../../fields/Doc';
+import { NumCast } from '../../../../fields/Types';
+import { PresEffect, PresEffectDirection } from './PresEnums';
+import './SlideEffect.scss';
+import { emptyFunction } from '../../../../Utils';
+
+interface SlideEffectProps {
+ doc?: Doc; // pass in doc to extract width, height, bg
+ dir: PresEffectDirection;
+ presEffect: PresEffect;
+ springSettings: {
+ stiffness: number;
+ damping: number;
+ mass: number;
+ };
+ children: React.ReactNode;
+ infinite?: boolean;
+ startOpacity?: number; // set to zero to linearly fade in while animating
+}
+
+const DEFAULT_WIDTH = 40;
+const PREVIEW_OFFSET = 60;
+const ACTUAL_OFFSET = 200;
+
+/**
+ * This component wraps around the doc to create an effect animation, and also wraps the preview animations
+ * for the effects as well.
+ */
+export default function SpringAnimation({ doc, dir, springSettings, presEffect, children, infinite, startOpacity }: SlideEffectProps) {
+ const expandConfig = {
+ to: { scale: 1, x: 0, y: 0 },
+ from: { scale: 0, x: 0, y: 0 },
+ };
+ const fadeConfig = {
+ to: { x: 0, y: 0 },
+ from: { x: 0, y: 0 },
+ };
+ const rotateConfig = {
+ to: { x: 360, y: 0 },
+ from: { x: 0, y: 0 },
+ };
+ const flipConfig = {
+ to: { x: 180, y: 0 },
+ from: { x: 0, y: 0 },
+ };
+ const bounceConfig = {
+ to: { x: 0, y: 0 },
+ from: (() => {
+ const offset = infinite ? PREVIEW_OFFSET : ACTUAL_OFFSET;
+ switch (dir) {
+ case PresEffectDirection.Left: return { x: -offset, y: 0, };
+ case PresEffectDirection.Right: return { x: offset, y: 0, };
+ case PresEffectDirection.Top: return { x: 0, y: -offset, };
+ case PresEffectDirection.Bottom:return { x: 0, y: offset, };
+ default: return { x: 0, y: 0, }; // no movement for center
+ }})(), // prettier-ignore
+ };
+ const rollConfig = {
+ to: { x: 0, y: 0 },
+ from: (() => {
+ switch (dir) {
+ case PresEffectDirection.Left: return { x: -100, y: -120, };
+ case PresEffectDirection.Right: return { x: 100, y: 120, };
+ case PresEffectDirection.Top: return { x: -100, y: -120, };
+ case PresEffectDirection.Bottom: return { x: -100, y: -120, };
+ default: return { x: 0, y: 0, }; // no movement for center
+ }})(), // prettier-ignore
+ };
+
+ // prettier-ignore
+ const effectConfig = (() => {
+ switch (presEffect) {
+ case PresEffect.Fade: return fadeConfig;
+ case PresEffect.Bounce: return bounceConfig;
+ case PresEffect.Rotate: return rotateConfig;
+ case PresEffect.Flip: return flipConfig;
+ case PresEffect.Roll: return rollConfig;
+ case PresEffect.Lightspeed: return { from: {}, to: {} };
+ case PresEffect.Expand:
+ default: return expandConfig;
+ } // prettier-ignore
+ })();
+
+ const [springs, api] = useSpring(
+ () => ({
+ to: { ...effectConfig.to, opacity: 1 },
+ from: { ...effectConfig.from, opacity: startOpacity ?? 1 },
+ config: { tension: springSettings.stiffness, friction: springSettings.damping, mass: springSettings.mass },
+ onStart: emptyFunction,
+ onRest: emptyFunction,
+ }),
+ [springSettings]
+ );
+
+ const [ref, inView] = useInView({
+ once: true,
+ });
+ useEffect(() => {
+ if (inView) {
+ api.start({ loop: infinite, delay: infinite ? 500 : 0 });
+ }
+ }, [inView]);
+ const animatedDiv = (style: any) => (
+ <animated.div ref={ref} style={{ ...style, opacity: to(springs.opacity, val => `${val}`) }}>
+ {children}
+ </animated.div>
+ );
+ const [width, height] = [NumCast(doc?.width, DEFAULT_WIDTH), NumCast(doc?.height, DEFAULT_WIDTH)];
+ const flipAxis = dir === PresEffectDirection.Bottom || dir === PresEffectDirection.Top ? 'X' : 'Y';
+ const [rotateX, rotateY] = flipAxis === 'X' ? ['180deg', undefined] : [undefined, '180deg'];
+ switch (presEffect) {
+ case PresEffect.Flip: return animatedDiv({ transform: to(springs.x, val => `perspective(600px) rotate${flipAxis}(${val}deg)`), width, height, rotateX, rotateY })
+ case PresEffect.Rotate:return animatedDiv({ transform: to(springs.x, val => `rotate(${val}deg)`) });
+ case PresEffect.Roll: return animatedDiv({ transform: to([springs.x, springs.y], (val, val2) => `translate3d(${val}%, 0, 0) rotate3d(0, 0, 1, ${val2}deg)`) });
+ default: return animatedDiv(springs);
+ } // prettier-ignore
+}
diff --git a/src/client/views/nodes/trails/SpringUtils.ts b/src/client/views/nodes/trails/SpringUtils.ts
new file mode 100644
index 000000000..73e1e14f1
--- /dev/null
+++ b/src/client/views/nodes/trails/SpringUtils.ts
@@ -0,0 +1,177 @@
+import { PresEffect, PresEffectDirection, PresMovement } from './PresEnums';
+
+/**
+ * Utilities like enums and interfaces for spring-based transitions.
+ */
+
+export const springPreviewColors = ['rgb(37, 161, 255)', 'rgb(99, 37, 255)', 'rgb(182, 37, 255)', 'rgb(255, 37, 168)'];
+// the type of slide effect timing (spring-driven)
+export enum SpringType {
+ GENTLE = 'gentle',
+ QUICK = 'quick',
+ BOUNCY = 'bouncy',
+ CUSTOM = 'custom',
+}
+
+// settings that control slide effect spring settings
+export interface SpringSettings {
+ type: SpringType;
+ stiffness: number;
+ damping: number;
+ mass: number;
+}
+
+// Overall config
+
+export interface AnimationSettings {
+ effect: PresEffect;
+ direction: PresEffectDirection;
+ stiffness: number;
+ damping: number;
+ mass: number;
+}
+
+// Options in the movement easing dropdown
+export const easeItems = [
+ {
+ text: 'Ease',
+ val: 'ease',
+ },
+ {
+ text: 'Ease In',
+ val: 'ease-in',
+ },
+ {
+ text: 'Ease Out',
+ val: 'ease-out',
+ },
+ {
+ text: 'Ease In Out',
+ val: 'ease-in-out',
+ },
+ {
+ text: 'Linear',
+ val: 'linear',
+ },
+ {
+ text: 'Custom',
+ val: 'custom',
+ },
+];
+
+// Options in the movement type dropdown
+export const movementItems = [
+ { text: 'None', val: PresMovement.None },
+ { text: 'Center', val: PresMovement.Center },
+ { text: 'Zoom', val: PresMovement.Zoom },
+ { text: 'Pan', val: PresMovement.Pan },
+ { text: 'Jump', val: PresMovement.Jump },
+];
+
+// Items in the slide effect dropdown
+export const effectItems = Object.values(PresEffect)
+ .filter(v => isNaN(Number(v)))
+ .map(effect => ({
+ text: effect,
+ val: effect,
+ }));
+
+// Maps each PresEffect to the default timing configuration
+export const presEffectDefaultTimings: {
+ [key: string]: SpringSettings;
+} = {
+ Expand: { type: SpringType.GENTLE, stiffness: 100, damping: 15, mass: 1 },
+ Bounce: {
+ type: SpringType.BOUNCY,
+ stiffness: 600,
+ damping: 15,
+ mass: 1,
+ },
+ Lightspeed: {
+ type: SpringType.GENTLE,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ Fade: {
+ type: SpringType.GENTLE,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ Flip: {
+ type: SpringType.GENTLE,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ Rotate: {
+ type: SpringType.GENTLE,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ Roll: {
+ type: SpringType.GENTLE,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ None: {
+ type: SpringType.GENTLE,
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+};
+
+// Dropdown items of timings for the effect
+export const effectTimings = [
+ {
+ text: 'Gentle',
+ val: SpringType.GENTLE,
+ },
+ {
+ text: 'Quick',
+ val: SpringType.QUICK,
+ },
+ {
+ text: 'Bouncy',
+ val: SpringType.BOUNCY,
+ },
+ {
+ text: 'Custom',
+ val: SpringType.CUSTOM,
+ },
+];
+
+// Maps spring names to spring parameters
+export const springMappings: {
+ [key: string]: { stiffness: number; damping: number; mass: number };
+} = {
+ default: {
+ stiffness: 600,
+ damping: 15,
+ mass: 1,
+ },
+ gentle: {
+ stiffness: 100,
+ damping: 15,
+ mass: 1,
+ },
+ quick: {
+ stiffness: 300,
+ damping: 20,
+ mass: 1,
+ },
+ bouncy: {
+ stiffness: 600,
+ damping: 15,
+ mass: 1,
+ },
+ custom: {
+ stiffness: 100,
+ damping: 10,
+ mass: 1,
+ },
+};
diff --git a/src/client/views/nodes/trails/index.ts b/src/client/views/nodes/trails/index.ts
index 8f3f7b03a..7b18974df 100644
--- a/src/client/views/nodes/trails/index.ts
+++ b/src/client/views/nodes/trails/index.ts
@@ -1,3 +1,3 @@
-export * from "./PresBox";
-export * from "./PresElementBox";
-export * from "./PresEnums"; \ No newline at end of file
+export * from './PresBox';
+export * from './PresElementBox';
+export * from './PresEnums';
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index a0c3cf487..b7247a034 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -4,21 +4,22 @@ import { IReactionDisposer, ObservableMap, action, computed, makeObservable, obs
import { observer } from 'mobx-react';
import * as React from 'react';
import { ColorResult } from 'react-color';
-import { Utils, returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../Utils';
+import { ClientUtils, returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction, unimplementedFunction } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
-import { DocUtils, Docs } from '../../documents/Documents';
-import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
-import { DocumentType } from '../../documents/DocumentTypes';
-import { SelectionManager } from '../../util/SelectionManager';
+import { gptAPICall } from '../../apis/gpt/GPT';
+import { GPTCallType } from '../../apis/gpt/setup';
import { SettingsManager } from '../../util/SettingsManager';
import { AntimodeMenu, AntimodeMenuProps } from '../AntimodeMenu';
import { LinkPopup } from '../linking/LinkPopup';
+import { DocumentView } from '../nodes/DocumentView';
import './AnchorMenu.scss';
import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup';
-import { PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';
+import { Docs } from '../../documents/Documents';
@observer
export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
+ // eslint-disable-next-line no-use-before-define
static Instance: AnchorMenu;
private _disposer: IReactionDisposer | undefined;
@@ -37,9 +38,11 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@observable public Status: 'marquee' | 'annotation' | '' = '';
// GPT additions
- @observable private selectedText: string = '';
+ @observable private _selectedText: string = '';
@action
- public setSelectedText = (txt: string) => (this.selectedText = txt);
+ public setSelectedText = (txt: string) => {
+ this._selectedText = txt.trim();
+ };
public onMakeAnchor: () => Opt<Doc> = () => undefined; // Method to get anchor from text search
@@ -48,8 +51,8 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
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, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
- public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => undefined;
+ public Highlight: (color: string) => Opt<Doc> = (/* color: string */) => undefined;
+ public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = emptyFunction;
public Delete: () => void = unimplementedFunction;
public PinToPres: () => void = unimplementedFunction;
public MakeTargetToggle: () => void = unimplementedFunction;
@@ -66,8 +69,8 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
componentDidMount() {
this._disposer = reaction(
- () => SelectionManager.Views.slice(),
- sel => AnchorMenu.Instance.fadeOut(true)
+ () => DocumentView.Selected().slice(),
+ () => AnchorMenu.Instance.fadeOut(true)
);
}
@@ -88,6 +91,10 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
}
GPTPopup.Instance.setLoading(false);
};
+ // gptSummarize = async () => {
+ // GPTPopup.Instance?.setSelectedText(this._selectedText);
+ // GPTPopup.Instance.generateSummary();
+ // };
/**
* Invokes the API with the selected text and stores it in the selected text.
@@ -134,35 +141,35 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
setupMoveUpEvents(
this,
e,
- (e: PointerEvent) => {
- this.StartDrag(e, this._commentRef.current!);
+ (moveEv: PointerEvent) => {
+ this.StartDrag(moveEv, this._commentRef.current!);
return true;
},
returnFalse,
- e => this.OnClick?.(e)
+ clickEv => this.OnClick?.(clickEv)
);
};
audioDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, returnFalse, e => this.OnAudio?.(e));
+ setupMoveUpEvents(this, e, returnFalse, returnFalse, clickEv => this.OnAudio?.(clickEv));
};
cropDown = (e: React.PointerEvent) => {
setupMoveUpEvents(
this,
e,
- (e: PointerEvent) => {
- this.StartCropDrag(e, this._cropRef.current!);
+ (moveEv: PointerEvent) => {
+ this.StartCropDrag(moveEv, this._cropRef.current!);
return true;
},
returnFalse,
- e => this.OnCrop?.(e)
+ clickev => this.OnCrop?.(clickev)
);
};
@action
- highlightClicked = (e: React.MouseEvent) => {
- this.Highlight(this.highlightColor, false, undefined, true);
+ highlightClicked = () => {
+ this.Highlight(this.highlightColor);
AnchorMenu.Instance.fadeOut(true);
};
@@ -171,7 +178,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
<Group>
<IconButton
icon={<FontAwesomeIcon icon="highlighter" style={{ transition: 'transform 0.1s', transform: 'rotate(-45deg)' }} />}
- tooltip={'Click to Highlight'}
+ tooltip="Click to Highlight"
onClick={this.highlightClicked}
colorPicker={this.highlightColor}
color={SettingsManager.userColor}
@@ -187,16 +194,9 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
hsl: { a: 0, h: 0, s: 0, l: 0 },
rgb: { a: 0, r: 0, b: 0, g: 0 },
};
- this.highlightColor = Utils.colorString(col);
+ this.highlightColor = ClientUtils.colorString(col);
};
- /**
- * Returns whether the selected text can be summarized. The goal is to have
- * all selected text available to summarize but its only supported for pdf and web ATM.
- * @returns Whether the GPT icon for summarization should appear
- */
- canSummarize = () => SelectionManager.Docs.some(doc => [DocumentType.PDF, DocumentType.WEB].includes(doc.type as any));
-
render() {
const buttons =
this.Status === 'marquee' ? (
@@ -210,8 +210,8 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
color={SettingsManager.userColor}
/>
</div>
- {/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection*/}
- {AnchorMenu.Instance.StartCropDrag === unimplementedFunction && this.canSummarize() && (
+ {/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection */}
+ {this._selectedText && (
<IconButton
tooltip="Summarize with AI" //
onPointerDown={this.gptSummarize}
@@ -237,7 +237,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
<Popup
tooltip="Find document to link to selected text" //
type={Type.PRIM}
- icon={<FontAwesomeIcon icon={'search'} />}
+ icon={<FontAwesomeIcon icon="search" />}
popup={<LinkPopup key="popup" linkCreateAnchor={this.onMakeAnchor} />}
color={SettingsManager.userColor}
/>
@@ -280,7 +280,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
)}
{this.IsTargetToggler !== returnFalse && (
<Toggle
- tooltip={'Make target visibility toggle on click'}
+ tooltip="Make target visibility toggle on click"
type={Type.PRIM}
toggleType={ToggleType.BUTTON}
toggleStatus={this.IsTargetToggler()}
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index a1f5ce703..7dd4047c1 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -1,24 +1,50 @@
import { action, computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Id } from '../../../fields/FieldSymbols';
+import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
+import { Highlight } from '../../../fields/DocSymbols';
import { List } from '../../../fields/List';
-import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
-import { LinkFollower } from '../../util/LinkFollower';
+import { BoolCast, DocCast, NumCast, StrCast } from '../../../fields/Types';
import { LinkManager } from '../../util/LinkManager';
-import { undoBatch } from '../../util/UndoManager';
-import { OpenWhere } from '../nodes/DocumentView';
+import { undoable } from '../../util/UndoManager';
+import { ObservableReactComponent } from '../ObservableReactComponent';
+import { DocumentView } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
+import { OpenWhere } from '../nodes/OpenWhere';
import { AnchorMenu } from './AnchorMenu';
import './Annotation.scss';
-import { ObservableReactComponent } from '../ObservableReactComponent';
+
+interface IRegionAnnotationProps {
+ x: number;
+ y: number;
+ width: number;
+ height: number;
+ opacity: () => number;
+ background: () => string;
+ outline: () => string | undefined;
+}
+
+const RegionAnnotation = function (props: IRegionAnnotationProps) {
+ return (
+ <div
+ className="htmlAnnotation"
+ style={{
+ left: NumCast(props.x),
+ top: NumCast(props.y),
+ width: NumCast(props.width),
+ height: NumCast(props.height),
+ opacity: props.opacity(),
+ outline: props.outline(),
+ backgroundColor: props.background(),
+ }}
+ />
+ );
+};
interface IAnnotationProps extends FieldViewProps {
- anno: Doc;
- dataDoc: Doc;
+ annoDoc: Doc;
+ containerDataDoc: Doc;
fieldKey: string;
- showInfo?: (anno: Opt<Doc>) => void;
pointerEvents?: () => Opt<string>;
}
@observer
@@ -27,62 +53,45 @@ export class Annotation extends ObservableReactComponent<IAnnotationProps> {
super(props);
makeObservable(this);
}
- render() {
- return (
- <div style={{ display: this._props.anno.textCopied && !Doc.GetBrushHighlightStatus(this._props.anno) ? 'none' : undefined }}>
- {DocListCast(this._props.anno.text_inlineAnnotations).map(a => (
- <RegionAnnotation pointerEvents={this._props.pointerEvents} {...this._props} document={a} key={a[Id]} />
- ))}
- </div>
- );
- }
-}
-interface IRegionAnnotationProps extends IAnnotationProps {
- document: Doc;
- pointerEvents?: () => Opt<string>;
-}
-@observer
-class RegionAnnotation extends ObservableReactComponent<IRegionAnnotationProps> {
- private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
-
- @computed get annoTextRegion() {
- return Cast(this._props.document.annoTextRegion, Doc, null) || this._props.document;
+ @computed get linkHighlighted() {
+ const found = LinkManager.Instance.getAllDirectLinks(this._props.annoDoc).find(link => {
+ const a1 = Doc.getOppositeAnchor(link, this._props.annoDoc);
+ return a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, a1));
+ });
+ return found;
}
- @undoBatch
- deleteAnnotation = () => {
- const docAnnotations = DocListCast(this._props.dataDoc[this._props.fieldKey]);
- this._props.dataDoc[this._props.fieldKey] = new List<Doc>(docAnnotations.filter(a => a !== this.annoTextRegion));
+ deleteAnnotation = undoable(() => {
+ const docAnnotations = DocListCast(this._props.containerDataDoc[this._props.fieldKey]);
+ this._props.containerDataDoc[this._props.fieldKey] = new List<Doc>(docAnnotations.filter(a => a !== this._props.annoDoc));
AnchorMenu.Instance.fadeOut(true);
this._props.select(false);
- };
+ }, 'delete annotation');
+
+ pinToPres = undoable(() => this._props.pinToPres(this._props.annoDoc, {}), 'pin to pres');
- @undoBatch
- pinToPres = () => this._props.pinToPres(this.annoTextRegion, {});
+ makeTargetToggle = undoable(() => { this._props.annoDoc.followLinkToggle = !this._props.annoDoc.followLinkToggle }, "set link toggle"); // prettier-ignore
- @undoBatch
- makeTargretToggle = () => (this.annoTextRegion.followLinkToggle = !this.annoTextRegion.followLinkToggle);
+ isTargetToggler = () => BoolCast(this._props.annoDoc.followLinkToggle);
- isTargetToggler = () => BoolCast(this.annoTextRegion.followLinkToggle);
- @undoBatch
- showTargetTrail = (anchor: Doc) => {
+ showTargetTrail = undoable((anchor: Doc) => {
const trail = DocCast(anchor.presentationTrail);
if (trail) {
Doc.ActivePresentation = trail;
this._props.addDocTab(trail, OpenWhere.replaceRight);
}
- };
+ }, 'show target trail');
@action
onContextMenu = (e: React.MouseEvent) => {
AnchorMenu.Instance.Status = 'annotation';
- AnchorMenu.Instance.Delete = this.deleteAnnotation.bind(this);
+ AnchorMenu.Instance.Delete = this.deleteAnnotation;
AnchorMenu.Instance.Pinned = false;
AnchorMenu.Instance.PinToPres = this.pinToPres;
- AnchorMenu.Instance.MakeTargetToggle = this.makeTargretToggle;
+ AnchorMenu.Instance.MakeTargetToggle = this.makeTargetToggle;
AnchorMenu.Instance.IsTargetToggler = this.isTargetToggler;
- AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this.annoTextRegion);
+ AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this._props.annoDoc);
AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
e.stopPropagation();
e.preventDefault();
@@ -94,44 +103,43 @@ class RegionAnnotation extends ObservableReactComponent<IRegionAnnotationProps>
e.preventDefault();
} else if (e.button === 0) {
e.stopPropagation();
- LinkFollower.FollowLink(undefined, this.annoTextRegion, false);
+ DocumentView.FollowLink(undefined, this._props.annoDoc, false);
}
};
-
- @computed get linkHighlighted() {
- for (const link of LinkManager.Instance.getAllDirectLinks(this._props.document)) {
- const a1 = LinkManager.getOppositeAnchor(link, this._props.document);
- if (a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, this._props.document))) return true;
- }
- }
-
+ brushed = () => this._props.annoDoc && Doc.GetBrushHighlightStatus(this._props.annoDoc);
+ opacity = () => (this.brushed() === Doc.DocBrushStatus.highlighted ? 0.5 : 1);
+ outline = () => (this.linkHighlighted ? 'solid 1px lightBlue' : undefined);
+ background = () => (this._props.annoDoc[Highlight] ? 'orange' : StrCast(this._props.annoDoc.backgroundColor));
render() {
- const brushed = this.annoTextRegion && Doc.GetBrushHighlightStatus(this.annoTextRegion);
return (
- <div
- className="htmlAnnotation"
- ref={this._mainCont}
- onPointerEnter={action(() => {
- Doc.BrushDoc(this._props.anno);
- this._props.showInfo?.(this._props.anno);
- })}
- onPointerLeave={action(() => {
- Doc.UnBrushDoc(this._props.anno);
- this._props.showInfo?.(undefined);
- })}
- onPointerDown={this.onPointerDown}
- onContextMenu={this.onContextMenu}
- style={{
- left: NumCast(this._props.document.x),
- top: NumCast(this._props.document.y),
- width: NumCast(this._props.document._width),
- height: NumCast(this._props.document._height),
- opacity: brushed === Doc.DocBrushStatus.highlighted ? 0.5 : undefined,
- pointerEvents: this._props.pointerEvents?.() as any,
- outline: brushed === Doc.DocBrushStatus.unbrushed && this.linkHighlighted ? 'solid 1px lightBlue' : undefined,
- backgroundColor: brushed === Doc.DocBrushStatus.highlighted ? 'orange' : StrCast(this._props.document.backgroundColor),
- }}
- />
+ <div style={{ display: this._props.annoDoc.textCopied && !Doc.GetBrushHighlightStatus(this._props.annoDoc) ? 'none' : undefined }}>
+ {StrListCast(this._props.annoDoc.text_inlineAnnotations)
+ .map(a => a.split?.(':'))
+ .filter(fields => fields)
+ .map(([x, y, width, height]) => (
+ <div
+ key={'' + x + y + width + height}
+ style={{ pointerEvents: this._props.pointerEvents?.() as any }}
+ onPointerDown={this.onPointerDown}
+ onContextMenu={this.onContextMenu}
+ onPointerEnter={() => {
+ Doc.BrushDoc(this._props.annoDoc);
+ }}
+ onPointerLeave={() => {
+ Doc.UnBrushDoc(this._props.annoDoc);
+ }}>
+ <RegionAnnotation //
+ x={Number(x)}
+ y={Number(y)}
+ width={Number(width)}
+ height={Number(height)}
+ outline={this.outline}
+ background={this.background}
+ opacity={this.opacity}
+ />
+ </div>
+ ))}
+ </div>
);
}
}
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.scss b/src/client/views/pdf/GPTPopup/GPTPopup.scss
index 5d966395c..6d8793f82 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.scss
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.scss
@@ -11,8 +11,8 @@ $highlightedText: #82e0ff;
right: 10px;
width: 250px;
min-height: 200px;
- border-radius: 15px;
- padding: 15px;
+ border-radius: 16px;
+ padding: 16px;
padding-bottom: 0;
z-index: 999;
display: flex;
@@ -55,16 +55,29 @@ $highlightedText: #82e0ff;
overflow-y: auto;
}
- .btns-wrapper {
+ .btns-wrapper-gpt {
height: 50px;
display: flex;
- justify-content: space-between;
+ justify-content: center;
align-items: center;
+ transform: translateY(30px);
+
+
+ .searchBox-input{
+ transform: translateY(-15px);
+ height: 50px;
+ border-radius: 10px;
+ border-color: #5b97ff;
+ }
+
+
.summarizing {
display: flex;
align-items: center;
}
+
+
}
button {
@@ -111,6 +124,28 @@ $highlightedText: #82e0ff;
}
}
+.loading-spinner {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100px;
+ font-size: 20px;
+ font-weight: bold;
+ color: #666;
+}
+
+
+
+
+
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+
+
.image-content-wrapper {
display: flex;
flex-direction: column;
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index 0b741c85e..cb5aad32d 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -1,3 +1,4 @@
+/* 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';
@@ -6,30 +7,36 @@ import * as React from 'react';
import { CgClose } from 'react-icons/cg';
import ReactLoading from 'react-loading';
import { TypeAnimation } from 'react-type-animation';
-import { Utils } from '../../../../Utils';
+import { ClientUtils } from '../../../../ClientUtils';
import { Doc } from '../../../../fields/Doc';
import { NumCast, StrCast } from '../../../../fields/Types';
import { Networking } from '../../../Network';
-import { gptImageCall } from '../../../apis/gpt/GPT';
-import { DocUtils, Docs } from '../../../documents/Documents';
+import { GPTCallType, gptAPICall, gptImageCall } from '../../../apis/gpt/GPT';
+import { Docs } from '../../../documents/Documents';
+import { DocUtils } from '../../../documents/DocUtils';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { AnchorMenu } from '../AnchorMenu';
import './GPTPopup.scss';
-import { ComparisonBox } from '../../nodes/ComparisonBox';
-import { DashColor, emptyFunction, lightOrDark, returnFalse } from '../../../../Utils';
+import { SettingsManager } from '../../../util/SettingsManager';
+import { SnappingManager } from '../../../util/SnappingManager';
export enum GPTPopupMode {
SUMMARY,
EDIT,
IMAGE,
FLASHCARD,
+ DATA,
+ SORT,
}
interface GPTPopupProps {}
@observer
export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
+ // eslint-disable-next-line no-use-before-define
static Instance: GPTPopup;
+ @observable private chatMode: boolean = false;
+ private correlatedColumns: string[] = [];
@observable
public visible: boolean = false;
@@ -49,6 +56,20 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
public setText = (text: string) => {
this.text = text;
};
+ @observable
+ public selectedText: string = '';
+ @action
+ public setSelectedText = (text: string) => {
+ this.selectedText = text;
+ };
+ @observable
+ public dataJson: string = '';
+ public dataChatPrompt: string | null = null;
+ @action
+ public setDataJson = (text: string) => {
+ if (text === '') this.dataChatPrompt = '';
+ this.dataJson = text;
+ };
@observable
public imgDesc: string = '';
@@ -74,14 +95,21 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
@observable
public highlightRange: number[] = [];
@action callSummaryApi = () => {};
- @action callEditApi = () => {};
- @action replaceText = (replacement: string) => {};
@observable
private done: boolean = false;
@action
public setDone = (done: boolean) => {
this.done = done;
+ this.chatMode = false;
+ };
+
+ @observable
+ private sortDone: boolean = false; // this is so redundant but the og done variable was causing weird unknown problems and im just a girl
+
+ @action
+ public setSortDone = (done: boolean) => {
+ this.sortDone = done;
};
// change what can be a ref into a ref
@@ -106,31 +134,108 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
this.textAnchor = anchor;
};
+ @observable
+ public sortDesc: string = '';
+
+ @action public setSortDesc = (t: string) => {
+ this.sortDesc = t;
+ };
+
+ @observable onSortComplete?: (sortResult: string) => void;
+ @observable cardsDoneLoading = false;
+
+ @action setCardsDoneLoading(done: boolean) {
+ console.log(done + 'HI HIHI');
+ this.cardsDoneLoading = done;
+ }
+
public addDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean = () => false;
+ public createFilteredDoc: (axes?: any) => boolean = () => false;
public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined;
/**
+ * Sorts cards in the CollectionCardDeckView
+ */
+ generateSort = async () => {
+ this.setLoading(true);
+ this.setSortDone(false);
+
+ try {
+ const res = await gptAPICall(this.sortDesc, GPTCallType.SORT);
+ // Trigger the callback with the result
+ if (this.onSortComplete) {
+ this.onSortComplete(res || 'Something went wrong :(');
+ console.log(res);
+ }
+ } catch (err) {
+ console.error(err);
+ }
+
+ this.setLoading(false);
+ this.setSortDone(true);
+ };
+
+ /**
* Generates a Dalle image and uploads it to the server.
*/
generateImage = async () => {
- if (this.imgDesc === '') return;
+ if (this.imgDesc === '') return undefined;
this.setImgUrls([]);
this.setMode(GPTPopupMode.IMAGE);
this.setVisible(true);
this.setLoading(true);
try {
- let image_urls = await gptImageCall(this.imgDesc);
- if (image_urls && image_urls[0]) {
- const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [image_urls[0]] });
- const source = Utils.prepend(result.accessPaths.agnostic.client);
- this.setImgUrls([[image_urls[0], source]]);
+ const imageUrls = await gptImageCall(this.imgDesc);
+ if (imageUrls && imageUrls[0]) {
+ const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [imageUrls[0]] });
+ const source = ClientUtils.prepend(result.accessPaths.agnostic.client);
+ this.setImgUrls([[imageUrls[0], source]]);
}
} catch (err) {
- console.log(err);
- return '';
+ console.error(err);
}
this.setLoading(false);
+ return undefined;
+ };
+
+ /**
+ * Completes an API call to generate a summary of
+ * this.selectedText in the popup.
+ */
+ generateSummary = async () => {
+ GPTPopup.Instance.setVisible(true);
+ GPTPopup.Instance.setMode(GPTPopupMode.SUMMARY);
+ GPTPopup.Instance.setLoading(true);
+
+ try {
+ const res = await gptAPICall(this.selectedText, GPTCallType.SUMMARY);
+ GPTPopup.Instance.setText(res || 'Something went wrong.');
+ } catch (err) {
+ console.error(err);
+ }
+ GPTPopup.Instance.setLoading(false);
+ };
+
+ /**
+ * Completes an API call to generate an analysis of
+ * this.dataJson in the popup.
+ */
+ generateDataAnalysis = async () => {
+ GPTPopup.Instance.setVisible(true);
+ GPTPopup.Instance.setLoading(true);
+ try {
+ const res = await gptAPICall(this.dataJson, GPTCallType.DATA, this.dataChatPrompt);
+ const json = JSON.parse(res! as string);
+ const keys = Object.keys(json);
+ this.correlatedColumns = [];
+ this.correlatedColumns.push(json[keys[0]]);
+ this.correlatedColumns.push(json[keys[1]]);
+ GPTPopup.Instance.setText(json[keys[2]] || 'Something went wrong.');
+ } catch (err) {
+ console.error(err);
+ }
+ GPTPopup.Instance.setLoading(false);
};
/**
@@ -144,6 +249,7 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
_layout_autoHeight: true,
});
this.addDoc(newDoc, this.sidebarId);
+ // newDoc.data = 'Hello world';
const anchor = AnchorMenu.Instance?.GetAnchor(undefined, false);
if (anchor) {
DocUtils.MakeLink(newDoc, anchor, {
@@ -153,6 +259,13 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
};
/**
+ * Creates a histogram to show the correlation relationship that was found
+ */
+ private createVisualization = () => {
+ this.createFilteredDoc(this.correlatedColumns);
+ };
+
+ /**
* Transfers the image urls to actual image docs
*/
private transferToImage = (source: string) => {
@@ -177,6 +290,16 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
DocUtils.MakeLink(textAnchor, newDoc, { link_relationship: 'Image Prompt' });
};
+ /**
+ * Creates a chatbox for analyzing data so that users can ask specific questions.
+ */
+ private chatWithAI = () => {
+ this.chatMode = true;
+ };
+ dataPromptChanged = action((e: React.ChangeEvent<HTMLInputElement>) => {
+ this.dataChatPrompt = e.target.value;
+ });
+
private getPreviewUrl = (source: string) => source.split('.').join('_m.');
constructor(props: GPTPopupProps) {
@@ -191,55 +314,77 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
}
};
- imageBox = () => {
- return (
- <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
- {this.heading('GENERATED IMAGE')}
- <div className="image-content-wrapper">
- {this.imgUrls.map(rawSrc => (
- <div className="img-wrapper">
- <div className="img-container">
- <img key={rawSrc[0]} src={rawSrc[0]} width={150} height={150} alt="dalle generation" />
- </div>
- <div className="btn-container">
- <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={StrCast(Doc.UserDoc().userColor)} type={Type.TERT} />
- </div>
+ sortBox = () => (
+ <>
+ <div>
+ {this.heading('SORTING')}
+ {this.loading ? (
+ <div className="content-wrapper">
+ <div className="loading-spinner">
+ <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
+ <span>Loading...</span>
</div>
- ))}
- </div>
- {!this.loading && (
+ </div>
+ ) : (
<>
- <IconButton tooltip="Generate Again" onClick={this.generateImage} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />
- </>
- )}
- </div>
- );
- };
-
- data = () => {
- return (
- <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
- {this.heading('GENERATED IMAGE')}
- <div className="image-content-wrapper">
- {this.imgUrls.map(rawSrc => (
- <div className="img-wrapper">
- <div className="img-container">
- <img key={rawSrc[0]} src={rawSrc[0]} width={150} height={150} alt="dalle generation" />
+ {!this.cardsDoneLoading ? (
+ <div className="content-wrapper">
+ <div className="loading-spinner">
+ <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
+ <span>Reading Cards...</span>
+ </div>
</div>
- <div className="btn-container">
- <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={StrCast(Doc.UserDoc().userColor)} type={Type.TERT} />
+ ) : (
+ !this.sortDone && (
+ <div className="btns-wrapper-gpt">
+ <Button
+ tooltip="Have ChatGPT sort your cards for you!"
+ text="Sort!"
+ onClick={this.generateSort}
+ color={StrCast(Doc.UserDoc().userVariantColor)}
+ type={Type.TERT}
+ style={{
+ width: '90%', // Almost as wide as the container
+ textAlign: 'center',
+ color: '#ffffff', // White text
+ fontSize: '16px', // Adjust font size as needed
+ }}
+ />
+ </div>
+ )
+ )}
+
+ {this.sortDone && (
+ <div>
+ <div className="content-wrapper">
+ <p>{this.text === 'Something went wrong :(' ? 'Something went wrong :(' : 'Sorting done! Feel free to move things around / regenerate :) !'}</p>
+ <IconButton tooltip="Generate Again" onClick={() => this.setSortDone(false)} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />
+ </div>
</div>
- </div>
- ))}
- </div>
- {!this.loading && (
- <>
- <IconButton tooltip="Generate Again" onClick={this.generateImage} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />
+ )}
</>
)}
</div>
- );
- };
+ </>
+ );
+ imageBox = () => (
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
+ {this.heading('GENERATED IMAGE')}
+ <div className="image-content-wrapper">
+ {this.imgUrls.map(rawSrc => (
+ <div className="img-wrapper">
+ <div className="img-container">
+ <img key={rawSrc[0]} src={rawSrc[0]} width={150} height={150} alt="dalle generation" />
+ </div>
+ <div className="btn-container">
+ <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={StrCast(Doc.UserDoc().userColor)} type={Type.TERT} />
+ </div>
+ </div>
+ ))}
+ </div>
+ {!this.loading && <IconButton tooltip="Generate Again" onClick={this.generateImage} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />}
+ </div>
+ );
summaryBox = () => (
<>
@@ -258,7 +403,6 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
}, 500);
},
]}
- //cursor={{ hideWhenDone: true }}
/>
) : (
this.text
@@ -269,9 +413,8 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
<div className="btns-wrapper">
{this.done ? (
<>
- <IconButton tooltip="Generate Again" onClick={this.callSummaryApi} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />
- <Button tooltip="Transfer to text" text="Transfer To Text" onClick={this.transferToText} color={StrCast(Doc.UserDoc().userVariantColor)} type={Type.TERT} />
- {/* <Button tooltip="Transfer to flashcard" text="flashcard" onClick={this.transferToFlashcard} color={StrCast(Doc.UserDoc().userVariantColor)} type={Type.TERT} /> */}
+ <IconButton tooltip="Generate Again" onClick={this.generateSummary /* this.callSummaryApi */} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(SettingsManager.userVariantColor)} />
+ <Button tooltip="Transfer to text" text="Transfer To Text" onClick={this.transferToText} color={StrCast(SettingsManager.userVariantColor)} type={Type.TERT} />
</>
) : (
<div className="summarizing">
@@ -282,7 +425,73 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
onClick={() => {
this.setDone(true);
}}
- color={StrCast(Doc.UserDoc().userVariantColor)}
+ color={StrCast(SettingsManager.userVariantColor)}
+ type={Type.TERT}
+ />
+ </div>
+ )}
+ </div>
+ )}
+ </>
+ );
+
+ dataAnalysisBox = () => (
+ <>
+ <div>
+ {this.heading('ANALYSIS')}
+ <div className="content-wrapper">
+ {!this.loading &&
+ (!this.done ? (
+ <TypeAnimation
+ speed={50}
+ sequence={[
+ this.text,
+ () => {
+ setTimeout(() => {
+ this.setDone(true);
+ }, 500);
+ },
+ ]}
+ />
+ ) : (
+ this.text
+ ))}
+ </div>
+ </div>
+ {!this.loading && (
+ <div className="btns-wrapper">
+ {this.done ? (
+ this.chatMode ? (
+ <input
+ defaultValue=""
+ autoComplete="off"
+ onChange={this.dataPromptChanged}
+ onKeyDown={e => {
+ e.key === 'Enter' ? this.generateDataAnalysis() : null;
+ e.stopPropagation();
+ }}
+ type="text"
+ placeholder="Ask GPT a question about the data..."
+ id="search-input"
+ className="searchBox-input"
+ style={{ width: '100%' }}
+ />
+ ) : (
+ <>
+ <Button tooltip="Transfer to text" text="Transfer To Text" onClick={this.transferToText} color={StrCast(SnappingManager.userVariantColor)} type={Type.TERT} />
+ <Button tooltip="Chat with AI" text="Chat with AI" onClick={this.chatWithAI} color={StrCast(SnappingManager.userVariantColor)} type={Type.TERT} />
+ </>
+ )
+ ) : (
+ <div className="summarizing">
+ <span>Summarizing</span>
+ <ReactLoading type="bubbles" color="#bcbcbc" width={20} height={20} />
+ <Button
+ text="Stop Animation"
+ onClick={() => {
+ this.setDone(true);
+ }}
+ color={StrCast(SnappingManager.userVariantColor)}
type={Type.TERT}
/>
</div>
@@ -298,21 +507,19 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
<FontAwesomeIcon icon="exclamation-circle" size="sm" style={{ paddingRight: '5px' }} />
AI generated responses can contain inaccurate or misleading content.
</div>
- ) : (
- <></>
- );
+ ) : null;
heading = (headingText: string) => (
<div className="summary-heading">
<label className="summary-text">{headingText}</label>
- {this.loading ? <ReactLoading type="spin" color="#bcbcbc" width={14} height={14} /> : <IconButton color={StrCast(Doc.UserDoc().userVariantColor)} tooltip="close" icon={<CgClose size="16px" />} onClick={() => this.setVisible(false)} />}
+ {this.loading ? <ReactLoading type="spin" color="#bcbcbc" width={14} height={14} /> : <IconButton color={StrCast(SettingsManager.userVariantColor)} tooltip="close" icon={<CgClose size="16px" />} onClick={() => this.setVisible(false)} />}
</div>
);
render() {
return (
<div className="summary-box" style={{ display: this.visible ? 'flex' : 'none' }}>
- {this.mode === GPTPopupMode.SUMMARY ? this.summaryBox() : this.mode === GPTPopupMode.IMAGE ? this.imageBox() : this.mode == GPTPopupMode.FLASHCARD ? this.summaryBox() : <></>}
+ {this.mode === GPTPopupMode.SUMMARY ? this.summaryBox() : this.mode === GPTPopupMode.DATA ? this.dataAnalysisBox() : this.mode === GPTPopupMode.IMAGE ? this.imageBox() : this.mode === GPTPopupMode.SORT ? this.sortBox() : null}
</div>
);
}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index fe1ed8159..6c1617c38 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -1,38 +1,41 @@
+/* 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';
import 'pdfjs-dist/web/pdf_viewer.css';
import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs';
import * as React from 'react';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Height } from '../../../fields/DocSymbols';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils';
+import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { DocData, Height } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, returnAll, returnFalse, returnNone, returnZero, smoothScroll, Utils } from '../../../Utils';
-import { DocUtils } from '../../documents/Documents';
-import { SelectionManager } from '../../util/SelectionManager';
+import { emptyFunction } from '../../../Utils';
+import { DocUtils } from '../../documents/DocUtils';
import { SnappingManager } from '../../util/SnappingManager';
import { MarqueeOptionsMenu } from '../collections/collectionFreeForm';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
+import { DocumentView } from '../nodes/DocumentView';
+import { FieldViewProps } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
import { LinkInfo } from '../nodes/LinkDocPreview';
import { PDFBox } from '../nodes/PDFBox';
import { ComparisonBox } from '../nodes/ComparisonBox';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { StyleProp } from '../StyleProvider';
+import { StyleProp } from '../StyleProp';
import { AnchorMenu } from './AnchorMenu';
import { Annotation } from './Annotation';
import { GPTPopup } from './GPTPopup/GPTPopup';
import { Docs } from '../../documents/Documents';
import './PDFViewer.scss';
-const _global = (window /* browser */ || global) /* node */ as any;
-//pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`;
+// pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`;
// The workerSrc property shall be specified.
-Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.0.379/build/pdf.worker.mjs';
+Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.2.67/build/pdf.worker.mjs';
interface IViewerProps extends FieldViewProps {
pdfBox: PDFBox;
@@ -44,6 +47,7 @@ interface IViewerProps extends FieldViewProps {
url: string;
sidebarAddDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean;
loaded?: (nw: number, nh: number, np: number) => void;
+ // eslint-disable-next-line no-use-before-define
setPdfViewer: (view: PDFViewer) => void;
anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
crop: (region: Doc | undefined, addCrop?: boolean) => Doc | undefined;
@@ -100,14 +104,18 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
}
componentDidMount() {
- runInAction(() => (this._showWaiting = true));
+ runInAction(() => {
+ this._showWaiting = true;
+ });
this.setupPdfJsViewer();
- this._mainCont.current?.addEventListener('scroll', e => ((e.target as any).scrollLeft = 0));
+ this._mainCont.current?.addEventListener('scroll', e => {
+ (e.target as any).scrollLeft = 0;
+ });
this._disposers.layout_autoHeight = reaction(
() => this._props.layoutDoc._layout_autoHeight,
- layout_autoHeight => {
- if (layout_autoHeight) {
+ layoutAutoHeight => {
+ if (layoutAutoHeight) {
this._props.layoutDoc._nativeHeight = NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']);
this._props.setHeight?.(NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1));
}
@@ -116,7 +124,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
this._disposers.selected = reaction(
() => this._props.isSelected(),
- selected => SelectionManager.Views.length === 1 && this.setupPdfJsViewer(),
+ () => DocumentView.Selected().length === 1 && this.setupPdfJsViewer(),
{ fireImmediately: true }
);
this._disposers.curPage = reaction(
@@ -137,7 +145,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
const anchor = this._getAnchor(undefined, false);
if (anchor) {
anchor.textCopied = true;
- e.clipboardData.setData('dash/pdfAnchor', anchor[Id]);
+ e.clipboardData.setData('dash/pdfAnchor', anchor[DocData][Id]);
}
e.preventDefault();
}
@@ -166,7 +174,9 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
)
);
}
- runInAction(() => (this._scrollHeight = (this._pageSizes.reduce((size, page) => size + page.height, 0) * 96) / 72));
+ runInAction(() => {
+ this._scrollHeight = (this._pageSizes.reduce((size, page) => size + page.height, 0) * 96) / 72;
+ });
};
_scrollStopper: undefined | (() => void);
@@ -178,7 +188,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
let focusSpeed: Opt<number>;
if (doc !== this._props.Document && mainCont) {
const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(scrollTop, doc[Height](), NumCast(this._props.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, this._scrollHeight);
+ const scrollTo = ClientUtils.scrollIntoView(scrollTop, doc[Height](), NumCast(this._props.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, this._scrollHeight);
if (scrollTo !== undefined && scrollTo !== this._props.layoutDoc._layout_scrollTop) {
if (!this._pdfViewer) this._initialScroll = { loc: scrollTo, easeFunc: options.easeFunc };
else if (!options.instant) this._scrollStopper = smoothScroll((focusSpeed = options.zoomTime ?? 500), mainCont, scrollTo, options.easeFunc, this._scrollStopper);
@@ -204,14 +214,18 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
pagesinit = () => {
if (this._pdfViewer._setDocumentViewerElement?.offsetParent) {
- runInAction(() => (this._pdfViewer.currentScaleValue = this._props.layoutDoc._freeform_scale = 1));
+ runInAction(() => {
+ this._pdfViewer.currentScaleValue = this._props.layoutDoc._freeform_scale = 1;
+ });
this.gotoPage(NumCast(this._props.Document._layout_curPage, 1));
}
document.removeEventListener('pagesinit', this.pagesinit);
- var quickScroll: { loc?: string; easeFunc?: 'ease' | 'linear' } | undefined = { loc: this._initialScroll ? this._initialScroll.loc?.toString() : '', easeFunc: this._initialScroll ? this._initialScroll.easeFunc : undefined };
+ 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),
+ scale => {
+ this._pdfViewer.currentScaleValue = scale;
+ },
{ fireImmediately: true }
);
this._disposers.scroll = reaction(
@@ -228,7 +242,9 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
setTimeout(
() => {
this._mainCont.current && (this._scrollStopper = smoothScroll(duration, this._mainCont.current, pos, this._initialScroll?.easeFunc ?? 'ease', this._scrollStopper));
- setTimeout(() => (this._forcedScroll = false), duration);
+ setTimeout(() => {
+ this._forcedScroll = false;
+ }, duration);
},
this._mainCont.current ? 0 : 250
); // wait for mainCont and try again to scroll
@@ -264,7 +280,9 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
eventBus._on('pagesinit', this.pagesinit);
eventBus._on(
'pagerendered',
- action(() => (this._showWaiting = false))
+ action(() => {
+ this._showWaiting = false;
+ })
);
const pdfLinkService = new PDFJSViewer.PDFLinkService({ eventBus });
const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService, eventBus });
@@ -307,7 +325,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
@observable private _scrollTimer: any = undefined;
- onScroll = (e: React.UIEvent<HTMLElement>) => {
+ onScroll = () => {
if (this._mainCont.current && !this._forcedScroll) {
this._ignoreScroll = true; // the pdf scrolled, so we need to tell the Doc to scroll but we don't want the doc to then try to set the PDF scroll pos (which would interfere with the smooth scroll animation)
if (!LinkInfo.Instance?.LinkInfo) {
@@ -316,7 +334,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
this._ignoreScroll = false;
if (this._scrollTimer) clearTimeout(this._scrollTimer); // wait until a scrolling pause, then create an anchor to audio
this._scrollTimer = setTimeout(() => {
- DocUtils.MakeLinkToActiveAudio(() => this._props.pdfBox.getAnchor(true)!, false);
+ CreateLinkToActiveAudio(() => this._props.pdfBox.getAnchor(true)!, false);
this._scrollTimer = undefined;
}, 200);
}
@@ -342,7 +360,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
query: searchString,
};
if (clear) {
- this._pdfViewer?.eventBus.dispatch('reset', {});
+ this._pdfViewer?.eventBus.dispatch('findbarclose', {});
} else if (!searchString) {
bwd ? this.prevAnnotation() : this.nextAnnotation();
} else if (this._pdfViewer?.pageViewsReady) {
@@ -373,7 +391,6 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
if (!e.altKey && e.button === 0 && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
this._props.select(false);
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
- this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]);
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'))) {
@@ -385,11 +402,12 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
this._styleRule = addStyleSheetRule(PDFViewer._annotationStyle, 'htmlAnnotation', { 'pointer-events': 'none' });
document.addEventListener('pointerup', this.onSelectEnd);
}
+ this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]);
}
};
@action
- finishMarquee = (x?: number, y?: number) => {
+ finishMarquee = (/* x?: number, y?: number */) => {
this._getAnchor = AnchorMenu.Instance?.GetAnchor;
this.isAnnotating = false;
this._marqueeref.current?.onTerminateSelection();
@@ -459,13 +477,15 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
onClick = (e: React.MouseEvent) => {
this._scrollStopper?.();
- if (this._setPreviewCursor && e.button === 0 && Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) {
+ if (this._setPreviewCursor && e.button === 0 && Math.abs(e.clientX - this._downX) < ClientUtils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < ClientUtils.DRAG_THRESHOLD) {
this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Document);
}
// e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks
};
- setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => (this._setPreviewCursor = func);
+ setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => {
+ this._setPreviewCursor = func;
+ };
@action
onZoomWheel = (e: React.WheelEvent) => {
@@ -488,7 +508,8 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
return (
<div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this._props.Document), transform: `scale(${NumCast(this._props.layoutDoc._freeform_scale, 1)})` }} ref={this._annotationLayer}>
{inlineAnnos.map(anno => (
- <Annotation {...this._props} fieldKey={this._props.fieldKey + '_annotations'} pointerEvents={this.pointerEvents} dataDoc={this._props.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ <Annotation {...this._props} fieldKey={this._props.fieldKey + '_annotations'} pointerEvents={this.pointerEvents} containerDataDoc={this._props.dataDoc} annoDoc={anno} key={`${anno[Id]}-annotation`} />
))}
</div>
);
@@ -499,8 +520,8 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
overlayTransform = () => this.scrollXf().scale(1 / NumCast(this._props.layoutDoc._freeform_scale, 1));
panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1);
panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
- transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter];
- opaqueFilter = () => [...this._props.childFilters(), Utils.noDragDocsFilter, ...(SnappingManager.CanEmbed && this._props.isContentActive() ? [] : [Utils.OpaqueBackgroundFilter])];
+ 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<FieldViewProps>, property: string): any => {
if (doc instanceof Doc && property === StyleProp.PointerEvents) {
if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none';
@@ -520,6 +541,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
pointerEvents: Doc.ActiveTool !== InkTool.None ? 'all' : undefined,
}}>
<CollectionFreeFormView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
NativeWidth={returnZero}
NativeHeight={returnZero}
@@ -527,7 +549,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
pointerEvents={this._props.isContentActive() && (SnappingManager.IsDragging || Doc.ActiveTool !== InkTool.None) ? returnAll : returnNone} // freeform view doesn't get events unless something is being dragged onto it.
childPointerEvents={this.childPointerEvents} // but freeform children need to get events to allow text editing, etc
renderDepth={this._props.renderDepth + 1}
- isAnnotationOverlay={true}
+ isAnnotationOverlay
fieldKey={this._props.fieldKey + '_annotations'}
getScrollHeight={this.getScrollHeight}
setPreviewCursor={this.setPreviewCursor}
@@ -535,7 +557,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
PanelWidth={this.panelWidth}
ScreenToLocalTransform={this.overlayTransform}
isAnyChildContentActive={returnFalse}
- isAnnotationOverlayScrollable={true}
+ isAnnotationOverlayScrollable
childFilters={childFilters}
select={emptyFunction}
styleProvider={this.childStyleProvider}
@@ -580,7 +602,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
{this.pdfViewerDiv}
{this.annotationLayer}
{this.overlayLayer}
- {this._showWaiting ? <img className="pdfViewerDash-waiting" src={'/assets/loading.gif'} /> : null}
+ {this._showWaiting ? <img alt="" className="pdfViewerDash-waiting" src="/assets/loading.gif" /> : null}
{!this._mainCont.current || !this._annotationLayer.current ? null : (
<MarqueeAnnotator
ref={this._marqueeref}
@@ -588,7 +610,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
getPageFromScroll={this.getPageFromScroll}
anchorMenuClick={this._props.anchorMenuClick}
scrollTop={0}
- isNativeScaled={true}
+ isNativeScaled
annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)}
addDocument={this.addDocumentWrapper}
docView={this._props.pdfBox.DocumentView!}
@@ -597,7 +619,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
selectionText={this.selectionText}
annotationLayer={this._annotationLayer.current}
marqueeContainer={this._mainCont.current}
- anchorMenuCrop={this._textSelecting ? undefined : this.crop}
+ anchorMenuCrop={this.crop}
/>
)}
</div>
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 9f153e86d..ae0838dd5 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -1,22 +1,26 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { Tooltip } from '@mui/material';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCastAsync, Field } from '../../../fields/Doc';
+import { ClientUtils } from '../../../ClientUtils';
+import { Doc, DocListCastAsync, Field, FieldType } from '../../../fields/Doc';
import { DirectLinks, DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { DocCast, StrCast } from '../../../fields/Types';
+import { DocUtils } from '../../documents/DocUtils';
import { DocumentType } from '../../documents/DocumentTypes';
-import { DocUtils } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
-import { LinkManager } from '../../util/LinkManager';
+import { Docs } from '../../documents/Documents';
import { SearchUtil } from '../../util/SearchUtil';
-import { SettingsManager } from '../../util/SettingsManager';
+import { SnappingManager } from '../../util/SnappingManager';
import { undoBatch } from '../../util/UndoManager';
import { ViewBoxBaseComponent } from '../DocComponent';
+import { ObservableReactComponent } from '../ObservableReactComponent';
import { CollectionDockingView } from '../collections/CollectionDockingView';
-import { IRecommendation, Recommendation } from '../newlightbox/components';
-import { fetchRecommendations } from '../newlightbox/utils';
+// import { IRecommendation, Recommendation } from '../newlightbox/components';
+// import { fetchRecommendations } from '../newlightbox/utils';
+import { DocumentView } from '../nodes/DocumentView';
import { FieldView, FieldViewProps } from '../nodes/FieldView';
import './SearchBox.scss';
@@ -24,6 +28,96 @@ const DAMPENING_FACTOR = 0.9;
const MAX_ITERATIONS = 25;
const ERROR = 0.03;
+export interface SearchBoxItemProps {
+ Document: Doc;
+ searchString: string;
+ isLinkSearch: boolean;
+ matchedKeys: string[];
+ className: string;
+ linkFrom: Doc | undefined;
+ selectItem: (doc: Doc) => void;
+ linkCreateAnchor?: () => Doc | undefined;
+ linkCreated?: (link: Doc) => void;
+}
+@observer
+export class SearchBoxItem extends ObservableReactComponent<SearchBoxItemProps> {
+ constructor(props: SearchBoxItemProps) {
+ super(props);
+ makeObservable(this);
+ }
+
+ /**
+ * @param {Doc} doc - doc to be selected
+ *
+ * This method selects a doc by either jumping to it (centering/zooming in on it)
+ * or opening it in a new tab.
+ */
+ selectElement = async (doc: Doc, finishFunc: () => void) => {
+ await DocumentView.showDocument(doc, { willZoomCentered: true }, finishFunc);
+ };
+
+ /**
+ * @param {Doc} doc - doc of the search result that has been clicked on
+ *
+ * This method is called when the user clicks on a search result. The _selectedResult is
+ * updated accordingly and the doc is highlighted with the selectElement method.
+ */
+ onResultClick = action(async (doc: Doc) => {
+ this._props.selectItem(doc);
+ this.selectElement(doc, () => DocumentView.getFirstDocumentView(doc)?.ComponentView?.search?.(this._props.searchString, undefined, false));
+ });
+
+ componentWillUnmount(): void {
+ const doc = this._props.Document;
+ DocumentView.getFirstDocumentView(doc)?.ComponentView?.search?.('', undefined, true);
+ }
+
+ @undoBatch
+ makeLink = action((linkTo: Doc) => {
+ const linkFrom = this._props.linkCreateAnchor?.();
+ if (linkFrom) {
+ const link = DocUtils.MakeLink(linkFrom, linkTo, {});
+ link && this._props.linkCreated?.(link);
+ }
+ });
+
+ render() {
+ // eslint-disable-next-line no-use-before-define
+ const formattedType = SearchBox.formatType(StrCast(this._props.Document.type), StrCast(this._props.Document.type_collection));
+ const { title } = this._props.Document;
+
+ return (
+ <Tooltip placement="right" title={<div className="dash-tooltip">{title as string}</div>}>
+ <div
+ onClick={
+ this._props.isLinkSearch
+ ? () => this.makeLink(this._props.Document)
+ : e => {
+ this.onResultClick(this._props.Document);
+ e.stopPropagation();
+ }
+ }
+ style={{
+ fontWeight: Doc.Links(this._props.linkFrom).find(
+ link => Doc.AreProtosEqual(Doc.getOppositeAnchor(link, this._props.linkFrom!), this._props.Document) || Doc.AreProtosEqual(DocCast(Doc.getOppositeAnchor(link, this._props.linkFrom!)?.annotationOn), this._props.Document)
+ )
+ ? 'bold'
+ : '',
+ }}
+ className={this._props.className}>
+ <div className="searchBox-result-title">{title as string}</div>
+ <div className="searchBox-result-type" style={{ color: SnappingManager.userVariantColor }}>
+ {formattedType}
+ </div>
+ <div className="searchBox-result-keys" style={{ color: SnappingManager.userVariantColor }}>
+ {this._props.matchedKeys.join(', ')}
+ </div>
+ </div>
+ </Tooltip>
+ );
+ }
+}
+
export interface SearchBoxProps extends FieldViewProps {
linkSearch: boolean;
linkFrom?: (() => Doc | undefined) | undefined;
@@ -40,6 +134,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(SearchBox, fieldKey);
}
+ // eslint-disable-next-line no-use-before-define
public static Instance: SearchBox;
private _inputRef = React.createRef<HTMLInputElement>();
@@ -47,7 +142,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
@observable _searchString = '';
@observable _docTypeString = 'all';
@observable _results: Map<Doc, string[]> = new Map<Doc, string[]>();
- @observable _recommendations: IRecommendation[] = [];
+ // @observable _recommendations: IRecommendation[] = [];
@observable _pageRanks: Map<Doc, number> = new Map<Doc, number>();
@observable _linkedDocsOut: Map<Doc, Set<Doc>> = new Map<Doc, Set<Doc>>();
@observable _linkedDocsIn: Map<Doc, Set<Doc>> = new Map<Doc, Set<Doc>>();
@@ -109,46 +204,29 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
});
/**
- * @param {Doc} doc - doc of the search result that has been clicked on
- *
- * This method is called when the user clicks on a search result. The _selectedResult is
- * updated accordingly and the doc is highlighted with the selectElement method.
- */
- onResultClick = action(async (doc: Doc) => {
- this._selectedResult = doc;
- this.selectElement(doc, () => DocumentManager.Instance.getFirstDocumentView(doc)?.ComponentView?.search?.(this._searchString, undefined, false));
- });
-
- @undoBatch
- makeLink = action((linkTo: Doc) => {
- const linkFrom = this._props.linkCreateAnchor?.();
- if (linkFrom) {
- const link = DocUtils.MakeLink(linkFrom, linkTo, {});
- link && this._props.linkCreated?.(link);
- }
- });
-
- /**
* @param {Doc[]} docs - docs to be searched through recursively
* @param {number, Doc => void} func - function to be called on each doc
*
* This method iterates asynchronously through an array of docs and all docs within those
* docs, calling the function func on each doc.
*/
- static async foreachRecursiveDocAsync(docs: Doc[], func: (depth: number, doc: Doc) => void) {
+ static async foreachRecursiveDocAsync(docsIn: Doc[], func: (depth: number, doc: Doc) => void) {
+ let docs = docsIn;
let newarray: Doc[] = [];
- var depth = 0;
+ let depth = 0;
while (docs.length > 0) {
newarray = [];
+ // eslint-disable-next-line no-await-in-loop
await Promise.all(
docs
.filter(d => d)
+ // eslint-disable-next-line no-loop-func
.map(async d => {
const fieldKey = Doc.LayoutFieldKey(d);
- const annos = !Field.toString(Doc.LayoutField(d) as Field).includes('CollectionView');
+ const annos = !Field.toString(Doc.LayoutField(d) as FieldType).includes('CollectionView');
const data = d[annos ? fieldKey + '_annotations' : fieldKey];
- const docs = await DocListCastAsync(data);
- docs && newarray.push(...docs);
+ const dataDocs = await DocListCastAsync(data);
+ dataDocs && newarray.push(...dataDocs);
func(depth, d);
})
);
@@ -170,6 +248,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
case DocumentType.IMG : return 'Img';
case DocumentType.RTF : return 'Rtf';
case DocumentType.COL : return 'Col:'+colType.substring(0,3);
+ default:
} // prettier-ignore
return type.charAt(0).toUpperCase() + type.substring(1, 3);
@@ -210,7 +289,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
if (doc[DocData][DirectLinks].size === 0) {
this._linkedDocsOut.set(doc, new Set(this._results.keys()));
- this._results.forEach((_, linkedDoc) => {
+ this._results.forEach((__, linkedDoc) => {
this._linkedDocsIn.get(linkedDoc)?.add(doc);
});
} else {
@@ -244,7 +323,6 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
pageRankIteration(): boolean {
let converged = true;
const pageRankFromAll = (1 - DAMPENING_FACTOR) / this._results.size;
-
const nextPageRanks = new Map<Doc, number>();
this._results.forEach((_, doc) => {
@@ -292,42 +370,34 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
const query = StrCast(this._searchString);
Doc.SetSearchQuery(query);
- if (!this._props.linkSearch) Array.from(this._results.keys()).forEach(doc => DocumentManager.Instance.getFirstDocumentView(doc)?.ComponentView?.search?.(this._searchString, undefined, true));
+ if (!this._props.linkSearch) Array.from(this._results.keys()).forEach(doc => DocumentView.getFirstDocumentView(doc)?.ComponentView?.search?.(this._searchString, undefined, true));
this._results.clear();
if (query) {
this.searchCollection(query);
- const response = await fetchRecommendations('', query, [], true);
- const recs = response.recommendations;
- const recommendations: IRecommendation[] = [];
- for (const key in recs) {
- const title = recs[key].title;
- const url = recs[key].url;
- const type = recs[key].type;
- const text = recs[key].text;
- const transcript = recs[key].transcript;
- const previewUrl = recs[key].previewUrl;
- const embedding = recs[key].embedding;
- const distance = recs[key].distance;
- const source = recs[key].source;
- const related_concepts = recs[key].related_concepts;
- const docId = recs[key].doc_id;
- recommendations.push({
- title: title,
- data: url,
- type: type,
- text: text,
- transcript: transcript,
- previewUrl: previewUrl,
- embedding: embedding,
- distance: Math.round(distance * 100) / 100,
- source: source,
- related_concepts: related_concepts,
- docId: docId,
- });
- }
- const setRecommendations = action(() => (this._recommendations = recommendations));
- setRecommendations();
+ // const response = await fetchRecommendations('', query, [], true);
+ // const recs = response.recommendations as any[];
+ // const recommendations: IRecommendation[] = [];
+ // recs.forEach(rec => {
+ // const { title, url, type, text, transcript, previewUrl, embedding, distance, source, related_concepts: relatedConcepts, doc_id: docId } = rec;
+ // recommendations.push({
+ // title,
+ // data: url,
+ // type,
+ // text,
+ // transcript,
+ // previewUrl,
+ // embedding,
+ // distance: Math.round(distance * 100) / 100,
+ // source: source,
+ // related_concepts: relatedConcepts,
+ // docId,
+ // });
+ // });
+ // const setRecommendations = action(() => {
+ // this._recommendations = recommendations;
+ // });
+ // setRecommendations();
}
};
@@ -339,7 +409,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
this._timeout && clearTimeout(this._timeout);
this._timeout = undefined;
this._results.forEach((_, doc) => {
- DocumentManager.Instance.getFirstDocumentView(doc)?.ComponentView?.search?.('', undefined, true);
+ DocumentView.getFirstDocumentView(doc)?.ComponentView?.search?.('', undefined, true);
Doc.UnBrushDoc(doc);
Doc.UnHighlightDoc(doc);
Doc.ClearSearchMatches();
@@ -347,16 +417,6 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
});
/**
- * @param {Doc} doc - doc to be selected
- *
- * This method selects a doc by either jumping to it (centering/zooming in on it)
- * or opening it in a new tab.
- */
- selectElement = async (doc: Doc, finishFunc: () => void) => {
- await DocumentManager.Instance.showDocument(doc, { willZoomCentered: true }, finishFunc);
- };
-
- /**
* This method returns a JSX list of the options in the select drop-down menu, which
* is used to filter the types of documents that appear in the search results.
*/
@@ -366,7 +426,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
return selectValues.map(value => (
<option key={value} value={value}>
- {SearchBox.formatType(value, '')}
+ {ClientUtils.cleanDocumentTypeExt(value as DocumentType)}
</option>
));
}
@@ -375,64 +435,45 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
* This method renders the search input box, select drop-down menu, and search results.
*/
render() {
- var validResults = 0;
-
const isLinkSearch: boolean = this._props.linkSearch;
-
const sortedResults = Array.from(this._results.entries()).sort((a, b) => (this._pageRanks.get(b[0]) ?? 0) - (this._pageRanks.get(a[0]) ?? 0)); // sorted by page rank
+ const resultsJSX = [] as any[];
+ const linkFrom = this._props.linkFrom?.();
- const resultsJSX = Array();
-
- const fromDoc = this._props.linkFrom?.();
+ let validResults = 0;
+ sortedResults.forEach(([Document, matchedKeys]) => {
+ let className = 'searchBox-results-scroll-view-result';
- sortedResults.forEach(result => {
- var className = 'searchBox-results-scroll-view-result';
-
- if (this._selectedResult === result[0]) {
+ if (this._selectedResult === Document) {
className += ' searchBox-results-scroll-view-result-selected';
}
- const formattedType = SearchBox.formatType(StrCast(result[0].type), StrCast(result[0].type_collection));
- const title = result[0].title;
-
- if (this._docTypeString === 'keys' || this._docTypeString === 'all' || this._docTypeString === result[0].type) {
+ if (this._docTypeString === 'keys' || this._docTypeString === 'all' || this._docTypeString === Document.type) {
validResults++;
resultsJSX.push(
- <Tooltip key={result[0][Id]} placement={'right'} title={<div className="dash-tooltip">{title as string}</div>}>
- <div
- onClick={
- isLinkSearch
- ? () => this.makeLink(result[0])
- : e => {
- this.onResultClick(result[0]);
- e.stopPropagation();
- }
- }
- style={{
- fontWeight: LinkManager.Links(fromDoc).find(
- link => Doc.AreProtosEqual(LinkManager.getOppositeAnchor(link, fromDoc!), result[0] as Doc) || Doc.AreProtosEqual(DocCast(LinkManager.getOppositeAnchor(link, fromDoc!)?.annotationOn), result[0] as Doc)
- )
- ? 'bold'
- : '',
- }}
- className={className}>
- <div className="searchBox-result-title">{title as string}</div>
- <div className="searchBox-result-type" style={{ color: SettingsManager.userVariantColor }}>
- {formattedType}
- </div>
- <div className="searchBox-result-keys" style={{ color: SettingsManager.userVariantColor }}>
- {result[1].join(', ')}
- </div>
- </div>
- </Tooltip>
+ <SearchBoxItem
+ key={Document[Id]}
+ Document={Document}
+ selectItem={action((doc: Doc) => {
+ this._selectedResult = doc;
+ })}
+ isLinkSearch={isLinkSearch}
+ searchString={this._searchString}
+ matchedKeys={matchedKeys}
+ linkFrom={linkFrom}
+ className={className}
+ linkCreateAnchor={this._props.linkCreateAnchor}
+ linkCreated={this._props.linkCreated}
+ />
);
}
});
- const recommendationsJSX: JSX.Element[] = this._recommendations.map(props => <Recommendation {...props} />);
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ const recommendationsJSX: JSX.Element[] = []; // this._recommendations.map(props => <Recommendation {...props} />);
return (
- <div className="searchBox-container" style={{ pointerEvents: 'all', color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }}>
+ <div className="searchBox-container" style={{ pointerEvents: 'all', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}>
<div className="searchBox-bar">
{isLinkSearch ? null : (
<select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
@@ -457,18 +498,18 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
</div>
{resultsJSX.length > 0 && (
<div className="searchBox-results-container">
- <div className="section-header" style={{ background: SettingsManager.userVariantColor }}>
+ <div className="section-header" style={{ background: SnappingManager.userVariantColor }}>
<div className="section-title">Results</div>
- <div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
+ <div className="section-subtitle">{`${validResults} result` + (validResults === 1 ? '' : 's')}</div>
</div>
<div className="searchBox-results-view">{resultsJSX}</div>
</div>
)}
{recommendationsJSX.length > 0 && (
<div className="searchBox-recommendations-container">
- <div className="section-header" style={{ background: SettingsManager.userVariantColor }}>
+ <div className="section-header" style={{ background: SnappingManager.userVariantColor }}>
<div className="section-title">Recommendations</div>
- <div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
+ <div className="section-subtitle">{`${validResults} result` + (validResults === 1 ? '' : 's')}</div>
</div>
<div className="searchBox-recommendations-view">{recommendationsJSX}</div>
</div>
@@ -477,3 +518,8 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.SEARCH, {
+ layout: { view: SearchBox, dataField: 'data' },
+ options: { acl: '', _width: 400 },
+});
diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx
index c9c01189e..78a1a92f7 100644
--- a/src/client/views/selectedDoc/SelectedDocView.tsx
+++ b/src/client/views/selectedDoc/SelectedDocView.tsx
@@ -6,9 +6,9 @@ import * as React from 'react';
import { emptyFunction } from '../../../Utils';
import { Doc } from '../../../fields/Doc';
import { StrCast } from '../../../fields/Types';
-import { DocumentManager } from '../../util/DocumentManager';
-import { SettingsManager } from '../../util/SettingsManager';
-import { FocusViewOptions } from '../nodes/FieldView';
+import { SnappingManager } from '../../util/SnappingManager';
+import { DocumentView } from '../nodes/DocumentView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
export interface SelectedDocViewProps {
selectedDocs: Doc[];
@@ -33,14 +33,14 @@ export class SelectedDocView extends React.Component<SelectedDocViewProps> {
return {
text: StrCast(doc.title),
val: StrCast(doc._id),
- color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
- icon: <FontAwesomeIcon size={'1x'} icon={Doc.toIcon(doc)} />,
- onClick: () => DocumentManager.Instance.showDocument(doc, options, emptyFunction),
+ color: SnappingManager.userColor,
+ background: SnappingManager.userBackgroundColor,
+ icon: <FontAwesomeIcon size="1x" icon={Doc.toIcon(doc)} />,
+ onClick: () => DocumentView.showDocument(doc, options, emptyFunction),
};
})}
- color={SettingsManager.userColor}
- background={SettingsManager.userBackgroundColor}
+ color={SnappingManager.userColor}
+ background={SnappingManager.userBackgroundColor}
/>
</div>
);
diff --git a/src/client/views/selectedDoc/index.ts b/src/client/views/selectedDoc/index.ts
index 1f1db91f6..968e9c2d4 100644
--- a/src/client/views/selectedDoc/index.ts
+++ b/src/client/views/selectedDoc/index.ts
@@ -1 +1 @@
-export * from './SelectedDocView' \ No newline at end of file
+export * from './SelectedDocView';
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index addad2bbc..e558e14e3 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -3,14 +3,15 @@ import { Button, IconButton, isDark, Size, Type } from 'browndash-components';
import { action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { Flip } from 'react-awesome-reveal';
import { FaBug } from 'react-icons/fa';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils';
import { Doc, DocListCast } from '../../../fields/Doc';
import { AclAdmin, DashVersion } from '../../../fields/DocSymbols';
import { StrCast } from '../../../fields/Types';
import { GetEffectiveAcl } from '../../../fields/util';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
-import { CurrentUserUtils } from '../../util/CurrentUserUtils';
-import { DocumentManager } from '../../util/DocumentManager';
+import { emptyFunction } from '../../../Utils';
+import { dropActionType } from '../../util/DropActionTypes';
import { PingManager } from '../../util/PingManager';
import { ReportManager } from '../../util/reportManager/ReportManager';
import { ServerStats } from '../../util/ServerStats';
@@ -22,12 +23,10 @@ import { CollectionDockingView } from '../collections/CollectionDockingView';
import { CollectionLinearView } from '../collections/collectionLinear';
import { DashboardView } from '../DashboardView';
import { Colors } from '../global/globalEnums';
-import { DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
-import { DefaultStyleProvider } from '../StyleProvider';
-import './TopBar.scss';
-import { dropActionType } from '../../util/DragManager';
-import { Flip } from 'react-awesome-reveal';
+import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
import { ObservableReactComponent } from '../ObservableReactComponent';
+import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider';
+import './TopBar.scss';
/**
* ABOUT: This is the topbar in Dash, which included the current Dashboard as well as access to information on the user
@@ -35,6 +34,7 @@ import { ObservableReactComponent } from '../ObservableReactComponent';
*/
@observer
export class TopBar extends ObservableReactComponent<{}> {
+ // eslint-disable-next-line no-use-before-define
static Instance: TopBar;
@observable private _flipDocumentation = 0;
constructor(props: any) {
@@ -44,10 +44,12 @@ export class TopBar extends ObservableReactComponent<{}> {
}
navigateToHome = () => {
- (CollectionDockingView.Instance?.CaptureThumbnail() ?? new Promise<void>(res => res())).then(() => {
+ (CollectionDockingView.Instance?.CaptureThumbnail() ??
+ new Promise<void>(res => { res(); })) .then(() =>
+ {
Doc.ActivePage = 'home';
DashboardView.closeActiveDashboard(); // bcz: if we do this, we need some other way to keep track, for user convenience, of the last dashboard in use
- });
+ }); // prettier-ignore
};
@computed get color() {
@@ -61,7 +63,9 @@ export class TopBar extends ObservableReactComponent<{}> {
}
@observable happyHeart: boolean = PingManager.Instance.IsBeating;
- setHappyHeart = action((status: boolean) => (this.happyHeart = status));
+ setHappyHeart = action((status: boolean) => {
+ this.happyHeart = status;
+ });
dispose = reaction(
() => PingManager.Instance.IsBeating,
isBeating => this.setHappyHeart(isBeating)
@@ -85,7 +89,7 @@ export class TopBar extends ObservableReactComponent<{}> {
/>
) : (
<div className="logo-container">
- <img className="logo" src="/assets/medium-blue-light-blue-circle.png" alt="dash logo"></img>
+ <img className="logo" src="/assets/medium-blue-light-blue-circle.png" alt="dash logo" />
<span style={{ color: isDark(this.backgroundColor) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, fontWeight: 200 }}>brown</span>
<span style={{ color: isDark(this.backgroundColor) ? Colors.LIGHT_BLUE : Colors.MEDIUM_BLUE, fontWeight: 500 }}>dash</span>
</div>
@@ -164,7 +168,7 @@ export class TopBar extends ObservableReactComponent<{}> {
color={this.color}
style={{ fontWeight: 700, fontSize: '1rem' }}
onClick={(e: React.MouseEvent) => {
- const dashView = Doc.ActiveDashboard && DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard);
+ const dashView = Doc.ActiveDashboard && DocumentView.getDocumentView(Doc.ActiveDashboard);
dashView?.showContextMenu(e.clientX + 20, e.clientY + 30);
}}
/>
@@ -178,7 +182,7 @@ export class TopBar extends ObservableReactComponent<{}> {
* and allows the user to access their account settings etc.
*/
@computed get topbarRight() {
- const upToDate = DashVersion === CurrentUserUtils.ServerVersion;
+ const upToDate = DashVersion === SnappingManager.ServerVersion;
return (
<div className="topbar-right">
{Doc.ActiveDashboard ? (
@@ -192,11 +196,11 @@ export class TopBar extends ObservableReactComponent<{}> {
}}
/>
) : null}
- <IconButton tooltip={'Issue Reporter ⌘I'} size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} />
+ <IconButton tooltip="Issue Reporter ⌘I" size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} />
<Flip key={this._flipDocumentation}>
- <IconButton tooltip={'Documentation ⌘D'} size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
+ <IconButton tooltip="Documentation ⌘D" size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
</Flip>
- <IconButton tooltip={'Settings ⌘⇧S'} size={Size.SMALL} color={this.color} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
+ <IconButton tooltip="Settings ⌘⇧S" size={Size.SMALL} color={this.color} onClick={SettingsManager.Instance.openMgr} icon={<FontAwesomeIcon icon="cog" />} />
<IconButton
size={Size.SMALL}
onClick={ServerStats.Instance.open}
@@ -213,11 +217,13 @@ export class TopBar extends ObservableReactComponent<{}> {
/**
* Make the documentation icon flip around to draw attention to it.
*/
- FlipDocumentationIcon = action(() => (this._flipDocumentation = this._flipDocumentation + 1));
+ FlipDocumentationIcon = action(() => {
+ this._flipDocumentation += 1;
+ });
render() {
return (
- //TODO:glr Add support for light / dark mode
+ // TODO:glr Add support for light / dark mode
<div
style={{
pointerEvents: 'all',
diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
deleted file mode 100644
index 5744ebbcd..000000000
--- a/src/client/views/webcam/DashWebRTCVideo.scss
+++ /dev/null
@@ -1,82 +0,0 @@
-@import '../global/globalCssVariables.module.scss';
-
-.webcam-cont {
- background: whitesmoke;
- color: grey;
- border-radius: 15px;
- box-shadow: #9c9396 0.2vw 0.2vw 0.4vw;
- border: solid #bbbbbbbb 5px;
- pointer-events: all;
- display: flex;
- flex-direction: column;
- overflow: hidden;
-
- .webcam-header {
- height: 50px;
- text-align: center;
- text-transform: uppercase;
- letter-spacing: 2px;
- font-size: 16px;
- width: 100%;
- margin-top: 20px;
- }
-
- .videoContainer {
- position: relative;
- width: calc(100% - 20px);
- height: 100%;
- /* border: 10px solid red; */
- margin-left: 10px;
- }
-
- .buttonContainer {
- display: flex;
- width: calc(100% - 20px);
- height: 50px;
- justify-content: center;
- text-align: center;
- /* border: 1px solid black; */
- margin-left: 10px;
- margin-top: 0;
- margin-bottom: 15px;
- }
-
- #roomName {
- outline: none;
- border-radius: inherit;
- border: 1px solid #bbbbbbbb;
- margin: 10px;
- padding: 10px;
- }
-
- .side {
- width: 25%;
- height: 20%;
- position: absolute;
- /* top: 65%; */
- z-index: 2;
- right: 0px;
- bottom: 18px;
- }
-
- .main {
- position: absolute;
- width: 100%;
- height: 100%;
- /* top: 20%; */
- align-self: center;
- }
-
- .videoButtons {
- border-radius: 50%;
- height: 30px;
- width: 30px;
- display: flex;
- justify-content: center;
- align-items: center;
- justify-self: center;
- align-self: center;
- margin: 5px;
- border: 1px solid black;
- }
-}
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
deleted file mode 100644
index 4e984f3d6..000000000
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import { IconLookup } from '@fortawesome/fontawesome-svg-core';
-import { faPhoneSlash, faSync } from '@fortawesome/free-solid-svg-icons';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { Doc } from '../../../fields/Doc';
-import { InkTool } from '../../../fields/InkField';
-import { SnappingManager } from '../../util/SnappingManager';
-import '../../views/nodes/WebBox.scss';
-import { FieldView, FieldViewProps } from '../nodes/FieldView';
-import './DashWebRTCVideo.scss';
-import { hangup, initialize, refreshVideos } from './WebCamLogic';
-
-/**
- * This models the component that will be rendered, that can be used as a doc that will reflect the video cams.
- */
-@observer
-export class DashWebRTCVideo extends React.Component<FieldViewProps> {
- private roomText: HTMLInputElement | undefined;
- @observable remoteVideoAdded: boolean = false;
-
- @action
- changeUILook = () => (this.remoteVideoAdded = true);
-
- /**
- * Function that submits the title entered by user on enter press.
- */
- private onEnterKeyDown = (e: React.KeyboardEvent) => {
- if (e.keyCode === 13) {
- const submittedTitle = this.roomText!.value;
- this.roomText!.value = '';
- this.roomText!.blur();
- initialize(submittedTitle, this.changeUILook);
- }
- };
-
- public static LayoutString(fieldKey: string) {
- return FieldView.LayoutString(DashWebRTCVideo, fieldKey);
- }
-
- onClickRefresh = () => refreshVideos();
-
- onClickHangUp = () => hangup();
-
- render() {
- const content = (
- <div className="webcam-cont" style={{ width: '100%', height: '100%' }}>
- <div className="webcam-header">DashWebRTC</div>
- <input id="roomName" type="text" placeholder="Enter room name" ref={e => (this.roomText = e!)} onKeyDown={this.onEnterKeyDown} />
- <div className="videoContainer">
- <video id="localVideo" className={'RTCVideo' + (this.remoteVideoAdded ? ' side' : ' main')} autoPlay playsInline muted ref={e => {}}></video>
- <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={e => {}}></video>
- </div>
- <div className="buttonContainer">
- <div className="videoButtons" style={{ background: 'red' }} onClick={this.onClickHangUp}>
- <FontAwesomeIcon icon={faPhoneSlash as IconLookup} color="white" />
- </div>
- <div className="videoButtons" style={{ background: 'green' }} onClick={this.onClickRefresh}>
- <FontAwesomeIcon icon={faSync as IconLookup} color="white" />
- </div>
- </div>
- </div>
- );
-
- const frozen = !this.props.isSelected() || SnappingManager.IsResizing;
- const classname = 'webBox-cont' + (this.props.isSelected() && Doc.ActiveTool === InkTool.None && !SnappingManager.IsResizing ? '-interactive' : '');
-
- return (
- <>
- <div className={classname}>{content}</div>
- {!frozen ? null : <div className="webBox-overlay" />}
- </>
- );
- }
-}
diff --git a/src/client/views/webcam/WebCamLogic.js b/src/client/views/webcam/WebCamLogic.js
deleted file mode 100644
index 5f6202bc8..000000000
--- a/src/client/views/webcam/WebCamLogic.js
+++ /dev/null
@@ -1,292 +0,0 @@
-'use strict';
-import io from "socket.io-client";
-
-var socket;
-var isChannelReady = false;
-var isInitiator = false;
-var isStarted = false;
-var localStream;
-var pc;
-var remoteStream;
-var turnReady;
-var room;
-
-export function initialize(roomName, handlerUI) {
-
- var pcConfig = {
- 'iceServers': [{
- 'urls': 'stun:stun.l.google.com:19302'
- }]
- };
-
- // Set up audio and video regardless of what devices are present.
- var sdpConstraints = {
- offerToReceiveAudio: true,
- offerToReceiveVideo: true
- };
-
- /////////////////////////////////////////////
-
- room = roomName;
-
- socket = io.connect(`${window.location.protocol}//${window.location.hostname}:4321`);
-
- if (room !== '') {
- socket.emit('create or join', room);
- console.log('Attempted to create or join room', room);
- }
-
- socket.on('created', function (room) {
- console.log('Created room ' + room);
- isInitiator = true;
- });
-
- socket.on('full', function (room) {
- console.log('Room ' + room + ' is full');
- });
-
- socket.on('join', function (room) {
- console.log('Another peer made a request to join room ' + room);
- console.log('This peer is the initiator of room ' + room + '!');
- isChannelReady = true;
- });
-
- socket.on('joined', function (room) {
- console.log('joined: ' + room);
- isChannelReady = true;
- });
-
- socket.on('log', function (array) {
- console.log.apply(console, array);
- });
-
- ////////////////////////////////////////////////
-
-
- // This client receives a message
- socket.on('message', function (message) {
- console.log('Client received message:', message);
- if (message === 'got user media') {
- maybeStart();
- } else if (message.type === 'offer') {
- if (!isInitiator && !isStarted) {
- maybeStart();
- }
- pc.setRemoteDescription(new RTCSessionDescription(message));
- doAnswer();
- } else if (message.type === 'answer' && isStarted) {
- pc.setRemoteDescription(new RTCSessionDescription(message));
- } else if (message.type === 'candidate' && isStarted) {
- var candidate = new RTCIceCandidate({
- sdpMLineIndex: message.label,
- candidate: message.candidate
- });
- pc.addIceCandidate(candidate);
- } else if (message === 'bye' && isStarted) {
- handleRemoteHangup();
- }
- });
-
- ////////////////////////////////////////////////////
-
- var localVideo = document.querySelector('#localVideo');
- var remoteVideo = document.querySelector('#remoteVideo');
-
- const gotStream = (stream) => {
- console.log('Adding local stream.');
- localStream = stream;
- localVideo.srcObject = stream;
- sendMessage('got user media');
- if (isInitiator) {
- maybeStart();
- }
- }
-
-
- navigator.mediaDevices.getUserMedia({
- audio: true,
- video: true
- })
- .then(gotStream)
- .catch(function (e) {
- alert('getUserMedia() error: ' + e.name);
- });
-
-
-
- var constraints = {
- video: true
- };
-
- console.log('Getting user media with constraints', constraints);
-
- const requestTurn = (turnURL) => {
- var turnExists = false;
- for (var i in pcConfig.iceServers) {
- if (pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
- turnExists = true;
- turnReady = true;
- break;
- }
- }
- if (!turnExists) {
- console.log('Getting TURN server from ', turnURL);
- // No TURN server. Get one from computeengineondemand.appspot.com:
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4 && xhr.status === 200) {
- var turnServer = JSON.parse(xhr.responseText);
- console.log('Got TURN server: ', turnServer);
- pcConfig.iceServers.push({
- 'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
- 'credential': turnServer.password
- });
- turnReady = true;
- }
- };
- xhr.open('GET', turnURL, true);
- xhr.send();
- }
- }
-
-
-
-
- if (location.hostname !== 'localhost') {
- requestTurn(
- `${window.location.origin}/corsProxy/${encodeURIComponent("https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913")}`
- );
- }
-
- const maybeStart = () => {
- console.log('>>>>>>> maybeStart() ', isStarted, localStream, isChannelReady);
- if (!isStarted && typeof localStream !== 'undefined' && isChannelReady) {
- console.log('>>>>>> creating peer connection');
- createPeerConnection();
- pc.addStream(localStream);
- isStarted = true;
- console.log('isInitiator', isInitiator);
- if (isInitiator) {
- doCall();
- }
- }
- };
-
- window.onbeforeunload = function () {
- sendMessage('bye');
- };
-
- /////////////////////////////////////////////////////////
-
- const createPeerConnection = () => {
- try {
- pc = new RTCPeerConnection(null);
- pc.onicecandidate = handleIceCandidate;
- pc.onaddstream = handleRemoteStreamAdded;
- pc.onremovestream = handleRemoteStreamRemoved;
- console.log('Created RTCPeerConnnection');
- } catch (e) {
- console.log('Failed to create PeerConnection, exception: ' + e.message);
- alert('Cannot create RTCPeerConnection object.');
- return;
- }
- }
-
- const handleIceCandidate = (event) => {
- console.log('icecandidate event: ', event);
- if (event.candidate) {
- sendMessage({
- type: 'candidate',
- label: event.candidate.sdpMLineIndex,
- id: event.candidate.sdpMid,
- candidate: event.candidate.candidate
- });
- } else {
- console.log('End of candidates.');
- }
- }
-
- const handleCreateOfferError = (event) => {
- console.log('createOffer() error: ', event);
- }
-
- const doCall = () => {
- console.log('Sending offer to peer');
- pc.createOffer(setLocalAndSendMessage, handleCreateOfferError);
- }
-
- const doAnswer = () => {
- console.log('Sending answer to peer.');
- pc.createAnswer().then(
- setLocalAndSendMessage,
- onCreateSessionDescriptionError
- );
- }
-
- const setLocalAndSendMessage = (sessionDescription) => {
- pc.setLocalDescription(sessionDescription);
- console.log('setLocalAndSendMessage sending message', sessionDescription);
- sendMessage(sessionDescription);
- }
-
- const onCreateSessionDescriptionError = (error) => {
- trace('Failed to create session description: ' + error.toString());
- }
-
-
-
- const handleRemoteStreamAdded = (event) => {
- console.log('Remote stream added.');
- remoteStream = event.stream;
- remoteVideo.srcObject = remoteStream;
- handlerUI();
-
- };
-
- const handleRemoteStreamRemoved = (event) => {
- console.log('Remote stream removed. Event: ', event);
- }
-}
-
-export function hangup() {
- console.log('Hanging up.');
- stop();
- sendMessage('bye');
- if (localStream) {
- localStream.getTracks().forEach(track => track.stop());
- }
-}
-
-function stop() {
- isStarted = false;
- if (pc) {
- pc.close();
- }
- pc = null;
-}
-
-function handleRemoteHangup() {
- console.log('Session terminated.');
- stop();
- isInitiator = false;
- if (localStream) {
- localStream.getTracks().forEach(track => track.stop());
- }
-}
-
-function sendMessage(message) {
- console.log('Client sending message: ', message);
- socket.emit('message', message, room);
-};
-
-export function refreshVideos() {
- var localVideo = document.querySelector('#localVideo');
- var remoteVideo = document.querySelector('#remoteVideo');
- if (localVideo) {
- localVideo.srcObject = localStream;
- }
- if (remoteVideo) {
- remoteVideo.srcObject = remoteStream;
- }
-
-} \ No newline at end of file
diff --git a/src/debug/Repl.tsx b/src/debug/Repl.tsx
index a9f7c085f..8ac502348 100644
--- a/src/debug/Repl.tsx
+++ b/src/debug/Repl.tsx
@@ -30,7 +30,7 @@ class Repl extends React.Component {
if (!script.compiled) {
this.executedCommands.push({ command: this.text, result: 'Compile Error' });
} else {
- const result = script.run({ makeInterface }, e => this.executedCommands.push({ command: this.text, result: e.message || e }));
+ const result = script.run({ makeInterface }, err => this.executedCommands.push({ command: this.text, result: err.message || err }));
result.success && this.executedCommands.push({ command: this.text, result: result.result });
}
this.text = '';
@@ -39,15 +39,13 @@ class Repl extends React.Component {
@computed
get commands() {
- return this.executedCommands.map(command => {
- return (
- <div style={{ marginTop: '5px' }}>
- <p>{command.command}</p>
- {/* <pre>{JSON.stringify(command.result, null, 2)}</pre> */}
- <pre>{command.result instanceof RefField || command.result instanceof ObjectField ? 'object' : String(command.result)}</pre>
- </div>
- );
- });
+ return this.executedCommands.map(command => (
+ <div style={{ marginTop: '5px' }}>
+ <p>{command.command}</p>
+ {/* <pre>{JSON.stringify(command.result, null, 2)}</pre> */}
+ <pre>{command.result instanceof RefField || command.result instanceof ObjectField ? 'object' : String(command.result)}</pre>
+ </div>
+ ));
}
render() {
diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx
index c906dcc03..856cf6bd4 100644
--- a/src/debug/Test.tsx
+++ b/src/debug/Test.tsx
@@ -1,11 +1,12 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
-console.log('ENTERED');
+
class Test extends React.Component {
render() {
return <div> HELLO WORLD </div>;
}
}
+
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(<Test />);
diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx
index f46adef77..f3295a6c6 100644
--- a/src/debug/Viewer.tsx
+++ b/src/debug/Viewer.tsx
@@ -1,14 +1,19 @@
+/* eslint-disable react/no-unescaped-entities */
+/* eslint-disable react/button-has-type */
+/* eslint-disable no-use-before-define */
+/* eslint-disable react/no-array-index-key */
+/* eslint-disable no-redeclare */
import { action, configure, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import * as ReactDOM from 'react-dom';
+import * as ReactDOM from 'react-dom/client';
import { DocServer } from '../client/DocServer';
import { resolvedPorts } from '../client/util/CurrentUserUtils';
import { CompileScript } from '../client/util/Scripting';
import { EditableView } from '../client/views/EditableView';
import CursorField from '../fields/CursorField';
import { DateField } from '../fields/DateField';
-import { Doc, Field, FieldResult } from '../fields/Doc';
+import { Doc, Field, FieldType, FieldResult } from '../fields/Doc';
import { Id } from '../fields/FieldSymbols';
import { List } from '../fields/List';
import { RichTextField } from '../fields/RichTextField';
@@ -39,7 +44,7 @@ configure({
});
@observer
-class ListViewer extends React.Component<{ field: List<Field> }> {
+class ListViewer extends React.Component<{ field: List<FieldType> }> {
@observable
expanded = false;
@@ -86,14 +91,12 @@ class DocumentViewer extends React.Component<{ field: Doc }> {
let content;
if (this.expanded) {
const keys = Object.keys(this.props.field);
- const fields = keys.map(key => {
- return (
- <div key={key}>
- <b>({key}): </b>
- <DebugViewer field={this.props.field[key]} setValue={value => applyToDoc(this.props.field, key, value)}></DebugViewer>
- </div>
- );
- });
+ const fields = keys.map(key => (
+ <div key={key}>
+ <b>({key}): </b>
+ <DebugViewer field={this.props.field[key]} setValue={value => applyToDoc(this.props.field, key, value)} />
+ </div>
+ ));
content = (
<div>
Document ({this.props.field[Id]})<div style={{ paddingLeft: '25px' }}>{fields}</div>
@@ -115,7 +118,7 @@ class DocumentViewer extends React.Component<{ field: Doc }> {
class DebugViewer extends React.Component<{ field: FieldResult; setValue(value: string): boolean }> {
render() {
let content;
- const field = this.props.field;
+ const { field } = this.props;
if (field instanceof List) {
content = <ListViewer field={field} />;
} else if (field instanceof Doc) {
@@ -144,7 +147,7 @@ class Viewer extends React.Component {
private idToAdd: string = '';
@observable
- private fields: Field[] = [];
+ private fields: FieldType[] = [];
@action
inputOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -152,7 +155,7 @@ class Viewer extends React.Component {
};
@action
- onKeyPress = (e: React.KeyboardEvent<HTMLDivElement>) => {
+ onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.key === 'Enter') {
DocServer.GetRefField(this.idToAdd).then(
action((field: any) => {
@@ -168,10 +171,10 @@ class Viewer extends React.Component {
render() {
return (
<>
- <input value={this.idToAdd} onChange={this.inputOnChange} onKeyDown={this.onKeyPress} />
+ <input value={this.idToAdd} onChange={this.inputOnChange} onKeyDown={this.onKeyDown} />
<div>
{this.fields.map((field, index) => (
- <DebugViewer field={field} key={index} setValue={() => false}></DebugViewer>
+ <DebugViewer field={field} key={index} setValue={() => false} />
))}
</div>
</>
@@ -181,10 +184,13 @@ class Viewer extends React.Component {
(async function () {
await DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts.socket, 'viewer');
- ReactDOM.render(
- <div style={{ position: 'absolute', width: '100%', height: '100%' }}>
- <Viewer />
- </div>,
- document.getElementById('root')
- );
+ const root = document.getElementById('root');
+ if (root) {
+ const reactDom = ReactDOM.createRoot(root);
+ reactDom.render(
+ <div style={{ position: 'absolute', width: '100%', height: '100%' }}>
+ <Viewer />
+ </div>
+ );
+ }
})();
diff --git a/src/extensions/Extensions.ts b/src/extensions/Extensions.ts
new file mode 100644
index 000000000..5815527d1
--- /dev/null
+++ b/src/extensions/Extensions.ts
@@ -0,0 +1,9 @@
+import { Assign as ArrayAssign } from './Extensions_Array';
+import { Assign as StringAssign } from './Extensions_String';
+
+function AssignAllExtensions() {
+ ArrayAssign();
+ StringAssign();
+}
+
+export { AssignAllExtensions };
diff --git a/src/extensions/General/ExtensionsTypings.ts b/src/extensions/ExtensionsTypings.ts
index 370157ed0..d6ffd3be3 100644
--- a/src/extensions/General/ExtensionsTypings.ts
+++ b/src/extensions/ExtensionsTypings.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
interface Array<T> {
lastElement(): T;
}
@@ -5,4 +6,4 @@ interface Array<T> {
interface String {
removeTrailingNewlines(): string;
hasNewline(): boolean;
-} \ No newline at end of file
+}
diff --git a/src/extensions/ArrayExtensions.ts b/src/extensions/Extensions_Array.ts
index 8e125766d..a50fb330f 100644
--- a/src/extensions/ArrayExtensions.ts
+++ b/src/extensions/Extensions_Array.ts
@@ -8,12 +8,12 @@ export default class ArrayExtension {
}
assign() {
+ // eslint-disable-next-line no-extend-native
Object.defineProperty(Array.prototype, this.property, {
value: this.body,
- enumerable: false
+ enumerable: false,
});
}
-
}
/**
@@ -22,16 +22,16 @@ export default class ArrayExtension {
* Typescript will not recognize your new function.
*/
const extensions = [
- new ArrayExtension("lastElement", function () {
+ new ArrayExtension('lastElement', function () {
if (!this.length) {
return undefined;
}
return this[this.length - 1];
- })
+ }),
];
function Assign() {
extensions.forEach(extension => extension.assign());
}
-export { Assign }; \ No newline at end of file
+export { Assign };
diff --git a/src/extensions/StringExtensions.ts b/src/extensions/Extensions_String.ts
index 2c76e56c8..c95095f8e 100644
--- a/src/extensions/StringExtensions.ts
+++ b/src/extensions/Extensions_String.ts
@@ -1,17 +1,16 @@
+/* eslint-disable no-extend-native */
function Assign() {
-
String.prototype.removeTrailingNewlines = function () {
let sliced = this;
- while (sliced.endsWith("\n")) {
+ while (sliced.endsWith('\n')) {
sliced = sliced.substring(0, this.length - 1);
}
return sliced as string;
};
String.prototype.hasNewline = function () {
- return this.endsWith("\n");
+ return this.endsWith('\n');
};
-
}
-export { Assign }; \ No newline at end of file
+export { Assign };
diff --git a/src/extensions/General/Extensions.ts b/src/extensions/General/Extensions.ts
deleted file mode 100644
index 4b6d05d5f..000000000
--- a/src/extensions/General/Extensions.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Assign as ArrayAssign } from "../ArrayExtensions";
-import { Assign as StringAssign } from "../StringExtensions";
-
-function AssignAllExtensions() {
- ArrayAssign();
- StringAssign();
-}
-
-export { AssignAllExtensions }; \ No newline at end of file
diff --git a/src/fields/DateField.ts b/src/fields/DateField.ts
index 1e5222fb6..f0a851ce6 100644
--- a/src/fields/DateField.ts
+++ b/src/fields/DateField.ts
@@ -1,5 +1,5 @@
+import { serializable, date as serializrDate } from 'serializr';
import { Deserializable } from '../client/util/SerializationHelper';
-import { serializable, date } from 'serializr';
import { ObjectField } from './ObjectField';
import { Copy, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGlobals';
@@ -7,7 +7,7 @@ import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGloba
@scriptingGlobal
@Deserializable('date')
export class DateField extends ObjectField {
- @serializable(date())
+ @serializable(serializrDate())
readonly date: Date;
constructor(date: Date = new Date()) {
@@ -38,6 +38,7 @@ export class DateField extends ObjectField {
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function d(...dateArgs: any[]) {
return new DateField(new (Date as any)(...dateArgs));
});
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index e47bfcbed..2d3dddc8b 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1,49 +1,63 @@
-import { saveAs } from 'file-saver';
+/* eslint-disable default-param-last */
+/* eslint-disable no-use-before-define */
import { action, computed, makeObservable, observable, ObservableMap, ObservableSet, runInAction } from 'mobx';
import { computedFn } from 'mobx-utils';
import { alias, map, serializable } from 'serializr';
import { DocServer } from '../client/DocServer';
import { CollectionViewType, DocumentType } from '../client/documents/DocumentTypes';
-import { LinkManager } from '../client/util/LinkManager';
import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGlobals';
import { afterDocDeserialize, autoObject, Deserializable, SerializationHelper } from '../client/util/SerializationHelper';
-import { undoable } from '../client/util/UndoManager';
-import { DocumentView } from '../client/views/nodes/DocumentView';
-import { decycle } from '../decycler/decycler';
-import * as JSZipUtils from '../JSZipUtils';
-import { incrementTitleCopy, Utils } from '../Utils';
-import { DateField } from './DateField';
+import { undoable, UndoManager } from '../client/util/UndoManager';
+import { ClientUtils, incrementTitleCopy } from '../ClientUtils';
import {
AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, Animation, AudioPlay, Brushed, CachedUpdates, DirectLinks,
- DocAcl, DocCss, DocData, DocFields, DocLayout, DocViews, FieldKeys, FieldTuples, ForceServerWrite, Height, Highlight,
+ DocAcl, DocCss, DocData, DocLayout, DocViews, FieldKeys, FieldTuples, ForceServerWrite, Height, Highlight,
Initializing, Self, SelfProxy, TransitionTimer, UpdatingFromServer, Width
} from './DocSymbols'; // prettier-ignore
import { Copy, FieldChanged, HandleUpdate, Id, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
-import { InkField, InkTool } from './InkField';
-import { List, ListFieldName } from './List';
+import { InkTool } from './InkField';
+import { List } from './List';
import { ObjectField } from './ObjectField';
import { PrefetchProxy, ProxyField } from './Proxy';
import { FieldId, RefField } from './RefField';
import { RichTextField } from './RichTextField';
import { listSpec } from './Schema';
import { ComputedField, ScriptField } from './ScriptField';
-import { BoolCast, Cast, DocCast, FieldValue, NumCast, StrCast, ToConstructor } from './Types';
-import { AudioField, CsvField, ImageField, PdfField, VideoField, WebField } from './URLField';
+import { BoolCast, Cast, DocCast, FieldValue, NumCast, StrCast, ToConstructor, toList } from './Types';
import { containedFieldChangedHandler, deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, setter, SharingPermissions } from './util';
-import * as JSZip from 'jszip';
-import { FieldViewProps } from '../client/views/nodes/FieldView';
+
export const LinkedTo = '-linkedTo';
export namespace Field {
- export function toKeyValueString(doc: Doc, key: string): string {
- const onDelegate = Object.keys(doc).includes(key.replace(/^_/, ''));
- const field = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
- return !Field.IsField(field)
- ? key.startsWith('_')
- ? '='
- : ''
- : (onDelegate ? '=' : '') + (field instanceof ComputedField ? `:=${field.script.originalScript}` : field instanceof ScriptField ? `$=${field.script.originalScript}` : Field.toScriptString(field));
- }
- export function toScriptString(field: Field) {
+ /**
+ * Converts a field to its equivalent input string in the key value box such that if the string
+ * is entered into a keyValueBox it will create an equivalent field (except if showComputedValue is set).
+ * @param doc doc containing key
+ * @param key field key to display
+ * @param showComputedValue whether copmuted function should display its value instead of its function
+ * @returns string representation of the field
+ */
+ export function toKeyValueString(doc: Doc, key: string, showComputedValue?: boolean): string {
+ const isOnDelegate = !Doc.IsDataProto(doc) && Object.keys(doc).includes(key.replace(/^_/, ''));
+ const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+ const valFunc = (field: FieldType): string => {
+ const res =
+ field instanceof ComputedField && showComputedValue
+ ? field.value(doc)
+ : field instanceof ComputedField
+ ? `:=${field.script.originalScript.replace(/dashCallChat\(_setCacheResult_, this, `(.*)`\)/, '(($1))')}`
+ : field instanceof ScriptField
+ ? `$=${field.script.originalScript}`
+ : Field.toScriptString(field);
+ const resStr = (res + '').replace(/^`(.*)`$/, '$1');
+ return typeof field === 'string' && (+resStr).toString() !== resStr && !Array.from('+-*/.').some(k => Array.from(resStr).includes(k))
+ ? resStr
+ : (res + '') // adjust the key value string to be easier to enter: represent any initial list as an array with []
+ .trim()
+ .replace(/^new List\((.*)\)$/, '$1');
+ };
+ return !Field.IsField(cfield) ? (key.startsWith('_') ? '=' : '') : (isOnDelegate ? '=' : '') + valFunc(cfield);
+ }
+ export function toScriptString(field: FieldType) {
switch (typeof field) {
case 'string': if (field.startsWith('{"')) return `'${field}'`; // bcz: hack ... want to quote the string the right way. if there are nested "'s, then use ' instead of ". In this case, test for the start of a JSON string of the format {"property": ... } and use outer 's instead of "s
return !field.includes('`') ? `\`${field}\`` : `"${field}"`;
@@ -52,8 +66,8 @@ export namespace Field {
default: return field?.[ToScriptString]?.() ?? 'null';
} // prettier-ignore
}
- export function toJavascriptString(field: Field) {
- var rawjava = '';
+ export function toJavascriptString(field: FieldType) {
+ let rawjava = '';
switch (typeof field) {
case 'string':
@@ -62,11 +76,12 @@ export namespace Field {
break;
default: rawjava = field?.[ToJavascriptString]?.() ?? '';
} // prettier-ignore
- var script = rawjava;
+ let script = rawjava;
// this is a bit hacky, but we treat '^@' references to a published document
// as a kind of macro to include the content of those documents
Doc.MyPublishedDocs.forEach(doc => {
- const regex = new RegExp(`^\\^${doc.title}\\s`, 'm');
+ const regexMultilineFlag = 'm';
+ const regex = new RegExp(`^\\^${StrCast(doc.title).replace(/[()]*/g, '')}\\s`, regexMultilineFlag); // need to remove characters that can cause the regular expression to be invalid
const sections = (Cast(doc.text, RichTextField, null)?.Text ?? '').split('--DOCDATA--');
if (script.match(regex)) {
script = script.replace(regex, sections[0]) + (sections.length > 1 ? sections[1] : '');
@@ -74,23 +89,25 @@ export namespace Field {
});
return script;
}
- export function toString(field: Field) {
+ export function toString(field: FieldType) {
if (typeof field === 'string' || typeof field === 'number' || typeof field === 'boolean') return String(field);
return field?.[ToString]?.() || '';
}
- export function IsField(field: any): field is Field;
- export function IsField(field: any, includeUndefined: true): field is Field | undefined;
- export function IsField(field: any, includeUndefined: boolean = false): field is Field | undefined {
+ 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 {
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;
}
+ UndoManager.SetFieldPrinter(toString);
}
-export type Field = number | string | boolean | ObjectField | RefField;
+export type FieldType = number | string | boolean | ObjectField | RefField;
export type Opt<T> = T | undefined;
export type FieldWaiting<T extends RefField = RefField> = T extends undefined ? never : Promise<T | undefined>;
-export type FieldResult<T extends Field = Field> = Opt<T> | FieldWaiting<Extract<T, RefField>>;
+export type FieldResult<T extends FieldType = FieldType> = Opt<T> | FieldWaiting<Extract<T, RefField>>;
/**
* Cast any field to either a List of Docs or undefined if the given field isn't a List of Docs.
@@ -99,7 +116,9 @@ export type FieldResult<T extends Field = Field> = Opt<T> | FieldWaiting<Extract
* If no default value is given, and the returned value is not undefined, it can be safely modified.
*/
export function DocListCastAsync(field: FieldResult): Promise<Doc[] | undefined>;
+// eslint-disable-next-line no-redeclare
export function DocListCastAsync(field: FieldResult, defaultValue: Doc[]): Promise<Doc[]>;
+// eslint-disable-next-line no-redeclare
export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) {
const list = Cast(field, listSpec(Doc));
return list ? Promise.all(list).then(() => list) : Promise.resolve(defaultValue);
@@ -135,19 +154,67 @@ export const ReverseHierarchyMap: Map<string, { level: aclLevel; acl: symbol; im
// caches the document access permissions for the current user.
// this recursively updates all protos as well.
export function updateCachedAcls(doc: Doc) {
- if (!doc) return;
+ if (doc) {
+ const target = (doc as any)?.__fieldTuples ?? doc;
+ const permissions: { [key: string]: symbol } = !target.author || target.author === ClientUtils.CurrentUserEmail() ? { acl_Me: AclAdmin } : {};
+ Object.keys(target).forEach(key => {
+ key.startsWith('acl_') && (permissions[key] = ReverseHierarchyMap.get(StrCast(target[key]))!.acl);
+ });
+ if (Object.keys(permissions).length || doc[DocAcl]?.length) {
+ runInAction(() => {
+ doc[DocAcl] = permissions;
+ });
+ }
- const target = (doc as any)?.__fieldTuples ?? doc;
- const permissions: { [key: string]: symbol } = !target.author || target.author === Doc.CurrentUserEmail ? { 'acl-Me': AclAdmin } : {};
- Object.keys(target).filter(key => key.startsWith('acl') && (permissions[key] = ReverseHierarchyMap.get(StrCast(target[key]))!.acl));
- if (Object.keys(permissions).length || doc[DocAcl]?.length) {
- runInAction(() => (doc[DocAcl] = permissions));
+ if (doc.proto instanceof Promise) {
+ doc.proto.then(proto => updateCachedAcls(DocCast(proto)));
+ return doc.proto;
+ }
}
+ return undefined;
+}
- if (doc.proto instanceof Promise) {
- doc.proto.then(proto => updateCachedAcls(DocCast(proto)));
- return doc.proto;
- }
+export function ActiveInkPen(): Doc { return Doc.UserDoc(); } // prettier-ignore
+export function ActiveInkColor(): string { return StrCast(ActiveInkPen()?.activeInkColor, 'black'); } // prettier-ignore
+export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activeFillColor, ''); } // prettier-ignore
+export function ActiveIsInkMask(): boolean { return BoolCast(ActiveInkPen()?.activeIsInkMask, false); } // prettier-ignore
+export function ActiveInkHideTextLabels(): boolean { return BoolCast(ActiveInkPen().activeInkHideTextLabels, false); } // prettier-ignore
+export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ''); } // prettier-ignore
+export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, ''); } // prettier-ignore
+export function ActiveArrowScale(): number { return NumCast(ActiveInkPen()?.activeArrowScale, 1); } // prettier-ignore
+export function ActiveDash(): string { return StrCast(ActiveInkPen()?.activeDash, '0'); } // prettier-ignore
+export function ActiveInkWidth(): number { return Number(ActiveInkPen()?.activeInkWidth); } // prettier-ignore
+export function ActiveInkBezierApprox(): string { return StrCast(ActiveInkPen()?.activeInkBezier); } // prettier-ignore
+
+export function SetActiveInkWidth(width: string): void {
+ !isNaN(parseInt(width)) && ActiveInkPen() && (ActiveInkPen().activeInkWidth = width);
+}
+export function SetActiveBezierApprox(bezier: string): void {
+ ActiveInkPen() && (ActiveInkPen().activeInkBezier = isNaN(parseInt(bezier)) ? '' : bezier);
+}
+export function SetActiveInkColor(value: string) {
+ ActiveInkPen() && (ActiveInkPen().activeInkColor = value);
+}
+export function SetActiveIsInkMask(value: boolean) {
+ ActiveInkPen() && (ActiveInkPen().activeIsInkMask = value);
+}
+export function SetActiveInkHideTextLabels(value: boolean) {
+ ActiveInkPen() && (ActiveInkPen().activeInkHideTextLabels = value);
+}
+export function SetActiveFillColor(value: string) {
+ ActiveInkPen() && (ActiveInkPen().activeFillColor = value);
+}
+export function SetActiveArrowStart(value: string) {
+ ActiveInkPen() && (ActiveInkPen().activeArrowStart = value);
+}
+export function SetActiveArrowEnd(value: string) {
+ ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value);
+}
+export function SetActiveArrowScale(value: number) {
+ ActiveInkPen() && (ActiveInkPen().activeArrowScale = value);
+}
+export function SetActiveDash(dash: string): void {
+ !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash);
}
@scriptingGlobal
@@ -157,8 +224,38 @@ export class Doc extends RefField {
@observable public static GuestDashboard: Doc | undefined = undefined;
@observable public static GuestTarget: Doc | undefined = undefined;
@observable public static GuestMobile: Doc | undefined = undefined;
- public static CurrentUserEmail: string = '';
-
+ @observable.shallow public static CurrentlyLoading: Doc[] = observable([]);
+ // DocServer api
+ public static FindDocByTitle(title: string) {
+ const foundDocId =
+ title &&
+ Array.from(Object.keys(DocServer.Cache()))
+ .filter(key => DocServer.Cache()[key] instanceof Doc)
+ .find(key => (DocServer.Cache()[key] as Doc).title === title);
+
+ return foundDocId ? (DocServer.Cache()[foundDocId] as Doc) : undefined;
+ }
+ // removes from currently loading doc set
+ public static removeCurrentlyLoading(doc: Doc) {
+ if (Doc.CurrentlyLoading) {
+ const index = Doc.CurrentlyLoading.indexOf(doc);
+ runInAction(() => index !== -1 && Doc.CurrentlyLoading.splice(index, 1));
+ }
+ }
+ // adds doc to currently loading display
+ public static addCurrentlyLoading(doc: Doc) {
+ if (Doc.CurrentlyLoading.indexOf(doc) === -1) {
+ runInAction(() => Doc.CurrentlyLoading.push(doc));
+ }
+ }
+ // LinkManager api
+ public static AddLink: (link: Doc, checkExists?: boolean) => void;
+ public static DeleteLink: (link: Doc) => void;
+ public static Links: (link: Doc | undefined) => Doc[];
+ public static getOppositeAnchor: (linkDoc: Doc, anchor: Doc) => Doc | undefined;
+ // KeyValue SetField
+ public static SetField: (doc: Doc, key: string, value: string, forceOnDelegate?: boolean, setResult?: (value: FieldResult) => void) => boolean;
+ // UserDoc "API"
public static get MySharedDocs() { return DocCast(Doc.UserDoc().mySharedDocs); } // prettier-ignore
public static get MyUserDocView() { return DocCast(Doc.UserDoc().myUserDocView); } // prettier-ignore
public static get MyDockedBtns() { return DocCast(Doc.UserDoc().myDockedBtns); } // prettier-ignore
@@ -182,6 +279,8 @@ export class Doc extends RefField {
public static set noviceMode(val) { Doc.UserDoc().noviceMode = val; } // prettier-ignore
public static get IsSharingEnabled() { return BoolCast(Doc.UserDoc().isSharingEnabled); } // prettier-ignore
public static set IsSharingEnabled(val) { Doc.UserDoc().isSharingEnabled = val; } // prettier-ignore
+ public static get IsInfoUIDisabled() { return BoolCast(Doc.UserDoc().isInfoUIDisabled); } // prettier-ignore
+ public static set IsInfoUIDisabled(val) { Doc.UserDoc().isInfoUIDisabled = val; } // prettier-ignore
public static get defaultAclPrivate() { return Doc.UserDoc().defaultAclPrivate; } // prettier-ignore
public static set defaultAclPrivate(val) { Doc.UserDoc().defaultAclPrivate = val; } // prettier-ignore
public static get ActivePage() { return StrCast(Doc.UserDoc().activePage); } // prettier-ignore
@@ -194,10 +293,16 @@ export class Doc extends RefField {
public static set ActiveDashboard(val: Opt<Doc>) { Doc.UserDoc().activeDashboard = val; } // prettier-ignore
public static IsInMyOverlay(doc: Doc) { return Doc.MyOverlayDocs.includes(doc); } // prettier-ignore
- public static AddToMyOverlay(doc: Doc) { Doc.ActiveDashboard?.myOverlayDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myOverlayDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore
- public static RemFromMyOverlay(doc: Doc) { Doc.ActiveDashboard?.myOverlayDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myOverlayDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore
- public static AddToMyPublished(doc: Doc) { Doc.ActiveDashboard?.myPublishedDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myPublishedDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore
- public static RemFromMyPublished(doc: Doc){ Doc.ActiveDashboard?.myPublishedDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myPublishedDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore
+ public static AddToMyOverlay(doc: Doc) { return Doc.ActiveDashboard?.myOverlayDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myOverlayDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore
+ public static RemFromMyOverlay(doc: Doc) { return Doc.ActiveDashboard?.myOverlayDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myOverlayDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore
+ public static AddToMyPublished(doc: Doc) {
+ doc[DocData].title_custom = true;
+ doc[DocData].layout_showTitle = 'title';
+ Doc.ActiveDashboard?.myPublishedDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myPublishedDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore
+ public static RemFromMyPublished(doc: Doc){
+ doc[DocData].title_custom = false;
+ doc[DocData].layout_showTitle = undefined;
+ Doc.ActiveDashboard?.myPublishedDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myPublishedDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore
public static IsComicStyle(doc?: Doc) { return doc && Doc.ActiveDashboard && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic' ; } // prettier-ignore
constructor(id?: FieldId, forceSave?: boolean) {
@@ -225,7 +330,6 @@ export class Doc extends RefField {
DocAcl,
DocCss,
DocData,
- DocFields,
DocLayout,
DocViews,
FieldKeys,
@@ -246,9 +350,9 @@ export class Doc extends RefField {
return Reflect.getOwnPropertyDescriptor(target, prop);
}
return {
- configurable: true, //TODO Should configurable be true?
+ configurable: true, // TODO Should configurable be true?
enumerable: true,
- value: 0, //() => target.__fieldTuples[prop])
+ value: 0, // () => target.__fieldTuples[prop])
};
},
deleteProperty: deleteProperty,
@@ -260,7 +364,8 @@ export class Doc extends RefField {
if (!id || forceSave) {
DocServer.CreateField(docProxy);
}
- return docProxy;
+ // eslint-disable-next-line no-constructor-return
+ return docProxy; // need to return the proxy from the constructor so that all our added fields will get called
}
[key: string]: FieldResult;
@@ -272,14 +377,16 @@ export class Doc extends RefField {
private set __fieldTuples(value) {
// called by deserializer to set all fields in one shot
this[FieldTuples] = value;
- for (const key in value) {
- const field = value[key];
- field !== undefined && (this[FieldKeys][key] = true);
- if (field instanceof ObjectField) {
- field[Parent] = this[Self];
- field[FieldChanged] = containedFieldChangedHandler(this[SelfProxy], key, field);
+ Object.keys(value).forEach(key => {
+ if (Object.prototype.hasOwnProperty.call(value, key)) {
+ const field = value[key];
+ field !== undefined && (this[FieldKeys][key] = true);
+ if (field instanceof ObjectField) {
+ field[Parent] = this[Self];
+ field[FieldChanged] = containedFieldChangedHandler(this[SelfProxy], key, field);
+ }
}
- }
+ });
}
@observable private [FieldTuples]: any = {};
@@ -292,7 +399,7 @@ export class Doc extends RefField {
@observable public [Animation]: Opt<Doc> = undefined;
@observable public [Highlight]: boolean = false;
@observable public [Brushed]: boolean = false;
- @observable public [DocViews] = new ObservableSet<DocumentView>();
+ @observable public [DocViews] = new ObservableSet<any /* DocumentView */>();
private [Self] = this;
private [SelfProxy]: any;
@@ -301,12 +408,11 @@ export class Doc extends RefField {
private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
public [Initializing]: boolean = false;
- public [FieldChanged] = (diff: undefined | { op: '$addToSet' | '$remFromSet' | '$set'; items: Field[] | undefined; length: number | undefined; hint?: any }, serverOp: any) => {
+ public [FieldChanged] = (diff: undefined | { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: any }, serverOp: any) => {
if (!this[UpdatingFromServer] || this[ForceServerWrite]) {
DocServer.UpdateField(this[Id], serverOp);
}
};
- public [DocFields] = () => this[Self][FieldTuples]; // Object.keys(this).reduce((fields, key) => { fields[key] = this[key]; return fields; }, {} as any);
public [Width] = () => NumCast(this[SelfProxy]._width);
public [Height] = () => NumCast(this[SelfProxy]._height);
public [TransitionTimer]: any = undefined;
@@ -325,7 +431,7 @@ export class Doc extends RefField {
let renderFieldKey: any;
const layoutField = templateLayoutDoc[StrCast(templateLayoutDoc.layout_fieldKey, 'layout')];
if (typeof layoutField === 'string') {
- renderFieldKey = layoutField.split("fieldKey={'")[1].split("'")[0]; //layoutField.split("'")[1];
+ [renderFieldKey] = layoutField.split("fieldKey={'")[1].split("'"); // layoutField.split("'")[1];
} else {
return Cast(layoutField, Doc, null);
}
@@ -336,13 +442,11 @@ export class Doc extends RefField {
public async [HandleUpdate](diff: any) {
const set = diff.$set;
- const sameAuthor = this.author === Doc.CurrentUserEmail;
- if (set) {
- for (const key in set) {
- const fprefix = 'fields.';
- if (!key.startsWith(fprefix)) {
- continue;
- }
+ const sameAuthor = this.author === ClientUtils.CurrentUserEmail();
+ const fprefix = 'fields.';
+ 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]);
@@ -350,7 +454,7 @@ export class Doc extends RefField {
this[UpdatingFromServer] = true;
this[fKey] = value;
this[UpdatingFromServer] = false;
- if (fKey.startsWith('acl')) {
+ if (fKey.startsWith('acl_')) {
updateCachedAcls(this);
}
if (prev === AclPrivate && GetEffectiveAcl(this) !== AclPrivate) {
@@ -358,20 +462,18 @@ export class Doc extends RefField {
}
};
const writeMode = DocServer.getFieldWriteMode(fKey);
- if (fKey.startsWith('acl') || writeMode !== DocServer.WriteMode.Playground) {
+ if (fKey.startsWith('acl_') || writeMode !== DocServer.WriteMode.Playground) {
delete this[CachedUpdates][fKey];
+ // eslint-disable-next-line no-await-in-loop
await fn();
} else {
this[CachedUpdates][fKey] = fn;
}
- }
- }
+ });
const unset = diff.$unset;
- if (unset) {
- for (const key in unset) {
- if (!key.startsWith('fields.')) {
- continue;
- }
+ Object.keys(unset ?? {})
+ .filter(key => key.startsWith(fprefix))
+ .forEach(async key => {
const fKey = key.substring(7);
const fn = () => {
this[UpdatingFromServer] = true;
@@ -384,12 +486,22 @@ export class Doc extends RefField {
} else {
this[CachedUpdates][fKey] = fn;
}
- }
- }
+ });
}
}
+// 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;
+ }
export function SetContainer(doc: Doc, container: Doc) {
if (container !== Doc.MyRecentlyClosed) {
doc.embedContainer = container;
@@ -427,9 +539,15 @@ export namespace Doc {
return doc;
}
}
- export function GetT<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): FieldResult<T> {
+ export function GetT<T extends FieldType>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): FieldResult<T> {
return Cast(Get(doc, key, ignoreProto), ctor) as FieldResult<T>;
}
+ export function isTemplateDoc(doc: Doc) {
+ return GetT(doc, 'isTemplateDoc', 'boolean', true);
+ }
+ export function isTemplateForField(doc: Doc) {
+ return GetT(doc, 'isTemplateForField', 'string', true);
+ }
export function IsDataProto(doc: Doc) {
return GetT(doc, 'isDataDoc', 'boolean', true);
}
@@ -449,8 +567,8 @@ export namespace Doc {
// 2) if the data doc has the field, then it's written there.
// 3) if neither already has the field, then 'defaultProto' determines whether to write it to the data doc (or the embedding)
//
- export async function SetInPlace(doc: Doc, key: string, value: Field | undefined, defaultProto: boolean) {
- if (key.startsWith('_')) key = key.substring(1);
+ export async function SetInPlace(doc: Doc, keyIn: string, value: FieldType | undefined, defaultProto: boolean) {
+ const key = keyIn.startsWith('_') ? keyIn.substring(1) : keyIn;
const hasProto = doc[DocData] !== doc ? doc[DocData] : undefined;
const onDeleg = Object.getOwnPropertyNames(doc).indexOf(key) !== -1;
const onProto = hasProto && Object.getOwnPropertyNames(hasProto).indexOf(key) !== -1;
@@ -467,7 +585,6 @@ export namespace Doc {
}
return protos;
}
-
/**
* This function is intended to model Object.assign({}, {}) [https://mzl.la/1Mo3l21], which copies
* the values of the properties of a source object into the target.
@@ -479,17 +596,15 @@ export namespace Doc {
* @param fields the fields to project onto the target. Its type signature defines a mapping from some string key
* to a potentially undefined field, where each entry in this mapping is optional.
*/
- export function assign<K extends string>(doc: Doc, fields: Partial<Record<K, Opt<Field>>>, skipUndefineds: boolean = false, isInitializing = false) {
+ export function assign<K extends string>(doc: Doc, fields: Partial<Record<K, Opt<FieldType>>>, skipUndefineds: boolean = false, isInitializing = false) {
isInitializing && (doc[Initializing] = true);
- for (const key in fields) {
- if (fields.hasOwnProperty(key)) {
- const value = fields[key];
- if (!skipUndefineds || value !== undefined) {
- // Do we want to filter out undefineds?
- doc[key] = value;
- }
+ Object.keys(fields).forEach(key => {
+ const value = (fields as any)[key];
+ if (!skipUndefineds || value !== undefined) {
+ // Do we want to filter out undefineds?
+ doc[key] = value;
}
- }
+ });
isInitializing && (doc[Initializing] = false);
return doc;
}
@@ -536,7 +651,7 @@ export namespace Doc {
* @returns true if successful, false otherwise.
*/
export function RemoveDocFromList(listDoc: Doc, fieldKey: string | undefined, doc: Doc, ignoreProto = false) {
- const key = fieldKey ? fieldKey : Doc.LayoutFieldKey(listDoc);
+ const key = fieldKey || Doc.LayoutFieldKey(listDoc);
const list = Doc.Get(listDoc, key, ignoreProto) === undefined ? (listDoc[DocData][key] = new List<Doc>()) : Cast(listDoc[key], listSpec(Doc));
if (list) {
const ind = list.indexOf(doc);
@@ -553,7 +668,7 @@ export namespace Doc {
* @returns true if successful, false otherwise.
*/
export function AddDocToList(listDoc: Doc, fieldKey: string | undefined, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean, ignoreProto?: boolean) {
- const key = fieldKey ? fieldKey : Doc.LayoutFieldKey(listDoc);
+ const key = fieldKey || Doc.LayoutFieldKey(listDoc);
const list = Doc.Get(listDoc, key, ignoreProto) === undefined ? (listDoc[DocData][key] = new List<Doc>()) : Cast(listDoc[key], listSpec(Doc));
if (list) {
if (!allowDuplicates) {
@@ -570,6 +685,7 @@ export namespace Doc {
if (reversed) list.splice(0, 0, doc);
else list.push(doc);
} else {
+ // eslint-disable-next-line no-lonely-if
if (reversed) list.splice(before ? list.length - ind + 1 : list.length - ind, 0, doc);
else list.splice(before ? ind : ind + 1, 0, doc);
}
@@ -601,7 +717,7 @@ export namespace Doc {
embedding.createdFrom = doc;
embedding.proto_embeddingId = doc[DocData].proto_embeddingId = Doc.GetEmbeddings(doc).length - 1;
!Doc.GetT(embedding, 'title', 'string', true) && (embedding.title = ComputedField.MakeFunction(`renameEmbedding(this)`));
- embedding.author = Doc.CurrentUserEmail;
+ embedding.author = ClientUtils.CurrentUserEmail();
return embedding;
}
@@ -609,7 +725,7 @@ export namespace Doc {
export function BestEmbedding(doc: Doc) {
const dataDoc = doc[DocData];
const availableEmbeddings = Doc.GetEmbeddings(dataDoc);
- const bestEmbedding = [...(dataDoc !== doc ? [doc] : []), ...availableEmbeddings].find(doc => !doc.embedContainer && doc.author === Doc.CurrentUserEmail);
+ const bestEmbedding = [...(dataDoc !== doc ? [doc] : []), ...availableEmbeddings].find(d => !d.embedContainer && d.author === ClientUtils.CurrentUserEmail());
bestEmbedding && Doc.AddEmbedding(doc, doc);
return bestEmbedding ?? Doc.MakeEmbedding(doc);
}
@@ -627,7 +743,7 @@ export namespace Doc {
cloneLinks: boolean,
cloneTemplates: boolean
): Promise<Doc> {
- if (Doc.IsBaseProto(doc) || ((Doc.Get(doc, 'isTemplateDoc', true) || Doc.Get(doc, 'isTemplateForField', true)) && !cloneTemplates)) {
+ if (Doc.IsBaseProto(doc) || ((Doc.isTemplateDoc(doc) || Doc.isTemplateForField(doc)) && !cloneTemplates)) {
return doc;
}
if (cloneMap.get(doc[Id])) return cloneMap.get(doc[Id])!;
@@ -637,37 +753,39 @@ export namespace Doc {
await Promise.all(
Object.keys(doc).map(async key => {
if (filter.includes(key)) return;
- const assignKey = (val: any) => (copy[key] = val);
+ const assignKey = (val: any) => {
+ copy[key] = val;
+ };
const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
const field = ProxyField.WithoutProxy(() => doc[key]);
- const copyObjectField = async (field: ObjectField) => {
+ const copyObjectField = async (objField: ObjectField) => {
const list = await Cast(doc[key], listSpec(Doc));
const docs = list && (await DocListCastAsync(list))?.filter(d => d instanceof Doc);
if (docs !== undefined && docs.length) {
const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, pruneDocs, cloneLinks, cloneTemplates)));
assignKey(new List<Doc>(clones));
} else {
- assignKey(ObjectField.MakeCopy(field));
- if (field instanceof RichTextField) {
- if (DocsInTextFieldIds.some(id => field.Data.includes(`"${id}":`))) {
+ assignKey(ObjectField.MakeCopy(objField));
+ if (objField instanceof RichTextField) {
+ if (DocsInTextFieldIds.some(id => objField.Data.includes(`"${id}":`))) {
const docidsearch = new RegExp('(' + DocsInTextFieldIds.map(exp => '(' + exp + ')').join('|') + ')":"([a-z-A-Z0-9_]*)"', 'g');
- const rawdocids = field.Data.match(docidsearch);
+ const rawdocids = objField.Data.match(docidsearch);
const docids = rawdocids?.map((str: string) =>
DocsInTextFieldIds.reduce((output, exp) => output.replace(new RegExp(`${exp}":`, 'g'), ''), str)
.replace(/"/g, '')
.trim()
);
const results = docids && (await DocServer.GetRefFields(docids));
- const docs = results && Array.from(Object.keys(results)).map(key => DocCast(results[key]));
- docs?.map(doc => doc && Doc.makeClone(doc, cloneMap, linkMap, rtfs, exclusions, pruneDocs, cloneLinks, cloneTemplates));
- rtfs.push({ copy, key, field });
+ const rdocs = results && Array.from(Object.keys(results)).map(rkey => DocCast(results[rkey]));
+ rdocs?.map(d => d && Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, pruneDocs, cloneLinks, cloneTemplates));
+ rtfs.push({ copy, key, field: objField });
}
}
}
};
const docAtKey = doc[key];
if (key === 'author') {
- assignKey(Doc.CurrentUserEmail);
+ assignKey(ClientUtils.CurrentUserEmail());
} else if (docAtKey instanceof Doc) {
if (pruneDocs.includes(docAtKey)) {
// prune doc and do nothing
@@ -676,7 +794,7 @@ export namespace Doc {
(key.includes('layout[') ||
key.startsWith('layout') || //
['embedContainer', 'annotationOn', 'proto'].includes(key) ||
- (['link_anchor_1', 'link_anchor_2'].includes(key) && doc.author === Doc.CurrentUserEmail))
+ (['link_anchor_1', 'link_anchor_2'].includes(key) && doc.author === ClientUtils.CurrentUserEmail()))
) {
assignKey(await Doc.makeClone(docAtKey, cloneMap, linkMap, rtfs, exclusions, pruneDocs, cloneLinks, cloneTemplates));
} else {
@@ -689,7 +807,8 @@ export namespace Doc {
} else if (field instanceof ObjectField) {
await copyObjectField(field);
} else if (field instanceof Promise) {
- debugger; //This shouldn't happen...
+ // eslint-disable-next-line no-debugger
+ debugger; // This shouldn't happen...
} else {
assignKey(field);
}
@@ -716,11 +835,11 @@ export namespace Doc {
visited.add(clone);
Object.keys(clone)
.filter(key => key !== 'cloneOf')
- .map(key => {
+ .forEach(key => {
const docAtKey = DocCast(clone[key]);
if (docAtKey && !Doc.IsSystem(docAtKey)) {
if (!Array.from(cloneMap.values()).includes(docAtKey)) {
- clone[key] = !cloneTemplates && (Doc.Get(docAtKey, 'isTemplateDoc', true) || Doc.Get(docAtKey, 'isTemplateForField', true)) ? docAtKey : cloneMap.get(docAtKey[Id]);
+ clone[key] = !cloneTemplates && (Doc.isTemplateDoc(docAtKey) || Doc.isTemplateForField(docAtKey)) ? docAtKey : cloneMap.get(docAtKey[Id]);
} else {
repairClone(docAtKey, cloneMap, cloneTemplates, visited);
}
@@ -735,16 +854,16 @@ export namespace Doc {
export async function MakeClone(doc: Doc, cloneLinks = true, cloneTemplates = true, cloneMap: Map<string, Doc> = new Map()) {
const linkMap = new Map<string, Doc>();
const rtfMap: { copy: Doc; key: string; field: RichTextField }[] = [];
- const copy = await Doc.makeClone(doc, cloneMap, linkMap, rtfMap, ['cloneOf'], doc.embedContainer ? [DocCast(doc.embedContainer)] : [], cloneLinks, cloneTemplates);
+ const clone = await Doc.makeClone(doc, cloneMap, linkMap, rtfMap, ['cloneOf'], doc.embedContainer ? [DocCast(doc.embedContainer)] : [], cloneLinks, cloneTemplates);
const repaired = new Set<Doc>();
const linkedDocs = Array.from(linkMap.values());
- linkedDocs.map((link: Doc) => LinkManager.Instance.addLink(link, true));
- rtfMap.map(({ copy, key, field }) => {
- const replacer = (match: any, attr: string, id: string, offset: any, string: any) => {
+ 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 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: any, href: string, id: string /* , offset: any, string: any */) => {
const mapped = cloneMap.get(id);
return href + (mapped ? mapped[Id] : id);
};
@@ -753,86 +872,8 @@ export namespace Doc {
copy[key] = new RichTextField(field.Data.replace(docidsearch, replacer).replace(re, replacer2), field.Text);
});
const clonedDocs = [...Array.from(cloneMap.values()), ...linkedDocs];
- clonedDocs.map(clone => Doc.repairClone(clone, cloneMap, cloneTemplates, repaired));
- return { clone: copy, map: cloneMap, linkMap };
- }
-
- export async function Zip(doc: Doc, zipFilename = 'dashExport.zip') {
- const { clone, map, linkMap } = await Doc.MakeClone(doc);
- const proms = new Set<string>();
- function replacer(key: any, value: any) {
- if (key && ['branchOf', 'cloneOf', 'cursors'].includes(key)) return undefined;
- if (value?.__type === 'image') {
- const extension = value.url.replace(/.*\./, '');
- proms.add(value.url.replace('.' + extension, '_o.' + extension));
- return SerializationHelper.Serialize(new ImageField(value.url));
- }
- if (value?.__type === 'pdf') {
- proms.add(value.url);
- return SerializationHelper.Serialize(new PdfField(value.url));
- }
- if (value?.__type === 'audio') {
- proms.add(value.url);
- return SerializationHelper.Serialize(new AudioField(value.url));
- }
- if (value?.__type === 'video') {
- proms.add(value.url);
- return SerializationHelper.Serialize(new VideoField(value.url));
- }
- if (
- value instanceof Doc ||
- value instanceof ScriptField ||
- value instanceof RichTextField ||
- value instanceof InkField ||
- value instanceof CsvField ||
- value instanceof WebField ||
- value instanceof DateField ||
- value instanceof ProxyField ||
- value instanceof ComputedField
- ) {
- return SerializationHelper.Serialize(value);
- }
- if (value instanceof Array && key !== ListFieldName && key !== InkField.InkDataFieldName) return { fields: value, __type: 'list' };
- return value;
- }
-
- const docs: { [id: string]: any } = {};
- const links: { [id: string]: any } = {};
- Array.from(map.entries()).forEach(f => (docs[f[0]] = f[1]));
- Array.from(linkMap.entries()).forEach(l => (links[l[0]] = l[1]));
- const jsonDocs = JSON.stringify({ id: clone[Id], docs, links }, decycle(replacer));
-
- const zip = new JSZip();
- var count = 0;
- const promArr = Array.from(proms)
- .filter(url => url?.startsWith('/files'))
- .map(url => url.replace('/', '')); // window.location.origin));
- console.log(promArr.length);
- if (!promArr.length) {
- zip.file('docs.json', jsonDocs);
- zip.generateAsync({ type: 'blob' }).then(content => saveAs(content, zipFilename));
- } 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) => {
- 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 });
- console.log(' => ' + url);
- if (++count === promArr.length) {
- zip.file('docs.json', jsonDocs);
- zip.generateAsync({ type: 'blob' }).then(content => saveAs(content, zipFilename));
- // const a = document.createElement("a");
- // const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`);
- // a.href = url;
- // a.download = `DocExport-${this.props.Document[Id]}.zip`;
- // a.click();
- }
- });
- });
+ clonedDocs.forEach(cloneDoc => Doc.repairClone(cloneDoc, cloneMap, cloneTemplates, repaired));
+ return { clone, map: cloneMap, linkMap };
}
const _pendingMap = new Set<string>();
@@ -842,7 +883,7 @@ export namespace Doc {
// of the original layout while allowing for individual layout properties to be overridden in the expanded layout.
export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc) {
// nothing to do if the layout isn't a template or we don't have a target that's different than the template
- if (!targetDoc || templateLayoutDoc === targetDoc || (!templateLayoutDoc.isTemplateForField && !templateLayoutDoc.isTemplateDoc)) {
+ if (!targetDoc || templateLayoutDoc === targetDoc || (!Doc.isTemplateForField(templateLayoutDoc) && !Doc.isTemplateDoc(templateLayoutDoc))) {
return templateLayoutDoc;
}
@@ -859,9 +900,10 @@ export namespace Doc {
expandedTemplateLayout = undefined;
_pendingMap.add(targetDoc[Id] + expandedLayoutFieldKey);
} else if (expandedTemplateLayout === undefined && !_pendingMap.has(targetDoc[Id] + expandedLayoutFieldKey)) {
- if (templateLayoutDoc.resolvedDataDoc === (targetDoc.rootDocument ?? Doc.GetProto(targetDoc))) {
+ if (templateLayoutDoc.resolvedDataDoc === targetDoc[DocData]) {
expandedTemplateLayout = templateLayoutDoc; // reuse an existing template layout if its for the same document with the same params
} else {
+ // eslint-disable-next-line no-param-reassign
templateLayoutDoc.resolvedDataDoc && (templateLayoutDoc = DocCast(templateLayoutDoc.proto, templateLayoutDoc)); // if the template has already been applied (ie, a nested template), then use the template's prototype
if (!targetDoc[expandedLayoutFieldKey]) {
_pendingMap.add(targetDoc[Id] + expandedLayoutFieldKey);
@@ -872,7 +914,7 @@ export namespace Doc {
newLayoutDoc.rootDocument = targetDoc;
newLayoutDoc.embedContainer = targetDoc;
newLayoutDoc.resolvedDataDoc = dataDoc;
- newLayoutDoc['acl-Guest'] = SharingPermissions.Edit;
+ newLayoutDoc.acl_Guest = SharingPermissions.Edit;
if (dataDoc[templateField] === undefined && (templateLayoutDoc[templateField] as any)?.length) {
dataDoc[templateField] = ObjectField.MakeCopy(templateLayoutDoc[templateField] as List<Doc>);
// ComputedField.MakeFunction(`ObjectField.MakeCopy(templateLayoutDoc["${templateField}"])`, { templateLayoutDoc: Doc.name }, { templateLayoutDoc });
@@ -895,8 +937,9 @@ export namespace Doc {
console.log('Warning: GetLayoutDataDocPair childDoc not defined');
return { layout: childDoc, data: childDoc };
}
- const resolvedDataDoc = Doc.AreProtosEqual(containerDataDoc, containerDoc) || (!childDoc.isTemplateDoc && !childDoc.isTemplateForField) ? undefined : containerDataDoc;
- return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc), data: resolvedDataDoc };
+ const resolvedDataDoc = Doc.AreProtosEqual(containerDataDoc, containerDoc) || (!Doc.isTemplateDoc(childDoc) && !Doc.isTemplateForField(childDoc)) ? undefined : containerDataDoc;
+ const templateRoot = DocCast(containerDoc?.rootDocument);
+ return { layout: Doc.expandTemplateLayout(childDoc, templateRoot), data: resolvedDataDoc };
}
export function FindReferences(infield: Doc | List<any>, references: Set<Doc>, system: boolean | undefined) {
@@ -920,7 +963,7 @@ export namespace Doc {
}
} else {
const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
- const field = key === 'author' ? Doc.CurrentUserEmail : ProxyField.WithoutProxy(() => doc[key]);
+ const field = key === 'author' ? ClientUtils.CurrentUserEmail() : ProxyField.WithoutProxy(() => doc[key]);
if (field instanceof RefField) {
if (field instanceof Doc) {
if (key === 'myLinkDatabase') {
@@ -931,6 +974,7 @@ export namespace Doc {
}
}
} else if (cfield instanceof ComputedField) {
+ /* empty */
} else if (field instanceof ObjectField) {
if (field instanceof Doc) {
Doc.FindReferences(field, references, system);
@@ -947,7 +991,8 @@ export namespace Doc {
Doc.FindReferences(field.value, references, system);
}
} else if (field instanceof Promise) {
- debugger; //This shouldn't happend...
+ // eslint-disable-next-line no-debugger
+ debugger; // This shouldn't happend...
}
}
});
@@ -966,7 +1011,7 @@ export namespace Doc {
}
} else {
const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
- const field = key === 'author' ? Doc.CurrentUserEmail : ProxyField.WithoutProxy(() => doc[key]);
+ const field = key === 'author' ? ClientUtils.CurrentUserEmail() : ProxyField.WithoutProxy(() => doc[key]);
if (field instanceof RefField) {
copy[key] = field;
} else if (cfield instanceof ComputedField) {
@@ -977,7 +1022,8 @@ export namespace Doc {
? new ProxyField(Doc.MakeCopy(doc[key] as any)) // copy the expanded render template
: ObjectField.MakeCopy(field);
} else if (field instanceof Promise) {
- debugger; //This shouldn't happend...
+ // eslint-disable-next-line no-debugger
+ debugger; // This shouldn't happend...
} else {
copy[key] = field;
}
@@ -1004,10 +1050,12 @@ export namespace Doc {
delegate[Initializing] = true;
updateCachedAcls(delegate);
delegate.proto = doc;
- delegate.author = Doc.CurrentUserEmail;
+ delegate.author = ClientUtils.CurrentUserEmail();
Object.keys(doc)
- .filter(key => key.startsWith('acl'))
- .forEach(key => (delegate[key] = doc[key]));
+ .filter(key => key.startsWith('acl_'))
+ .forEach(key => {
+ delegate[key] = doc[key];
+ });
title && (delegate.title = title);
delegate[Initializing] = false;
if (!Doc.IsSystem(doc)) Doc.AddEmbedding(doc, delegate);
@@ -1020,27 +1068,20 @@ export namespace Doc {
// (ie, the 'data' doc), and then creates another delegate of that (ie, the 'layout' doc).
// This is appropriate if you're trying to create a document that behaves like all
// regularly created documents (e.g, text docs, pdfs, etc which all have data/layout docs)
- export function MakeDelegateWithProto(doc: Doc, id?: string, title?: string): Doc {
- const delegateProto = new Doc();
- delegateProto[Initializing] = true;
- delegateProto.proto = doc;
- delegateProto.author = Doc.CurrentUserEmail;
- delegateProto.isDataDoc = true;
- title && (delegateProto.title = title);
- const delegate = new Doc(id, true);
- delegate[Initializing] = true;
- delegate.proto = delegateProto;
- delegate.author = Doc.CurrentUserEmail;
- delegate[Initializing] = false;
- delegateProto[Initializing] = false;
- return delegate;
+ export function MakeDelegateWithProto(doc: Doc /* , id?: string, title?: string */) {
+ const ndoc = Doc.ApplyTemplate(doc);
+ if (ndoc) {
+ Doc.GetProto(ndoc).isDataDoc = true;
+ ndoc && (Doc.GetProto(ndoc).proto = doc);
+ }
+ return ndoc;
}
let _applyCount: number = 0;
export function ApplyTemplate(templateDoc: Doc) {
if (templateDoc) {
const proto = new Doc();
- proto.author = Doc.CurrentUserEmail;
+ proto.author = ClientUtils.CurrentUserEmail();
const target = Doc.MakeDelegate(proto);
const targetKey = StrCast(templateDoc.layout_fieldKey, 'layout');
const applied = ApplyTemplateTo(templateDoc, target, targetKey, templateDoc.title + '(...' + _applyCount++ + ')');
@@ -1076,7 +1117,6 @@ export namespace Doc {
!keepFieldKey && (templateField.title = metadataFieldKey);
const templateFieldValue = templateField[metadataFieldKey] || templateField[Doc.LayoutFieldKey(templateField)];
- const templateCaptionValue = templateField.caption;
// move any data that the template field had been rendering over to the template doc so that things will still be rendered
// when the template field is adjusted to point to the new metadatafield key.
// note 1: if the template field contained a list of documents, each of those documents will be converted to templates as well.
@@ -1096,7 +1136,7 @@ export namespace Doc {
// converts a document id to a url path on the server
export function globalServerPath(doc: Doc | string = ''): string {
- return Utils.prepend('/doc/' + (doc instanceof Doc ? doc[Id] : doc));
+ return ClientUtils.prepend('/doc/' + (doc instanceof Doc ? doc[Id] : doc));
}
// converts a document id to a url path on the server
export function localServerPath(doc?: Doc): string {
@@ -1135,7 +1175,8 @@ export namespace Doc {
return doc[StrCast(doc.layout_fieldKey, 'layout')];
}
export function LayoutFieldKey(doc: Doc, templateLayoutString?: string): string {
- return StrCast(templateLayoutString || Doc.Layout(doc).layout).split("'")[1]; // bcz: TODO check on this . used to always reference 'layout', now it uses the layout speicfied by the current layout_fieldKey
+ const match = StrCast(templateLayoutString || Doc.Layout(doc).layout).match(/fieldKey={'([^']+)'}/);
+ return match?.[1] || ''; // bcz: TODO check on this . used to always reference 'layout', now it uses the layout speicfied by the current layout_fieldKey
}
export function NativeAspect(doc: Doc, dataDoc?: Doc, useDim?: boolean) {
return Doc.NativeWidth(doc, dataDoc, useDim) / (Doc.NativeHeight(doc, dataDoc, useDim) || 1);
@@ -1161,7 +1202,9 @@ export namespace Doc {
return manager._searchQuery;
}
export function SetSearchQuery(query: string) {
- runInAction(() => (manager._searchQuery = query));
+ runInAction(() => {
+ manager._searchQuery = query;
+ });
}
export function UserDoc(): Doc {
return manager._user_doc;
@@ -1173,12 +1216,13 @@ export namespace Doc {
return Cast(Doc.UserDoc().myLinkDatabase, Doc, null);
}
export function SetUserDoc(doc: Doc) {
+ // eslint-disable-next-line no-return-assign
return (manager._user_doc = doc);
}
- const isSearchMatchCache = computedFn(function IsSearchMatch(doc: Doc) {
- return brushManager.SearchMatchDoc.has(doc) ? brushManager.SearchMatchDoc.get(doc) : brushManager.SearchMatchDoc.has(doc[DocData]) ? brushManager.SearchMatchDoc.get(doc[DocData]) : undefined;
- });
+ const isSearchMatchCache = computedFn((doc: Doc) =>
+ (brushManager.SearchMatchDoc.has(doc) ? brushManager.SearchMatchDoc.get(doc) :
+ brushManager.SearchMatchDoc.has(doc[DocData]) ? brushManager.SearchMatchDoc.get(doc[DocData]) : undefined)); // prettier-ignore
export function IsSearchMatch(doc: Doc) {
return isSearchMatchCache(doc);
}
@@ -1224,11 +1268,16 @@ export namespace Doc {
return BrushDoc(doc, true);
}
export function UnBrushAllDocs() {
- Array.from(brushManager.BrushedDoc).forEach(action(doc => (doc[Brushed] = false)));
+ Array.from(brushManager.BrushedDoc).forEach(
+ action(doc => {
+ doc[Brushed] = false;
+ })
+ );
}
- let UnhighlightWatchers: (() => void)[] = [];
- export let UnhighlightTimer: any;
+ const UnhighlightWatchers: (() => void)[] = [];
+ let UnhighlightTimer: any;
+ export function IsUnhighlightTimerSet() { return UnhighlightTimer; } // prettier-ignore
export function AddUnHighlightWatcher(watcher: () => void) {
if (UnhighlightTimer) {
UnhighlightWatchers.push(watcher);
@@ -1242,42 +1291,48 @@ export namespace Doc {
highlightedDocs.forEach(doc => Doc.UnHighlightDoc(doc));
document.removeEventListener('pointerdown', linkFollowUnhighlight);
}
- export function linkFollowHighlight(destDoc: Doc | Doc[], dataAndDisplayDocs = true, presentation_effect?: Doc) {
+ export function linkFollowHighlight(destDoc: Doc | Doc[], dataAndDisplayDocs = true, presentationEffect?: Doc) {
linkFollowUnhighlight();
- (destDoc instanceof Doc ? [destDoc] : destDoc).forEach(doc => Doc.HighlightDoc(doc, dataAndDisplayDocs, presentation_effect));
+ toList(destDoc).forEach(doc => Doc.HighlightDoc(doc, dataAndDisplayDocs, presentationEffect));
document.removeEventListener('pointerdown', linkFollowUnhighlight);
document.addEventListener('pointerdown', linkFollowUnhighlight);
if (UnhighlightTimer) clearTimeout(UnhighlightTimer);
+ const presTransition = Number(presentationEffect?.presentation_transition);
+ const duration = isNaN(presTransition) ? 5000 : presTransition;
UnhighlightTimer = window.setTimeout(() => {
linkFollowUnhighlight();
UnhighlightTimer = 0;
- }, 5000);
+ }, duration);
}
- export var highlightedDocs = new ObservableSet<Doc>();
+ export const highlightedDocs = new ObservableSet<Doc>();
export function IsHighlighted(doc: Doc) {
if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(doc[DocData]) === AclPrivate || doc.opacity === 0) return false;
return doc[Highlight] || doc[DocData][Highlight];
}
- export function HighlightDoc(doc: Doc, dataAndDisplayDocs = true, presentation_effect?: Doc) {
+ export function HighlightDoc(doc: Doc, dataAndDisplayDocs = true, presentationEffect?: Doc) {
runInAction(() => {
highlightedDocs.add(doc);
doc[Highlight] = true;
- doc[Animation] = presentation_effect;
- if (dataAndDisplayDocs) {
+ doc[Animation] = presentationEffect;
+ if (dataAndDisplayDocs && !doc.resolvedDataDoc) {
+ // if doc is a layout template then we don't want to highlight the proto since that will be the entire template, not just the specific layout field
highlightedDocs.add(doc[DocData]);
doc[DocData][Highlight] = true;
+ // want to highlight the targets of presentation docs explicitly since following a pres target does not highlight PDf <Annotations> which are not DocumentViews
+ if (doc.presentation_targetDoc) DocCast(doc.presentation_targetDoc)[Highlight] = true;
}
});
}
/// if doc is defined, then it is unhighlighted, otherwise all highlighted docs are unhighlighted
- export function UnHighlightDoc(doc?: Doc) {
+ export function UnHighlightDoc(docs?: Doc) {
runInAction(() => {
- (doc ? [doc] : Array.from(highlightedDocs)).forEach(doc => {
+ (docs ? [docs] : Array.from(highlightedDocs)).forEach(doc => {
highlightedDocs.delete(doc);
highlightedDocs.delete(doc[DocData]);
doc[Highlight] = doc[DocData][Highlight] = false;
doc[Animation] = undefined;
+ if (doc.presentation_targetDoc) DocCast(doc.presentation_targetDoc)[Highlight] = false;
});
});
}
@@ -1351,6 +1406,7 @@ export namespace Doc {
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()) {
+ // eslint-disable-next-line no-param-reassign
if (toggle) modifiers = 'remove';
else return;
}
@@ -1375,9 +1431,12 @@ export namespace Doc {
return [Number(childFiltersByRanges[i + 1]), Number(childFiltersByRanges[i + 2])];
}
}
+ return undefined;
}
export function assignDocToField(doc: Doc, field: string, id: string) {
- DocServer.GetRefField(id).then(layout => layout instanceof Doc && (doc[field] = layout));
+ DocServer.GetRefField(id).then(layout => {
+ layout instanceof Doc && (doc[field] = layout);
+ });
return id;
}
@@ -1397,20 +1456,6 @@ export namespace Doc {
});
}
- export function styleFromLayoutString(doc: Doc, props: FieldViewProps, scale: number) {
- const style: { [key: string]: any } = {};
- const divKeys = ['width', 'height', 'fontSize', 'transform', 'left', 'backgroundColor', 'left', 'right', 'top', 'bottom', 'pointerEvents', 'position'];
- const replacer = (match: any, expr: string, offset: any, string: any) => {
- // bcz: this executes a script to convert a property expression string: { script } into a value
- return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: 'number' })?.script.run({ this: doc, self: doc, scale }).result?.toString() ?? '';
- };
- divKeys.map((prop: string) => {
- const p = (props as any)[prop];
- typeof p === 'string' && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
- });
- return style;
- }
-
export function Paste(docids: string[], clone: boolean, addDocument: (doc: Doc | Doc[]) => boolean, ptx?: number, pty?: number, newPoint?: number[]) {
DocServer.GetRefFields(docids).then(async fieldlist => {
const list = Array.from(Object.values(fieldlist))
@@ -1466,6 +1511,7 @@ export namespace Doc {
case DocumentType.EQUATION: return 'calculator';
case DocumentType.SIMULATION: return 'rocket';
case DocumentType.CONFIG: return 'folder-closed';
+ default:
}
return 'question';
}
@@ -1476,7 +1522,7 @@ export namespace Doc {
// If they are not remapped, loading the file will overwrite any existing documents with those ids
//
export async function importDocument(file: File, remap = false) {
- const upload = Utils.prepend('/uploadDoc');
+ const upload = ClientUtils.prepend('/uploadDoc');
const formData = new FormData();
if (file) {
formData.append('file', file);
@@ -1484,12 +1530,13 @@ export namespace Doc {
const response = await fetch(upload, { method: 'POST', body: formData });
const json = await response.json();
if (json !== 'error') {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
const docs = await DocServer.GetRefFields(json.docids as string[]);
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])
- .forEach(link => link instanceof Doc && LinkManager.Instance.addLink(link));
+ .forEach(link => link instanceof Doc && Doc.AddLink?.(link));
return doc;
}
}
@@ -1549,6 +1596,7 @@ export namespace Doc {
*/
export function FromJson({ data, title, appendToExisting, excludeEmptyObjects }: JsonConversionOpts): Opt<Doc> {
if (excludeEmptyObjects === undefined) {
+ // eslint-disable-next-line no-param-reassign
excludeEmptyObjects = true;
}
if (data === undefined || data === null || ![...primitives, 'object'].includes(typeof data)) {
@@ -1588,12 +1636,12 @@ export namespace Doc {
if (hasEntries || !excludeEmptyObjects) {
const resolved = target ?? new Doc();
if (hasEntries) {
- let result: Opt<Field>;
- Object.keys(object).map(key => {
+ Object.keys(object).forEach(key => {
// if excludeEmptyObjects is true, any qualifying conversions from toField will
// be undefined, and thus the results that would have
// otherwise been empty (List or Doc)s will just not be written
- if ((result = toField(object[key], excludeEmptyObjects, key))) {
+ const result = toField(object[key], excludeEmptyObjects, key);
+ if (result) {
resolved[key] = result;
}
});
@@ -1601,6 +1649,7 @@ export namespace Doc {
title && (resolved.title = title);
return resolved;
}
+ return undefined;
};
/**
@@ -1610,19 +1659,22 @@ 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<any>, excludeEmptyObjects: boolean): Opt<List<Field>> => {
+ const convertList = (list: Array<any>, excludeEmptyObjects: boolean): Opt<List<FieldType>> => {
const target = new List();
- let result: Opt<Field>;
+ let result: Opt<FieldType>;
// if excludeEmptyObjects is true, any qualifying conversions from toField will
// be undefined, and thus the results that would have
// otherwise been empty (List or Doc)s will just not be written
- list.map(item => (result = toField(item, excludeEmptyObjects)) && target.push(result));
+ list.forEach(item => {
+ (result = toField(item, excludeEmptyObjects)) && target.push(result);
+ });
if (target.length || !excludeEmptyObjects) {
return target;
}
+ return undefined;
};
- const toField = (data: any, excludeEmptyObjects: boolean, title?: string): Opt<Field> => {
+ const toField = (data: any, excludeEmptyObjects: boolean, title?: string): Opt<FieldType> => {
if (data === null || data === undefined) {
return undefined;
}
@@ -1637,58 +1689,102 @@ export namespace Doc {
}
}
+export function RTFIsFragment(html: string) {
+ return html.indexOf('data-pm-slice') !== -1;
+}
+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;
+ }
+ return '';
+}
+export function GetDocFromUrl(url: string) {
+ return url.startsWith(document.location.origin) ? new URL(url).pathname.split('doc/').lastElement() : ''; // docId
+}
+
+let activeAudioLinker: (f: () => Doc | undefined, broadcast?: boolean) => (Doc | undefined)[];
+export function SetActiveAudioLinker(func: (f: () => Doc | undefined, broadcast?: boolean) => (Doc | undefined)[]) {
+ activeAudioLinker = func;
+}
+export function CreateLinkToActiveAudio(func: () => Doc | undefined, broadcast?: boolean) {
+ return activeAudioLinker(func, broadcast);
+}
+
export function IdToDoc(id: string) {
return DocCast(DocServer.GetCachedRefField(id));
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function idToDoc(id: string): any {
return IdToDoc(id);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function renameEmbedding(doc: any) {
return StrCast(doc[DocData].title).replace(/\([0-9]*\)/, '') + `(${doc.proto_embeddingId})`;
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function getProto(doc: any) {
return Doc.GetProto(doc);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function getDocTemplate(doc?: any) {
return Doc.getDocTemplate(doc);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function getEmbedding(doc: any) {
return Doc.MakeEmbedding(doc);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function getCopy(doc: any, copyProto: any) {
- return doc.isTemplateDoc ? Doc.ApplyTemplate(doc) : Doc.MakeCopy(doc, copyProto);
+ return doc.isTemplateDoc ? Doc.MakeDelegateWithProto(doc) : Doc.MakeCopy(doc, copyProto);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function copyField(field: any) {
return Field.Copy(field);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function docList(field: any) {
return DocListCast(field);
});
+// eslint-disable-next-line prefer-arrow-callback
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) {
return Doc.SetInPlace(doc, field, value, false);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function sameDocs(doc1: any, doc2: any) {
return Doc.AreProtosEqual(doc1, doc2);
});
+// eslint-disable-next-line prefer-arrow-callback
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 {
return Cast(doc, Doc);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function activePresentationItem() {
const curPres = Doc.ActivePresentation;
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') {
Doc.setDocFilter(container, key, value, modifiers);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function setDocRangeFilter(container: Doc, key: string, range: number[]) {
Doc.setDocRangeFilter(container, key, range);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function toJavascriptString(str: string) {
- return Field.toJavascriptString(str as Field);
+ return Field.toJavascriptString(str as FieldType);
+});
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function RtfField() {
+ return RichTextField.RTFfield();
});
diff --git a/src/fields/DocSymbols.ts b/src/fields/DocSymbols.ts
index 64d657e4f..837fcc90e 100644
--- a/src/fields/DocSymbols.ts
+++ b/src/fields/DocSymbols.ts
@@ -1,8 +1,26 @@
-export const DocUpdated = Symbol('DocUpdated');
+// Symbols for fundamental Doc operations such as: permissions, field and proxy access and server interactions
+export const AclPrivate = Symbol('DocAclOwnerOnly');
+export const AclReadonly = Symbol('DocAclReadOnly');
+export const AclAugment = Symbol('DocAclAugment');
+export const AclSelfEdit = Symbol('DocAclSelfEdit');
+export const AclEdit = Symbol('DocAclEdit');
+export const AclAdmin = Symbol('DocAclAdmin');
+export const DocAcl = Symbol('DocAcl');
+export const CachedUpdates = Symbol('DocCachedUpdates');
+export const UpdatingFromServer = Symbol('DocUpdatingFromServer');
+export const ForceServerWrite = Symbol('DocForceServerWrite');
export const Self = Symbol('DocSelf');
export const SelfProxy = Symbol('DocSelfProxy');
export const FieldKeys = Symbol('DocFieldKeys');
export const FieldTuples = Symbol('DocFieldTuples');
+export const Initializing = Symbol('DocInitializing');
+
+// Symbols for core Dash document model including data docs, layout docs, and links
+export const DocData = Symbol('DocData');
+export const DocLayout = Symbol('DocLayout');
+export const DirectLinks = Symbol('DocDirectLinks');
+
+// Symbols for view related operations for Documents
export const AudioPlay = Symbol('DocAudioPlay');
export const Width = Symbol('DocWidth');
export const Height = Symbol('DocHeight');
@@ -10,22 +28,7 @@ export const Animation = Symbol('DocAnimation');
export const Highlight = Symbol('DocHighlight');
export const DocViews = Symbol('DocViews');
export const Brushed = Symbol('DocBrushed');
-export const DocData = Symbol('DocData');
-export const DocLayout = Symbol('DocLayout');
-export const DocFields = Symbol('DocFields');
export const DocCss = Symbol('DocCss');
-export const DocAcl = Symbol('DocAcl');
export const TransitionTimer = Symbol('DocTransitionTimer');
-export const DirectLinks = Symbol('DocDirectLinks');
-export const AclPrivate = Symbol('DocAclOwnerOnly');
-export const AclReadonly = Symbol('DocAclReadOnly');
-export const AclAugment = Symbol('DocAclAugment');
-export const AclSelfEdit = Symbol('DocAclSelfEdit');
-export const AclEdit = Symbol('DocAclEdit');
-export const AclAdmin = Symbol('DocAclAdmin');
-export const UpdatingFromServer = Symbol('DocUpdatingFromServer');
-export const Initializing = Symbol('DocInitializing');
-export const ForceServerWrite = Symbol('DocForceServerWrite');
-export const CachedUpdates = Symbol('DocCachedUpdates');
export const DashVersion = 'v0.8.0';
diff --git a/src/fields/HtmlField.ts b/src/fields/HtmlField.ts
index b67f0f7e9..536f5ce4c 100644
--- a/src/fields/HtmlField.ts
+++ b/src/fields/HtmlField.ts
@@ -1,7 +1,7 @@
+import { primitive, serializable } from 'serializr';
import { Deserializable } from '../client/util/SerializationHelper';
-import { serializable, primitive } from 'serializr';
-import { ObjectField } from './ObjectField';
import { Copy, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
+import { ObjectField } from './ObjectField';
@Deserializable('html')
export class HtmlField extends ObjectField {
diff --git a/src/fields/IconField.ts b/src/fields/IconField.ts
index 4d2badb68..33e5be7af 100644
--- a/src/fields/IconField.ts
+++ b/src/fields/IconField.ts
@@ -1,5 +1,5 @@
-import { Deserializable } from '../client/util/SerializationHelper';
import { serializable, primitive } from 'serializr';
+import { Deserializable } from '../client/util/SerializationHelper';
import { ObjectField } from './ObjectField';
import { Copy, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts
index b3e01229a..46704eb2b 100644
--- a/src/fields/InkField.ts
+++ b/src/fields/InkField.ts
@@ -2,6 +2,7 @@ import { Bezier } from 'bezier-js';
import { alias, createSimpleSchema, list, object, serializable } from 'serializr';
import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
import { Deserializable } from '../client/util/SerializationHelper';
+import { PointData } from '../pen-gestures/GestureTypes';
import { Copy, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
import { ObjectField } from './ObjectField';
@@ -16,12 +17,6 @@ export enum InkTool {
PresentationPin = 'presentationpin',
}
-// Defines a point in an ink as a pair of x- and y-coordinates.
-export interface PointData {
- X: number;
- Y: number;
-}
-
export type Segment = Array<Bezier>;
// Defines an ink as an array of points.
@@ -62,10 +57,10 @@ const strokeDataSchema = createSimpleSchema({
'*': true,
});
+export const InkDataFieldName = '__inkData';
@Deserializable('ink')
export class InkField extends ObjectField {
- public static InkDataFieldName = '__inkData';
- @serializable(alias(InkField.InkDataFieldName, list(object(strokeDataSchema))))
+ @serializable(alias(InkDataFieldName, list(object(strokeDataSchema))))
readonly inkData: InkData;
constructor(data: InkData) {
@@ -94,6 +89,17 @@ export class InkField extends ObjectField {
[ToString]() {
return 'InkField';
}
+
+ public static getBounds(stroke: InkData, pad?: boolean) {
+ const padding = pad ? [-20000, 20000] : [];
+ const xs = [...padding, ...stroke.map(p => p.X)];
+ const ys = [...padding, ...stroke.map(p => p.Y)];
+ const right = Math.max(...xs);
+ const left = Math.min(...xs);
+ const bottom = Math.max(...ys);
+ const top = Math.min(...ys);
+ return { right, left, bottom, top, width: right - left, height: bottom - top };
+ }
}
ScriptingGlobals.add('InkField', InkField);
diff --git a/src/fields/List.ts b/src/fields/List.ts
index ec31f7dae..38c47d546 100644
--- a/src/fields/List.ts
+++ b/src/fields/List.ts
@@ -1,31 +1,28 @@
import { action, computed, makeObservable, observable } from 'mobx';
-import { alias, list, serializable } from 'serializr';
-import { DocServer } from '../client/DocServer';
+import { alias, list as serializrList, serializable } from 'serializr';
import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
import { Deserializable, afterDocDeserialize, autoObject } from '../client/util/SerializationHelper';
-import { Field } from './Doc';
+import { Field, FieldType, StrListCast } from './Doc';
import { FieldTuples, Self, SelfProxy } from './DocSymbols';
import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
-import { ObjectField } from './ObjectField';
+import { ObjGetRefFields, ObjectField } from './ObjectField';
import { ProxyField } from './Proxy';
import { RefField } from './RefField';
-import { listSpec } from './Schema';
-import { Cast } from './Types';
import { containedFieldChangedHandler, deleteProperty, getter, setter } from './util';
-function toObjectField(field: Field) {
+function toObjectField(field: FieldType) {
return field instanceof RefField ? new ProxyField(field) : field;
}
-function toRealField(field: Field) {
+function toRealField(field: FieldType) {
return field instanceof ProxyField ? field.value : field;
}
-type StoredType<T extends Field> = T extends RefField ? ProxyField<T> : T;
+type StoredType<T extends FieldType> = T extends RefField ? ProxyField<T> : T;
export const ListFieldName = 'fields';
@Deserializable('list')
-class ListImpl<T extends Field> extends ObjectField {
+class ListImpl<T extends FieldType> extends ObjectField {
static listHandlers: any = {
/// Mutator methods
copyWithin() {
@@ -44,14 +41,14 @@ class ListImpl<T extends Field> extends ObjectField {
this[SelfProxy][FieldChanged]?.();
return field;
},
- push: action(function (this: ListImpl<any>, ...items: any[]) {
- items = items.map(toObjectField);
+ push: action(function (this: ListImpl<any>, ...itemsIn: any[]) {
+ const items = itemsIn.map(toObjectField);
const list = this[Self];
- const length = list.__fieldTuples.length;
+ const { length } = list.__fieldTuples;
for (let i = 0; i < items.length; i++) {
const item = items[i];
- //TODO Error checking to make sure parent doesn't already exist
+ // TODO Error checking to make sure parent doesn't already exist
if (item instanceof ObjectField) {
item[Parent] = list;
item[FieldChanged] = containedFieldChangedHandler(this[SelfProxy], i + length, item);
@@ -77,21 +74,21 @@ class ListImpl<T extends Field> extends ObjectField {
this[SelfProxy][FieldChanged]?.();
return res;
},
- splice: action(function (this: any, start: number, deleteCount: number, ...items: any[]) {
+ splice: action(function (this: any, start: number, deleteCount: number, ...itemsIn: any[]) {
this[Self].__realFields; // coerce retrieving entire array
- items = items.map(toObjectField);
+ const items = itemsIn.map(toObjectField);
const list = this[Self];
const removed = list.__fieldTuples.filter((item: any, 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
- //TODO Need to change indices of other fields in array
+ // TODO Error checking to make sure parent doesn't already exist
+ // TODO Need to change indices of other fields in array
if (item instanceof ObjectField) {
item[Parent] = list;
item[FieldChanged] = containedFieldChangedHandler(this, i + start, item);
}
}
- let hintArray: { val: any; index: number }[] = [];
+ const hintArray: { val: any; index: number }[] = [];
for (let i = start; i < start + deleteCount; i++) {
hintArray.push({ val: list.__fieldTuples[i], index: i });
}
@@ -107,13 +104,13 @@ class ListImpl<T extends Field> extends ObjectField {
);
return res.map(toRealField);
}),
- unshift(...items: any[]) {
- items = items.map(toObjectField);
+ unshift(...itemsIn: any[]) {
+ const items = itemsIn.map(toObjectField);
const list = this[Self];
for (let i = 0; i < items.length; i++) {
const item = items[i];
- //TODO Error checking to make sure parent doesn't already exist
- //TODO Need to change indices of other fields in array
+ // TODO Error checking to make sure parent doesn't already exist
+ // TODO Need to change indices of other fields in array
if (item instanceof ObjectField) {
item[Parent] = list;
item[FieldChanged] = containedFieldChangedHandler(this, i, item);
@@ -131,9 +128,8 @@ class ListImpl<T extends Field> extends ObjectField {
includes(valueToFind: any, fromIndex: number) {
if (valueToFind instanceof RefField) {
return this[Self].__realFields.includes(valueToFind, fromIndex);
- } else {
- return this[Self].__fieldTuples.includes(valueToFind, fromIndex);
}
+ return this[Self].__fieldTuples.includes(valueToFind, fromIndex);
},
indexOf(valueToFind: any, fromIndex: number) {
if (valueToFind instanceof RefField) {
@@ -151,9 +147,8 @@ class ListImpl<T extends Field> extends ObjectField {
lastIndexOf(valueToFind: any, fromIndex: number) {
if (valueToFind instanceof RefField) {
return this[Self].__realFields.lastIndexOf(valueToFind, fromIndex);
- } else {
- return this[Self].__fieldTuples.lastIndexOf(valueToFind, fromIndex);
}
+ return this[Self].__fieldTuples.lastIndexOf(valueToFind, fromIndex);
},
slice(begin: number, end: number) {
this[Self].__realFields;
@@ -226,7 +221,7 @@ class ListImpl<T extends Field> extends ObjectField {
},
};
static listGetter(target: any, prop: string | symbol, receiver: any): any {
- if (ListImpl.listHandlers.hasOwnProperty(prop)) {
+ if (Object.prototype.hasOwnProperty.call(ListImpl.listHandlers, prop)) {
return ListImpl.listHandlers[prop];
}
return getter(target, prop, receiver);
@@ -244,7 +239,7 @@ class ListImpl<T extends Field> extends ObjectField {
getOwnPropertyDescriptor: (target, prop) => {
if (prop in target[FieldTuples]) {
return {
- configurable: true, //TODO Should configurable be true?
+ configurable: true, // TODO Should configurable be true?
enumerable: true,
};
}
@@ -255,11 +250,13 @@ class ListImpl<T extends Field> extends ObjectField {
throw new Error("Currently properties can't be defined on documents using Object.defineProperty");
},
});
- this[SelfProxy] = list as any as List<Field>; // bcz: ugh .. don't know how to convince typesecript that list is a List
+ // eslint-disable-next-line no-use-before-define
+ this[SelfProxy] = list as any as List<FieldType>; // bcz: ugh .. don't know how to convince typesecript that list is a List
if (fields) {
this[SelfProxy].push(...fields);
}
- return list;
+ // eslint-disable-next-line no-constructor-return
+ return list; // need to return the proxy here, otherwise we don't get any of our list handler functions
}
[key: number]: T | (T extends RefField ? Promise<T> : never);
@@ -271,7 +268,7 @@ class ListImpl<T extends Field> extends ObjectField {
// 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 = DocServer.GetRefFields(unrequested.map(p => p.fieldId));
+ 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]))));
@@ -282,20 +279,20 @@ class ListImpl<T extends Field> extends ObjectField {
return this[FieldTuples].map(toRealField);
}
- @serializable(alias(ListFieldName, list(autoObject(), { afterDeserialize: afterDocDeserialize })))
+ @serializable(alias(ListFieldName, serializrList(autoObject(), { afterDeserialize: afterDocDeserialize })))
private get __fieldTuples() {
return this[FieldTuples];
}
private set __fieldTuples(value) {
this[FieldTuples] = value;
- for (const key in value) {
- const item = value[key];
+ Object.keys(value).forEach(key => {
+ const item = value[Number(key)];
if (item instanceof ObjectField) {
item[Parent] = this[Self];
item[FieldChanged] = containedFieldChangedHandler(this[SelfProxy], Number(key), item);
}
- }
+ });
}
[Copy]() {
@@ -308,24 +305,24 @@ class ListImpl<T extends Field> extends ObjectField {
@observable
private [FieldTuples]: StoredType<T>[] = [];
private [Self] = this;
- private [SelfProxy]: List<Field>; // also used in utils.ts even though it won't be found using find all references
+ // eslint-disable-next-line no-use-before-define
+ private [SelfProxy]: List<FieldType>; // also used in utils.ts even though it won't be found using find all references
- [ToJavascriptString]() {
- return `[${(this as any).map((field: any) => Field.toScriptString(field))}]`;
- }
- [ToScriptString]() {
- return `new List([${(this as any).map((field: any) => Field.toScriptString(field))}])`;
- }
- [ToString]() {
- return `[${(this as any).map((field: any) => Field.toString(field))}]`;
- }
+ [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
}
-export type List<T extends Field> = ListImpl<T> & (T | (T extends RefField ? Promise<T> : never))[];
-export const List: { new <T extends Field>(fields?: T[]): List<T> } = ListImpl as any;
+
+// declare List as a type so you can use it in type declarations, e.g., { l: List, ...}
+export type List<T extends FieldType> = ListImpl<T> & (T | (T extends RefField ? Promise<T> : never))[];
+// decalre List as a value so you can invoke 'new' on it, e.g., new List<Doc>()
+// eslint-disable-next-line no-redeclare
+export const List: { new <T extends FieldType>(fields?: T[]): List<T> } = ListImpl as any;
ScriptingGlobals.add('List', List);
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function compareLists(l1: any, l2: any) {
- const L1 = Cast(l1, listSpec('string'), []);
- const L2 = Cast(l2, listSpec('string'), []);
+ 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);
}, 'compare two lists');
diff --git a/src/fields/ObjectField.ts b/src/fields/ObjectField.ts
index e1b5b036c..231086262 100644
--- a/src/fields/ObjectField.ts
+++ b/src/fields/ObjectField.ts
@@ -1,26 +1,36 @@
-import { RefField } from './RefField';
-import { FieldChanged, Parent, Copy, ToScriptString, ToString, ToJavascriptString } from './FieldSymbols';
import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
-import { Field } from './Doc';
+import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
+import { RefField } from './RefField';
export abstract class ObjectField {
// prettier-ignore
public [FieldChanged]?: (diff?: { op: '$addToSet' | '$remFromSet' | '$set';
- items: Field[] | undefined;
+ // eslint-disable-next-line no-use-before-define
+ items: FieldType[] | undefined;
length: number | undefined;
hint?: any }, serverOp?: any) => void;
+ // eslint-disable-next-line no-use-before-define
public [Parent]?: RefField | ObjectField;
abstract [Copy](): ObjectField;
abstract [ToJavascriptString](): string;
abstract [ToScriptString](): string;
abstract [ToString](): string;
-}
-
-export namespace ObjectField {
- export function MakeCopy<T extends ObjectField>(field: T) {
+ static MakeCopy<T extends ObjectField>(field: T) {
return field?.[Copy]();
}
}
+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<RefField | undefined>;
+// 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<RefField | undefined>) {
+ ObjGetRefField = func;
+}
+export function SetObjGetRefFields(func: (ids: string[]) => Promise<{ [id: string]: RefField | undefined }>) {
+ ObjGetRefFields = func;
+}
ScriptingGlobals.add(ObjectField);
diff --git a/src/fields/PresField.ts b/src/fields/PresField.ts
deleted file mode 100644
index f236a04fd..000000000
--- a/src/fields/PresField.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-//insert code here
-import { ObjectField } from "./ObjectField";
-
-export abstract class PresField extends ObjectField {
-
-} \ No newline at end of file
diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts
index 820d9b6ff..83b5672b3 100644
--- a/src/fields/Proxy.ts
+++ b/src/fields/Proxy.ts
@@ -21,7 +21,7 @@ export class ProxyField<T extends RefField> extends ObjectField {
constructor(value?: T | string) {
super();
if (typeof value === 'string') {
- //this.cache = DocServer.GetCachedRefField(value) as any;
+ // this.cache = DocServer.GetCachedRefField(value) as any;
this.fieldId = value;
} else if (value) {
this.cache = { field: value, p: undefined };
@@ -29,7 +29,7 @@ export class ProxyField<T extends RefField> extends ObjectField {
}
}
- [ToValue](doc: any) {
+ [ToValue](/* doc: any */) {
return ProxyField.toValue(this);
}
@@ -39,13 +39,13 @@ export class ProxyField<T extends RefField> extends ObjectField {
}
[ToJavascriptString]() {
- return Field.toScriptString(this[ToValue](undefined)?.value);
+ return Field.toScriptString(this[ToValue]()?.value);
}
[ToScriptString]() {
- return Field.toScriptString(this[ToValue](undefined)?.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); // not sure this is quite right since it doesn't recreate a proxy field, but better than 'invalid' ?
}
[ToString]() {
- return 'ProxyField';
+ return Field.toString(this[ToValue]()?.value);
}
@serializable(primitive())
@@ -59,7 +59,9 @@ export class ProxyField<T extends RefField> extends ObjectField {
return this._cache;
}
private set cache(val: { field: T | undefined; p: FieldWaiting<T> | undefined }) {
- runInAction(() => (this._cache = { ...val }));
+ runInAction(() => {
+ this._cache = { ...val };
+ });
}
private failed = false;
@@ -78,7 +80,7 @@ export class ProxyField<T extends RefField> extends ObjectField {
return this.cache.field ?? this.cache.p;
}
@computed get needsRequesting(): boolean {
- return !this.cache.field && !this.failed && !this._cache.p && !DocServer.GetCachedRefField(this.fieldId) ? true : false;
+ return !!(!this.cache.field && !this.failed && !this._cache.p && !DocServer.GetCachedRefField(this.fieldId));
}
setExternalValuePromise(externalValuePromise: Promise<any>) {
@@ -92,6 +94,7 @@ export class ProxyField<T extends RefField> extends ObjectField {
}
}
+// eslint-disable-next-line no-redeclare
export namespace ProxyField {
let useProxy = true;
export function DisableProxyFields() {
@@ -115,9 +118,11 @@ export namespace ProxyField {
if (useProxy) {
return { value: value.value };
}
+ return undefined;
}
}
+// eslint-disable-next-line no-use-before-define
function prefetchValue(proxy: PrefetchProxy<RefField>) {
return proxy.value as any;
}
diff --git a/src/fields/RefField.ts b/src/fields/RefField.ts
index 01828dd14..1ce81368a 100644
--- a/src/fields/RefField.ts
+++ b/src/fields/RefField.ts
@@ -1,7 +1,7 @@
-import { serializable, primitive, alias } from 'serializr';
+import { alias, primitive, serializable } from 'serializr';
import { Utils } from '../Utils';
-import { Id, HandleUpdate, ToScriptString, ToString, ToJavascriptString } from './FieldSymbols';
import { afterDocDeserialize } from '../client/util/SerializationHelper';
+import { HandleUpdate, Id, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
export type FieldId = string;
export abstract class RefField {
diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts
index 50cfab988..3f13f7e6d 100644
--- a/src/fields/RichTextField.ts
+++ b/src/fields/RichTextField.ts
@@ -31,15 +31,15 @@ export class RichTextField extends ObjectField {
return '`' + this.Text + '`';
}
[ToScriptString]() {
- return `new RichTextField("${this.Data.replace(/"/g, '\\"')}", "${this.Text}")`;
+ return `new RichTextField(\`${this.Data?.replace(/"/g, '\\"')}\`, \`${this.Text}\`)`;
}
[ToString]() {
return this.Text;
}
- public static DashField(fieldKey: string) {
+ public static RTFfield() {
return new RichTextField(
- `{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[{"type":"dashField","attrs":{"fieldKey":"${fieldKey}","docId":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`,
+ `{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`,
''
);
}
diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts
index b84a91709..3763dcd2c 100644
--- a/src/fields/RichTextUtils.ts
+++ b/src/fields/RichTextUtils.ts
@@ -1,21 +1,25 @@
+/* eslint-disable no-await-in-loop */
+/* eslint-disable no-use-before-define */
import { AssertionError } from 'assert';
-import { docs_v1 } from 'googleapis';
+import * as Color from 'color';
+import { docs_v1 as docsV1 } from 'googleapis';
import { Fragment, Mark, Node } from 'prosemirror-model';
import { sinkListItem } from 'prosemirror-schema-list';
import { EditorState, TextSelection, Transaction } from 'prosemirror-state';
-import { GoogleApiClientUtils } from '../client/apis/google_docs/GoogleApiClientUtils';
-import { GooglePhotos } from '../client/apis/google_docs/GooglePhotosClientUtils';
+import { ClientUtils, DashColor } from '../ClientUtils';
+import { Utils } from '../Utils';
import { DocServer } from '../client/DocServer';
-import { Docs, DocUtils } from '../client/documents/Documents';
import { Networking } from '../client/Network';
+import { GoogleApiClientUtils } from '../client/apis/google_docs/GoogleApiClientUtils';
+import { GooglePhotos } from '../client/apis/google_docs/GooglePhotosClientUtils';
+import { Docs } from '../client/documents/Documents';
+import { DocUtils } from '../client/documents/DocUtils';
import { FormattedTextBox } from '../client/views/nodes/formattedText/FormattedTextBox';
import { schema } from '../client/views/nodes/formattedText/schema_rts';
-import { DashColor, Utils } from '../Utils';
import { Doc, Opt } from './Doc';
import { Id } from './FieldSymbols';
import { RichTextField } from './RichTextField';
import { Cast, StrCast } from './Types';
-import * as Color from 'color';
export namespace RichTextUtils {
const delimiter = '\n';
@@ -47,13 +51,11 @@ export namespace RichTextUtils {
return JSON.stringify(state);
};
- export const Synthesize = (plainText: string, oldState?: RichTextField) => {
- return new RichTextField(ToProsemirrorState(plainText, oldState), plainText);
- };
+ export const Synthesize = (plainText: string, oldState?: RichTextField) => new RichTextField(ToProsemirrorState(plainText, oldState), plainText);
export const ToPlainText = (state: EditorState) => {
// Because we're working with plain text, just concatenate all paragraphs
- const content = state.doc.content;
+ const { content } = state.doc;
const paragraphs: Node[] = [];
content.forEach(node => node.type.name === 'paragraph' && paragraphs.push(node));
@@ -112,9 +114,9 @@ export namespace RichTextUtils {
agnostic: string;
}
- const parseInlineObjects = async (document: docs_v1.Schema$Document): Promise<Map<string, ImageTemplate>> => {
+ const parseInlineObjects = async (document: docsV1.Schema$Document): Promise<Map<string, ImageTemplate>> => {
const inlineObjectMap = new Map<string, ImageTemplate>();
- const inlineObjects = document.inlineObjects;
+ const { inlineObjects } = document;
if (inlineObjects) {
const objects = Object.keys(inlineObjects).map(objectId => inlineObjects[objectId]);
@@ -140,8 +142,8 @@ export namespace RichTextUtils {
inlineObjectMap.set(object.objectId!, {
title: embeddedObject.title || `Imported Image from ${document.title}`,
width,
- url: Utils.prepend(_m.client),
- agnostic: Utils.prepend(agnostic.client),
+ url: ClientUtils.prepend(_m.client),
+ agnostic: ClientUtils.prepend(agnostic.client),
});
}
}
@@ -162,7 +164,7 @@ export namespace RichTextUtils {
const inlineObjectMap = await parseInlineObjects(document);
const title = document.title!;
const { text, paragraphs } = GoogleApiClientUtils.Docs.Utils.extractText(document);
- let state = FormattedTextBox.blankState();
+ let state = EditorState.create(new FormattedTextBox({} as any).config);
const structured = parseLists(paragraphs);
let position = 3;
@@ -170,10 +172,12 @@ export namespace RichTextUtils {
const indentMap = new Map<ListGroup, BulletPosition[]>();
let globalOffset = 0;
const nodes: Node[] = [];
+ // eslint-disable-next-line no-restricted-syntax
for (const element of structured) {
if (Array.isArray(element)) {
lists.push(element);
const positions: BulletPosition[] = [];
+ // eslint-disable-next-line no-loop-func
const items = element.map(paragraph => {
const item = listItem(state.schema, paragraph.contents);
const sinks = paragraph.bullet!;
@@ -187,41 +191,42 @@ export namespace RichTextUtils {
});
indentMap.set(element, positions);
nodes.push(list(state.schema, items));
+ } else if (element.contents.some(child => 'inlineObjectId' in child)) {
+ const group = element.contents;
+ // eslint-disable-next-line no-loop-func
+ group.forEach((child, i) => {
+ let node: Opt<Node>;
+ if ('inlineObjectId' in child) {
+ node = imageNode(state.schema, inlineObjectMap.get(child.inlineObjectId!)!, textNote);
+ } else if ('content' in child && (i !== group.length - 1 || child.content!.removeTrailingNewlines().length)) {
+ node = paragraphNode(state.schema, [child]);
+ }
+ if (node) {
+ position += node.nodeSize;
+ nodes.push(node);
+ }
+ });
} else {
- if (element.contents.some(child => 'inlineObjectId' in child)) {
- const group = element.contents;
- group.forEach((child, i) => {
- let node: Opt<Node>;
- if ('inlineObjectId' in child) {
- node = imageNode(state.schema, inlineObjectMap.get(child.inlineObjectId!)!, textNote);
- } else if ('content' in child && (i !== group.length - 1 || child.content!.removeTrailingNewlines().length)) {
- node = paragraphNode(state.schema, [child]);
- }
- if (node) {
- position += node.nodeSize;
- nodes.push(node);
- }
- });
- } else {
- const paragraph = paragraphNode(state.schema, element.contents);
- nodes.push(paragraph);
- position += paragraph.nodeSize;
- }
+ const paragraph = paragraphNode(state.schema, element.contents);
+ nodes.push(paragraph);
+ position += paragraph.nodeSize;
}
}
state = state.apply(state.tr.replaceWith(0, 2, nodes));
const sink = sinkListItem(state.schema.nodes.list_item);
- const dispatcher = (tr: Transaction) => (state = state.apply(tr));
- for (const list of lists) {
- for (const pos of indentMap.get(list)!) {
+ const dispatcher = (tr: Transaction) => {
+ state = state.apply(tr);
+ };
+ lists.forEach(list => {
+ indentMap.get(list)?.forEach(pos => {
const resolved = state.doc.resolve(pos.value);
state = state.apply(state.tr.setSelection(new TextSelection(resolved)));
for (let i = 0; i < pos.sinks; i++) {
sink(state, dispatcher);
}
- }
- }
+ });
+ });
return { title, text, state };
};
@@ -233,7 +238,7 @@ export namespace RichTextUtils {
const parseLists = (paragraphs: ListGroup) => {
const groups: PreparedParagraphs = [];
let group: ListGroup = [];
- for (const paragraph of paragraphs) {
+ paragraphs.forEach(paragraph => {
if (paragraph.bullet !== undefined) {
group.push(paragraph);
} else {
@@ -243,26 +248,22 @@ export namespace RichTextUtils {
}
groups.push(paragraph);
}
- }
+ });
group.length && groups.push(group);
return groups;
};
- const listItem = (schema: any, runs: docs_v1.Schema$TextRun[]): Node => {
- return schema.node('list_item', null, paragraphNode(schema, runs));
- };
+ const listItem = (lschema: any, runs: docsV1.Schema$TextRun[]): Node => lschema.node('list_item', null, paragraphNode(lschema, runs));
- const list = (schema: any, items: Node[]): Node => {
- return schema.node('ordered_list', { mapStyle: 'bullet' }, items);
- };
+ const list = (lschema: any, items: Node[]): Node => lschema.node('ordered_list', { mapStyle: 'bullet' }, items);
- const paragraphNode = (schema: any, runs: docs_v1.Schema$TextRun[]): Node => {
- const children = runs.map(run => textNode(schema, run)).filter(child => child !== undefined);
+ const paragraphNode = (lschema: any, runs: docsV1.Schema$TextRun[]): Node => {
+ const children = runs.map(run => textNode(lschema, run)).filter(child => child !== undefined);
const fragment = children.length ? Fragment.from(children) : undefined;
- return schema.node('paragraph', null, fragment);
+ return lschema.node('paragraph', null, fragment);
};
- const imageNode = (schema: any, image: ImageTemplate, textNote: Doc) => {
+ const imageNode = (lschema: any, image: ImageTemplate, textNote: Doc) => {
const { url: src, width, agnostic } = image;
let docId: string;
const guid = Utils.GenerateDeterministicGuid(agnostic);
@@ -275,30 +276,30 @@ export namespace RichTextUtils {
} else {
docId = backingDocId;
}
- return schema.node('image', { src, agnostic, width, docId, float: null });
+ return lschema.node('image', { src, agnostic, width, docId, float: null });
};
- const textNode = (schema: any, run: docs_v1.Schema$TextRun) => {
+ const textNode = (lschema: any, run: docsV1.Schema$TextRun) => {
const text = run.content!.removeTrailingNewlines();
- return text.length ? schema.text(text, styleToMarks(schema, run.textStyle)) : undefined;
+ return text.length ? lschema.text(text, styleToMarks(lschema, run.textStyle)) : undefined;
};
- const StyleToMark = new Map<keyof docs_v1.Schema$TextStyle, keyof typeof schema.marks>([
+ const StyleToMark = new Map<keyof docsV1.Schema$TextStyle, keyof typeof schema.marks>([
['bold', 'strong'],
['italic', 'em'],
['foregroundColor', 'pFontColor'],
['fontSize', 'pFontSize'],
]);
- const styleToMarks = (schema: any, textStyle?: docs_v1.Schema$TextStyle) => {
+ const styleToMarks = (lschema: any, textStyle?: docsV1.Schema$TextStyle) => {
if (!textStyle) {
return undefined;
}
const marks: Mark[] = [];
Object.keys(textStyle).forEach(key => {
- let value: any;
- const targeted = key as keyof docs_v1.Schema$TextStyle;
- if ((value = textStyle[targeted])) {
+ const targeted = key as keyof docsV1.Schema$TextStyle;
+ const value = textStyle[targeted] as any;
+ if (value) {
const attributes: any = {};
let converted = StyleToMark.get(targeted) || targeted;
@@ -315,20 +316,20 @@ export namespace RichTextUtils {
converted = ImportFontFamilyMapping.get(value.fontFamily) || 'timesNewRoman';
}
- const mapped = schema.marks[converted];
+ const mapped = lschema.marks[converted];
if (!mapped) {
alert(`No mapping found for ${converted}!`);
return;
}
- const mark = schema.mark(mapped, attributes);
+ const mark = lschema.mark(mapped, attributes);
mark && marks.push(mark);
}
});
return marks;
};
- const MarkToStyle = new Map<keyof typeof schema.marks, keyof docs_v1.Schema$TextStyle>([
+ const MarkToStyle = new Map<keyof typeof schema.marks, keyof docsV1.Schema$TextStyle>([
['strong', 'bold'],
['em', 'italic'],
['pFontColor', 'foregroundColor'],
@@ -360,16 +361,18 @@ export namespace RichTextUtils {
const ignored = ['user_mark'];
- const marksToStyle = async (nodes: (Node | null)[]): Promise<docs_v1.Schema$Request[]> => {
- const requests: docs_v1.Schema$Request[] = [];
+ const marksToStyle = async (nodes: (Node | null)[]): Promise<docsV1.Schema$Request[]> => {
+ const requests: docsV1.Schema$Request[] = [];
let position = 1;
+ // eslint-disable-next-line no-restricted-syntax
for (const node of nodes) {
if (node === null) {
position += 2;
+ // eslint-disable-next-line no-continue
continue;
}
const { marks, attrs, nodeSize } = node;
- const textStyle: docs_v1.Schema$TextStyle = {};
+ const textStyle: docsV1.Schema$TextStyle = {};
const information: LinkInformation = {
startIndex: position,
endIndex: position + nodeSize,
@@ -377,36 +380,45 @@ export namespace RichTextUtils {
};
let mark: Mark;
const markMap = BuildMarkMap(marks);
+ // eslint-disable-next-line no-restricted-syntax
for (const markName of Object.keys(schema.marks)) {
+ // eslint-disable-next-line no-cond-assign
if (ignored.includes(markName) || !(mark = markMap[markName])) {
+ // eslint-disable-next-line no-continue
continue;
}
- let converted = MarkToStyle.get(markName) || (markName as keyof docs_v1.Schema$TextStyle);
+ let converted = MarkToStyle.get(markName) || (markName as keyof docsV1.Schema$TextStyle);
let value: any = true;
if (!converted) {
+ // eslint-disable-next-line no-continue
continue;
}
+ // eslint-disable-next-line @typescript-eslint/no-shadow
const { attrs } = mark;
switch (converted) {
case 'link':
- let url = attrs.allLinks.length ? attrs.allLinks[0].href : '';
- const delimiter = '/doc/';
- const alreadyShared = '?sharing=true';
- if (new RegExp(window.location.origin + delimiter).test(url) && !url.endsWith(alreadyShared)) {
- const linkDoc = await DocServer.GetRefField(url.split(delimiter)[1]);
- if (linkDoc instanceof Doc) {
- let exported = (await Cast(linkDoc.link_anchor_2, Doc))!;
- if (!exported.customLayout) {
- exported = Doc.MakeEmbedding(exported);
- DocUtils.makeCustomViewClicked(exported, Docs.Create.FreeformDocument);
- linkDoc.link_anchor_2 = exported;
+ {
+ let url = attrs.allLinks.length ? attrs.allLinks[0].href : '';
+ const docDelimeter = '/doc/';
+ const alreadyShared = '?sharing=true';
+ if (new RegExp(window.location.origin + docDelimeter).test(url) && !url.endsWith(alreadyShared)) {
+ // eslint-disable-next-line no-await-in-loop
+ const linkDoc = await DocServer.GetRefField(url.split(docDelimeter)[1]);
+ if (linkDoc instanceof Doc) {
+ // eslint-disable-next-line no-await-in-loop
+ let exported = (await Cast(linkDoc.link_anchor_2, Doc))!;
+ if (!exported.customLayout) {
+ exported = Doc.MakeEmbedding(exported);
+ DocUtils.makeCustomViewClicked(exported, Docs.Create.FreeformDocument);
+ linkDoc.link_anchor_2 = exported;
+ }
+ url = ClientUtils.shareUrl(exported[Id]);
}
- url = Utils.shareUrl(exported[Id]);
}
+ value = { url };
+ textStyle.foregroundColor = fromRgb.blue;
+ textStyle.bold = true;
}
- value = { url };
- textStyle.foregroundColor = fromRgb.blue;
- textStyle.bold = true;
break;
case 'fontSize':
value = { magnitude: attrs.fontSize, unit: 'PT' };
@@ -416,9 +428,11 @@ export namespace RichTextUtils {
break;
case 'weightedFontFamily':
value = { fontFamily: ExportFontFamilyMapping.get(markName) };
+ break;
+ default:
}
- let matches: RegExpExecArray | null;
- if ((matches = /p(\d+)/g.exec(markName)) !== null) {
+ const matches = /p(\d+)/g.exec(markName);
+ if (matches !== null) {
converted = 'fontSize';
value = { magnitude: parseInt(matches[1].replace('px', '')), unit: 'PT' };
}
@@ -428,7 +442,7 @@ export namespace RichTextUtils {
requests.push(EncodeStyleUpdate(information));
}
if (node.type.name === 'image') {
- const width = attrs.width;
+ const { width } = attrs;
requests.push(
await EncodeImage({
startIndex: position + nodeSize - 1,
@@ -444,14 +458,16 @@ export namespace RichTextUtils {
const BuildMarkMap = (marks: readonly Mark[]) => {
const markMap: { [type: string]: Mark } = {};
- marks.forEach(mark => (markMap[mark.type.name] = mark));
+ marks.forEach(mark => {
+ markMap[mark.type.name] = mark;
+ });
return markMap;
};
interface LinkInformation {
startIndex: number;
endIndex: number;
- textStyle: docs_v1.Schema$TextStyle;
+ textStyle: docsV1.Schema$TextStyle;
}
interface ImageInformation {
@@ -461,36 +477,34 @@ export namespace RichTextUtils {
}
namespace fromRgb {
- export const convert = (red: number, green: number, blue: number): docs_v1.Schema$OptionalColor => {
- return {
- color: {
- rgbColor: {
- red: red / 255,
- green: green / 255,
- blue: blue / 255,
- },
+ export const convert = (red: number, green: number, blue: number): docsV1.Schema$OptionalColor => ({
+ color: {
+ rgbColor: {
+ red: red / 255,
+ green: green / 255,
+ blue: blue / 255,
},
- };
- };
+ },
+ });
export const red = convert(255, 0, 0);
export const green = convert(0, 255, 0);
export const blue = convert(0, 0, 255);
}
- const fromHex = (color: string): docs_v1.Schema$OptionalColor => {
+ const fromHex = (color: string): docsV1.Schema$OptionalColor => {
const c = DashColor(color);
return fromRgb.convert(c.red(), c.green(), c.blue());
};
- const EncodeStyleUpdate = (information: LinkInformation): docs_v1.Schema$Request => {
+ const EncodeStyleUpdate = (information: LinkInformation): docsV1.Schema$Request => {
const { startIndex, endIndex, textStyle } = information;
return {
updateTextStyle: {
fields: '*',
range: { startIndex, endIndex },
textStyle,
- } as docs_v1.Schema$UpdateTextStyleRequest,
+ } as docsV1.Schema$UpdateTextStyleRequest,
};
};
diff --git a/src/fields/Schema.ts b/src/fields/Schema.ts
index f5e64ae1f..89e5cda8d 100644
--- a/src/fields/Schema.ts
+++ b/src/fields/Schema.ts
@@ -1,5 +1,9 @@
+/* eslint-disable guard-for-in */
+/* eslint-disable no-restricted-syntax */
+/* eslint-disable no-redeclare */
+/* eslint-disable no-use-before-define */
import { Interface, ToInterface, Cast, ToConstructor, HasTail, Head, Tail, ListSpec, ToType, DefaultFieldConstructor } from './Types';
-import { Doc, Field } from './Doc';
+import { Doc, FieldType } from './Doc';
import { ObjectField } from './ObjectField';
import { RefField } from './RefField';
import { SelfProxy } from './DocSymbols';
@@ -12,6 +16,7 @@ type AllToInterface<T extends Interface[]> = {
export const emptySchema = createSchema({});
export const Document = makeInterface(emptySchema);
+// eslint-disable-next-line no-redeclare
export type Document = makeInterface<[typeof emptySchema]>;
export interface InterfaceFunc<T extends Interface[]> {
@@ -36,9 +41,10 @@ export function makeInterface<T extends Interface[]>(...schemas: T): InterfaceFu
if (prop in schema) {
const desc = prop === 'proto' ? Doc : (schema as any)[prop]; // bcz: proto doesn't appear in schemas ... maybe it should?
if (typeof desc === 'object' && 'defaultVal' in desc && 'type' in desc) {
- //defaultSpec
+ // defaultSpec
return Cast(field, desc.type, desc.defaultVal);
}
+ // eslint-disable-next-line no-prototype-builtins
if (typeof desc === 'function' && !ObjectField.isPrototypeOf(desc) && !RefField.isPrototypeOf(desc)) {
const doc = Cast(field, Doc);
if (doc === undefined) {
@@ -47,7 +53,7 @@ export function makeInterface<T extends Interface[]>(...schemas: T): InterfaceFu
if (doc instanceof Doc) {
return desc(doc);
}
- return doc.then(doc => doc && desc(doc));
+ return doc.then(d => d && desc(d));
}
return Cast(field, desc);
}
@@ -73,8 +79,8 @@ export function makeStrictInterface<T extends Interface>(schema: T): (doc: Doc)
get() {
return Cast(this.__doc[key], type as any);
},
- set(value) {
- value = Cast(value, type as any);
+ set(setValue) {
+ const value = Cast(setValue, type as any);
if (value !== undefined) {
this.__doc[key] = value;
return;
@@ -93,17 +99,18 @@ export function makeStrictInterface<T extends Interface>(schema: T): (doc: Doc)
};
}
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function createSchema<T extends Interface>(schema: T): T & { proto: ToConstructor<Doc> } {
return undefined as any;
- (schema as any).proto = Doc;
- return schema as any;
+ // (schema as any).proto = Doc;
+ // return schema as any;
}
-export function listSpec<U extends ToConstructor<Field>>(type: U): ListSpec<ToType<U>> {
- return { List: type as any }; //TODO Types
+export function listSpec<U extends ToConstructor<FieldType>>(type: U): ListSpec<ToType<U>> {
+ return { List: type as any }; // TODO Types
}
-export function defaultSpec<T extends ToConstructor<Field>>(type: T, defaultVal: ToType<T>): DefaultFieldConstructor<ToType<T>> {
+export function defaultSpec<T extends ToConstructor<FieldType>>(type: T, defaultVal: ToType<T>): DefaultFieldConstructor<ToType<T>> {
return {
type: type as any,
defaultVal,
diff --git a/src/fields/SchemaHeaderField.ts b/src/fields/SchemaHeaderField.ts
index fb4dc4e5b..0a8dd1d9e 100644
--- a/src/fields/SchemaHeaderField.ts
+++ b/src/fields/SchemaHeaderField.ts
@@ -1,9 +1,19 @@
+import { primitive, serializable } from 'serializr';
+import { ScriptingGlobals, scriptingGlobal } from '../client/util/ScriptingGlobals';
import { Deserializable } from '../client/util/SerializationHelper';
-import { serializable, primitive } from 'serializr';
+import { Copy, FieldChanged, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
import { ObjectField } from './ObjectField';
-import { Copy, ToScriptString, ToString, FieldChanged, ToJavascriptString } from './FieldSymbols';
-import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGlobals';
-import { ColumnType } from '../client/views/collections/collectionSchema/CollectionSchemaView';
+
+export enum ColumnType {
+ Number,
+ String,
+ Boolean,
+ Date,
+ Image,
+ RTF,
+ Enumeration,
+ Any,
+}
export const PastelSchemaPalette = new Map<string, string>([
// ["pink1", "#FFB4E8"],
@@ -69,13 +79,14 @@ export class SchemaHeaderField extends ObjectField {
@serializable(primitive())
desc: boolean | undefined; // boolean determines sort order, undefined when no sort
+ // eslint-disable-next-line default-param-last
constructor(heading: string = '', color: string = RandomPastel(), type?: ColumnType, width?: number, desc?: boolean, collapsed?: boolean) {
super();
this.heading = heading;
this.color = color;
- this.type = type ? type : 0;
- this.width = width ? width : -1;
+ this.type = type ?? 0;
+ this.width = width ?? -1;
this.desc = desc;
this.collapsed = collapsed;
}
@@ -124,6 +135,8 @@ export class SchemaHeaderField extends ObjectField {
return `SchemaHeaderField`;
}
}
+
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function schemaHeaderField(heading: string, color: string, type: number, width: number, desc?: boolean, collapsed?: boolean) {
return new SchemaHeaderField(heading, color, type, width, desc, collapsed);
});
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index c7fe72ca6..8fe365ac2 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -1,14 +1,15 @@
+import { action, makeObservable, observable } from 'mobx';
import { computedFn } from 'mobx-utils';
-import { createSimpleSchema, custom, map, object, primitive, PropSchema, serializable, SKIP } from 'serializr';
-import { DocServer } from '../client/DocServer';
-import { CompiledScript, CompileScript, ScriptOptions } from '../client/util/Scripting';
-import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGlobals';
-import { autoObject, Deserializable } from '../client/util/SerializationHelper';
+import { PropSchema, SKIP, createSimpleSchema, custom, map, object, primitive, serializable } from 'serializr';
import { numberRange } from '../Utils';
-import { Doc, Field, Opt } from './Doc';
-import { Copy, Id, ToJavascriptString, ToScriptString, ToString, ToValue } from './FieldSymbols';
+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 { Copy, FieldChanged, Id, ToJavascriptString, ToScriptString, ToString, ToValue } from './FieldSymbols';
import { List } from './List';
-import { ObjectField } from './ObjectField';
+import { ObjGetRefField, ObjectField } from './ObjectField';
import { Cast, StrCast } from './Types';
function optional(propSchema: PropSchema) {
@@ -42,7 +43,9 @@ const scriptSchema = createSimpleSchema({
originalScript: true,
});
-function finalizeScript(script: ScriptField) {
+// eslint-disable-next-line no-use-before-define
+function finalizeScript(scriptIn: ScriptField) {
+ const script = scriptIn;
const comp = CompileScript(script.script.originalScript, script.script.options);
if (!comp.compiled) {
throw new Error("Couldn't compile loaded script");
@@ -52,11 +55,13 @@ function finalizeScript(script: ScriptField) {
if (!compset.compiled) {
throw new Error("Couldn't compile setter script");
}
- (script as any).setterscript = compset;
+ script.setterscript = compset;
}
return comp;
}
-async function deserializeScript(script: ScriptField) {
+// eslint-disable-next-line no-use-before-define
+async function deserializeScript(scriptIn: ScriptField) {
+ const script = scriptIn;
if (script.captures) {
const captured: any = {};
(script.script.options as ScriptOptions).capturedVariables = captured;
@@ -66,13 +71,16 @@ async function deserializeScript(script: ScriptField) {
const val = capture.split(':')[1];
if (val === 'true') captured[key] = true;
else if (val === 'false') captured[key] = false;
- else if (val.startsWith('ID->')) captured[key] = await DocServer.GetRefField(val.replace('ID->', ''));
+ else if (val.startsWith('ID->')) captured[key] = await ObjGetRefField(val.replace('ID->', ''));
else if (!isNaN(Number(val))) captured[key] = Number(val);
else captured[key] = val;
})
- ).then(() => ((script as any).script = finalizeScript(script)));
+ ).then(() => {
+ script.script = finalizeScript(script);
+ });
} else {
- (script as any).script = ScriptField.GetScriptFieldCache(script.script.originalScript) ?? finalizeScript(script);
+ // eslint-disable-next-line no-use-before-define
+ script.script = ScriptField.GetScriptFieldCache(script.script.originalScript) ?? finalizeScript(script);
}
}
@@ -82,9 +90,16 @@ export class ScriptField extends ObjectField {
@serializable
readonly rawscript: string | undefined;
@serializable(object(scriptSchema))
- readonly script: CompiledScript;
+ script: CompiledScript;
@serializable(object(scriptSchema))
- readonly setterscript: CompiledScript | undefined;
+ setterscript: CompiledScript | undefined;
+ @serializable
+ @observable
+ _cachedResult: FieldResult = undefined;
+ setCacheResult = action((value: FieldResult) => {
+ this._cachedResult = value;
+ this[FieldChanged]?.();
+ });
@serializable(autoObject())
captures?: List<string>;
@@ -122,56 +137,109 @@ export class ScriptField extends ObjectField {
[ToString]() {
return this.script.originalScript;
}
- public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Doc | string | number | boolean }) {
+ // eslint-disable-next-line default-param-last
+ public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Doc | string | number | boolean }, transformer?: Transformer) {
return CompileScript(script, {
params: {
this: Doc?.name || 'Doc', // this is the doc that executes the script
- self: Doc?.name || 'Doc', // self is the root doc of the doc that executes the script
+ documentView: 'any',
_last_: 'any', // _last_ is the previous value of a computed field when it is being triggered to re-run.
+ _setCacheResult_: 'any', // set the cached value of the function
_readOnly_: 'boolean', // _readOnly_ is set when a computed field is executed to indicate that it should not have mobx side-effects. used for checking the value of a set function (see FontIconBox)
...params,
},
+ transformer,
typecheck: false,
editable: true,
addReturn: addReturn,
capturedVariables,
});
}
+
+ // eslint-disable-next-line default-param-last
public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Doc | string | number | boolean }) {
const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
return compiled.compiled ? new ScriptField(compiled) : undefined;
}
+ // eslint-disable-next-line default-param-last
public static MakeScript(script: string, params: object = {}, capturedVariables?: { [name: string]: Doc | string | number | boolean }) {
const compiled = ScriptField.CompileScript(script, params, false, capturedVariables);
return compiled.compiled ? new ScriptField(compiled) : undefined;
}
+ public static CallGpt(queryTextIn: string, setVal: (val: FieldResult) => void, target: Doc) {
+ let queryText = queryTextIn;
+ if (typeof queryText === 'string' && setVal) {
+ while (queryText.match(/\(this\.[a-zA-Z_]*\)/)?.length) {
+ const fieldRef = queryText.split('(this.')[1].replace(/\).*/, '');
+ queryText = queryText.replace(/\(this\.[a-zA-Z_]*\)/, Field.toString(target[fieldRef] as FieldType));
+ }
+ setVal(`Chat Pending: ${queryText}`);
+ gptAPICall(queryText, GPTCallType.COMPLETION).then(result => {
+ if (queryText.includes('#')) {
+ const matches = result.match(/-?[0-9][0-9,]+[.]?[0-9]*/);
+ if (matches?.length) setVal(Number(matches[0].replace(/,/g, '')));
+ } else setVal(result.trim());
+ });
+ }
+ }
}
@scriptingGlobal
@Deserializable('computed', deserializeScript)
export class ComputedField extends ScriptField {
- _lastComputedResult: any;
- //TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc
- value = computedFn((doc: Doc) => this._valueOutsideReaction(doc));
- _valueOutsideReaction = (doc: Doc) => (this._lastComputedResult = this.script.compiled && this.script.run({ this: doc, self: doc, value: '', _last_: this._lastComputedResult, _readOnly_: true }, console.log).result);
-
- [ToValue](doc: Doc) {
- return ComputedField.toValue(doc, this);
+ static undefined = '__undefined';
+ static useComputed = true;
+ static DisableComputedFields() { this.useComputed = false; } // prettier-ignore
+ static EnableComputedFields() { this.useComputed = true; } // prettier-ignore
+ static WithoutComputed<T>(fn: () => T) {
+ this.DisableComputedFields();
+ try {
+ return fn();
+ } finally {
+ this.EnableComputedFields();
+ }
}
- [Copy](): ObjectField {
- return new ComputedField(this.script, this.setterscript, this.rawscript);
+
+ constructor(script: CompiledScript | undefined, setterscript?: CompiledScript, rawscript?: string) {
+ super(script, setterscript, rawscript);
+ makeObservable(this);
}
+ _lastComputedResult: FieldResult;
+ value = (doc: Doc) => {
+ this._lastComputedResult =
+ this._cachedResult ??
+ computedFn(() =>
+ this.script.compiled &&
+ this.script.run(
+ {
+ this: doc,
+ // value: '',
+ _setCacheResult_: this.setCacheResult,
+ _last_: this._lastComputedResult,
+ _readOnly_: true,
+ },
+ console.log
+ ).result
+ )(); // prettier-ignore
+ return this._lastComputedResult;
+ };
+
+ [ToValue](doc: Doc) { return ComputedField.useComputed ? { value: this.value(doc) } : undefined; } // prettier-ignore
+ [Copy](): ObjectField { return new ComputedField(this.script, this.setterscript, this.rawscript); } // prettier-ignore
+
+ // eslint-disable-next-line default-param-last
public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Doc | string | number | boolean }, setterscript?: string) {
const compiled = ScriptField.CompileScript(script, params, true, { value: '', ...capturedVariables });
const compiledsetter = setterscript ? ScriptField.CompileScript(setterscript, { ...params, value: 'any' }, false, capturedVariables) : undefined;
const compiledsetscript = compiledsetter?.compiled ? compiledsetter : undefined;
return compiled.compiled ? new ComputedField(compiled, compiledsetscript) : undefined;
}
+
public static MakeInterpolatedNumber(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number, defaultVal: Opt<number>) {
if (!doc[`${fieldKey}_indexed`]) {
- const flist = new List<number>(numberRange(curTimecode + 1).map(i => undefined) as any as number[]);
+ const flist = new List<number>(numberRange(curTimecode + 1).map(() => undefined) as any as number[]);
flist[curTimecode] = Cast(doc[fieldKey], 'number', null);
doc[`${fieldKey}_indexed`] = flist;
}
@@ -181,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<string>(numberRange(curTimecode + 1).map(i => undefined) as any as string[]);
+ const flist = new List<string>(numberRange(curTimecode + 1).map(() => undefined) as any as string[]);
flist[curTimecode] = StrCast(doc[fieldKey]);
doc[`${fieldKey}_indexed`] = flist;
}
@@ -190,9 +258,9 @@ export class ComputedField extends ScriptField {
return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
}
public static MakeInterpolatedDataField(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) {
- if (doc[`${fieldKey}`] instanceof List) return;
+ if (doc[`${fieldKey}`] instanceof List) return undefined;
if (!doc[`${fieldKey}_indexed`]) {
- const flist = new List<Field>(numberRange(curTimecode + 1).map(i => undefined) as any as Field[]);
+ const flist = new List<FieldType>(numberRange(curTimecode + 1).map(() => undefined) as any as FieldType[]);
flist[curTimecode] = Field.Copy(doc[fieldKey]);
doc[`${fieldKey}_indexed`] = flist;
}
@@ -203,38 +271,13 @@ export class ComputedField extends ScriptField {
false,
{}
);
- return (doc[`${fieldKey}`] = getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined);
- }
-}
-export namespace ComputedField {
- let useComputed = true;
- export function DisableComputedFields() {
- useComputed = false;
- }
-
- export function EnableComputedFields() {
- useComputed = true;
- }
-
- export const undefined = '__undefined';
-
- export function WithoutComputed<T>(fn: () => T) {
- DisableComputedFields();
- try {
- return fn();
- } finally {
- EnableComputedFields();
- }
- }
-
- export function toValue(doc: any, value: any) {
- if (useComputed) {
- return { value: value._valueOutsideReaction(doc) };
- }
+ doc[fieldKey] = getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
+ return doc[fieldKey];
}
}
ScriptingGlobals.add(
+ // eslint-disable-next-line prefer-arrow-callback
function setIndexVal(list: any[], index: number, value: any) {
while (list.length <= index) list.push(undefined);
list[index] = value;
@@ -244,6 +287,7 @@ ScriptingGlobals.add(
);
ScriptingGlobals.add(
+ // eslint-disable-next-line prefer-arrow-callback
function getIndexVal(list: any[], index: number, defaultVal: Opt<number> = undefined) {
return list?.reduce((p, x, i) => ((i <= index && x !== undefined) || p === undefined ? x : p), defaultVal);
},
@@ -252,9 +296,14 @@ ScriptingGlobals.add(
);
ScriptingGlobals.add(
+ // eslint-disable-next-line prefer-arrow-callback
function makeScript(script: string) {
return ScriptField.MakeScript(script);
},
'returns the value at a given index of a list',
'(list: any[], index: number)'
);
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function dashCallChat(setVal: (val: FieldResult) => void, target: Doc, queryText: string) {
+ ScriptField.CallGpt(queryText, setVal, target);
+}, 'calls chat gpt for the query string and then calls setVal with the result');
diff --git a/src/fields/Types.ts b/src/fields/Types.ts
index 337e8ca21..ef79f72e4 100644
--- a/src/fields/Types.ts
+++ b/src/fields/Types.ts
@@ -1,69 +1,75 @@
import { DateField } from './DateField';
-import { Doc, Field, FieldResult, Opt } from './Doc';
+import { Doc, FieldType, FieldResult, Opt } from './Doc';
import { List } from './List';
import { ProxyField } from './Proxy';
import { RefField } from './RefField';
import { RichTextField } from './RichTextField';
import { ScriptField } from './ScriptField';
-import { CsvField, ImageField, WebField } from './URLField';
+import { CsvField, ImageField, PdfField, WebField } from './URLField';
+
+// eslint-disable-next-line no-use-before-define
+export type ToConstructor<T extends FieldType> = T extends string ? 'string' : T extends number ? 'number' : T extends boolean ? 'boolean' : T extends List<infer U> ? ListSpec<U> : new (...args: any[]) => T;
+
+export type DefaultFieldConstructor<T extends FieldType> = {
+ type: ToConstructor<T>;
+ defaultVal: T;
+};
+// type ListSpec<T extends Field[]> = { List: ToContructor<Head<T>> | ListSpec<Tail<T>> };
+export type ListSpec<T extends FieldType> = { List: ToConstructor<T> };
+
+export type InterfaceValue = ToConstructor<FieldType> | ListSpec<FieldType> | DefaultFieldConstructor<FieldType> | ((doc?: Doc) => any);
export type ToType<T extends InterfaceValue> = T extends 'string'
? string
: T extends 'number'
- ? number
- : T extends 'boolean'
- ? boolean
- : T extends ListSpec<infer U>
- ? List<U>
- : // T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never;
- T extends DefaultFieldConstructor<infer _U>
- ? never
- : T extends { new (...args: any[]): List<Field> }
- ? never
- : T extends { new (...args: any[]): infer R }
- ? R
- : T extends (doc?: Doc) => infer R
- ? R
- : never;
-
-export type ToConstructor<T extends Field> = T extends string ? 'string' : T extends number ? 'number' : T extends boolean ? 'boolean' : T extends List<infer U> ? ListSpec<U> : new (...args: any[]) => T;
+ ? number
+ : T extends 'boolean'
+ ? boolean
+ : T extends ListSpec<infer U>
+ ? List<U>
+ : // T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never;
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ T extends DefaultFieldConstructor<infer _U>
+ ? never
+ : T extends { new (...args: any[]): List<FieldType> }
+ ? never
+ : T extends { new (...args: any[]): infer R }
+ ? R
+ : T extends (doc?: Doc) => infer R
+ ? R
+ : never;
+export interface Interface {
+ [key: string]: InterfaceValue;
+ // [key: string]: ToConstructor<Field> | ListSpec<Field[]>;
+}
export type ToInterface<T extends Interface> = {
[P in Exclude<keyof T, 'proto'>]: T[P] extends DefaultFieldConstructor<infer F> ? Exclude<FieldResult<F>, undefined> : FieldResult<ToType<T[P]>>;
};
-// type ListSpec<T extends Field[]> = { List: ToContructor<Head<T>> | ListSpec<Tail<T>> };
-export type ListSpec<T extends Field> = { List: ToConstructor<T> };
-
-export type DefaultFieldConstructor<T extends Field> = {
- type: ToConstructor<T>;
- defaultVal: T;
-};
-
// type ListType<U extends Field[]> = { 0: List<ListType<Tail<U>>>, 1: ToType<Head<U>> }[HasTail<U> extends true ? 0 : 1];
export type Head<T extends any[]> = T extends [any, ...any[]] ? T[0] : never;
export type Tail<T extends any[]> = ((...t: T) => any) extends (_: any, ...tail: infer TT) => any ? TT : [];
export type HasTail<T extends any[]> = T extends [] | [any] ? false : true;
+// TODO Allow you to optionally specify default values for schemas, which should then make that field not be partial
+export type WithoutRefField<T extends FieldType> = T extends RefField ? never : T;
-export type InterfaceValue = ToConstructor<Field> | ListSpec<Field> | DefaultFieldConstructor<Field> | ((doc?: Doc) => any);
-//TODO Allow you to optionally specify default values for schemas, which should then make that field not be partial
-export interface Interface {
- [key: string]: InterfaceValue;
- // [key: string]: ToConstructor<Field> | ListSpec<Field[]>;
-}
-export type WithoutRefField<T extends Field> = T extends RefField ? never : T;
+export type CastCtor = ToConstructor<FieldType> | ListSpec<FieldType>;
-export type CastCtor = ToConstructor<Field> | ListSpec<Field>;
+type WithoutList<T extends FieldType> = T extends List<infer R> ? (R extends RefField ? (R | Promise<R>)[] : R[]) : T;
export function Cast<T extends CastCtor>(field: FieldResult, ctor: T): FieldResult<ToType<T>>;
+// eslint-disable-next-line no-redeclare
export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal: WithoutList<WithoutRefField<ToType<T>>> | null): WithoutList<ToType<T>>;
+// eslint-disable-next-line no-redeclare
export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal?: ToType<T> | null): FieldResult<ToType<T>> | undefined {
if (field instanceof Promise) {
return defaultVal === undefined ? (field.then(f => Cast(f, ctor) as any) as any) : defaultVal === null ? undefined : defaultVal;
}
if (field !== undefined && !(field instanceof Promise)) {
if (typeof ctor === 'string') {
+ // eslint-disable-next-line valid-typeof
if (typeof field === ctor) {
return field as ToType<T>;
}
@@ -80,6 +86,10 @@ export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal
return defaultVal === null ? undefined : defaultVal;
}
+export function toList(doc: Doc | Doc[]) {
+ return doc instanceof Doc ? [doc] : doc;
+}
+
export function DocCast(field: FieldResult, defaultVal?: Doc) {
const doc = Cast(field, Doc, null);
return doc && !(doc instanceof Promise) ? doc : (defaultVal as Doc);
@@ -112,22 +122,25 @@ export function CsvCast(field: FieldResult, defaultVal: CsvField | null = null)
export function WebCast(field: FieldResult, defaultVal: WebField | null = null) {
return Cast(field, WebField, defaultVal);
}
+export function PDFCast(field: FieldResult, defaultVal: PdfField | null = null) {
+ return Cast(field, PdfField, defaultVal);
+}
export function ImageCast(field: FieldResult, defaultVal: ImageField | null = null) {
return Cast(field, ImageField, defaultVal);
}
-type WithoutList<T extends Field> = T extends List<infer R> ? (R extends RefField ? (R | Promise<R>)[] : R[]) : T;
-
-export function FieldValue<T extends Field, U extends WithoutList<T>>(field: FieldResult<T>, defaultValue: U): WithoutList<T>;
-export function FieldValue<T extends Field>(field: FieldResult<T>): Opt<T>;
-export function FieldValue<T extends Field>(field: FieldResult<T>, defaultValue?: T): Opt<T> {
+export function FieldValue<T extends FieldType, U extends WithoutList<T>>(field: FieldResult<T>, defaultValue: U): WithoutList<T>;
+// eslint-disable-next-line no-redeclare
+export function FieldValue<T extends FieldType>(field: FieldResult<T>): Opt<T>;
+// eslint-disable-next-line no-redeclare
+export function FieldValue<T extends FieldType>(field: FieldResult<T>, defaultValue?: T): Opt<T> {
return field instanceof Promise || field === undefined ? defaultValue : field;
}
export interface PromiseLike<T> {
then(callback: (field: Opt<T>) => void): void;
}
-export function PromiseValue<T extends Field>(field: FieldResult<T>): PromiseLike<Opt<T>> {
+export function PromiseValue<T extends FieldType>(field: FieldResult<T>): PromiseLike<Opt<T>> {
if (field instanceof Promise) return field as Promise<Opt<T>>;
return {
then(cb: (field: Opt<T>) => void) {
diff --git a/src/fields/URLField.ts b/src/fields/URLField.ts
index 87334ad16..3a83e7ca0 100644
--- a/src/fields/URLField.ts
+++ b/src/fields/URLField.ts
@@ -1,18 +1,14 @@
+import { custom, serializable } from 'serializr';
+import { ClientUtils } from '../ClientUtils';
+import { scriptingGlobal } from '../client/util/ScriptingGlobals';
import { Deserializable } from '../client/util/SerializationHelper';
-import { serializable, custom } from 'serializr';
+import { Copy, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
import { ObjectField } from './ObjectField';
-import { ToScriptString, ToString, Copy, ToJavascriptString } from './FieldSymbols';
-import { scriptingGlobal } from '../client/util/ScriptingGlobals';
-import { Utils } from '../Utils';
function url() {
return custom(
- function (value: URL) {
- return value?.origin === window.location.origin ? value.pathname : value?.href;
- },
- function (jsonValue: string) {
- return new URL(jsonValue, window.location.origin);
- }
+ (value: URL) => (value?.origin === window.location.origin ? value.pathname : value?.href),
+ (jsonValue: string) => new URL(jsonValue, window.location.origin)
);
}
@@ -20,30 +16,34 @@ export abstract class URLField extends ObjectField {
@serializable(url())
readonly url: URL;
- constructor(url: string);
- constructor(url: URL);
- constructor(url: URL | string) {
+ constructor(urlVal: string);
+ // eslint-disable-next-line @typescript-eslint/no-shadow
+ constructor(urlVal: URL);
+ // eslint-disable-next-line @typescript-eslint/no-shadow
+ constructor(urlVal: URL | string) {
super();
- if (typeof url === 'string') {
- url = url.startsWith('http') ? new URL(url) : new URL(url, window.location.origin);
- }
- this.url = url;
+ this.url =
+ typeof urlVal !== 'string'
+ ? urlVal // it's an URL
+ : urlVal.startsWith('http')
+ ? new URL(urlVal)
+ : new URL(urlVal, window.location.origin);
}
[ToScriptString]() {
- if (Utils.prepend(this.url?.pathname) === this.url?.href) {
+ if (ClientUtils.prepend(this.url?.pathname) === this.url?.href) {
return `new ${this.constructor.name}("${this.url.pathname}")`;
}
return `new ${this.constructor.name}("${this.url?.href}")`;
}
[ToJavascriptString]() {
- if (Utils.prepend(this.url?.pathname) === this.url?.href) {
+ if (ClientUtils.prepend(this.url?.pathname) === this.url?.href) {
return `new ${this.constructor.name}("${this.url.pathname}")`;
}
return `new ${this.constructor.name}("${this.url?.href}")`;
}
[ToString]() {
- if (Utils.prepend(this.url?.pathname) === this.url?.href) {
+ if (ClientUtils.prepend(this.url?.pathname) === this.url?.href) {
return this.url.pathname;
}
return this.url?.href;
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
index 1cacfe30c..335683270 100644
--- a/src/fields/documentSchemas.ts
+++ b/src/fields/documentSchemas.ts
@@ -86,7 +86,6 @@ export const documentSchema = createSchema({
followLinkLocation: 'string', // flag for where to place content when following a click interaction (e.g., add:right, lightbox, default, )
hideLinkButton: 'boolean', // whether the blue link counter button should be hidden
layout_hideAllLinks: 'boolean', // whether all individual blue anchor dots should be hidden
- link_displayLine: 'boolean', // whether a link connection should be shown between link anchor endpoints.
isLightbox: 'boolean', // whether the marked object will display addDocTab() calls that target "lightbox" destinations
layers: listSpec('string'), // which layers the document is part of
_lockedPosition: 'boolean', // whether the document can be moved (dragged)
@@ -104,7 +103,7 @@ export const documentSchema = createSchema({
export const collectionSchema = createSchema({
childLayoutTemplate: Doc, // layout template to use to render children of a collecion
- childLayoutString: 'string', //layout string to use to render children of a collection
+ childLayoutString: 'string', // layout string to use to render children of a collection
childClickedOpenTemplateView: Doc, // layout template to apply to a child when its clicked on in a collection and opened (requires onChildClick or other script to read this value and apply template)
childDontRegisterViews: 'boolean', // whether views made of this document are registered so that they can be found when drawing links
onChildClick: ScriptField, // script to run for each child when its clicked
@@ -113,4 +112,5 @@ export const collectionSchema = createSchema({
});
export type Document = makeInterface<[typeof documentSchema]>;
+// eslint-disable-next-line no-redeclare
export const Document = makeInterface(documentSchema);
diff --git a/src/fields/util.ts b/src/fields/util.ts
index b73520999..a6499c3e3 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -1,12 +1,11 @@
import { $mobx, action, observable, runInAction, trace } from 'mobx';
import { computedFn } from 'mobx-utils';
-import { returnZero } from '../Utils';
+import { ClientUtils, returnZero } from '../ClientUtils';
import { DocServer } from '../client/DocServer';
-import { LinkManager } from '../client/util/LinkManager';
import { SerializationHelper } from '../client/util/SerializationHelper';
import { UndoManager } from '../client/util/UndoManager';
-import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, ReverseHierarchyMap, StrListCast, aclLevel, updateCachedAcls } from './Doc';
-import { AclAdmin, AclAugment, AclEdit, AclPrivate, DocAcl, DocData, DocLayout, FieldKeys, ForceServerWrite, Height, Initializing, SelfProxy, UpdatingFromServer, Width } from './DocSymbols';
+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 { ObjectField } from './ObjectField';
@@ -17,22 +16,43 @@ import { SchemaHeaderField } from './SchemaHeaderField';
import { ComputedField } from './ScriptField';
import { DocCast, ScriptCast, StrCast } from './Types';
+/**
+ * These are the various levels of access a user can have to a document.
+ *
+ * Admin: a user with admin access to a document can remove/edit that document, add/remove/edit annotations (depending on permissions), as well as change others' access rights to that document.
+ * Edit: a user with edit access to a document can remove/edit that document, add/remove/edit annotations (depending on permissions), but not change any access rights to that document.
+ * Add: a user with add access to a document can augment documents/annotations to that document but cannot edit or delete anything.
+ * View: a user with view access to a document can only view it - they cannot add/remove/edit anything.
+ * None: the document is not shared with that user.
+ * Unset: Remove a sharing permission (eg., used )
+ */
+export enum SharingPermissions {
+ Admin = 'Admin',
+ Edit = 'Edit',
+ Augment = 'Augment',
+ View = 'View',
+ None = 'Not-Shared',
+}
+
function _readOnlySetter(): never {
throw new Error("Documents can't be modified in read-only mode");
}
-var tracing = false;
+// eslint-disable-next-line prefer-const
+let tracing = false;
export function TraceMobx() {
tracing && trace();
}
-const _setterImpl = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+export const _propSetterCB = new Map<string, ((target: any, value: any) => void) | undefined>();
+
+const _setterImpl = action((target: any, prop: string | symbol | number, valueIn: any, receiver: any): boolean => {
if (SerializationHelper.IsSerializing() || typeof prop === 'symbol') {
- target[prop] = value;
+ target[prop] = valueIn;
return true;
}
- value = value?.[SelfProxy] ?? value; // convert any Doc type values to Proxy's
+ let value = valueIn?.[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])) {
@@ -49,6 +69,7 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
throw new Error("Can't put the same object in multiple documents at the same time");
}
value[Parent] = receiver;
+ // eslint-disable-next-line no-use-before-define
value[FieldChanged] = containedFieldChangedHandler(receiver, prop, value);
}
if (curValue instanceof ObjectField) {
@@ -56,11 +77,14 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
delete curValue[FieldChanged];
}
+ if (typeof prop === 'string' && _propSetterCB.has(prop)) _propSetterCB.get(prop)!(target[SelfProxy], value);
+
+ // eslint-disable-next-line no-use-before-define
const effectiveAcl = GetEffectiveAcl(target);
const writeMode = DocServer.getFieldWriteMode(prop as string);
const fromServer = target[UpdatingFromServer];
- const sameAuthor = fromServer || receiver.author === Doc.CurrentUserEmail;
+ const sameAuthor = fromServer || receiver.author === ClientUtils.CurrentUserEmail();
const writeToDoc =
sameAuthor || effectiveAcl === AclEdit || effectiveAcl === AclAdmin || writeMode === DocServer.WriteMode.Playground || writeMode === DocServer.WriteMode.LivePlayground || (effectiveAcl === AclAugment && value instanceof RichTextField);
const writeToServer =
@@ -83,7 +107,7 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
if (value === undefined)
(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);
+ if (prop === 'author' || prop.toString().startsWith('acl_')) updateCachedAcls(target);
} else {
DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
}
@@ -92,7 +116,9 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
(!receiver[UpdatingFromServer] || receiver[ForceServerWrite]) &&
UndoManager.AddEvent(
{
- redo: () => (receiver[prop] = value),
+ redo: () => {
+ receiver[prop] = value;
+ },
undo: () => {
const wasUpdate = receiver[UpdatingFromServer];
const wasForce = receiver[ForceServerWrite];
@@ -128,57 +154,16 @@ export function denormalizeEmail(email: string) {
return email.replace(/__/g, '.');
}
-/**
- * Copies parent's acl fields to the child
- */
-export function inheritParentAcls(parent: Doc, child: Doc, layoutOnly: boolean) {
- [...Object.keys(parent), ...(Doc.CurrentUserEmail !== parent.author ? ['acl-Owner'] : [])]
- .filter(key => key.startsWith('acl'))
- .forEach(key => {
- // if the default acl mode is private, then don't inherit the acl-guest permission, but set it to private.
- // const permission: string = key === 'acl-guest' && Doc.defaultAclPrivate ? AclPrivate : parent[key];
- const parAcl = ReverseHierarchyMap.get(StrCast(key === 'acl-Owner' ? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Edit) : parent[key]))?.acl;
- if (parAcl) {
- const sharePermission = HierarchyMapping.get(parAcl)?.name;
- sharePermission && distributeAcls(key === 'acl-Owner' ? `acl-${normalizeEmail(StrCast(parent.author))}` : key, sharePermission, child, undefined, false, layoutOnly);
- }
- });
-}
-
-/**
- * These are the various levels of access a user can have to a document.
- *
- * Admin: a user with admin access to a document can remove/edit that document, add/remove/edit annotations (depending on permissions), as well as change others' access rights to that document.
- *
- * Edit: a user with edit access to a document can remove/edit that document, add/remove/edit annotations (depending on permissions), but not change any access rights to that document.
- *
- * Add: a user with add access to a document can augment documents/annotations to that document but cannot edit or delete anything.
- *
- * View: a user with view access to a document can only view it - they cannot add/remove/edit anything.
- *
- * None: the document is not shared with that user.
- *
- * Unset: Remove a sharing permission (eg., used )
- */
-export enum SharingPermissions {
- Admin = 'Admin',
- Edit = 'Edit',
- Augment = 'Augment',
- View = 'View',
- None = 'Not-Shared',
-}
-
// return acl from cache or cache the acl and return.
-const getEffectiveAclCache = computedFn(function (target: any, user?: string) {
- return getEffectiveAcl(target, user);
-}, true);
+// eslint-disable-next-line no-use-before-define
+const getEffectiveAclCache = computedFn((target: any, 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 {
if (!target) return AclPrivate;
- if (target[UpdatingFromServer] || Doc.CurrentUserEmail === 'guest') return AclAdmin;
+ 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)
}
@@ -188,10 +173,9 @@ export function GetPropAcl(target: any, prop: string | symbol | number) {
return GetEffectiveAcl(target);
}
-let cachedGroups = observable([] as string[]);
-const getCachedGroupByNameCache = computedFn(function (name: string) {
- return cachedGroups.includes(name);
-}, true);
+const cachedGroups = observable([] as string[]);
+const getCachedGroupByNameCache = computedFn((name: string) => cachedGroups.includes(name), true);
+
export function GetCachedGroupByName(name: string) {
return getCachedGroupByNameCache(name);
}
@@ -200,12 +184,12 @@ export function SetCachedGroups(groups: string[]) {
}
function getEffectiveAcl(target: any, user?: string): symbol {
const targetAcls = target[DocAcl];
- if (targetAcls?.['acl-Me'] === AclAdmin || GetCachedGroupByName('Admin')) return AclAdmin;
+ if (targetAcls?.acl_Me === AclAdmin || GetCachedGroupByName('Admin')) return AclAdmin;
- const userChecked = user || Doc.CurrentUserEmail; // if the current user is the author of the document / the current user is a member of the admin group
+ const userChecked = user || ClientUtils.CurrentUserEmail(); // if the current user is the author of the document / the current user is a member of the admin group
if (targetAcls && Object.keys(targetAcls).length) {
let effectiveAcl = AclPrivate;
- for (const [key, value] of Object.entries(targetAcls)) {
+ Object.entries(targetAcls).forEach(([key, value]) => {
// there are issues with storing fields with . in the name, so they are replaced with _ during creation
// as a result we need to restore them again during this comparison.
const entity = denormalizeEmail(key.substring(4)); // an individual or a group
@@ -214,7 +198,7 @@ function getEffectiveAcl(target: any, user?: string): symbol {
effectiveAcl = value as symbol;
}
}
- }
+ });
return DocServer?.Control?.isReadOnly?.() && HierarchyMapping.get(effectiveAcl)!.level < aclLevel.editable ? AclEdit : effectiveAcl;
}
@@ -226,16 +210,16 @@ function getEffectiveAcl(target: any, user?: string): symbol {
/**
* Recursively distributes the access right for a user across the children of a document and its annotations.
- * @param key the key storing the access right (e.g. acl-groupname)
+ * @param key the key storing the access right (e.g. acl_groupname)
* @param acl the access right being stored (e.g. "Can Edit")
* @param target the document on which this access right is being set
* @param visited list of Doc's already distributed to.
* @param allowUpgrade whether permissions can be made less restrictive
* @param layoutOnly just sets the layout doc's ACL (unless the data doc has no entry for the ACL, in which case it will be set as well)
*/
-export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, visited?: Doc[], allowUpgrade?: boolean, layoutOnly = false) {
- const selfKey = `acl-${normalizeEmail(Doc.CurrentUserEmail)}`;
- if (!visited) visited = [] as Doc[];
+// eslint-disable-next-line default-param-last
+export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, visited: Doc[] = [], allowUpgrade?: boolean, layoutOnly = false) {
+ const selfKey = `acl_${normalizeEmail(ClientUtils.CurrentUserEmail())}`;
if (!target || visited.includes(target) || key === selfKey) return;
visited.push(target);
@@ -246,23 +230,21 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
if (!layoutOnly && dataDoc && (allowUpgrade !== false || !dataDoc[key] || curVal > aclVal)) {
// propagate ACLs to links, children, and annotations
- LinkManager.Links(dataDoc).forEach(link => distributeAcls(key, acl, link, visited, allowUpgrade ? true : false));
+ dataDoc[DirectLinks].forEach(link => distributeAcls(key, acl, link, visited, !!allowUpgrade));
DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc)]).forEach(d => {
- distributeAcls(key, acl, d, visited, allowUpgrade ? true : false);
- d !== d[DocData] && distributeAcls(key, acl, d[DocData], visited, allowUpgrade ? true : false);
+ distributeAcls(key, acl, d, visited, !!allowUpgrade);
+ d !== d[DocData] && distributeAcls(key, acl, d[DocData], visited, !!allowUpgrade);
});
DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc) + '_annotations']).forEach(d => {
- distributeAcls(key, acl, d, visited, allowUpgrade ? true : false);
- d !== d[DocData] && distributeAcls(key, acl, d[DocData], visited, allowUpgrade ? true : false);
+ distributeAcls(key, acl, d, visited, !!allowUpgrade);
+ d !== d[DocData] && distributeAcls(key, acl, d[DocData], visited, !!allowUpgrade);
});
Object.keys(target) // share expanded layout templates (eg, for presElementBox'es )
.filter(lkey => lkey.includes('layout[') && DocCast(target[lkey]))
- .map(lkey => {
- distributeAcls(key, acl, DocCast(target[lkey]), visited, allowUpgrade ? true : false);
- });
+ .forEach(lkey => distributeAcls(key, acl, DocCast(target[lkey]), visited, !!allowUpgrade));
if (GetEffectiveAcl(dataDoc) === AclAdmin) {
dataDoc[key] = acl;
@@ -282,15 +264,46 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
dataDocChanged && updateCachedAcls(dataDoc);
}
+/**
+ * Copies parent's acl fields to the child
+ */
+export function inheritParentAcls(parent: Doc, child: Doc, layoutOnly: boolean) {
+ [...Object.keys(parent), ...(ClientUtils.CurrentUserEmail() !== parent.author ? ['acl_Owner'] : [])]
+ .filter(key => key.startsWith('acl_'))
+ .forEach(key => {
+ // if the default acl mode is private, then don't inherit the acl_guest permission, but set it to private.
+ // const permission: string = key === 'acl_Guest' && Doc.defaultAclPrivate ? AclPrivate : parent[key];
+ const parAcl = ReverseHierarchyMap.get(StrCast(key === 'acl_Owner' ? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Edit) : parent[key]))?.acl;
+ if (parAcl) {
+ const sharePermission = HierarchyMapping.get(parAcl)?.name;
+ sharePermission && distributeAcls(key === 'acl_Owner' ? `acl_${normalizeEmail(StrCast(parent.author))}` : key, sharePermission, child, undefined, false, layoutOnly);
+ }
+ });
+}
+
+/**
+ * sets a callback function to be called whenever a value is assigned to the specified field key.
+ * For example, this is used to "publish" documents with titles that start with '@'
+ * @param prop
+ * @param propSetter
+ */
+export function SetPropSetterCb(prop: string, propSetter: ((target: any, value: any) => void) | undefined) {
+ _propSetterCB.set(prop, propSetter);
+}
+
//
// target should be either a Doc or ListImpl. receiver should be a Proxy<Doc> Or List.
//
-export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean {
- let prop = in_prop;
- const effectiveAcl = in_prop === 'constructor' || typeof in_prop === 'symbol' ? AclAdmin : GetPropAcl(target, prop);
+export function setter(target: any, inProp: string | symbol | number, value: any, receiver: any): boolean {
+ if (!inProp) {
+ console.log('WARNING: trying to set an empty property. This should be fixed. ');
+ return false;
+ }
+ let prop = inProp;
+ 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))) return true;
if (typeof prop === 'string' && prop !== '__id' && prop !== '__fieldTuples' && prop.startsWith('_')) {
if (!prop.startsWith('__')) prop = prop.substring(1);
@@ -301,12 +314,24 @@ export function setter(target: any, in_prop: string | symbol | number, value: an
}
if (target.__fieldTuples[prop] instanceof ComputedField) {
if (target.__fieldTuples[prop].setterscript && value !== undefined && !(value instanceof ComputedField)) {
- return ScriptCast(target.__fieldTuples[prop])?.setterscript?.run({ self: target[SelfProxy], this: target[SelfProxy], value }).success ? true : false;
+ return !!ScriptCast(target.__fieldTuples[prop])?.setterscript?.run({ self: target[SelfProxy], this: target[SelfProxy], value }).success;
}
}
return _setter(target, prop, value, receiver);
}
+function getFieldImpl(target: any, prop: string | number, proxy: any, ignoreProto: boolean = false): any {
+ const field = target.__fieldTuples[prop];
+ const value = field?.[ToValue]?.(proxy); // converts ComputedFields to values, or unpacks ProxyFields into Proxys
+ if (value) return value.value;
+ if (field === undefined && !ignoreProto && prop !== 'proto') {
+ const proto = getFieldImpl(target, 'proto', proxy, true); // TODO tfs: instead of proxy we could use target[SelfProxy]... I don't which semantics we want or if it really matters
+ if (proto instanceof Doc && GetEffectiveAcl(proto) !== AclPrivate) {
+ return getFieldImpl(proto, prop, proxy, ignoreProto);
+ }
+ }
+ return field;
+}
export function getter(target: any, prop: string | symbol, proxy: any): any {
// prettier-ignore
switch (prop) {
@@ -318,6 +343,7 @@ export function getter(target: any, prop: string | symbol, proxy: any): any {
case $mobx: return target.__fieldTuples[prop];
case DocLayout: return target.__LAYOUT__;
case Height: case Width: if (GetEffectiveAcl(target) === AclPrivate) return returnZero;
+ // eslint-disable-next-line no-fallthrough
default :
if (typeof prop === 'symbol') return target[prop];
if (prop.startsWith('isMobX')) return target[prop];
@@ -325,23 +351,11 @@ export function getter(target: any, prop: string | symbol, proxy: any): any {
if (GetEffectiveAcl(target) === AclPrivate && prop !== 'author') return undefined;
}
- const layout_prop = prop.startsWith('_') ? prop.substring(1) : undefined;
- if (layout_prop && target.__LAYOUT__) return target.__LAYOUT__[layout_prop];
- return getFieldImpl(target, layout_prop ?? prop, proxy);
+ const layoutProp = prop.startsWith('_') ? prop.substring(1) : undefined;
+ if (layoutProp && target.__LAYOUT__) return target.__LAYOUT__[layoutProp];
+ return getFieldImpl(target, layoutProp ?? prop, proxy);
}
-function getFieldImpl(target: any, prop: string | number, proxy: any, ignoreProto: boolean = false): any {
- const field = target.__fieldTuples[prop];
- const value = field?.[ToValue]?.(proxy); // converts ComputedFields to values, or unpacks ProxyFields into Proxys
- if (value) return value.value;
- if (field === undefined && !ignoreProto && prop !== 'proto') {
- const proto = getFieldImpl(target, 'proto', proxy, true); //TODO tfs: instead of proxy we could use target[SelfProxy]... I don't which semantics we want or if it really matters
- if (proto instanceof Doc && GetEffectiveAcl(proto) !== AclPrivate) {
- return getFieldImpl(proto, prop, proxy, ignoreProto);
- }
- }
- return field;
-}
export function getField(target: any, prop: string | number, ignoreProto: boolean = false): any {
return getFieldImpl(target, prop, target[SelfProxy], ignoreProto);
}
@@ -364,10 +378,10 @@ 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<Field> | Doc, prop: string | number, liveContainedField: ObjectField) {
+export function containedFieldChangedHandler(container: List<FieldType> | Doc, prop: string | number, liveContainedField: ObjectField) {
let lastValue: FieldResult = liveContainedField instanceof ObjectField ? ObjectField.MakeCopy(liveContainedField) : liveContainedField;
- return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: Field[] | undefined; length: number | undefined; hint?: any }, dummyServerOp?: any) => {
- const serializeItems = () => ({ __type: 'list', fields: diff?.items?.map((item: Field) => SerializationHelper.Serialize(item)) });
+ return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: any } /* , 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 }
@@ -383,8 +397,8 @@ export function containedFieldChangedHandler(container: List<Field> | Doc, prop:
UndoManager.AddEvent(
{
redo: () => {
- //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));
+ // 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]);
},
undo: action(() => {
@@ -398,7 +412,7 @@ export function containedFieldChangedHandler(container: List<Field> | Doc, prop:
});
lastValue = ObjectField.MakeCopy((container as any)[prop as any]);
}),
- prop: 'add ' + diff.items?.length + ' items to list',
+ prop: 'add ' + (diff.items?.length ?? 0) + ' items to list',
},
diff?.items
);
@@ -429,12 +443,14 @@ export function containedFieldChangedHandler(container: List<Field> | Doc, prop:
});
lastValue = ObjectField.MakeCopy((container as any)[prop as any]);
},
- prop: 'remove ' + diff.items?.length + ' items from list',
+ prop: 'remove ' + (diff.items?.length ?? 0) + ' items from list(' + ((container as any)?.title ?? '') + ':' + prop + ')',
},
diff?.items
);
} else {
- const setFieldVal = (val: Field | undefined) => (container instanceof Doc ? (container[prop as string] = val) : (container[prop as number] = val as Field));
+ const setFieldVal = (val: FieldType | undefined) => {
+ container instanceof Doc ? (container[prop as string] = val) : (container[prop as number] = val as FieldType);
+ };
UndoManager.AddEvent(
{
redo: () => {
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index e333e6a2e..7a1e35636 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -1,9 +1,11 @@
+/* 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';
import * as React from 'react';
import * as rp from 'request-promise';
-import { Utils } from '../Utils';
+import { ClientUtils } from '../ClientUtils';
import { DocServer } from '../client/DocServer';
import { Networking } from '../client/Network';
import { Docs } from '../client/documents/Documents';
@@ -13,8 +15,9 @@ import { List } from '../fields/List';
import { listSpec } from '../fields/Schema';
import { Cast } from '../fields/Types';
import './ImageUpload.scss';
-import { MobileInterface } from './MobileInterface';
-const { default: { DFLT_IMAGE_NATIVE_DIM } } = require('../client/views/global/globalCssVariables.module.scss'); // prettier-ignore
+
+const { DFLT_IMAGE_NATIVE_DIM } = require('../client/views/global/globalCssVariables.module.scss'); // prettier-ignore
+
export interface ImageUploadProps {
Document: Doc; // Target document for upload (upload location)
}
@@ -24,28 +27,30 @@ const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', ''));
@observer
export class Uploader extends React.Component<ImageUploadProps> {
- @observable error: string = '';
@observable nm: string = 'Choose files'; // Text of 'Choose Files' button
@observable process: string = ''; // Current status of upload
+ @observable private dialogueBoxOpacity = 1;
onClick = async () => {
try {
+ // eslint-disable-next-line react/destructuring-assignment
const col = this.props.Document;
await Docs.Prototypes.initialize();
const imgPrev = document.getElementById('img_preview');
this.setOpacity(1, '1'); // Slab 1
- if (imgPrev) {
- const files: FileList | null = inputRef.current!.files;
+ if (imgPrev && inputRef.current) {
+ const { files } = inputRef.current;
this.setOpacity(2, '1'); // Slab 2
if (files && files.length !== 0) {
this.process = 'Uploading Files';
for (let index = 0; index < files.length; ++index) {
const file = files[index];
+ // eslint-disable-next-line no-await-in-loop
const res = await Networking.UploadFilesToServer({ file });
this.setOpacity(3, '1'); // Slab 3
// For each item that the user has selected
res.map(async ({ result }) => {
- const name = file.name;
+ const { name } = file;
if (result instanceof Error) {
return;
}
@@ -62,17 +67,17 @@ export class Uploader extends React.Component<ImageUploadProps> {
doc = Docs.Create.ImageDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name });
}
this.setOpacity(4, '1'); // Slab 4
- const res = await rp.get(Utils.prepend('/getUserDocumentIds'));
- if (!res) {
+ const docidsRes = await rp.get(ClientUtils.prepend('/getUserDocumentIds'));
+ if (!docidsRes) {
throw new Error('No user id returned');
}
- const field = await DocServer.GetRefField(JSON.parse(res).userDocumentId);
+ const field = await DocServer.GetRefField(JSON.parse(docidsRes).userDocumentId);
let pending: Opt<Doc>;
if (field instanceof Doc) {
pending = col;
}
if (pending) {
- const data = await Cast(pending.data, listSpec(Doc));
+ const data = Cast(pending.data, listSpec(Doc));
if (data) data.push(doc);
else pending.data = new List([doc]);
this.setOpacity(5, '1'); // Slab 5
@@ -93,22 +98,49 @@ export class Uploader extends React.Component<ImageUploadProps> {
setTimeout(this.clearUpload, 3000);
}
} catch (error) {
- this.error = JSON.stringify(error);
+ console.log(JSON.stringify(error));
}
};
+ // Returns the upload interface for mobile
+ private get uploadInterface() {
+ return (
+ <div className="imgupload_cont">
+ <div className="closeUpload" onClick={() => this.closeUpload()}>
+ <FontAwesomeIcon icon="window-close" size="lg" />
+ </div>
+ <FontAwesomeIcon icon="upload" size="lg" style={{ fontSize: '130' }} />
+ <input type="file" accept="application/pdf, video/*,image/*" className={`inputFile ${this.nm !== 'Choose files' ? 'active' : ''}`} id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple />
+ <label className="file" id="label" htmlFor="input_image_file">
+ {this.nm}
+ </label>
+ <div className="upload_label" onClick={this.onClick}>
+ Upload
+ </div>
+ <img id="img_preview" src="" alt="" />
+ <div className="loadingImage">
+ <div className="loadingSlab" id="slab1" />
+ <div className="loadingSlab" id="slab2" />
+ <div className="loadingSlab" id="slab3" />
+ <div className="loadingSlab" id="slab4" />
+ <div className="loadingSlab" id="slab5" />
+ <div className="loadingSlab" id="slab6" />
+ <div className="loadingSlab" id="slab7" />
+ </div>
+ <p className="status">{this.process}</p>
+ </div>
+ );
+ }
+
// Updates label after a files is selected (so user knows a file is uploaded)
inputLabel = async () => {
- const files: FileList | null = inputRef.current!.files;
- await files;
+ const files: FileList | null = await inputRef.current!.files;
if (files && files.length === 1) {
this.nm = files[0].name;
} else if (files && files.length > 1) {
this.nm = files.length.toString() + ' files selected';
}
- };
-
- // Loops through load icons, and resets buttons
+ }; // Loops through load icons, and resets buttons
@action
clearUpload = () => {
for (let i = 1; i < 8; i++) {
@@ -125,7 +157,6 @@ export class Uploader extends React.Component<ImageUploadProps> {
// Clears the upload and closes the upload menu
closeUpload = () => {
this.clearUpload();
- MobileInterface.Instance.toggleUpload();
};
// Handles the setting of the loading bar
@@ -134,40 +165,7 @@ export class Uploader extends React.Component<ImageUploadProps> {
if (slab) slab.style.opacity = opacity;
};
- // Returns the upload interface for mobile
- private get uploadInterface() {
- return (
- <div className="imgupload_cont">
- <div className="closeUpload" onClick={() => this.closeUpload()}>
- <FontAwesomeIcon icon="window-close" size={'lg'} />
- </div>
- <FontAwesomeIcon icon="upload" size="lg" style={{ fontSize: '130' }} />
- <input type="file" accept="application/pdf, video/*,image/*" className={`inputFile ${this.nm !== 'Choose files' ? 'active' : ''}`} id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple></input>
- <label className="file" id="label" htmlFor="input_image_file">
- {this.nm}
- </label>
- <div className="upload_label" onClick={this.onClick}>
- Upload
- </div>
- <img id="img_preview" src=""></img>
- <div className="loadingImage">
- <div className="loadingSlab" id="slab1" />
- <div className="loadingSlab" id="slab2" />
- <div className="loadingSlab" id="slab3" />
- <div className="loadingSlab" id="slab4" />
- <div className="loadingSlab" id="slab5" />
- <div className="loadingSlab" id="slab6" />
- <div className="loadingSlab" id="slab7" />
- </div>
- <p className="status">{this.process}</p>
- </div>
- );
- }
-
- @observable private dialogueBoxOpacity = 1;
- @observable private overlayOpacity = 0.4;
-
render() {
- return <MainViewModal contents={this.uploadInterface} isDisplayed={true} interactive={true} dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.closeUpload} />;
+ return <MainViewModal contents={this.uploadInterface} isDisplayed interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} closeOnExternalClick={this.closeUpload} />;
}
}
diff --git a/src/mobile/MobileInkOverlay.tsx b/src/mobile/MobileInkOverlay.tsx
index 23e19585a..6babd2f39 100644
--- a/src/mobile/MobileInkOverlay.tsx
+++ b/src/mobile/MobileInkOverlay.tsx
@@ -4,7 +4,7 @@ import * as React from 'react';
import { DocServer } from '../client/DocServer';
import { DragManager } from '../client/util/DragManager';
import { Doc } from '../fields/Doc';
-import { GestureUtils } from '../pen-gestures/GestureUtils';
+import { Gestures } from '../pen-gestures/GestureTypes';
import { GestureContent, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent } from '../server/Message';
import './MobileInkOverlay.scss';
@@ -76,11 +76,11 @@ export default class MobileInkOverlay extends React.Component {
const target = document.elementFromPoint(this._x + 10, this._y + 10);
target?.dispatchEvent(
- new CustomEvent<GestureUtils.GestureEvent>('dashOnGesture', {
+ new CustomEvent<GestureEvent>('dashOnGesture', {
bubbles: true,
detail: {
points: points,
- gesture: GestureUtils.Gestures.Stroke,
+ gesture: Gestures.Stroke,
bounds: B,
},
})
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index dc4af8303..d8ba89fdb 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -60,6 +60,7 @@ import {
faLongArrowAltLeft,
faLongArrowAltRight,
faMicrophone,
+ faCircleHalfStroke,
faMinus,
faMobile,
faMousePointer,
@@ -92,7 +93,6 @@ import {
faTrash,
faTrashAlt,
faTree,
- faRoute,
faTv,
faUndoAlt,
faVideo,
@@ -104,7 +104,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../Utils';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../ClientUtils';
import { CollectionViewType, DocumentType } from '../client/documents/DocumentTypes';
import { Docs, DocumentOptions } from '../client/documents/Documents';
import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
@@ -112,8 +112,8 @@ import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
import { SettingsManager } from '../client/util/SettingsManager';
import { Transform } from '../client/util/Transform';
import { UndoManager } from '../client/util/UndoManager';
+import { DashboardView } from '../client/views/DashboardView';
import { GestureOverlay } from '../client/views/GestureOverlay';
-import { TabDocView } from '../client/views/collections/TabDocView';
import { AudioBox } from '../client/views/nodes/AudioBox';
import { DocumentView } from '../client/views/nodes/DocumentView';
import { RadialMenu } from '../client/views/nodes/RadialMenu';
@@ -127,6 +127,7 @@ import './AudioUpload.scss';
import { Uploader } from './ImageUpload';
import './ImageUpload.scss';
import './MobileInterface.scss';
+import { emptyFunction } from '../Utils';
library.add(
...[
@@ -197,6 +198,7 @@ library.add(
faHighlighter,
faLongArrowAltRight,
faMicrophone,
+ faCircleHalfStroke,
faMousePointer,
faMusic,
faObjectGroup,
@@ -583,7 +585,7 @@ export class MobileInterface extends React.Component {
};
const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
- const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row');
+ const dashboardDoc = DashboardView.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row');
const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`);
@@ -690,7 +692,7 @@ export class MobileInterface extends React.Component {
// Only making button available if it is an image
if (!(this._activeDoc.type === 'collection' || this._activeDoc.type === 'presentation')) {
return (
- <div className="docButton" title={'Pin to presentation'} style={{ backgroundColor: 'white', color: 'black' }} onClick={e => TabDocView.PinDoc(this._activeDoc, {})}>
+ <div className="docButton" title={'Pin to presentation'} style={{ backgroundColor: 'white', color: 'black' }} onClick={e => DocumentView.PinDoc(this._activeDoc, {})}>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
</div>
);
@@ -857,7 +859,7 @@ ScriptingGlobals.add(function switchToMobilePresentation() {
return MobileInterface.Instance.setupDefaultPresentation();
}, 'opens the presentation on Dash Mobile');
ScriptingGlobals.add(function openMobileSettings() {
- return SettingsManager.Instance.open();
+ return SettingsManager.Instance.openMgr();
}, 'opens settings on Dash Mobile');
// Other global functions for mobile
diff --git a/src/mobile/MobileMain.tsx b/src/mobile/MobileMain.tsx
index dc3a73def..07839b6f6 100644
--- a/src/mobile/MobileMain.tsx
+++ b/src/mobile/MobileMain.tsx
@@ -3,7 +3,7 @@ import * as ReactDOM from 'react-dom';
import { DocServer } from '../client/DocServer';
import { Docs } from '../client/documents/Documents';
import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
-import { AssignAllExtensions } from '../extensions/General/Extensions';
+import { AssignAllExtensions } from '../extensions/Extensions';
import { MobileInterface } from './MobileInterface';
AssignAllExtensions();
diff --git a/src/pen-gestures/GestureTypes.ts b/src/pen-gestures/GestureTypes.ts
new file mode 100644
index 000000000..d86562580
--- /dev/null
+++ b/src/pen-gestures/GestureTypes.ts
@@ -0,0 +1,16 @@
+export enum Gestures {
+ Line = 'line',
+ Stroke = 'stroke',
+ Scribble = 'scribble',
+ Text = 'text',
+ Triangle = 'triangle',
+ Circle = 'circle',
+ Rectangle = 'rectangle',
+ Arrow = 'arrow',
+}
+
+// Defines a point in an ink as a pair of x- and y-coordinates.
+export interface PointData {
+ X: number;
+ Y: number;
+}
diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts
index 41917aac9..28323d62f 100644
--- a/src/pen-gestures/GestureUtils.ts
+++ b/src/pen-gestures/GestureUtils.ts
@@ -1,32 +1,32 @@
import { Rect } from 'react-measure';
-import { PointData } from '../fields/InkField';
+import { Gestures, PointData } from './GestureTypes';
import { NDollarRecognizer } from './ndollar';
export namespace GestureUtils {
export class GestureEvent {
- constructor(readonly gesture: Gestures, readonly points: PointData[], readonly bounds: Rect, readonly text?: any) {}
+ readonly gesture: Gestures;
+ readonly points: PointData[];
+ readonly bounds: Rect;
+ readonly text?: any;
+
+ constructor(gesture: Gestures, points: PointData[], bounds: Rect, text?: any) {
+ this.gesture = gesture;
+ this.points = points;
+ this.bounds = bounds;
+ this.text = text;
+ }
}
export interface GestureEventDisposer {
(): void;
}
+ // eslint-disable-next-line no-undef
export function MakeGestureTarget(element: HTMLElement, func: (e: Event, ge: GestureEvent) => void): GestureEventDisposer {
const handler = (e: Event) => func(e, (e as CustomEvent<GestureEvent>).detail);
element.addEventListener('dashOnGesture', handler);
return () => element.removeEventListener('dashOnGesture', handler);
}
- export enum Gestures {
- Line = 'line',
- Stroke = 'stroke',
- Scribble = 'scribble',
- Text = 'text',
- Triangle = 'triangle',
- Circle = 'circle',
- Rectangle = 'rectangle',
- Arrow = 'arrow',
- }
-
export const GestureRecognizer = new NDollarRecognizer(false);
}
diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts
index 3ee9506cb..ff7f7310b 100644
--- a/src/pen-gestures/ndollar.ts
+++ b/src/pen-gestures/ndollar.ts
@@ -1,4 +1,5 @@
-import { GestureUtils } from './GestureUtils';
+/* eslint-disable no-use-before-define */
+import { Gestures } from './GestureTypes';
/**
* The $N Multistroke Recognizer (JavaScript version)
@@ -69,20 +70,34 @@ import { GestureUtils } from './GestureUtils';
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- **/
+ * */
//
// Point class
//
export class Point {
- constructor(public X: number, public Y: number) {}
+ // eslint-disable-next-line no-useless-constructor
+ constructor(
+ public X: number,
+ public Y: number
+ ) {
+ /* empty */
+ }
}
//
// Rectangle class
//
export class Rectangle {
- constructor(public X: number, public Y: number, public Width: number, public Height: number) {}
+ // eslint-disable-next-line no-useless-constructor
+ constructor(
+ public X: number,
+ public Y: number,
+ public Width: number,
+ public Height: number
+ ) {
+ /* empty */
+ }
}
//
@@ -93,7 +108,11 @@ export class Unistroke {
public StartUnitVector: Point;
public Vector: number[];
- constructor(public Name: string, useBoundedRotationInvariance: boolean, points: Point[]) {
+ constructor(
+ public Name: string,
+ useBoundedRotationInvariance: boolean,
+ points: Point[]
+ ) {
this.Points = Resample(points, NumPoints);
const radians = IndicativeAngle(this.Points);
this.Points = RotateBy(this.Points, -radians);
@@ -121,15 +140,15 @@ export class Multistroke {
this.NumStrokes = strokes.length; // number of individual strokes
const order = new Array(strokes.length); // array of integer indices
- for (var i = 0; i < strokes.length; i++) {
+ for (let i = 0; i < strokes.length; i++) {
order[i] = i; // initialize
}
- const orders = new Array(); // array of integer arrays
- HeapPermute(strokes.length, order, /*out*/ orders);
+ const orders = [] as any[]; // array of integer arrays
+ HeapPermute(strokes.length, order, /* out */ orders);
const unistrokes = MakeUnistrokes(strokes, orders); // returns array of point arrays
this.Unistrokes = new Array(unistrokes.length); // unistrokes for this multistroke
- for (var j = 0; j < unistrokes.length; j++) {
+ for (let j = 0; j < unistrokes.length; j++) {
this.Unistrokes[j] = new Unistroke(this.Name, useBoundedRotationInvariance, unistrokes[j]);
}
}
@@ -139,7 +158,14 @@ export class Multistroke {
// Result class
//
export class Result {
- constructor(public Name: string, public Score: any, public Time: any) {}
+ // eslint-disable-next-line no-useless-constructor
+ constructor(
+ public Name: string,
+ public Score: any,
+ public Time: any
+ ) {
+ /* empty */
+ }
}
//
@@ -172,46 +198,42 @@ export class NDollarRecognizer {
//
this.Multistrokes.push(
new Multistroke(
- GestureUtils.Gestures.Rectangle,
+ Gestures.Rectangle,
useBoundedRotationInvariance,
- new Array(
- new Array(
- new Point(30, 146), //new Point(29, 160), new Point(30, 180), new Point(31, 200),
- new Point(30, 222), //new Point(50, 219), new Point(70, 225), new Point(90, 230),
- new Point(106, 225), //new Point(100, 200), new Point(106, 180), new Point(110, 160),
- new Point(106, 146), //new Point(80, 150), new Point(50, 146),
- new Point(30, 143)
- )
- )
+ new Array([
+ new Point(30, 146), // new Point(29, 160), new Point(30, 180), new Point(31, 200),
+ new Point(30, 222), // new Point(50, 219), new Point(70, 225), new Point(90, 230),
+ new Point(106, 225), // new Point(100, 200), new Point(106, 180), new Point(110, 160),
+ new Point(106, 146), // new Point(80, 150), new Point(50, 146),
+ new Point(30, 143),
+ ])
)
);
- this.Multistrokes.push(new Multistroke(GestureUtils.Gestures.Line, useBoundedRotationInvariance, new Array(new Array(new Point(12, 347), new Point(119, 347)))));
+ this.Multistrokes.push(new Multistroke(Gestures.Line, useBoundedRotationInvariance, [[new Point(12, 347), new Point(119, 347)]]));
this.Multistrokes.push(
new Multistroke(
- GestureUtils.Gestures.Triangle, // equilateral
+ Gestures.Triangle, // equilateral
useBoundedRotationInvariance,
- new Array(new Array(new Point(40, 100), new Point(100, 200), new Point(140, 102), new Point(42, 100)))
+ new Array([new Point(40, 100), new Point(100, 200), new Point(140, 102), new Point(42, 100)])
)
);
this.Multistrokes.push(
new Multistroke(
- GestureUtils.Gestures.Circle,
+ Gestures.Circle,
useBoundedRotationInvariance,
- new Array(
- new Array(
- new Point(200, 250),
- new Point(240, 230),
- new Point(248, 210),
- new Point(248, 190),
- new Point(240, 170),
- new Point(200, 150),
- new Point(160, 170),
- new Point(151, 190),
- new Point(151, 210),
- new Point(160, 230),
- new Point(201, 250)
- )
- )
+ new Array([
+ new Point(200, 250),
+ new Point(240, 230),
+ new Point(248, 210),
+ new Point(248, 190),
+ new Point(240, 170),
+ new Point(200, 150),
+ new Point(160, 170),
+ new Point(151, 190),
+ new Point(151, 210),
+ new Point(160, 230),
+ new Point(201, 250),
+ ])
)
);
NumMultistrokes = this.Multistrokes.length; // NumMultistrokes flags the end of the non user-defined gstures strokes
@@ -287,25 +309,26 @@ export class NDollarRecognizer {
//
}
- Recognize = (strokes: any[], useBoundedRotationInvariance: boolean = false, requireSameNoOfStrokes: boolean = false, useProtractor: boolean = true) => {
+ Recognize = (strokes: { X: number; Y: number }[][], useBoundedRotationInvariance: boolean = false, requireSameNoOfStrokes: boolean = false, useProtractor: boolean = true) => {
const t0 = Date.now();
const points = CombineStrokes(strokes); // make one connected unistroke from the given strokes
const candidate = new Unistroke('', useBoundedRotationInvariance, points);
- var u = -1;
- var b = +Infinity;
+ let u = -1;
+ let b = +Infinity;
for (
- var i = 0;
+ let i = 0;
i < this.Multistrokes.length;
i++ // for each multistroke template
) {
if (!requireSameNoOfStrokes || strokes.length === this.Multistrokes[i].NumStrokes) {
// optional -- only attempt match when same # of component strokes
- for (const unistroke of this.Multistrokes[i].Unistrokes) {
+ // eslint-disable-next-line no-loop-func
+ this.Multistrokes[i].Unistrokes.forEach(unistroke => {
// for each unistroke within this multistroke
if (AngleBetweenUnitVectors(candidate.StartUnitVector, unistroke.StartUnitVector) <= AngleSimilarityThreshold) {
// strokes start in the same direction
- var d;
+ let d;
if (useProtractor) {
d = OptimalCosineDistance(unistroke.Vector, candidate.Vector); // Protractor
} else {
@@ -316,7 +339,7 @@ export class NDollarRecognizer {
u = i; // multistroke owner of unistroke
}
}
- }
+ });
}
}
const t1 = Date.now();
@@ -325,12 +348,12 @@ export class NDollarRecognizer {
AddGesture = (name: string, useBoundedRotationInvariance: boolean, strokes: any[]) => {
this.Multistrokes[this.Multistrokes.length] = new Multistroke(name, useBoundedRotationInvariance, strokes);
- var num = 0;
- for (const multistroke of this.Multistrokes) {
+ let num = 0;
+ this.Multistrokes.forEach(multistroke => {
if (multistroke.Name === name) {
num++;
}
- }
+ });
return num;
};
@@ -343,11 +366,11 @@ export class NDollarRecognizer {
//
// Private helper functions from here on down
//
-function HeapPermute(n: number, order: any[], /*out*/ orders: any[]) {
+function HeapPermute(n: number, order: any[], /* out */ orders: any[]) {
if (n === 1) {
orders[orders.length] = order.slice(); // append copy
} else {
- for (var i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
HeapPermute(n - 1, order, orders);
if (n % 2 === 1) {
// swap 0, n-1
@@ -364,47 +387,44 @@ function HeapPermute(n: number, order: any[], /*out*/ orders: any[]) {
}
}
-function MakeUnistrokes(strokes: any, orders: any) {
- const unistrokes = new Array(); // array of point arrays
- for (const order of orders) {
+function MakeUnistrokes(strokes: any, orders: any[]) {
+ const unistrokes = [] as any[]; // array of point arrays
+ orders.forEach(order => {
for (
- var b = 0;
- b < Math.pow(2, order.length);
+ let b = 0;
+ b < order.length ** 2;
b++ // use b's bits for directions
) {
- const unistroke = new Array(); // array of points
- for (var i = 0; i < order.length; i++) {
- var pts;
+ const unistroke = [] as any[]; // array of points
+ for (let i = 0; i < order.length; i++) {
+ let pts;
+ // eslint-disable-next-line no-bitwise
if (((b >> i) & 1) === 1) {
// is b's bit at index i on?
pts = strokes[order[i]].slice().reverse(); // copy and reverse
} else {
pts = strokes[order[i]].slice(); // copy
}
- for (const point of pts) {
+ pts.forEach((point: any) => {
unistroke[unistroke.length] = point; // append points
- }
+ });
}
unistrokes[unistrokes.length] = unistroke; // add one unistroke to set
}
- }
+ });
return unistrokes;
}
-function CombineStrokes(strokes: any) {
- const points = new Array();
- for (const stroke of strokes) {
- for (const { X, Y } of stroke) {
- points[points.length] = new Point(X, Y);
- }
- }
+function CombineStrokes(strokes: { X: number; Y: number }[][]) {
+ const points: Point[] = [];
+ strokes.forEach(stroke => stroke.forEach(({ X, Y }) => points.push(new Point(X, Y))));
return points;
}
function Resample(points: any, n: any) {
const I = PathLength(points) / (n - 1); // interval length
- var D = 0.0;
+ let D = 0.0;
const newpoints = new Array(points[0]);
- for (var i = 1; i < points.length; i++) {
+ for (let i = 1; i < points.length; i++) {
const d = Distance(points[i - 1], points[i]);
if (D + d >= I) {
const qx = points[i - 1].X + ((I - D) / d) * (points[i].X - points[i - 1].X);
@@ -425,55 +445,55 @@ function IndicativeAngle(points: any) {
const c = Centroid(points);
return Math.atan2(c.Y - points[0].Y, c.X - points[0].X);
}
-function RotateBy(points: any, radians: any) {
+function RotateBy(points: Point[], radians: any) {
// rotates points around centroid
const c = Centroid(points);
const cos = Math.cos(radians);
const sin = Math.sin(radians);
- const newpoints = new Array();
- for (const point of points) {
+ const newpoints: Point[] = [];
+ points.forEach(point => {
const qx = (point.X - c.X) * cos - (point.Y - c.Y) * sin + c.X;
const qy = (point.X - c.X) * sin + (point.Y - c.Y) * cos + c.Y;
- newpoints[newpoints.length] = new Point(qx, qy);
- }
+ newpoints.push(new Point(qx, qy));
+ });
return newpoints;
}
function ScaleDimTo(points: any, size: any, ratio1D: any) {
// scales bbox uniformly for 1D, non-uniformly for 2D
const B = BoundingBox(points);
const uniformly = Math.min(B.Width / B.Height, B.Height / B.Width) <= ratio1D; // 1D or 2D gesture test
- const newpoints = new Array();
- for (const { X, Y } of points) {
+ const newpoints: Point[] = [];
+ points.forEach(({ X, Y }) => {
const qx = uniformly ? X * (size / Math.max(B.Width, B.Height)) : X * (size / B.Width);
const qy = uniformly ? Y * (size / Math.max(B.Width, B.Height)) : Y * (size / B.Height);
newpoints[newpoints.length] = new Point(qx, qy);
- }
+ });
return newpoints;
}
function TranslateTo(points: any, pt: any) {
// translates points' centroid
const c = Centroid(points);
- const newpoints = new Array();
- for (const { X, Y } of points) {
+ const newpoints: Point[] = [];
+ points.forEach(({ X, Y }) => {
const qx = X + pt.X - c.X;
const qy = Y + pt.Y - c.Y;
newpoints[newpoints.length] = new Point(qx, qy);
- }
+ });
return newpoints;
}
function Vectorize(points: any, useBoundedRotationInvariance: any) {
// for Protractor
- var cos = 1.0;
- var sin = 0.0;
+ let cos = 1.0;
+ let sin = 0.0;
if (useBoundedRotationInvariance) {
const iAngle = Math.atan2(points[0].Y, points[0].X);
const baseOrientation = (Math.PI / 4.0) * Math.floor((iAngle + Math.PI / 8.0) / (Math.PI / 4.0));
cos = Math.cos(baseOrientation - iAngle);
sin = Math.sin(baseOrientation - iAngle);
}
- var sum = 0.0;
- const vector = new Array<number>();
- for (var i = 0; i < points.length; i++) {
+ let sum = 0.0;
+ const vector: number[] = [];
+ for (let i = 0; i < points.length; i++) {
const newX = points[i].X * cos - points[i].Y * sin;
const newY = points[i].Y * cos + points[i].X * sin;
vector[vector.length] = newX;
@@ -481,16 +501,16 @@ function Vectorize(points: any, useBoundedRotationInvariance: any) {
sum += newX * newX + newY * newY;
}
const magnitude = Math.sqrt(sum);
- for (var i = 0; i < vector.length; i++) {
+ for (let i = 0; i < vector.length; i++) {
vector[i] /= magnitude;
}
return vector;
}
function OptimalCosineDistance(v1: any, v2: any) {
// for Protractor
- var a = 0.0;
- var b = 0.0;
- for (var i = 0; i < v1.length; i += 2) {
+ let a = 0.0;
+ let b = 0.0;
+ for (let i = 0; i < v1.length; i += 2) {
a += v1[i] * v2[i] + v1[i + 1] * v2[i + 1];
b += v1[i] * v2[i + 1] - v1[i + 1] * v2[i];
}
@@ -498,18 +518,20 @@ function OptimalCosineDistance(v1: any, v2: any) {
return Math.acos(a * Math.cos(angle) + b * Math.sin(angle));
}
function DistanceAtBestAngle(points: any, T: any, a: any, b: any, threshold: any) {
- var x1 = Phi * a + (1.0 - Phi) * b;
- var f1 = DistanceAtAngle(points, T, x1);
- var x2 = (1.0 - Phi) * a + Phi * b;
- var f2 = DistanceAtAngle(points, T, x2);
+ let x1 = Phi * a + (1.0 - Phi) * b;
+ let f1 = DistanceAtAngle(points, T, x1);
+ let x2 = (1.0 - Phi) * a + Phi * b;
+ let f2 = DistanceAtAngle(points, T, x2);
while (Math.abs(b - a) > threshold) {
if (f1 < f2) {
+ // eslint-disable-next-line no-param-reassign
b = x2;
x2 = x1;
f2 = f1;
x1 = Phi * a + (1.0 - Phi) * b;
f1 = DistanceAtAngle(points, T, x1);
} else {
+ // eslint-disable-next-line no-param-reassign
a = x1;
x1 = x2;
f1 = f2;
@@ -523,34 +545,34 @@ function DistanceAtAngle(points: any, T: any, radians: any) {
const newpoints = RotateBy(points, radians);
return PathDistance(newpoints, T.Points);
}
-function Centroid(points: any) {
- var x = 0.0,
- y = 0.0;
- for (const point of points) {
- x += point.X;
- y += point.Y;
- }
+function Centroid(points: Point[]) {
+ let x = 0.0;
+ let y = 0.0;
+ points.forEach(({ X, Y }) => {
+ x += X;
+ y += Y;
+ });
x /= points.length;
y /= points.length;
return new Point(x, y);
}
-function BoundingBox(points: any) {
- var minX = +Infinity,
- maxX = -Infinity,
- minY = +Infinity,
- maxY = -Infinity;
- for (const { X, Y } of points) {
+function BoundingBox(points: Point[]) {
+ let minX = +Infinity;
+ let maxX = -Infinity;
+ let minY = +Infinity;
+ let maxY = -Infinity;
+ points.forEach(({ X, Y }) => {
minX = Math.min(minX, X);
minY = Math.min(minY, Y);
maxX = Math.max(maxX, X);
maxY = Math.max(maxY, Y);
- }
+ });
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
}
function PathDistance(pts1: any, pts2: any) {
// average distance between corresponding points in two paths
- var d = 0.0;
- for (var i = 0; i < pts1.length; i++) {
+ let d = 0.0;
+ for (let i = 0; i < pts1.length; i++) {
// assumes pts1.length == pts2.length
d += Distance(pts1[i], pts2[i]);
}
@@ -558,8 +580,8 @@ function PathDistance(pts1: any, pts2: any) {
}
function PathLength(points: any) {
// length traversed by a point path
- var d = 0.0;
- for (var i = 1; i < points.length; i++) {
+ let d = 0.0;
+ for (let i = 1; i < points.length; i++) {
d += Distance(points[i - 1], points[i]);
}
return d;
@@ -570,9 +592,9 @@ function Distance(p1: any, p2: any) {
const dy = p2.Y - p1.Y;
return Math.sqrt(dx * dx + dy * dy);
}
-function CalcStartUnitVector(points: any, index: any) {
+function CalcStartUnitVector(points: Point[], index: any) {
// start angle from points[0] to points[index] normalized as a unit vector
- const v = new Point(points[index]?.X - points[0]?.X, points[index]?.Y - points[0]?.Y);
+ const v = new Point(points[index].X - points[0].X, points[index].Y - points[0].Y);
const len = Math.sqrt(v.X * v.X + v.Y * v.Y);
return new Point(v.X / len, v.Y / len);
}
diff --git a/src/server/ActionUtilities.ts b/src/server/ActionUtilities.ts
index 55b50cc12..520ebb42e 100644
--- a/src/server/ActionUtilities.ts
+++ b/src/server/ActionUtilities.ts
@@ -1,14 +1,14 @@
import { exec } from 'child_process';
import { Color, yellow } from 'colors';
import { createWriteStream, exists, mkdir, readFile, unlink, writeFile } from 'fs';
-import * as nodemailer from "nodemailer";
-import { MailOptions } from "nodemailer/lib/json-transport";
+import * as nodemailer from 'nodemailer';
+import { MailOptions } from 'nodemailer/lib/json-transport';
import * as path from 'path';
-import { rimraf } from "rimraf";
+import { rimraf } from 'rimraf';
import { ExecOptions } from 'shelljs';
import * as Mail from 'nodemailer/lib/mailer';
-const projectRoot = path.resolve(__dirname, "../../");
+const projectRoot = path.resolve(__dirname, '../../');
export function pathFromRoot(relative?: string) {
if (!relative) {
return projectRoot;
@@ -16,36 +16,37 @@ export function pathFromRoot(relative?: string) {
return path.resolve(projectRoot, relative);
}
-export async function fileDescriptorFromStream(path: string) {
- const logStream = createWriteStream(path);
- return new Promise<number>(resolve => logStream.on("open", resolve));
+export async function fileDescriptorFromStream(filePath: string) {
+ const logStream = createWriteStream(filePath);
+ return new Promise<number>(resolve => {
+ logStream.on('open', resolve);
+ });
}
-export const command_line = (command: string, fromDirectory?: string) => {
- return new Promise<string>((resolve, reject) => {
+export const commandLine = (command: string, fromDirectory?: string) =>
+ new Promise<string>((resolve, reject) => {
const options: ExecOptions = {};
if (fromDirectory) {
options.cwd = fromDirectory ? path.resolve(projectRoot, fromDirectory) : projectRoot;
}
- exec(command, options, (err, stdout) => err ? reject(err) : resolve(stdout));
+ exec(command, options, (err, stdout) => (err ? reject(err) : resolve(stdout)));
});
-};
-export const read_text_file = (relativePath: string) => {
+export const readTextFile = (relativePath: string) => {
const target = path.resolve(__dirname, relativePath);
return new Promise<string>((resolve, reject) => {
- readFile(target, (err, data) => err ? reject(err) : resolve(data.toString()));
+ readFile(target, (err, data) => (err ? reject(err) : resolve(data.toString())));
});
};
-export const write_text_file = (relativePath: string, contents: any) => {
+export const writeTextFile = (relativePath: string, contents: any) => {
const target = path.resolve(__dirname, relativePath);
return new Promise<void>((resolve, reject) => {
- writeFile(target, contents, (err) => err ? reject(err) : resolve());
+ writeFile(target, contents, err => (err ? reject(err) : resolve()));
});
};
-export type Messager<T> = (outcome: { result: T | undefined, error: Error | null }) => string;
+export type Messager<T> = (outcome: { result: T | undefined; error: Error | null }) => string;
export interface LogData<T> {
startMessage: string;
@@ -55,70 +56,80 @@ export interface LogData<T> {
color?: Color;
}
+function logHelper(content: string, color: Color | string) {
+ if (typeof color === 'string') {
+ console.log(color, content);
+ } else {
+ console.log(color(content));
+ }
+}
+
let current = Math.ceil(Math.random() * 20);
-export async function log_execution<T>({ startMessage, endMessage, action, color }: LogData<T>): Promise<T | undefined> {
- let result: T | undefined = undefined, error: Error | null = null;
- const resolvedColor = color || `\x1b[${31 + ++current % 6}m%s\x1b[0m`;
- log_helper(`${startMessage}...`, resolvedColor);
+export async function logExecution<T>({ startMessage, endMessage, action, color }: LogData<T>): Promise<T | undefined> {
+ let result: T | undefined;
+ let error: Error | null = null;
+ const resolvedColor = color || `\x1b[${31 + (++current % 6)}m%s\x1b[0m`;
+ logHelper(`${startMessage}...`, resolvedColor);
try {
result = await action();
} catch (e: any) {
error = e;
} finally {
- log_helper(typeof endMessage === "string" ? endMessage : endMessage({ result, error }), resolvedColor);
+ logHelper(typeof endMessage === 'string' ? endMessage : endMessage({ result, error }), resolvedColor);
}
return result;
}
-
-function log_helper(content: string, color: Color | string) {
- if (typeof color === "string") {
- console.log(color, content);
- } else {
- console.log(color(content));
- }
-}
-
export function logPort(listener: string, port: number) {
console.log(`${listener} listening on port ${yellow(String(port))}`);
}
export function msToTime(duration: number) {
- const milliseconds = Math.floor((duration % 1000) / 100),
- seconds = Math.floor((duration / 1000) % 60),
- minutes = Math.floor((duration / (1000 * 60)) % 60),
- hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
+ const milliseconds = Math.floor((duration % 1000) / 100);
+ const seconds = Math.floor((duration / 1000) % 60);
+ const minutes = Math.floor((duration / (1000 * 60)) % 60);
+ const hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
- const hoursS = (hours < 10) ? "0" + hours : hours;
- const minutesS = (minutes < 10) ? "0" + minutes : minutes;
- const secondsS = (seconds < 10) ? "0" + seconds : seconds;
+ const hoursS = hours < 10 ? '0' + hours : hours;
+ const minutesS = minutes < 10 ? '0' + minutes : minutes;
+ const secondsS = seconds < 10 ? '0' + seconds : seconds;
- return hoursS + ":" + minutesS + ":" + secondsS + "." + milliseconds;
+ return hoursS + ':' + minutesS + ':' + secondsS + '.' + milliseconds;
}
-export const createIfNotExists = async (path: string) => {
- if (await new Promise<boolean>(resolve => exists(path, resolve))) {
+export const createIfNotExists = async (filePath: string) => {
+ if (
+ await new Promise<boolean>(resolve => {
+ exists(filePath, resolve);
+ })
+ ) {
return true;
}
- return new Promise<boolean>(resolve => mkdir(path, error => resolve(error === null)));
+ return new Promise<boolean>(resolve => {
+ mkdir(filePath, error => resolve(error === null));
+ });
};
export async function Prune(rootDirectory: string): Promise<boolean> {
// const error = await new Promise<Error>(resolve => rimraf(rootDirectory).then(resolve));
- await new Promise<void>(resolve => rimraf(rootDirectory).then(() => resolve()));
+ await new Promise<void>(resolve => {
+ rimraf(rootDirectory).then(() => resolve());
+ });
// return error === null;
return true;
}
-export const Destroy = (mediaPath: string) => new Promise<boolean>(resolve => unlink(mediaPath, error => resolve(error === null)));
+export const Destroy = (mediaPath: string) =>
+ new Promise<boolean>(resolve => {
+ unlink(mediaPath, error => resolve(error === null));
+ });
export namespace Email {
-
const smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'browndashptc@gmail.com',
- pass: 'TsarNicholas#2'
- }
+ pass: 'TsarNicholas#2',
+ },
});
export interface DispatchOptions<T extends string | string[]> {
@@ -135,16 +146,18 @@ export namespace Email {
export async function dispatchAll({ to, subject, content, attachments }: DispatchOptions<string[]>) {
const failures: DispatchFailure[] = [];
- await Promise.all(to.map(async recipient => {
- let error: Error | null;
- const resolved = attachments ? "length" in attachments ? attachments : [attachments] : undefined;
- if ((error = await Email.dispatch({ to: recipient, subject, content, attachments: resolved })) !== null) {
- failures.push({
- recipient,
- error
- });
- }
- }));
+ await Promise.all(
+ to.map(async recipient => {
+ const resolved = attachments ? ('length' in attachments ? attachments : [attachments]) : undefined;
+ const error = await Email.dispatch({ to: recipient, subject, content, attachments: resolved });
+ if (error !== null) {
+ failures.push({
+ recipient,
+ error,
+ });
+ }
+ })
+ );
return failures.length ? failures : undefined;
}
@@ -153,10 +166,11 @@ export namespace Email {
to,
from: 'browndashptc@gmail.com',
subject,
- text: `Hello ${to.split("@")[0]},\n\n${content}`,
- attachments
+ text: `Hello ${to.split('@')[0]},\n\n${content}`,
+ attachments,
} as MailOptions;
- return new Promise<Error | null>(resolve => smtpTransport.sendMail(mailOptions, resolve));
+ return new Promise<Error | null>(resolve => {
+ smtpTransport.sendMail(mailOptions, resolve);
+ });
}
-
-} \ No newline at end of file
+}
diff --git a/src/server/ApiManagers/ApiManager.ts b/src/server/ApiManagers/ApiManager.ts
index 27e9de065..f55495b2e 100644
--- a/src/server/ApiManagers/ApiManager.ts
+++ b/src/server/ApiManagers/ApiManager.ts
@@ -1,4 +1,4 @@
-import { RouteInitializer } from "../RouteManager";
+import { RouteInitializer } from '../RouteManager';
export type Registration = (initializer: RouteInitializer) => void;
@@ -8,4 +8,4 @@ export default abstract class ApiManager {
public register(register: Registration) {
this.initialize(register);
}
-} \ No newline at end of file
+}
diff --git a/src/server/ApiManagers/AssistantManager.ts b/src/server/ApiManagers/AssistantManager.ts
new file mode 100644
index 000000000..82e48167a
--- /dev/null
+++ b/src/server/ApiManagers/AssistantManager.ts
@@ -0,0 +1,131 @@
+import * as fs from 'fs';
+import { createReadStream, writeFile } from 'fs';
+import OpenAI from 'openai';
+import * as path from 'path';
+import { promisify } from 'util';
+import * as uuid from 'uuid';
+import { filesDirectory, publicDirectory } from '..';
+import { Method } from '../RouteManager';
+import ApiManager, { Registration } from './ApiManager';
+
+export enum Directory {
+ parsed_files = 'parsed_files',
+ images = 'images',
+ videos = 'videos',
+ pdfs = 'pdfs',
+ text = 'text',
+ pdf_thumbnails = 'pdf_thumbnails',
+ audio = 'audio',
+ csv = 'csv',
+}
+
+export function serverPathToFile(directory: Directory, filename: string) {
+ return path.normalize(`${filesDirectory}/${directory}/${filename}`);
+}
+
+export function pathToDirectory(directory: Directory) {
+ return path.normalize(`${filesDirectory}/${directory}`);
+}
+
+export function clientPathToFile(directory: Directory, filename: string) {
+ return `/files/${directory}/${filename}`;
+}
+
+const writeFileAsync = promisify(writeFile);
+const readFileAsync = promisify(fs.readFile);
+
+export default class AssistantManager extends ApiManager {
+ protected initialize(register: Registration): void {
+ const openai = new OpenAI({ apiKey: process.env.OPENAI_KEY, dangerouslyAllowBrowser: true });
+
+ register({
+ method: Method.POST,
+ subscription: '/uploadPDFToVectorStore',
+ secureHandler: async ({ req, res }) => {
+ const { urls, threadID, assistantID, vector_store_id } = req.body;
+
+ const csvFilesIds: string[] = [];
+ const otherFileIds: string[] = [];
+ const allFileIds: string[] = [];
+
+ const fileProcesses = urls.map(async (source: string) => {
+ const fullPath = path.join(publicDirectory, source);
+ const fileData = await openai.files.create({ file: createReadStream(fullPath), purpose: 'assistants' });
+ allFileIds.push(fileData.id);
+ if (source.endsWith('.csv')) {
+ console.log(source);
+ csvFilesIds.push(fileData.id);
+ } else {
+ openai.beta.vectorStores.files.create(vector_store_id, { file_id: fileData.id });
+ otherFileIds.push(fileData.id);
+ }
+ });
+ try {
+ await Promise.all(fileProcesses).then(() => {
+ res.send({ vector_store_id: vector_store_id, openai_file_ids: allFileIds });
+ });
+ } catch (error) {
+ res.status(500).send({ error: 'Failed to process files' + error });
+ }
+ },
+ });
+
+ register({
+ method: Method.POST,
+ subscription: '/downloadFileFromOpenAI',
+ secureHandler: async ({ req, res }) => {
+ const { file_id, file_name } = req.body;
+ //let files_directory: string;
+ let files_directory = '/files/openAIFiles/';
+ switch (file_name.split('.').pop()) {
+ case 'pdf':
+ files_directory = '/files/pdfs/';
+ break;
+ case 'csv':
+ files_directory = '/files/csv/';
+ break;
+ case 'png':
+ case 'jpg':
+ case 'jpeg':
+ files_directory = '/files/images/';
+ break;
+ default:
+ break;
+ }
+
+ const directory = path.join(publicDirectory, files_directory);
+
+ if (!fs.existsSync(directory)) {
+ fs.mkdirSync(directory);
+ }
+ const file = await openai.files.content(file_id);
+ const new_file_name = `${uuid.v4()}-${file_name}`;
+ const file_path = path.join(directory, new_file_name);
+ const file_array_buffer = await file.arrayBuffer();
+ const bufferView = new Uint8Array(file_array_buffer);
+ try {
+ const written_file = await writeFileAsync(file_path, bufferView);
+ console.log(written_file);
+ console.log(file_path);
+ console.log(file_array_buffer);
+ console.log(bufferView);
+ const file_object = new File([bufferView], file_name);
+ //DashUploadUtils.upload(file_object, 'openAIFiles');
+ res.send({ file_path: path.join(files_directory, new_file_name) });
+ /* res.send( {
+ source: "file",
+ result: {
+ accessPaths: {
+ agnostic: {client: path.join('/files/openAIFiles/', `${uuid.v4()}-${file_name}`)}
+ },
+ rawText: "",
+ duration: 0,
+ },
+ } ); */
+ } catch (error) {
+ res.status(500).send({ error: 'Failed to write file' + error });
+ }
+ },
+ });
+ }
+}
diff --git a/src/server/ApiManagers/DataVizManager.ts b/src/server/ApiManagers/DataVizManager.ts
index 0d43130d1..88f22992d 100644
--- a/src/server/ApiManagers/DataVizManager.ts
+++ b/src/server/ApiManagers/DataVizManager.ts
@@ -1,14 +1,14 @@
-import { csvParser, csvToString } from "../DataVizUtils";
-import { Method, _success } from "../RouteManager";
-import ApiManager, { Registration } from "./ApiManager";
-import { Directory, serverPathToFile } from "./UploadManager";
import * as path from 'path';
+import { csvParser, csvToString } from '../DataVizUtils';
+import { Method, _success } from '../RouteManager';
+import { Directory, serverPathToFile } from '../SocketData';
+import ApiManager, { Registration } from './ApiManager';
export default class DataVizManager extends ApiManager {
protected initialize(register: Registration): void {
register({
method: Method.GET,
- subscription: "/csvData",
+ subscription: '/csvData',
secureHandler: async ({ req, res }) => {
const uri = req.query.uri as string;
@@ -19,8 +19,7 @@ export default class DataVizManager extends ApiManager {
_success(res, parsedCsv);
resolve();
});
- }
+ },
});
}
-
-} \ No newline at end of file
+}
diff --git a/src/server/ApiManagers/DeleteManager.ts b/src/server/ApiManagers/DeleteManager.ts
index c6c4ca464..9ad334c1b 100644
--- a/src/server/ApiManagers/DeleteManager.ts
+++ b/src/server/ApiManagers/DeleteManager.ts
@@ -1,12 +1,12 @@
-import ApiManager, { Registration } from './ApiManager';
-import { Method, _permission_denied } from '../RouteManager';
-import { WebSocket } from '../websocket';
-import { Database } from '../database';
+import { mkdirSync } from 'fs';
import { rimraf } from 'rimraf';
-import { filesDirectory } from '..';
+import { filesDirectory } from '../SocketData';
import { DashUploadUtils } from '../DashUploadUtils';
-import { mkdirSync } from 'fs';
+import { Method } from '../RouteManager';
import RouteSubscriber from '../RouteSubscriber';
+import { Database } from '../database';
+import { WebSocket } from '../websocket';
+import ApiManager, { Registration } from './ApiManager';
export default class DeleteManager extends ApiManager {
protected initialize(register: Registration): void {
@@ -24,9 +24,11 @@ export default class DeleteManager extends ApiManager {
switch (target) {
case 'all':
all = true;
+ // eslint-disable-next-line no-fallthrough
case 'database':
await WebSocket.doDelete(false);
if (!all) break;
+ // eslint-disable-next-line no-fallthrough
case 'files':
rimraf.sync(filesDirectory);
mkdirSync(filesDirectory);
diff --git a/src/server/ApiManagers/DownloadManager.ts b/src/server/ApiManagers/DownloadManager.ts
index 2175b6db6..5ee21fb44 100644
--- a/src/server/ApiManagers/DownloadManager.ts
+++ b/src/server/ApiManagers/DownloadManager.ts
@@ -1,13 +1,13 @@
-import ApiManager, { Registration } from "./ApiManager";
-import { Method } from "../RouteManager";
-import RouteSubscriber from "../RouteSubscriber";
import * as Archiver from 'archiver';
import * as express from 'express';
-import { Database } from "../database";
-import * as path from "path";
-import { DashUploadUtils, SizeSuffix } from "../DashUploadUtils";
-import { publicDirectory } from "..";
-import { serverPathToFile, Directory } from "./UploadManager";
+import * as path from 'path';
+import { URL } from 'url';
+import { DashUploadUtils, SizeSuffix } from '../DashUploadUtils';
+import { Method } from '../RouteManager';
+import RouteSubscriber from '../RouteSubscriber';
+import { Directory, publicDirectory, serverPathToFile } from '../SocketData';
+import { Database } from '../database';
+import ApiManager, { Registration } from './ApiManager';
export type Hierarchy = { [id: string]: string | Hierarchy };
export type ZipMutator = (file: Archiver.Archiver) => void | Promise<void>;
@@ -16,147 +16,45 @@ export interface DocumentElements {
title: string;
}
-export default class DownloadManager extends ApiManager {
-
- protected initialize(register: Registration): void {
-
- /**
- * Let's say someone's using Dash to organize images in collections.
- * This lets them export the hierarchy they've built to their
- * own file system in a useful format.
- *
- * This handler starts with a single document id (interesting only
- * if it's that of a collection). It traverses the database, captures
- * the nesting of only nested images or collections, writes
- * that to a zip file and returns it to the client for download.
- */
- register({
- method: Method.GET,
- subscription: new RouteSubscriber("imageHierarchyExport").add('docId'),
- secureHandler: async ({ req, res }) => {
- const id = req.params.docId;
- const hierarchy: Hierarchy = {};
- await buildHierarchyRecursive(id, hierarchy);
- return BuildAndDispatchZip(res, zip => writeHierarchyRecursive(zip, hierarchy));
- }
- });
-
- register({
- method: Method.GET,
- subscription: new RouteSubscriber("downloadId").add("docId"),
- secureHandler: async ({ req, res }) => {
- return BuildAndDispatchZip(res, async zip => {
- const { id, docs, files } = await getDocs(req.params.docId);
- const docString = JSON.stringify({ id, docs });
- zip.append(docString, { name: "doc.json" });
- files.forEach(val => {
- zip.file(publicDirectory + val, { name: val.substring(1) });
- });
- });
- }
- });
-
- register({
- method: Method.GET,
- subscription: new RouteSubscriber("serializeDoc").add("docId"),
- secureHandler: async ({ req, res }) => {
- const { docs, files } = await getDocs(req.params.docId);
- res.send({ docs, files: Array.from(files) });
- }
- });
-
- }
-
-}
-
-async function getDocs(id: string) {
- const files = new Set<string>();
- const docs: { [id: string]: any } = {};
- const fn = (doc: any): string[] => {
- const id = doc.id;
- if (typeof id === "string" && id.endsWith("Proto")) {
- //Skip protos
- return [];
- }
- const ids: string[] = [];
- for (const key in doc.fields) {
- if (!doc.fields.hasOwnProperty(key)) { continue; }
- const field = doc.fields[key];
- if (field === undefined || field === null) { continue; }
-
- if (field.__type === "proxy" || field.__type === "prefetch_proxy") {
- ids.push(field.fieldId);
- } else if (field.__type === "script" || field.__type === "computed") {
- field.captures && ids.push(field.captures.fieldId);
- } else if (field.__type === "list") {
- ids.push(...fn(field));
- } else if (typeof field === "string") {
- const re = /"(?:dataD|d)ocumentId"\s*:\s*"([\w\-]*)"/g;
- let match: string[] | null;
- while ((match = re.exec(field)) !== null) {
- ids.push(match[1]);
- }
- } else if (field.__type === "RichTextField") {
- const re = /"href"\s*:\s*"(.*?)"/g;
- let match: string[] | null;
- while ((match = re.exec(field.Data)) !== null) {
- const urlString = match[1];
- const split = new URL(urlString).pathname.split("doc/");
- if (split.length > 1) {
- ids.push(split[split.length - 1]);
- }
- }
- const re2 = /"src"\s*:\s*"(.*?)"/g;
- while ((match = re2.exec(field.Data)) !== null) {
- const urlString = match[1];
- const pathname = new URL(urlString).pathname;
- files.add(pathname);
- }
- } else if (["audio", "image", "video", "pdf", "web", "map"].includes(field.__type)) {
- const url = new URL(field.url);
- const pathname = url.pathname;
- files.add(pathname);
- }
- }
-
- if (doc.id) {
- docs[doc.id] = doc;
- }
- return ids;
- };
- await Database.Instance.visit([id], fn);
- return { id, docs, files };
-}
-
/**
- * This utility function factors out the process
- * of creating a zip file and sending it back to the client
- * by piping it into a response.
- *
- * Learn more about piping and readable / writable streams here!
- * https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/
- *
- * @param res the writable stream response object that will transfer the generated zip file
- * @param mutator the callback function used to actually modify and insert information into the zip instance
+ * This is a very specific utility method to help traverse the database
+ * to parse data and titles out of images and collections alone.
+ *
+ * We don't know if the document id given to is corresponds to a view document or a data
+ * document. If it's a data document, the response from the database will have
+ * a data field. If not, call recursively on the proto, and resolve with *its* data
+ *
+ * @param targetId the id of the Dash document whose data is being requests
+ * @returns the data of the document, as well as its title
*/
-export async function BuildAndDispatchZip(res: express.Response, mutator: ZipMutator): Promise<void> {
- res.set('Content-disposition', `attachment;`);
- res.set('Content-Type', "application/zip");
- const zip = Archiver('zip');
- zip.pipe(res);
- await mutator(zip);
- return zip.finalize();
+async function getData(targetId: string): Promise<DocumentElements> {
+ return new Promise<DocumentElements>((resolve, reject) => {
+ Database.Instance.getDocument(targetId, async (result: any) => {
+ const { data, proto, title } = result.fields;
+ if (data) {
+ if (data.url) {
+ resolve({ data: data.url, title });
+ } else if (data.fields) {
+ resolve({ data: data.fields, title });
+ } else {
+ reject();
+ }
+ } else if (proto) {
+ getData(proto.fieldId).then(resolve, reject);
+ } else {
+ reject();
+ }
+ });
+ });
}
/**
* This function starts with a single document id as a seed,
* typically that of a collection, and then descends the entire tree
- * of image or collection documents that are reachable from that seed.
+ * of image or collection documents that are reachable from that seed.
* @param seedId the id of the root of the subtree we're trying to capture, interesting only if it's a collection
* @param hierarchy the data structure we're going to use to record the nesting of the collections and images as we descend
- */
-
-/*
+
Below is an example of the JSON hierarchy built from two images contained inside a collection titled 'a nested collection',
following the general recursive structure shown immediately below
{
@@ -190,74 +88,175 @@ async function buildHierarchyRecursive(seedId: string, hierarchy: Hierarchy): Pr
}
/**
- * This is a very specific utility method to help traverse the database
- * to parse data and titles out of images and collections alone.
- *
- * We don't know if the document id given to is corresponds to a view document or a data
- * document. If it's a data document, the response from the database will have
- * a data field. If not, call recursively on the proto, and resolve with *its* data
- *
- * @param targetId the id of the Dash document whose data is being requests
- * @returns the data of the document, as well as its title
+ * This utility function factors out the process
+ * of creating a zip file and sending it back to the client
+ * by piping it into a response.
+ *
+ * Learn more about piping and readable / writable streams here!
+ * https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/
+ *
+ * @param res the writable stream response object that will transfer the generated zip file
+ * @param mutator the callback function used to actually modify and insert information into the zip instance
*/
-async function getData(targetId: string): Promise<DocumentElements> {
- return new Promise<DocumentElements>((resolve, reject) => {
- Database.Instance.getDocument(targetId, async (result: any) => {
- const { data, proto, title } = result.fields;
- if (data) {
- if (data.url) {
- resolve({ data: data.url, title });
- } else if (data.fields) {
- resolve({ data: data.fields, title });
- } else {
- reject();
- }
- } else if (proto) {
- getData(proto.fieldId).then(resolve, reject);
- } else {
- reject();
- }
- });
- });
+export async function BuildAndDispatchZip(res: express.Response, mutator: ZipMutator): Promise<void> {
+ res.set('Content-disposition', `attachment;`);
+ res.set('Content-Type', 'application/zip');
+ const zip = Archiver('zip');
+ zip.pipe(res);
+ await mutator(zip);
+ return zip.finalize();
}
/**
- *
+ *
* @param file the zip file to which we write the files
* @param hierarchy the data structure from which we read, defining the nesting of the documents in the zip
* @param prefix lets us create nested folders in the zip file by continually appending to the end
* of the prefix with each layer of recursion.
- *
+ *
* Function Call #1 => "Dash Export"
* Function Call #2 => "Dash Export/a nested collection"
* Function Call #3 => "Dash Export/a nested collection/lowest level collection"
* ...
*/
-async function writeHierarchyRecursive(file: Archiver.Archiver, hierarchy: Hierarchy, prefix = "Dash Export"): Promise<void> {
- for (const documentTitle of Object.keys(hierarchy)) {
- const result = hierarchy[documentTitle];
- // base case or leaf node, we've hit a url (image)
- if (typeof result === "string") {
- let path: string;
- let matches: RegExpExecArray | null;
- if ((matches = /\:\d+\/files\/images\/(upload\_[\da-z]{32}.*)/g.exec(result)) !== null) {
- // image already exists on our server
- path = serverPathToFile(Directory.images, matches[1]);
+async function writeHierarchyRecursive(file: Archiver.Archiver, hierarchy: Hierarchy, prefix = 'Dash Export'): Promise<void> {
+ // eslint-disable-next-line no-restricted-syntax
+ for (const documentTitle in hierarchy) {
+ if (Object.prototype.hasOwnProperty.call(hierarchy, documentTitle)) {
+ const result = hierarchy[documentTitle];
+ // base case or leaf node, we've hit a url (image)
+ if (typeof result === 'string') {
+ let fPath: string;
+ const matches = /:\d+\/files\/images\/(upload_[\da-z]{32}.*)/g.exec(result);
+ if (matches !== null) {
+ // image already exists on our server
+ fPath = serverPathToFile(Directory.images, matches[1]);
+ } else {
+ // the image doesn't already exist on our server (may have been dragged
+ // and dropped in the browser and thus hosted remotely) so we upload it
+ // to our server and point the zip file to it, so it can bundle up the bytes
+ // eslint-disable-next-line no-await-in-loop
+ const information = await DashUploadUtils.UploadImage(result);
+ fPath = information instanceof Error ? '' : information.accessPaths[SizeSuffix.Original].server;
+ }
+ // write the file specified by the path to the directory in the
+ // zip file given by the prefix.
+ if (fPath) {
+ file.file(fPath, { name: documentTitle, prefix });
+ }
} else {
- // the image doesn't already exist on our server (may have been dragged
- // and dropped in the browser and thus hosted remotely) so we upload it
- // to our server and point the zip file to it, so it can bundle up the bytes
- const information = await DashUploadUtils.UploadImage(result);
- path = information instanceof Error ? "" : information.accessPaths[SizeSuffix.Original].server;
+ // we've hit a collection, so we have to recurse
+ // eslint-disable-next-line no-await-in-loop
+ await writeHierarchyRecursive(file, result, `${prefix}/${documentTitle}`);
}
- // write the file specified by the path to the directory in the
- // zip file given by the prefix.
- if (path) {
- file.file(path, { name: documentTitle, prefix });
+ }
+ }
+}
+
+async function getDocs(docId: string) {
+ const files = new Set<string>();
+ const docs: { [id: string]: any } = {};
+ const fn = (doc: any): string[] => {
+ const { id } = doc;
+ if (typeof id === 'string' && id.endsWith('Proto')) {
+ // Skip protos
+ return [];
+ }
+ const ids: string[] = [];
+ // eslint-disable-next-line no-restricted-syntax
+ for (const key in doc.fields) {
+ // eslint-disable-next-line no-continue
+ if (!Object.prototype.hasOwnProperty.call(doc.fields, key)) continue;
+
+ const field = doc.fields[key];
+ // eslint-disable-next-line no-continue
+ if (field === undefined || field === null) continue;
+
+ if (field.__type === 'proxy' || field.__type === 'prefetch_proxy') {
+ ids.push(field.fieldId);
+ } else if (field.__type === 'script' || field.__type === 'computed') {
+ field.captures && ids.push(field.captures.fieldId);
+ } else if (field.__type === 'list') {
+ ids.push(...fn(field));
+ } else if (typeof field === 'string') {
+ const re = /"(?:dataD|d)ocumentId"\s*:\s*"([\w-]*)"/g;
+ for (let match = re.exec(field); match !== null; match = re.exec(field)) {
+ ids.push(match[1]);
+ }
+ } else if (field.__type === 'RichTextField') {
+ const re = /"href"\s*:\s*"(.*?)"/g;
+ for (let match = re.exec(field.data); match !== null; match = re.exec(field.Data)) {
+ const urlString = match[1];
+ const split = new URL(urlString).pathname.split('doc/');
+ if (split.length > 1) {
+ ids.push(split[split.length - 1]);
+ }
+ }
+ const re2 = /"src"\s*:\s*"(.*?)"/g;
+ for (let match = re2.exec(field.Data); match !== null; match = re2.exec(field.Data)) {
+ const urlString = match[1];
+ const { pathname } = new URL(urlString);
+ files.add(pathname);
+ }
+ } else if (['audio', 'image', 'video', 'pdf', 'web', 'map'].includes(field.__type)) {
+ const { pathname } = new URL(field.url);
+ files.add(pathname);
}
- } else {
- // we've hit a collection, so we have to recurse
- await writeHierarchyRecursive(file, result, `${prefix}/${documentTitle}`);
}
+
+ if (doc.id) {
+ docs[doc.id] = doc;
+ }
+ return ids;
+ };
+ await Database.Instance.visit([docId], fn);
+ return { id: docId, docs, files };
+}
+
+export default class DownloadManager extends ApiManager {
+ protected initialize(register: Registration): void {
+ /**
+ * Let's say someone's using Dash to organize images in collections.
+ * This lets them export the hierarchy they've built to their
+ * own file system in a useful format.
+ *
+ * This handler starts with a single document id (interesting only
+ * if it's that of a collection). It traverses the database, captures
+ * the nesting of only nested images or collections, writes
+ * that to a zip file and returns it to the client for download.
+ */
+ register({
+ method: Method.GET,
+ subscription: new RouteSubscriber('imageHierarchyExport').add('docId'),
+ secureHandler: async ({ req, res }) => {
+ const id = req.params.docId;
+ const hierarchy: Hierarchy = {};
+ await buildHierarchyRecursive(id, hierarchy);
+ return BuildAndDispatchZip(res, zip => writeHierarchyRecursive(zip, hierarchy));
+ },
+ });
+
+ register({
+ method: Method.GET,
+ subscription: new RouteSubscriber('downloadId').add('docId'),
+ secureHandler: async ({ req, res }) =>
+ BuildAndDispatchZip(res, async zip => {
+ const { id, docs, files } = await getDocs(req.params.docId);
+ const docString = JSON.stringify({ id, docs });
+ zip.append(docString, { name: 'doc.json' });
+ files.forEach(val => {
+ zip.file(publicDirectory + val, { name: val.substring(1) });
+ });
+ }),
+ });
+
+ register({
+ method: Method.GET,
+ subscription: new RouteSubscriber('serializeDoc').add('docId'),
+ secureHandler: async ({ req, res }) => {
+ const { docs, files } = await getDocs(req.params.docId);
+ res.send({ docs, files: Array.from(files) });
+ },
+ });
}
-} \ No newline at end of file
+}
diff --git a/src/server/ApiManagers/GeneralGoogleManager.ts b/src/server/ApiManagers/GeneralGoogleManager.ts
index f94b77cac..12913b1ef 100644
--- a/src/server/ApiManagers/GeneralGoogleManager.ts
+++ b/src/server/ApiManagers/GeneralGoogleManager.ts
@@ -1,51 +1,49 @@
-import ApiManager, { Registration } from "./ApiManager";
-import { Method, _permission_denied } from "../RouteManager";
-import { GoogleApiServerUtils } from "../apis/google/GoogleApiServerUtils";
-import RouteSubscriber from "../RouteSubscriber";
-import { Database } from "../database";
+import ApiManager, { Registration } from './ApiManager';
+import { Method } from '../RouteManager';
+import { GoogleApiServerUtils } from '../apis/google/GoogleApiServerUtils';
+import RouteSubscriber from '../RouteSubscriber';
+import { Database } from '../database';
const EndpointHandlerMap = new Map<GoogleApiServerUtils.Action, GoogleApiServerUtils.ApiRouter>([
- ["create", (api, params) => api.create(params)],
- ["retrieve", (api, params) => api.get(params)],
- ["update", (api, params) => api.batchUpdate(params)],
+ ['create', (api, params) => api.create(params)],
+ ['retrieve', (api, params) => api.get(params)],
+ ['update', (api, params) => api.batchUpdate(params)],
]);
export default class GeneralGoogleManager extends ApiManager {
-
protected initialize(register: Registration): void {
-
register({
method: Method.GET,
- subscription: "/readGoogleAccessToken",
+ subscription: '/readGoogleAccessToken',
secureHandler: async ({ user, res }) => {
- const { credentials } = (await GoogleApiServerUtils.retrieveCredentials(user.id));
+ const { credentials } = await GoogleApiServerUtils.retrieveCredentials(user.id);
if (!credentials?.access_token) {
return res.send(GoogleApiServerUtils.generateAuthenticationUrl());
}
return res.send(credentials);
- }
+ },
});
register({
method: Method.POST,
- subscription: "/writeGoogleAccessToken",
+ subscription: '/writeGoogleAccessToken',
secureHandler: async ({ user, req, res }) => {
res.send(await GoogleApiServerUtils.processNewUser(user.id, req.body.authenticationCode));
- }
+ },
});
register({
method: Method.GET,
- subscription: "/revokeGoogleAccessToken",
+ subscription: '/revokeGoogleAccessToken',
secureHandler: async ({ user, res }) => {
await Database.Auxiliary.GoogleAccessToken.Revoke(user.id);
res.send();
- }
+ },
});
register({
method: Method.POST,
- subscription: new RouteSubscriber("googleDocs").add("sector", "action"),
+ subscription: new RouteSubscriber('googleDocs').add('sector', 'action'),
secureHandler: async ({ req, res, user }) => {
const sector: GoogleApiServerUtils.Service = req.params.sector as GoogleApiServerUtils.Service;
const action: GoogleApiServerUtils.Action = req.params.action as GoogleApiServerUtils.Action;
@@ -61,8 +59,7 @@ export default class GeneralGoogleManager extends ApiManager {
return;
}
res.send(undefined);
- }
+ },
});
-
}
-} \ No newline at end of file
+}
diff --git a/src/server/ApiManagers/MongoStore.js b/src/server/ApiManagers/MongoStore.js
new file mode 100644
index 000000000..5d91c2805
--- /dev/null
+++ b/src/server/ApiManagers/MongoStore.js
@@ -0,0 +1,413 @@
+const __createBinding =
+ (this && this.__createBinding) ||
+ (Object.create
+ ? function (o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ let desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = {
+ enumerable: true,
+ get: function () {
+ return m[k];
+ },
+ };
+ }
+ Object.defineProperty(o, k2, desc);
+ }
+ : function (o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+ });
+const __setModuleDefault =
+ (this && this.__setModuleDefault) ||
+ (Object.create
+ ? function (o, v) {
+ Object.defineProperty(o, 'default', { enumerable: true, value: v });
+ }
+ : function (o, v) {
+ o.default = v;
+ });
+const __importStar =
+ (this && this.__importStar) ||
+ function (mod) {
+ if (mod && mod.__esModule) return mod;
+ const result = {};
+ if (mod != null) for (const k in mod) if (k !== 'default' && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+ };
+const __importDefault =
+ (this && this.__importDefault) ||
+ function (mod) {
+ return mod && mod.__esModule ? mod : { default: mod };
+ };
+Object.defineProperty(exports, '__esModule', { value: true });
+const console_1 = require('console');
+const util_1 = __importDefault(require('util'));
+const session = __importStar(require('express-session'));
+const mongodb_1 = require('mongodb');
+const debug_1 = __importDefault(require('debug'));
+const debug = (0, debug_1.default)('connect-mongo');
+// eslint-disable-next-line @typescript-eslint/no-empty-function
+const noop = () => {};
+const unit = a => a;
+function defaultSerializeFunction(session) {
+ // Copy each property of the session to a new object
+ const obj = {};
+ let prop;
+ for (prop in session) {
+ if (prop === 'cookie') {
+ // Convert the cookie instance to an object, if possible
+ // This gets rid of the duplicate object under session.cookie.data property
+ // @ts-ignore FIXME:
+ obj.cookie = session.cookie.toJSON
+ ? // @ts-ignore FIXME:
+ session.cookie.toJSON()
+ : session.cookie;
+ } else {
+ // @ts-ignore FIXME:
+ obj[prop] = session[prop];
+ }
+ }
+ return obj;
+}
+function computeTransformFunctions(options) {
+ if (options.serialize || options.unserialize) {
+ return {
+ serialize: options.serialize || defaultSerializeFunction,
+ unserialize: options.unserialize || unit,
+ };
+ }
+ if (options.stringify === false) {
+ return {
+ serialize: defaultSerializeFunction,
+ unserialize: unit,
+ };
+ }
+ // Default case
+ return {
+ serialize: JSON.stringify,
+ unserialize: JSON.parse,
+ };
+}
+class MongoStore extends session.Store {
+ constructor({ collectionName = 'sessions', ttl = 1209600, mongoOptions = {}, autoRemove = 'native', autoRemoveInterval = 10, touchAfter = 0, stringify = true, crypto, ...required }) {
+ super();
+ this.crypto = null;
+ debug('create MongoStore instance');
+ const options = {
+ collectionName,
+ ttl,
+ mongoOptions,
+ autoRemove,
+ autoRemoveInterval,
+ touchAfter,
+ stringify,
+ crypto: {
+ ...{
+ secret: false,
+ algorithm: 'aes-256-gcm',
+ hashing: 'sha512',
+ encodeas: 'base64',
+ key_size: 32,
+ iv_size: 16,
+ at_size: 16,
+ },
+ ...crypto,
+ },
+ ...required,
+ };
+ // Check params
+ (0, console_1.assert)(options.mongoUrl || options.clientPromise || options.client, 'You must provide either mongoUrl|clientPromise|client in options');
+ (0, console_1.assert)(options.createAutoRemoveIdx === null || options.createAutoRemoveIdx === undefined, 'options.createAutoRemoveIdx has been reverted to autoRemove and autoRemoveInterval');
+ (0, console_1.assert)(!options.autoRemoveInterval || options.autoRemoveInterval <= 71582, /* (Math.pow(2, 32) - 1) / (1000 * 60) */ 'autoRemoveInterval is too large. options.autoRemoveInterval is in minutes but not seconds nor mills');
+ this.transformFunctions = computeTransformFunctions(options);
+ let _clientP;
+ if (options.mongoUrl) {
+ _clientP = mongodb_1.MongoClient.connect(options.mongoUrl, options.mongoOptions);
+ } else if (options.clientPromise) {
+ _clientP = options.clientPromise;
+ } else if (options.client) {
+ _clientP = Promise.resolve(options.client);
+ } else {
+ throw new Error('Cannot init client. Please provide correct options');
+ }
+ (0, console_1.assert)(!!_clientP, 'Client is null|undefined');
+ this.clientP = _clientP;
+ this.options = options;
+ this.collectionP = _clientP.then(async con => {
+ const collection = con.db(options.dbName).collection(options.collectionName);
+ await this.setAutoRemove(collection);
+ return collection;
+ });
+ if (options.crypto.secret) {
+ this.crypto = require('kruptein')(options.crypto);
+ }
+ }
+ static create(options) {
+ return new MongoStore(options);
+ }
+ setAutoRemove(collection) {
+ const removeQuery = () => ({
+ expires: {
+ $lt: new Date(),
+ },
+ });
+ switch (this.options.autoRemove) {
+ case 'native':
+ debug('Creating MongoDB TTL index');
+ return collection.createIndex(
+ { expires: 1 },
+ {
+ background: true,
+ expireAfterSeconds: 0,
+ }
+ );
+ case 'interval':
+ debug('create Timer to remove expired sessions');
+ this.timer = setInterval(
+ () =>
+ collection.deleteMany(removeQuery(), {
+ writeConcern: {
+ w: 0,
+ j: false,
+ },
+ }),
+ this.options.autoRemoveInterval * 1000 * 60
+ );
+ this.timer.unref();
+ return Promise.resolve();
+ case 'disabled':
+ default:
+ return Promise.resolve();
+ }
+ }
+ computeStorageId(sessionId) {
+ if (this.options.transformId && typeof this.options.transformId === 'function') {
+ return this.options.transformId(sessionId);
+ }
+ return sessionId;
+ }
+ /**
+ * promisify and bind the `this.crypto.get` function.
+ * Please check !!this.crypto === true before using this getter!
+ */
+ get cryptoGet() {
+ if (!this.crypto) {
+ throw new Error('Check this.crypto before calling this.cryptoGet!');
+ }
+ return util_1.default.promisify(this.crypto.get).bind(this.crypto);
+ }
+ /**
+ * Decrypt given session data
+ * @param session session data to be decrypt. Mutate the input session.
+ */
+ async decryptSession(session) {
+ if (this.crypto && session) {
+ const plaintext = await this.cryptoGet(this.options.crypto.secret, session.session).catch(err => {
+ throw new Error(err);
+ });
+ // @ts-ignore
+ session.session = JSON.parse(plaintext);
+ }
+ }
+ /**
+ * Get a session from the store given a session ID (sid)
+ * @param sid session ID
+ */
+ get(sid, callback) {
+ (async () => {
+ try {
+ debug(`MongoStore#get=${sid}`);
+ const collection = await this.collectionP;
+ const session = await collection.findOne({
+ _id: this.computeStorageId(sid),
+ $or: [{ expires: { $exists: false } }, { expires: { $gt: new Date() } }],
+ });
+ if (this.crypto && session) {
+ await this.decryptSession(session).catch(err => callback(err));
+ }
+ const s = session && this.transformFunctions.unserialize(session.session);
+ if (this.options.touchAfter > 0 && (session === null || session === void 0 ? void 0 : session.lastModified)) {
+ s.lastModified = session.lastModified;
+ }
+ this.emit('get', sid);
+ callback(null, s === undefined ? null : s);
+ } catch (error) {
+ callback(error);
+ }
+ })();
+ }
+ /**
+ * Upsert a session into the store given a session ID (sid) and session (session) object.
+ * @param sid session ID
+ * @param session session object
+ */
+ set(sid, session, callback = noop) {
+ (async () => {
+ let _a;
+ try {
+ debug(`MongoStore#set=${sid}`);
+ // Removing the lastModified prop from the session object before update
+ // @ts-ignore
+ if (this.options.touchAfter > 0 && (session === null || session === void 0 ? void 0 : session.lastModified)) {
+ // @ts-ignore
+ delete session.lastModified;
+ }
+ const s = {
+ _id: this.computeStorageId(sid),
+ session: this.transformFunctions.serialize(session),
+ };
+ // Expire handling
+ if ((_a = session === null || session === void 0 ? void 0 : session.cookie) === null || _a === void 0 ? void 0 : _a.expires) {
+ s.expires = new Date(session.cookie.expires);
+ } else {
+ // If there's no expiration date specified, it is
+ // browser-session cookie or there is no cookie at all,
+ // as per the connect docs.
+ //
+ // So we set the expiration to two-weeks from now
+ // - as is common practice in the industry (e.g Django) -
+ // or the default specified in the options.
+ s.expires = new Date(Date.now() + this.options.ttl * 1000);
+ }
+ // Last modify handling
+ if (this.options.touchAfter > 0) {
+ s.lastModified = new Date();
+ }
+ if (this.crypto) {
+ const cryptoSet = util_1.default.promisify(this.crypto.set).bind(this.crypto);
+ const data = await cryptoSet(this.options.crypto.secret, s.session).catch(err => {
+ throw new Error(err);
+ });
+ s.session = data;
+ }
+ const collection = await this.collectionP;
+ const rawResp = await collection.updateOne(
+ { _id: s._id },
+ { $set: s },
+ {
+ upsert: true,
+ writeConcern: this.options.writeOperationOptions,
+ }
+ );
+ if (rawResp.upsertedCount > 0) {
+ this.emit('create', sid);
+ } else {
+ this.emit('update', sid);
+ }
+ this.emit('set', sid);
+ } catch (error) {
+ return callback(error);
+ }
+ return callback(null);
+ })();
+ }
+ touch(sid, session, callback = noop) {
+ (async () => {
+ let _a;
+ try {
+ debug(`MongoStore#touch=${sid}`);
+ const updateFields = {};
+ const touchAfter = this.options.touchAfter * 1000;
+ const lastModified = session.lastModified ? session.lastModified.getTime() : 0;
+ const currentDate = new Date();
+ // If the given options has a touchAfter property, check if the
+ // current timestamp - lastModified timestamp is bigger than
+ // the specified, if it's not, don't touch the session
+ if (touchAfter > 0 && lastModified > 0) {
+ const timeElapsed = currentDate.getTime() - lastModified;
+ if (timeElapsed < touchAfter) {
+ debug(`Skip touching session=${sid}`);
+ return callback(null);
+ }
+ updateFields.lastModified = currentDate;
+ }
+ if ((_a = session === null || session === void 0 ? void 0 : session.cookie) === null || _a === void 0 ? void 0 : _a.expires) {
+ updateFields.expires = new Date(session.cookie.expires);
+ } else {
+ updateFields.expires = new Date(Date.now() + this.options.ttl * 1000);
+ }
+ const collection = await this.collectionP;
+ const rawResp = await collection.updateOne({ _id: this.computeStorageId(sid) }, { $set: updateFields }, { writeConcern: this.options.writeOperationOptions });
+ if (rawResp.matchedCount === 0) {
+ return callback(new Error('Unable to find the session to touch'));
+ } else {
+ this.emit('touch', sid, session);
+ return callback(null);
+ }
+ } catch (error) {
+ return callback(error);
+ }
+ })();
+ }
+ /**
+ * Get all sessions in the store as an array
+ */
+ all(callback) {
+ (async () => {
+ try {
+ debug('MongoStore#all()');
+ const collection = await this.collectionP;
+ const sessions = collection.find({
+ $or: [{ expires: { $exists: false } }, { expires: { $gt: new Date() } }],
+ });
+ const results = [];
+ for await (const session of sessions) {
+ if (this.crypto && session) {
+ await this.decryptSession(session);
+ }
+ results.push(this.transformFunctions.unserialize(session.session));
+ }
+ this.emit('all', results);
+ callback(null, results);
+ } catch (error) {
+ callback(error);
+ }
+ })();
+ }
+ /**
+ * Destroy/delete a session from the store given a session ID (sid)
+ * @param sid session ID
+ */
+ destroy(sid, callback = noop) {
+ debug(`MongoStore#destroy=${sid}`);
+ this.collectionP
+ .then(colleciton => colleciton.deleteOne({ _id: this.computeStorageId(sid) }, { writeConcern: this.options.writeOperationOptions }))
+ .then(() => {
+ this.emit('destroy', sid);
+ callback(null);
+ })
+ .catch(err => callback(err));
+ }
+ /**
+ * Get the count of all sessions in the store
+ */
+ length(callback) {
+ debug('MongoStore#length()');
+ this.collectionP
+ .then(collection => collection.countDocuments())
+ .then(c => callback(null, c))
+ // @ts-ignore
+ .catch(err => callback(err));
+ }
+ /**
+ * Delete all sessions from the store.
+ */
+ clear(callback = noop) {
+ debug('MongoStore#clear()');
+ this.collectionP
+ .then(collection => collection.drop())
+ .then(() => callback(null))
+ .catch(err => callback(err));
+ }
+ /**
+ * Close database connection
+ */
+ close() {
+ debug('MongoStore#close()');
+ return this.clientP.then(c => c.close());
+ }
+}
+exports.default = MongoStore;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTW9uZ29TdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvTW9uZ29TdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEscUNBQWdDO0FBQ2hDLGdEQUF1QjtBQUN2Qix5REFBMEM7QUFDMUMscUNBS2dCO0FBQ2hCLGtEQUF5QjtBQUd6QixNQUFNLEtBQUssR0FBRyxJQUFBLGVBQUssRUFBQyxlQUFlLENBQUMsQ0FBQTtBQWdFcEMsZ0VBQWdFO0FBQ2hFLE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQTtBQUNyQixNQUFNLElBQUksR0FBbUIsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQTtBQUVyQyxTQUFTLHdCQUF3QixDQUMvQixPQUE0QjtJQUU1QixvREFBb0Q7SUFDcEQsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFBO0lBQ2QsSUFBSSxJQUFJLENBQUE7SUFDUixLQUFLLElBQUksSUFBSSxPQUFPLEVBQUU7UUFDcEIsSUFBSSxJQUFJLEtBQUssUUFBUSxFQUFFO1lBQ3JCLHdEQUF3RDtZQUN4RCwyRUFBMkU7WUFDM0Usb0JBQW9CO1lBQ3BCLEdBQUcsQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNO2dCQUNoQyxDQUFDLENBQUMsb0JBQW9CO29CQUNwQixPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRTtnQkFDekIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUE7U0FDbkI7YUFBTTtZQUNMLG9CQUFvQjtZQUNwQixHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFBO1NBQzFCO0tBQ0Y7SUFFRCxPQUFPLEdBQTBCLENBQUE7QUFDbkMsQ0FBQztBQUVELFNBQVMseUJBQXlCLENBQUMsT0FBbUM7SUFDcEUsSUFBSSxPQUFPLENBQUMsU0FBUyxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUU7UUFDNUMsT0FBTztZQUNMLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxJQUFJLHdCQUF3QjtZQUN4RCxXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVcsSUFBSSxJQUFJO1NBQ3pDLENBQUE7S0FDRjtJQUVELElBQUksT0FBTyxDQUFDLFNBQVMsS0FBSyxLQUFLLEVBQUU7UUFDL0IsT0FBTztZQUNMLFNBQVMsRUFBRSx3QkFBd0I7WUFDbkMsV0FBVyxFQUFFLElBQUk7U0FDbEIsQ0FBQTtLQUNGO0lBQ0QsZUFBZTtJQUNmLE9BQU87UUFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7UUFDekIsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLO0tBQ3hCLENBQUE7QUFDSCxDQUFDO0FBRUQsTUFBcUIsVUFBVyxTQUFRLE9BQU8sQ0FBQyxLQUFLO0lBWW5ELFlBQVksRUFDVixjQUFjLEdBQUcsVUFBVSxFQUMzQixHQUFHLEdBQUcsT0FBTyxFQUNiLFlBQVksR0FBRyxFQUFFLEVBQ2pCLFVBQVUsR0FBRyxRQUFRLEVBQ3JCLGtCQUFrQixHQUFHLEVBQUUsRUFDdkIsVUFBVSxHQUFHLENBQUMsRUFDZCxTQUFTLEdBQUcsSUFBSSxFQUNoQixNQUFNLEVBQ04sR0FBRyxRQUFRLEVBQ1M7UUFDcEIsS0FBSyxFQUFFLENBQUE7UUFyQkQsV0FBTSxHQUFvQixJQUFJLENBQUE7UUFzQnBDLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFBO1FBQ25DLE1BQU0sT0FBTyxHQUErQjtZQUMxQyxjQUFjO1lBQ2QsR0FBRztZQUNILFlBQVk7WUFDWixVQUFVO1lBQ1Ysa0JBQWtCO1lBQ2xCLFVBQVU7WUFDVixTQUFTO1lBQ1QsTUFBTSxFQUFFO2dCQUNOLEdBQUc7b0JBQ0QsTUFBTSxFQUFFLEtBQUs7b0JBQ2IsU0FBUyxFQUFFLGFBQWE7b0JBQ3hCLE9BQU8sRUFBRSxRQUFRO29CQUNqQixRQUFRLEVBQUUsUUFBUTtvQkFDbEIsUUFBUSxFQUFFLEVBQUU7b0JBQ1osT0FBTyxFQUFFLEVBQUU7b0JBQ1gsT0FBTyxFQUFFLEVBQUU7aUJBQ1o7Z0JBQ0QsR0FBRyxNQUFNO2FBQ1Y7WUFDRCxHQUFHLFFBQVE7U0FDWixDQUFBO1FBQ0QsZUFBZTtRQUNmLElBQUEsZ0JBQU0sRUFDSixPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDLE1BQU0sRUFDM0Qsa0VBQWtFLENBQ25FLENBQUE7UUFDRCxJQUFBLGdCQUFNLEVBQ0osT0FBTyxDQUFDLG1CQUFtQixLQUFLLElBQUk7WUFDbEMsT0FBTyxDQUFDLG1CQUFtQixLQUFLLFNBQVMsRUFDM0Msb0ZBQW9GLENBQ3JGLENBQUE7UUFDRCxJQUFBLGdCQUFNLEVBQ0osQ0FBQyxPQUFPLENBQUMsa0JBQWtCLElBQUksT0FBTyxDQUFDLGtCQUFrQixJQUFJLEtBQUs7UUFDbEUseUNBQXlDLENBQUMscUdBQXFHLENBQ2hKLENBQUE7UUFDRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcseUJBQXlCLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDNUQsSUFBSSxRQUE4QixDQUFBO1FBQ2xDLElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRTtZQUNwQixRQUFRLEdBQUcscUJBQVcsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUE7U0FDdkU7YUFBTSxJQUFJLE9BQU8sQ0FBQyxhQUFhLEVBQUU7WUFDaEMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUE7U0FDakM7YUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUU7WUFDekIsUUFBUSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1NBQzNDO2FBQU07WUFDTCxNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUE7U0FDdEU7UUFDRCxJQUFBLGdCQUFNLEVBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSwwQkFBMEIsQ0FBQyxDQUFBO1FBQzlDLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFBO1FBQ3ZCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO1FBQ3RCLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDN0MsTUFBTSxVQUFVLEdBQUcsR0FBRztpQkFDbkIsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7aUJBQ2xCLFVBQVUsQ0FBc0IsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFBO1lBQzFELE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUNwQyxPQUFPLFVBQVUsQ0FBQTtRQUNuQixDQUFDLENBQUMsQ0FBQTtRQUNGLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDekIsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1NBQ2xEO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBNEI7UUFDeEMsT0FBTyxJQUFJLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUNoQyxDQUFDO0lBRU8sYUFBYSxDQUNuQixVQUEyQztRQUUzQyxNQUFNLFdBQVcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ3pCLE9BQU8sRUFBRTtnQkFDUCxHQUFHLEVBQUUsSUFBSSxJQUFJLEVBQUU7YUFDaEI7U0FDRixDQUFDLENBQUE7UUFDRixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFO1lBQy9CLEtBQUssUUFBUTtnQkFDWCxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQTtnQkFDbkMsT0FBTyxVQUFVLENBQUMsV0FBVyxDQUMzQixFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFDZDtvQkFDRSxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsa0JBQWtCLEVBQUUsQ0FBQztpQkFDdEIsQ0FDRixDQUFBO1lBQ0gsS0FBSyxVQUFVO2dCQUNiLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFBO2dCQUNoRCxJQUFJLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FDdEIsR0FBRyxFQUFFLENBQ0gsVUFBVSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsRUFBRTtvQkFDbkMsWUFBWSxFQUFFO3dCQUNaLENBQUMsRUFBRSxDQUFDO3dCQUNKLENBQUMsRUFBRSxLQUFLO3FCQUNUO2lCQUNGLENBQUMsRUFDSixJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixHQUFHLElBQUksR0FBRyxFQUFFLENBQzVDLENBQUE7Z0JBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQTtnQkFDbEIsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUE7WUFDMUIsS0FBSyxVQUFVLENBQUM7WUFDaEI7Z0JBQ0UsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUE7U0FDM0I7SUFDSCxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsU0FBaUI7UUFDeEMsSUFDRSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVc7WUFDeEIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsS0FBSyxVQUFVLEVBQzlDO1lBQ0EsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQTtTQUMzQztRQUNELE9BQU8sU0FBUyxDQUFBO0lBQ2xCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFZLFNBQVM7UUFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxrREFBa0QsQ0FBQyxDQUFBO1NBQ3BFO1FBQ0QsT0FBTyxjQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMxRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssS0FBSyxDQUFDLGNBQWMsQ0FDMUIsT0FBK0M7UUFFL0MsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sRUFBRTtZQUMxQixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQ3BDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQWdCLEVBQ3BDLE9BQU8sQ0FBQyxPQUFPLENBQ2hCLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ2QsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUN0QixDQUFDLENBQUMsQ0FBQTtZQUNGLGFBQWE7WUFDYixPQUFPLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUE7U0FDeEM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsR0FBRyxDQUNELEdBQVcsRUFDWCxRQUFrRTtRQUVsRSxDQUFDO1FBQUEsQ0FBQyxLQUFLLElBQUksRUFBRTtZQUNYLElBQUk7Z0JBQ0YsS0FBSyxDQUFDLGtCQUFrQixHQUFHLEVBQUUsQ0FBQyxDQUFBO2dCQUM5QixNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUE7Z0JBQ3pDLE1BQU0sT0FBTyxHQUFHLE1BQU0sVUFBVSxDQUFDLE9BQU8sQ0FBQztvQkFDdkMsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUM7b0JBQy9CLEdBQUcsRUFBRTt3QkFDSCxFQUFFLE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRTt3QkFDL0IsRUFBRSxPQUFPLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxJQUFJLEVBQUUsRUFBRSxFQUFFO3FCQUNqQztpQkFDRixDQUFDLENBQUE7Z0JBQ0YsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sRUFBRTtvQkFDMUIsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUN2QixPQUF5QyxDQUMxQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7aUJBQ2hDO2dCQUNELE1BQU0sQ0FBQyxHQUNMLE9BQU8sSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQTtnQkFDakUsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxDQUFDLEtBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFlBQVksQ0FBQSxFQUFFO29CQUN4RCxDQUFDLENBQUMsWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUE7aUJBQ3RDO2dCQUNELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFBO2dCQUNyQixRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7YUFDM0M7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDZCxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7YUFDaEI7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFBO0lBQ04sQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxHQUFHLENBQ0QsR0FBVyxFQUNYLE9BQTRCLEVBQzVCLFdBQStCLElBQUk7UUFFbkMsQ0FBQztRQUFBLENBQUMsS0FBSyxJQUFJLEVBQUU7O1lBQ1gsSUFBSTtnQkFDRixLQUFLLENBQUMsa0JBQWtCLEdBQUcsRUFBRSxDQUFDLENBQUE7Z0JBQzlCLHVFQUF1RTtnQkFDdkUsYUFBYTtnQkFDYixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLENBQUMsS0FBSSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsWUFBWSxDQUFBLEVBQUU7b0JBQ3hELGFBQWE7b0JBQ2IsT0FBTyxPQUFPLENBQUMsWUFBWSxDQUFBO2lCQUM1QjtnQkFDRCxNQUFNLENBQUMsR0FBd0I7b0JBQzdCLEdBQUcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDO29CQUMvQixPQUFPLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUM7aUJBQ3BELENBQUE7Z0JBQ0Qsa0JBQWtCO2dCQUNsQixJQUFJLE1BQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLE1BQU0sMENBQUUsT0FBTyxFQUFFO29CQUM1QixDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUE7aUJBQzdDO3FCQUFNO29CQUNMLGlEQUFpRDtvQkFDakQsdURBQXVEO29CQUN2RCwyQkFBMkI7b0JBQzNCLEVBQUU7b0JBQ0YsaURBQWlEO29CQUNqRCx5REFBeUQ7b0JBQ3pELDJDQUEyQztvQkFDM0MsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUE7aUJBQzNEO2dCQUNELHVCQUF1QjtnQkFDdkIsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUU7b0JBQy9CLENBQUMsQ0FBQyxZQUFZLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQTtpQkFDNUI7Z0JBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO29CQUNmLE1BQU0sU0FBUyxHQUFHLGNBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO29CQUNuRSxNQUFNLElBQUksR0FBRyxNQUFNLFNBQVMsQ0FDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBZ0IsRUFDcEMsQ0FBQyxDQUFDLE9BQU8sQ0FDVixDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO3dCQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7b0JBQ3RCLENBQUMsQ0FBQyxDQUFBO29CQUNGLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBc0MsQ0FBQTtpQkFDbkQ7Z0JBQ0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFBO2dCQUN6QyxNQUFNLE9BQU8sR0FBRyxNQUFNLFVBQVUsQ0FBQyxTQUFTLENBQ3hDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFDZCxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFDWDtvQkFDRSxNQUFNLEVBQUUsSUFBSTtvQkFDWixZQUFZLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUI7aUJBQ2pELENBQ0YsQ0FBQTtnQkFDRCxJQUFJLE9BQU8sQ0FBQyxhQUFhLEdBQUcsQ0FBQyxFQUFFO29CQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQTtpQkFDekI7cUJBQU07b0JBQ0wsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUE7aUJBQ3pCO2dCQUNELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFBO2FBQ3RCO1lBQUMsT0FBTyxLQUFLLEVBQUU7Z0JBQ2QsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7YUFDdkI7WUFDRCxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUN2QixDQUFDLENBQUMsRUFBRSxDQUFBO0lBQ04sQ0FBQztJQUVELEtBQUssQ0FDSCxHQUFXLEVBQ1gsT0FBc0QsRUFDdEQsV0FBK0IsSUFBSTtRQUVuQyxDQUFDO1FBQUEsQ0FBQyxLQUFLLElBQUksRUFBRTs7WUFDWCxJQUFJO2dCQUNGLEtBQUssQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUMsQ0FBQTtnQkFDaEMsTUFBTSxZQUFZLEdBSWQsRUFBRSxDQUFBO2dCQUNOLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQTtnQkFDakQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVk7b0JBQ3ZDLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRTtvQkFDaEMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtnQkFDTCxNQUFNLFdBQVcsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFBO2dCQUU5QiwrREFBK0Q7Z0JBQy9ELDREQUE0RDtnQkFDNUQsc0RBQXNEO2dCQUN0RCxJQUFJLFVBQVUsR0FBRyxDQUFDLElBQUksWUFBWSxHQUFHLENBQUMsRUFBRTtvQkFDdEMsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxHQUFHLFlBQVksQ0FBQTtvQkFDeEQsSUFBSSxXQUFXLEdBQUcsVUFBVSxFQUFFO3dCQUM1QixLQUFLLENBQUMseUJBQXlCLEdBQUcsRUFBRSxDQUFDLENBQUE7d0JBQ3JDLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO3FCQUN0QjtvQkFDRCxZQUFZLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQTtpQkFDeEM7Z0JBRUQsSUFBSSxNQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxNQUFNLDBDQUFFLE9BQU8sRUFBRTtvQkFDNUIsWUFBWSxDQUFDLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO2lCQUN4RDtxQkFBTTtvQkFDTCxZQUFZLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQTtpQkFDdEU7Z0JBQ0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFBO2dCQUN6QyxNQUFNLE9BQU8sR0FBRyxNQUFNLFVBQVUsQ0FBQyxTQUFTLENBQ3hDLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUNuQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsRUFDdEIsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUNyRCxDQUFBO2dCQUNELElBQUksT0FBTyxDQUFDLFlBQVksS0FBSyxDQUFDLEVBQUU7b0JBQzlCLE9BQU8sUUFBUSxDQUFDLElBQUksS0FBSyxDQUFDLHFDQUFxQyxDQUFDLENBQUMsQ0FBQTtpQkFDbEU7cUJBQU07b0JBQ0wsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFBO29CQUNoQyxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtpQkFDdEI7YUFDRjtZQUFDLE9BQU8sS0FBSyxFQUFFO2dCQUNkLE9BQU8sUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFBO2FBQ3ZCO1FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUNOLENBQUM7SUFFRDs7T0FFRztJQUNILEdBQUcsQ0FDRCxRQU1TO1FBRVQsQ0FBQztRQUFBLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDWCxJQUFJO2dCQUNGLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO2dCQUN6QixNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUE7Z0JBQ3pDLE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7b0JBQy9CLEdBQUcsRUFBRTt3QkFDSCxFQUFFLE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRTt3QkFDL0IsRUFBRSxPQUFPLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxJQUFJLEVBQUUsRUFBRSxFQUFFO3FCQUNqQztpQkFDRixDQUFDLENBQUE7Z0JBQ0YsTUFBTSxPQUFPLEdBQTBCLEVBQUUsQ0FBQTtnQkFDekMsSUFBSSxLQUFLLEVBQUUsTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFO29CQUNwQyxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxFQUFFO3dCQUMxQixNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBeUMsQ0FBQyxDQUFBO3FCQUNyRTtvQkFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7aUJBQ25FO2dCQUNELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFBO2dCQUN6QixRQUFRLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFBO2FBQ3hCO1lBQUMsT0FBTyxLQUFLLEVBQUU7Z0JBQ2QsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFBO2FBQ2hCO1FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUNOLENBQUM7SUFFRDs7O09BR0c7SUFDSCxPQUFPLENBQUMsR0FBVyxFQUFFLFdBQStCLElBQUk7UUFDdEQsS0FBSyxDQUFDLHNCQUFzQixHQUFHLEVBQUUsQ0FBQyxDQUFBO1FBQ2xDLElBQUksQ0FBQyxXQUFXO2FBQ2IsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FDbkIsVUFBVSxDQUFDLFNBQVMsQ0FDbEIsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQ25DLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FDckQsQ0FDRjthQUNBLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQTtZQUN6QixRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDaEIsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtJQUNsQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsUUFBNEM7UUFDakQsS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUE7UUFDNUIsSUFBSSxDQUFDLFdBQVc7YUFDYixJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUNqRCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0IsYUFBYTthQUNaLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDbEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFdBQStCLElBQUk7UUFDdkMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUE7UUFDM0IsSUFBSSxDQUFDLFdBQVc7YUFDYixJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUN2QyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQzFCLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDbEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSztRQUNILEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO1FBQzNCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO0lBQzVDLENBQUM7Q0FDRjtBQW5hRCw2QkFtYUMifQ==
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts
index 72c01def7..684b49eaf 100644
--- a/src/server/ApiManagers/SearchManager.ts
+++ b/src/server/ApiManagers/SearchManager.ts
@@ -1,14 +1,12 @@
+/* eslint-disable no-use-before-define */
import { exec } from 'child_process';
import { cyan, green, red, yellow } from 'colors';
-import * as path from 'path';
-import { log_execution } from '../ActionUtilities';
-import { Database } from '../database';
+import { logExecution } from '../ActionUtilities';
import { Method } from '../RouteManager';
import RouteSubscriber from '../RouteSubscriber';
import { Search } from '../Search';
+import { Database } from '../database';
import ApiManager, { Registration } from './ApiManager';
-import { Directory, pathToDirectory } from './UploadManager';
-import { find } from 'find-in-files';
export class SearchManager extends ApiManager {
protected initialize(register: Registration): void {
@@ -20,8 +18,10 @@ export class SearchManager extends ApiManager {
switch (action) {
case 'start':
case 'stop':
- const status = req.params.action === 'start';
- SolrManager.SetRunning(status);
+ {
+ const status = req.params.action === 'start';
+ SolrManager.SetRunning(status);
+ }
break;
case 'update':
await SolrManager.update();
@@ -35,39 +35,12 @@ export class SearchManager extends ApiManager {
register({
method: Method.GET,
- subscription: '/textsearch',
- secureHandler: async ({ req, res }) => {
- const q = req.query.q;
- if (q === undefined) {
- res.send([]);
- return;
- }
- const resObj: { ids: string[]; numFound: number; lines: string[] } = { ids: [], numFound: 0, lines: [] };
- let results: any;
- const dir = pathToDirectory(Directory.text);
- try {
- const regex = new RegExp(q.toString());
- results = await find({ term: q, flags: 'ig' }, dir, '.txt$');
- for (const result in results) {
- resObj.ids.push(path.basename(result, '.txt').replace(/upload_/, ''));
- resObj.lines.push(results[result].line);
- resObj.numFound++;
- }
- res.send(resObj);
- } catch (e) {
- console.log(red('textsearch:bad RegExp' + q.toString()));
- res.send([]);
- return;
- }
- },
- });
-
- register({
- method: Method.GET,
subscription: '/dashsearch',
secureHandler: async ({ req, res }) => {
const solrQuery: any = {};
- ['q', 'fq', 'start', 'rows', 'sort', 'hl.maxAnalyzedChars', 'hl', 'hl.fl'].forEach(key => (solrQuery[key] = req.query[key]));
+ ['q', 'fq', 'start', 'rows', 'sort', 'hl.maxAnalyzedChars', 'hl', 'hl.fl'].forEach(key => {
+ solrQuery[key] = req.query[key];
+ });
if (solrQuery.q === undefined) {
res.send([]);
return;
@@ -98,13 +71,13 @@ export namespace SolrManager {
export async function update() {
console.log(green('Beginning update...'));
- await log_execution<void>({
+ await logExecution<void>({
startMessage: 'Clearing existing Solr information...',
endMessage: 'Solr information successfully cleared',
action: Search.clear,
color: cyan,
});
- const cursor = await log_execution({
+ const cursor = await logExecution({
startMessage: 'Connecting to and querying for all documents from database...',
endMessage: ({ result, error }) => {
const success = error === null && result !== undefined;
@@ -127,30 +100,30 @@ export namespace SolrManager {
if (doc.__type !== 'Doc') {
return;
}
- const fields = doc.fields;
+ const { fields } = doc;
if (!fields) {
return;
}
- const update: any = { id: doc._id };
+ const update2: any = { id: doc._id };
let dynfield = false;
- for (const key in fields) {
+ fields.forEach((key: any) => {
const value = fields[key];
const term = ToSearchTerm(value);
if (term !== undefined) {
- const { suffix, value } = term;
+ const { suffix, value: tvalue } = term;
if (key.endsWith('modificationDate')) {
- update['modificationDate' + suffix] = value;
+ update2['modificationDate' + suffix] = tvalue;
}
- update[key + suffix] = value;
+ update2[key + suffix] = value;
dynfield = true;
}
- }
+ });
if (dynfield) {
- updates.push(update);
+ updates.push(update2);
}
}
await cursor?.forEach(updateDoc);
- const result = await log_execution({
+ const result = await logExecution({
startMessage: `Dispatching updates for ${updates.length} documents`,
endMessage: 'Dispatched updates complete',
action: () => Search.updateDocuments(updates),
@@ -188,6 +161,7 @@ export namespace SolrManager {
'_l',
list => {
const results = [];
+ // eslint-disable-next-line no-restricted-syntax
for (const value of list.fields) {
const term = ToSearchTerm(value);
if (term) {
@@ -199,14 +173,15 @@ export namespace SolrManager {
],
};
- function ToSearchTerm(val: any): { suffix: string; value: any } | undefined {
+ function ToSearchTerm(valIn: any): { suffix: string; value: any } | undefined {
+ let val = valIn;
if (val === null || val === undefined) {
- return;
+ return undefined;
}
const type = val.__type || typeof val;
let suffix = suffixMap[type];
if (!suffix) {
- return;
+ return undefined;
}
if (Array.isArray(suffix)) {
@@ -216,6 +191,7 @@ export namespace SolrManager {
} else {
val = val[accessor];
}
+ // eslint-disable-next-line prefer-destructuring
suffix = suffix[0];
}
diff --git a/src/server/ApiManagers/SessionManager.ts b/src/server/ApiManagers/SessionManager.ts
index e37f8c6db..bebe50a62 100644
--- a/src/server/ApiManagers/SessionManager.ts
+++ b/src/server/ApiManagers/SessionManager.ts
@@ -1,67 +1,64 @@
-import ApiManager, { Registration } from "./ApiManager";
-import { Method, _permission_denied, AuthorizedCore, SecureHandler } from "../RouteManager";
-import RouteSubscriber from "../RouteSubscriber";
-import { sessionAgent } from "..";
-import { DashSessionAgent } from "../DashSession/DashSessionAgent";
+import ApiManager, { Registration } from './ApiManager';
+import { Method, _permissionDenied, AuthorizedCore, SecureHandler } from '../RouteManager';
+import RouteSubscriber from '../RouteSubscriber';
+import { sessionAgent } from '..';
+import { DashSessionAgent } from '../DashSession/DashSessionAgent';
-const permissionError = "You are not authorized!";
+const permissionError = 'You are not authorized!';
export default class SessionManager extends ApiManager {
+ private secureSubscriber = (root: string, ...params: string[]) => new RouteSubscriber(root).add('session_key', ...params);
- private secureSubscriber = (root: string, ...params: string[]) => new RouteSubscriber(root).add("session_key", ...params);
-
- private authorizedAction = (handler: SecureHandler) => {
- return (core: AuthorizedCore) => {
- const { req: { params }, res } = core;
- if (!process.env.MONITORED) {
- return res.send("This command only makes sense in the context of a monitored session.");
- }
- if (params.session_key !== process.env.session_key) {
- return _permission_denied(res, permissionError);
- }
- return handler(core);
- };
- }
+ private authorizedAction = (handler: SecureHandler) => (core: AuthorizedCore) => {
+ const {
+ req: { params },
+ res,
+ } = core;
+ if (!process.env.MONITORED) {
+ return res.send('This command only makes sense in the context of a monitored session.');
+ }
+ if (params.session_key !== process.env.session_key) {
+ return _permissionDenied(res, permissionError);
+ }
+ return handler(core);
+ };
protected initialize(register: Registration): void {
-
register({
method: Method.GET,
- subscription: this.secureSubscriber("debug", "to?"),
+ subscription: this.secureSubscriber('debug', 'to?'),
secureHandler: this.authorizedAction(async ({ req: { params }, res }) => {
const to = params.to || DashSessionAgent.notificationRecipient;
- const { error } = await sessionAgent.serverWorker.emit("debug", { to });
+ const { error } = await sessionAgent.serverWorker.emit('debug', { to });
res.send(error ? error.message : `Your request was successful: the server captured and compressed (but did not save) a new back up. It was sent to ${to}.`);
- })
+ }),
});
register({
method: Method.GET,
- subscription: this.secureSubscriber("backup"),
+ subscription: this.secureSubscriber('backup'),
secureHandler: this.authorizedAction(async ({ res }) => {
- const { error } = await sessionAgent.serverWorker.emit("backup");
- res.send(error ? error.message : "Your request was successful: the server successfully created a new back up.");
- })
+ const { error } = await sessionAgent.serverWorker.emit('backup');
+ res.send(error ? error.message : 'Your request was successful: the server successfully created a new back up.');
+ }),
});
register({
method: Method.GET,
- subscription: this.secureSubscriber("kill"),
+ subscription: this.secureSubscriber('kill'),
secureHandler: this.authorizedAction(({ res }) => {
- res.send("Your request was successful: the server and its session have been killed.");
- sessionAgent.killSession("an authorized user has manually ended the server session via the /kill route");
- })
+ res.send('Your request was successful: the server and its session have been killed.');
+ sessionAgent.killSession('an authorized user has manually ended the server session via the /kill route');
+ }),
});
register({
method: Method.GET,
- subscription: this.secureSubscriber("deleteSession"),
+ subscription: this.secureSubscriber('deleteSession'),
secureHandler: this.authorizedAction(async ({ res }) => {
- const { error } = await sessionAgent.serverWorker.emit("delete");
- res.send(error ? error.message : "Your request was successful: the server successfully deleted the database. Return to /home.");
- })
+ const { error } = await sessionAgent.serverWorker.emit('delete');
+ res.send(error ? error.message : 'Your request was successful: the server successfully deleted the database. Return to /home.');
+ }),
});
-
}
-
-} \ No newline at end of file
+}
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 8a2fe1389..4cb3d8baf 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -1,51 +1,27 @@
+import * as AdmZip from 'adm-zip';
import * as formidable from 'formidable';
-import { createReadStream, createWriteStream, unlink, writeFile } from 'fs';
-import * as path from 'path';
+import * as fs from 'fs';
+import { createReadStream, createWriteStream, unlink } from 'fs';
+import * as imageDataUri from 'image-data-uri';
import Jimp from 'jimp';
-import { filesDirectory, publicDirectory } from '..';
+import * as path from 'path';
+import * as uuid from 'uuid';
import { retrocycle } from '../../decycler/decycler';
+import { DashVersion } from '../../fields/DocSymbols';
import { DashUploadUtils, InjectSize, SizeSuffix } from '../DashUploadUtils';
-import { Database } from '../database';
import { Method, _success } from '../RouteManager';
-import RouteSubscriber from '../RouteSubscriber';
import { AcceptableMedia, Upload } from '../SharedMediaTypes';
+import { clientPathToFile, Directory, pathToDirectory, publicDirectory, serverPathToFile } from '../SocketData';
+import { Database } from '../database';
import ApiManager, { Registration } from './ApiManager';
import { SolrManager } from './SearchManager';
-import * as uuid from 'uuid';
-import { DashVersion } from '../../fields/DocSymbols';
-import * as AdmZip from 'adm-zip';
-import * as imageDataUri from 'image-data-uri';
-import * as fs from 'fs';
-
-export enum Directory {
- parsed_files = 'parsed_files',
- images = 'images',
- videos = 'videos',
- pdfs = 'pdfs',
- text = 'text',
- pdf_thumbnails = 'pdf_thumbnails',
- audio = 'audio',
- csv = 'csv',
-}
-
-export function serverPathToFile(directory: Directory, filename: string) {
- return path.normalize(`${filesDirectory}/${directory}/${filename}`);
-}
-
-export function pathToDirectory(directory: Directory) {
- return path.normalize(`${filesDirectory}/${directory}`);
-}
-
-export function clientPathToFile(directory: Directory, filename: string) {
- return `/files/${directory}/${filename}`;
-}
export default class UploadManager extends ApiManager {
protected initialize(register: Registration): void {
register({
method: Method.POST,
subscription: '/ping',
- secureHandler: async ({ req, res }) => {
+ secureHandler: async ({ /* req, */ res }) => {
_success(res, { message: DashVersion, date: new Date() });
},
});
@@ -79,31 +55,33 @@ export default class UploadManager extends ApiManager {
form.on('progress', e => fileguids.split(';').map(guid => DashUploadUtils.uploadProgress.set(guid, `read:(${Math.round((100 * +e) / +filesize)}%) ${e} of ${filesize}`)));
return new Promise<void>(resolve => {
form.parse(req, async (_err, _fields, files) => {
- const results: Upload.FileResponse[] = [];
if (_err?.message) {
- results.push({
- source: {
- filepath: '',
- originalFilename: 'none',
- newFilename: 'none',
- mimetype: 'text',
- size: 0,
- hashAlgorithm: 'md5',
- toJSON: () => ({ name: 'none', size: 0, length: 0, mtime: new Date(), filepath: '', originalFilename: 'none', newFilename: 'none', mimetype: 'text' }),
+ _success(res, [
+ {
+ source: {
+ filepath: '',
+ originalFilename: 'none',
+ newFilename: 'none',
+ mimetype: 'text',
+ size: 0,
+ hashAlgorithm: 'md5',
+ toJSON: () => ({ name: 'none', size: 0, length: 0, mtime: new Date(), filepath: '', originalFilename: 'none', newFilename: 'none', mimetype: 'text' }),
+ },
+ result: { name: 'failed upload', message: `${_err.message}` },
},
- result: { name: 'failed upload', message: `${_err.message}` },
- });
- }
- fileguids.split(';').map(guid => DashUploadUtils.uploadProgress.set(guid, `resampling images`));
+ ]);
+ } else {
+ fileguids.split(';').map(guid => DashUploadUtils.uploadProgress.set(guid, `resampling images`));
+ const results = (
+ await Promise.all(
+ Array.from(Object.keys(files)).map(
+ async key => (!files[key] ? undefined : DashUploadUtils.upload(files[key]![0] /* , key */)) // key is the guid used by the client to track upload progress.
+ )
+ )
+ ).filter(result => result && !(result.result instanceof Error));
- for (const key in files) {
- const f = files[key];
- if (f) {
- const result = await DashUploadUtils.upload(f[0], key); // key is the guid used by the client to track upload progress.
- result && !(result.result instanceof Error) && results.push(result);
- }
+ _success(res, results);
}
- _success(res, results);
resolve();
});
});
@@ -114,17 +92,14 @@ export default class UploadManager extends ApiManager {
method: Method.POST,
subscription: '/uploadYoutubeVideo',
secureHandler: async ({ req, res }) => {
- //req.readableBuffer.head.data
- return new Promise<void>(async resolve => {
- req.addListener('data', async args => {
- const payload = String.fromCharCode.apply(String, args);
- const { videoId, overwriteId } = JSON.parse(payload);
- const results: Upload.FileResponse[] = [];
- const result = await DashUploadUtils.uploadYoutube(videoId, overwriteId ?? videoId);
- result && results.push(result);
- _success(res, results);
- resolve();
- });
+ // req.readableBuffer.head.data
+ req.addListener('data', async args => {
+ const payload = String.fromCharCode(...args); // .apply(String, args);
+ const { videoId, overwriteId } = JSON.parse(payload);
+ const results: Upload.FileResponse[] = [];
+ const result = await DashUploadUtils.uploadYoutube(videoId, overwriteId ?? videoId);
+ result && results.push(result);
+ _success(res, results);
});
},
});
@@ -133,49 +108,10 @@ export default class UploadManager extends ApiManager {
method: Method.POST,
subscription: '/queryYoutubeProgress',
secureHandler: async ({ req, res }) => {
- return new Promise<void>(async resolve => {
- req.addListener('data', args => {
- const payload = String.fromCharCode.apply(String, args);
- const videoId = JSON.parse(payload).videoId;
- _success(res, { progress: DashUploadUtils.QueryYoutubeProgress(videoId, req.user) });
- resolve();
- });
- });
- },
- });
-
- register({
- method: Method.POST,
- subscription: new RouteSubscriber('youtubeScreenshot'),
- secureHandler: async ({ req, res }) => {
- const { id, timecode } = req.body;
- const convert = (raw: string) => {
- const number = Math.floor(Number(raw));
- const seconds = number % 60;
- const minutes = (number - seconds) / 60;
- return `${minutes}m${seconds}s`;
- };
- const suffix = timecode ? `&t=${convert(timecode)}` : ``;
- const targetUrl = `https://www.youtube.com/watch?v=${id}${suffix}`;
- const buffer = await captureYoutubeScreenshot(targetUrl);
- if (!buffer) {
- return res.send();
- }
- const resolvedName = `youtube_capture_${id}_${suffix}.png`;
- const resolvedPath = serverPathToFile(Directory.images, resolvedName);
- return new Promise<void>(resolve => {
- writeFile(resolvedPath, buffer, async error => {
- if (error) {
- return res.send();
- }
- await DashUploadUtils.outputResizedImages(resolvedPath, resolvedName, pathToDirectory(Directory.images));
- res.send({
- accessPaths: {
- agnostic: DashUploadUtils.getAccessPaths(Directory.images, resolvedName),
- },
- } as Upload.FileInformation);
- resolve();
- });
+ req.addListener('data', args => {
+ const payload = String.fromCharCode(...args); // .apply(String, args);
+ const { videoId } = JSON.parse(payload);
+ _success(res, { progress: DashUploadUtils.QueryYoutubeProgress(videoId) });
});
},
});
@@ -187,7 +123,8 @@ export default class UploadManager extends ApiManager {
const { sources } = req.body;
if (Array.isArray(sources)) {
const results = await Promise.all(sources.map(source => DashUploadUtils.UploadImage(source)));
- return res.send(results);
+ res.send(results);
+ return;
}
res.send();
},
@@ -204,20 +141,22 @@ export default class UploadManager extends ApiManager {
const getId = (id: string): string => {
if (!remap || id.endsWith('Proto')) return id;
if (id in ids) return ids[id];
- return (ids[id] = uuid.v4());
+ ids[id] = uuid.v4();
+ return ids[id];
};
- const mapFn = (doc: any) => {
+ const mapFn = (docIn: any) => {
+ const doc = docIn;
if (doc.id) {
doc.id = getId(doc.id);
}
+ // eslint-disable-next-line no-restricted-syntax
for (const key in doc.fields) {
- if (!doc.fields.hasOwnProperty(key)) {
- continue;
- }
+ // eslint-disable-next-line no-continue
+ if (!Object.prototype.hasOwnProperty.call(doc.fields, key)) continue;
+
const field = doc.fields[key];
- if (field === undefined || field === null) {
- continue;
- }
+ // eslint-disable-next-line no-continue
+ if (field === undefined || field === null) continue;
if (field.__type === 'Doc') {
mapFn(field);
@@ -230,78 +169,80 @@ export default class UploadManager extends ApiManager {
} else if (field.__type === 'list') {
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) => {
- return `${p1}${getId(p2)}"`;
- });
+ 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)}"`);
} else if (field.__type === 'RichTextField') {
const re = /("href"\s*:\s*")(.*?)"/g;
- field.Data = field.Data.replace(re, (match: any, p1: string, p2: string) => {
- return `${p1}${getId(p2)}"`;
- });
+ field.Data = field.Data.replace(re, (match: any, p1: string, p2: string) => `${p1}${getId(p2)}"`);
}
}
};
return new Promise<void>(resolve => {
form.parse(req, async (_err, fields, files) => {
- remap = Object.keys(fields).some(key => key === 'remap' && !fields.remap?.includes('false')); //.remap !== 'false'; // bcz: looking to see if the field 'remap' is set to 'false'
+ remap = Object.keys(fields).some(key => key === 'remap' && !fields.remap?.includes('false')); // .remap !== 'false'; // bcz: looking to see if the field 'remap' is set to 'false'
let id: string = '';
let docids: string[] = [];
let linkids: string[] = [];
try {
- for (const name in files) {
- const f = files[name];
- if (!f) continue;
- const path_2 = f[0]; // what about the rest of the array? are we guaranteed only one value is set?
- const zip = new AdmZip(path_2.filepath);
- zip.getEntries().forEach((entry: any) => {
- let entryName = entry.entryName.replace(/%%%/g, '/');
- if (!entryName.startsWith('files/')) {
- return;
- }
- const extension = path.extname(entryName);
- const pathname = publicDirectory + '/' + entry.entryName;
- const targetname = publicDirectory + '/' + entryName;
- try {
- zip.extractEntryTo(entry.entryName, publicDirectory, true, false);
- createReadStream(pathname).pipe(createWriteStream(targetname));
- Jimp.read(pathname).then(img => {
- DashUploadUtils.imageResampleSizes(extension).forEach(({ width, suffix }) => {
- const outputPath = InjectSize(targetname, suffix);
- if (!width) createReadStream(pathname).pipe(createWriteStream(outputPath));
- else img = img.resize(width, Jimp.AUTO).write(outputPath);
+ // eslint-disable-next-line no-restricted-syntax
+ for (const name in Object.keys(files)) {
+ if (Object.prototype.hasOwnProperty.call(files, name)) {
+ const f = files[name];
+ // eslint-disable-next-line no-continue
+ 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) => {
+ const entryName = entry.entryName.replace(/%%%/g, '/');
+ if (!entryName.startsWith('files/')) {
+ return;
+ }
+ const extension = path.extname(entryName);
+ const pathname = publicDirectory + '/' + entry.entryName;
+ const targetname = publicDirectory + '/' + entryName;
+ try {
+ zip.extractEntryTo(entry.entryName, publicDirectory, true, false);
+ createReadStream(pathname).pipe(createWriteStream(targetname));
+ Jimp.read(pathname).then(imgIn => {
+ let img = imgIn;
+ DashUploadUtils.imageResampleSizes(extension).forEach(({ width, suffix }) => {
+ const outputPath = InjectSize(targetname, suffix);
+ if (!width) createReadStream(pathname).pipe(createWriteStream(outputPath));
+ else img = img.resize(width, Jimp.AUTO).write(outputPath);
+ });
+ unlink(pathname, () => {});
});
- unlink(pathname, () => {});
- });
- } catch (e) {
- console.log(e);
- }
- });
- const json = zip.getEntry('docs.json');
- if (json) {
- try {
- const data = JSON.parse(json.getData().toString('utf8'), retrocycle());
- const { docs, links } = data;
- id = getId(data.id);
- const rdocs = Object.keys(docs).map(key => docs[key]);
- const ldocs = Object.keys(links).map(key => links[key]);
- [...rdocs, ...ldocs].forEach(mapFn);
- docids = rdocs.map(doc => doc.id);
- linkids = ldocs.map(link => link.id);
- await Promise.all(
- [...rdocs, ...ldocs].map(
- doc =>
- new Promise<void>(res => {
- // overwrite mongo doc with json doc contents
- Database.Instance.replace(doc.id, doc, (err, r) => res(err && console.log(err)), true);
- })
- )
- );
- } catch (e) {
- console.log(e);
+ } catch (e) {
+ console.log(e);
+ }
+ });
+ const json = zip.getEntry('docs.json');
+ if (json) {
+ try {
+ const data = JSON.parse(json.getData().toString('utf8'), retrocycle());
+ const { docs, links } = data;
+ id = getId(data.id);
+ const rdocs = Object.keys(docs).map(key => docs[key]);
+ const ldocs = Object.keys(links).map(key => links[key]);
+ [...rdocs, ...ldocs].forEach(mapFn);
+ docids = rdocs.map(doc => doc.id);
+ linkids = ldocs.map(link => link.id);
+ // eslint-disable-next-line no-await-in-loop
+ await Promise.all(
+ [...rdocs, ...ldocs].map(
+ doc =>
+ new Promise<void>(dbRes => {
+ // overwrite mongo doc with json doc contents
+ Database.Instance.replace(doc.id, doc, err => dbRes(err && console.log(err)), true);
+ })
+ )
+ );
+ } catch (e) {
+ console.log(e);
+ }
}
+ unlink(path2.filepath, () => {});
}
- unlink(path_2.filepath, () => {});
}
SolrManager.update();
res.send(JSON.stringify({ id, docids, linkids } || 'error'));
@@ -320,9 +261,8 @@ export default class UploadManager extends ApiManager {
secureHandler: async ({ req, res }) => {
const { source } = req.body;
if (typeof source === 'string') {
- return res.send(await DashUploadUtils.InspectImage(source));
- }
- res.send({});
+ res.send(await DashUploadUtils.InspectImage(source));
+ } else res.send({});
},
});
@@ -330,7 +270,7 @@ export default class UploadManager extends ApiManager {
method: Method.POST,
subscription: '/uploadURI',
secureHandler: ({ req, res }) => {
- const uri: any = req.body.uri;
+ const { uri } = req.body;
const filename = req.body.name;
const origSuffix = req.body.nosuffix ? SizeSuffix.None : SizeSuffix.Original;
const deleteFiles = req.body.replaceRootFilename;
@@ -339,23 +279,24 @@ export default class UploadManager extends ApiManager {
return;
}
if (deleteFiles) {
- const path = serverPathToFile(Directory.images, '');
+ const serverPath = serverPathToFile(Directory.images, '');
const regex = new RegExp(`${deleteFiles}.*`);
- fs.readdirSync(path)
+ fs.readdirSync(serverPath)
.filter((f: any) => regex.test(f))
- .map((f: any) => fs.unlinkSync(path + f));
+ .map((f: any) => fs.unlinkSync(serverPath + f));
}
- return imageDataUri.outputFile(uri, serverPathToFile(Directory.images, InjectSize(filename, origSuffix))).then((savedName: string) => {
+ imageDataUri.outputFile(uri, serverPathToFile(Directory.images, InjectSize(filename, origSuffix))).then((savedName: string) => {
const ext = path.extname(savedName).toLowerCase();
if (AcceptableMedia.imageFormats.includes(ext)) {
- Jimp.read(savedName).then(img =>
+ Jimp.read(savedName).then(imgIn => {
+ let img = imgIn;
(!origSuffix ? [{ width: 400, suffix: SizeSuffix.Medium }] : Object.values(DashUploadUtils.Sizes)) //
.forEach(({ width, suffix }) => {
const outputPath = serverPathToFile(Directory.images, InjectSize(filename, suffix) + ext);
if (!width) createReadStream(savedName).pipe(createWriteStream(outputPath));
else img = img.resize(width, Jimp.AUTO).write(outputPath);
- })
- );
+ });
+ });
}
res.send(clientPathToFile(Directory.images, filename + ext));
});
@@ -363,35 +304,3 @@ export default class UploadManager extends ApiManager {
});
}
}
-function delay(ms: number) {
- return new Promise(resolve => setTimeout(resolve, ms));
-}
-/**
- * On success, returns a buffer containing the bytes of a screenshot
- * of the video (optionally, at a timecode) specified by @param targetUrl.
- *
- * On failure, returns undefined.
- */
-async function captureYoutubeScreenshot(targetUrl: string) {
- // const browser = await launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
- // const page = await browser.newPage();
- // // await page.setViewport({ width: 1920, height: 1080 });
-
- // // await page.goto(targetUrl, { waitUntil: 'domcontentloaded' as any });
-
- // const videoPlayer = await page.$('.html5-video-player');
- // videoPlayer && await page.focus("video");
- // await delay(7000);
- // const ad = await page.$('.ytp-ad-skip-button-text');
- // await ad?.click();
- // await videoPlayer?.click();
- // await delay(1000);
- // // hide youtube player controls.
- // await page.evaluate(() => (document.querySelector('.ytp-chrome-bottom') as HTMLElement).style.display = 'none');
-
- // const buffer = await videoPlayer?.screenshot({ encoding: "binary" });
- // await browser.close();
-
- // return buffer;
- return null;
-}
diff --git a/src/server/ApiManagers/UserManager.ts b/src/server/ApiManagers/UserManager.ts
index 0431b9bcf..b587340e2 100644
--- a/src/server/ApiManagers/UserManager.ts
+++ b/src/server/ApiManagers/UserManager.ts
@@ -1,16 +1,14 @@
-import ApiManager, { Registration } from './ApiManager';
-import { Method } from '../RouteManager';
-import { Database } from '../database';
-import { msToTime } from '../ActionUtilities';
import * as bcrypt from 'bcrypt-nodejs';
+import { check, validationResult } from 'express-validator';
+import { Utils } from '../../Utils';
import { Opt } from '../../fields/Doc';
-import { WebSocket } from '../websocket';
-import { resolvedPorts } from '../server_Initialization';
import { DashVersion } from '../../fields/DocSymbols';
-import { Utils } from '../../Utils';
-import { check, validationResult } from 'express-validator';
+import { msToTime } from '../ActionUtilities';
+import { Method } from '../RouteManager';
+import { resolvedPorts, socketMap, timeMap } from '../SocketData';
+import { Database } from '../database';
+import ApiManager, { Registration } from './ApiManager';
-export const timeMap: { [id: string]: number } = {};
interface ActivityUnit {
user: string;
duration: number;
@@ -32,9 +30,10 @@ export default class UserManager extends ApiManager {
method: Method.POST,
subscription: '/setCacheDocumentIds',
secureHandler: async ({ user, req, res }) => {
+ const userModel = user;
const result: any = {};
- user.cacheDocumentIds = req.body.cacheDocumentIds;
- user.save().then(undefined, err => {
+ userModel.cacheDocumentIds = req.body.cacheDocumentIds;
+ userModel.save().then(undefined, (err: any) => {
if (err) {
result.error = [{ msg: 'Error while caching documents' }];
}
@@ -90,17 +89,19 @@ export default class UserManager extends ApiManager {
method: Method.POST,
subscription: '/internalResetPassword',
secureHandler: async ({ user, req, res }) => {
+ const userModel = user;
const result: any = {};
- const { curr_pass, new_pass, new_confirm } = req.body;
+ // eslint-disable-next-line camelcase
+ const { curr_pass, new_pass } = req.body;
// perhaps should assert whether curr password is entered correctly
const validated = await new Promise<Opt<boolean>>(resolve => {
- bcrypt.compare(curr_pass, user.password, (err, passwords_match) => {
- if (err || !passwords_match) {
+ bcrypt.compare(curr_pass, userModel.password, (err, passwordsMatch) => {
+ if (err || !passwordsMatch) {
result.error = [{ msg: 'Incorrect current password' }];
res.send(result);
resolve(undefined);
} else {
- resolve(passwords_match);
+ resolve(passwordsMatch);
}
});
});
@@ -111,10 +112,11 @@ export default class UserManager extends ApiManager {
check('new_pass', 'Password must be at least 4 characters long')
.run(req)
- .then(chcekcres => console.log(chcekcres)); //.len({ min: 4 });
+ .then(chcekcres => console.log(chcekcres)); // .len({ min: 4 });
check('new_confirm', 'Passwords do not match')
.run(req)
- .then(theres => console.log(theres)); //.equals(new_pass);
+ .then(theres => console.log(theres)); // .equals(new_pass);
+ // eslint-disable-next-line camelcase
if (curr_pass === new_pass) {
result.error = [{ msg: 'Current and new password are the same' }];
}
@@ -125,12 +127,13 @@ export default class UserManager extends ApiManager {
// will only change password if there are no errors.
if (!result.error) {
- user.password = new_pass;
- user.passwordResetToken = undefined;
- user.passwordResetExpires = undefined;
+ // eslint-disable-next-line camelcase
+ userModel.password = new_pass;
+ userModel.passwordResetToken = undefined;
+ userModel.passwordResetExpires = undefined;
}
- user.save().then(undefined, err => {
+ userModel.save().then(undefined, err => {
if (err) {
result.error = [{ msg: 'Error while saving new password' }];
}
@@ -149,13 +152,16 @@ export default class UserManager extends ApiManager {
const activeTimes: ActivityUnit[] = [];
const inactiveTimes: ActivityUnit[] = [];
+ // eslint-disable-next-line no-restricted-syntax
for (const user in timeMap) {
- const time = timeMap[user];
- const socketPair = Array.from(WebSocket.socketMap).find(pair => pair[1] === user);
- if (socketPair && !socketPair[0].disconnected) {
- const duration = now - time;
- const target = duration / 1000 < 60 * 5 ? activeTimes : inactiveTimes;
- target.push({ user, duration });
+ if (Object.prototype.hasOwnProperty.call(timeMap, user)) {
+ const time = timeMap[user];
+ const socketPair = Array.from(socketMap).find(pair => pair[1] === user);
+ if (socketPair && !socketPair[0].disconnected) {
+ const duration = now - time;
+ const target = duration / 1000 < 60 * 5 ? activeTimes : inactiveTimes;
+ target.push({ user, duration });
+ }
}
}
diff --git a/src/server/ApiManagers/UtilManager.ts b/src/server/ApiManagers/UtilManager.ts
index e657866ce..8ad421a30 100644
--- a/src/server/ApiManagers/UtilManager.ts
+++ b/src/server/ApiManagers/UtilManager.ts
@@ -1,6 +1,7 @@
-import ApiManager, { Registration } from "./ApiManager";
-import { Method } from "../RouteManager";
import { exec } from 'child_process';
+import ApiManager, { Registration } from './ApiManager';
+import { Method } from '../RouteManager';
+
// import { IBM_Recommender } from "../../client/apis/IBM_Recommender";
// import { Recommender } from "../Recommender";
@@ -8,9 +9,7 @@ import { exec } from 'child_process';
// recommender.testModel();
export default class UtilManager extends ApiManager {
-
protected initialize(register: Registration): void {
-
// register({
// method: Method.POST,
// subscription: "/IBMAnalysis",
@@ -33,26 +32,25 @@ export default class UtilManager extends ApiManager {
register({
method: Method.GET,
- subscription: "/pull",
- secureHandler: async ({ res }) => {
- return new Promise<void>(resolve => {
+ subscription: '/pull',
+ secureHandler: async ({ res }) =>
+ new Promise<void>(resolve => {
exec('"C:\\Program Files\\Git\\git-bash.exe" -c "git pull"', err => {
if (err) {
res.send(err.message);
return;
}
- res.redirect("/");
+ res.redirect('/');
resolve();
});
- });
- }
+ }),
});
register({
method: Method.GET,
- subscription: "/version",
- secureHandler: ({ res }) => {
- return new Promise<void>(resolve => {
+ subscription: '/version',
+ secureHandler: ({ res }) =>
+ new Promise<void>(resolve => {
exec('"C:\\Program Files\\Git\\bin\\git.exe" rev-parse HEAD', (err, stdout) => {
if (err) {
res.send(err.message);
@@ -61,10 +59,7 @@ export default class UtilManager extends ApiManager {
res.send(stdout);
});
resolve();
- });
- }
+ }),
});
-
}
-
-} \ No newline at end of file
+}
diff --git a/src/server/Client.ts b/src/server/Client.ts
index e6f953712..f67999c5b 100644
--- a/src/server/Client.ts
+++ b/src/server/Client.ts
@@ -1,4 +1,4 @@
-import { computed } from "mobx";
+import { computed } from 'mobx';
export class Client {
private _guid: string;
@@ -7,5 +7,7 @@ export class Client {
this._guid = guid;
}
- @computed public get GUID(): string { return this._guid; }
-} \ No newline at end of file
+ @computed public get GUID(): string {
+ return this._guid;
+ }
+}
diff --git a/src/server/DashSession/DashSessionAgent.ts b/src/server/DashSession/DashSessionAgent.ts
index 1ef7a131d..891316b80 100644
--- a/src/server/DashSession/DashSessionAgent.ts
+++ b/src/server/DashSession/DashSessionAgent.ts
@@ -1,18 +1,19 @@
-import { Email, pathFromRoot } from '../ActionUtilities';
-import { red, yellow, green, cyan } from 'colors';
-import { get } from 'request-promise';
-import { Utils } from '../../Utils';
-import { WebSocket } from '../websocket';
-import { MessageStore } from '../Message';
-import { launchServer, onWindows } from '..';
-import { readdirSync, statSync, createWriteStream, readFileSync, unlinkSync } from 'fs';
import * as Archiver from 'archiver';
+import { cyan, green, red, yellow } from 'colors';
+import { createWriteStream, readFileSync, readdirSync, statSync, unlinkSync } from 'fs';
import { resolve } from 'path';
+import { get } from 'request-promise';
import { rimraf } from 'rimraf';
+import { launchServer, onWindows } from '..';
+import { Utils } from '../../Utils';
+import { ServerUtils } from '../../ServerUtils';
+import { Email, pathFromRoot } from '../ActionUtilities';
+import { MessageStore } from '../Message';
+import { WebSocket } from '../websocket';
import { AppliedSessionAgent, ExitHandler } from './Session/agents/applied_session_agent';
-import { ServerWorker } from './Session/agents/server_worker';
import { Monitor } from './Session/agents/monitor';
-import { MessageHandler, ErrorLike } from './Session/agents/promisified_ipc_manager';
+import { ErrorLike, MessageHandler } from './Session/agents/promisified_ipc_manager';
+import { ServerWorker } from './Session/agents/server_worker';
/**
* If we're the monitor (master) thread, we should launch the monitor logic for the session.
@@ -22,6 +23,7 @@ import { MessageHandler, ErrorLike } from './Session/agents/promisified_ipc_mana
export class DashSessionAgent extends AppliedSessionAgent {
private readonly signature = '-Dash Server Session Manager';
private readonly releaseDesktop = pathFromRoot('../../Desktop');
+ public static notificationRecipient = 'browndashptc@gmail.com';
/**
* The core method invoked when the single master thread is initialized.
@@ -33,7 +35,7 @@ export class DashSessionAgent extends AppliedSessionAgent {
monitor.addReplCommand('pull', [], () => monitor.exec('git pull'));
monitor.addReplCommand('solr', [/start|stop|index/], this.executeSolrCommand);
monitor.addReplCommand('backup', [], this.backup);
- monitor.addReplCommand('debug', [/\S+\@\S+/], async ([to]) => this.dispatchZippedDebugBackup(to));
+ monitor.addReplCommand('debug', [/\S+@\S+/], async ([to]) => this.dispatchZippedDebugBackup(to));
monitor.on('backup', this.backup);
monitor.on('debug', async ({ to }) => this.dispatchZippedDebugBackup(to));
monitor.on('delete', WebSocket.doDelete);
@@ -149,7 +151,7 @@ export class DashSessionAgent extends AppliedSessionAgent {
const { _socket } = WebSocket;
if (_socket) {
const message = typeof reason === 'boolean' ? (reason ? 'exit' : 'temporary') : 'crash';
- Utils.Emit(_socket, MessageStore.ConnectionTerminated, message);
+ ServerUtils.Emit(_socket, MessageStore.ConnectionTerminated, message);
}
};
@@ -217,7 +219,3 @@ export class DashSessionAgent extends AppliedSessionAgent {
}
}
}
-
-export namespace DashSessionAgent {
- export const notificationRecipient = 'browndashptc@gmail.com';
-}
diff --git a/src/server/DashSession/Session/agents/applied_session_agent.ts b/src/server/DashSession/Session/agents/applied_session_agent.ts
index 2037e93e5..c42ba95cc 100644
--- a/src/server/DashSession/Session/agents/applied_session_agent.ts
+++ b/src/server/DashSession/Session/agents/applied_session_agent.ts
@@ -1,13 +1,13 @@
-import * as _cluster from "cluster";
-import { Monitor } from "./monitor";
-import { ServerWorker } from "./server_worker";
+import * as _cluster from 'cluster';
+import { Monitor } from './monitor';
+import { ServerWorker } from './server_worker';
+
const cluster = _cluster as any;
const isMaster = cluster.isPrimary;
export type ExitHandler = (reason: Error | boolean) => void | Promise<void>;
export abstract class AppliedSessionAgent {
-
// the following two methods allow the developer to create a custom
// session and use the built in customization options for each thread
protected abstract initializeMonitor(monitor: Monitor): Promise<string>;
@@ -18,15 +18,15 @@ export abstract class AppliedSessionAgent {
public killSession = (reason: string, graceful = true, errorCode = 0) => {
const target = cluster.default.isPrimary ? this.sessionMonitor : this.serverWorker;
target.killSession(reason, graceful, errorCode);
- }
+ };
private sessionMonitorRef: Monitor | undefined;
public get sessionMonitor(): Monitor {
if (!cluster.default.isPrimary) {
- this.serverWorker.emit("kill", {
+ this.serverWorker.emit('kill', {
graceful: false,
- reason: "Cannot access the session monitor directly from the server worker thread.",
- errorCode: 1
+ reason: 'Cannot access the session monitor directly from the server worker thread.',
+ errorCode: 1,
});
throw new Error();
}
@@ -36,7 +36,7 @@ export abstract class AppliedSessionAgent {
private serverWorkerRef: ServerWorker | undefined;
public get serverWorker(): ServerWorker {
if (isMaster) {
- throw new Error("Cannot access the server worker directly from the session monitor thread");
+ throw new Error('Cannot access the server worker directly from the session monitor thread');
}
return this.serverWorkerRef!;
}
@@ -52,8 +52,7 @@ export abstract class AppliedSessionAgent {
this.serverWorkerRef = await this.initializeServerWorker();
}
} else {
- throw new Error("Cannot launch a session thread more than once per process.");
+ throw new Error('Cannot launch a session thread more than once per process.');
}
}
-
-} \ No newline at end of file
+}
diff --git a/src/server/DashSession/Session/agents/monitor.ts b/src/server/DashSession/Session/agents/monitor.ts
index a6fde4356..6cdad46c2 100644
--- a/src/server/DashSession/Session/agents/monitor.ts
+++ b/src/server/DashSession/Session/agents/monitor.ts
@@ -1,21 +1,19 @@
-import { ExitHandler } from './applied_session_agent';
-import { Configuration, configurationSchema, defaultConfig, Identifiers, colorMapping } from '../utilities/session_config';
-import Repl, { ReplAction } from '../utilities/repl';
+import { ExecOptions, exec } from 'child_process';
import * as _cluster from 'cluster';
import { Worker } from 'cluster';
-import { manage, MessageHandler, ErrorLike } from './promisified_ipc_manager';
-import { red, cyan, white, yellow, blue } from 'colors';
-import { exec, ExecOptions } from 'child_process';
-import { validate, ValidationError } from 'jsonschema';
-import { Utilities } from '../utilities/utilities';
+import { blue, cyan, red, white, yellow } from 'colors';
import { readFileSync } from 'fs';
+import { ValidationError, validate } from 'jsonschema';
+import Repl, { ReplAction } from '../utilities/repl';
+import { Configuration, Identifiers, colorMapping, configurationSchema, defaultConfig } from '../utilities/session_config';
+import { Utilities } from '../utilities/utilities';
+import { ExitHandler } from './applied_session_agent';
import IPCMessageReceiver from './process_message_router';
+import { ErrorLike, MessageHandler, manage } from './promisified_ipc_manager';
import { ServerWorker } from './server_worker';
+
const cluster = _cluster as any;
-const isWorker = cluster.isWorker;
-const setupMaster = cluster.setupPrimary;
-const on = cluster.on;
-const fork = cluster.fork;
+const { isWorker, setupMaster, on, fork } = cluster;
/**
* Validates and reads the configuration file, accordingly builds a child process factory
@@ -41,9 +39,8 @@ export class Monitor extends IPCMessageReceiver {
} else if (++Monitor.count > 1) {
console.error(red('cannot create more than one monitor.'));
process.exit(1);
- } else {
- return new Monitor();
}
+ return new Monitor();
}
private constructor() {
@@ -128,25 +125,25 @@ export class Monitor extends IPCMessageReceiver {
this.repl.registerCommand(basename, argPatterns, action);
};
- public exec = (command: string, options?: ExecOptions) => {
- return new Promise<void>(resolve => {
+ public exec = (command: string, options?: ExecOptions) =>
+ new Promise<void>(resolve => {
exec(command, { ...options, encoding: 'utf8' }, (error, stdout, stderr) => {
if (error) {
this.execLog(red(`unable to execute ${white(command)}`));
error.message.split('\n').forEach(line => line.length && this.execLog(red(`(error) ${line}`)));
} else {
- let outLines: string[], errorLines: string[];
- if ((outLines = stdout.split('\n').filter(line => line.length)).length) {
+ const outLines = stdout.split('\n').filter(line => line.length);
+ if (outLines.length) {
outLines.forEach(line => line.length && this.execLog(cyan(`(stdout) ${line}`)));
}
- if ((errorLines = stderr.split('\n').filter(line => line.length)).length) {
+ const errorLines = stderr.split('\n').filter(line => line.length);
+ if (errorLines.length) {
errorLines.forEach(line => line.length && this.execLog(yellow(`(stderr) ${line}`)));
}
}
resolve();
});
});
- };
/**
* Generates a blue UTC string associated with the time
@@ -226,12 +223,10 @@ export class Monitor extends IPCMessageReceiver {
const newPollingIntervalSeconds = Math.floor(Number(args[1]));
if (newPollingIntervalSeconds < 0) {
this.mainLog(red('the polling interval must be a non-negative integer'));
- } else {
- if (newPollingIntervalSeconds !== this.config.polling.intervalSeconds) {
- this.config.polling.intervalSeconds = newPollingIntervalSeconds;
- if (args[2] === 'true') {
- Monitor.IPCManager.emit('updatePollingInterval', { newPollingIntervalSeconds });
- }
+ } else if (newPollingIntervalSeconds !== this.config.polling.intervalSeconds) {
+ this.config.polling.intervalSeconds = newPollingIntervalSeconds;
+ if (args[2] === 'true') {
+ Monitor.IPCManager.emit('updatePollingInterval', { newPollingIntervalSeconds });
}
}
});
@@ -297,6 +292,7 @@ export class Monitor extends IPCMessageReceiver {
};
}
+// eslint-disable-next-line no-redeclare
export namespace Monitor {
export enum IntrinsicEvents {
KeyGenerated = 'key_generated',
diff --git a/src/server/DashSession/Session/agents/process_message_router.ts b/src/server/DashSession/Session/agents/process_message_router.ts
index 0745ea455..3e2b7d8d0 100644
--- a/src/server/DashSession/Session/agents/process_message_router.ts
+++ b/src/server/DashSession/Session/agents/process_message_router.ts
@@ -1,7 +1,6 @@
-import { MessageHandler, PromisifiedIPCManager, HandlerMap } from "./promisified_ipc_manager";
+import { MessageHandler, PromisifiedIPCManager, HandlerMap } from './promisified_ipc_manager';
export default abstract class IPCMessageReceiver {
-
protected static IPCManager: PromisifiedIPCManager;
protected handlers: HandlerMap = {};
@@ -18,7 +17,7 @@ export default abstract class IPCMessageReceiver {
} else {
handlers.push(handler);
}
- }
+ };
/**
* Unregister a given listener at this message.
@@ -31,11 +30,10 @@ export default abstract class IPCMessageReceiver {
handlers.splice(index, 1);
}
}
- }
+ };
- /**
+ /**
* Unregister all listeners at this message.
*/
public clearMessageListeners = (...names: string[]) => names.map(name => delete this.handlers[name]);
-
-} \ No newline at end of file
+}
diff --git a/src/server/DashSession/Session/agents/promisified_ipc_manager.ts b/src/server/DashSession/Session/agents/promisified_ipc_manager.ts
index 76e218977..fc870d003 100644
--- a/src/server/DashSession/Session/agents/promisified_ipc_manager.ts
+++ b/src/server/DashSession/Session/agents/promisified_ipc_manager.ts
@@ -1,13 +1,14 @@
-import { Utilities } from '../utilities/utilities';
import { ChildProcess } from 'child_process';
+import { Utilities } from '../utilities/utilities';
/**
- * Convenience constructor
- * @param target the process / worker to which to attach the specialized listeners
+ * Specifies a general message format for this API
*/
-export function manage(target: IPCTarget, handlers?: HandlerMap) {
- return new PromisifiedIPCManager(target, handlers);
-}
+export type Message<T = any> = {
+ name: string;
+ args?: T;
+};
+export type MessageHandler<T = any> = (args: T) => any | Promise<any>;
/**
* Captures the logic to execute upon receiving a message
@@ -22,15 +23,10 @@ export type HandlerMap = { [name: string]: MessageHandler[] };
*/
export type IPCTarget = NodeJS.Process | ChildProcess;
-/**
- * Specifies a general message format for this API
- */
-export type Message<T = any> = {
- name: string;
- args?: T;
-};
-export type MessageHandler<T = any> = (args: T) => any | Promise<any>;
-
+interface Metadata {
+ isResponse: boolean;
+ id: string;
+}
/**
* When a message is emitted, it is embedded with private metadata
* to facilitate the resolution of promises, etc.
@@ -38,10 +34,6 @@ export type MessageHandler<T = any> = (args: T) => any | Promise<any>;
interface InternalMessage extends Message {
metadata: Metadata;
}
-interface Metadata {
- isResponse: boolean;
- id: string;
-}
/**
* Allows for the transmission of the error's key features over IPC.
@@ -95,11 +87,11 @@ export class PromisifiedIPCManager {
}
return new Promise<Response<T>>(resolve => {
const messageId = Utilities.guid();
- type InternalMessageHandler = (message: any /* MessageListener*/) => any | Promise<any>;
- const responseHandler: InternalMessageHandler = ({ metadata: { id, isResponse }, args }) => {
+ type InternalMessageHandler = (message: any /* MessageListener */) => any | Promise<any>;
+ const responseHandler: InternalMessageHandler = ({ metadata: { id, isResponse }, args: hargs }) => {
if (isResponse && id === messageId) {
this.target.removeListener('message', responseHandler);
- resolve(args);
+ resolve(hargs);
}
};
this.target.addListener('message', responseHandler);
@@ -118,8 +110,9 @@ export class PromisifiedIPCManager {
* completion response for each of the pending messages, allowing their
* promises in the caller to resolve.
*/
- public destroy = () => {
- return new Promise<void>(async resolve => {
+ public destroy = () =>
+ // eslint-disable-next-line no-async-promise-executor
+ new Promise<void>(async resolve => {
if (this.callerIsTarget) {
this.destroyHelper();
} else {
@@ -127,7 +120,6 @@ export class PromisifiedIPCManager {
}
resolve();
});
- };
/**
* Dispatches the dummy responses and sets the isDestroyed flag to true.
@@ -168,12 +160,20 @@ export class PromisifiedIPCManager {
error = e;
}
if (!this.isDestroyed && this.target.send) {
- const metadata = { id, isResponse: true };
+ const metadataRes = { id, isResponse: true };
const response: Response = { results, error };
- const message = { name, args: response, metadata };
+ const messageRes = { name, args: response, metadata: metadataRes };
delete this.pendingMessages[id];
- this.target.send(message);
+ this.target.send(messageRes);
}
}
};
}
+
+/**
+ * Convenience constructor
+ * @param target the process / worker to which to attach the specialized listeners
+ */
+export function manage(target: IPCTarget, handlers?: HandlerMap) {
+ return new PromisifiedIPCManager(target, handlers);
+}
diff --git a/src/server/DashSession/Session/agents/server_worker.ts b/src/server/DashSession/Session/agents/server_worker.ts
index d8b3ee80b..85e1b31d6 100644
--- a/src/server/DashSession/Session/agents/server_worker.ts
+++ b/src/server/DashSession/Session/agents/server_worker.ts
@@ -1,10 +1,10 @@
-import cluster from "cluster";
-import { green, red, white, yellow } from "colors";
-import { get } from "request-promise";
-import { ExitHandler } from "./applied_session_agent";
-import { Monitor } from "./monitor";
-import IPCMessageReceiver from "./process_message_router";
-import { ErrorLike, manage } from "./promisified_ipc_manager";
+import cluster from 'cluster';
+import { green, red, white, yellow } from 'colors';
+import { get } from 'request-promise';
+import { ExitHandler } from './applied_session_agent';
+import { Monitor } from './monitor';
+import IPCMessageReceiver from './process_message_router';
+import { ErrorLike, manage } from './promisified_ipc_manager';
/**
* Effectively, each worker repairs the connection to the server by reintroducing a consistent state
@@ -23,18 +23,17 @@ export class ServerWorker extends IPCMessageReceiver {
private isInitialized = false;
public static Create(work: Function) {
if (cluster.isPrimary) {
- console.error(red("cannot create a worker on the monitor process."));
+ console.error(red('cannot create a worker on the monitor process.'));
process.exit(1);
} else if (++ServerWorker.count > 1) {
- ServerWorker.IPCManager.emit("kill", {
- reason: "cannot create more than one worker on a given worker process.",
+ ServerWorker.IPCManager.emit('kill', {
+ reason: 'cannot create more than one worker on a given worker process.',
graceful: false,
- errorCode: 1
+ errorCode: 1,
});
process.exit(1);
- } else {
- return new ServerWorker(work);
}
+ return new ServerWorker(work);
}
/**
@@ -48,7 +47,7 @@ export class ServerWorker extends IPCMessageReceiver {
* server worker (child process). This will also kill
* this process (child process).
*/
- public killSession = (reason: string, graceful = true, errorCode = 0) => this.emit<never>("kill", { reason, graceful, errorCode });
+ public killSession = (reason: string, graceful = true, errorCode = 0) => this.emit<never>('kill', { reason, graceful, errorCode });
/**
* A convenience wrapper to tell the session monitor (parent process)
@@ -60,7 +59,7 @@ export class ServerWorker extends IPCMessageReceiver {
super();
this.configureInternalHandlers();
ServerWorker.IPCManager = manage(process, this.handlers);
- this.lifecycleNotification(green(`initializing process... ${white(`[${process.execPath} ${process.execArgv.join(" ")}]`)}`));
+ this.lifecycleNotification(green(`initializing process... ${white(`[${process.execPath} ${process.execArgv.join(' ')}]`)}`));
const { pollingRoute, serverPort, pollingIntervalSeconds, pollingFailureTolerance } = process.env;
this.serverPort = Number(serverPort);
@@ -78,8 +77,10 @@ export class ServerWorker extends IPCMessageReceiver {
*/
protected configureInternalHandlers = () => {
// updates the local values of variables to the those sent from master
- this.on("updatePollingInterval", ({ newPollingIntervalSeconds }) => this.pollingIntervalSeconds = newPollingIntervalSeconds);
- this.on("manualExit", async ({ isSessionEnd }) => {
+ this.on('updatePollingInterval', ({ newPollingIntervalSeconds }) => {
+ this.pollingIntervalSeconds = newPollingIntervalSeconds;
+ });
+ this.on('manualExit', async ({ isSessionEnd }) => {
await ServerWorker.IPCManager.destroy();
await this.executeExitHandlers(isSessionEnd);
process.exit(0);
@@ -91,7 +92,7 @@ export class ServerWorker extends IPCMessageReceiver {
const appropriateError = reason instanceof Error ? reason : new Error(`unhandled rejection: ${reason}`);
this.proactiveUnplannedExit(appropriateError);
});
- }
+ };
/**
* Execute the list of functions registered to be called
@@ -102,7 +103,7 @@ export class ServerWorker extends IPCMessageReceiver {
/**
* Notify master thread (which will log update in the console) of initialization via IPC.
*/
- public lifecycleNotification = (event: string) => this.emit("lifecycle", { event });
+ public lifecycleNotification = (event: string) => this.emit('lifecycle', { event });
/**
* Called whenever the process has a reason to terminate, either through an uncaught exception
@@ -120,11 +121,11 @@ export class ServerWorker extends IPCMessageReceiver {
this.lifecycleNotification(red(error.message));
await ServerWorker.IPCManager.destroy();
process.exit(1);
- }
+ };
/**
* This monitors the health of the server by submitting a get request to whatever port / route specified
- * by the configuration every n seconds, where n is also given by the configuration.
+ * by the configuration every n seconds, where n is also given by the configuration.
*/
private pollServer = async (): Promise<void> => {
await new Promise<void>(resolve => {
@@ -156,6 +157,5 @@ export class ServerWorker extends IPCMessageReceiver {
});
// controlled, asynchronous infinite recursion achieves a persistent poll that does not submit a new request until the previous has completed
this.pollServer();
- }
-
+ };
}
diff --git a/src/server/DashSession/Session/utilities/repl.ts b/src/server/DashSession/Session/utilities/repl.ts
index 643141286..5d9f15e4c 100644
--- a/src/server/DashSession/Session/utilities/repl.ts
+++ b/src/server/DashSession/Session/utilities/repl.ts
@@ -1,5 +1,5 @@
-import { createInterface, Interface } from "readline";
-import { red, green, white } from "colors";
+import { createInterface, Interface } from 'readline';
+import { red, green, white } from 'colors';
export interface Configuration {
identifier: () => string | string;
@@ -32,76 +32,82 @@ export default class Repl {
this.interface = createInterface(process.stdin, process.stdout).on('line', this.considerInput);
}
- private resolvedIdentifier = () => typeof this.identifier === "string" ? this.identifier : this.identifier();
+ private resolvedIdentifier = () => (typeof this.identifier === 'string' ? this.identifier : this.identifier());
private usage = (command: string, validCommand: boolean) => {
if (validCommand) {
const formatted = white(command);
- const patterns = green(this.commandMap.get(command)!.map(({ argPatterns }) => `${formatted} ${argPatterns.join(" ")}`).join('\n'));
+ const patterns = green(
+ this.commandMap
+ .get(command)!
+ .map(({ argPatterns }) => `${formatted} ${argPatterns.join(' ')}`)
+ .join('\n')
+ );
return `${this.resolvedIdentifier()}\nthe given arguments do not match any registered patterns for ${formatted}\nthe list of valid argument patterns is given by:\n${patterns}`;
- } else {
- const resolved = this.keys;
- if (resolved) {
- return resolved;
- }
- const members: string[] = [];
- const keys = this.commandMap.keys();
- let next: IteratorResult<string>;
- while (!(next = keys.next()).done) {
- members.push(next.value);
- }
- return `${this.resolvedIdentifier()} commands: { ${members.sort().join(", ")} }`;
}
- }
+ const resolved = this.keys;
+ if (resolved) {
+ return resolved;
+ }
+ const members: string[] = [];
+ const keys = this.commandMap.keys();
+ let next: IteratorResult<string>;
+ // eslint-disable-next-line no-cond-assign
+ while (!(next = keys.next()).done) {
+ members.push(next.value);
+ }
+ return `${this.resolvedIdentifier()} commands: { ${members.sort().join(', ')} }`;
+ };
private success = (command: string) => `${this.resolvedIdentifier()} completed local execution of ${white(command)}`;
public registerCommand = (basename: string, argPatterns: (RegExp | string)[], action: ReplAction) => {
const existing = this.commandMap.get(basename);
- const converted = argPatterns.map(input => input instanceof RegExp ? input : new RegExp(input));
+ const converted = argPatterns.map(input => (input instanceof RegExp ? input : new RegExp(input)));
const registration = { argPatterns: converted, action };
if (existing) {
existing.push(registration);
} else {
this.commandMap.set(basename, [registration]);
}
- }
+ };
private invalid = (command: string, validCommand: boolean) => {
- console.log(red(typeof this.onInvalid === "string" ? this.onInvalid : this.onInvalid(command, validCommand)));
+ console.log(red(typeof this.onInvalid === 'string' ? this.onInvalid : this.onInvalid(command, validCommand)));
this.busy = false;
- }
+ };
private valid = (command: string) => {
- console.log(green(typeof this.onValid === "string" ? this.onValid : this.onValid(command)));
+ console.log(green(typeof this.onValid === 'string' ? this.onValid : this.onValid(command)));
this.busy = false;
- }
+ };
- private considerInput = async (line: string) => {
+ private considerInput = async (lineIn: string) => {
if (this.busy) {
- console.log(red("Busy"));
+ console.log(red('Busy'));
return;
}
this.busy = true;
- line = line.trim();
+ let line = lineIn.trim();
if (this.isCaseSensitive) {
line = line.toLowerCase();
}
const [command, ...args] = line.split(/\s+/g);
if (!command) {
- return this.invalid(command, false);
+ this.invalid(command, false);
+ return;
}
const registered = this.commandMap.get(command);
if (registered) {
const { length } = args;
const candidates = registered.filter(({ argPatterns: { length: count } }) => count === length);
- for (const { argPatterns, action } of candidates) {
+ candidates.forEach(({ argPatterns, action }: { argPatterns: any; action: any }) => {
const parsed: string[] = [];
let matched = true;
if (length) {
for (let i = 0; i < length; i++) {
- let matches: RegExpExecArray | null;
- if ((matches = argPatterns[i].exec(args[i])) === null) {
+ const matches = argPatterns[i].exec(args[i]);
+ if (matches === null) {
matched = false;
break;
}
@@ -110,19 +116,17 @@ export default class Repl {
}
if (!length || matched) {
const result = action(parsed);
- const resolve = () => this.valid(`${command} ${parsed.join(" ")}`);
+ const resolve = () => this.valid(`${command} ${parsed.join(' ')}`);
if (result instanceof Promise) {
result.then(resolve);
} else {
resolve();
}
- return;
}
- }
+ });
this.invalid(command, true);
} else {
this.invalid(command, false);
}
- }
-
-} \ No newline at end of file
+ };
+}
diff --git a/src/server/DashSession/Session/utilities/session_config.ts b/src/server/DashSession/Session/utilities/session_config.ts
index 266759929..b42c1a3c7 100644
--- a/src/server/DashSession/Session/utilities/session_config.ts
+++ b/src/server/DashSession/Session/utilities/session_config.ts
@@ -1,85 +1,85 @@
-import { Schema } from "jsonschema";
-import { yellow, red, cyan, green, blue, magenta, Color, grey, gray, white, black } from "colors";
+import { Schema } from 'jsonschema';
+import { yellow, red, cyan, green, blue, magenta, Color, grey, gray, white, black } from 'colors';
const colorPattern = /black|red|green|yellow|blue|magenta|cyan|white|gray|grey/;
const identifierProperties: Schema = {
- type: "object",
+ type: 'object',
properties: {
text: {
- type: "string",
- minLength: 1
+ type: 'string',
+ minLength: 1,
},
color: {
- type: "string",
- pattern: colorPattern
- }
- }
+ type: 'string',
+ pattern: colorPattern,
+ },
+ },
};
const portProperties: Schema = {
- type: "number",
+ type: 'number',
minimum: 443,
- maximum: 65535
+ maximum: 65535,
};
export const configurationSchema: Schema = {
- id: "/configuration",
- type: "object",
+ id: '/configuration',
+ type: 'object',
properties: {
- showServerOutput: { type: "boolean" },
+ showServerOutput: { type: 'boolean' },
ports: {
- type: "object",
+ type: 'object',
properties: {
server: portProperties,
- socket: portProperties
+ socket: portProperties,
},
- required: ["server"],
- additionalProperties: true
+ required: ['server'],
+ additionalProperties: true,
},
identifiers: {
- type: "object",
+ type: 'object',
properties: {
master: identifierProperties,
worker: identifierProperties,
- exec: identifierProperties
- }
+ exec: identifierProperties,
+ },
},
polling: {
- type: "object",
+ type: 'object',
additionalProperties: false,
properties: {
intervalSeconds: {
- type: "number",
+ type: 'number',
minimum: 1,
- maximum: 86400
+ maximum: 86400,
},
route: {
- type: "string",
- pattern: /\/[a-zA-Z]*/g
+ type: 'string',
+ pattern: /\/[a-zA-Z]*/g,
},
failureTolerance: {
- type: "number",
+ type: 'number',
minimum: 0,
- }
- }
+ },
+ },
},
- }
+ },
};
-type ColorLabel = "yellow" | "red" | "cyan" | "green" | "blue" | "magenta" | "grey" | "gray" | "white" | "black";
+type ColorLabel = 'yellow' | 'red' | 'cyan' | 'green' | 'blue' | 'magenta' | 'grey' | 'gray' | 'white' | 'black';
export const colorMapping: Map<ColorLabel, Color> = new Map([
- ["yellow", yellow],
- ["red", red],
- ["cyan", cyan],
- ["green", green],
- ["blue", blue],
- ["magenta", magenta],
- ["grey", grey],
- ["gray", gray],
- ["white", white],
- ["black", black]
+ ['yellow', yellow],
+ ['red', red],
+ ['cyan', cyan],
+ ['green', green],
+ ['blue', blue],
+ ['magenta', magenta],
+ ['grey', grey],
+ ['gray', gray],
+ ['white', white],
+ ['black', black],
]);
interface Identifier {
@@ -108,22 +108,22 @@ export const defaultConfig: Configuration = {
showServerOutput: false,
identifiers: {
master: {
- text: "__monitor__",
- color: "yellow"
+ text: '__monitor__',
+ color: 'yellow',
},
worker: {
- text: "__server__",
- color: "magenta"
+ text: '__server__',
+ color: 'magenta',
},
exec: {
- text: "__exec__",
- color: "green"
- }
+ text: '__exec__',
+ color: 'green',
+ },
},
ports: { server: 1050 },
polling: {
- route: "/",
+ route: '/',
intervalSeconds: 30,
- failureTolerance: 0
- }
-}; \ No newline at end of file
+ failureTolerance: 0,
+ },
+};
diff --git a/src/server/DashSession/Session/utilities/utilities.ts b/src/server/DashSession/Session/utilities/utilities.ts
index eb8de9d7e..a2ba29c67 100644
--- a/src/server/DashSession/Session/utilities/utilities.ts
+++ b/src/server/DashSession/Session/utilities/utilities.ts
@@ -1,31 +1,16 @@
-import { v4 } from "uuid";
+import { v4 } from 'uuid';
export namespace Utilities {
-
export function guid() {
return v4();
}
- /**
- * At any arbitrary layer of nesting within the configuration objects, any single value that
- * is not specified by the configuration is given the default counterpart. If, within an object,
- * one peer is given by configuration and two are not, the one is preserved while the two are given
- * the default value.
- * @returns the composition of all of the assigned objects, much like Object.assign(), but with more
- * granularity in the overwriting of nested objects
- */
- export function preciseAssign(target: any, ...sources: any[]): any {
- for (const source of sources) {
- preciseAssignHelper(target, source);
- }
- return target;
- }
-
export function preciseAssignHelper(target: any, source: any) {
- Array.from(new Set([...Object.keys(target), ...Object.keys(source)])).map(property => {
- let targetValue: any, sourceValue: any;
- if (sourceValue = source[property]) {
- if (typeof sourceValue === "object" && typeof (targetValue = target[property]) === "object") {
+ Array.from(new Set([...Object.keys(target), ...Object.keys(source)])).forEach(property => {
+ const targetValue = target[property];
+ const sourceValue = source[property];
+ if (sourceValue) {
+ if (typeof sourceValue === 'object' && typeof targetValue === 'object') {
preciseAssignHelper(targetValue, sourceValue);
} else {
target[property] = sourceValue;
@@ -34,4 +19,18 @@ export namespace Utilities {
});
}
-} \ No newline at end of file
+ /**
+ * At any arbitrary layer of nesting within the configuration objects, any single value that
+ * is not specified by the configuration is given the default counterpart. If, within an object,
+ * one peer is given by configuration and two are not, the one is preserved while the two are given
+ * the default value.
+ * @returns the composition of all of the assigned objects, much like Object.assign(), but with more
+ * granularity in the overwriting of nested objects
+ */
+ export function preciseAssign(target: any, ...sources: any[]): any {
+ sources.forEach(source => {
+ preciseAssignHelper(target, source);
+ });
+ return target;
+ }
+}
diff --git a/src/server/DashStats.ts b/src/server/DashStats.ts
index a9e6af67c..808d2c6f2 100644
--- a/src/server/DashStats.ts
+++ b/src/server/DashStats.ts
@@ -1,9 +1,7 @@
import { cyan, magenta } from 'colors';
import { Response } from 'express';
-import SocketIO from 'socket.io';
-import { timeMap } from './ApiManagers/UserManager';
-import { WebSocket } from './websocket';
import * as fs from 'fs';
+import { socketMap, timeMap, userOperations } from './SocketData';
/**
* DashStats focuses on tracking user data for each session.
@@ -17,7 +15,6 @@ export namespace DashStats {
const statsCSVDirectory = './src/server/stats/';
const statsCSVFilename = statsCSVDirectory + 'userLoginStats.csv';
- const columns = ['USERNAME', 'ACTION', 'TIME'];
/**
* UserStats holds the stats associated with a particular user.
@@ -78,111 +75,14 @@ export namespace DashStats {
export const lastUserOperations = new Map<string, UserLastOperations>();
/**
- * handleStats is called when the /stats route is called, providing a JSON
- * object with relevant stats. In this case, we return the number of
- * current connections and
- * @param res Response object from Express
- */
- export function handleStats(res: Response) {
- let current = getCurrentStats();
- const results: CSVStore[] = [];
- res.json({
- currentConnections: current.length,
- socketMap: current,
- });
- }
-
- /**
- * getUpdatedStatesBundle() sends an updated copy of the current stats to the
- * frontend /statsview route via websockets.
- *
- * @returns a StatsDataBundle that is sent to the frontend view on each websocket update
- */
- export function getUpdatedStatsBundle(): StatsDataBundle {
- let current = getCurrentStats();
-
- return {
- connectedUsers: current,
- };
- }
-
- /**
- * handleStatsView() is called when the /statsview route is called. This
- * will use pug to render a frontend view of the current stats
- *
- * @param res
- */
- export function handleStatsView(res: Response) {
- let current = getCurrentStats();
-
- let connectedUsers = current.map(socketPair => {
- return socketPair.time + ' - ' + socketPair.username + ' Operations: ' + socketPair.operations;
- });
-
- let serverTraffic = ServerTraffic.NOT_BUSY;
- if (current.length < BUSY_SERVER_BOUND) {
- serverTraffic = ServerTraffic.NOT_BUSY;
- } else if (current.length >= BUSY_SERVER_BOUND && current.length < VERY_BUSY_SERVER_BOUND) {
- serverTraffic = ServerTraffic.BUSY;
- } else {
- serverTraffic = ServerTraffic.VERY_BUSY;
- }
-
- res.render('stats.pug', {
- title: 'Dash Stats',
- numConnections: connectedUsers.length,
- serverTraffic: serverTraffic,
- serverTrafficMessage: serverTrafficMessages[serverTraffic],
- connectedUsers: connectedUsers,
- });
- }
-
- /**
- * logUserLogin() writes a login event to the CSV file.
- *
- * @param username the username in the format of "username@domain.com logged in"
- * @param socket the websocket associated with the current connection
- */
- export function logUserLogin(username: string | undefined, socket: SocketIO.Socket) {
- if (!(username === undefined)) {
- let currentDate = new Date();
- console.log(magenta(`User ${username.split(' ')[0]} logged in at: ${currentDate.toISOString()}`));
-
- let toWrite: CSVStore = {
- USERNAME: username,
- ACTION: 'loggedIn',
- TIME: currentDate.toISOString(),
- };
-
- if (!fs.existsSync(statsCSVDirectory)) fs.mkdirSync(statsCSVDirectory);
- let statsFile = fs.createWriteStream(statsCSVFilename, { flags: 'a' });
- statsFile.write(convertToCSV(toWrite));
- statsFile.end();
- console.log(cyan(convertToCSV(toWrite)));
- }
- }
-
- /**
- * logUserLogout() writes a logout event to the CSV file.
- *
- * @param username the username in the format of "username@domain.com logged in"
- * @param socket the websocket associated with the current connection.
+ * convertToCSV() is a helper method that stringifies a CSVStore object
+ * that can be written to the CSV file later.
+ * @param dataObject the object to stringify
+ * @returns the object as a string.
*/
- export function logUserLogout(username: string | undefined, socket: SocketIO.Socket) {
- if (!(username === undefined)) {
- let currentDate = new Date();
-
- let statsFile = fs.createWriteStream(statsCSVFilename, { flags: 'a' });
- let toWrite: CSVStore = {
- USERNAME: username,
- ACTION: 'loggedOut',
- TIME: currentDate.toISOString(),
- };
- statsFile.write(convertToCSV(toWrite));
- statsFile.end();
- }
+ function convertToCSV(dataObject: CSVStore): string {
+ return `${dataObject.USERNAME},${dataObject.ACTION},${dataObject.TIME}\n`;
}
-
/**
* getLastOperationsOrDefault() is a helper method that will attempt
* to query the lastUserOperations map for a specified username. If the
@@ -193,7 +93,7 @@ export namespace DashStats {
*/
function getLastOperationsOrDefault(username: string): UserLastOperations {
if (lastUserOperations.get(username) === undefined) {
- let initializeOperationsQueue = [];
+ const initializeOperationsQueue = [];
for (let i = 0; i < RATE_INTERVAL; i++) {
initializeOperationsQueue.push(0);
}
@@ -217,7 +117,7 @@ export namespace DashStats {
*/
function updateLastOperations(lastOperationData: UserLastOperations, currentOperations: number): UserLastOperations {
// create a copy of the UserLastOperations to modify
- let newLastOperationData: UserLastOperations = {
+ const newLastOperationData: UserLastOperations = {
sampleOperations: lastOperationData.sampleOperations,
lastSampleOperations: lastOperationData.lastSampleOperations,
previousOperationsQueue: lastOperationData.previousOperationsQueue.slice(),
@@ -225,7 +125,7 @@ export namespace DashStats {
let newSampleOperations = newLastOperationData.sampleOperations;
newSampleOperations -= newLastOperationData.previousOperationsQueue.shift()!; // removes and returns the first element of the queue
- let operationsThisCycle = currentOperations - lastOperationData.lastSampleOperations;
+ const operationsThisCycle = currentOperations - lastOperationData.lastSampleOperations;
newSampleOperations += operationsThisCycle; // add the operations this cycle to find out what our count for the interval should be (e.g operations in the last 10 seconds)
// update values for the copy object
@@ -245,7 +145,7 @@ export namespace DashStats {
* @returns the total number of operations recorded up to this sampling cycle.
*/
function getUserOperationsOrDefault(username: string): number {
- return WebSocket.userOperations.get(username) === undefined ? 0 : WebSocket.userOperations.get(username)!;
+ return userOperations.get(username) === undefined ? 0 : userOperations.get(username)!;
}
/**
@@ -255,37 +155,129 @@ export namespace DashStats {
* @returns an array of UserStats storing data for each user at the current moment.
*/
function getCurrentStats(): UserStats[] {
- let socketPairs: UserStats[] = [];
- for (let [key, value] of WebSocket.socketMap) {
- let username = value.split(' ')[0];
- let connectionTime = new Date(timeMap[username]);
+ const socketPairs: UserStats[] = [];
+ Array.from(socketMap.entries()).forEach(([key, value]) => {
+ const username = value.split(' ')[0];
+ const connectionTime = new Date(timeMap[username]);
- let connectionTimeString = connectionTime.toLocaleDateString() + ' ' + connectionTime.toLocaleTimeString();
+ const connectionTimeString = connectionTime.toLocaleDateString() + ' ' + connectionTime.toLocaleTimeString();
if (!key.disconnected) {
- let lastRecordedOperations = getLastOperationsOrDefault(username);
- let currentUserOperationCount = getUserOperationsOrDefault(username);
+ const lastRecordedOperations = getLastOperationsOrDefault(username);
+ const currentUserOperationCount = getUserOperationsOrDefault(username);
socketPairs.push({
socketId: key.id,
username: username,
time: connectionTimeString.includes('Invalid Date') ? '' : connectionTimeString,
- operations: WebSocket.userOperations.get(username) ? WebSocket.userOperations.get(username)! : 0,
+ operations: userOperations.get(username) ? userOperations.get(username)! : 0,
rate: lastRecordedOperations.sampleOperations,
});
lastUserOperations.set(username, updateLastOperations(lastRecordedOperations, currentUserOperationCount));
}
- }
+ });
return socketPairs;
}
/**
- * convertToCSV() is a helper method that stringifies a CSVStore object
- * that can be written to the CSV file later.
- * @param dataObject the object to stringify
- * @returns the object as a string.
+ * handleStats is called when the /stats route is called, providing a JSON
+ * object with relevant stats. In this case, we return the number of
+ * current connections and
+ * @param res Response object from Express
*/
- function convertToCSV(dataObject: CSVStore): string {
- return `${dataObject.USERNAME},${dataObject.ACTION},${dataObject.TIME}\n`;
+ export function handleStats(res: Response) {
+ const current = getCurrentStats();
+ res.json({
+ currentConnections: current.length,
+ socketMap: current,
+ });
+ }
+
+ /**
+ * getUpdatedStatesBundle() sends an updated copy of the current stats to the
+ * frontend /statsview route via websockets.
+ *
+ * @returns a StatsDataBundle that is sent to the frontend view on each websocket update
+ */
+ export function getUpdatedStatsBundle(): StatsDataBundle {
+ const current = getCurrentStats();
+
+ return {
+ connectedUsers: current,
+ };
+ }
+
+ /**
+ * handleStatsView() is called when the /statsview route is called. This
+ * will use pug to render a frontend view of the current stats
+ *
+ * @param res
+ */
+ export function handleStatsView(res: Response) {
+ const current = getCurrentStats();
+ const connectedUsers = current.map(({ time, username, operations }) => time + ' - ' + username + ' Operations: ' + operations);
+
+ let serverTraffic = ServerTraffic.NOT_BUSY;
+ if (current.length < BUSY_SERVER_BOUND) {
+ serverTraffic = ServerTraffic.NOT_BUSY;
+ } else if (current.length >= BUSY_SERVER_BOUND && current.length < VERY_BUSY_SERVER_BOUND) {
+ serverTraffic = ServerTraffic.BUSY;
+ } else {
+ serverTraffic = ServerTraffic.VERY_BUSY;
+ }
+
+ res.render('stats.pug', {
+ title: 'Dash Stats',
+ numConnections: connectedUsers.length,
+ serverTraffic: serverTraffic,
+ serverTrafficMessage: serverTrafficMessages[serverTraffic],
+ connectedUsers: connectedUsers,
+ });
+ }
+
+ /**
+ * logUserLogin() writes a login event to the CSV file.
+ *
+ * @param username the username in the format of "username@domain.com logged in"
+ * @param socket the websocket associated with the current connection
+ */
+ export function logUserLogin(username: string | undefined) {
+ if (!(username === undefined)) {
+ const currentDate = new Date();
+ console.log(magenta(`User ${username.split(' ')[0]} logged in at: ${currentDate.toISOString()}`));
+
+ const toWrite: CSVStore = {
+ USERNAME: username,
+ ACTION: 'loggedIn',
+ TIME: currentDate.toISOString(),
+ };
+
+ if (!fs.existsSync(statsCSVDirectory)) fs.mkdirSync(statsCSVDirectory);
+ const statsFile = fs.createWriteStream(statsCSVFilename, { flags: 'a' });
+ statsFile.write(convertToCSV(toWrite));
+ statsFile.end();
+ console.log(cyan(convertToCSV(toWrite)));
+ }
+ }
+
+ /**
+ * logUserLogout() writes a logout event to the CSV file.
+ *
+ * @param username the username in the format of "username@domain.com logged in"
+ * @param socket the websocket associated with the current connection.
+ */
+ export function logUserLogout(username: string | undefined) {
+ if (!(username === undefined)) {
+ const currentDate = new Date();
+
+ const statsFile = fs.createWriteStream(statsCSVFilename, { flags: 'a' });
+ const toWrite: CSVStore = {
+ USERNAME: username,
+ ACTION: 'loggedOut',
+ TIME: currentDate.toISOString(),
+ };
+ statsFile.write(convertToCSV(toWrite));
+ statsFile.end();
+ }
}
}
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 307aec6fc..08cea1de5 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -15,16 +15,15 @@ import { basename } from 'path';
import * as parse from 'pdf-parse';
import * as request from 'request-promise';
import { Duplex, Stream } from 'stream';
-import { filesDirectory, publicDirectory } from '.';
import { Utils } from '../Utils';
-import { Opt } from '../fields/Doc';
-import { ParsedPDF } from '../server/PdfTypes';
import { createIfNotExists } from './ActionUtilities';
import { AzureManager } from './ApiManagers/AzureManager';
-import { Directory, clientPathToFile, pathToDirectory, serverPathToFile } from './ApiManagers/UploadManager';
+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').spawn;
+
+const { spawn } = require('child_process');
const { exec } = require('child_process');
const requestImageSize = require('../client/util/request-image-size');
@@ -42,7 +41,7 @@ export function InjectSize(filename: string, size: SizeSuffix) {
}
function isLocal() {
- return /Dash-Web[0-9]*[\\\/]src[\\\/]server[\\\/]public[\\\/](.*)/;
+ return /Dash-Web[0-9]*[\\/]src[\\/]server[\\/]public[\\/](.*)/;
}
function usingAzure() {
@@ -68,11 +67,21 @@ export namespace DashUploadUtils {
const size = 'content-length';
const type = 'content-type';
- const BLOBSTORE_URL = process.env.BLOBSTORE_URL;
- const RESIZE_FUNCTION_URL = process.env.RESIZE_FUNCTION_URL;
+ const { BLOBSTORE_URL, RESIZE_FUNCTION_URL } = process.env;
- const { imageFormats, videoFormats, applicationFormats, audioFormats } = AcceptableMedia; //TODO:glr
+ const { imageFormats, videoFormats, applicationFormats, audioFormats } = AcceptableMedia; // TODO:glr
+ export function fExists(name: string, destination: Directory) {
+ const destinationPath = serverPathToFile(destination, name);
+ return existsSync(destinationPath);
+ }
+
+ export function getAccessPaths(directory: Directory, fileName: string) {
+ return {
+ client: clientPathToFile(directory, fileName),
+ server: serverPathToFile(directory, fileName),
+ };
+ }
export async function concatVideos(filePaths: string[]): Promise<Upload.AccessPathInfo> {
// make a list of paths to create the ordered text file for ffmpeg
const inputListName = 'concat.txt';
@@ -80,14 +89,14 @@ export namespace DashUploadUtils {
// make a list of paths to create the ordered text file for ffmpeg
const filePathsText = filePaths.map(filePath => `file '${filePath}'`).join('\n');
// write the text file to the file system
- await new Promise<void>((res, reject) =>
+ await new Promise<void>((res, reject) => {
writeFile(textFilePath, filePathsText, err => {
if (err) {
reject();
console.log(err);
} else res();
- })
- );
+ });
+ });
// make output file name based on timestamp
const outputFileName = `output-${Utils.GenerateGuid()}.mp4`;
@@ -95,19 +104,19 @@ export namespace DashUploadUtils {
const outputFilePath = path.join(pathToDirectory(Directory.videos), outputFileName);
// concatenate the videos
- await new Promise((resolve, reject) =>
+ await new Promise((resolve, reject) => {
ffmpeg()
.input(textFilePath)
.inputOptions(['-f concat', '-safe 0'])
// .outputOptions('-c copy')
- //.videoCodec("copy")
+ // .videoCodec("copy")
.save(outputFilePath)
.on('error', (err: any) => {
console.log(err);
reject();
})
- .on('end', resolve)
- );
+ .on('end', resolve);
+ });
// delete concat.txt from the file system
unlinkSync(textFilePath);
@@ -135,270 +144,76 @@ export namespace DashUploadUtils {
};
}
- export function QueryYoutubeProgress(videoId: string, user?: Express.User) {
+ export const uploadProgress = new Map<string, string>();
+
+ export function QueryYoutubeProgress(videoId: string) {
// console.log(`PROGRESS:${videoId}`, (user as any)?.email);
return uploadProgress.get(videoId) ?? 'pending data upload';
}
- export let uploadProgress = new Map<string, string>();
-
- export function uploadYoutube(videoId: string, overwriteId: string): Promise<Upload.FileResponse> {
- return new Promise<Upload.FileResponse<Upload.FileInformation>>((res, rej) => {
- const name = videoId;
- const filepath = name.replace(/^-/, '__') + '.mp4';
- const finalPath = serverPathToFile(Directory.videos, filepath);
- if (existsSync(finalPath)) {
- uploadProgress.set(overwriteId, 'computing duration');
- 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);
- res(resolveExistingFile(name, filepath, Directory.videos, 'video/mp4', duration, undefined));
- });
- } else {
- uploadProgress.set(overwriteId, 'starting download');
- const ytdlp = spawn(`yt-dlp`, ['-o', filepath, `https://www.youtube.com/watch?v=${videoId}`, '--max-filesize', '100M', '-f', 'mp4']);
-
- ytdlp.stdout.on('data', (data: any) => uploadProgress.set(overwriteId, data.toString()));
-
- let errors = '';
- ytdlp.stderr.on('data', (data: any) => {
- uploadProgress.set(overwriteId, 'error:' + data.toString());
- errors = data.toString();
- });
-
- ytdlp.on('exit', function (code: any) {
- if (code) {
- res({
- source: {
- size: 0,
- filepath: name,
- originalFilename: name,
- newFilename: name,
- mimetype: 'video',
- hashAlgorithm: 'md5',
- toJSON: () => ({ newFilename: name, filepath, mimetype: 'video', mtime: new Date(), size: 0, length: 0, originalFilename: name }),
- },
- result: { name: 'failed youtube query', message: `Could not archive video. ${code ? errors : uploadProgress.get(videoId)}` },
- });
- } else {
- uploadProgress.set(overwriteId, 'computing duration');
- 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 }) };
- MoveParsedFile(file, Directory.videos).then(output => {
- console.log('OUTPUT = ' + output);
- res(output);
- });
- });
- }
+ /**
+ * Basically just a wrapper around rename, which 'deletes'
+ * the file at the old path and 'moves' it to the new one. For simplicity, the
+ * caller just has to pass in the name of the target directory, and this function
+ * will resolve the actual target path from that.
+ * @param file The file to move
+ * @param destination One of the specific media asset directories into which to move it
+ * @param suffix If the file doesn't have a suffix and you want to provide it one
+ * to appear in the new location
+ */
+ export async function MoveParsedFile(file: formidable.File, destination: Directory, suffix?: string, text?: string, duration?: number, targetName?: string): Promise<Upload.FileResponse> {
+ const { filepath } = file;
+ let name = targetName ?? path.basename(filepath);
+ suffix && (name += suffix);
+ return new Promise(resolve => {
+ const destinationPath = serverPathToFile(destination, name);
+ rename(filepath, destinationPath, error => {
+ resolve({
+ source: file,
+ result: error ?? {
+ accessPaths: {
+ agnostic: getAccessPaths(destination, name),
+ },
+ rawText: text,
+ duration,
+ },
});
- }
+ });
});
}
- export async function upload(file: File, overwriteGuid?: string): Promise<Upload.FileResponse> {
- const isAzureOn = usingAzure();
- const { mimetype: type, filepath, originalFilename } = file;
- const types = type?.split('/') ?? [];
- // uploadProgress.set(overwriteGuid ?? name, 'uploading'); // If the client sent a guid it uses to track upload progress, use that guid. Otherwise, use the file's name.
-
- const category = types[0];
- let format = `.${types[1]}`;
- console.log(green(`Processing upload of file (${originalFilename}) and format (${format}) with upload type (${type}) in category (${category}).`));
-
- switch (category) {
- case 'image':
- if (imageFormats.includes(format)) {
- const result = await UploadImage(filepath, basename(filepath));
- return { source: file, result };
- }
- fs.unlink(filepath, () => {});
- return { source: file, result: { name: 'Unsupported image format', message: `Could not upload unsupported file (${originalFilename}). Please convert to an .jpg` } };
- case 'video':
- if (format.includes('x-matroska')) {
- console.log('case video');
- await new Promise(res =>
- ffmpeg(file.filepath)
- .videoCodec('copy') // this will copy the data instead of reencode it
- .save(file.filepath.replace('.mkv', '.mp4'))
- .on('end', res)
- .on('error', (e: any) => console.log(e))
- );
- file.filepath = file.filepath.replace('.mkv', '.mp4');
- format = '.mp4';
- }
- if (format.includes('quicktime')) {
- let abort = false;
- await new Promise<void>(res =>
- ffmpeg.ffprobe(file.filepath, (err: any, metadata: any) => {
- if (metadata.streams.some((stream: any) => stream.codec_name === 'hevc')) {
- abort = true;
- }
- res();
- })
- );
- if (abort) {
- // bcz: instead of aborting, we could convert the file using the code below to an mp4. Problem is that this takes a long time and will clog up the server.
- // await new Promise(res =>
- // ffmpeg(file.path)
- // .videoCodec('libx264') // this will copy the data instead of reencode it
- // .audioCodec('mp2')
- // .save(file.path.replace('.MOV', '.mp4').replace('.mov', '.mp4'))
- // .on('end', res)
- // );
- // file.path = file.path.replace('.mov', '.mp4').replace('.MOV', '.mp4');
- // format = '.mp4';
- fs.unlink(filepath, () => {});
- return { source: file, result: { name: 'Unsupported video format', message: `Could not upload unsupported file (${originalFilename}). Please convert to an .mp4` } };
- }
- }
- if (videoFormats.includes(format) || format.includes('.webm')) {
- return MoveParsedFile(file, Directory.videos);
- }
- fs.unlink(filepath, () => {});
- return { source: file, result: { name: 'Unsupported video format', message: `Could not upload unsupported file (${originalFilename}). Please convert to an .mp4` } };
- case 'application':
- if (applicationFormats.includes(format)) {
- const val = UploadPdf(file);
- if (val) return val;
- }
- case 'audio':
- const components = format.split(';');
- if (components.length > 1) {
- format = components[0];
- }
- if (audioFormats.includes(format)) {
- return UploadAudio(file, format);
- }
- fs.unlink(filepath, () => {});
- return { source: file, result: { name: 'Unsupported audio format', message: `Could not upload unsupported file (${originalFilename}). Please convert to an .mp3` } };
- case 'text':
- if (types[1] == 'csv') {
- return UploadCsv(file);
- }
- }
-
- console.log(red(`Ignoring unsupported file (${originalFilename}) with upload type (${type}).`));
- fs.unlink(filepath, () => {});
- return { source: file, result: new Error(`Could not upload unsupported file (${originalFilename}) with upload type (${type}).`) };
- }
-
- async function UploadPdf(file: File) {
- const fileKey = (await md5File(file.filepath)) + '.pdf';
- const textFilename = `${fileKey.substring(0, fileKey.length - 4)}.txt`;
- if (fExists(fileKey, Directory.pdfs) && fExists(textFilename, Directory.text)) {
- fs.unlink(file.filepath, () => {});
- return new Promise<Upload.FileResponse>(res => {
- const textFilename = `${fileKey.substring(0, fileKey.length - 4)}.txt`;
- const readStream = createReadStream(serverPathToFile(Directory.text, textFilename));
- var rawText = '';
- readStream
- .on('data', chunk => (rawText += chunk.toString())) //
- .on('end', () => res(resolveExistingFile(file.originalFilename ?? '', fileKey, Directory.pdfs, file.mimetype, undefined, rawText)));
- });
- }
- const dataBuffer = readFileSync(file.filepath);
- const result: ParsedPDF | any = await parse(dataBuffer).catch((e: any) => e);
- if (!result.code) {
- await new Promise<void>((resolve, reject) => {
- const writeStream = createWriteStream(serverPathToFile(Directory.text, textFilename));
- writeStream.write(result?.text, error => (error ? reject(error) : resolve()));
+ const parseExifData = async (source: string) => {
+ const image = await request.get(source, { encoding: null });
+ const { /* data, */ error } = await new Promise<{ data: any; error: any }>(resolve => {
+ // eslint-disable-next-line no-new
+ new ExifImage({ image }, (exifError, data) => {
+ const reason = (exifError as any)?.code;
+ resolve({ data, error: reason });
});
- 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}` } };
- }
-
- async function UploadCsv(file: File) {
- const { filepath: sourcePath } = file;
- // read the file as a string
- const data = readFileSync(sourcePath, 'utf8');
- // split the string into an array of lines
- return MoveParsedFile(file, Directory.csv, undefined, data);
- // console.log(csvParser(data));
- }
-
- const manualSuffixes = ['.webm'];
-
- async function UploadAudio(file: File, format: string) {
- const suffix = manualSuffixes.includes(format) ? format : undefined;
- return MoveParsedFile(file, Directory.audio, suffix);
- }
-
- /**
- * Uploads an image specified by the @param source to Dash's /public/files/
- * directory, and returns information generated during that upload
- *
- * @param {string} source is either the absolute path of an already uploaded image or
- * the url of a remote image
- * @param {string} filename dictates what to call the image. If not specified,
- * the name {@param prefix}_upload_{GUID}
- * @param {string} prefix is a string prepended to the generated image name in the
- * event that @param filename is not specified
- *
- * @returns {ImageUploadInformation | Error} This method returns
- * 1) the paths to the uploaded images (plural due to resizing)
- * 2) the exif data embedded in the image, or the error explaining why exif couldn't be parsed
- * 3) the size of the image, in bytes (4432130)
- * 4) the content type of the image, i.e. image/(jpeg | png | ...)
- */
- export const UploadImage = async (source: string, filename?: string, prefix: string = ''): Promise<Upload.ImageInformation | Error> => {
- const metadata = await InspectImage(source);
- if (metadata instanceof Error) {
- return { name: metadata.name, message: metadata.message };
- }
- const outputFile = filename || metadata.filename || '';
-
- return UploadInspectedImage(metadata, outputFile, prefix);
+ });
+ return error ? { data: undefined, error } : { data: await exifr.parse(image), error };
};
-
- export async function buildFileDirectories() {
- if (!existsSync(publicDirectory)) {
- console.error('\nPlease ensure that the following directory exists...\n');
- console.log(publicDirectory);
- process.exit(0);
- }
- if (!existsSync(filesDirectory)) {
- console.error('\nPlease ensure that the following directory exists...\n');
- console.log(filesDirectory);
- process.exit(0);
- }
- const pending = Object.keys(Directory).map(sub => createIfNotExists(`${filesDirectory}/${sub}`));
- return Promise.all(pending);
- }
-
- export interface RequestedImageSize {
- width: number;
- height: number;
- type: string;
- }
-
- export interface ImageResizer {
- width: number;
- suffix: SizeSuffix;
- }
-
/**
* Based on the url's classification as local or remote, gleans
* as much information as possible about the specified image
*
* @param source is the path or url to the image in question
*/
- export const InspectImage = async (source: string): Promise<Upload.InspectionResults | Error> => {
- let rawMatches: RegExpExecArray | null;
+ export const InspectImage = async (sourceIn: string): Promise<Upload.InspectionResults | Error> => {
+ let source = sourceIn;
+ const rawMatches = /^data:image\/([a-z]+);base64,(.*)/.exec(source);
let filename: string | undefined;
/**
* Just more edge case handling: this if clause handles the case where an image onto the canvas that
* is represented by a base64 encoded data uri, rather than a proper file. We manually write it out
* to the server and then carry on as if it had been put there by the Formidable form / file parser.
*/
- if ((rawMatches = /^data:image\/([a-z]+);base64,(.*)/.exec(source)) !== null) {
+ if (rawMatches !== null) {
const [ext, data] = rawMatches.slice(1, 3);
- const resolved = (filename = `upload_${Utils.GenerateGuid()}.${ext}`);
+ filename = `upload_${Utils.GenerateGuid()}.${ext}`;
+ const resolved = filename;
if (usingAzure()) {
- const response = await AzureManager.UploadBase64ImageBlob(resolved, data);
+ await AzureManager.UploadBase64ImageBlob(resolved, data);
source = `${AzureManager.BASE_STRING}/${resolved}`;
} else {
source = `${resolvedServerUrl}${clientPathToFile(Directory.images, resolved)}`;
@@ -438,7 +253,7 @@ export namespace DashUploadUtils {
// Use the request library to parse out file level image information in the headers
const { headers } = await new Promise<any>((resolve, reject) => {
- return request.head(resolvedUrl, (error, res) => (error ? reject(error) : resolve(res)));
+ request.head(resolvedUrl, (error, res) => (error ? reject(error) : resolve(res)));
}).catch(e => {
console.log('Error processing headers: ', e);
});
@@ -449,6 +264,7 @@ export namespace DashUploadUtils {
// Bundle up the information into an object
return {
source,
+ // eslint-disable-next-line radix
contentSize: parseInt(headers[size]),
contentType: headers[type],
nativeWidth,
@@ -462,49 +278,71 @@ export namespace DashUploadUtils {
}
};
+ async function correctRotation(imgSourcePath: string) {
+ const buffer = fs.readFileSync(imgSourcePath);
+ try {
+ return (await autorotate.rotate(buffer, { quality: 30 })).buffer;
+ } catch (e) {
+ return buffer;
+ }
+ }
+
/**
- * Basically just a wrapper around rename, which 'deletes'
- * the file at the old path and 'moves' it to the new one. For simplicity, the
- * caller just has to pass in the name of the target directory, and this function
- * will resolve the actual target path from that.
- * @param file The file to move
- * @param destination One of the specific media asset directories into which to move it
- * @param suffix If the file doesn't have a suffix and you want to provide it one
- * to appear in the new location
+ * define the resizers to use
+ * @param ext the extension
+ * @returns an array of resize descriptions
*/
- export async function MoveParsedFile(file: formidable.File, destination: Directory, suffix: string | undefined = undefined, text?: string, duration?: number, targetName?: string): Promise<Upload.FileResponse> {
- const { filepath } = file;
- let name = targetName ?? path.basename(filepath);
- suffix && (name += suffix);
- return new Promise(resolve => {
- const destinationPath = serverPathToFile(destination, name);
- rename(filepath, destinationPath, error => {
- resolve({
- source: file,
- result: error
- ? error
- : {
- accessPaths: {
- agnostic: getAccessPaths(destination, name),
- },
- rawText: text,
- duration,
- },
- });
- });
- });
+ export function imageResampleSizes(ext: string): DashUploadUtils.ImageResizer[] {
+ return [
+ { suffix: SizeSuffix.Original, width: 0 },
+ ...[...(AcceptableMedia.imageFormats.includes(ext.toLowerCase()) ? Object.values(DashUploadUtils.Sizes) : [])].map(({ suffix, width }) => ({
+ width,
+ suffix,
+ })),
+ ];
}
- export function fExists(name: string, destination: Directory) {
- const destinationPath = serverPathToFile(destination, name);
- return existsSync(destinationPath);
- }
+ /**
+ * outputResizedImages takes in a readable stream and resizes the images according to the sizes defined at the top of this file.
+ *
+ * The new images will be saved to the server with the corresponding prefixes.
+ * @param imgSourcePath file path for image being resized
+ * @param outputFileName the basename (No suffix) of the outputted file.
+ * @param outputDirectory the directory to output to, usually Directory.Images
+ * @returns a map with suffixes as keys and resized filenames as values.
+ */
+ export async function outputResizedImages(imgSourcePath: string, outputFileName: string, outputDirectory: string) {
+ const writtenFiles: { [suffix: string]: string } = {};
+ const sizes = imageResampleSizes(path.extname(outputFileName));
- export function getAccessPaths(directory: Directory, fileName: string) {
- return {
- client: clientPathToFile(directory, fileName),
- server: serverPathToFile(directory, fileName),
+ const imgBuffer = await correctRotation(imgSourcePath);
+ const imgReadStream = new Duplex();
+ imgReadStream.push(imgBuffer);
+ imgReadStream.push(null);
+ const outputPath = (suffix: SizeSuffix) => {
+ writtenFiles[suffix] = InjectSize(outputFileName, suffix);
+ return path.resolve(outputDirectory, writtenFiles[suffix]);
};
+ await Promise.all(
+ sizes.filter(({ width }) => !width).map(({ suffix }) =>
+ new Promise<void>(res => {
+ imgReadStream.pipe(createWriteStream(outputPath(suffix))).on('close', res);
+ })
+ )); // prettier-ignore
+
+ return Jimp.read(imgBuffer)
+ .then(async (imgIn: any) => {
+ let img = imgIn;
+ await Promise.all( sizes.filter(({ width }) => width).map(({ width, suffix }) => {
+ img = img.resize(width, Jimp.AUTO).write(outputPath(suffix));
+ return img;
+ } )); // prettier-ignore
+ return writtenFiles;
+ })
+ .catch((e: any) => {
+ console.log('ERROR' + e);
+ return writtenFiles;
+ });
}
/**
@@ -555,119 +393,265 @@ export namespace DashUploadUtils {
} catch (e) {
// input is a blob or other, try reading it to create a metadata source file.
const reqSource = request(metadata.source);
- let readStream: Stream = reqSource instanceof Promise ? await reqSource : reqSource;
+ const readStream: Stream = reqSource instanceof Promise ? await reqSource : reqSource;
const readSource = `${prefix}upload_${Utils.GenerateGuid()}.${metadata.contentType.split('/')[1].toLowerCase()}`;
- await new Promise<void>((res, rej) =>
+ await new Promise<void>((res, rej) => {
readStream
.pipe(createWriteStream(readSource))
.on('close', () => res())
- .on('error', () => rej())
- );
+ .on('error', () => rej());
+ });
writtenFiles = await outputResizedImages(readSource, resolved, pathToDirectory(Directory.images));
- fs.unlink(readSource, err => console.log("Couldn't unlink temporary image file:" + readSource));
+ fs.unlink(readSource, err => console.log("Couldn't unlink temporary image file:" + readSource, err));
}
}
- for (const suffix of Object.keys(writtenFiles)) {
+ Array.from(Object.keys(writtenFiles)).forEach(suffix => {
information.accessPaths[suffix] = getAccessPaths(images, writtenFiles[suffix]);
- }
+ });
if (isLocal().test(source) && cleanUp) {
unlinkSync(source);
}
return information;
};
- const bufferConverterRec = (layer: any) => {
- for (const key of Object.keys(layer)) {
- const val: any = layer[key];
- if (val instanceof Buffer) {
- layer[key] = val.toString();
- } else if (Array.isArray(val) && typeof val[0] === 'number') {
- layer[key] = Buffer.from(val).toString();
- } else if (typeof val === 'object') {
- bufferConverterRec(val);
- }
+ /**
+ * Uploads an image specified by the @param source to Dash's /public/files/
+ * directory, and returns information generated during that upload
+ *
+ * @param {string} source is either the absolute path of an already uploaded image or
+ * the url of a remote image
+ * @param {string} filename dictates what to call the image. If not specified,
+ * the name {@param prefix}_upload_{GUID}
+ * @param {string} prefix is a string prepended to the generated image name in the
+ * event that @param filename is not specified
+ *
+ * @returns {ImageUploadInformation | Error} This method returns
+ * 1) the paths to the uploaded images (plural due to resizing)
+ * 2) the exif data embedded in the image, or the error explaining why exif couldn't be parsed
+ * 3) the size of the image, in bytes (4432130)
+ * 4) the content type of the image, i.e. image/(jpeg | png | ...)
+ */
+ export const UploadImage = async (source: string, filename?: string, prefix: string = ''): Promise<Upload.ImageInformation | Error> => {
+ const metadata = await InspectImage(source);
+ if (metadata instanceof Error) {
+ return { name: metadata.name, message: metadata.message };
}
+ const outputFile = filename || metadata.filename || '';
+
+ return UploadInspectedImage(metadata, outputFile, prefix);
};
- const parseExifData = async (source: string) => {
- const image = await request.get(source, { encoding: null });
- const { data, error } = await new Promise<{ data: any; error: any }>(resolve => {
- new ExifImage({ image }, (error, data) => {
- let reason: Opt<string> = undefined;
- if (error) {
- reason = (error as any).code;
- }
- resolve({ data, error: reason });
- });
+ export function uploadYoutube(videoId: string, overwriteId: string): Promise<Upload.FileResponse> {
+ return new Promise<Upload.FileResponse<Upload.FileInformation>>(res => {
+ const name = videoId;
+ const filepath = name.replace(/^-/, '__') + '.mp4';
+ const finalPath = serverPathToFile(Directory.videos, filepath);
+ if (existsSync(finalPath)) {
+ uploadProgress.set(overwriteId, 'computing duration');
+ 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);
+ res(resolveExistingFile(name, filepath, Directory.videos, 'video/mp4', duration, undefined));
+ });
+ } else {
+ uploadProgress.set(overwriteId, 'starting download');
+ const ytdlp = spawn(`yt-dlp`, ['-o', filepath, `https://www.youtube.com/watch?v=${videoId}`, '--max-filesize', '100M', '-f', 'mp4']);
+
+ ytdlp.stdout.on('data', (data: any) => uploadProgress.set(overwriteId, data.toString()));
+
+ let errors = '';
+ ytdlp.stderr.on('data', (data: any) => {
+ uploadProgress.set(overwriteId, 'error:' + data.toString());
+ errors = data.toString();
+ });
+
+ ytdlp.on('exit', (code: any) => {
+ if (code) {
+ res({
+ source: {
+ size: 0,
+ filepath: name,
+ originalFilename: name,
+ newFilename: name,
+ mimetype: 'video',
+ hashAlgorithm: 'md5',
+ toJSON: () => ({ newFilename: name, filepath, mimetype: 'video', mtime: new Date(), size: 0, length: 0, originalFilename: name }),
+ },
+ result: { name: 'failed youtube query', message: `Could not archive video. ${code ? errors : uploadProgress.get(videoId)}` },
+ });
+ } else {
+ uploadProgress.set(overwriteId, 'computing duration');
+ 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 }) };
+ MoveParsedFile(file, Directory.videos).then(output => res(output));
+ });
+ }
+ });
+ }
});
- //data && bufferConverterRec(data);
- return error ? { data: undefined, error } : { data: await exifr.parse(image), error };
- };
+ }
+ const manualSuffixes = ['.webm'];
- const { pngs, jpgs, webps, tiffs } = AcceptableMedia;
- const pngOptions = {
- compressionLevel: 9,
- adaptiveFiltering: true,
- force: true,
- };
+ async function UploadAudio(file: File, format: string) {
+ const suffix = manualSuffixes.includes(format) ? format : undefined;
+ return MoveParsedFile(file, Directory.audio, suffix);
+ }
- async function correctRotation(imgSourcePath: string) {
- const buffer = fs.readFileSync(imgSourcePath);
- try {
- return (await autorotate.rotate(buffer, { quality: 30 })).buffer;
- } catch (e) {
- return buffer;
+ async function UploadPdf(file: File) {
+ const fileKey = (await md5File(file.filepath)) + '.pdf';
+ const textFilename = `${fileKey.substring(0, fileKey.length - 4)}.txt`;
+ if (fExists(fileKey, Directory.pdfs) && fExists(textFilename, Directory.text)) {
+ fs.unlink(file.filepath, () => {});
+ return new Promise<Upload.FileResponse>(res => {
+ const pdfTextFilename = `${fileKey.substring(0, fileKey.length - 4)}.txt`;
+ const readStream = createReadStream(serverPathToFile(Directory.text, pdfTextFilename));
+ let rawText = '';
+ readStream
+ .on('data', chunk => {
+ rawText += chunk.toString();
+ })
+ .on('end', () => res(resolveExistingFile(file.originalFilename ?? '', fileKey, Directory.pdfs, file.mimetype, undefined, rawText)));
+ });
}
+ const dataBuffer = readFileSync(file.filepath);
+ const result: ParsedPDF | any = await parse(dataBuffer).catch((e: any) => e);
+ if (!result.code) {
+ await new Promise<void>((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}` } };
}
- /**
- * outputResizedImages takes in a readable stream and resizes the images according to the sizes defined at the top of this file.
- *
- * The new images will be saved to the server with the corresponding prefixes.
- * @param imgSourcePath file path for image being resized
- * @param outputFileName the basename (No suffix) of the outputted file.
- * @param outputDirectory the directory to output to, usually Directory.Images
- * @returns a map with suffixes as keys and resized filenames as values.
- */
- export async function outputResizedImages(imgSourcePath: string, outputFileName: string, outputDirectory: string) {
- const writtenFiles: { [suffix: string]: string } = {};
- const sizes = imageResampleSizes(path.extname(outputFileName));
+ async function UploadCsv(file: File) {
+ const { filepath: sourcePath } = file;
+ // read the file as a string
+ const data = readFileSync(sourcePath, 'utf8');
+ // split the string into an array of lines
+ return MoveParsedFile(file, Directory.csv, undefined, data);
+ // console.log(csvParser(data));
+ }
- const imgBuffer = await correctRotation(imgSourcePath);
- const imgReadStream = new Duplex();
- imgReadStream.push(imgBuffer);
- imgReadStream.push(null);
- const outputPath = (suffix: SizeSuffix) => path.resolve(outputDirectory, (writtenFiles[suffix] = InjectSize(outputFileName, suffix)));
- await Promise.all(
- sizes.filter(({ width }) => !width).map(({ suffix }) =>
- new Promise<void>(res => imgReadStream.pipe(createWriteStream(outputPath(suffix))).on('close', res))
- )); // prettier-ignore
+ export async function upload(file: File /* , overwriteGuid?: string */): Promise<Upload.FileResponse> {
+ // const isAzureOn = usingAzure();
+ const { mimetype, filepath, originalFilename } = file;
+ const types = mimetype?.split('/') ?? [];
+ // uploadProgress.set(overwriteGuid ?? name, 'uploading'); // If the client sent a guid it uses to track upload progress, use that guid. Otherwise, use the file's name.
- return Jimp.read(imgBuffer)
- .then(async (img: any) => {
- await Promise.all( sizes.filter(({ width }) => width).map(({ width, suffix }) =>
- img = img.resize(width, Jimp.AUTO).write(outputPath(suffix))
- )); // prettier-ignore
- return writtenFiles;
- })
- .catch((e: any) => {
- console.log('ERROR' + e);
- return writtenFiles;
- });
+ const category = types[0];
+ let format = `.${types[1]}`;
+ console.log(green(`Processing upload of file (${originalFilename}) and format (${format}) with upload type (${mimetype}) in category (${category}).`));
+
+ switch (category) {
+ case 'image':
+ if (imageFormats.includes(format)) {
+ const result = await UploadImage(filepath, basename(filepath));
+ return { source: file, result };
+ }
+ fs.unlink(filepath, () => {});
+ return { source: file, result: { name: 'Unsupported image format', message: `Could not upload unsupported file (${originalFilename}). Please convert to an .jpg` } };
+ case 'video': {
+ const vidFile = file;
+ if (format.includes('x-matroska')) {
+ await new Promise(res => {
+ ffmpeg(vidFile.filepath)
+ .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));
+ });
+ vidFile.filepath = vidFile.filepath.replace('.mkv', '.mp4');
+ format = '.mp4';
+ }
+ if (format.includes('quicktime')) {
+ let abort = false;
+ await new Promise<void>(res => {
+ ffmpeg.ffprobe(vidFile.filepath, (err: any, metadata: any) => {
+ if (metadata.streams.some((stream: any) => stream.codec_name === 'hevc')) {
+ abort = true;
+ }
+ res();
+ });
+ });
+ if (abort) {
+ // bcz: instead of aborting, we could convert the file using the code below to an mp4. Problem is that this takes a long time and will clog up the server.
+ // await new Promise(res =>
+ // ffmpeg(file.path)
+ // .videoCodec('libx264') // this will copy the data instead of reencode it
+ // .audioCodec('mp2')
+ // .save(vidFile.path.replace('.MOV', '.mp4').replace('.mov', '.mp4'))
+ // .on('end', res)
+ // );
+ // vidFile.path = vidFile.path.replace('.mov', '.mp4').replace('.MOV', '.mp4');
+ // format = '.mp4';
+ fs.unlink(filepath, () => {});
+ return { source: file, result: { name: 'Unsupported video format', message: `Could not upload unsupported file (${originalFilename}). Please convert to an .mp4` } };
+ }
+ }
+ if (videoFormats.includes(format) || format.includes('.webm')) {
+ return MoveParsedFile(vidFile, Directory.videos);
+ }
+ fs.unlink(filepath, () => {});
+ return { source: vidFile, result: { name: 'Unsupported video format', message: `Could not upload unsupported file (${originalFilename}). Please convert to an .mp4` } };
+ }
+ case 'application':
+ if (applicationFormats.includes(format)) {
+ const val = UploadPdf(file);
+ if (val) return val;
+ }
+ break;
+ case 'audio': {
+ const components = format.split(';');
+ if (components.length > 1) {
+ [format] = components;
+ }
+ if (audioFormats.includes(format)) {
+ return UploadAudio(file, format);
+ }
+ fs.unlink(filepath, () => {});
+ return { source: file, result: { name: 'Unsupported audio format', message: `Could not upload unsupported file (${originalFilename}). Please convert to an .mp3` } };
+ }
+ case 'text':
+ if (types[1] === 'csv') {
+ return UploadCsv(file);
+ }
+ break;
+ default:
+ }
+
+ console.log(red(`Ignoring unsupported file (${originalFilename}) with upload type (${mimetype}).`));
+ fs.unlink(filepath, () => {});
+ return { source: file, result: new Error(`Could not upload unsupported file (${originalFilename}) with upload type (${mimetype}).`) };
}
- /**
- * define the resizers to use
- * @param ext the extension
- * @returns an array of resize descriptions
- */
- export function imageResampleSizes(ext: string): DashUploadUtils.ImageResizer[] {
- return [
- { suffix: SizeSuffix.Original, width: 0 },
- ...[...(AcceptableMedia.imageFormats.includes(ext.toLowerCase()) ? Object.values(DashUploadUtils.Sizes) : [])].map(({ suffix, width }) => ({
- width,
- suffix,
- })),
- ];
+ export async function buildFileDirectories() {
+ if (!existsSync(publicDirectory)) {
+ console.error('\nPlease ensure that the following directory exists...\n');
+ console.log(publicDirectory);
+ process.exit(0);
+ }
+ if (!existsSync(filesDirectory)) {
+ console.error('\nPlease ensure that the following directory exists...\n');
+ console.log(filesDirectory);
+ process.exit(0);
+ }
+ const pending = Object.keys(Directory).map(sub => createIfNotExists(`${filesDirectory}/${sub}`));
+ return Promise.all(pending);
+ }
+
+ export interface RequestedImageSize {
+ width: number;
+ height: number;
+ type: string;
+ }
+
+ export interface ImageResizer {
+ width: number;
+ suffix: SizeSuffix;
}
}
diff --git a/src/server/DataVizUtils.ts b/src/server/DataVizUtils.ts
index 15f03b319..64805633f 100644
--- a/src/server/DataVizUtils.ts
+++ b/src/server/DataVizUtils.ts
@@ -4,10 +4,13 @@ export function csvParser(csv: string) {
const lines = csv.split('\n');
const headers = lines[0].split(',').map(header => header.trim());
const data = lines.slice(1).map(line =>
- line.split(',').reduce((last, value, i) => {
- last[headers[i]] = value.trim();
- return last;
- }, {} as any)
+ line.split(',').reduce(
+ (last, value, i) => {
+ last[headers[i]] = value.trim();
+ return last;
+ },
+ {} as { [key: string]: string }
+ )
);
return data;
}
diff --git a/src/server/GarbageCollector.ts b/src/server/GarbageCollector.ts
index 423c719c2..041f65592 100644
--- a/src/server/GarbageCollector.ts
+++ b/src/server/GarbageCollector.ts
@@ -1,11 +1,15 @@
+/* eslint-disable no-await-in-loop */
+/* eslint-disable no-continue */
+/* eslint-disable no-cond-assign */
+/* eslint-disable no-restricted-syntax */
import * as fs from 'fs';
import * as path from 'path';
import { Database } from './database';
import { Search } from './Search';
-
function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) {
for (const key in doc) {
+ // eslint-disable-next-line no-prototype-builtins
if (!doc.hasOwnProperty(key)) {
continue;
}
@@ -13,22 +17,22 @@ function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) {
if (field === undefined || field === null) {
continue;
}
- if (field.__type === "proxy" || field.__type === "prefetch_proxy") {
+ if (field.__type === 'proxy' || field.__type === 'prefetch_proxy') {
ids.push(field.fieldId);
- } else if (field.__type === "list") {
+ } else if (field.__type === 'list') {
addDoc(field.fields, ids, files);
- } else if (typeof field === "string") {
- const re = /"(?:dataD|d)ocumentId"\s*:\s*"([\w\-]*)"/g;
+ } else if (typeof field === 'string') {
+ const re = /"(?:dataD|d)ocumentId"\s*:\s*"([\w-]*)"/g;
let match: string[] | null;
while ((match = re.exec(field)) !== null) {
ids.push(match[1]);
}
- } else if (field.__type === "RichTextField") {
+ } else if (field.__type === 'RichTextField') {
const re = /"href"\s*:\s*"(.*?)"/g;
let match: string[] | null;
while ((match = re.exec(field.Data)) !== null) {
const urlString = match[1];
- const split = new URL(urlString).pathname.split("doc/");
+ const split = new URL(urlString).pathname.split('doc/');
if (split.length > 1) {
ids.push(split[split.length - 1]);
}
@@ -36,7 +40,7 @@ function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) {
const re2 = /"src"\s*:\s*"(.*?)"/g;
while ((match = re2.exec(field.Data)) !== null) {
const urlString = match[1];
- const pathname = new URL(urlString).pathname;
+ const { pathname } = new URL(urlString);
const ext = path.extname(pathname);
const fileName = path.basename(pathname, ext);
let exts = files[fileName];
@@ -45,9 +49,9 @@ function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) {
}
exts.push(ext);
}
- } else if (["audio", "image", "video", "pdf", "web", "map"].includes(field.__type)) {
+ } else if (['audio', 'image', 'video', 'pdf', 'web', 'map'].includes(field.__type)) {
const url = new URL(field.url);
- const pathname = url.pathname;
+ const { pathname } = url;
const ext = path.extname(pathname);
const fileName = path.basename(pathname, ext);
let exts = files[fileName];
@@ -60,12 +64,12 @@ function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) {
}
async function GarbageCollect(full: boolean = true) {
- console.log("start GC");
+ console.log('start GC');
const start = Date.now();
// await new Promise(res => setTimeout(res, 3000));
const cursor = await Database.Instance.query({}, { userDocumentId: 1 }, 'users');
const users = await cursor.toArray();
- const ids: string[] = [...users.map((user:any) => user.userDocumentId), ...users.map((user:any) => user.sharingDocumentId), ...users.map((user:any) => user.linkDatabaseId)];
+ const ids: string[] = [...users.map((user: any) => user.userDocumentId), ...users.map((user: any) => user.sharingDocumentId), ...users.map((user: any) => user.linkDatabaseId)];
const visited = new Set<string>();
const files: { [name: string]: string[] } = {};
@@ -76,9 +80,11 @@ async function GarbageCollect(full: boolean = true) {
if (!fetchIds.length) {
continue;
}
- const docs = await new Promise<{ [key: string]: any }[]>(res => Database.Instance.getDocuments(fetchIds, res));
+ const docs = await new Promise<{ [key: string]: any }[]>(res => {
+ Database.Instance.getDocuments(fetchIds, res);
+ });
for (const doc of docs) {
- const id = doc.id;
+ const { id } = doc;
if (doc === undefined) {
console.log(`Couldn't find field with Id ${id}`);
continue;
@@ -95,19 +101,27 @@ async function GarbageCollect(full: boolean = true) {
const notToDelete = Array.from(visited);
const toDeleteCursor = await Database.Instance.query({ _id: { $nin: notToDelete } }, { _id: 1 });
- const toDelete: string[] = (await toDeleteCursor.toArray()).map((doc:any) => doc._id);
+ const toDelete: string[] = (await toDeleteCursor.toArray()).map((doc: any) => doc._id);
toDeleteCursor.close();
if (!full) {
- await Database.Instance.updateMany({ _id: { $nin: notToDelete } }, { $set: { "deleted": true } });
- await Database.Instance.updateMany({ _id: { $in: notToDelete } }, { $unset: { "deleted": true } });
- console.log(await Search.updateDocuments(
- notToDelete.map<any>(id => ({
- id, deleted: { set: null }
- }))
- .concat(toDelete.map(id => ({
- id, deleted: { set: true }
- })))));
- console.log("Done with partial GC");
+ await Database.Instance.updateMany({ _id: { $nin: notToDelete } }, { $set: { deleted: true } });
+ await Database.Instance.updateMany({ _id: { $in: notToDelete } }, { $unset: { deleted: true } });
+ console.log(
+ await Search.updateDocuments(
+ notToDelete
+ .map<any>(id => ({
+ id,
+ deleted: { set: null },
+ }))
+ .concat(
+ toDelete.map(id => ({
+ id,
+ deleted: { set: true },
+ }))
+ )
+ )
+ );
+ console.log('Done with partial GC');
console.log(`Took ${(Date.now() - start) / 1000} seconds`);
} else {
let i = 0;
@@ -123,15 +137,15 @@ async function GarbageCollect(full: boolean = true) {
console.log(`${deleted} documents deleted`);
await Search.deleteDocuments(toDelete);
- console.log("Cleared search documents");
+ console.log('Cleared search documents');
- const folder = "./src/server/public/files/";
+ const folder = './src/server/public/files/';
fs.readdir(folder, (_, fileList) => {
const filesToDelete = fileList.filter(file => {
const ext = path.extname(file);
let base = path.basename(file, ext);
const existsInDb = (base in files || (base = base.substring(0, base.length - 2)) in files) && files[base].includes(ext);
- return file !== ".gitignore" && !existsInDb;
+ return file !== '.gitignore' && !existsInDb;
});
console.log(`Deleting ${filesToDelete.length} files`);
filesToDelete.forEach(file => {
diff --git a/src/server/MemoryDatabase.ts b/src/server/MemoryDatabase.ts
index b74332bf5..1432d91c4 100644
--- a/src/server/MemoryDatabase.ts
+++ b/src/server/MemoryDatabase.ts
@@ -3,16 +3,15 @@ import { DocumentsCollection, IDatabase } from './IDatabase';
import { Transferable } from './Message';
export class MemoryDatabase implements IDatabase {
-
private db: { [collectionName: string]: { [id: string]: any } } = {};
private getCollection(collectionName: string) {
const collection = this.db[collectionName];
if (collection) {
return collection;
- } else {
- return this.db[collectionName] = {};
}
+ this.db[collectionName] = {};
+ return {};
}
public getCollectionNames() {
@@ -21,15 +20,15 @@ export class MemoryDatabase implements IDatabase {
public update(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateResult) => void, _upsert?: boolean, collectionName = DocumentsCollection): Promise<void> {
const collection = this.getCollection(collectionName);
- const set = "$set";
+ const set = '$set';
if (set in value) {
let currentVal = collection[id] ?? (collection[id] = {});
const val = value[set];
for (const key in val) {
- const keys = key.split(".");
+ const keys = key.split('.');
for (let i = 0; i < keys.length - 1; i++) {
const k = keys[i];
- if (typeof currentVal[k] === "object") {
+ if (typeof currentVal[k] === 'object') {
currentVal = currentVal[k];
} else {
currentVal[k] = {};
@@ -45,7 +44,7 @@ export class MemoryDatabase implements IDatabase {
return Promise.resolve(undefined);
}
- public updateMany(query: any, update: any, collectionName = DocumentsCollection): Promise<mongodb.UpdateResult> {
+ public updateMany(/* query: any, update: any, collectionName = DocumentsCollection */): Promise<mongodb.UpdateResult> {
throw new Error("Can't updateMany a MemoryDatabase");
}
@@ -54,7 +53,9 @@ export class MemoryDatabase implements IDatabase {
}
public delete(query: any, collectionName?: string): Promise<mongodb.DeleteResult>;
+ // eslint-disable-next-line no-dupe-class-members
public delete(id: string, collectionName?: string): Promise<mongodb.DeleteResult>;
+ // eslint-disable-next-line no-dupe-class-members
public delete(id: any, collectionName = DocumentsCollection): Promise<mongodb.DeleteResult> {
const i = id.id ?? id;
delete this.getCollection(collectionName)[i];
@@ -75,7 +76,7 @@ export class MemoryDatabase implements IDatabase {
}
public insert(value: any, collectionName = DocumentsCollection): Promise<void> {
- const id = value.id;
+ const { id } = value;
this.getCollection(collectionName)[id] = value;
return Promise.resolve();
}
@@ -93,14 +94,18 @@ export class MemoryDatabase implements IDatabase {
const count = Math.min(ids.length, 1000);
const index = ids.length - count;
const fetchIds = ids.splice(index, count).filter(id => !visited.has(id));
- if (!fetchIds.length) {
- continue;
- }
- const docs = await new Promise<{ [key: string]: any }[]>(res => this.getDocuments(fetchIds, res, collectionName));
- for (const doc of docs) {
- const id = doc.id;
- visited.add(id);
- ids.push(...(await fn(doc)));
+ if (fetchIds.length) {
+ // eslint-disable-next-line no-await-in-loop
+ const docs = await new Promise<{ [key: string]: any }[]>(res => {
+ this.getDocuments(fetchIds, res, collectionName);
+ });
+ // eslint-disable-next-line no-restricted-syntax
+ for (const doc of docs) {
+ const { id } = doc;
+ visited.add(id);
+ // eslint-disable-next-line no-await-in-loop
+ ids.push(...(await fn(doc)));
+ }
}
}
}
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 8f0af08bc..03150c841 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -1,22 +1,47 @@
-import { Point } from "../pen-gestures/ndollar";
-import { Utils } from "../Utils";
+import * as uuid from 'uuid';
+import { Point } from '../pen-gestures/ndollar';
+function GenerateDeterministicGuid(seed: string): string {
+ return uuid.v5(seed, uuid.v5.URL);
+}
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
export class Message<T> {
private _name: string;
private _guid: string;
constructor(name: string) {
this._name = name;
- this._guid = Utils.GenerateDeterministicGuid(name);
+ this._guid = GenerateDeterministicGuid(name);
}
- get Name(): string { return this._name; }
- get Message(): string { return this._guid; }
+ get Name(): string {
+ return this._name;
+ }
+ get Message(): string {
+ return this._guid;
+ }
}
export enum Types {
- Number, List, Key, Image, Web, Document, Text, Icon, RichText, DocumentReference,
- Html, Video, Audio, Ink, PDF, Tuple, Boolean, Script, Templates
+ Number,
+ List,
+ Key,
+ Image,
+ Web,
+ Document,
+ Text,
+ Icon,
+ RichText,
+ DocumentReference,
+ Html,
+ Video,
+ Audio,
+ Ink,
+ PDF,
+ Tuple,
+ Boolean,
+ Script,
+ Templates,
}
export interface Transferable {
@@ -26,7 +51,9 @@ export interface Transferable {
}
export enum YoutubeQueryTypes {
- Channels, SearchVideo, VideoDetails
+ Channels,
+ SearchVideo,
+ VideoDetails,
}
export interface YoutubeQueryInput {
@@ -45,7 +72,7 @@ export interface Diff extends Reference {
export interface GestureContent {
readonly points: Array<Point>;
- readonly bounds: { right: number, left: number, bottom: number, top: number, width: number, height: number };
+ readonly bounds: { right: number; left: number; bottom: number; top: number; width: number; height: number };
readonly width?: string;
readonly color?: string;
}
@@ -73,27 +100,27 @@ export interface RoomMessage {
}
export namespace MessageStore {
- export const Foo = new Message<string>("Foo");
- export const Bar = new Message<string>("Bar");
- export const SetField = new Message<Transferable>("Set Field"); // send Transferable (no reply)
- export const GetField = new Message<string>("Get Field"); // send string 'id' get Transferable back
- export const GetFields = new Message<string[]>("Get Fields"); // send string[] of 'id' get Transferable[] back
- export const GetDocument = new Message<string>("Get Document");
- export const DeleteAll = new Message<any>("Delete All");
- export const ConnectionTerminated = new Message<string>("Connection Terminated");
-
- export const GesturePoints = new Message<GestureContent>("Gesture Points");
- export const MobileInkOverlayTrigger = new Message<MobileInkOverlayContent>("Trigger Mobile Ink Overlay");
- export const UpdateMobileInkOverlayPosition = new Message<UpdateMobileInkOverlayPositionContent>("Update Mobile Ink Overlay Position");
- export const MobileDocumentUpload = new Message<MobileDocumentUploadContent>("Upload Document From Mobile");
-
- export const GetRefField = new Message<string>("Get Ref Field");
- export const GetRefFields = new Message<string[]>("Get Ref Fields");
- export const UpdateField = new Message<Diff>("Update Ref Field");
- export const CreateField = new Message<Reference>("Create Ref Field");
- export const YoutubeApiQuery = new Message<YoutubeQueryInput>("Youtube Api Query");
- export const DeleteField = new Message<string>("Delete field");
- export const DeleteFields = new Message<string[]>("Delete fields");
-
- export const UpdateStats = new Message<string>("updatestats");
+ export const Foo = new Message<string>('Foo');
+ export const Bar = new Message<string>('Bar');
+ export const SetField = new Message<Transferable>('Set Field'); // send Transferable (no reply)
+ export const GetField = new Message<string>('Get Field'); // send string 'id' get Transferable back
+ export const GetFields = new Message<string[]>('Get Fields'); // send string[] of 'id' get Transferable[] back
+ export const GetDocument = new Message<string>('Get Document');
+ export const DeleteAll = new Message<any>('Delete All');
+ export const ConnectionTerminated = new Message<string>('Connection Terminated');
+
+ export const GesturePoints = new Message<GestureContent>('Gesture Points');
+ export const MobileInkOverlayTrigger = new Message<MobileInkOverlayContent>('Trigger Mobile Ink Overlay');
+ export const UpdateMobileInkOverlayPosition = new Message<UpdateMobileInkOverlayPositionContent>('Update Mobile Ink Overlay Position');
+ export const MobileDocumentUpload = new Message<MobileDocumentUploadContent>('Upload Document From Mobile');
+
+ export const GetRefField = new Message<string>('Get Ref Field');
+ export const GetRefFields = new Message<string[]>('Get Ref Fields');
+ export const UpdateField = new Message<Diff>('Update Ref Field');
+ export const CreateField = new Message<Reference>('Create Ref Field');
+ export const YoutubeApiQuery = new Message<YoutubeQueryInput>('Youtube Api Query');
+ export const DeleteField = new Message<string>('Delete field');
+ export const DeleteFields = new Message<string[]>('Delete fields');
+
+ export const UpdateStats = new Message<string>('updatestats');
}
diff --git a/src/server/PdfTypes.ts b/src/server/PdfTypes.ts
index e87f08e1d..fb435a677 100644
--- a/src/server/PdfTypes.ts
+++ b/src/server/PdfTypes.ts
@@ -1,21 +1,19 @@
-export interface ParsedPDF {
- numpages: number;
- numrender: number;
- info: PDFInfo;
- metadata: PDFMetadata;
- version: string; //https://mozilla.github.io/pdf.js/getting_started/
- text: string;
-}
-
export interface PDFInfo {
PDFFormatVersion: string;
IsAcroFormPresent: boolean;
IsXFAPresent: boolean;
[key: string]: any;
}
-
export interface PDFMetadata {
parse(): void;
get(name: string): string;
has(name: string): boolean;
-} \ No newline at end of file
+}
+export interface ParsedPDF {
+ numpages: number;
+ numrender: number;
+ info: PDFInfo;
+ metadata: PDFMetadata;
+ version: string; // https://mozilla.github.io/pdf.js/getting_started/
+ text: string;
+}
diff --git a/src/server/ProcessFactory.ts b/src/server/ProcessFactory.ts
index f69eda4c3..3791b0e1e 100644
--- a/src/server/ProcessFactory.ts
+++ b/src/server/ProcessFactory.ts
@@ -1,44 +1,42 @@
-import { ChildProcess, spawn, StdioOptions } from "child_process";
-import { existsSync, mkdirSync } from "fs";
-import { Stream } from "stream";
+import { ChildProcess, spawn, StdioOptions } from 'child_process';
+import { existsSync, mkdirSync } from 'fs';
+import { rimraf } from 'rimraf';
+import { Stream } from 'stream';
import { fileDescriptorFromStream, pathFromRoot } from './ActionUtilities';
-import { rimraf } from "rimraf";
-
-export namespace ProcessFactory {
-
- export type Sink = "pipe" | "ipc" | "ignore" | "inherit" | Stream | number | null | undefined;
-
- export async function createWorker(command: string, args?: readonly string[], stdio?: StdioOptions | "logfile", detached = true): Promise<ChildProcess> {
- if (stdio === "logfile") {
- const log_fd = await Logger.create(command, args);
- stdio = ["ignore", log_fd, log_fd];
- }
- const child = spawn(command, args ?? [], { detached, stdio });
- child.unref();
- return child;
- }
-
-}
export namespace Logger {
-
- const logPath = pathFromRoot("./logs");
+ const logPath = pathFromRoot('./logs');
export async function initialize() {
if (existsSync(logPath)) {
if (!process.env.SPAWNED) {
- await new Promise<any>(resolve => rimraf(logPath).then(resolve));
+ await new Promise<any>(resolve => {
+ rimraf(logPath).then(resolve);
+ });
}
}
mkdirSync(logPath);
}
- export async function create(command: string, args?: readonly string[]): Promise<number> {
- return fileDescriptorFromStream(generate_log_path(command, args));
+ function generateLogPath(command: string, args?: readonly string[]) {
+ return pathFromRoot(`./logs/${command}-${args?.length}-${new Date().toUTCString()}.log`);
}
- function generate_log_path(command: string, args?: readonly string[]) {
- return pathFromRoot(`./logs/${command}-${args?.length}-${new Date().toUTCString()}.log`);
+ export async function create(command: string, args?: readonly string[]): Promise<number> {
+ return fileDescriptorFromStream(generateLogPath(command, args));
}
+}
+export namespace ProcessFactory {
+ export type Sink = 'pipe' | 'ipc' | 'ignore' | 'inherit' | Stream | number | null | undefined;
-} \ No newline at end of file
+ export async function createWorker(command: string, args?: readonly string[], stdio?: StdioOptions | 'logfile', detached = true): Promise<ChildProcess> {
+ if (stdio === 'logfile') {
+ const logFd = await Logger.create(command, args);
+ // eslint-disable-next-line no-param-reassign
+ stdio = ['ignore', logFd, logFd];
+ }
+ const child = spawn(command, args ?? [], { detached, stdio });
+ child.unref();
+ return child;
+ }
+}
diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts
index 540bca776..d8e0455f6 100644
--- a/src/server/RouteManager.ts
+++ b/src/server/RouteManager.ts
@@ -1,9 +1,9 @@
import { cyan, green, red } from 'colors';
import { Express, Request, Response } from 'express';
-import { AdminPriviliges } from '.';
import { Utils } from '../Utils';
-import { DashUserModel } from './authentication/DashUserModel';
import RouteSubscriber from './RouteSubscriber';
+import { AdminPrivileges } from './SocketData';
+import { DashUserModel } from './authentication/DashUserModel';
export enum Method {
GET,
@@ -21,6 +21,34 @@ export type SecureHandler = (core: AuthorizedCore) => any | Promise<any>;
export type PublicHandler = (core: CoreArguments) => any | Promise<any>;
export type ErrorHandler = (core: CoreArguments & { error: any }) => any | Promise<any>;
+export const STATUS = {
+ OK: 200,
+ BAD_REQUEST: 400,
+ EXECUTION_ERROR: 500,
+ PERMISSION_DENIED: 403,
+};
+
+export function _error(res: Response, message: string, error?: any) {
+ console.error(message, error);
+ res.statusMessage = message;
+ res.status(STATUS.EXECUTION_ERROR).send(error);
+}
+
+export function _success(res: Response, body: any) {
+ res.status(STATUS.OK).send(body);
+}
+
+export function _invalid(res: Response, message: string) {
+ res.statusMessage = message;
+ res.status(STATUS.BAD_REQUEST).send();
+}
+
+export function _permissionDenied(res: Response, message?: string) {
+ if (message) {
+ res.statusMessage = message;
+ }
+ res.status(STATUS.PERMISSION_DENIED).send(`Permission Denied! ${message}`);
+}
export interface RouteInitializer {
method: Method;
subscription: string | RouteSubscriber | (string | RouteSubscriber)[];
@@ -71,7 +99,7 @@ export default class RouteManager {
console.log('please remove all duplicate routes before continuing');
}
if (malformedCount) {
- console.log(`please ensure all routes adhere to ^\/$|^\/[A-Za-z]+(\/\:[A-Za-z?_]+)*$`);
+ console.log(`please ensure all routes adhere to ^/$|^/[A-Za-z]+(/:[A-Za-z?_]+)*$`);
}
process.exit(1);
} else {
@@ -94,7 +122,7 @@ export default class RouteManager {
typeof initializer.subscription === 'string' && RouteManager.routes.push(initializer.subscription);
initializer.subscription instanceof RouteSubscriber && RouteManager.routes.push(initializer.subscription.root);
initializer.subscription instanceof Array &&
- initializer.subscription.map(sub => {
+ initializer.subscription.forEach(sub => {
typeof sub === 'string' && RouteManager.routes.push(sub);
sub instanceof RouteSubscriber && RouteManager.routes.push(sub.root);
});
@@ -120,23 +148,23 @@ export default class RouteManager {
};
if (user) {
if (requireAdmin && isRelease && process.env.PASSWORD) {
- if (AdminPriviliges.get(user.id)) {
- AdminPriviliges.delete(user.id);
+ if (AdminPrivileges.get(user.id)) {
+ AdminPrivileges.delete(user.id);
} else {
- return res.redirect(`/admin/${req.originalUrl.substring(1).replace('/', ':')}`);
+ res.redirect(`/admin/${req.originalUrl.substring(1).replace('/', ':')}`);
+ return;
}
}
await tryExecute(secureHandler, { ...core, user });
- } else {
- //req.session!.target = target;
- if (publicHandler) {
- await tryExecute(publicHandler, core);
- if (!res.headersSent) {
- // res.redirect("/login");
- }
- } else {
- res.redirect('/login');
+ }
+ // req.session!.target = target;
+ else if (publicHandler) {
+ await tryExecute(publicHandler, core);
+ if (!res.headersSent) {
+ // res.redirect("/login");
}
+ } else {
+ res.redirect('/login');
}
setTimeout(() => {
if (!res.headersSent) {
@@ -153,7 +181,7 @@ export default class RouteManager {
} else {
route = subscriber.build;
}
- if (!/^\/$|^\/[A-Za-z\*]+(\/\:[A-Za-z?_\*]+)*$/g.test(route)) {
+ if (!/^\/$|^\/[A-Za-z*]+(\/:[A-Za-z?_*]+)*$/g.test(route)) {
this.failedRegistrations.push({
reason: RegistrationError.Malformed,
route,
@@ -180,6 +208,7 @@ export default class RouteManager {
case Method.POST:
this.server.post(route, supervised);
break;
+ default:
}
}
};
@@ -190,32 +219,3 @@ export default class RouteManager {
}
};
}
-
-export const STATUS = {
- OK: 200,
- BAD_REQUEST: 400,
- EXECUTION_ERROR: 500,
- PERMISSION_DENIED: 403,
-};
-
-export function _error(res: Response, message: string, error?: any) {
- console.error(message, error);
- res.statusMessage = message;
- res.status(STATUS.EXECUTION_ERROR).send(error);
-}
-
-export function _success(res: Response, body: any) {
- res.status(STATUS.OK).send(body);
-}
-
-export function _invalid(res: Response, message: string) {
- res.statusMessage = message;
- res.status(STATUS.BAD_REQUEST).send();
-}
-
-export function _permission_denied(res: Response, message?: string) {
- if (message) {
- res.statusMessage = message;
- }
- res.status(STATUS.PERMISSION_DENIED).send(`Permission Denied! ${message}`);
-}
diff --git a/src/server/RouteSubscriber.ts b/src/server/RouteSubscriber.ts
index a1cf7c1c4..b923805a8 100644
--- a/src/server/RouteSubscriber.ts
+++ b/src/server/RouteSubscriber.ts
@@ -18,9 +18,8 @@ export default class RouteSubscriber {
public get build() {
let output = this._root;
if (this.requestParameters.length) {
- output = `${output}/:${this.requestParameters.join("/:")}`;
+ output = `${output}/:${this.requestParameters.join('/:')}`;
}
return output;
}
-
-} \ No newline at end of file
+}
diff --git a/src/server/Search.ts b/src/server/Search.ts
index 25bd8badf..b21ee853a 100644
--- a/src/server/Search.ts
+++ b/src/server/Search.ts
@@ -4,32 +4,33 @@ import * as rp from 'request-promise';
const pathTo = (relative: string) => `http://localhost:8983/solr/dash/${relative}`;
export namespace Search {
-
export async function updateDocument(document: any) {
try {
- return await rp.post(pathTo("update"), {
+ return await rp.post(pathTo('update'), {
headers: { 'content-type': 'application/json' },
- body: JSON.stringify([document])
+ body: JSON.stringify([document]),
});
} catch (e) {
// console.warn("Search error: " + e + document);
}
+ return undefined;
}
export async function updateDocuments(documents: any[]) {
try {
- return await rp.post(pathTo("update"), {
+ return await rp.post(pathTo('update'), {
headers: { 'content-type': 'application/json' },
- body: JSON.stringify(documents)
+ body: JSON.stringify(documents),
});
} catch (e) {
// console.warn("Search error: ", e, documents);
}
+ return undefined;
}
export async function search(query: any) {
try {
- const output = await rp.get(pathTo("select"), { qs: query });
+ const output = await rp.get(pathTo('select'), { qs: query });
const searchResults = JSON.parse(output);
const { docs, numFound } = searchResults.response;
const ids = docs.map((field: any) => field.id);
@@ -41,16 +42,16 @@ export namespace Search {
export async function clear() {
try {
- await rp.post(pathTo("update"), {
+ await rp.post(pathTo('update'), {
body: {
delete: {
- query: "*:*"
- }
+ query: '*:*',
+ },
},
- json: true
+ json: true,
});
} catch (e: any) {
- console.log(red("Unable to clear search..."));
+ console.log(red('Unable to clear search...'));
console.log(red(e.message));
}
}
@@ -63,16 +64,18 @@ export namespace Search {
const count = Math.min(docs.length - index, nToDelete);
const deleteIds = docs.slice(index, index + count);
index += count;
- promises.push(rp.post(pathTo("update"), {
- body: {
- delete: {
- query: deleteIds.map(id => `id:"${id}"`).join(" ")
- }
- },
- json: true
- }));
+ promises.push(
+ rp.post(pathTo('update'), {
+ body: {
+ delete: {
+ query: deleteIds.map(id => `id:"${id}"`).join(' '),
+ },
+ },
+ json: true,
+ })
+ );
}
return Promise.all(promises);
}
-} \ No newline at end of file
+}
diff --git a/src/server/SharedMediaTypes.ts b/src/server/SharedMediaTypes.ts
index 7db1c2dae..8ae13454e 100644
--- a/src/server/SharedMediaTypes.ts
+++ b/src/server/SharedMediaTypes.ts
@@ -13,6 +13,11 @@ export namespace AcceptableMedia {
export const audioFormats = ['.wav', '.mp3', '.mpeg', '.flac', '.au', '.aiff', '.m4a', '.webm'];
}
+export enum AudioAnnoState {
+ stopped = 'stopped',
+ playing = 'playing',
+}
+
export namespace Upload {
export function isImageInformation(uploadResponse: Upload.FileInformation): uploadResponse is Upload.ImageInformation {
return 'nativeWidth' in uploadResponse;
@@ -22,24 +27,17 @@ export namespace Upload {
return 'duration' in uploadResponse;
}
+ export interface AccessPathInfo {
+ [suffix: string]: { client: string; server: string };
+ }
export interface FileInformation {
accessPaths: AccessPathInfo;
rawText?: string;
duration?: number;
}
-
- export type FileResponse<T extends FileInformation = FileInformation> = { source: File; result: T | Error };
-
- export type ImageInformation = FileInformation & InspectionResults;
-
- export type VideoInformation = FileInformation & VideoResults;
-
- export interface AccessPathInfo {
- [suffix: string]: { client: string; server: string };
- }
-
- export interface VideoResults {
- duration: number;
+ export interface EnrichedExifData {
+ data: ExifData & ExifData['gps'];
+ error?: string;
}
export interface InspectionResults {
source: string;
@@ -51,9 +49,13 @@ export namespace Upload {
nativeHeight: number;
filename?: string;
}
-
- export interface EnrichedExifData {
- data: ExifData & ExifData['gps'];
- error?: string;
+ export interface VideoResults {
+ duration: number;
}
+
+ export type FileResponse<T extends FileInformation = FileInformation> = { source: File; result: T | Error };
+
+ export type ImageInformation = FileInformation & InspectionResults;
+
+ export type VideoInformation = FileInformation & VideoResults;
}
diff --git a/src/server/SocketData.ts b/src/server/SocketData.ts
new file mode 100644
index 000000000..e857996e5
--- /dev/null
+++ b/src/server/SocketData.ts
@@ -0,0 +1,35 @@
+import { Socket } from 'socket.io';
+import * as path from 'path';
+
+export const timeMap: { [id: string]: number } = {};
+export const userOperations = new Map<string, number>();
+export const socketMap = new Map<Socket, string>();
+
+export const publicDirectory = path.resolve(__dirname, 'public');
+export const filesDirectory = path.resolve(publicDirectory, 'files');
+
+export const AdminPrivileges: Map<string, boolean> = new Map();
+
+export const resolvedPorts: { server: number; socket: number } = { server: 1050, socket: 4321 };
+
+export enum Directory {
+ parsed_files = 'parsed_files',
+ images = 'images',
+ videos = 'videos',
+ pdfs = 'pdfs',
+ text = 'text',
+ audio = 'audio',
+ csv = 'csv',
+}
+
+export function serverPathToFile(directory: Directory, filename: string) {
+ return path.normalize(`${filesDirectory}/${directory}/${filename}`);
+}
+
+export function pathToDirectory(directory: Directory) {
+ return path.normalize(`${filesDirectory}/${directory}`);
+}
+
+export function clientPathToFile(directory: Directory, filename: string) {
+ return `/files/${directory}/${filename}`;
+}
diff --git a/src/server/apis/google/CredentialsLoader.ts b/src/server/apis/google/CredentialsLoader.ts
index ef1f9a91e..a6e0644c3 100644
--- a/src/server/apis/google/CredentialsLoader.ts
+++ b/src/server/apis/google/CredentialsLoader.ts
@@ -1,10 +1,9 @@
-import { readFile, readFileSync } from "fs";
-import { pathFromRoot } from "../../ActionUtilities";
-import { SecureContextOptions } from "tls";
-import { blue, red } from "colors";
+import { readFile, readFileSync } from 'fs';
+import { SecureContextOptions } from 'tls';
+import { blue, red } from 'colors';
+import { pathFromRoot } from '../../ActionUtilities';
export namespace GoogleCredentialsLoader {
-
export interface InstalledCredentials {
client_id: string;
project_id: string;
@@ -19,7 +18,8 @@ export namespace GoogleCredentialsLoader {
export async function loadCredentials() {
ProjectCredentials = await new Promise<InstalledCredentials>(resolve => {
- readFile(__dirname + '/google_project_credentials.json', function processClientSecrets(err, content) {
+ // eslint-disable-next-line no-path-concat
+ readFile(__dirname + '/google_project_credentials.json', (err, content) => {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
@@ -28,18 +28,16 @@ export namespace GoogleCredentialsLoader {
});
});
}
-
}
export namespace SSL {
-
export let Credentials: SecureContextOptions = {};
export let Loaded = false;
const suffixes = {
- privateKey: ".key",
- certificate: ".crt",
- caBundle: "-ca.crt"
+ privateKey: '.key',
+ certificate: '.crt',
+ caBundle: '-ca.crt',
};
export async function loadCredentials() {
@@ -57,11 +55,10 @@ export namespace SSL {
}
export function exit() {
- console.log(red("Running this server in release mode requires the following SSL credentials in the project root:"));
- const serverName = process.env.serverName ? process.env.serverName : "{process.env.serverName}";
+ console.log(red('Running this server in release mode requires the following SSL credentials in the project root:'));
+ const serverName = process.env.serverName ? process.env.serverName : '{process.env.serverName}';
Object.values(suffixes).forEach(suffix => console.log(blue(`${serverName}${suffix}`)));
- console.log(red("Please ensure these files exist and restart, or run this in development mode."));
+ console.log(red('Please ensure these files exist and restart, or run this in development mode.'));
process.exit(0);
}
-
}
diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts
index 3940b7a3d..d3acc968b 100644
--- a/src/server/apis/google/GoogleApiServerUtils.ts
+++ b/src/server/apis/google/GoogleApiServerUtils.ts
@@ -1,9 +1,9 @@
-import { google } from 'googleapis';
-import { OAuth2Client, Credentials, OAuth2ClientOptions } from 'google-auth-library';
-import { Opt } from '../../../fields/Doc';
import { GaxiosResponse } from 'gaxios';
-import * as request from 'request-promise';
+import { Credentials, OAuth2Client, OAuth2ClientOptions } from 'google-auth-library';
+import { google } from 'googleapis';
import * as qs from 'query-string';
+import * as request from 'request-promise';
+import { Opt } from '../../../fields/Doc';
import { Database } from '../../database';
import { GoogleCredentialsLoader } from './CredentialsLoader';
@@ -57,12 +57,12 @@ export namespace GoogleApiServerUtils {
* global, intentionally unauthenticated worker OAuth2 client instance.
*/
export function processProjectCredentials(): void {
- const { client_secret, client_id, redirect_uris } = GoogleCredentialsLoader.ProjectCredentials;
+ const { client_secret: clientSecret, client_id: clientId, redirect_uris: redirectUris } = GoogleCredentialsLoader.ProjectCredentials;
// initialize the global authorization client
oAuthOptions = {
- clientId: client_id,
- clientSecret: client_secret,
- redirectUri: redirect_uris[0],
+ clientId,
+ clientSecret,
+ redirectUri: redirectUris[0],
};
worker = generateClient();
}
diff --git a/src/server/apis/google/SharedTypes.ts b/src/server/apis/google/SharedTypes.ts
index 9ad6130b6..f5e0e2e2b 100644
--- a/src/server/apis/google/SharedTypes.ts
+++ b/src/server/apis/google/SharedTypes.ts
@@ -1,9 +1,3 @@
-export interface NewMediaItemResult {
- uploadToken: string;
- status: { code: number, message: string };
- mediaItem: MediaItem;
-}
-
export interface MediaItem {
id: string;
description: string;
@@ -17,5 +11,10 @@ export interface MediaItem {
};
filename: string;
}
+export interface NewMediaItemResult {
+ uploadToken: string;
+ status: { code: number; message: string };
+ mediaItem: MediaItem;
+}
-export type MediaItemCreationResult = { newMediaItemResults: NewMediaItemResult[] }; \ No newline at end of file
+export type MediaItemCreationResult = { newMediaItemResults: NewMediaItemResult[] };
diff --git a/src/server/apis/youtube/youtubeApiSample.d.ts b/src/server/apis/youtube/youtubeApiSample.d.ts
index 427f54608..97c3f0b54 100644
--- a/src/server/apis/youtube/youtubeApiSample.d.ts
+++ b/src/server/apis/youtube/youtubeApiSample.d.ts
@@ -1,2 +1,2 @@
declare const YoutubeApi: any;
-export = YoutubeApi; \ No newline at end of file
+export = YoutubeApi;
diff --git a/src/server/authentication/AuthenticationManager.ts b/src/server/authentication/AuthenticationManager.ts
index b1b84c300..0cc1553c0 100644
--- a/src/server/authentication/AuthenticationManager.ts
+++ b/src/server/authentication/AuthenticationManager.ts
@@ -1,21 +1,21 @@
-import { default as User, DashUserModel, initializeGuest } from './DashUserModel';
-import { Request, Response, NextFunction } from 'express';
-import * as passport from 'passport';
-import { IVerifyOptions } from 'passport-local';
-import './Passport';
import * as async from 'async';
-import * as nodemailer from 'nodemailer';
import * as c from 'crypto';
-import { emptyFunction, Utils } from '../../Utils';
-import { MailOptions } from 'nodemailer/lib/stream-transport';
+import { NextFunction, Request, Response } from 'express';
import { check, validationResult } from 'express-validator';
+import * as nodemailer from 'nodemailer';
+import { MailOptions } from 'nodemailer/lib/stream-transport';
+import * as passport from 'passport';
+import { Utils } from '../../Utils';
+import User, { DashUserModel, initializeGuest } from './DashUserModel';
+import './Passport';
+// import { IVerifyOptions } from 'passport-local';
/**
* GET /signup
* Directs user to the signup page
* modeled by signup.pug in views
*/
-export let getSignup = (req: Request, res: Response) => {
+export const getSignup = (req: Request, res: Response) => {
if (req.user) {
return res.redirect('/home');
}
@@ -23,13 +23,23 @@ export let getSignup = (req: Request, res: Response) => {
title: 'Sign Up',
user: req.user,
});
+ return undefined;
+};
+
+const tryRedirectToTarget = (req: Request, res: Response) => {
+ const target = (req.session as any)?.target;
+ if (req.session && target) {
+ res.redirect(target);
+ } else {
+ res.redirect('/home');
+ }
};
/**
* POST /signup
* Create a new local account.
*/
-export let postSignup = (req: Request, res: Response, next: NextFunction) => {
+export const postSignup = (req: Request, res: Response, next: NextFunction) => {
const email = req.body.email as String;
check('email', 'Email is not valid').isEmail().run(req);
check('password', 'Password must be at least 4 characters long').isLength({ min: 4 }).run(req);
@@ -42,7 +52,7 @@ export let postSignup = (req: Request, res: Response, next: NextFunction) => {
return res.redirect('/signup');
}
- const password = req.body.password;
+ const { password } = req.body;
const model = {
email,
@@ -56,7 +66,7 @@ export let postSignup = (req: Request, res: Response, next: NextFunction) => {
const user = new User(model);
User.findOne({ email })
- .then(existingUser => {
+ .then((existingUser: any) => {
if (existingUser) {
return res.redirect('/login');
}
@@ -65,35 +75,29 @@ export let postSignup = (req: Request, res: Response, next: NextFunction) => {
req.logIn(user, err => {
if (err) return next(err);
tryRedirectToTarget(req, res);
+ return undefined;
});
})
- .catch(err => next(err));
+ .catch((err: any) => next(err));
+ return undefined;
})
- .catch(err => next(err));
+ .catch((err: any) => next(err));
+ return undefined;
};
-
-const tryRedirectToTarget = (req: Request, res: Response) => {
- const target = (req.session as any)?.target;
- if (req.session && target) {
- res.redirect(target);
- } else {
- res.redirect('/home');
- }
-};
-
/**
* GET /login
* Login page.
*/
-export let getLogin = (req: Request, res: Response) => {
+export const getLogin = (req: Request, res: Response) => {
if (req.user) {
- //req.session.target = undefined;
+ // req.session.target = undefined;
return res.redirect('/home');
}
res.render('login.pug', {
title: 'Log In',
user: req.user,
});
+ return undefined;
};
/**
@@ -101,11 +105,11 @@ export let getLogin = (req: Request, res: Response) => {
* Sign in using email and password.
* On failure, redirect to signup page
*/
-export let postLogin = (req: Request, res: Response, next: NextFunction) => {
+export const postLogin = (req: Request, res: Response, next: NextFunction) => {
if (req.body.email === '') {
User.findOne({ email: 'guest' })
- .then(user => !user && initializeGuest())
- .catch(err => err);
+ .then((user: any) => !user && initializeGuest())
+ .catch((err: any) => err);
req.body.email = 'guest';
req.body.password = 'guest';
} else {
@@ -115,27 +119,25 @@ export let postLogin = (req: Request, res: Response, next: NextFunction) => {
}
if (validationResult(req).array().length) {
- req.flash('errors', 'Unable to login at this time. Please try again.');
+ // req.flash('errors', 'Unable to login at this time. Please try again.');
return res.redirect('/signup');
}
- const callback = (err: Error, user: DashUserModel, _info: IVerifyOptions) => {
+ const callback = (err: Error, user: DashUserModel /* , _info: IVerifyOptions */) => {
if (err) {
next(err);
- return;
- }
- if (!user) {
+ } else if (!user) {
return res.redirect('/signup');
- }
- req.logIn(user, err => {
- if (err) {
- next(err);
- return;
- }
- tryRedirectToTarget(req, res);
- });
+ } else
+ req.logIn(user, loginErr => {
+ if (loginErr) {
+ next(loginErr);
+ } else tryRedirectToTarget(req, res);
+ });
+ return undefined;
};
setTimeout(() => passport.authenticate('local', callback)(req, res, next), 500);
+ return undefined;
};
/**
@@ -143,35 +145,33 @@ export let postLogin = (req: Request, res: Response, next: NextFunction) => {
* Invokes the logout function on the request
* and destroys the user's current session.
*/
-export let getLogout = (req: Request, res: Response) => {
+export const getLogout = (req: Request, res: Response) => {
req.logout(err => {
if (err) console.log(err);
else res.redirect('/login');
});
};
-export let getForgot = function (req: Request, res: Response) {
+export const getForgot = function (req: Request, res: Response) {
res.render('forgot.pug', {
title: 'Recover Password',
user: req.user,
});
};
-export let postForgot = function (req: Request, res: Response, next: NextFunction) {
- const email = req.body.email;
+export const postForgot = function (req: Request, res: Response, next: NextFunction) {
+ const { email } = req.body;
async.waterfall(
[
function (done: any) {
- c.randomBytes(20, function (err: any, buffer: Buffer) {
+ c.randomBytes(20, (err: any, buffer: Buffer) => {
if (err) {
done(null);
- return;
- }
- done(null, buffer.toString('hex'));
+ } else done(null, buffer.toString('hex'));
});
},
function (token: string, done: any) {
- User.findOne({ email }).then(user => {
+ User.findOne({ email }).then((user: any) => {
if (!user) {
// NO ACCOUNT WITH SUBMITTED EMAIL
res.redirect('/forgotPassword');
@@ -204,37 +204,39 @@ export let postForgot = function (req: Request, res: Response, next: NextFunctio
'\n\n' +
'If you did not request this, please ignore this email and your password will remain unchanged.\n',
} as MailOptions;
- smtpTransport.sendMail(mailOptions, function (err: Error | null) {
+ smtpTransport.sendMail(mailOptions, (err: Error | null) => {
// req.flash('info', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
done(null, err, 'done');
});
},
],
- function (err) {
+ err => {
if (err) return next(err);
res.redirect('/forgotPassword');
+ return undefined;
}
);
};
-export let getReset = function (req: Request, res: Response) {
+export const getReset = function (req: Request, res: Response) {
User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } })
- .then(user => {
+ .then((user: any) => {
if (!user) return res.redirect('/forgotPassword');
res.render('reset.pug', {
title: 'Reset Password',
user: req.user,
});
+ return undefined;
})
- .catch(err => res.redirect('/forgotPassword'));
+ .catch(() => res.redirect('/forgotPassword'));
};
-export let postReset = function (req: Request, res: Response) {
+export const postReset = function (req: Request, res: Response) {
async.waterfall(
[
function (done: any) {
User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } })
- .then(user => {
+ .then((user: any) => {
if (!user) return res.redirect('back');
check('password', 'Password must be at least 4 characters long').isLength({ min: 4 }).run(req);
@@ -251,10 +253,11 @@ export let postReset = function (req: Request, res: Response) {
() => (req as any).logIn(user),
(err: any) => err
)
- .catch(err => res.redirect('/login'));
+ .catch(() => res.redirect('/login'));
done(null, user);
+ return undefined;
})
- .catch(err => res.redirect('back'));
+ .catch(() => res.redirect('back'));
},
function (user: DashUserModel, done: any) {
const smtpTransport = nodemailer.createTransport({
@@ -268,13 +271,13 @@ export let postReset = function (req: Request, res: Response) {
to: user.email,
from: 'browndashptc@gmail.com',
subject: 'Your password has been changed',
- text: 'Hello,\n\n' + 'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n',
+ text: 'Hello,\n\nThis is a confirmation that the password for your account ' + user.email + ' has just been changed.\n',
} as MailOptions;
smtpTransport.sendMail(mailOptions, err => done(null, err));
},
],
- function (err) {
+ () => {
res.redirect('/login');
}
);
diff --git a/src/server/authentication/DashUserModel.ts b/src/server/authentication/DashUserModel.ts
index dbb7a79ed..bfa6d7bdb 100644
--- a/src/server/authentication/DashUserModel.ts
+++ b/src/server/authentication/DashUserModel.ts
@@ -1,9 +1,8 @@
-//@ts-ignore
import * as bcrypt from 'bcrypt-nodejs';
-//@ts-ignore
import * as mongoose from 'mongoose';
import { Utils } from '../../Utils';
+type comparePasswordFunction = (candidatePassword: string, cb: (err: any, isMatch: any) => void) => void;
export type DashUserModel = mongoose.Document & {
email: String;
password: string;
@@ -26,8 +25,6 @@ export type DashUserModel = mongoose.Document & {
comparePassword: comparePasswordFunction;
};
-type comparePasswordFunction = (candidatePassword: string, cb: (err: any, isMatch: any) => void) => void;
-
export type AuthToken = {
accessToken: string;
kind: string;
@@ -64,7 +61,7 @@ const userSchema = new mongoose.Schema(
* Password hash middleware.
*/
userSchema.pre('save', function save(next) {
- const user = this as any as DashUserModel;
+ const user = this;
if (!user.isModified('password')) {
return next();
}
@@ -73,18 +70,21 @@ userSchema.pre('save', function save(next) {
return next(err);
}
bcrypt.hash(
- user.password,
+ user.password ?? '',
salt,
- () => void {},
- (err: mongoose.Error, hash: string) => {
- if (err) {
- return next(err);
+ () => {},
+ (cryptErr: mongoose.Error, hash: string) => {
+ if (cryptErr) {
+ return next(cryptErr);
}
user.password = hash;
next();
+ return undefined;
}
);
+ return undefined;
});
+ return undefined;
});
const comparePassword: comparePasswordFunction = function (this: DashUserModel, candidatePassword, cb) {
@@ -97,7 +97,7 @@ const comparePassword: comparePasswordFunction = function (this: DashUserModel,
userSchema.methods.comparePassword = comparePassword;
-const User = mongoose.model('User', userSchema);
+const User: any = mongoose.model('User', userSchema);
export function initializeGuest() {
new User({
email: 'guest',
diff --git a/src/server/authentication/Passport.ts b/src/server/authentication/Passport.ts
index a9cf6698b..ca9e3058e 100644
--- a/src/server/authentication/Passport.ts
+++ b/src/server/authentication/Passport.ts
@@ -1,6 +1,6 @@
import * as passport from 'passport';
import * as passportLocal from 'passport-local';
-import { DashUserModel, default as User } from './DashUserModel';
+import User, { DashUserModel } from './DashUserModel';
const LocalStrategy = passportLocal.Strategy;
@@ -11,22 +11,25 @@ passport.serializeUser<any, any>((req, user, done) => {
passport.deserializeUser<any, any>((id, done) => {
User.findById(id)
.exec()
- .then(user => done(undefined, user));
+ .then((user: any) => done(undefined, user));
});
// AUTHENTICATE JUST WITH EMAIL AND PASSWORD
passport.use(
new LocalStrategy({ usernameField: 'email', passReqToCallback: true }, (req, email, password, done) => {
User.findOne({ email: email.toLowerCase() })
- .then(user => {
- if (!user) return done(undefined, false, { message: 'Invalid email or password' }); // invalid email
- (user as any as DashUserModel).comparePassword(password, (error: Error, isMatch: boolean) => {
- if (error) return done(error);
- if (!isMatch) return done(undefined, false, { message: 'Invalid email or password' }); // invalid password
- // valid authentication HERE
- return done(undefined, user);
- });
+ .then((user: DashUserModel) => {
+ if (!user) {
+ done(undefined, false, { message: 'Invalid email or password' }); // invalid email
+ } else {
+ user.comparePassword(password, (error: Error, isMatch: boolean) => {
+ if (error) return done(error);
+ if (!isMatch) return done(undefined, false, { message: 'Invalid email or password' }); // invalid password
+ // valid authentication HERE
+ return done(undefined, user);
+ });
+ }
})
- .catch(error => done(error));
+ .catch((error: any) => done(error));
})
);
diff --git a/src/server/database.ts b/src/server/database.ts
index 3a087ce38..ff8584cd7 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -30,7 +30,10 @@ export namespace Database {
export async function tryInitializeConnection() {
try {
const { connection } = mongoose;
- disconnect = async () => new Promise<any>(resolve => connection.close().then(resolve));
+ disconnect = async () =>
+ new Promise<any>(resolve => {
+ connection.close().then(resolve);
+ });
if (connection.readyState === ConnectionStates.disconnected) {
await new Promise<void>((resolve, reject) => {
connection.on('error', reject);
@@ -39,7 +42,7 @@ export namespace Database {
resolve();
});
mongoose.connect(url, {
- //useNewUrlParser: true,
+ // useNewUrlParser: true,
dbName: schema,
// reconnectTries: Number.MAX_VALUE,
// reconnectInterval: 1000,
@@ -54,6 +57,7 @@ export namespace Database {
}
}
+ // eslint-disable-next-line @typescript-eslint/no-shadow
export class Database implements IDatabase {
private MongoClient = mongodb.MongoClient;
private currentWrites: { [id: string]: Promise<void> } = {};
@@ -81,8 +85,8 @@ export namespace Database {
const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
let newProm: Promise<void>;
- const run = (): Promise<void> => {
- return new Promise<void>(resolve => {
+ const run = (): Promise<void> =>
+ new Promise<void>(resolve => {
collection
.updateOne({ _id: id }, value, { upsert })
.then(res => {
@@ -96,13 +100,12 @@ export namespace Database {
console.log('MOngo UPDATE ONE ERROR:', error);
});
});
- };
newProm = prom ? prom.then(run) : run();
this.currentWrites[id] = newProm;
return newProm;
- } else {
- this.onConnect.push(() => this.update(id, value, callback, upsert, collectionName));
}
+ this.onConnect.push(() => this.update(id, value, callback, upsert, collectionName));
+ return undefined;
}
public replace(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateResult<mongodb.Document>) => void, upsert = true, collectionName = DocumentsCollection) {
@@ -110,8 +113,8 @@ export namespace Database {
const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
let newProm: Promise<void>;
- const run = (): Promise<void> => {
- return new Promise<void>(resolve => {
+ const run = (): Promise<void> =>
+ new Promise<void>(resolve => {
collection.replaceOne({ _id: id }, value, { upsert }).then(res => {
if (this.currentWrites[id] === newProm) {
delete this.currentWrites[id];
@@ -120,7 +123,6 @@ export namespace Database {
callback(undefined as any, res as any);
});
});
- };
newProm = prom ? prom.then(run) : run();
this.currentWrites[id] = newProm;
} else {
@@ -132,8 +134,10 @@ export namespace Database {
const cursor = this.db?.listCollections();
const collectionNames: string[] = [];
if (cursor) {
+ // eslint-disable-next-line no-await-in-loop
while (await cursor.hasNext()) {
- const collection: any = await cursor.next();
+ // eslint-disable-next-line no-await-in-loop
+ const collection = await cursor.next();
collection && collectionNames.push(collection.name);
}
}
@@ -141,26 +145,30 @@ export namespace Database {
}
public delete(query: any, collectionName?: string): Promise<mongodb.DeleteResult>;
+ // eslint-disable-next-line no-dupe-class-members
public delete(id: string, collectionName?: string): Promise<mongodb.DeleteResult>;
- public delete(id: any, collectionName = DocumentsCollection) {
+ // eslint-disable-next-line no-dupe-class-members
+ public delete(idIn: any, collectionName = DocumentsCollection) {
+ let id = idIn;
if (typeof id === 'string') {
id = { _id: id };
}
if (this.db) {
- const db = this.db;
- return new Promise(res =>
- db
- .collection(collectionName)
+ const { db } = this;
+ return new Promise(res => {
+ db.collection(collectionName)
.deleteMany(id)
- .then(result => res(result))
- );
- } else {
- return new Promise(res => this.onConnect.push(() => res(this.delete(id, collectionName))));
+ .then(result => res(result));
+ });
}
+ return new Promise(res => {
+ this.onConnect.push(() => res(this.delete(id, collectionName)));
+ });
}
public async dropSchema(...targetSchemas: string[]): Promise<any> {
const executor = async (database: mongodb.Db) => {
+ // eslint-disable-next-line no-use-before-define
const existing = await Instance.getCollectionNames();
let valid: string[];
if (targetSchemas.length) {
@@ -173,12 +181,13 @@ export namespace Database {
};
if (this.db) {
return executor(this.db);
- } else {
- this.onConnect.push(() => this.db && executor(this.db));
}
+ this.onConnect.push(() => this.db && executor(this.db));
+ return undefined;
}
- public async insert(value: any, collectionName = DocumentsCollection) {
+ public async insert(valueIn: any, collectionName = DocumentsCollection) {
+ const value = valueIn;
if (this.db && value !== null) {
if ('id' in value) {
value._id = value.id;
@@ -188,36 +197,36 @@ export namespace Database {
const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
let newProm: Promise<void>;
- const run = (): Promise<void> => {
- return new Promise<void>(resolve => {
+ const run = (): Promise<void> =>
+ new Promise<void>(resolve => {
collection
.insertOne(value)
- .then(res => {
+ .then(() => {
if (this.currentWrites[id] === newProm) {
delete this.currentWrites[id];
}
resolve();
})
- .catch(err => {
- console.log('Mongo INSERT ERROR: ', err);
- });
+ .catch(err => console.log('Mongo INSERT ERROR: ', err));
});
- };
newProm = prom ? prom.then(run) : run();
this.currentWrites[id] = newProm;
return newProm;
- } else if (value !== null) {
+ }
+ if (value !== null) {
this.onConnect.push(() => this.insert(value, collectionName));
}
+ return undefined;
}
public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = DocumentsCollection) {
if (this.db) {
const collection = this.db.collection<DocSchema>(collectionName);
- collection.findOne({ _id: id }).then(result => {
+ collection.findOne({ _id: id }).then(resultIn => {
+ const result = resultIn;
if (result) {
result.id = result._id;
- //delete result._id;
+ // delete result._id;
fn(result as any);
} else {
fn(undefined);
@@ -235,7 +244,8 @@ export namespace Database {
.find({ _id: { $in: ids } })
.toArray();
fn(
- found.map((doc: any) => {
+ found.map((docIn: any) => {
+ const doc = docIn;
doc.id = doc._id;
delete doc._id;
return doc;
@@ -253,24 +263,26 @@ export namespace Database {
const count = Math.min(ids.length, 1000);
const index = ids.length - count;
const fetchIds = ids.splice(index, count).filter(id => !visited.has(id));
- if (!fetchIds.length) {
- continue;
- }
- const docs = await new Promise<{ [key: string]: any }[]>(res => this.getDocuments(fetchIds, res, collectionName));
- for (const doc of docs) {
- const id = doc.id;
- visited.add(id);
- ids.push(...(await fn(doc)));
+ if (fetchIds.length) {
+ // eslint-disable-next-line no-await-in-loop
+ const docs = await new Promise<{ [key: string]: any }[]>(res => {
+ this.getDocuments(fetchIds, res, collectionName);
+ });
+ docs.forEach(async doc => {
+ const { id } = doc;
+ visited.add(id);
+ ids.push(...(await fn(doc)));
+ });
}
}
- } else {
- return new Promise(res => {
- this.onConnect.push(() => {
- this.visit(ids, fn, collectionName);
- res();
- });
- });
+ return undefined;
}
+ return new Promise(res => {
+ this.onConnect.push(() => {
+ this.visit(ids, fn, collectionName);
+ res();
+ });
+ });
}
public query(query: { [key: string]: any }, projection?: { [key: string]: 0 | 1 }, collectionName = DocumentsCollection): Promise<mongodb.FindCursor> {
@@ -280,36 +292,31 @@ export namespace Database {
cursor = cursor.project(projection);
}
return Promise.resolve<mongodb.FindCursor>(cursor);
- } else {
- return new Promise<mongodb.FindCursor>(res => {
- this.onConnect.push(() => res(this.query(query, projection, collectionName)));
- });
}
+ return new Promise<mongodb.FindCursor>(res => {
+ this.onConnect.push(() => {
+ res(this.query(query, projection, collectionName));
+ });
+ });
}
public updateMany(query: any, update: any, collectionName = DocumentsCollection) {
if (this.db) {
- const db = this.db;
- return new Promise<mongodb.UpdateResult>(res =>
- db
- .collection(collectionName)
+ const { db } = this;
+ return new Promise<mongodb.UpdateResult>(res => {
+ db.collection(collectionName)
.updateMany(query, update)
.then(result => res(result))
- .catch(error => {
- console.log('Mongo INSERT MANY ERROR:', error);
- })
- );
- } else {
- return new Promise<mongodb.UpdateResult>(res => {
- this.onConnect.push(() =>
- this.updateMany(query, update, collectionName)
- .then(res)
- .catch(error => {
- console.log('Mongo UPDATAE MANY ERROR: ', error);
- })
- );
+ .catch(error => console.log('Mongo INSERT MANY ERROR:', error));
});
}
+ return new Promise<mongodb.UpdateResult>(res => {
+ this.onConnect.push(() =>
+ this.updateMany(query, update, collectionName)
+ .then(res)
+ .catch(error => console.log('Mongo UPDATAE MANY ERROR: ', error))
+ );
+ });
}
public print() {
@@ -375,9 +382,7 @@ export namespace Database {
* Checks to see if an image with the given @param contentSize
* already exists in the aux database, i.e. has already been downloaded from Google Photos.
*/
- export const QueryUploadHistory = async (contentSize: number) => {
- return SanitizedSingletonQuery<Upload.ImageInformation>({ contentSize }, AuxiliaryCollections.GooglePhotosUploadHistory);
- };
+ export const QueryUploadHistory = async (contentSize: number) => SanitizedSingletonQuery<Upload.ImageInformation>({ contentSize }, AuxiliaryCollections.GooglePhotosUploadHistory);
/**
* Records the uploading of the image with the given @param information,
@@ -405,28 +410,25 @@ export namespace Database {
* Retrieves the credentials associaed with @param userId
* and optionally removes their database id according to @param removeId.
*/
- export const Fetch = async (userId: string, removeId = true): Promise<Opt<StoredCredentials>> => {
- return SanitizedSingletonQuery<StoredCredentials>({ userId }, AuxiliaryCollections.GoogleAccess, removeId);
- };
+ export const Fetch = async (userId: string, removeId = true): Promise<Opt<StoredCredentials>> => SanitizedSingletonQuery<StoredCredentials>({ userId }, AuxiliaryCollections.GoogleAccess, removeId);
/**
* Writes the @param enrichedCredentials to the database, associated
* with @param userId for later retrieval and updating.
*/
- export const Write = async (userId: string, enrichedCredentials: GoogleApiServerUtils.EnrichedCredentials) => {
- return Instance.insert({ userId, canAccess: [], ...enrichedCredentials }, AuxiliaryCollections.GoogleAccess);
- };
+ export const Write = async (userId: string, enrichedCredentials: GoogleApiServerUtils.EnrichedCredentials) => Instance.insert({ userId, canAccess: [], ...enrichedCredentials }, AuxiliaryCollections.GoogleAccess);
/**
- * Updates the @param access_token and @param expiry_date fields
+ * Updates the @param accessToken and @param expiryDate fields
* in the stored credentials associated with @param userId.
*/
- export const Update = async (userId: string, access_token: string, expiry_date: number) => {
+ export const Update = async (userId: string, accessToken: string, expiryDate: number) => {
const entry = await Fetch(userId, false);
if (entry) {
- const parameters = { $set: { access_token, expiry_date } };
+ const parameters = { $set: { access_token: accessToken, expiry_date: expiryDate } };
return Instance.update(entry._id, parameters, emptyFunction, true, AuxiliaryCollections.GoogleAccess);
}
+ return undefined;
};
/**
diff --git a/src/server/index.ts b/src/server/index.ts
index 47c37c9f0..3151c2975 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -1,36 +1,36 @@
-import * as dotenv from 'dotenv';
import { yellow } from 'colors';
+import * as dotenv from 'dotenv';
import * as mobileDetect from 'mobile-detect';
import * as path from 'path';
-import * as qs from 'query-string';
-import { log_execution } from './ActionUtilities';
+import { logExecution } from './ActionUtilities';
+import AssistantManager from './ApiManagers/AssistantManager';
import DataVizManager from './ApiManagers/DataVizManager';
import DeleteManager from './ApiManagers/DeleteManager';
import DownloadManager from './ApiManagers/DownloadManager';
import GeneralGoogleManager from './ApiManagers/GeneralGoogleManager';
-//import GooglePhotosManager from './ApiManagers/GooglePhotosManager';
import { SearchManager } from './ApiManagers/SearchManager';
import SessionManager from './ApiManagers/SessionManager';
import UploadManager from './ApiManagers/UploadManager';
import UserManager from './ApiManagers/UserManager';
import UtilManager from './ApiManagers/UtilManager';
-import { GoogleCredentialsLoader, SSL } from './apis/google/CredentialsLoader';
-import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils';
import { DashSessionAgent } from './DashSession/DashSessionAgent';
import { AppliedSessionAgent } from './DashSession/Session/agents/applied_session_agent';
import { DashStats } from './DashStats';
import { DashUploadUtils } from './DashUploadUtils';
-import { Database } from './database';
import { Logger } from './ProcessFactory';
import RouteManager, { Method, PublicHandler } from './RouteManager';
import RouteSubscriber from './RouteSubscriber';
-import initializeServer, { resolvedPorts } from './server_Initialization';
+import { AdminPrivileges, resolvedPorts } from './SocketData';
+import { GoogleCredentialsLoader, SSL } from './apis/google/CredentialsLoader';
+import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils';
+import { Database } from './database';
+import initializeServer from './server_Initialization';
+// import GooglePhotosManager from './ApiManagers/GooglePhotosManager';
+
dotenv.config();
-export const AdminPriviliges: Map<string, boolean> = new Map();
export const onWindows = process.platform === 'win32';
+// eslint-disable-next-line import/no-mutable-exports
export let sessionAgent: AppliedSessionAgent;
-export const publicDirectory = path.resolve(__dirname, 'public');
-export const filesDirectory = path.resolve(publicDirectory, 'files');
/**
* These are the functions run before the server starts
@@ -45,7 +45,7 @@ async function preliminaryFunctions() {
SSL.loadCredentials();
GoogleApiServerUtils.processProjectCredentials();
if (process.env.DB !== 'MEM') {
- await log_execution({
+ await logExecution({
startMessage: 'attempting to initialize mongodb connection',
endMessage: 'connection outcome determined',
action: Database.tryInitializeConnection,
@@ -62,8 +62,19 @@ async function preliminaryFunctions() {
* that will manage the registration of new routes
* with the server
*/
-function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }: RouteManager) {
- const managers = [new SessionManager(), new UserManager(), new UploadManager(), new DownloadManager(), new SearchManager(), new DeleteManager(), new UtilManager(), new GeneralGoogleManager(), /* new GooglePhotosManager(),*/ new DataVizManager()];
+function routeSetter({ addSupervisedRoute, logRegistrationOutcome }: RouteManager) {
+ const managers = [
+ new SessionManager(),
+ new UserManager(),
+ new UploadManager(),
+ new DownloadManager(),
+ new SearchManager(),
+ new DeleteManager(),
+ new UtilManager(),
+ new GeneralGoogleManager(),
+ /* new GooglePhotosManager(), */ new DataVizManager(),
+ new AssistantManager(),
+ ];
// initialize API Managers
console.log(yellow('\nregistering server routes...'));
@@ -104,6 +115,7 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }:
});
const serve: PublicHandler = ({ req, res }) => {
+ // eslint-disable-next-line new-cap
const detector = new mobileDetect(req.headers['user-agent'] || '');
const filename = detector.mobile() !== null ? 'mobile/image.html' : 'index.html';
res.sendFile(path.join(__dirname, '../../deploy/' + filename));
@@ -118,9 +130,8 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }:
secureHandler: ({ res, isRelease }) => {
const { PASSWORD } = process.env;
if (!(isRelease && PASSWORD)) {
- return res.redirect('/home');
- }
- res.render('admin.pug', { title: 'Enter Administrator Password' });
+ res.redirect('/home');
+ } else res.render('admin.pug', { title: 'Enter Administrator Password' });
},
});
@@ -130,18 +141,19 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }:
secureHandler: async ({ req, res, isRelease, user: { id } }) => {
const { PASSWORD } = process.env;
if (!(isRelease && PASSWORD)) {
- return res.redirect('/home');
- }
- const { password } = req.body;
- const { previous_target } = req.params;
- let redirect: string;
- if (password === PASSWORD) {
- AdminPriviliges.set(id, true);
- redirect = `/${previous_target.replace(':', '/')}`;
+ res.redirect('/home');
} else {
- redirect = `/admin/${previous_target}`;
+ const { password } = req.body;
+ const { previous_target: previousTarget } = req.params;
+ let redirect: string;
+ if (password === PASSWORD) {
+ AdminPrivileges.set(id, true);
+ redirect = `/${previousTarget.replace(':', '/')}`;
+ } else {
+ redirect = `/admin/${previousTarget}`;
+ }
+ res.redirect(redirect);
}
- res.redirect(redirect);
},
});
@@ -151,7 +163,6 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }:
secureHandler: serve,
publicHandler: ({ req, res, ...remaining }) => {
const { originalUrl: target } = req;
- const sharing = qs.parse(qs.extract(req.originalUrl), { sort: false }).sharing === 'true';
const docAccess = target.startsWith('/doc/');
// since this is the public handler, there's no meaning of '/home' to speak of
// since there's no user logged in, so the only viable operation
@@ -174,7 +185,7 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }:
* the main monitor (master) thread.
*/
export async function launchServer() {
- await log_execution({
+ await logExecution({
startMessage: '\nstarting execution of preliminary functions',
endMessage: 'completed preliminary functions\n',
action: preliminaryFunctions,
diff --git a/src/server/public/assets/dash-colon-menu.gif b/src/server/public/assets/dash-colon-menu.gif
new file mode 100644
index 000000000..b5512afb1
--- /dev/null
+++ b/src/server/public/assets/dash-colon-menu.gif
Binary files differ
diff --git a/src/server/public/assets/dash-create-link-board.gif b/src/server/public/assets/dash-create-link-board.gif
new file mode 100644
index 000000000..354188fd9
--- /dev/null
+++ b/src/server/public/assets/dash-create-link-board.gif
Binary files differ
diff --git a/src/server/public/assets/dash-following-link.gif b/src/server/public/assets/dash-following-link.gif
new file mode 100644
index 000000000..9e3e6df82
--- /dev/null
+++ b/src/server/public/assets/dash-following-link.gif
Binary files differ
diff --git a/src/server/public/assets/documentation.png b/src/server/public/assets/documentation.png
new file mode 100644
index 000000000..95c76b198
--- /dev/null
+++ b/src/server/public/assets/documentation.png
Binary files differ
diff --git a/src/server/public/assets/pdf.worker.2.4.456.min.js b/src/server/public/assets/pdf.worker.2.4.456.min.js
deleted file mode 100644
index 54eb544f6..000000000
--- a/src/server/public/assets/pdf.worker.2.4.456.min.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * @licstart The following is the entire license notice for the
- * Javascript code in this page
- *
- * Copyright 2020 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * Javascript code in this page
- */
-!function (e, t) { "object" == typeof exports && "object" == typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define("pdfjs-dist/build/pdf.worker", [], t) : "object" == typeof exports ? exports["pdfjs-dist/build/pdf.worker"] = t() : e["pdfjs-dist/build/pdf.worker"] = e.pdfjsWorker = t() }(this, (function () { return function (e) { var t = {}; function a(r) { if (t[r]) return t[r].exports; var i = t[r] = { i: r, l: !1, exports: {} }; e[r].call(i.exports, i, i.exports, a); i.l = !0; return i.exports } a.m = e; a.c = t; a.d = function (e, t, r) { a.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r }) }; a.r = function (e) { "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }); Object.defineProperty(e, "__esModule", { value: !0 }) }; a.t = function (e, t) { 1 & t && (e = a(e)); if (8 & t) return e; if (4 & t && "object" == typeof e && e && e.__esModule) return e; var r = Object.create(null); a.r(r); Object.defineProperty(r, "default", { enumerable: !0, value: e }); if (2 & t && "string" != typeof e) for (var i in e) a.d(r, i, function (t) { return e[t] }.bind(null, i)); return r }; a.n = function (e) { var t = e && e.__esModule ? function () { return e.default } : function () { return e }; a.d(t, "a", t); return t }; a.o = function (e, t) { return Object.prototype.hasOwnProperty.call(e, t) }; a.p = ""; return a(a.s = 0) }([function (e, t, a) { "use strict"; const r = a(1); t.WorkerMessageHandler = r.WorkerMessageHandler }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.WorkerMessageHandler = t.WorkerTask = void 0; var r = a(2), i = a(4), n = a(5), s = a(44), o = a(45), c = a(46), l = a(7), h = function () { function e(e) { this.name = e; this.terminated = !1; this._capability = (0, r.createPromiseCapability)() } e.prototype = { get finished() { return this._capability.promise }, finish() { this._capability.resolve() }, terminate() { this.terminated = !0 }, ensureNotTerminated() { if (this.terminated) throw new Error("Worker task was terminated") } }; return e }(); t.WorkerTask = h; var u, d = { setup(e, t) { var a = !1; e.on("test", (function (t) { if (a) return; a = !0; if (!(t instanceof Uint8Array)) { e.send("test", null); return } const r = 255 === t[0]; e.postMessageTransfers = r; e.send("test", { supportTransfers: r }) })); e.on("configure", (function (e) { (0, r.setVerbosityLevel)(e.verbosity) })); e.on("GetDocRequest", (function (e) { return d.createDocumentHandler(e, t) })) }, createDocumentHandler(e, t) { var a, s = !1, u = null, d = []; const f = (0, r.getVerbosityLevel)(), g = e.apiVersion; if ("2.4.456" !== g) throw new Error(`The API version "${g}" does not match ` + 'the Worker version "2.4.456".'); const m = []; for (const e in []) m.push(e); if (m.length) throw new Error("The `Array.prototype` contains unexpected enumerable properties: " + m.join(", ") + "; thus breaking e.g. `for...in` iteration of `Array`s."); var p = e.docId, b = e.docBaseUrl, y = e.docId + "_worker", v = new o.MessageHandler(y, p, t); v.postMessageTransfers = e.postMessageTransfers; function w() { if (s) throw new Error("Worker was terminated") } function k(e) { d.push(e) } function S(e) { e.finish(); var t = d.indexOf(e); d.splice(t, 1) } async function C(e) { await a.ensureDoc("checkHeader"); await a.ensureDoc("parseStartXRef"); await a.ensureDoc("parse", [e]); e || await a.ensureDoc("checkFirstPage"); const [t, r] = await Promise.all([a.ensureDoc("numPages"), a.ensureDoc("fingerprint")]); return { numPages: t, fingerprint: r } } function x(e, t) { var a, i = (0, r.createPromiseCapability)(), s = e.source; if (s.data) { try { a = new n.LocalPdfManager(p, s.data, s.password, t, b); i.resolve(a) } catch (e) { i.reject(e) } return i.promise } var o, l = []; try { o = new c.PDFWorkerStream(v) } catch (e) { i.reject(e); return i.promise } var h = o.getFullReader(); h.headersReady.then((function () { if (h.isRangeSupported) { var e = s.disableAutoFetch || h.isStreamingSupported; a = new n.NetworkPdfManager(p, o, { msgHandler: v, password: s.password, length: h.contentLength, disableAutoFetch: e, rangeChunkSize: s.rangeChunkSize }, t, b); for (let e = 0; e < l.length; e++)a.sendProgressiveData(l[e]); l = []; i.resolve(a); u = null } })).catch((function (e) { i.reject(e); u = null })); var d = 0; new Promise((function (e, o) { var c = function (e) { try { w(); if (e.done) { a || function () { var e = (0, r.arraysToBytes)(l); s.length && e.length !== s.length && (0, r.warn)("reported HTTP length is different from actual"); try { a = new n.LocalPdfManager(p, e, s.password, t, b); i.resolve(a) } catch (e) { i.reject(e) } l = [] }(); u = null; return } var f = e.value; d += (0, r.arrayByteLength)(f); h.isStreamingSupported || v.send("DocProgress", { loaded: d, total: Math.max(d, h.contentLength || 0) }); a ? a.sendProgressiveData(f) : l.push(f); h.read().then(c, o) } catch (e) { o(e) } }; h.read().then(c, o) })).catch((function (e) { i.reject(e); u = null })); u = function (e) { o.cancelAllRequests(e) }; return i.promise } v.on("GetPage", (function (e) { return a.getPage(e.pageIndex).then((function (e) { return Promise.all([a.ensure(e, "rotate"), a.ensure(e, "ref"), a.ensure(e, "userUnit"), a.ensure(e, "view")]).then((function ([e, t, a, r]) { return { rotate: e, ref: t, userUnit: a, view: r } })) })) })); v.on("GetPageIndex", (function (e) { var t = i.Ref.get(e.ref.num, e.ref.gen); return a.pdfDocument.catalog.getPageIndex(t) })); v.on("GetDestinations", (function (e) { return a.ensureCatalog("destinations") })); v.on("GetDestination", (function (e) { return a.ensureCatalog("getDestination", [e.id]) })); v.on("GetPageLabels", (function (e) { return a.ensureCatalog("pageLabels") })); v.on("GetPageLayout", (function (e) { return a.ensureCatalog("pageLayout") })); v.on("GetPageMode", (function (e) { return a.ensureCatalog("pageMode") })); v.on("GetViewerPreferences", (function (e) { return a.ensureCatalog("viewerPreferences") })); v.on("GetOpenAction", (function (e) { return a.ensureCatalog("openAction") })); v.on("GetAttachments", (function (e) { return a.ensureCatalog("attachments") })); v.on("GetJavaScript", (function (e) { return a.ensureCatalog("javaScript") })); v.on("GetOutline", (function (e) { return a.ensureCatalog("documentOutline") })); v.on("GetPermissions", (function (e) { return a.ensureCatalog("permissions") })); v.on("GetMetadata", (function (e) { return Promise.all([a.ensureDoc("documentInfo"), a.ensureCatalog("metadata")]) })); v.on("GetData", (function (e) { a.requestLoadedStream(); return a.onLoadedStream().then((function (e) { return e.bytes })) })); v.on("GetStats", (function (e) { return a.pdfDocument.xref.stats })); v.on("GetAnnotations", (function ({ pageIndex: e, intent: t }) { return a.getPage(e).then((function (e) { return e.getAnnotationsData(t) })) })); v.on("GetOperatorList", (function (e, t) { var i = e.pageIndex; a.getPage(i).then((function (a) { var n = new h(`GetOperatorList: page ${i}`); k(n); const s = f >= r.VerbosityLevel.INFOS ? Date.now() : 0; a.getOperatorList({ handler: v, sink: t, task: n, intent: e.intent, renderInteractiveForms: e.renderInteractiveForms }).then((function (e) { S(n); s && (0, r.info)(`page=${i + 1} - getOperatorList: time=` + `${Date.now() - s}ms, len=${e.length}`); t.close() }), (function (e) { S(n); if (!n.terminated) { v.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); t.error(e) } })) })) }), this); v.on("GetTextContent", (function (e, t) { var i = e.pageIndex; t.onPull = function (e) { }; t.onCancel = function (e) { }; a.getPage(i).then((function (a) { var n = new h("GetTextContent: page " + i); k(n); const s = f >= r.VerbosityLevel.INFOS ? Date.now() : 0; a.extractTextContent({ handler: v, task: n, sink: t, normalizeWhitespace: e.normalizeWhitespace, combineTextItems: e.combineTextItems }).then((function () { S(n); s && (0, r.info)(`page=${i + 1} - getTextContent: time=` + `${Date.now() - s}ms`); t.close() }), (function (e) { S(n); n.terminated || t.error(e) })) })) })); v.on("FontFallback", (function (e) { return a.fontFallback(e.id, v) })); v.on("Cleanup", (function (e) { return a.cleanup() })); v.on("Terminate", (function (e) { s = !0; const t = []; if (a) { a.terminate(new r.AbortException("Worker was terminated.")); const e = a.cleanup(); t.push(e); a = null } else (0, i.clearPrimitiveCaches)(); u && u(new r.AbortException("Worker was terminated.")); d.forEach((function (e) { t.push(e.finished); e.terminate() })); return Promise.all(t).then((function () { v.destroy(); v = null })) })); v.on("Ready", (function (t) { !function (e) { function t(e) { w(); v.send("GetDoc", { pdfInfo: e }) } function i(e) { w(); if (e instanceof r.PasswordException) { var t = new h(`PasswordException: response ${e.code}`); k(t); v.sendWithPromise("PasswordRequest", e).then((function (e) { S(t); a.updatePassword(e.password); n() })).catch((function () { S(t); v.send("DocException", e) })) } else e instanceof r.InvalidPDFException || e instanceof r.MissingPDFException || e instanceof r.UnexpectedResponseException || e instanceof r.UnknownErrorException ? v.send("DocException", e) : v.send("DocException", new r.UnknownErrorException(e.message, e.toString())) } function n() { w(); C(!1).then(t, (function (e) { w(); if (e instanceof l.XRefParseException) { a.requestLoadedStream(); a.onLoadedStream().then((function () { w(); C(!0).then(t, i) })) } else i(e) }), i) } w(); x(e, { forceDataSchema: e.disableCreateObjectURL, maxImageSize: e.maxImageSize, disableFontFace: e.disableFontFace, nativeImageDecoderSupport: e.nativeImageDecoderSupport, ignoreErrors: e.ignoreErrors, isEvalSupported: e.isEvalSupported }).then((function (e) { if (s) { e.terminate(new r.AbortException("Worker was terminated.")); throw new Error("Worker was terminated") } (a = e).onLoadedStream().then((function (e) { v.send("DataLoaded", { length: e.bytes.byteLength }) })) })).then(n, i) }(e); e = null })); return y }, initializeFromPort(e) { var t = new o.MessageHandler("worker", "main", e); d.setup(t, e); t.send("ready", null) } }; t.WorkerMessageHandler = d; "undefined" == typeof window && !s.isNodeJS && "undefined" != typeof self && ("function" == typeof (u = self).postMessage && "onmessage" in u) && d.initializeFromPort(self) }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.arrayByteLength = d; t.arraysToBytes = function (e) { const t = e.length; if (1 === t && e[0] instanceof Uint8Array) return e[0]; let a = 0; for (let r = 0; r < t; r++)a += d(e[r]); let r = 0; const i = new Uint8Array(a); for (let a = 0; a < t; a++) { let t = e[a]; t instanceof Uint8Array || (t = "string" == typeof t ? u(t) : new Uint8Array(t)); const n = t.byteLength; i.set(t, r); r += n } return i }; t.assert = o; t.bytesToString = function (e) { o(null !== e && "object" == typeof e && void 0 !== e.length, "Invalid argument for bytesToString"); const t = e.length; if (t < 8192) return String.fromCharCode.apply(null, e); const a = []; for (let r = 0; r < t; r += 8192) { const i = Math.min(r + 8192, t), n = e.subarray(r, i); a.push(String.fromCharCode.apply(null, n)) } return a.join("") }; t.createPromiseCapability = function () { const e = Object.create(null); let t = !1; Object.defineProperty(e, "settled", { get: () => t }); e.promise = new Promise((function (a, r) { e.resolve = function (e) { t = !0; a(e) }; e.reject = function (e) { t = !0; r(e) } })); return e }; t.getVerbosityLevel = function () { return i }; t.info = function (e) { i >= r.INFOS && console.log(`Info: ${e}`) }; t.isArrayBuffer = function (e) { return "object" == typeof e && null !== e && void 0 !== e.byteLength }; t.isArrayEqual = function (e, t) { if (e.length !== t.length) return !1; return e.every((function (e, a) { return e === t[a] })) }; t.isBool = function (e) { return "boolean" == typeof e }; t.isEmptyObj = function (e) { for (const t in e) return !1; return !0 }; t.isNum = function (e) { return "number" == typeof e }; t.isString = function (e) { return "string" == typeof e }; t.isSameOrigin = function (e, t) { let a; try { a = new URL(e); if (!a.origin || "null" === a.origin) return !1 } catch (e) { return !1 } const r = new URL(t, a); return a.origin === r.origin }; t.createValidAbsoluteUrl = function (e, t) { if (!e) return null; try { const a = t ? new URL(e, t) : new URL(e); if (function (e) { if (!e) return !1; switch (e.protocol) { case "http:": case "https:": case "ftp:": case "mailto:": case "tel:": return !0; default: return !1 } }(a)) return a } catch (e) { } return null }; t.removeNullCharacters = function (e) { if ("string" != typeof e) { n("The argument for removeNullCharacters must be a string."); return e } return e.replace(h, "") }; t.setVerbosityLevel = function (e) { Number.isInteger(e) && (i = e) }; t.shadow = c; t.string32 = function (e) { return String.fromCharCode(e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e) }; t.stringToBytes = u; t.stringToPDFString = function (e) { const t = e.length, a = []; if ("þ" === e[0] && "ÿ" === e[1]) for (let r = 2; r < t; r += 2)a.push(String.fromCharCode(e.charCodeAt(r) << 8 | e.charCodeAt(r + 1))); else if ("ÿ" === e[0] && "þ" === e[1]) for (let r = 2; r < t; r += 2)a.push(String.fromCharCode(e.charCodeAt(r + 1) << 8 | e.charCodeAt(r))); else for (let r = 0; r < t; ++r) { const t = b[e.charCodeAt(r)]; a.push(t ? String.fromCharCode(t) : e.charAt(r)) } return a.join("") }; t.stringToUTF8String = function (e) { return decodeURIComponent(escape(e)) }; t.utf8StringToString = function (e) { return unescape(encodeURIComponent(e)) }; t.warn = n; t.unreachable = s; t.IsEvalSupportedCached = t.IsLittleEndianCached = t.createObjectURL = t.FormatError = t.Util = t.UnknownErrorException = t.UnexpectedResponseException = t.TextRenderingMode = t.StreamType = t.PermissionFlag = t.PasswordResponses = t.PasswordException = t.NativeImageDecoding = t.MissingPDFException = t.InvalidPDFException = t.AbortException = t.CMapCompressionType = t.ImageKind = t.FontType = t.AnnotationType = t.AnnotationStateModelType = t.AnnotationReviewState = t.AnnotationReplyType = t.AnnotationMarkedState = t.AnnotationFlag = t.AnnotationFieldFlag = t.AnnotationBorderStyleType = t.UNSUPPORTED_FEATURES = t.VerbosityLevel = t.OPS = t.IDENTITY_MATRIX = t.FONT_IDENTITY_MATRIX = t.BaseException = void 0; a(3); t.IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; t.FONT_IDENTITY_MATRIX = [.001, 0, 0, .001, 0, 0]; t.NativeImageDecoding = { NONE: "none", DECODE: "decode", DISPLAY: "display" }; t.PermissionFlag = { PRINT: 4, MODIFY_CONTENTS: 8, COPY: 16, MODIFY_ANNOTATIONS: 32, FILL_INTERACTIVE_FORMS: 256, COPY_FOR_ACCESSIBILITY: 512, ASSEMBLE: 1024, PRINT_HIGH_QUALITY: 2048 }; t.TextRenderingMode = { FILL: 0, STROKE: 1, FILL_STROKE: 2, INVISIBLE: 3, FILL_ADD_TO_PATH: 4, STROKE_ADD_TO_PATH: 5, FILL_STROKE_ADD_TO_PATH: 6, ADD_TO_PATH: 7, FILL_STROKE_MASK: 3, ADD_TO_PATH_FLAG: 4 }; t.ImageKind = { GRAYSCALE_1BPP: 1, RGB_24BPP: 2, RGBA_32BPP: 3 }; t.AnnotationType = { TEXT: 1, LINK: 2, FREETEXT: 3, LINE: 4, SQUARE: 5, CIRCLE: 6, POLYGON: 7, POLYLINE: 8, HIGHLIGHT: 9, UNDERLINE: 10, SQUIGGLY: 11, STRIKEOUT: 12, STAMP: 13, CARET: 14, INK: 15, POPUP: 16, FILEATTACHMENT: 17, SOUND: 18, MOVIE: 19, WIDGET: 20, SCREEN: 21, PRINTERMARK: 22, TRAPNET: 23, WATERMARK: 24, THREED: 25, REDACT: 26 }; t.AnnotationStateModelType = { MARKED: "Marked", REVIEW: "Review" }; t.AnnotationMarkedState = { MARKED: "Marked", UNMARKED: "Unmarked" }; t.AnnotationReviewState = { ACCEPTED: "Accepted", REJECTED: "Rejected", CANCELLED: "Cancelled", COMPLETED: "Completed", NONE: "None" }; t.AnnotationReplyType = { GROUP: "Group", REPLY: "R" }; t.AnnotationFlag = { INVISIBLE: 1, HIDDEN: 2, PRINT: 4, NOZOOM: 8, NOROTATE: 16, NOVIEW: 32, READONLY: 64, LOCKED: 128, TOGGLENOVIEW: 256, LOCKEDCONTENTS: 512 }; t.AnnotationFieldFlag = { READONLY: 1, REQUIRED: 2, NOEXPORT: 4, MULTILINE: 4096, PASSWORD: 8192, NOTOGGLETOOFF: 16384, RADIO: 32768, PUSHBUTTON: 65536, COMBO: 131072, EDIT: 262144, SORT: 524288, FILESELECT: 1048576, MULTISELECT: 2097152, DONOTSPELLCHECK: 4194304, DONOTSCROLL: 8388608, COMB: 16777216, RICHTEXT: 33554432, RADIOSINUNISON: 33554432, COMMITONSELCHANGE: 67108864 }; t.AnnotationBorderStyleType = { SOLID: 1, DASHED: 2, BEVELED: 3, INSET: 4, UNDERLINE: 5 }; t.StreamType = { UNKNOWN: "UNKNOWN", FLATE: "FLATE", LZW: "LZW", DCT: "DCT", JPX: "JPX", JBIG: "JBIG", A85: "A85", AHX: "AHX", CCF: "CCF", RLX: "RLX" }; t.FontType = { UNKNOWN: "UNKNOWN", TYPE1: "TYPE1", TYPE1C: "TYPE1C", CIDFONTTYPE0: "CIDFONTTYPE0", CIDFONTTYPE0C: "CIDFONTTYPE0C", TRUETYPE: "TRUETYPE", CIDFONTTYPE2: "CIDFONTTYPE2", TYPE3: "TYPE3", OPENTYPE: "OPENTYPE", TYPE0: "TYPE0", MMTYPE1: "MMTYPE1" }; const r = { ERRORS: 0, WARNINGS: 1, INFOS: 5 }; t.VerbosityLevel = r; t.CMapCompressionType = { NONE: 0, BINARY: 1, STREAM: 2 }; t.OPS = { dependency: 1, setLineWidth: 2, setLineCap: 3, setLineJoin: 4, setMiterLimit: 5, setDash: 6, setRenderingIntent: 7, setFlatness: 8, setGState: 9, save: 10, restore: 11, transform: 12, moveTo: 13, lineTo: 14, curveTo: 15, curveTo2: 16, curveTo3: 17, closePath: 18, rectangle: 19, stroke: 20, closeStroke: 21, fill: 22, eoFill: 23, fillStroke: 24, eoFillStroke: 25, closeFillStroke: 26, closeEOFillStroke: 27, endPath: 28, clip: 29, eoClip: 30, beginText: 31, endText: 32, setCharSpacing: 33, setWordSpacing: 34, setHScale: 35, setLeading: 36, setFont: 37, setTextRenderingMode: 38, setTextRise: 39, moveText: 40, setLeadingMoveText: 41, setTextMatrix: 42, nextLine: 43, showText: 44, showSpacedText: 45, nextLineShowText: 46, nextLineSetSpacingShowText: 47, setCharWidth: 48, setCharWidthAndBounds: 49, setStrokeColorSpace: 50, setFillColorSpace: 51, setStrokeColor: 52, setStrokeColorN: 53, setFillColor: 54, setFillColorN: 55, setStrokeGray: 56, setFillGray: 57, setStrokeRGBColor: 58, setFillRGBColor: 59, setStrokeCMYKColor: 60, setFillCMYKColor: 61, shadingFill: 62, beginInlineImage: 63, beginImageData: 64, endInlineImage: 65, paintXObject: 66, markPoint: 67, markPointProps: 68, beginMarkedContent: 69, beginMarkedContentProps: 70, endMarkedContent: 71, beginCompat: 72, endCompat: 73, paintFormXObjectBegin: 74, paintFormXObjectEnd: 75, beginGroup: 76, endGroup: 77, beginAnnotations: 78, endAnnotations: 79, beginAnnotation: 80, endAnnotation: 81, paintJpegXObject: 82, paintImageMaskXObject: 83, paintImageMaskXObjectGroup: 84, paintImageXObject: 85, paintInlineImageXObject: 86, paintInlineImageXObjectGroup: 87, paintImageXObjectRepeat: 88, paintImageMaskXObjectRepeat: 89, paintSolidColorImageMask: 90, constructPath: 91 }; t.UNSUPPORTED_FEATURES = { unknown: "unknown", forms: "forms", javaScript: "javaScript", smask: "smask", shadingPattern: "shadingPattern", font: "font" }; t.PasswordResponses = { NEED_PASSWORD: 1, INCORRECT_PASSWORD: 2 }; let i = r.WARNINGS; function n(e) { i >= r.WARNINGS && console.log(`Warning: ${e}`) } function s(e) { throw new Error(e) } function o(e, t) { e || s(t) } function c(e, t, a) { Object.defineProperty(e, t, { value: a, enumerable: !0, configurable: !0, writable: !1 }); return a } const l = function () { function e(t) { this.constructor === e && s("Cannot initialize BaseException."); this.message = t; this.name = this.constructor.name } e.prototype = new Error; e.constructor = e; return e }(); t.BaseException = l; t.PasswordException = class extends l { constructor(e, t) { super(e); this.code = t } }; t.UnknownErrorException = class extends l { constructor(e, t) { super(e); this.details = t } }; t.InvalidPDFException = class extends l { }; t.MissingPDFException = class extends l { }; t.UnexpectedResponseException = class extends l { constructor(e, t) { super(e); this.status = t } }; t.FormatError = class extends l { }; t.AbortException = class extends l { }; const h = /\x00/g; function u(e) { o("string" == typeof e, "Invalid argument for stringToBytes"); const t = e.length, a = new Uint8Array(t); for (let r = 0; r < t; ++r)a[r] = 255 & e.charCodeAt(r); return a } function d(e) { if (void 0 !== e.length) return e.length; o(void 0 !== e.byteLength); return e.byteLength } const f = { get value() { return c(this, "value", function () { const e = new Uint8Array(4); e[0] = 1; return 1 === new Uint32Array(e.buffer, 0, 1)[0] }()) } }; t.IsLittleEndianCached = f; const g = { get value() { return c(this, "value", function () { try { new Function(""); return !0 } catch (e) { return !1 } }()) } }; t.IsEvalSupportedCached = g; const m = ["rgb(", 0, ",", 0, ",", 0, ")"]; class p { static makeCssRgb(e, t, a) { m[1] = e; m[3] = t; m[5] = a; return m.join("") } static transform(e, t) { return [e[0] * t[0] + e[2] * t[1], e[1] * t[0] + e[3] * t[1], e[0] * t[2] + e[2] * t[3], e[1] * t[2] + e[3] * t[3], e[0] * t[4] + e[2] * t[5] + e[4], e[1] * t[4] + e[3] * t[5] + e[5]] } static applyTransform(e, t) { return [e[0] * t[0] + e[1] * t[2] + t[4], e[0] * t[1] + e[1] * t[3] + t[5]] } static applyInverseTransform(e, t) { const a = t[0] * t[3] - t[1] * t[2]; return [(e[0] * t[3] - e[1] * t[2] + t[2] * t[5] - t[4] * t[3]) / a, (-e[0] * t[1] + e[1] * t[0] + t[4] * t[1] - t[5] * t[0]) / a] } static getAxialAlignedBoundingBox(e, t) { const a = p.applyTransform(e, t), r = p.applyTransform(e.slice(2, 4), t), i = p.applyTransform([e[0], e[3]], t), n = p.applyTransform([e[2], e[1]], t); return [Math.min(a[0], r[0], i[0], n[0]), Math.min(a[1], r[1], i[1], n[1]), Math.max(a[0], r[0], i[0], n[0]), Math.max(a[1], r[1], i[1], n[1])] } static inverseTransform(e) { const t = e[0] * e[3] - e[1] * e[2]; return [e[3] / t, -e[1] / t, -e[2] / t, e[0] / t, (e[2] * e[5] - e[4] * e[3]) / t, (e[4] * e[1] - e[5] * e[0]) / t] } static apply3dTransform(e, t) { return [e[0] * t[0] + e[1] * t[1] + e[2] * t[2], e[3] * t[0] + e[4] * t[1] + e[5] * t[2], e[6] * t[0] + e[7] * t[1] + e[8] * t[2]] } static singularValueDecompose2dScale(e) { const t = [e[0], e[2], e[1], e[3]], a = e[0] * t[0] + e[1] * t[2], r = e[0] * t[1] + e[1] * t[3], i = e[2] * t[0] + e[3] * t[2], n = e[2] * t[1] + e[3] * t[3], s = (a + n) / 2, o = Math.sqrt((a + n) * (a + n) - 4 * (a * n - i * r)) / 2, c = s + o || 1, l = s - o || 1; return [Math.sqrt(c), Math.sqrt(l)] } static normalizeRect(e) { const t = e.slice(0); if (e[0] > e[2]) { t[0] = e[2]; t[2] = e[0] } if (e[1] > e[3]) { t[1] = e[3]; t[3] = e[1] } return t } static intersect(e, t) { function a(e, t) { return e - t } const r = [e[0], e[2], t[0], t[2]].sort(a), i = [e[1], e[3], t[1], t[3]].sort(a), n = []; e = p.normalizeRect(e); t = p.normalizeRect(t); if (!(r[0] === e[0] && r[1] === t[0] || r[0] === t[0] && r[1] === e[0])) return null; n[0] = r[1]; n[2] = r[2]; if (!(i[0] === e[1] && i[1] === t[1] || i[0] === t[1] && i[1] === e[1])) return null; n[1] = i[1]; n[3] = i[2]; return n } } t.Util = p; const b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 728, 711, 710, 729, 733, 731, 730, 732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8226, 8224, 8225, 8230, 8212, 8211, 402, 8260, 8249, 8250, 8722, 8240, 8222, 8220, 8221, 8216, 8217, 8218, 8482, 64257, 64258, 321, 338, 352, 376, 381, 305, 322, 339, 353, 382, 0, 8364]; const y = function () { const e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; return function (t, a, r = !1) { if (!r && URL.createObjectURL) { const e = new Blob([t], { type: a }); return URL.createObjectURL(e) } let i = `data:${a};base64,`; for (let a = 0, r = t.length; a < r; a += 3) { const n = 255 & t[a], s = 255 & t[a + 1], o = 255 & t[a + 2]; i += e[n >> 2] + e[(3 & n) << 4 | s >> 4] + e[a + 1 < r ? (15 & s) << 2 | o >> 6 : 64] + e[a + 2 < r ? 63 & o : 64] } return i } }(); t.createObjectURL = y }, function (e, t, a) { }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.clearPrimitiveCaches = function () { n._clearCache(); i._clearCache(); o._clearCache() }; t.isEOF = function (e) { return e === r }; t.isCmd = function (e, t) { return e instanceof n && (void 0 === t || e.cmd === t) }; t.isDict = u; t.isName = h; t.isRef = function (e) { return e instanceof o }; t.isRefsEqual = function (e, t) { return e.num === t.num && e.gen === t.gen }; t.isStream = function (e) { return "object" == typeof e && null !== e && void 0 !== e.getBytes }; t.RefSetCache = t.RefSet = t.Ref = t.Name = t.Dict = t.Cmd = t.EOF = void 0; a(2); var r = {}; t.EOF = r; var i = function () { let e = Object.create(null); function t(e) { this.name = e } t.prototype = {}; t.get = function (a) { var r = e[a]; return r || (e[a] = new t(a)) }; t._clearCache = function () { e = Object.create(null) }; return t }(); t.Name = i; var n = function () { let e = Object.create(null); function t(e) { this.cmd = e } t.prototype = {}; t.get = function (a) { var r = e[a]; return r || (e[a] = new t(a)) }; t._clearCache = function () { e = Object.create(null) }; return t }(); t.Cmd = n; var s = function () { var e = function () { return e }; function t(t) { this._map = Object.create(null); this.xref = t; this.objId = null; this.suppressEncryption = !1; this.__nonSerializable__ = e } t.prototype = { assignXref: function (e) { this.xref = e }, get(e, t, a) { let r = this._map[e]; if (void 0 === r && void 0 !== t) { r = this._map[t]; void 0 === r && void 0 !== a && (r = this._map[a]) } return r instanceof o && this.xref ? this.xref.fetch(r, this.suppressEncryption) : r }, async getAsync(e, t, a) { let r = this._map[e]; if (void 0 === r && void 0 !== t) { r = this._map[t]; void 0 === r && void 0 !== a && (r = this._map[a]) } return r instanceof o && this.xref ? this.xref.fetchAsync(r, this.suppressEncryption) : r }, getArray(e, t, a) { let r = this.get(e, t, a); if (!Array.isArray(r) || !this.xref) return r; r = r.slice(); for (let e = 0, t = r.length; e < t; e++)r[e] instanceof o && (r[e] = this.xref.fetch(r[e], this.suppressEncryption)); return r }, getRaw: function (e) { return this._map[e] }, getKeys: function () { return Object.keys(this._map) }, set: function (e, t) { this._map[e] = t }, has: function (e) { return void 0 !== this._map[e] }, forEach: function (e) { for (var t in this._map) e(t, this.get(t)) } }; t.empty = new t(null); t.merge = function (e, a) { const r = new t(e); for (let e = 0, t = a.length; e < t; e++) { const t = a[e]; if (u(t)) for (const e in t._map) void 0 === r._map[e] && (r._map[e] = t._map[e]) } return r }; return t }(); t.Dict = s; var o = function () { let e = Object.create(null); function t(e, t) { this.num = e; this.gen = t } t.prototype = { toString: function () { return 0 === this.gen ? `${this.num}R` : `${this.num}R${this.gen}` } }; t.get = function (a, r) { const i = 0 === r ? `${a}R` : `${a}R${r}`, n = e[i]; return n || (e[i] = new t(a, r)) }; t._clearCache = function () { e = Object.create(null) }; return t }(); t.Ref = o; var c = function () { function e() { this.dict = Object.create(null) } e.prototype = { has: function (e) { return e.toString() in this.dict }, put: function (e) { this.dict[e.toString()] = !0 }, remove: function (e) { delete this.dict[e.toString()] } }; return e }(); t.RefSet = c; var l = function () { function e() { this.dict = Object.create(null) } e.prototype = { get: function (e) { return this.dict[e.toString()] }, has: function (e) { return e.toString() in this.dict }, put: function (e, t) { this.dict[e.toString()] = t }, putAlias: function (e, t) { this.dict[e.toString()] = this.get(t) }, forEach: function (e) { for (const t in this.dict) e(this.dict[t]) }, clear: function () { this.dict = Object.create(null) } }; return e }(); t.RefSetCache = l; function h(e, t) { return e instanceof i && (void 0 === t || e.name === t) } function u(e, t) { return e instanceof s && (void 0 === t || h(e.get("Type"), t)) } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.NetworkPdfManager = t.LocalPdfManager = void 0; var r = a(2), i = a(6), n = a(7), s = a(8), o = a(11); class c { constructor() { this.constructor === c && (0, r.unreachable)("Cannot initialize BasePdfManager.") } get docId() { return this._docId } get password() { return this._password } get docBaseUrl() { let e = null; if (this._docBaseUrl) { const t = (0, r.createValidAbsoluteUrl)(this._docBaseUrl); t ? e = t.href : (0, r.warn)(`Invalid absolute docBaseUrl: "${this._docBaseUrl}".`) } return (0, r.shadow)(this, "docBaseUrl", e) } onLoadedStream() { (0, r.unreachable)("Abstract method `onLoadedStream` called") } ensureDoc(e, t) { return this.ensure(this.pdfDocument, e, t) } ensureXRef(e, t) { return this.ensure(this.pdfDocument.xref, e, t) } ensureCatalog(e, t) { return this.ensure(this.pdfDocument.catalog, e, t) } getPage(e) { return this.pdfDocument.getPage(e) } fontFallback(e, t) { return this.pdfDocument.fontFallback(e, t) } cleanup() { return this.pdfDocument.cleanup() } async ensure(e, t, a) { (0, r.unreachable)("Abstract method `ensure` called") } requestRange(e, t) { (0, r.unreachable)("Abstract method `requestRange` called") } requestLoadedStream() { (0, r.unreachable)("Abstract method `requestLoadedStream` called") } sendProgressiveData(e) { (0, r.unreachable)("Abstract method `sendProgressiveData` called") } updatePassword(e) { this._password = e } terminate(e) { (0, r.unreachable)("Abstract method `terminate` called") } } t.LocalPdfManager = class extends c { constructor(e, t, a, r, i) { super(); this._docId = e; this._password = a; this._docBaseUrl = i; this.evaluatorOptions = r; const n = new o.Stream(t); this.pdfDocument = new s.PDFDocument(this, n); this._loadedStreamPromise = Promise.resolve(n) } async ensure(e, t, a) { const r = e[t]; return "function" == typeof r ? r.apply(e, a) : r } requestRange(e, t) { return Promise.resolve() } requestLoadedStream() { } onLoadedStream() { return this._loadedStreamPromise } terminate(e) { } }; t.NetworkPdfManager = class extends c { constructor(e, t, a, r, n) { super(); this._docId = e; this._password = a.password; this._docBaseUrl = n; this.msgHandler = a.msgHandler; this.evaluatorOptions = r; this.streamManager = new i.ChunkedStreamManager(t, { msgHandler: a.msgHandler, length: a.length, disableAutoFetch: a.disableAutoFetch, rangeChunkSize: a.rangeChunkSize }); this.pdfDocument = new s.PDFDocument(this, this.streamManager.getStream()) } async ensure(e, t, a) { try { const r = e[t]; return "function" == typeof r ? r.apply(e, a) : r } catch (r) { if (!(r instanceof n.MissingDataException)) throw r; await this.requestRange(r.begin, r.end); return this.ensure(e, t, a) } } requestRange(e, t) { return this.streamManager.requestRange(e, t) } requestLoadedStream() { this.streamManager.requestAllChunks() } sendProgressiveData(e) { this.streamManager.onReceiveData({ chunk: e }) } onLoadedStream() { return this.streamManager.onLoadedStream() } terminate(e) { this.streamManager.abort(e) } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.ChunkedStreamManager = t.ChunkedStream = void 0; var r = a(2), i = a(7); class n { constructor(e, t, a) { this.bytes = new Uint8Array(e); this.start = 0; this.pos = 0; this.end = e; this.chunkSize = t; this.loadedChunks = []; this.numChunksLoaded = 0; this.numChunks = Math.ceil(e / t); this.manager = a; this.progressiveDataLength = 0; this.lastSuccessfulEnsureByteChunk = -1 } getMissingChunks() { const e = []; for (let t = 0, a = this.numChunks; t < a; ++t)this.loadedChunks[t] || e.push(t); return e } getBaseStreams() { return [this] } allChunksLoaded() { return this.numChunksLoaded === this.numChunks } onReceiveData(e, t) { const a = this.chunkSize; if (e % a != 0) throw new Error(`Bad begin offset: ${e}`); const r = e + t.byteLength; if (r % a != 0 && r !== this.bytes.length) throw new Error(`Bad end offset: ${r}`); this.bytes.set(new Uint8Array(t), e); const i = Math.floor(e / a), n = Math.floor((r - 1) / a) + 1; for (let e = i; e < n; ++e)if (!this.loadedChunks[e]) { this.loadedChunks[e] = !0; ++this.numChunksLoaded } } onReceiveProgressiveData(e) { let t = this.progressiveDataLength; const a = Math.floor(t / this.chunkSize); this.bytes.set(new Uint8Array(e), t); t += e.byteLength; this.progressiveDataLength = t; const r = t >= this.end ? this.numChunks : Math.floor(t / this.chunkSize); for (let e = a; e < r; ++e)if (!this.loadedChunks[e]) { this.loadedChunks[e] = !0; ++this.numChunksLoaded } } ensureByte(e) { if (e < this.progressiveDataLength) return; const t = Math.floor(e / this.chunkSize); if (t !== this.lastSuccessfulEnsureByteChunk) { if (!this.loadedChunks[t]) throw new i.MissingDataException(e, e + 1); this.lastSuccessfulEnsureByteChunk = t } } ensureRange(e, t) { if (e >= t) return; if (t <= this.progressiveDataLength) return; const a = this.chunkSize, r = Math.floor(e / a), n = Math.floor((t - 1) / a) + 1; for (let a = r; a < n; ++a)if (!this.loadedChunks[a]) throw new i.MissingDataException(e, t) } nextEmptyChunk(e) { const t = this.numChunks; for (let a = 0; a < t; ++a) { const r = (e + a) % t; if (!this.loadedChunks[r]) return r } return null } hasChunk(e) { return !!this.loadedChunks[e] } get length() { return this.end - this.start } get isEmpty() { return 0 === this.length } getByte() { const e = this.pos; if (e >= this.end) return -1; e >= this.progressiveDataLength && this.ensureByte(e); return this.bytes[this.pos++] } getUint16() { const e = this.getByte(), t = this.getByte(); return -1 === e || -1 === t ? -1 : (e << 8) + t } getInt32() { return (this.getByte() << 24) + (this.getByte() << 16) + (this.getByte() << 8) + this.getByte() } getBytes(e, t = !1) { const a = this.bytes, r = this.pos, i = this.end; if (!e) { i > this.progressiveDataLength && this.ensureRange(r, i); const e = a.subarray(r, i); return t ? new Uint8ClampedArray(e) : e } let n = r + e; n > i && (n = i); n > this.progressiveDataLength && this.ensureRange(r, n); this.pos = n; const s = a.subarray(r, n); return t ? new Uint8ClampedArray(s) : s } peekByte() { const e = this.getByte(); -1 !== e && this.pos--; return e } peekBytes(e, t = !1) { const a = this.getBytes(e, t); this.pos -= a.length; return a } getByteRange(e, t) { e < 0 && (e = 0); t > this.end && (t = this.end); t > this.progressiveDataLength && this.ensureRange(e, t); return this.bytes.subarray(e, t) } skip(e) { e || (e = 1); this.pos += e } reset() { this.pos = this.start } moveStart() { this.start = this.pos } makeSubStream(e, t, a) { t ? e + t > this.progressiveDataLength && this.ensureRange(e, e + t) : e >= this.progressiveDataLength && this.ensureByte(e); function r() { } r.prototype = Object.create(this); r.prototype.getMissingChunks = function () { const e = this.chunkSize, t = Math.floor(this.start / e), a = Math.floor((this.end - 1) / e) + 1, r = []; for (let e = t; e < a; ++e)this.loadedChunks[e] || r.push(e); return r }; r.prototype.allChunksLoaded = function () { return this.numChunksLoaded === this.numChunks || 0 === this.getMissingChunks().length }; const i = new r; i.pos = i.start = e; i.end = e + t || this.end; i.dict = a; return i } } t.ChunkedStream = n; t.ChunkedStreamManager = class { constructor(e, t) { this.length = t.length; this.chunkSize = t.rangeChunkSize; this.stream = new n(this.length, this.chunkSize, this); this.pdfNetworkStream = e; this.disableAutoFetch = t.disableAutoFetch; this.msgHandler = t.msgHandler; this.currRequestId = 0; this.chunksNeededByRequest = Object.create(null); this.requestsByChunk = Object.create(null); this.promisesByRequest = Object.create(null); this.progressiveDataLength = 0; this.aborted = !1; this._loadedStreamCapability = (0, r.createPromiseCapability)() } onLoadedStream() { return this._loadedStreamCapability.promise } sendRequest(e, t) { const a = this.pdfNetworkStream.getRangeReader(e, t); a.isStreamingSupported || (a.onProgress = this.onProgress.bind(this)); let i = [], n = 0; new Promise((e, t) => { const s = o => { try { if (!o.done) { const e = o.value; i.push(e); n += (0, r.arrayByteLength)(e); a.isStreamingSupported && this.onProgress({ loaded: n }); a.read().then(s, t); return } const c = (0, r.arraysToBytes)(i); i = null; e(c) } catch (e) { t(e) } }; a.read().then(s, t) }).then(t => { this.aborted || this.onReceiveData({ chunk: t, begin: e }) }) } requestAllChunks() { const e = this.stream.getMissingChunks(); this._requestChunks(e); return this._loadedStreamCapability.promise } _requestChunks(e) { const t = this.currRequestId++, a = Object.create(null); this.chunksNeededByRequest[t] = a; for (const t of e) this.stream.hasChunk(t) || (a[t] = !0); if ((0, r.isEmptyObj)(a)) return Promise.resolve(); const i = (0, r.createPromiseCapability)(); this.promisesByRequest[t] = i; const n = []; for (let e in a) { e |= 0; if (!(e in this.requestsByChunk)) { this.requestsByChunk[e] = []; n.push(e) } this.requestsByChunk[e].push(t) } if (!n.length) return i.promise; const s = this.groupChunks(n); for (const e of s) { const t = e.beginChunk * this.chunkSize, a = Math.min(e.endChunk * this.chunkSize, this.length); this.sendRequest(t, a) } return i.promise } getStream() { return this.stream } requestRange(e, t) { t = Math.min(t, this.length); const a = this.getBeginChunk(e), r = this.getEndChunk(t), i = []; for (let e = a; e < r; ++e)i.push(e); return this._requestChunks(i) } requestRanges(e = []) { const t = []; for (const a of e) { const e = this.getBeginChunk(a.begin), r = this.getEndChunk(a.end); for (let a = e; a < r; ++a)t.includes(a) || t.push(a) } t.sort((function (e, t) { return e - t })); return this._requestChunks(t) } groupChunks(e) { const t = []; let a = -1, r = -1; for (let i = 0, n = e.length; i < n; ++i) { const n = e[i]; a < 0 && (a = n); if (r >= 0 && r + 1 !== n) { t.push({ beginChunk: a, endChunk: r + 1 }); a = n } i + 1 === e.length && t.push({ beginChunk: a, endChunk: n + 1 }); r = n } return t } onProgress(e) { this.msgHandler.send("DocProgress", { loaded: this.stream.numChunksLoaded * this.chunkSize + e.loaded, total: this.length }) } onReceiveData(e) { const t = e.chunk, a = void 0 === e.begin, i = a ? this.progressiveDataLength : e.begin, n = i + t.byteLength, s = Math.floor(i / this.chunkSize), o = n < this.length ? Math.floor(n / this.chunkSize) : Math.ceil(n / this.chunkSize); if (a) { this.stream.onReceiveProgressiveData(t); this.progressiveDataLength = n } else this.stream.onReceiveData(i, t); this.stream.allChunksLoaded() && this._loadedStreamCapability.resolve(this.stream); const c = []; for (let e = s; e < o; ++e) { const t = this.requestsByChunk[e] || []; delete this.requestsByChunk[e]; for (const a of t) { const t = this.chunksNeededByRequest[a]; e in t && delete t[e]; (0, r.isEmptyObj)(t) && c.push(a) } } if (!this.disableAutoFetch && (0, r.isEmptyObj)(this.requestsByChunk)) { let e; if (1 === this.stream.numChunksLoaded) { const t = this.stream.numChunks - 1; this.stream.hasChunk(t) || (e = t) } else e = this.stream.nextEmptyChunk(o); Number.isInteger(e) && this._requestChunks([e]) } for (const e of c) { const t = this.promisesByRequest[e]; delete this.promisesByRequest[e]; t.resolve() } this.msgHandler.send("DocProgress", { loaded: this.stream.numChunksLoaded * this.chunkSize, total: this.length }) } onError(e) { this._loadedStreamCapability.reject(e) } getBeginChunk(e) { return Math.floor(e / this.chunkSize) } getEndChunk(e) { return Math.floor((e - 1) / this.chunkSize) + 1 } abort(e) { this.aborted = !0; this.pdfNetworkStream && this.pdfNetworkStream.cancelAllRequests(e); for (const t in this.promisesByRequest) this.promisesByRequest[t].reject(e) } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getLookupTableFactory = function (e) { let t; return function () { if (e) { t = Object.create(null); e(t); e = null } return t } }; t.getInheritableProperty = function ({ dict: e, key: t, getArray: a = !1, stopWhenFound: i = !0 }) { let n, s = 0; for (; e;) { const o = a ? e.getArray(t) : e.get(t); if (void 0 !== o) { if (i) return o; n || (n = []); n.push(o) } if (++s > 100) { (0, r.warn)(`getInheritableProperty: maximum loop count exceeded for "${t}"`); break } e = e.get("Parent") } return n }; t.toRomanNumerals = function (e, t = !1) { (0, r.assert)(Number.isInteger(e) && e > 0, "The number should be a positive integer."); const a = []; let i; for (; e >= 1e3;) { e -= 1e3; a.push("M") } i = e / 100 | 0; e %= 100; a.push(o[i]); i = e / 10 | 0; e %= 10; a.push(o[10 + i]); a.push(o[20 + e]); const n = a.join(""); return t ? n.toLowerCase() : n }; t.log2 = function (e) { if (e <= 0) return 0; return Math.ceil(Math.log2(e)) }; t.readInt8 = function (e, t) { return e[t] << 24 >> 24 }; t.readUint16 = function (e, t) { return e[t] << 8 | e[t + 1] }; t.readUint32 = function (e, t) { return (e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3]) >>> 0 }; t.isWhiteSpace = function (e) { return 32 === e || 9 === e || 13 === e || 10 === e }; t.XRefParseException = t.XRefEntryException = t.MissingDataException = void 0; var r = a(2); class i extends r.BaseException { constructor(e, t) { super(`Missing data [${e}, ${t})`); this.begin = e; this.end = t } } t.MissingDataException = i; class n extends r.BaseException { } t.XRefEntryException = n; class s extends r.BaseException { } t.XRefParseException = s; const o = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"] }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PDFDocument = t.Page = void 0; var r = a(2), i = a(9), n = a(4), s = a(7), o = a(11), c = a(23), l = a(21), h = a(10), u = a(24), d = a(25), f = a(39); const g = [0, 0, 612, 792]; function m(e, t) { return "display" === t && e.viewable || "print" === t && e.printable } class p { constructor({ pdfManager: e, xref: t, pageIndex: a, pageDict: r, ref: i, fontCache: n, builtInCMapCache: s, pdfFunctionFactory: o }) { this.pdfManager = e; this.pageIndex = a; this.pageDict = r; this.xref = t; this.ref = i; this.fontCache = n; this.builtInCMapCache = s; this.pdfFunctionFactory = o; this.evaluatorOptions = e.evaluatorOptions; this.resourcesPromise = null; const c = { obj: 0 }; this.idFactory = { createObjId: () => `p${a}_${++c.obj}`, getDocId: () => `g_${e.docId}` } } _getInheritableProperty(e, t = !1) { const a = (0, s.getInheritableProperty)({ dict: this.pageDict, key: e, getArray: t, stopWhenFound: !1 }); return Array.isArray(a) ? 1 !== a.length && (0, n.isDict)(a[0]) ? n.Dict.merge(this.xref, a) : a[0] : a } get content() { return this.pageDict.get("Contents") } get resources() { return (0, r.shadow)(this, "resources", this._getInheritableProperty("Resources") || n.Dict.empty) } _getBoundingBox(e) { const t = this._getInheritableProperty(e, !0); if (Array.isArray(t) && 4 === t.length) { if (t[2] - t[0] != 0 && t[3] - t[1] != 0) return t; (0, r.warn)(`Empty /${e} entry.`) } return null } get mediaBox() { return (0, r.shadow)(this, "mediaBox", this._getBoundingBox("MediaBox") || g) } get cropBox() { return (0, r.shadow)(this, "cropBox", this._getBoundingBox("CropBox") || this.mediaBox) } get userUnit() { let e = this.pageDict.get("UserUnit"); (!(0, r.isNum)(e) || e <= 0) && (e = 1); return (0, r.shadow)(this, "userUnit", e) } get view() { const { cropBox: e, mediaBox: t } = this; let a; if (e === t || (0, r.isArrayEqual)(e, t)) a = t; else { const i = r.Util.intersect(e, t); i && i[2] - i[0] != 0 && i[3] - i[1] != 0 ? a = i : (0, r.warn)("Empty /CropBox and /MediaBox intersection.") } return (0, r.shadow)(this, "view", a || t) } get rotate() { let e = this._getInheritableProperty("Rotate") || 0; e % 90 != 0 ? e = 0 : e >= 360 ? e %= 360 : e < 0 && (e = (e % 360 + 360) % 360); return (0, r.shadow)(this, "rotate", e) } getContentStream() { const e = this.content; let t; if (Array.isArray(e)) { const a = this.xref, r = []; for (const t of e) r.push(a.fetchIfRef(t)); t = new o.StreamsSequenceStream(r) } else t = (0, n.isStream)(e) ? e : new o.NullStream; return t } loadResources(e) { this.resourcesPromise || (this.resourcesPromise = this.pdfManager.ensure(this, "resources")); return this.resourcesPromise.then(() => new i.ObjectLoader(this.resources, e, this.xref).load()) } getOperatorList({ handler: e, sink: t, task: a, intent: i, renderInteractiveForms: n }) { const s = this.pdfManager.ensure(this, "getContentStream"), o = this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"]), c = new d.PartialEvaluator({ xref: this.xref, handler: e, pageIndex: this.pageIndex, idFactory: this.idFactory, fontCache: this.fontCache, builtInCMapCache: this.builtInCMapCache, options: this.evaluatorOptions, pdfFunctionFactory: this.pdfFunctionFactory }), l = Promise.all([s, o]).then(([r]) => { const n = new u.OperatorList(i, t, this.pageIndex); e.send("StartRenderPage", { transparency: c.hasBlendModes(this.resources), pageIndex: this.pageIndex, intent: i }); return c.getOperatorList({ stream: r, task: a, resources: this.resources, operatorList: n }).then((function () { return n })) }); return Promise.all([l, this._parsedAnnotations]).then((function ([e, t]) { if (0 === t.length) { e.flush(!0); return { length: e.totalLength } } const s = []; for (const e of t) m(e, i) && s.push(e.getOperatorList(c, a, n)); return Promise.all(s).then((function (t) { e.addOp(r.OPS.beginAnnotations, []); for (const a of t) e.addOpList(a); e.addOp(r.OPS.endAnnotations, []); e.flush(!0); return { length: e.totalLength } })) })) } extractTextContent({ handler: e, task: t, normalizeWhitespace: a, sink: r, combineTextItems: i }) { const n = this.pdfManager.ensure(this, "getContentStream"), s = this.loadResources(["ExtGState", "XObject", "Font"]); return Promise.all([n, s]).then(([n]) => new d.PartialEvaluator({ xref: this.xref, handler: e, pageIndex: this.pageIndex, idFactory: this.idFactory, fontCache: this.fontCache, builtInCMapCache: this.builtInCMapCache, options: this.evaluatorOptions, pdfFunctionFactory: this.pdfFunctionFactory }).getTextContent({ stream: n, task: t, resources: this.resources, normalizeWhitespace: a, combineTextItems: i, sink: r })) } getAnnotationsData(e) { return this._parsedAnnotations.then((function (t) { const a = []; for (let r = 0, i = t.length; r < i; r++)e && !m(t[r], e) || a.push(t[r].data); return a })) } get annotations() { return (0, r.shadow)(this, "annotations", this._getInheritableProperty("Annots") || []) } get _parsedAnnotations() { const e = this.pdfManager.ensure(this, "annotations").then(() => { const e = this.annotations, t = []; for (let a = 0, r = e.length; a < r; a++)t.push(c.AnnotationFactory.create(this.xref, e[a], this.pdfManager, this.idFactory)); return Promise.all(t).then((function (e) { return e.filter((function (e) { return !!e })) }), (function (e) { (0, r.warn)(`_parsedAnnotations: "${e}".`); return [] })) }); return (0, r.shadow)(this, "_parsedAnnotations", e) } } t.Page = p; const b = new Uint8Array([37, 80, 68, 70, 45]), y = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]), v = new Uint8Array([101, 110, 100, 111, 98, 106]), w = /^[1-9]\.[0-9]$/; function k(e, t, a = 1024, r = !1) { const i = t.length, n = e.peekBytes(a), s = n.length - i; if (s <= 0) return !1; if (r) { const a = i - 1; let r = n.length - 1; for (; r >= a;) { let s = 0; for (; s < i && n[r - s] === t[a - s];)s++; if (s >= i) { e.pos += r - a; return !0 } r-- } } else { let a = 0; for (; a <= s;) { let r = 0; for (; r < i && n[a + r] === t[r];)r++; if (r >= i) { e.pos += a; return !0 } a++ } } return !1 } t.PDFDocument = class { constructor(e, t) { let a; if ((0, n.isStream)(t)) a = t; else { if (!(0, r.isArrayBuffer)(t)) throw new Error("PDFDocument: Unknown argument type"); a = new o.Stream(t) } if (a.length <= 0) throw new r.InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes."); this.pdfManager = e; this.stream = a; this.xref = new i.XRef(a, e); this.pdfFunctionFactory = new f.PDFFunctionFactory({ xref: this.xref, isEvalSupported: e.evaluatorOptions.isEvalSupported }); this._pagePromises = [] } parse(e) { this.setup(e); const t = this.catalog.catDict.get("Version"); (0, n.isName)(t) && (this.pdfFormatVersion = t.name); try { this.acroForm = this.catalog.catDict.get("AcroForm"); if (this.acroForm) { this.xfa = this.acroForm.get("XFA"); const e = this.acroForm.get("Fields"); Array.isArray(e) && 0 !== e.length || this.xfa || (this.acroForm = null) } } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("Cannot fetch AcroForm entry; assuming no AcroForms are present"); this.acroForm = null } try { const e = this.catalog.catDict.get("Collection"); (0, n.isDict)(e) && e.getKeys().length > 0 && (this.collection = e) } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("Cannot fetch Collection dictionary.") } } get linearization() { let e = null; try { e = h.Linearization.create(this.stream) } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)(e) } return (0, r.shadow)(this, "linearization", e) } get startXRef() { const e = this.stream; let t = 0; if (this.linearization) { e.reset(); k(e, v) && (t = e.pos + 6 - e.start) } else { const a = 1024, r = y.length; let i = !1, n = e.end; for (; !i && n > 0;) { n -= a - r; n < 0 && (n = 0); e.pos = n; i = k(e, y, a, !0) } if (i) { e.skip(9); let a; do { a = e.getByte() } while ((0, s.isWhiteSpace)(a)); let r = ""; for (; a >= 32 && a <= 57;) { r += String.fromCharCode(a); a = e.getByte() } t = parseInt(r, 10); isNaN(t) && (t = 0) } } return (0, r.shadow)(this, "startXRef", t) } checkHeader() { const e = this.stream; e.reset(); if (!k(e, b)) return; e.moveStart(); let t, a = ""; for (; (t = e.getByte()) > 32 && !(a.length >= 12);)a += String.fromCharCode(t); this.pdfFormatVersion || (this.pdfFormatVersion = a.substring(5)) } parseStartXRef() { this.xref.setStartXRef(this.startXRef) } setup(e) { this.xref.parse(e); this.catalog = new i.Catalog(this.pdfManager, this.xref) } get numPages() { const e = this.linearization, t = e ? e.numPages : this.catalog.numPages; return (0, r.shadow)(this, "numPages", t) } get documentInfo() { const e = { Title: r.isString, Author: r.isString, Subject: r.isString, Keywords: r.isString, Creator: r.isString, Producer: r.isString, CreationDate: r.isString, ModDate: r.isString, Trapped: n.isName }; let t = this.pdfFormatVersion; if ("string" != typeof t || !w.test(t)) { (0, r.warn)(`Invalid PDF header version number: ${t}`); t = null } const a = { PDFFormatVersion: t, IsLinearized: !!this.linearization, IsAcroFormPresent: !!this.acroForm, IsXFAPresent: !!this.xfa, IsCollectionPresent: !!this.collection }; let i; try { i = this.xref.trailer.get("Info") } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("The document information dictionary is invalid.") } if ((0, n.isDict)(i)) for (const t of i.getKeys()) { const s = i.get(t); if (e[t]) e[t](s) ? a[t] = "string" != typeof s ? s : (0, r.stringToPDFString)(s) : (0, r.info)(`Bad value in document info for "${t}".`); else if ("string" == typeof t) { let e; if ((0, r.isString)(s)) e = (0, r.stringToPDFString)(s); else { if (!((0, n.isName)(s) || (0, r.isNum)(s) || (0, r.isBool)(s))) { (0, r.info)(`Unsupported value in document info for (custom) "${t}".`); continue } e = s } a.Custom || (a.Custom = Object.create(null)); a.Custom[t] = e } } return (0, r.shadow)(this, "documentInfo", a) } get fingerprint() { let e; const t = this.xref.trailer.get("ID"); e = Array.isArray(t) && t[0] && (0, r.isString)(t[0]) && "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" !== t[0] ? (0, r.stringToBytes)(t[0]) : (0, l.calculateMD5)(this.stream.getByteRange(0, 1024), 0, 1024); const a = []; for (let t = 0, r = e.length; t < r; t++) { const r = e[t].toString(16); a.push(r.padStart(2, "0")) } return (0, r.shadow)(this, "fingerprint", a.join("")) } _getLinearizationPage(e) { const { catalog: t, linearization: a } = this; (0, r.assert)(a && a.pageFirst === e); const i = n.Ref.get(a.objectNumberFirst, 0); return this.xref.fetchAsync(i).then(e => { if ((0, n.isDict)(e, "Page") || (0, n.isDict)(e) && !e.has("Type") && e.has("Contents")) { i && !t.pageKidsCountCache.has(i) && t.pageKidsCountCache.put(i, 1); return [e, i] } throw new r.FormatError("The Linearization dictionary doesn't point to a valid Page dictionary.") }).catch(a => { (0, r.info)(a); return t.getPageDict(e) }) } getPage(e) { if (void 0 !== this._pagePromises[e]) return this._pagePromises[e]; const { catalog: t, linearization: a } = this, r = a && a.pageFirst === e ? this._getLinearizationPage(e) : t.getPageDict(e); return this._pagePromises[e] = r.then(([a, r]) => new p({ pdfManager: this.pdfManager, xref: this.xref, pageIndex: e, pageDict: a, ref: r, fontCache: t.fontCache, builtInCMapCache: t.builtInCMapCache, pdfFunctionFactory: this.pdfFunctionFactory })) } checkFirstPage() { return this.getPage(0).catch(async e => { if (e instanceof s.XRefEntryException) { this._pagePromises.length = 0; await this.cleanup(); throw new s.XRefParseException } }) } fontFallback(e, t) { return this.catalog.fontFallback(e, t) } async cleanup() { return this.catalog ? this.catalog.cleanup() : (0, n.clearPrimitiveCaches)() } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.FileSpec = t.XRef = t.ObjectLoader = t.Catalog = void 0; var r = a(2), i = a(4), n = a(10), s = a(7), o = a(21), c = a(22); function l(e) { return (0, i.isDict)(e) ? e.get("D") : e } class h { constructor(e, t) { this.pdfManager = e; this.xref = t; this.catDict = t.getCatalogObj(); if (!(0, i.isDict)(this.catDict)) throw new r.FormatError("Catalog object is not a dictionary."); this.fontCache = new i.RefSetCache; this.builtInCMapCache = new Map; this.pageKidsCountCache = new i.RefSetCache } get metadata() { const e = this.catDict.getRaw("Metadata"); if (!(0, i.isRef)(e)) return (0, r.shadow)(this, "metadata", null); const t = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata), a = this.xref.fetch(e, t); let n; if (a && (0, i.isDict)(a.dict)) { const e = a.dict.get("Type"), t = a.dict.get("Subtype"); if ((0, i.isName)(e, "Metadata") && (0, i.isName)(t, "XML")) try { n = (0, r.stringToUTF8String)((0, r.bytesToString)(a.getBytes())) } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("Skipping invalid metadata.") } } return (0, r.shadow)(this, "metadata", n) } get toplevelPagesDict() { const e = this.catDict.get("Pages"); if (!(0, i.isDict)(e)) throw new r.FormatError("Invalid top-level pages dictionary."); return (0, r.shadow)(this, "toplevelPagesDict", e) } get documentOutline() { let e = null; try { e = this._readDocumentOutline() } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)("Unable to read document outline.") } return (0, r.shadow)(this, "documentOutline", e) } _readDocumentOutline() { let e = this.catDict.get("Outlines"); if (!(0, i.isDict)(e)) return null; e = e.getRaw("First"); if (!(0, i.isRef)(e)) return null; const t = { items: [] }, a = [{ obj: e, parent: t }], n = new i.RefSet; n.put(e); const s = this.xref, o = new Uint8ClampedArray(3); for (; a.length > 0;) { const t = a.shift(), l = s.fetchIfRef(t.obj); if (null === l) continue; if (!l.has("Title")) throw new r.FormatError("Invalid outline item encountered."); const u = { url: null, dest: null }; h.parseDestDictionary({ destDict: l, resultObj: u, docBaseUrl: this.pdfManager.docBaseUrl }); const d = l.get("Title"), f = l.get("F") || 0, g = l.getArray("C"), m = l.get("Count"); let p = o; !Array.isArray(g) || 3 !== g.length || 0 === g[0] && 0 === g[1] && 0 === g[2] || (p = c.ColorSpace.singletons.rgb.getRgb(g, 0)); const b = { dest: u.dest, url: u.url, unsafeUrl: u.unsafeUrl, newWindow: u.newWindow, title: (0, r.stringToPDFString)(d), color: p, count: Number.isInteger(m) ? m : void 0, bold: !!(2 & f), italic: !!(1 & f), items: [] }; t.parent.items.push(b); e = l.getRaw("First"); if ((0, i.isRef)(e) && !n.has(e)) { a.push({ obj: e, parent: b }); n.put(e) } e = l.getRaw("Next"); if ((0, i.isRef)(e) && !n.has(e)) { a.push({ obj: e, parent: t.parent }); n.put(e) } } return t.items.length > 0 ? t.items : null } get permissions() { let e = null; try { e = this._readPermissions() } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)("Unable to read permissions.") } return (0, r.shadow)(this, "permissions", e) } _readPermissions() { const e = this.xref.trailer.get("Encrypt"); if (!(0, i.isDict)(e)) return null; let t = e.get("P"); if (!(0, r.isNum)(t)) return null; t += 2 ** 32; const a = []; for (const e in r.PermissionFlag) { const i = r.PermissionFlag[e]; t & i && a.push(i) } return a } get numPages() { const e = this.toplevelPagesDict.get("Count"); if (!Number.isInteger(e)) throw new r.FormatError("Page count in top-level pages dictionary is not an integer."); return (0, r.shadow)(this, "numPages", e) } get destinations() { const e = this._readDests(), t = Object.create(null); if (e instanceof f) { const a = e.getAll(); for (const e in a) t[e] = l(a[e]) } else e instanceof i.Dict && e.forEach((function (e, a) { a && (t[e] = l(a)) })); return (0, r.shadow)(this, "destinations", t) } getDestination(e) { const t = this._readDests(); return t instanceof f || t instanceof i.Dict ? l(t.get(e) || null) : null } _readDests() { const e = this.catDict.get("Names"); return e && e.has("Dests") ? new f(e.getRaw("Dests"), this.xref) : this.catDict.has("Dests") ? this.catDict.get("Dests") : void 0 } get pageLabels() { let e = null; try { e = this._readPageLabels() } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)("Unable to read page labels.") } return (0, r.shadow)(this, "pageLabels", e) } _readPageLabels() { const e = this.catDict.getRaw("PageLabels"); if (!e) return null; const t = new Array(this.numPages); let a = null, n = ""; const o = new g(e, this.xref).getAll(); let c = "", l = 1; for (let e = 0, h = this.numPages; e < h; e++) { if (e in o) { const t = o[e]; if (!(0, i.isDict)(t)) throw new r.FormatError("PageLabel is not a dictionary."); if (t.has("Type") && !(0, i.isName)(t.get("Type"), "PageLabel")) throw new r.FormatError("Invalid type in PageLabel dictionary."); if (t.has("S")) { const e = t.get("S"); if (!(0, i.isName)(e)) throw new r.FormatError("Invalid style in PageLabel dictionary."); a = e.name } else a = null; if (t.has("P")) { const e = t.get("P"); if (!(0, r.isString)(e)) throw new r.FormatError("Invalid prefix in PageLabel dictionary."); n = (0, r.stringToPDFString)(e) } else n = ""; if (t.has("St")) { const e = t.get("St"); if (!(Number.isInteger(e) && e >= 1)) throw new r.FormatError("Invalid start in PageLabel dictionary."); l = e } else l = 1 } switch (a) { case "D": c = l; break; case "R": case "r": c = (0, s.toRomanNumerals)(l, "r" === a); break; case "A": case "a": const e = 26, t = 65, i = 97, n = "a" === a ? i : t, o = l - 1, h = String.fromCharCode(n + o % e), u = []; for (let t = 0, a = o / e | 0; t <= a; t++)u.push(h); c = u.join(""); break; default: if (a) throw new r.FormatError(`Invalid style "${a}" in PageLabel dictionary.`); c = "" }t[e] = n + c; l++ } return t } get pageLayout() { const e = this.catDict.get("PageLayout"); let t = ""; if ((0, i.isName)(e)) switch (e.name) { case "SinglePage": case "OneColumn": case "TwoColumnLeft": case "TwoColumnRight": case "TwoPageLeft": case "TwoPageRight": t = e.name }return (0, r.shadow)(this, "pageLayout", t) } get pageMode() { const e = this.catDict.get("PageMode"); let t = "UseNone"; if ((0, i.isName)(e)) switch (e.name) { case "UseNone": case "UseOutlines": case "UseThumbs": case "FullScreen": case "UseOC": case "UseAttachments": t = e.name }return (0, r.shadow)(this, "pageMode", t) } get viewerPreferences() { const e = { HideToolbar: r.isBool, HideMenubar: r.isBool, HideWindowUI: r.isBool, FitWindow: r.isBool, CenterWindow: r.isBool, DisplayDocTitle: r.isBool, NonFullScreenPageMode: i.isName, Direction: i.isName, ViewArea: i.isName, ViewClip: i.isName, PrintArea: i.isName, PrintClip: i.isName, PrintScaling: i.isName, Duplex: i.isName, PickTrayByPDFSize: r.isBool, PrintPageRange: Array.isArray, NumCopies: Number.isInteger }, t = this.catDict.get("ViewerPreferences"), a = Object.create(null); if ((0, i.isDict)(t)) for (const i in e) { if (!t.has(i)) continue; const n = t.get(i); if (!e[i](n)) { (0, r.info)(`Bad value in ViewerPreferences for "${i}".`); continue } let s; switch (i) { case "NonFullScreenPageMode": switch (n.name) { case "UseNone": case "UseOutlines": case "UseThumbs": case "UseOC": s = n.name; break; default: s = "UseNone" }break; case "Direction": switch (n.name) { case "L2R": case "R2L": s = n.name; break; default: s = "L2R" }break; case "ViewArea": case "ViewClip": case "PrintArea": case "PrintClip": switch (n.name) { case "MediaBox": case "CropBox": case "BleedBox": case "TrimBox": case "ArtBox": s = n.name; break; default: s = "CropBox" }break; case "PrintScaling": switch (n.name) { case "None": case "AppDefault": s = n.name; break; default: s = "AppDefault" }break; case "Duplex": switch (n.name) { case "Simplex": case "DuplexFlipShortEdge": case "DuplexFlipLongEdge": s = n.name; break; default: s = "None" }break; case "PrintPageRange": if (n.length % 2 != 0) break; n.every((e, t, a) => Number.isInteger(e) && e > 0 && (0 === t || e >= a[t - 1]) && e <= this.numPages) && (s = n); break; case "NumCopies": n > 0 && (s = n); break; default: (0, r.assert)("boolean" == typeof n); s = n }void 0 !== s ? a[i] = s : (0, r.info)(`Bad value in ViewerPreferences for "${i}".`) } return (0, r.shadow)(this, "viewerPreferences", a) } get openAction() { const e = this.catDict.get("OpenAction"); let t = null; if ((0, i.isDict)(e)) { const a = new i.Dict(this.xref); a.set("A", e); const r = { url: null, dest: null, action: null }; h.parseDestDictionary({ destDict: a, resultObj: r }); if (Array.isArray(r.dest)) { t || (t = Object.create(null)); t.dest = r.dest } else if (r.action) { t || (t = Object.create(null)); t.action = r.action } } else if (Array.isArray(e)) { t || (t = Object.create(null)); t.dest = e } return (0, r.shadow)(this, "openAction", t) } get attachments() { const e = this.catDict.get("Names"); let t = null; if (e && e.has("EmbeddedFiles")) { const a = new f(e.getRaw("EmbeddedFiles"), this.xref).getAll(); for (const e in a) { const i = new m(a[e], this.xref); t || (t = Object.create(null)); t[(0, r.stringToPDFString)(e)] = i.serializable } } return (0, r.shadow)(this, "attachments", t) } get javaScript() { const e = this.catDict.get("Names"); let t = null; function a(e) { const a = e.get("S"); if (!(0, i.isName)(a, "JavaScript")) return; let n = e.get("JS"); if ((0, i.isStream)(n)) n = (0, r.bytesToString)(n.getBytes()); else if (!(0, r.isString)(n)) return; t || (t = []); t.push((0, r.stringToPDFString)(n)) } if (e && e.has("JavaScript")) { const t = new f(e.getRaw("JavaScript"), this.xref).getAll(); for (const e in t) { const r = t[e]; (0, i.isDict)(r) && a(r) } } const n = this.catDict.get("OpenAction"); (0, i.isDict)(n) && (0, i.isName)(n.get("S"), "JavaScript") && a(n); return (0, r.shadow)(this, "javaScript", t) } fontFallback(e, t) { const a = []; this.fontCache.forEach((function (e) { a.push(e) })); return Promise.all(a).then(a => { for (const r of a) if (r.loadedName === e) { r.fallback(t); return } }) } cleanup() { (0, i.clearPrimitiveCaches)(); this.pageKidsCountCache.clear(); const e = []; this.fontCache.forEach((function (t) { e.push(t) })); return Promise.all(e).then(e => { for (const { dict: t } of e) delete t.translated; this.fontCache.clear(); this.builtInCMapCache.clear() }) } getPageDict(e) { const t = (0, r.createPromiseCapability)(), a = [this.catDict.getRaw("Pages")], n = new i.RefSet, s = this.xref, o = this.pageKidsCountCache; let c, l = 0; !function h() { for (; a.length;) { const u = a.pop(); if ((0, i.isRef)(u)) { c = o.get(u); if (c > 0 && l + c < e) { l += c; continue } if (n.has(u)) { t.reject(new r.FormatError("Pages tree contains circular reference.")); return } n.put(u); s.fetchAsync(u).then((function (r) { if ((0, i.isDict)(r, "Page") || (0, i.isDict)(r) && !r.has("Kids")) if (e === l) { u && !o.has(u) && o.put(u, 1); t.resolve([r, u]) } else { l++; h() } else { a.push(r); h() } }), t.reject); return } if (!(0, i.isDict)(u)) { t.reject(new r.FormatError("Page dictionary kid reference points to wrong type of object.")); return } c = u.get("Count"); if (Number.isInteger(c) && c >= 0) { const t = u.objId; t && !o.has(t) && o.put(t, c); if (l + c <= e) { l += c; continue } } const d = u.get("Kids"); if (!Array.isArray(d)) { if ((0, i.isName)(u.get("Type"), "Page") || !u.has("Type") && u.has("Contents")) { if (l === e) { t.resolve([u, null]); return } l++; continue } t.reject(new r.FormatError("Page dictionary kids object is not an array.")); return } for (let e = d.length - 1; e >= 0; e--)a.push(d[e]) } t.reject(new Error(`Page index ${e} not found.`)) }(); return t.promise } getPageIndex(e) { const t = this.xref; let a = 0; return function n(s) { return function (a) { let n, s = 0; return t.fetchAsync(a).then((function (t) { if ((0, i.isRefsEqual)(a, e) && !(0, i.isDict)(t, "Page") && (!(0, i.isDict)(t) || t.has("Type") || !t.has("Contents"))) throw new r.FormatError("The reference does not point to a /Page dictionary."); if (!t) return null; if (!(0, i.isDict)(t)) throw new r.FormatError("Node must be a dictionary."); n = t.getRaw("Parent"); return t.getAsync("Parent") })).then((function (e) { if (!e) return null; if (!(0, i.isDict)(e)) throw new r.FormatError("Parent must be a dictionary."); return e.getAsync("Kids") })).then((function (e) { if (!e) return null; const o = []; let c = !1; for (let n = 0, l = e.length; n < l; n++) { const l = e[n]; if (!(0, i.isRef)(l)) throw new r.FormatError("Kid must be a reference."); if ((0, i.isRefsEqual)(l, a)) { c = !0; break } o.push(t.fetchAsync(l).then((function (e) { if (!(0, i.isDict)(e)) throw new r.FormatError("Kid node must be a dictionary."); e.has("Count") ? s += e.get("Count") : s++ }))) } if (!c) throw new r.FormatError("Kid reference not found in parent's kids."); return Promise.all(o).then((function () { return [s, n] })) })) }(s).then((function (e) { if (!e) return a; const [t, r] = e; a += t; return n(r) })) }(e) } static parseDestDictionary(e) { const t = e.destDict; if (!(0, i.isDict)(t)) { (0, r.warn)("parseDestDictionary: `destDict` must be a dictionary."); return } const a = e.resultObj; if ("object" != typeof a) { (0, r.warn)("parseDestDictionary: `resultObj` must be an object."); return } const n = e.docBaseUrl || null; let s, o, c = t.get("A"); !(0, i.isDict)(c) && t.has("Dest") && (c = t.get("Dest")); if ((0, i.isDict)(c)) { const e = c.get("S"); if (!(0, i.isName)(e)) { (0, r.warn)("parseDestDictionary: Invalid type in Action dictionary."); return } const t = e.name; switch (t) { case "URI": s = c.get("URI"); (0, i.isName)(s) ? s = "/" + s.name : (0, r.isString)(s) && (s = function (e) { return e.startsWith("www.") ? `http://${e}` : e }(s)); break; case "GoTo": o = c.get("D"); break; case "Launch": case "GoToR": const e = c.get("F"); (0, i.isDict)(e) ? s = e.get("F") || null : (0, r.isString)(e) && (s = e); let n = c.get("D"); if (n) { (0, i.isName)(n) && (n = n.name); if ((0, r.isString)(s)) { const e = s.split("#")[0]; (0, r.isString)(n) ? s = e + "#" + n : Array.isArray(n) && (s = e + "#" + JSON.stringify(n)) } } const l = c.get("NewWindow"); (0, r.isBool)(l) && (a.newWindow = l); break; case "Named": const h = c.get("N"); (0, i.isName)(h) && (a.action = h.name); break; case "JavaScript": const u = c.get("JS"); let d; (0, i.isStream)(u) ? d = (0, r.bytesToString)(u.getBytes()) : (0, r.isString)(u) && (d = u); if (d) { const e = new RegExp("^\\s*(" + ["app.launchURL", "window.open"].join("|").split(".").join("\\.") + ")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))", "i").exec((0, r.stringToPDFString)(d)); if (e && e[2]) { s = e[2]; "true" === e[3] && "app.launchURL" === e[1] && (a.newWindow = !0); break } } default: (0, r.warn)(`parseDestDictionary: unsupported action type "${t}".`) } } else t.has("Dest") && (o = t.get("Dest")); if ((0, r.isString)(s)) { s = function (e) { try { return (0, r.stringToUTF8String)(e) } catch (t) { return e } }(s); const e = (0, r.createValidAbsoluteUrl)(s, n); e && (a.url = e.href); a.unsafeUrl = s } if (o) { (0, i.isName)(o) && (o = o.name); ((0, r.isString)(o) || Array.isArray(o)) && (a.dest = o) } } } t.Catalog = h; var u = function () { function e(e, t) { this.stream = e; this.pdfManager = t; this.entries = []; this.xrefstms = Object.create(null); this._cacheMap = new Map; this.stats = { streamTypes: Object.create(null), fontTypes: Object.create(null) } } e.prototype = { setStartXRef: function (e) { this.startXRefQueue = [e] }, parse: function (e) { var t; if (e) { (0, r.warn)("Indexing all PDF objects"); t = this.indexObjects() } else t = this.readXRef(); t.assignXref(this); this.trailer = t; let a, n; try { a = t.get("Encrypt") } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)(`XRef.parse - Invalid "Encrypt" reference: "${e}".`) } if ((0, i.isDict)(a)) { var c = t.get("ID"), l = c && c.length ? c[0] : ""; a.suppressEncryption = !0; this.encrypt = new o.CipherTransformFactory(a, l, this.pdfManager.password) } try { n = t.get("Root") } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)(`XRef.parse - Invalid "Root" reference: "${e}".`) } if (!(0, i.isDict)(n) || !n.has("Pages")) { if (!e) throw new s.XRefParseException; throw new r.FormatError("Invalid root reference") } this.root = n }, processXRefTable: function (e) { "tableState" in this || (this.tableState = { entryNum: 0, streamPos: e.lexer.stream.pos, parserBuf1: e.buf1, parserBuf2: e.buf2 }); var t = this.readXRefTable(e); if (!(0, i.isCmd)(t, "trailer")) throw new r.FormatError("Invalid XRef table: could not find trailer dictionary"); var a = e.getObj(); !(0, i.isDict)(a) && a.dict && (a = a.dict); if (!(0, i.isDict)(a)) throw new r.FormatError("Invalid XRef table: could not parse trailer dictionary"); delete this.tableState; return a }, readXRefTable: function (e) { var t, a = e.lexer.stream, n = this.tableState; a.pos = n.streamPos; e.buf1 = n.parserBuf1; e.buf2 = n.parserBuf2; for (; ;) { if (!("firstEntryNum" in n) || !("entryCount" in n)) { if ((0, i.isCmd)(t = e.getObj(), "trailer")) break; n.firstEntryNum = t; n.entryCount = e.getObj() } var s = n.firstEntryNum, o = n.entryCount; if (!Number.isInteger(s) || !Number.isInteger(o)) throw new r.FormatError("Invalid XRef table: wrong types in subsection header"); for (var c = n.entryNum; c < o; c++) { n.streamPos = a.pos; n.entryNum = c; n.parserBuf1 = e.buf1; n.parserBuf2 = e.buf2; var l = {}; l.offset = e.getObj(); l.gen = e.getObj(); var h = e.getObj(); if (h instanceof i.Cmd) switch (h.cmd) { case "f": l.free = !0; break; case "n": l.uncompressed = !0 }if (!Number.isInteger(l.offset) || !Number.isInteger(l.gen) || !l.free && !l.uncompressed) throw new r.FormatError(`Invalid entry in XRef subsection: ${s}, ${o}`); 0 === c && l.free && 1 === s && (s = 0); this.entries[c + s] || (this.entries[c + s] = l) } n.entryNum = 0; n.streamPos = a.pos; n.parserBuf1 = e.buf1; n.parserBuf2 = e.buf2; delete n.firstEntryNum; delete n.entryCount } if (this.entries[0] && !this.entries[0].free) throw new r.FormatError("Invalid XRef table: unexpected first object"); return t }, processXRefStream: function (e) { if (!("streamState" in this)) { var t = e.dict, a = t.get("W"), r = t.get("Index"); r || (r = [0, t.get("Size")]); this.streamState = { entryRanges: r, byteWidths: a, entryNum: 0, streamPos: e.pos } } this.readXRefStream(e); delete this.streamState; return e.dict }, readXRefStream: function (e) { var t, a, i = this.streamState; e.pos = i.streamPos; for (var n = i.byteWidths, s = n[0], o = n[1], c = n[2], l = i.entryRanges; l.length > 0;) { var h = l[0], u = l[1]; if (!Number.isInteger(h) || !Number.isInteger(u)) throw new r.FormatError(`Invalid XRef range fields: ${h}, ${u}`); if (!Number.isInteger(s) || !Number.isInteger(o) || !Number.isInteger(c)) throw new r.FormatError(`Invalid XRef entry fields length: ${h}, ${u}`); for (t = i.entryNum; t < u; ++t) { i.entryNum = t; i.streamPos = e.pos; var d = 0, f = 0, g = 0; for (a = 0; a < s; ++a)d = d << 8 | e.getByte(); 0 === s && (d = 1); for (a = 0; a < o; ++a)f = f << 8 | e.getByte(); for (a = 0; a < c; ++a)g = g << 8 | e.getByte(); var m = {}; m.offset = f; m.gen = g; switch (d) { case 0: m.free = !0; break; case 1: m.uncompressed = !0; break; case 2: break; default: throw new r.FormatError(`Invalid XRef entry type: ${d}`) }this.entries[h + t] || (this.entries[h + t] = m) } i.entryNum = 0; i.streamPos = e.pos; l.splice(0, 2) } }, indexObjects: function () { function e(e, t) { for (var a = "", r = e[t]; 10 !== r && 13 !== r && 60 !== r && !(++t >= e.length);) { a += String.fromCharCode(r); r = e[t] } return a } function t(e, t, a) { for (var r = a.length, i = e.length, n = 0; t < i;) { for (var s = 0; s < r && e[t + s] === a[s];)++s; if (s >= r) break; t++; n++ } return n } var a = /^(\d+)\s+(\d+)\s+obj\b/; const o = /\bendobj[\b\s]$/, c = /\s+(\d+\s+\d+\s+obj[\b\s<])$/; var l = new Uint8Array([116, 114, 97, 105, 108, 101, 114]), h = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]); const u = new Uint8Array([111, 98, 106]); var d = new Uint8Array([47, 88, 82, 101, 102]); this.entries.length = 0; var f = this.stream; f.pos = 0; for (var g, m, p = f.getBytes(), b = f.start, y = p.length, v = [], w = []; b < y;) { var k = p[b]; if (9 !== k && 10 !== k && 13 !== k && 32 !== k) if (37 !== k) { var S, C = e(p, b); if (C.startsWith("xref") && (4 === C.length || /\s/.test(C[4]))) { b += t(p, b, l); v.push(b); b += t(p, b, h) } else if (S = a.exec(C)) { const e = 0 | S[1], a = 0 | S[2]; this.entries[e] && this.entries[e].gen !== a || (this.entries[e] = { offset: b - f.start, gen: a, uncompressed: !0 }); let i, n = b + C.length; for (; n < p.length;) { const e = n + t(p, n, u) + 4; i = e - b; const a = Math.max(e - 25, n), s = (0, r.bytesToString)(p.subarray(a, e)); if (o.test(s)) break; { const e = c.exec(s); if (e && e[1]) { (0, r.warn)('indexObjects: Found new "obj" inside of another "obj", caused by missing "endobj" -- trying to recover.'); i -= e[1].length; break } } n = e } const s = p.subarray(b, b + i); var x = t(s, 0, d); if (x < i && s[x + 5] < 64) { w.push(b - f.start); this.xrefstms[b - f.start] = 1 } b += i } else if (C.startsWith("trailer") && (7 === C.length || /\s/.test(C[7]))) { v.push(b); b += t(p, b, h) } else b += C.length + 1 } else do { if (++b >= y) break; k = p[b] } while (10 !== k && 13 !== k); else ++b } for (g = 0, m = w.length; g < m; ++g) { this.startXRefQueue.push(w[g]); this.readXRef(!0) } let A; for (g = 0, m = v.length; g < m; ++g) { f.pos = v[g]; const e = new n.Parser({ lexer: new n.Lexer(f), xref: this, allowStreams: !0, recoveryMode: !0 }); var I = e.getObj(); if (!(0, i.isCmd)(I, "trailer")) continue; const t = e.getObj(); if (!(0, i.isDict)(t)) continue; let a; try { a = t.get("Root") } catch (e) { if (e instanceof s.MissingDataException) throw e; continue } if ((0, i.isDict)(a) && a.has("Pages")) { if (t.has("ID")) return t; A = t } } if (A) return A; throw new r.InvalidPDFException("Invalid PDF structure.") }, readXRef: function (e) { var t = this.stream; const a = Object.create(null); try { for (; this.startXRefQueue.length;) { var o = this.startXRefQueue[0]; if (a[o]) { (0, r.warn)("readXRef - skipping XRef table since it was already parsed."); this.startXRefQueue.shift(); continue } a[o] = !0; t.pos = o + t.start; const e = new n.Parser({ lexer: new n.Lexer(t), xref: this, allowStreams: !0 }); var c, l = e.getObj(); if ((0, i.isCmd)(l, "xref")) { c = this.processXRefTable(e); this.topDict || (this.topDict = c); l = c.get("XRefStm"); if (Number.isInteger(l)) { var h = l; if (!(h in this.xrefstms)) { this.xrefstms[h] = 1; this.startXRefQueue.push(h) } } } else { if (!Number.isInteger(l)) throw new r.FormatError("Invalid XRef stream header"); if (!Number.isInteger(e.getObj()) || !(0, i.isCmd)(e.getObj(), "obj") || !(0, i.isStream)(l = e.getObj())) throw new r.FormatError("Invalid XRef stream"); c = this.processXRefStream(l); this.topDict || (this.topDict = c); if (!c) throw new r.FormatError("Failed to read XRef stream") } l = c.get("Prev"); Number.isInteger(l) ? this.startXRefQueue.push(l) : (0, i.isRef)(l) && this.startXRefQueue.push(l.num); this.startXRefQueue.shift() } return this.topDict } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.info)("(while reading XRef): " + e) } if (!e) throw new s.XRefParseException }, getEntry: function (e) { var t = this.entries[e]; return t && !t.free && t.offset ? t : null }, fetchIfRef: function (e, t) { return e instanceof i.Ref ? this.fetch(e, t) : e }, fetch: function (e, t) { if (!(e instanceof i.Ref)) throw new Error("ref object is not a reference"); const a = e.num, r = this._cacheMap.get(a); if (void 0 !== r) { r instanceof i.Dict && !r.objId && (r.objId = e.toString()); return r } let n = this.getEntry(a); if (null === n) { this._cacheMap.set(a, n); return n } n = n.uncompressed ? this.fetchUncompressed(e, n, t) : this.fetchCompressed(e, n, t); (0, i.isDict)(n) ? n.objId = e.toString() : (0, i.isStream)(n) && (n.dict.objId = e.toString()); return n }, fetchUncompressed(e, t, a = !1) { var r = e.gen, o = e.num; if (t.gen !== r) throw new s.XRefEntryException(`Inconsistent generation in XRef: ${e}`); var c = this.stream.makeSubStream(t.offset + this.stream.start); const l = new n.Parser({ lexer: new n.Lexer(c), xref: this, allowStreams: !0 }); var h = l.getObj(), u = l.getObj(), d = l.getObj(); if (h !== o || u !== r || !(d instanceof i.Cmd)) throw new s.XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`); if ("obj" !== d.cmd) { if (d.cmd.startsWith("obj")) { o = parseInt(d.cmd.substring(3), 10); if (!Number.isNaN(o)) return o } throw new s.XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`) } t = this.encrypt && !a ? l.getObj(this.encrypt.createCipherTransform(o, r)) : l.getObj(); (0, i.isStream)(t) || this._cacheMap.set(o, t); return t }, fetchCompressed(e, t, a = !1) { const o = t.offset, c = this.fetch(i.Ref.get(o, 0)); if (!(0, i.isStream)(c)) throw new r.FormatError("bad ObjStm stream"); const l = c.dict.get("First"), h = c.dict.get("N"); if (!Number.isInteger(l) || !Number.isInteger(h)) throw new r.FormatError("invalid first and n parameters for ObjStm stream"); const u = new n.Parser({ lexer: new n.Lexer(c), xref: this, allowStreams: !0 }), d = new Array(h); for (let e = 0; e < h; ++e) { const t = u.getObj(); if (!Number.isInteger(t)) throw new r.FormatError(`invalid object number in the ObjStm stream: ${t}`); const a = u.getObj(); if (!Number.isInteger(a)) throw new r.FormatError(`invalid object offset in the ObjStm stream: ${a}`); d[e] = t } const f = new Array(h); for (let e = 0; e < h; ++e) { const t = u.getObj(); f[e] = t; u.buf1 instanceof i.Cmd && "endobj" === u.buf1.cmd && u.shift(); if ((0, i.isStream)(t)) continue; const a = d[e], r = this.entries[a]; r && r.offset === o && r.gen === e && this._cacheMap.set(a, t) } if (void 0 === (t = f[t.gen])) throw new s.XRefEntryException(`Bad (compressed) XRef entry: ${e}`); return t }, async fetchIfRefAsync(e, t) { return e instanceof i.Ref ? this.fetchAsync(e, t) : e }, async fetchAsync(e, t) { try { return this.fetch(e, t) } catch (a) { if (!(a instanceof s.MissingDataException)) throw a; await this.pdfManager.requestRange(a.begin, a.end); return this.fetchAsync(e, t) } }, getCatalogObj: function () { return this.root } }; return e }(); t.XRef = u; class d { constructor(e, t, a) { this.constructor === d && (0, r.unreachable)("Cannot initialize NameOrNumberTree."); this.root = e; this.xref = t; this._type = a } getAll() { const e = Object.create(null); if (!this.root) return e; const t = this.xref, a = new i.RefSet; a.put(this.root); const n = [this.root]; for (; n.length > 0;) { const s = t.fetchIfRef(n.shift()); if (!(0, i.isDict)(s)) continue; if (s.has("Kids")) { const e = s.get("Kids"); for (let t = 0, i = e.length; t < i; t++) { const i = e[t]; if (a.has(i)) throw new r.FormatError(`Duplicate entry in "${this._type}" tree.`); n.push(i); a.put(i) } continue } const o = s.get(this._type); if (Array.isArray(o)) for (let a = 0, r = o.length; a < r; a += 2)e[t.fetchIfRef(o[a])] = t.fetchIfRef(o[a + 1]) } return e } get(e) { if (!this.root) return null; const t = this.xref; let a = t.fetchIfRef(this.root), i = 0; for (; a.has("Kids");) { if (++i > 10) { (0, r.warn)(`Search depth limit reached for "${this._type}" tree.`); return null } const n = a.get("Kids"); if (!Array.isArray(n)) return null; let s = 0, o = n.length - 1; for (; s <= o;) { const r = s + o >> 1, i = t.fetchIfRef(n[r]).get("Limits"); if (e < t.fetchIfRef(i[0])) o = r - 1; else { if (!(e > t.fetchIfRef(i[1]))) { a = t.fetchIfRef(n[r]); break } s = r + 1 } } if (s > o) return null } const n = a.get(this._type); if (Array.isArray(n)) { let a = 0, i = n.length - 2; for (; a <= i;) { const r = a + i >> 1, s = r + (1 & r), o = t.fetchIfRef(n[s]); if (e < o) i = s - 2; else { if (!(e > o)) return t.fetchIfRef(n[s + 1]); a = s + 2 } } (0, r.info)(`Falling back to an exhaustive search, for key "${e}", ` + `in "${this._type}" tree.`); for (let a = 0, i = n.length; a < i; a += 2) { if (t.fetchIfRef(n[a]) === e) { (0, r.warn)(`The "${e}" key was found at an incorrect, ` + `i.e. out-of-order, position in "${this._type}" tree.`); return t.fetchIfRef(n[a + 1]) } } } return null } } class f extends d { constructor(e, t) { super(e, t, "Names") } } class g extends d { constructor(e, t) { super(e, t, "Nums") } } var m = function () { function e(e, t) { if (e && (0, i.isDict)(e)) { this.xref = t; this.root = e; e.has("FS") && (this.fs = e.get("FS")); this.description = e.has("Desc") ? (0, r.stringToPDFString)(e.get("Desc")) : ""; e.has("RF") && (0, r.warn)("Related file specifications are not supported"); this.contentAvailable = !0; if (!e.has("EF")) { this.contentAvailable = !1; (0, r.warn)("Non-embedded file specifications are not supported") } } } function t(e) { return e.has("UF") ? e.get("UF") : e.has("F") ? e.get("F") : e.has("Unix") ? e.get("Unix") : e.has("Mac") ? e.get("Mac") : e.has("DOS") ? e.get("DOS") : null } e.prototype = { get filename() { if (!this._filename && this.root) { var e = t(this.root) || "unnamed"; this._filename = (0, r.stringToPDFString)(e).replace(/\\\\/g, "\\").replace(/\\\//g, "/").replace(/\\/g, "/") } return this._filename }, get content() { if (!this.contentAvailable) return null; !this.contentRef && this.root && (this.contentRef = t(this.root.get("EF"))); var e = null; if (this.contentRef) { var a = this.xref.fetchIfRef(this.contentRef); a && (0, i.isStream)(a) ? e = a.getBytes() : (0, r.warn)("Embedded file specification points to non-existing/invalid content") } else (0, r.warn)("Embedded file specification does not have a content"); return e }, get serializable() { return { filename: this.filename, content: this.content } } }; return e }(); t.FileSpec = m; const p = function () { function e(e) { return e instanceof i.Ref || e instanceof i.Dict || Array.isArray(e) || (0, i.isStream)(e) } function t(t, a) { if (t instanceof i.Dict || (0, i.isStream)(t)) { const r = t instanceof i.Dict ? t : t.dict, n = r.getKeys(); for (let t = 0, i = n.length; t < i; t++) { const i = r.getRaw(n[t]); e(i) && a.push(i) } } else if (Array.isArray(t)) for (let r = 0, i = t.length; r < i; r++) { const i = t[r]; e(i) && a.push(i) } } function a(e, t, a) { this.dict = e; this.keys = t; this.xref = a; this.refSet = null } a.prototype = { async load() { if (!this.xref.stream.allChunksLoaded || this.xref.stream.allChunksLoaded()) return; const { keys: e, dict: t } = this; this.refSet = new i.RefSet; const a = []; for (let r = 0, i = e.length; r < i; r++) { const i = t.getRaw(e[r]); void 0 !== i && a.push(i) } return this._walk(a) }, async _walk(e) { const a = [], r = []; for (; e.length;) { let n = e.pop(); if (n instanceof i.Ref) { if (this.refSet.has(n)) continue; try { this.refSet.put(n); n = this.xref.fetch(n) } catch (e) { if (!(e instanceof s.MissingDataException)) throw e; a.push(n); r.push({ begin: e.begin, end: e.end }) } } if (n && n.getBaseStreams) { const e = n.getBaseStreams(); let t = !1; for (let a = 0, i = e.length; a < i; a++) { const i = e[a]; if (i.allChunksLoaded && !i.allChunksLoaded()) { t = !0; r.push({ begin: i.start, end: i.end }) } } t && a.push(n) } t(n, e) } if (r.length) { await this.xref.stream.manager.requestRanges(r); for (let e = 0, t = a.length; e < t; e++) { const t = a[e]; t instanceof i.Ref && this.refSet.remove(t) } return this._walk(a) } this.refSet = null } }; return a }(); t.ObjectLoader = p }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.Parser = t.Linearization = t.Lexer = void 0; var r = a(11), i = a(2), n = a(4), s = a(7), o = a(12), c = a(14), l = a(17), h = a(19); function u(e) { const t = e.length; let a = 1, r = 0; for (let i = 0; i < t; ++i) { a += 255 & e[i]; r += a } return r % 65521 << 16 | a % 65521 } class d { constructor({ lexer: e, xref: t, allowStreams: a = !1, recoveryMode: r = !1 }) { this.lexer = e; this.xref = t; this.allowStreams = a; this.recoveryMode = r; this.imageCache = Object.create(null); this.refill() } refill() { this.buf1 = this.lexer.getObj(); this.buf2 = this.lexer.getObj() } shift() { if (this.buf2 instanceof n.Cmd && "ID" === this.buf2.cmd) { this.buf1 = this.buf2; this.buf2 = null } else { this.buf1 = this.buf2; this.buf2 = this.lexer.getObj() } } tryShift() { try { this.shift(); return !0 } catch (e) { if (e instanceof s.MissingDataException) throw e; return !1 } } getObj(e = null) { const t = this.buf1; this.shift(); if (t instanceof n.Cmd) switch (t.cmd) { case "BI": return this.makeInlineImage(e); case "[": const a = []; for (; !(0, n.isCmd)(this.buf1, "]") && !(0, n.isEOF)(this.buf1);)a.push(this.getObj(e)); if ((0, n.isEOF)(this.buf1)) { if (!this.recoveryMode) throw new i.FormatError("End of file inside array"); return a } this.shift(); return a; case "<<": const r = new n.Dict(this.xref); for (; !(0, n.isCmd)(this.buf1, ">>") && !(0, n.isEOF)(this.buf1);) { if (!(0, n.isName)(this.buf1)) { (0, i.info)("Malformed dictionary: key must be a name object"); this.shift(); continue } const t = this.buf1.name; this.shift(); if ((0, n.isEOF)(this.buf1)) break; r.set(t, this.getObj(e)) } if ((0, n.isEOF)(this.buf1)) { if (!this.recoveryMode) throw new i.FormatError("End of file inside dictionary"); return r } if ((0, n.isCmd)(this.buf2, "stream")) return this.allowStreams ? this.makeStream(r, e) : r; this.shift(); return r; default: return t }if (Number.isInteger(t)) { if (Number.isInteger(this.buf1) && (0, n.isCmd)(this.buf2, "R")) { const e = n.Ref.get(t, this.buf1); this.shift(); this.shift(); return e } return t } return "string" == typeof t && e ? e.decryptString(t) : t } findDefaultInlineStreamEnd(e) { const t = e.pos; let a, r, n = 0; for (; -1 !== (a = e.getByte());)if (0 === n) n = 69 === a ? 1 : 0; else if (1 === n) n = 73 === a ? 2 : 0; else { (0, i.assert)(2 === n); if (32 === a || 10 === a || 13 === a) { r = e.pos; const t = e.peekBytes(10); for (let e = 0, r = t.length; e < r; e++) { a = t[e]; if ((0 !== a || 0 === t[e + 1]) && (10 !== a && 13 !== a && (a < 32 || a > 127))) { n = 0; break } } if (2 === n) break } else n = 0 } if (-1 === a) { (0, i.warn)("findDefaultInlineStreamEnd: Reached the end of the stream without finding a valid EI marker"); if (r) { (0, i.warn)('... trying to recover by using the last "EI" occurrence.'); e.skip(-(e.pos - r)) } } let o = 4; e.skip(-o); a = e.peekByte(); e.skip(o); (0, s.isWhiteSpace)(a) || o--; return e.pos - o - t } findDCTDecodeInlineStreamEnd(e) { const t = e.pos; let a, r, n = !1; for (; -1 !== (a = e.getByte());)if (255 === a) { switch (e.getByte()) { case 0: break; case 255: e.skip(-1); break; case 217: n = !0; break; case 192: case 193: case 194: case 195: case 197: case 198: case 199: case 201: case 202: case 203: case 205: case 206: case 207: case 196: case 204: case 218: case 219: case 220: case 221: case 222: case 223: case 224: case 225: case 226: case 227: case 228: case 229: case 230: case 231: case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239: case 254: r = e.getUint16(); r > 2 ? e.skip(r - 2) : e.skip(-2) }if (n) break } const s = e.pos - t; if (-1 === a) { (0, i.warn)("Inline DCTDecode image stream: EOI marker not found, searching for /EI/ instead."); e.skip(-s); return this.findDefaultInlineStreamEnd(e) } this.inlineStreamSkipEI(e); return s } findASCII85DecodeInlineStreamEnd(e) { const t = e.pos; let a; for (; -1 !== (a = e.getByte());)if (126 === a) { const t = e.pos; a = e.peekByte(); for (; (0, s.isWhiteSpace)(a);) { e.skip(); a = e.peekByte() } if (62 === a) { e.skip(); break } if (e.pos > t) { const t = e.peekBytes(2); if (69 === t[0] && 73 === t[1]) break } } const r = e.pos - t; if (-1 === a) { (0, i.warn)("Inline ASCII85Decode image stream: EOD marker not found, searching for /EI/ instead."); e.skip(-r); return this.findDefaultInlineStreamEnd(e) } this.inlineStreamSkipEI(e); return r } findASCIIHexDecodeInlineStreamEnd(e) { const t = e.pos; let a; for (; -1 !== (a = e.getByte()) && 62 !== a;); const r = e.pos - t; if (-1 === a) { (0, i.warn)("Inline ASCIIHexDecode image stream: EOD marker not found, searching for /EI/ instead."); e.skip(-r); return this.findDefaultInlineStreamEnd(e) } this.inlineStreamSkipEI(e); return r } inlineStreamSkipEI(e) { let t, a = 0; for (; -1 !== (t = e.getByte());)if (0 === a) a = 69 === t ? 1 : 0; else if (1 === a) a = 73 === t ? 2 : 0; else if (2 === a) break } makeInlineImage(e) { const t = this.lexer, a = t.stream, r = new n.Dict(this.xref); let s; for (; !(0, n.isCmd)(this.buf1, "ID") && !(0, n.isEOF)(this.buf1);) { if (!(0, n.isName)(this.buf1)) throw new i.FormatError("Dictionary key must be a name object"); const t = this.buf1.name; this.shift(); if ((0, n.isEOF)(this.buf1)) break; r.set(t, this.getObj(e)) } -1 !== t.beginInlineImagePos && (s = a.pos - t.beginInlineImagePos); const o = r.get("Filter", "F"); let c; if ((0, n.isName)(o)) c = o.name; else if (Array.isArray(o)) { const e = this.xref.fetchIfRef(o[0]); (0, n.isName)(e) && (c = e.name) } const l = a.pos; let h; h = "DCTDecode" === c || "DCT" === c ? this.findDCTDecodeInlineStreamEnd(a) : "ASCII85Decode" === c || "A85" === c ? this.findASCII85DecodeInlineStreamEnd(a) : "ASCIIHexDecode" === c || "AHx" === c ? this.findASCIIHexDecodeInlineStreamEnd(a) : this.findDefaultInlineStreamEnd(a); let d, f = a.makeSubStream(l, h, r); if (h < 1e3 && s < 5552) { const e = f.getBytes(); f.reset(); const r = a.pos; a.pos = t.beginInlineImagePos; const i = a.getBytes(s); a.pos = r; d = u(e) + "_" + u(i); const o = this.imageCache[d]; if (void 0 !== o) { this.buf2 = n.Cmd.get("EI"); this.shift(); o.reset(); return o } } e && (f = e.createStream(f, h)); f = this.filter(f, r, h); f.dict = r; if (void 0 !== d) { f.cacheKey = `inline_${h}_${d}`; this.imageCache[d] = f } this.buf2 = n.Cmd.get("EI"); this.shift(); return f } _findStreamLength(e, t) { const { stream: a } = this.lexer; a.pos = e; const r = t.length; for (; a.pos < a.end;) { const i = a.peekBytes(2048), n = i.length - r; if (n <= 0) break; let s = 0; for (; s < n;) { let n = 0; for (; n < r && i[s + n] === t[n];)n++; if (n >= r) { a.pos += s; return a.pos - e } s++ } a.pos += n } return -1 } makeStream(e, t) { const a = this.lexer; let r = a.stream; a.skipToNextLine(); const o = r.pos - 1; let c = e.get("Length"); if (!Number.isInteger(c)) { (0, i.info)(`Bad length "${c}" in stream`); c = 0 } r.pos = o + c; a.nextChar(); if (this.tryShift() && (0, n.isCmd)(this.buf2, "endstream")) this.shift(); else { const e = new Uint8Array([101, 110, 100, 115, 116, 114, 101, 97, 109]); let t = this._findStreamLength(o, e); if (t < 0) { const a = 1; for (let n = 1; n <= a; n++) { const a = e.length - n, c = e.slice(0, a), l = this._findStreamLength(o, c); if (l >= 0) { const e = r.peekBytes(a + 1)[a]; if (!(0, s.isWhiteSpace)(e)) break; (0, i.info)(`Found "${(0, i.bytesToString)(c)}" when ` + "searching for endstream command."); t = l; break } } if (t < 0) throw new i.FormatError("Missing endstream command.") } c = t; a.nextChar(); this.shift(); this.shift() } this.shift(); r = r.makeSubStream(o, c, e); t && (r = t.createStream(r, c)); r = this.filter(r, e, c); r.dict = e; return r } filter(e, t, a) { let r = t.get("Filter", "F"), s = t.get("DecodeParms", "DP"); if ((0, n.isName)(r)) { Array.isArray(s) && (0, i.warn)("/DecodeParms should not contain an Array, when /Filter contains a Name."); return this.makeFilter(e, r.name, a, s) } let o = a; if (Array.isArray(r)) { const t = r, a = s; for (let c = 0, l = t.length; c < l; ++c) { r = this.xref.fetchIfRef(t[c]); if (!(0, n.isName)(r)) throw new i.FormatError(`Bad filter name "${r}"`); s = null; Array.isArray(a) && c in a && (s = this.xref.fetchIfRef(a[c])); e = this.makeFilter(e, r.name, o, s); o = null } } return e } makeFilter(e, t, a, n) { if (0 === a) { (0, i.warn)(`Empty "${t}" stream.`); return new r.NullStream } try { const s = this.xref.stats.streamTypes; if ("FlateDecode" === t || "Fl" === t) { s[i.StreamType.FLATE] = !0; return n ? new r.PredictorStream(new r.FlateStream(e, a), a, n) : new r.FlateStream(e, a) } if ("LZWDecode" === t || "LZW" === t) { s[i.StreamType.LZW] = !0; let t = 1; if (n) { n.has("EarlyChange") && (t = n.get("EarlyChange")); return new r.PredictorStream(new r.LZWStream(e, a, t), a, n) } return new r.LZWStream(e, a, t) } if ("DCTDecode" === t || "DCT" === t) { s[i.StreamType.DCT] = !0; return new l.JpegStream(e, a, e.dict, n) } if ("JPXDecode" === t || "JPX" === t) { s[i.StreamType.JPX] = !0; return new h.JpxStream(e, a, e.dict, n) } if ("ASCII85Decode" === t || "A85" === t) { s[i.StreamType.A85] = !0; return new r.Ascii85Stream(e, a) } if ("ASCIIHexDecode" === t || "AHx" === t) { s[i.StreamType.AHX] = !0; return new r.AsciiHexStream(e, a) } if ("CCITTFaxDecode" === t || "CCF" === t) { s[i.StreamType.CCF] = !0; return new o.CCITTFaxStream(e, a, n) } if ("RunLengthDecode" === t || "RL" === t) { s[i.StreamType.RLX] = !0; return new r.RunLengthStream(e, a) } if ("JBIG2Decode" === t) { s[i.StreamType.JBIG] = !0; return new c.Jbig2Stream(e, a, e.dict, n) } (0, i.warn)(`Filter "${t}" is not supported.`); return e } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, i.warn)(`Invalid stream: "${e}"`); return new r.NullStream } } } t.Parser = d; const f = [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; function g(e) { return e >= 48 && e <= 57 ? 15 & e : e >= 65 && e <= 70 || e >= 97 && e <= 102 ? 9 + (15 & e) : -1 } class m { constructor(e, t = null) { this.stream = e; this.nextChar(); this.strBuf = []; this.knownCommands = t; this._hexStringNumWarn = 0; this.beginInlineImagePos = -1 } nextChar() { return this.currentChar = this.stream.getByte() } peekChar() { return this.stream.peekByte() } getNumber() { let e = this.currentChar, t = !1, a = 0, r = 0; if (45 === e) { r = -1; e = this.nextChar(); 45 === e && (e = this.nextChar()) } else if (43 === e) { r = 1; e = this.nextChar() } if (10 === e || 13 === e) do { e = this.nextChar() } while (10 === e || 13 === e); if (46 === e) { a = 10; e = this.nextChar() } if (e < 48 || e > 57) { if (10 === a && 0 === r && ((0, s.isWhiteSpace)(e) || -1 === e)) { (0, i.warn)("Lexer.getNumber - treating a single decimal point as zero."); return 0 } throw new i.FormatError(`Invalid number: ${String.fromCharCode(e)} (charCode ${e})`) } r = r || 1; let n = e - 48, o = 0, c = 1; for (; (e = this.nextChar()) >= 0;)if (e >= 48 && e <= 57) { const r = e - 48; if (t) o = 10 * o + r; else { 0 !== a && (a *= 10); n = 10 * n + r } } else if (46 === e) { if (0 !== a) break; a = 1 } else if (45 === e) (0, i.warn)("Badly formatted number: minus sign in the middle"); else { if (69 !== e && 101 !== e) break; e = this.peekChar(); if (43 === e || 45 === e) { c = 45 === e ? -1 : 1; this.nextChar() } else if (e < 48 || e > 57) break; t = !0 } 0 !== a && (n /= a); t && (n *= 10 ** (c * o)); return r * n } getString() { let e = 1, t = !1; const a = this.strBuf; a.length = 0; let r = this.nextChar(); for (; ;) { let n = !1; switch (0 | r) { case -1: (0, i.warn)("Unterminated string"); t = !0; break; case 40: ++e; a.push("("); break; case 41: if (0 == --e) { this.nextChar(); t = !0 } else a.push(")"); break; case 92: r = this.nextChar(); switch (r) { case -1: (0, i.warn)("Unterminated string"); t = !0; break; case 110: a.push("\n"); break; case 114: a.push("\r"); break; case 116: a.push("\t"); break; case 98: a.push("\b"); break; case 102: a.push("\f"); break; case 92: case 40: case 41: a.push(String.fromCharCode(r)); break; case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: let e = 15 & r; r = this.nextChar(); n = !0; if (r >= 48 && r <= 55) { e = (e << 3) + (15 & r); r = this.nextChar(); if (r >= 48 && r <= 55) { n = !1; e = (e << 3) + (15 & r) } } a.push(String.fromCharCode(e)); break; case 13: 10 === this.peekChar() && this.nextChar(); break; case 10: break; default: a.push(String.fromCharCode(r)) }break; default: a.push(String.fromCharCode(r)) }if (t) break; n || (r = this.nextChar()) } return a.join("") } getName() { let e, t; const a = this.strBuf; a.length = 0; for (; (e = this.nextChar()) >= 0 && !f[e];)if (35 === e) { e = this.nextChar(); if (f[e]) { (0, i.warn)("Lexer_getName: NUMBER SIGN (#) should be followed by a hexadecimal number."); a.push("#"); break } const r = g(e); if (-1 !== r) { t = e; e = this.nextChar(); const n = g(e); if (-1 === n) { (0, i.warn)(`Lexer_getName: Illegal digit (${String.fromCharCode(e)}) ` + "in hexadecimal number."); a.push("#", String.fromCharCode(t)); if (f[e]) break; a.push(String.fromCharCode(e)); continue } a.push(String.fromCharCode(r << 4 | n)) } else a.push("#", String.fromCharCode(e)) } else a.push(String.fromCharCode(e)); a.length > 127 && (0, i.warn)(`Name token is longer than allowed by the spec: ${a.length}`); return n.Name.get(a.join("")) } _hexStringWarn(e) { 5 != this._hexStringNumWarn++ ? this._hexStringNumWarn > 5 || (0, i.warn)(`getHexString - ignoring invalid character: ${e}`) : (0, i.warn)("getHexString - ignoring additional invalid characters.") } getHexString() { const e = this.strBuf; e.length = 0; let t, a, r = this.currentChar, n = !0; this._hexStringNumWarn = 0; for (; ;) { if (r < 0) { (0, i.warn)("Unterminated hex string"); break } if (62 === r) { this.nextChar(); break } if (1 !== f[r]) { if (n) { t = g(r); if (-1 === t) { this._hexStringWarn(r); r = this.nextChar(); continue } } else { a = g(r); if (-1 === a) { this._hexStringWarn(r); r = this.nextChar(); continue } e.push(String.fromCharCode(t << 4 | a)) } n = !n; r = this.nextChar() } else r = this.nextChar() } return e.join("") } getObj() { let e = !1, t = this.currentChar; for (; ;) { if (t < 0) return n.EOF; if (e) 10 !== t && 13 !== t || (e = !1); else if (37 === t) e = !0; else if (1 !== f[t]) break; t = this.nextChar() } switch (0 | t) { case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 43: case 45: case 46: return this.getNumber(); case 40: return this.getString(); case 47: return this.getName(); case 91: this.nextChar(); return n.Cmd.get("["); case 93: this.nextChar(); return n.Cmd.get("]"); case 60: t = this.nextChar(); if (60 === t) { this.nextChar(); return n.Cmd.get("<<") } return this.getHexString(); case 62: t = this.nextChar(); if (62 === t) { this.nextChar(); return n.Cmd.get(">>") } return n.Cmd.get(">"); case 123: this.nextChar(); return n.Cmd.get("{"); case 125: this.nextChar(); return n.Cmd.get("}"); case 41: this.nextChar(); throw new i.FormatError(`Illegal character: ${t}`) }let a = String.fromCharCode(t); const r = this.knownCommands; let s = r && void 0 !== r[a]; for (; (t = this.nextChar()) >= 0 && !f[t];) { const e = a + String.fromCharCode(t); if (s && void 0 === r[e]) break; if (128 === a.length) throw new i.FormatError(`Command token too long: ${a.length}`); a = e; s = r && void 0 !== r[a] } if ("true" === a) return !0; if ("false" === a) return !1; if ("null" === a) return null; "BI" === a && (this.beginInlineImagePos = this.stream.pos); return n.Cmd.get(a) } skipToNextLine() { let e = this.currentChar; for (; e >= 0;) { if (13 === e) { e = this.nextChar(); 10 === e && this.nextChar(); break } if (10 === e) { this.nextChar(); break } e = this.nextChar() } } } t.Lexer = m; t.Linearization = class { static create(e) { function t(e, t, a = !1) { const r = e.get(t); if (Number.isInteger(r) && (a ? r >= 0 : r > 0)) return r; throw new Error(`The "${t}" parameter in the linearization ` + "dictionary is invalid.") } const a = new d({ lexer: new m(e), xref: null }), r = a.getObj(), s = a.getObj(), o = a.getObj(), c = a.getObj(); let l, h; if (!(Number.isInteger(r) && Number.isInteger(s) && (0, n.isCmd)(o, "obj") && (0, n.isDict)(c) && (0, i.isNum)(l = c.get("Linearized")) && l > 0)) return null; if ((h = t(c, "L")) !== e.length) throw new Error('The "L" parameter in the linearization dictionary does not equal the stream length.'); return { length: h, hints: function (e) { const t = e.get("H"); let a; if (Array.isArray(t) && (2 === (a = t.length) || 4 === a)) { for (let e = 0; e < a; e++) { const a = t[e]; if (!(Number.isInteger(a) && a > 0)) throw new Error(`Hint (${e}) in the linearization dictionary is invalid.`) } return t } throw new Error("Hint array in the linearization dictionary is invalid.") }(c), objectNumberFirst: t(c, "O"), endFirst: t(c, "E"), numPages: t(c, "N"), mainXRefEntriesOffset: t(c, "T"), pageFirst: c.has("P") ? t(c, "P", !0) : 0 } } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.LZWStream = t.StringStream = t.StreamsSequenceStream = t.Stream = t.RunLengthStream = t.PredictorStream = t.NullStream = t.FlateStream = t.DecodeStream = t.DecryptStream = t.AsciiHexStream = t.Ascii85Stream = void 0; var r = a(2), i = a(4), n = a(7), s = function () { function e(e, t, a, r) { this.bytes = e instanceof Uint8Array ? e : new Uint8Array(e); this.start = t || 0; this.pos = this.start; this.end = t + a || this.bytes.length; this.dict = r } e.prototype = { get length() { return this.end - this.start }, get isEmpty() { return 0 === this.length }, getByte: function () { return this.pos >= this.end ? -1 : this.bytes[this.pos++] }, getUint16: function () { var e = this.getByte(), t = this.getByte(); return -1 === e || -1 === t ? -1 : (e << 8) + t }, getInt32: function () { return (this.getByte() << 24) + (this.getByte() << 16) + (this.getByte() << 8) + this.getByte() }, getBytes(e, t = !1) { var a = this.bytes, r = this.pos, i = this.end; if (!e) { const e = a.subarray(r, i); return t ? new Uint8ClampedArray(e) : e } var n = r + e; n > i && (n = i); this.pos = n; const s = a.subarray(r, n); return t ? new Uint8ClampedArray(s) : s }, peekByte: function () { var e = this.getByte(); -1 !== e && this.pos--; return e }, peekBytes(e, t = !1) { var a = this.getBytes(e, t); this.pos -= a.length; return a }, getByteRange(e, t) { e < 0 && (e = 0); t > this.end && (t = this.end); return this.bytes.subarray(e, t) }, skip: function (e) { e || (e = 1); this.pos += e }, reset: function () { this.pos = this.start }, moveStart: function () { this.start = this.pos }, makeSubStream: function (t, a, r) { return new e(this.bytes.buffer, t, a, r) } }; return e }(); t.Stream = s; var o = function () { function e(e) { const t = (0, r.stringToBytes)(e); s.call(this, t) } e.prototype = s.prototype; return e }(); t.StringStream = o; var c = function () { var e = new Uint8Array(0); function t(t) { this._rawMinBufferLength = t || 0; this.pos = 0; this.bufferLength = 0; this.eof = !1; this.buffer = e; this.minBufferLength = 512; if (t) for (; this.minBufferLength < t;)this.minBufferLength *= 2 } t.prototype = { get isEmpty() { for (; !this.eof && 0 === this.bufferLength;)this.readBlock(); return 0 === this.bufferLength }, ensureBuffer: function (e) { var t = this.buffer; if (e <= t.byteLength) return t; for (var a = this.minBufferLength; a < e;)a *= 2; var r = new Uint8Array(a); r.set(t); return this.buffer = r }, getByte: function () { for (var e = this.pos; this.bufferLength <= e;) { if (this.eof) return -1; this.readBlock() } return this.buffer[this.pos++] }, getUint16: function () { var e = this.getByte(), t = this.getByte(); return -1 === e || -1 === t ? -1 : (e << 8) + t }, getInt32: function () { return (this.getByte() << 24) + (this.getByte() << 16) + (this.getByte() << 8) + this.getByte() }, getBytes(e, t = !1) { var a, r = this.pos; if (e) { this.ensureBuffer(r + e); a = r + e; for (; !this.eof && this.bufferLength < a;)this.readBlock(); var i = this.bufferLength; a > i && (a = i) } else { for (; !this.eof;)this.readBlock(); a = this.bufferLength } this.pos = a; const n = this.buffer.subarray(r, a); return !t || n instanceof Uint8ClampedArray ? n : new Uint8ClampedArray(n) }, peekByte: function () { var e = this.getByte(); -1 !== e && this.pos--; return e }, peekBytes(e, t = !1) { var a = this.getBytes(e, t); this.pos -= a.length; return a }, makeSubStream: function (e, t, a) { for (var r = e + t; this.bufferLength <= r && !this.eof;)this.readBlock(); return new s(this.buffer, e, t, a) }, getByteRange(e, t) { (0, r.unreachable)("Should not call DecodeStream.getByteRange") }, skip: function (e) { e || (e = 1); this.pos += e }, reset: function () { this.pos = 0 }, getBaseStreams: function () { return this.str && this.str.getBaseStreams ? this.str.getBaseStreams() : [] } }; return t }(); t.DecodeStream = c; var l = function () { function e(e) { this.streams = e; let t = 0; for (let a = 0, r = e.length; a < r; a++) { const r = e[a]; t += r instanceof c ? r._rawMinBufferLength : r.length } c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { var e = this.streams; if (0 !== e.length) { var t = e.shift().getBytes(), a = this.bufferLength, r = a + t.length; this.ensureBuffer(r).set(t, a); this.bufferLength = r } else this.eof = !0 }; e.prototype.getBaseStreams = function () { for (var e = [], t = 0, a = this.streams.length; t < a; t++) { var r = this.streams[t]; r.getBaseStreams && e.push(...r.getBaseStreams()) } return e }; return e }(); t.StreamsSequenceStream = l; var h = function () { var e = new Int32Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]), t = new Int32Array([3, 4, 5, 6, 7, 8, 9, 10, 65547, 65549, 65551, 65553, 131091, 131095, 131099, 131103, 196643, 196651, 196659, 196667, 262211, 262227, 262243, 262259, 327811, 327843, 327875, 327907, 258, 258, 258]), a = new Int32Array([1, 2, 3, 4, 65541, 65543, 131081, 131085, 196625, 196633, 262177, 262193, 327745, 327777, 393345, 393409, 459009, 459137, 524801, 525057, 590849, 591361, 657409, 658433, 724993, 727041, 794625, 798721, 868353, 876545]), i = [new Int32Array([459008, 524368, 524304, 524568, 459024, 524400, 524336, 590016, 459016, 524384, 524320, 589984, 524288, 524416, 524352, 590048, 459012, 524376, 524312, 589968, 459028, 524408, 524344, 590032, 459020, 524392, 524328, 59e4, 524296, 524424, 524360, 590064, 459010, 524372, 524308, 524572, 459026, 524404, 524340, 590024, 459018, 524388, 524324, 589992, 524292, 524420, 524356, 590056, 459014, 524380, 524316, 589976, 459030, 524412, 524348, 590040, 459022, 524396, 524332, 590008, 524300, 524428, 524364, 590072, 459009, 524370, 524306, 524570, 459025, 524402, 524338, 590020, 459017, 524386, 524322, 589988, 524290, 524418, 524354, 590052, 459013, 524378, 524314, 589972, 459029, 524410, 524346, 590036, 459021, 524394, 524330, 590004, 524298, 524426, 524362, 590068, 459011, 524374, 524310, 524574, 459027, 524406, 524342, 590028, 459019, 524390, 524326, 589996, 524294, 524422, 524358, 590060, 459015, 524382, 524318, 589980, 459031, 524414, 524350, 590044, 459023, 524398, 524334, 590012, 524302, 524430, 524366, 590076, 459008, 524369, 524305, 524569, 459024, 524401, 524337, 590018, 459016, 524385, 524321, 589986, 524289, 524417, 524353, 590050, 459012, 524377, 524313, 589970, 459028, 524409, 524345, 590034, 459020, 524393, 524329, 590002, 524297, 524425, 524361, 590066, 459010, 524373, 524309, 524573, 459026, 524405, 524341, 590026, 459018, 524389, 524325, 589994, 524293, 524421, 524357, 590058, 459014, 524381, 524317, 589978, 459030, 524413, 524349, 590042, 459022, 524397, 524333, 590010, 524301, 524429, 524365, 590074, 459009, 524371, 524307, 524571, 459025, 524403, 524339, 590022, 459017, 524387, 524323, 589990, 524291, 524419, 524355, 590054, 459013, 524379, 524315, 589974, 459029, 524411, 524347, 590038, 459021, 524395, 524331, 590006, 524299, 524427, 524363, 590070, 459011, 524375, 524311, 524575, 459027, 524407, 524343, 590030, 459019, 524391, 524327, 589998, 524295, 524423, 524359, 590062, 459015, 524383, 524319, 589982, 459031, 524415, 524351, 590046, 459023, 524399, 524335, 590014, 524303, 524431, 524367, 590078, 459008, 524368, 524304, 524568, 459024, 524400, 524336, 590017, 459016, 524384, 524320, 589985, 524288, 524416, 524352, 590049, 459012, 524376, 524312, 589969, 459028, 524408, 524344, 590033, 459020, 524392, 524328, 590001, 524296, 524424, 524360, 590065, 459010, 524372, 524308, 524572, 459026, 524404, 524340, 590025, 459018, 524388, 524324, 589993, 524292, 524420, 524356, 590057, 459014, 524380, 524316, 589977, 459030, 524412, 524348, 590041, 459022, 524396, 524332, 590009, 524300, 524428, 524364, 590073, 459009, 524370, 524306, 524570, 459025, 524402, 524338, 590021, 459017, 524386, 524322, 589989, 524290, 524418, 524354, 590053, 459013, 524378, 524314, 589973, 459029, 524410, 524346, 590037, 459021, 524394, 524330, 590005, 524298, 524426, 524362, 590069, 459011, 524374, 524310, 524574, 459027, 524406, 524342, 590029, 459019, 524390, 524326, 589997, 524294, 524422, 524358, 590061, 459015, 524382, 524318, 589981, 459031, 524414, 524350, 590045, 459023, 524398, 524334, 590013, 524302, 524430, 524366, 590077, 459008, 524369, 524305, 524569, 459024, 524401, 524337, 590019, 459016, 524385, 524321, 589987, 524289, 524417, 524353, 590051, 459012, 524377, 524313, 589971, 459028, 524409, 524345, 590035, 459020, 524393, 524329, 590003, 524297, 524425, 524361, 590067, 459010, 524373, 524309, 524573, 459026, 524405, 524341, 590027, 459018, 524389, 524325, 589995, 524293, 524421, 524357, 590059, 459014, 524381, 524317, 589979, 459030, 524413, 524349, 590043, 459022, 524397, 524333, 590011, 524301, 524429, 524365, 590075, 459009, 524371, 524307, 524571, 459025, 524403, 524339, 590023, 459017, 524387, 524323, 589991, 524291, 524419, 524355, 590055, 459013, 524379, 524315, 589975, 459029, 524411, 524347, 590039, 459021, 524395, 524331, 590007, 524299, 524427, 524363, 590071, 459011, 524375, 524311, 524575, 459027, 524407, 524343, 590031, 459019, 524391, 524327, 589999, 524295, 524423, 524359, 590063, 459015, 524383, 524319, 589983, 459031, 524415, 524351, 590047, 459023, 524399, 524335, 590015, 524303, 524431, 524367, 590079]), 9], n = [new Int32Array([327680, 327696, 327688, 327704, 327684, 327700, 327692, 327708, 327682, 327698, 327690, 327706, 327686, 327702, 327694, 0, 327681, 327697, 327689, 327705, 327685, 327701, 327693, 327709, 327683, 327699, 327691, 327707, 327687, 327703, 327695, 0]), 5]; function s(e, t) { this.str = e; this.dict = e.dict; var a = e.getByte(), i = e.getByte(); if (-1 === a || -1 === i) throw new r.FormatError(`Invalid header in flate stream: ${a}, ${i}`); if (8 != (15 & a)) throw new r.FormatError(`Unknown compression method in flate stream: ${a}, ${i}`); if (((a << 8) + i) % 31 != 0) throw new r.FormatError(`Bad FCHECK in flate stream: ${a}, ${i}`); if (32 & i) throw new r.FormatError(`FDICT bit set in flate stream: ${a}, ${i}`); this.codeSize = 0; this.codeBuf = 0; c.call(this, t) } s.prototype = Object.create(c.prototype); s.prototype.getBits = function (e) { for (var t, a = this.str, i = this.codeSize, n = this.codeBuf; i < e;) { if (-1 === (t = a.getByte())) throw new r.FormatError("Bad encoding in flate stream"); n |= t << i; i += 8 } t = n & (1 << e) - 1; this.codeBuf = n >> e; this.codeSize = i -= e; return t }; s.prototype.getCode = function (e) { for (var t, a = this.str, i = e[0], n = e[1], s = this.codeSize, o = this.codeBuf; s < n && -1 !== (t = a.getByte());) { o |= t << s; s += 8 } var c = i[o & (1 << n) - 1], l = c >> 16, h = 65535 & c; if (l < 1 || s < l) throw new r.FormatError("Bad encoding in flate stream"); this.codeBuf = o >> l; this.codeSize = s - l; return h }; s.prototype.generateHuffmanTable = function (e) { var t, a = e.length, r = 0; for (t = 0; t < a; ++t)e[t] > r && (r = e[t]); for (var i = 1 << r, n = new Int32Array(i), s = 1, o = 0, c = 2; s <= r; ++s, o <<= 1, c <<= 1)for (var l = 0; l < a; ++l)if (e[l] === s) { var h = 0, u = o; for (t = 0; t < s; ++t) { h = h << 1 | 1 & u; u >>= 1 } for (t = h; t < i; t += c)n[t] = s << 16 | l; ++o } return [n, r] }; s.prototype.readBlock = function () { var s, o, c = this.str, l = this.getBits(3); 1 & l && (this.eof = !0); if (0 !== (l >>= 1)) { var h, u; if (1 === l) { h = i; u = n } else { if (2 !== l) throw new r.FormatError("Unknown block type in flate stream"); var d, f = this.getBits(5) + 257, g = this.getBits(5) + 1, m = this.getBits(4) + 4, p = new Uint8Array(e.length); for (d = 0; d < m; ++d)p[e[d]] = this.getBits(3); var b = this.generateHuffmanTable(p); o = 0; d = 0; for (var y, v, w, k = f + g, S = new Uint8Array(k); d < k;) { var C = this.getCode(b); if (16 === C) { y = 2; v = 3; w = o } else if (17 === C) { y = 3; v = 3; w = o = 0 } else { if (18 !== C) { S[d++] = o = C; continue } y = 7; v = 11; w = o = 0 } for (var x = this.getBits(y) + v; x-- > 0;)S[d++] = w } h = this.generateHuffmanTable(S.subarray(0, f)); u = this.generateHuffmanTable(S.subarray(f, k)) } for (var A = (s = this.buffer) ? s.length : 0, I = this.bufferLength; ;) { var F = this.getCode(h); if (F < 256) { I + 1 >= A && (A = (s = this.ensureBuffer(I + 1)).length); s[I++] = F } else { if (256 === F) { this.bufferLength = I; return } var T = (F = t[F -= 257]) >> 16; T > 0 && (T = this.getBits(T)); o = (65535 & F) + T; F = this.getCode(u); (T = (F = a[F]) >> 16) > 0 && (T = this.getBits(T)); var E = (65535 & F) + T; I + o >= A && (A = (s = this.ensureBuffer(I + o)).length); for (var O = 0; O < o; ++O, ++I)s[I] = s[I - E] } } } else { var P; if (-1 === (P = c.getByte())) throw new r.FormatError("Bad block header in flate stream"); var B = P; if (-1 === (P = c.getByte())) throw new r.FormatError("Bad block header in flate stream"); B |= P << 8; if (-1 === (P = c.getByte())) throw new r.FormatError("Bad block header in flate stream"); var D = P; if (-1 === (P = c.getByte())) throw new r.FormatError("Bad block header in flate stream"); if ((D |= P << 8) !== (65535 & ~B) && (0 !== B || 0 !== D)) throw new r.FormatError("Bad uncompressed block length in flate stream"); this.codeBuf = 0; this.codeSize = 0; const e = this.bufferLength, t = e + B; s = this.ensureBuffer(t); this.bufferLength = t; if (0 === B) -1 === c.peekByte() && (this.eof = !0); else { const t = c.getBytes(B); s.set(t, e); t.length < B && (this.eof = !0) } } }; return s }(); t.FlateStream = h; var u = function () { function e(e, t, a) { if (!(0, i.isDict)(a)) return e; var n = this.predictor = a.get("Predictor") || 1; if (n <= 1) return e; if (2 !== n && (n < 10 || n > 15)) throw new r.FormatError(`Unsupported predictor: ${n}`); this.readBlock = 2 === n ? this.readBlockTiff : this.readBlockPng; this.str = e; this.dict = e.dict; var s = this.colors = a.get("Colors") || 1, o = this.bits = a.get("BitsPerComponent") || 8, l = this.columns = a.get("Columns") || 1; this.pixBytes = s * o + 7 >> 3; this.rowBytes = l * s * o + 7 >> 3; c.call(this, t); return this } e.prototype = Object.create(c.prototype); e.prototype.readBlockTiff = function () { var e = this.rowBytes, t = this.bufferLength, a = this.ensureBuffer(t + e), r = this.bits, i = this.colors, n = this.str.getBytes(e); this.eof = !n.length; if (!this.eof) { var s, o = 0, c = 0, l = 0, h = 0, u = t; if (1 === r && 1 === i) for (s = 0; s < e; ++s) { var d = n[s] ^ o; d ^= d >> 1; d ^= d >> 2; o = (1 & (d ^= d >> 4)) << 7; a[u++] = d } else if (8 === r) { for (s = 0; s < i; ++s)a[u++] = n[s]; for (; s < e; ++s) { a[u] = a[u - i] + n[s]; u++ } } else if (16 === r) { var f = 2 * i; for (s = 0; s < f; ++s)a[u++] = n[s]; for (; s < e; s += 2) { var g = ((255 & n[s]) << 8) + (255 & n[s + 1]) + ((255 & a[u - f]) << 8) + (255 & a[u - f + 1]); a[u++] = g >> 8 & 255; a[u++] = 255 & g } } else { var m = new Uint8Array(i + 1), p = (1 << r) - 1, b = 0, y = t, v = this.columns; for (s = 0; s < v; ++s)for (var w = 0; w < i; ++w) { if (l < r) { o = o << 8 | 255 & n[b++]; l += 8 } m[w] = m[w] + (o >> l - r) & p; l -= r; c = c << r | m[w]; if ((h += r) >= 8) { a[y++] = c >> h - 8 & 255; h -= 8 } } h > 0 && (a[y++] = (c << 8 - h) + (o & (1 << 8 - h) - 1)) } this.bufferLength += e } }; e.prototype.readBlockPng = function () { var e = this.rowBytes, t = this.pixBytes, a = this.str.getByte(), i = this.str.getBytes(e); this.eof = !i.length; if (!this.eof) { var n = this.bufferLength, s = this.ensureBuffer(n + e), o = s.subarray(n - e, n); 0 === o.length && (o = new Uint8Array(e)); var c, l, h, u = n; switch (a) { case 0: for (c = 0; c < e; ++c)s[u++] = i[c]; break; case 1: for (c = 0; c < t; ++c)s[u++] = i[c]; for (; c < e; ++c) { s[u] = s[u - t] + i[c] & 255; u++ } break; case 2: for (c = 0; c < e; ++c)s[u++] = o[c] + i[c] & 255; break; case 3: for (c = 0; c < t; ++c)s[u++] = (o[c] >> 1) + i[c]; for (; c < e; ++c) { s[u] = (o[c] + s[u - t] >> 1) + i[c] & 255; u++ } break; case 4: for (c = 0; c < t; ++c) { l = o[c]; h = i[c]; s[u++] = l + h } for (; c < e; ++c) { l = o[c]; var d = o[c - t], f = s[u - t], g = f + l - d, m = g - f; m < 0 && (m = -m); var p = g - l; p < 0 && (p = -p); var b = g - d; b < 0 && (b = -b); h = i[c]; s[u++] = m <= p && m <= b ? f + h : p <= b ? l + h : d + h } break; default: throw new r.FormatError(`Unsupported predictor: ${a}`) }this.bufferLength += e } }; return e }(); t.PredictorStream = u; var d = function () { function e(e, t, a) { this.str = e; this.dict = e.dict; this.decrypt = a; this.nextChunk = null; this.initialized = !1; c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { var e; if (this.initialized) e = this.nextChunk; else { e = this.str.getBytes(512); this.initialized = !0 } if (e && 0 !== e.length) { this.nextChunk = this.str.getBytes(512); var t = this.nextChunk && this.nextChunk.length > 0; e = (0, this.decrypt)(e, !t); var a, r = this.bufferLength, i = e.length, n = this.ensureBuffer(r + i); for (a = 0; a < i; a++)n[r++] = e[a]; this.bufferLength = r } else this.eof = !0 }; return e }(); t.DecryptStream = d; var f = function () { function e(e, t) { this.str = e; this.dict = e.dict; this.input = new Uint8Array(5); t && (t *= .8); c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { for (var e = this.str, t = e.getByte(); (0, n.isWhiteSpace)(t);)t = e.getByte(); if (-1 !== t && 126 !== t) { var a, r, i = this.bufferLength; if (122 === t) { a = this.ensureBuffer(i + 4); for (r = 0; r < 4; ++r)a[i + r] = 0; this.bufferLength += 4 } else { var s = this.input; s[0] = t; for (r = 1; r < 5; ++r) { t = e.getByte(); for (; (0, n.isWhiteSpace)(t);)t = e.getByte(); s[r] = t; if (-1 === t || 126 === t) break } a = this.ensureBuffer(i + r - 1); this.bufferLength += r - 1; if (r < 5) { for (; r < 5; ++r)s[r] = 117; this.eof = !0 } var o = 0; for (r = 0; r < 5; ++r)o = 85 * o + (s[r] - 33); for (r = 3; r >= 0; --r) { a[i + r] = 255 & o; o >>= 8 } } } else this.eof = !0 }; return e }(); t.Ascii85Stream = f; var g = function () { function e(e, t) { this.str = e; this.dict = e.dict; this.firstDigit = -1; t && (t *= .5); c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { var e = this.str.getBytes(8e3); if (e.length) { for (var t = e.length + 1 >> 1, a = this.ensureBuffer(this.bufferLength + t), r = this.bufferLength, i = this.firstDigit, n = 0, s = e.length; n < s; n++) { var o, c = e[n]; if (c >= 48 && c <= 57) o = 15 & c; else { if (!(c >= 65 && c <= 70 || c >= 97 && c <= 102)) { if (62 === c) { this.eof = !0; break } continue } o = 9 + (15 & c) } if (i < 0) i = o; else { a[r++] = i << 4 | o; i = -1 } } if (i >= 0 && this.eof) { a[r++] = i << 4; i = -1 } this.firstDigit = i; this.bufferLength = r } else this.eof = !0 }; return e }(); t.AsciiHexStream = g; var m = function () { function e(e, t) { this.str = e; this.dict = e.dict; c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBlock = function () { var e = this.str.getBytes(2); if (!e || e.length < 2 || 128 === e[0]) this.eof = !0; else { var t, a = this.bufferLength, r = e[0]; if (r < 128) { (t = this.ensureBuffer(a + r + 1))[a++] = e[1]; if (r > 0) { var i = this.str.getBytes(r); t.set(i, a); a += r } } else { r = 257 - r; var n = e[1]; t = this.ensureBuffer(a + r + 1); for (var s = 0; s < r; s++)t[a++] = n } this.bufferLength = a } }; return e }(); t.RunLengthStream = m; var p = function () { function e(e, t, a) { this.str = e; this.dict = e.dict; this.cachedData = 0; this.bitsCached = 0; for (var r = { earlyChange: a, codeLength: 9, nextCode: 258, dictionaryValues: new Uint8Array(4096), dictionaryLengths: new Uint16Array(4096), dictionaryPrevCodes: new Uint16Array(4096), currentSequence: new Uint8Array(4096), currentSequenceLength: 0 }, i = 0; i < 256; ++i) { r.dictionaryValues[i] = i; r.dictionaryLengths[i] = 1 } this.lzwState = r; c.call(this, t) } e.prototype = Object.create(c.prototype); e.prototype.readBits = function (e) { for (var t = this.bitsCached, a = this.cachedData; t < e;) { var r = this.str.getByte(); if (-1 === r) { this.eof = !0; return null } a = a << 8 | r; t += 8 } this.bitsCached = t -= e; this.cachedData = a; this.lastCode = null; return a >>> t & (1 << e) - 1 }; e.prototype.readBlock = function () { var e, t, a, r = 1024, i = this.lzwState; if (i) { var n = i.earlyChange, s = i.nextCode, o = i.dictionaryValues, c = i.dictionaryLengths, l = i.dictionaryPrevCodes, h = i.codeLength, u = i.prevCode, d = i.currentSequence, f = i.currentSequenceLength, g = 0, m = this.bufferLength, p = this.ensureBuffer(this.bufferLength + r); for (e = 0; e < 512; e++) { var b = this.readBits(h), y = f > 0; if (b < 256) { d[0] = b; f = 1 } else { if (!(b >= 258)) { if (256 === b) { h = 9; s = 258; f = 0; continue } this.eof = !0; delete this.lzwState; break } if (b < s) for (t = (f = c[b]) - 1, a = b; t >= 0; t--) { d[t] = o[a]; a = l[a] } else d[f++] = d[0] } if (y) { l[s] = u; c[s] = c[u] + 1; o[s] = d[0]; h = ++s + n & s + n - 1 ? h : 0 | Math.min(Math.log(s + n) / .6931471805599453 + 1, 12) } u = b; if (r < (g += f)) { do { r += 512 } while (r < g); p = this.ensureBuffer(this.bufferLength + r) } for (t = 0; t < f; t++)p[m++] = d[t] } i.nextCode = s; i.codeLength = h; i.prevCode = u; i.currentSequenceLength = f; this.bufferLength = m } }; return e }(); t.LZWStream = p; var b = function () { function e() { s.call(this, new Uint8Array(0)) } e.prototype = s.prototype; return e }(); t.NullStream = b }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.CCITTFaxStream = void 0; var r = a(4), i = a(13), n = a(11), s = function () { function e(e, t, a) { this.str = e; this.dict = e.dict; (0, r.isDict)(a) || (a = r.Dict.empty); const s = { next: () => e.getByte() }; this.ccittFaxDecoder = new i.CCITTFaxDecoder(s, { K: a.get("K"), EndOfLine: a.get("EndOfLine"), EncodedByteAlign: a.get("EncodedByteAlign"), Columns: a.get("Columns"), Rows: a.get("Rows"), EndOfBlock: a.get("EndOfBlock"), BlackIs1: a.get("BlackIs1") }); n.DecodeStream.call(this, t) } e.prototype = Object.create(n.DecodeStream.prototype); e.prototype.readBlock = function () { for (; !this.eof;) { const e = this.ccittFaxDecoder.readNextChar(); if (-1 === e) { this.eof = !0; return } this.ensureBuffer(this.bufferLength + 1); this.buffer[this.bufferLength++] = e } }; return e }(); t.CCITTFaxStream = s }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.CCITTFaxDecoder = void 0; var r = a(2); const i = function () { const e = [[-1, -1], [-1, -1], [7, 8], [7, 7], [6, 6], [6, 6], [6, 5], [6, 5], [4, 0], [4, 0], [4, 0], [4, 0], [4, 0], [4, 0], [4, 0], [4, 0], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [3, 3], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2]], t = [[-1, -1], [12, -2], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [12, 1984], [12, 2048], [12, 2112], [12, 2176], [12, 2240], [12, 2304], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [12, 2368], [12, 2432], [12, 2496], [12, 2560]], a = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [8, 29], [8, 29], [8, 30], [8, 30], [8, 45], [8, 45], [8, 46], [8, 46], [7, 22], [7, 22], [7, 22], [7, 22], [7, 23], [7, 23], [7, 23], [7, 23], [8, 47], [8, 47], [8, 48], [8, 48], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [7, 20], [7, 20], [7, 20], [7, 20], [8, 33], [8, 33], [8, 34], [8, 34], [8, 35], [8, 35], [8, 36], [8, 36], [8, 37], [8, 37], [8, 38], [8, 38], [7, 19], [7, 19], [7, 19], [7, 19], [8, 31], [8, 31], [8, 32], [8, 32], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [8, 53], [8, 53], [8, 54], [8, 54], [7, 26], [7, 26], [7, 26], [7, 26], [8, 39], [8, 39], [8, 40], [8, 40], [8, 41], [8, 41], [8, 42], [8, 42], [8, 43], [8, 43], [8, 44], [8, 44], [7, 21], [7, 21], [7, 21], [7, 21], [7, 28], [7, 28], [7, 28], [7, 28], [8, 61], [8, 61], [8, 62], [8, 62], [8, 63], [8, 63], [8, 0], [8, 0], [8, 320], [8, 320], [8, 384], [8, 384], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [7, 27], [7, 27], [7, 27], [7, 27], [8, 59], [8, 59], [8, 60], [8, 60], [9, 1472], [9, 1536], [9, 1600], [9, 1728], [7, 18], [7, 18], [7, 18], [7, 18], [7, 24], [7, 24], [7, 24], [7, 24], [8, 49], [8, 49], [8, 50], [8, 50], [8, 51], [8, 51], [8, 52], [8, 52], [7, 25], [7, 25], [7, 25], [7, 25], [8, 55], [8, 55], [8, 56], [8, 56], [8, 57], [8, 57], [8, 58], [8, 58], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [8, 448], [8, 448], [8, 512], [8, 512], [9, 704], [9, 768], [8, 640], [8, 640], [8, 576], [8, 576], [9, 832], [9, 896], [9, 960], [9, 1024], [9, 1088], [9, 1152], [9, 1216], [9, 1280], [9, 1344], [9, 1408], [7, 256], [7, 256], [7, 256], [7, 256], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7]], i = [[-1, -1], [-1, -1], [12, -2], [12, -2], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [11, 1792], [11, 1792], [12, 1984], [12, 1984], [12, 2048], [12, 2048], [12, 2112], [12, 2112], [12, 2176], [12, 2176], [12, 2240], [12, 2240], [12, 2304], [12, 2304], [11, 1856], [11, 1856], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [11, 1920], [11, 1920], [12, 2368], [12, 2368], [12, 2432], [12, 2432], [12, 2496], [12, 2496], [12, 2560], [12, 2560], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [12, 52], [12, 52], [13, 640], [13, 704], [13, 768], [13, 832], [12, 55], [12, 55], [12, 56], [12, 56], [13, 1280], [13, 1344], [13, 1408], [13, 1472], [12, 59], [12, 59], [12, 60], [12, 60], [13, 1536], [13, 1600], [11, 24], [11, 24], [11, 24], [11, 24], [11, 25], [11, 25], [11, 25], [11, 25], [13, 1664], [13, 1728], [12, 320], [12, 320], [12, 384], [12, 384], [12, 448], [12, 448], [13, 512], [13, 576], [12, 53], [12, 53], [12, 54], [12, 54], [13, 896], [13, 960], [13, 1024], [13, 1088], [13, 1152], [13, 1216], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64]], n = [[8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [11, 23], [11, 23], [12, 50], [12, 51], [12, 44], [12, 45], [12, 46], [12, 47], [12, 57], [12, 58], [12, 61], [12, 256], [10, 16], [10, 16], [10, 16], [10, 16], [10, 17], [10, 17], [10, 17], [10, 17], [12, 48], [12, 49], [12, 62], [12, 63], [12, 30], [12, 31], [12, 32], [12, 33], [12, 40], [12, 41], [11, 22], [11, 22], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [12, 128], [12, 192], [12, 26], [12, 27], [12, 28], [12, 29], [11, 19], [11, 19], [11, 20], [11, 20], [12, 34], [12, 35], [12, 36], [12, 37], [12, 38], [12, 39], [11, 21], [11, 21], [12, 42], [12, 43], [10, 0], [10, 0], [10, 0], [10, 0], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12]], s = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [6, 9], [6, 8], [5, 7], [5, 7], [4, 6], [4, 6], [4, 6], [4, 6], [4, 5], [4, 5], [4, 5], [4, 5], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]]; function o(e, t = {}) { if (!e || "function" != typeof e.next) throw new Error('CCITTFaxDecoder - invalid "source" parameter.'); this.source = e; this.eof = !1; this.encoding = t.K || 0; this.eoline = t.EndOfLine || !1; this.byteAlign = t.EncodedByteAlign || !1; this.columns = t.Columns || 1728; this.rows = t.Rows || 0; let a, r = t.EndOfBlock; null == r && (r = !0); this.eoblock = r; this.black = t.BlackIs1 || !1; this.codingLine = new Uint32Array(this.columns + 1); this.refLine = new Uint32Array(this.columns + 2); this.codingLine[0] = this.columns; this.codingPos = 0; this.row = 0; this.nextLine2D = this.encoding < 0; this.inputBits = 0; this.inputBuf = 0; this.outputBits = 0; this.rowsDone = !1; for (; 0 === (a = this._lookBits(12));)this._eatBits(1); 1 === a && this._eatBits(12); if (this.encoding > 0) { this.nextLine2D = !this._lookBits(1); this._eatBits(1) } } o.prototype = { readNextChar() { if (this.eof) return -1; const e = this.refLine, t = this.codingLine, a = this.columns; let i, n, s, o, c; if (0 === this.outputBits) { this.rowsDone && (this.eof = !0); if (this.eof) return -1; this.err = !1; let s, c, l; if (this.nextLine2D) { for (o = 0; t[o] < a; ++o)e[o] = t[o]; e[o++] = a; e[o] = a; t[0] = 0; this.codingPos = 0; i = 0; n = 0; for (; t[this.codingPos] < a;) { s = this._getTwoDimCode(); switch (s) { case 0: this._addPixels(e[i + 1], n); e[i + 1] < a && (i += 2); break; case 1: s = c = 0; if (n) { do { s += l = this._getBlackCode() } while (l >= 64); do { c += l = this._getWhiteCode() } while (l >= 64) } else { do { s += l = this._getWhiteCode() } while (l >= 64); do { c += l = this._getBlackCode() } while (l >= 64) } this._addPixels(t[this.codingPos] + s, n); t[this.codingPos] < a && this._addPixels(t[this.codingPos] + c, 1 ^ n); for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2; break; case 7: this._addPixels(e[i] + 3, n); n ^= 1; if (t[this.codingPos] < a) { ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 5: this._addPixels(e[i] + 2, n); n ^= 1; if (t[this.codingPos] < a) { ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 3: this._addPixels(e[i] + 1, n); n ^= 1; if (t[this.codingPos] < a) { ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 2: this._addPixels(e[i], n); n ^= 1; if (t[this.codingPos] < a) { ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 8: this._addPixelsNeg(e[i] - 3, n); n ^= 1; if (t[this.codingPos] < a) { i > 0 ? --i : ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 6: this._addPixelsNeg(e[i] - 2, n); n ^= 1; if (t[this.codingPos] < a) { i > 0 ? --i : ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case 4: this._addPixelsNeg(e[i] - 1, n); n ^= 1; if (t[this.codingPos] < a) { i > 0 ? --i : ++i; for (; e[i] <= t[this.codingPos] && e[i] < a;)i += 2 } break; case -1: this._addPixels(a, 0); this.eof = !0; break; default: (0, r.info)("bad 2d code"); this._addPixels(a, 0); this.err = !0 } } } else { t[0] = 0; this.codingPos = 0; n = 0; for (; t[this.codingPos] < a;) { s = 0; if (n) do { s += l = this._getBlackCode() } while (l >= 64); else do { s += l = this._getWhiteCode() } while (l >= 64); this._addPixels(t[this.codingPos] + s, n); n ^= 1 } } let h = !1; this.byteAlign && (this.inputBits &= -8); if (this.eoblock || this.row !== this.rows - 1) { s = this._lookBits(12); if (this.eoline) for (; -1 !== s && 1 !== s;) { this._eatBits(1); s = this._lookBits(12) } else for (; 0 === s;) { this._eatBits(1); s = this._lookBits(12) } if (1 === s) { this._eatBits(12); h = !0 } else -1 === s && (this.eof = !0) } else this.rowsDone = !0; if (!this.eof && this.encoding > 0 && !this.rowsDone) { this.nextLine2D = !this._lookBits(1); this._eatBits(1) } if (this.eoblock && h && this.byteAlign) { s = this._lookBits(12); if (1 === s) { this._eatBits(12); if (this.encoding > 0) { this._lookBits(1); this._eatBits(1) } if (this.encoding >= 0) for (o = 0; o < 4; ++o) { s = this._lookBits(12); 1 !== s && (0, r.info)("bad rtc code: " + s); this._eatBits(12); if (this.encoding > 0) { this._lookBits(1); this._eatBits(1) } } this.eof = !0 } } else if (this.err && this.eoline) { for (; ;) { s = this._lookBits(13); if (-1 === s) { this.eof = !0; return -1 } if (s >> 1 == 1) break; this._eatBits(1) } this._eatBits(12); if (this.encoding > 0) { this._eatBits(1); this.nextLine2D = !(1 & s) } } t[0] > 0 ? this.outputBits = t[this.codingPos = 0] : this.outputBits = t[this.codingPos = 1]; this.row++ } if (this.outputBits >= 8) { c = 1 & this.codingPos ? 0 : 255; this.outputBits -= 8; if (0 === this.outputBits && t[this.codingPos] < a) { this.codingPos++; this.outputBits = t[this.codingPos] - t[this.codingPos - 1] } } else { s = 8; c = 0; do { if (this.outputBits > s) { c <<= s; 1 & this.codingPos || (c |= 255 >> 8 - s); this.outputBits -= s; s = 0 } else { c <<= this.outputBits; 1 & this.codingPos || (c |= 255 >> 8 - this.outputBits); s -= this.outputBits; this.outputBits = 0; if (t[this.codingPos] < a) { this.codingPos++; this.outputBits = t[this.codingPos] - t[this.codingPos - 1] } else if (s > 0) { c <<= s; s = 0 } } } while (s) } this.black && (c ^= 255); return c }, _addPixels(e, t) { const a = this.codingLine; let i = this.codingPos; if (e > a[i]) { if (e > this.columns) { (0, r.info)("row is wrong length"); this.err = !0; e = this.columns } 1 & i ^ t && ++i; a[i] = e } this.codingPos = i }, _addPixelsNeg(e, t) { const a = this.codingLine; let i = this.codingPos; if (e > a[i]) { if (e > this.columns) { (0, r.info)("row is wrong length"); this.err = !0; e = this.columns } 1 & i ^ t && ++i; a[i] = e } else if (e < a[i]) { if (e < 0) { (0, r.info)("invalid code"); this.err = !0; e = 0 } for (; i > 0 && e < a[i - 1];)--i; a[i] = e } this.codingPos = i }, _findTableCode(e, t, a, r) { const i = r || 0; for (let r = e; r <= t; ++r) { let e = this._lookBits(r); if (-1 === e) return [!0, 1, !1]; r < t && (e <<= t - r); if (!i || e >= i) { const t = a[e - i]; if (t[0] === r) { this._eatBits(r); return [!0, t[1], !0] } } } return [!1, 0, !1] }, _getTwoDimCode() { let t, a = 0; if (this.eoblock) { a = this._lookBits(7); t = e[a]; if (t && t[0] > 0) { this._eatBits(t[0]); return t[1] } } else { const t = this._findTableCode(1, 7, e); if (t[0] && t[2]) return t[1] } (0, r.info)("Bad two dim code"); return -1 }, _getWhiteCode() { let e, i = 0; if (this.eoblock) { i = this._lookBits(12); if (-1 === i) return 1; e = i >> 5 == 0 ? t[i] : a[i >> 3]; if (e[0] > 0) { this._eatBits(e[0]); return e[1] } } else { let e = this._findTableCode(1, 9, a); if (e[0]) return e[1]; e = this._findTableCode(11, 12, t); if (e[0]) return e[1] } (0, r.info)("bad white code"); this._eatBits(1); return 1 }, _getBlackCode() { let e, t; if (this.eoblock) { e = this._lookBits(13); if (-1 === e) return 1; t = e >> 7 == 0 ? i[e] : e >> 9 == 0 && e >> 7 != 0 ? n[(e >> 1) - 64] : s[e >> 7]; if (t[0] > 0) { this._eatBits(t[0]); return t[1] } } else { let e = this._findTableCode(2, 6, s); if (e[0]) return e[1]; e = this._findTableCode(7, 12, n, 64); if (e[0]) return e[1]; e = this._findTableCode(10, 13, i); if (e[0]) return e[1] } (0, r.info)("bad black code"); this._eatBits(1); return 1 }, _lookBits(e) { let t; for (; this.inputBits < e;) { if (-1 === (t = this.source.next())) return 0 === this.inputBits ? -1 : this.inputBuf << e - this.inputBits & 65535 >> 16 - e; this.inputBuf = this.inputBuf << 8 | t; this.inputBits += 8 } return this.inputBuf >> this.inputBits - e & 65535 >> 16 - e }, _eatBits(e) { (this.inputBits -= e) < 0 && (this.inputBits = 0) } }; return o }(); t.CCITTFaxDecoder = i }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.Jbig2Stream = void 0; var r = a(4), i = a(11), n = a(15), s = a(2); const o = function () { function e(e, t, a, r) { this.stream = e; this.maybeLength = t; this.dict = a; this.params = r; i.DecodeStream.call(this, t) } e.prototype = Object.create(i.DecodeStream.prototype); Object.defineProperty(e.prototype, "bytes", { get() { return (0, s.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)) }, configurable: !0 }); e.prototype.ensureBuffer = function (e) { }; e.prototype.readBlock = function () { if (this.eof) return; const e = new n.Jbig2Image, t = []; if ((0, r.isDict)(this.params)) { const e = this.params.get("JBIG2Globals"); if ((0, r.isStream)(e)) { const a = e.getBytes(); t.push({ data: a, start: 0, end: a.length }) } } t.push({ data: this.bytes, start: 0, end: this.bytes.length }); const a = e.parseChunks(t), i = a.length; for (let e = 0; e < i; e++)a[e] ^= 255; this.buffer = a; this.bufferLength = i; this.eof = !0 }; return e }(); t.Jbig2Stream = o }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.Jbig2Image = void 0; var r = a(2), i = a(7), n = a(16), s = a(13); class o extends r.BaseException { constructor(e) { super(`JBIG2 error: ${e}`) } } var c = function () { function e() { } e.prototype = { getContexts(e) { return e in this ? this[e] : this[e] = new Int8Array(65536) } }; function t(e, t, a) { this.data = e; this.start = t; this.end = a } t.prototype = { get decoder() { var e = new n.ArithmeticDecoder(this.data, this.start, this.end); return (0, r.shadow)(this, "decoder", e) }, get contextCache() { var t = new e; return (0, r.shadow)(this, "contextCache", t) } }; function a(e, t, a) { var r = e.getContexts(t), i = 1; function n(e) { for (var t = 0, n = 0; n < e; n++) { var s = a.readBit(r, i); i = i < 256 ? i << 1 | s : 511 & (i << 1 | s) | 256; t = t << 1 | s } return t >>> 0 } var s = n(1), o = n(1) ? n(1) ? n(1) ? n(1) ? n(1) ? n(32) + 4436 : n(12) + 340 : n(8) + 84 : n(6) + 20 : n(4) + 4 : n(2); return 0 === s ? o : o > 0 ? -o : null } function c(e, t, a) { for (var r = e.getContexts("IAID"), i = 1, n = 0; n < a; n++) { i = i << 1 | t.readBit(r, i) } return a < 31 ? i & (1 << a) - 1 : 2147483647 & i } var l = ["SymbolDictionary", null, null, null, "IntermediateTextRegion", null, "ImmediateTextRegion", "ImmediateLosslessTextRegion", null, null, null, null, null, null, null, null, "PatternDictionary", null, null, null, "IntermediateHalftoneRegion", null, "ImmediateHalftoneRegion", "ImmediateLosslessHalftoneRegion", null, null, null, null, null, null, null, null, null, null, null, null, "IntermediateGenericRegion", null, "ImmediateGenericRegion", "ImmediateLosslessGenericRegion", "IntermediateGenericRefinementRegion", null, "ImmediateGenericRefinementRegion", "ImmediateLosslessGenericRefinementRegion", null, null, null, null, "PageInformation", "EndOfPage", "EndOfStripe", "EndOfFile", "Profiles", "Tables", null, null, null, null, null, null, null, null, "Extension"], h = [[{ x: -1, y: -2 }, { x: 0, y: -2 }, { x: 1, y: -2 }, { x: -2, y: -1 }, { x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: 2, y: -1 }, { x: -4, y: 0 }, { x: -3, y: 0 }, { x: -2, y: 0 }, { x: -1, y: 0 }], [{ x: -1, y: -2 }, { x: 0, y: -2 }, { x: 1, y: -2 }, { x: 2, y: -2 }, { x: -2, y: -1 }, { x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: 2, y: -1 }, { x: -3, y: 0 }, { x: -2, y: 0 }, { x: -1, y: 0 }], [{ x: -1, y: -2 }, { x: 0, y: -2 }, { x: 1, y: -2 }, { x: -2, y: -1 }, { x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: -2, y: 0 }, { x: -1, y: 0 }], [{ x: -3, y: -1 }, { x: -2, y: -1 }, { x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: -4, y: 0 }, { x: -3, y: 0 }, { x: -2, y: 0 }, { x: -1, y: 0 }]], u = [{ coding: [{ x: 0, y: -1 }, { x: 1, y: -1 }, { x: -1, y: 0 }], reference: [{ x: 0, y: -1 }, { x: 1, y: -1 }, { x: -1, y: 0 }, { x: 0, y: 0 }, { x: 1, y: 0 }, { x: -1, y: 1 }, { x: 0, y: 1 }, { x: 1, y: 1 }] }, { coding: [{ x: -1, y: -1 }, { x: 0, y: -1 }, { x: 1, y: -1 }, { x: -1, y: 0 }], reference: [{ x: 0, y: -1 }, { x: -1, y: 0 }, { x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }] }], d = [39717, 1941, 229, 405], f = [32, 8]; function g(e, t, a, r, i, n, s, o) { if (e) { return B(new E(o.data, o.start, o.end), t, a, !1) } if (0 === r && !n && !i && 4 === s.length && 3 === s[0].x && -1 === s[0].y && -3 === s[1].x && -1 === s[1].y && 2 === s[2].x && -2 === s[2].y && -2 === s[3].x && -2 === s[3].y) return function (e, t, a) { var r, i, n, s, o, c, l, h = a.decoder, u = a.contextCache.getContexts("GB"), d = []; for (i = 0; i < t; i++) { o = d[i] = new Uint8Array(e); c = i < 1 ? o : d[i - 1]; r = (l = i < 2 ? o : d[i - 2])[0] << 13 | l[1] << 12 | l[2] << 11 | c[0] << 7 | c[1] << 6 | c[2] << 5 | c[3] << 4; for (n = 0; n < e; n++) { o[n] = s = h.readBit(u, r); r = (31735 & r) << 1 | (n + 3 < e ? l[n + 3] << 11 : 0) | (n + 4 < e ? c[n + 4] << 4 : 0) | s } } return d }(t, a, o); var c = !!n, l = h[r].concat(s); l.sort((function (e, t) { return e.y - t.y || e.x - t.x })); var u, f, g = l.length, m = new Int8Array(g), p = new Int8Array(g), b = [], y = 0, v = 0, w = 0, k = 0; for (f = 0; f < g; f++) { m[f] = l[f].x; p[f] = l[f].y; v = Math.min(v, l[f].x); w = Math.max(w, l[f].x); k = Math.min(k, l[f].y); f < g - 1 && l[f].y === l[f + 1].y && l[f].x === l[f + 1].x - 1 ? y |= 1 << g - 1 - f : b.push(f) } var S = b.length, C = new Int8Array(S), x = new Int8Array(S), A = new Uint16Array(S); for (u = 0; u < S; u++) { f = b[u]; C[u] = l[f].x; x[u] = l[f].y; A[u] = 1 << g - 1 - f } for (var I, F, T, O, P, D = -v, N = -k, M = t - w, L = d[r], R = new Uint8Array(t), U = [], q = o.decoder, j = o.contextCache.getContexts("GB"), _ = 0, z = 0, H = 0; H < a; H++) { if (i) { if (_ ^= q.readBit(j, L)) { U.push(R); continue } } R = new Uint8Array(R); U.push(R); for (I = 0; I < t; I++)if (c && n[H][I]) R[I] = 0; else { if (I >= D && I < M && H >= N) { z = z << 1 & y; for (f = 0; f < S; f++) { F = H + x[f]; T = I + C[f]; (O = U[F][T]) && (z |= O = A[f]) } } else { z = 0; P = g - 1; for (f = 0; f < g; f++, P--)(T = I + m[f]) >= 0 && T < t && (F = H + p[f]) >= 0 && (O = U[F][T]) && (z |= O << P) } var G = q.readBit(j, z); R[I] = G } } return U } function m(e, t, a, r, i, n, s, c, l) { var h = u[a].coding; 0 === a && (h = h.concat([c[0]])); var d, g = h.length, m = new Int32Array(g), p = new Int32Array(g); for (d = 0; d < g; d++) { m[d] = h[d].x; p[d] = h[d].y } var b = u[a].reference; 0 === a && (b = b.concat([c[1]])); var y = b.length, v = new Int32Array(y), w = new Int32Array(y); for (d = 0; d < y; d++) { v[d] = b[d].x; w[d] = b[d].y } for (var k = r[0].length, S = r.length, C = f[a], x = [], A = l.decoder, I = l.contextCache.getContexts("GR"), F = 0, T = 0; T < t; T++) { if (s) { if (F ^= A.readBit(I, C)) throw new o("prediction is not supported") } var E = new Uint8Array(e); x.push(E); for (var O = 0; O < e; O++) { var P, B, D = 0; for (d = 0; d < g; d++) { P = T + p[d]; B = O + m[d]; P < 0 || B < 0 || B >= e ? D <<= 1 : D = D << 1 | x[P][B] } for (d = 0; d < y; d++) { P = T + w[d] - n; B = O + v[d] - i; P < 0 || P >= S || B < 0 || B >= k ? D <<= 1 : D = D << 1 | r[P][B] } var N = A.readBit(I, D); E[O] = N } } return x } function p(e, t, r, i, n, s, l, h, u, d, f, g, p, b, y, v, w, k, S) { if (e && t) throw new o("refinement with Huffman is not supported"); var C, x, A = []; for (C = 0; C < i; C++) { x = new Uint8Array(r); if (n) for (var I = 0; I < r; I++)x[I] = n; A.push(x) } var F = w.decoder, T = w.contextCache, E = e ? -b.tableDeltaT.decode(S) : -a(T, "IADT", F), O = 0; C = 0; for (; C < s;) { E += e ? b.tableDeltaT.decode(S) : a(T, "IADT", F); for (var P = O += e ? b.tableFirstS.decode(S) : a(T, "IAFS", F); ;) { let i = 0; l > 1 && (i = e ? S.readBits(k) : a(T, "IAIT", F)); var B = l * E + i, D = e ? b.symbolIDTable.decode(S) : c(T, F, u), N = t && (e ? S.readBit() : a(T, "IARI", F)), M = h[D], L = M[0].length, R = M.length; if (N) { var U = a(T, "IARDW", F), q = a(T, "IARDH", F); M = m(L += U, R += q, y, M, (U >> 1) + a(T, "IARDX", F), (q >> 1) + a(T, "IARDY", F), !1, v, w) } var j, _, z, H = B - (1 & g ? 0 : R - 1), G = P - (2 & g ? L - 1 : 0); if (d) { for (j = 0; j < R; j++)if (x = A[G + j]) { z = M[j]; var W = Math.min(r - H, L); switch (p) { case 0: for (_ = 0; _ < W; _++)x[H + _] |= z[_]; break; case 2: for (_ = 0; _ < W; _++)x[H + _] ^= z[_]; break; default: throw new o(`operator ${p} is not supported`) } } P += R - 1 } else { for (_ = 0; _ < R; _++)if (x = A[H + _]) { z = M[_]; switch (p) { case 0: for (j = 0; j < L; j++)x[G + j] |= z[j]; break; case 2: for (j = 0; j < L; j++)x[G + j] ^= z[j]; break; default: throw new o(`operator ${p} is not supported`) } } P += L - 1 } C++; var X = e ? b.tableDeltaS.decode(S) : a(T, "IADS", F); if (null === X) break; P += X + f } } return A } function b(e, t) { var a = {}; a.number = (0, i.readUint32)(e, t); var r = e[t + 4], n = 63 & r; if (!l[n]) throw new o("invalid segment type: " + n); a.type = n; a.typeName = l[n]; a.deferredNonRetain = !!(128 & r); var s = !!(64 & r), c = e[t + 5], h = c >> 5 & 7, u = [31 & c], d = t + 6; if (7 === c) { h = 536870911 & (0, i.readUint32)(e, d - 1); d += 3; var f = h + 7 >> 3; u[0] = e[d++]; for (; --f > 0;)u.push(e[d++]) } else if (5 === c || 6 === c) throw new o("invalid referred-to flags"); a.retainBits = u; let g = 4; a.number <= 256 ? g = 1 : a.number <= 65536 && (g = 2); var m, p, b = []; for (m = 0; m < h; m++) { let t; t = 1 === g ? e[d] : 2 === g ? (0, i.readUint16)(e, d) : (0, i.readUint32)(e, d); b.push(t); d += g } a.referredTo = b; if (s) { a.pageAssociation = (0, i.readUint32)(e, d); d += 4 } else a.pageAssociation = e[d++]; a.length = (0, i.readUint32)(e, d); d += 4; if (4294967295 === a.length) { if (38 !== n) throw new o("invalid unknown segment length"); var y = v(e, d), k = !!(1 & e[d + w]), S = new Uint8Array(6); if (!k) { S[0] = 255; S[1] = 172 } S[2] = y.height >>> 24 & 255; S[3] = y.height >> 16 & 255; S[4] = y.height >> 8 & 255; S[5] = 255 & y.height; for (m = d, p = e.length; m < p; m++) { for (var C = 0; C < 6 && S[C] === e[m + C];)C++; if (6 === C) { a.length = m + 6; break } } if (4294967295 === a.length) throw new o("segment end was not found") } a.headerEnd = d; return a } function y(e, t, a, r) { for (var i = [], n = a; n < r;) { var s = b(t, n); n = s.headerEnd; var o = { header: s, data: t }; if (!e.randomAccess) { o.start = n; n += s.length; o.end = n } i.push(o); if (51 === s.type) break } if (e.randomAccess) for (var c = 0, l = i.length; c < l; c++) { i[c].start = n; n += i[c].header.length; i[c].end = n } return i } function v(e, t) { return { width: (0, i.readUint32)(e, t), height: (0, i.readUint32)(e, t + 4), x: (0, i.readUint32)(e, t + 8), y: (0, i.readUint32)(e, t + 12), combinationOperator: 7 & e[t + 16] } } var w = 17; function k(e, t) { var a, r, n, s, c = e.header, l = e.data, h = e.start, u = e.end; switch (c.type) { case 0: var d = {}, f = (0, i.readUint16)(l, h); d.huffman = !!(1 & f); d.refinement = !!(2 & f); d.huffmanDHSelector = f >> 2 & 3; d.huffmanDWSelector = f >> 4 & 3; d.bitmapSizeSelector = f >> 6 & 1; d.aggregationInstancesSelector = f >> 7 & 1; d.bitmapCodingContextUsed = !!(256 & f); d.bitmapCodingContextRetained = !!(512 & f); d.template = f >> 10 & 3; d.refinementTemplate = f >> 12 & 1; h += 2; if (!d.huffman) { s = 0 === d.template ? 4 : 1; r = []; for (n = 0; n < s; n++) { r.push({ x: (0, i.readInt8)(l, h), y: (0, i.readInt8)(l, h + 1) }); h += 2 } d.at = r } if (d.refinement && !d.refinementTemplate) { r = []; for (n = 0; n < 2; n++) { r.push({ x: (0, i.readInt8)(l, h), y: (0, i.readInt8)(l, h + 1) }); h += 2 } d.refinementAt = r } d.numberOfExportedSymbols = (0, i.readUint32)(l, h); h += 4; d.numberOfNewSymbols = (0, i.readUint32)(l, h); h += 4; a = [d, c.number, c.referredTo, l, h, u]; break; case 6: case 7: var g = {}; g.info = v(l, h); h += w; var m = (0, i.readUint16)(l, h); h += 2; g.huffman = !!(1 & m); g.refinement = !!(2 & m); g.logStripSize = m >> 2 & 3; g.stripSize = 1 << g.logStripSize; g.referenceCorner = m >> 4 & 3; g.transposed = !!(64 & m); g.combinationOperator = m >> 7 & 3; g.defaultPixelValue = m >> 9 & 1; g.dsOffset = m << 17 >> 27; g.refinementTemplate = m >> 15 & 1; if (g.huffman) { var p = (0, i.readUint16)(l, h); h += 2; g.huffmanFS = 3 & p; g.huffmanDS = p >> 2 & 3; g.huffmanDT = p >> 4 & 3; g.huffmanRefinementDW = p >> 6 & 3; g.huffmanRefinementDH = p >> 8 & 3; g.huffmanRefinementDX = p >> 10 & 3; g.huffmanRefinementDY = p >> 12 & 3; g.huffmanRefinementSizeSelector = !!(16384 & p) } if (g.refinement && !g.refinementTemplate) { r = []; for (n = 0; n < 2; n++) { r.push({ x: (0, i.readInt8)(l, h), y: (0, i.readInt8)(l, h + 1) }); h += 2 } g.refinementAt = r } g.numberOfSymbolInstances = (0, i.readUint32)(l, h); h += 4; a = [g, c.referredTo, l, h, u]; break; case 16: const e = {}, t = l[h++]; e.mmr = !!(1 & t); e.template = t >> 1 & 3; e.patternWidth = l[h++]; e.patternHeight = l[h++]; e.maxPatternIndex = (0, i.readUint32)(l, h); h += 4; a = [e, c.number, l, h, u]; break; case 22: case 23: const C = {}; C.info = v(l, h); h += w; const x = l[h++]; C.mmr = !!(1 & x); C.template = x >> 1 & 3; C.enableSkip = !!(8 & x); C.combinationOperator = x >> 4 & 7; C.defaultPixelValue = x >> 7 & 1; C.gridWidth = (0, i.readUint32)(l, h); h += 4; C.gridHeight = (0, i.readUint32)(l, h); h += 4; C.gridOffsetX = 4294967295 & (0, i.readUint32)(l, h); h += 4; C.gridOffsetY = 4294967295 & (0, i.readUint32)(l, h); h += 4; C.gridVectorX = (0, i.readUint16)(l, h); h += 2; C.gridVectorY = (0, i.readUint16)(l, h); h += 2; a = [C, c.referredTo, l, h, u]; break; case 38: case 39: var b = {}; b.info = v(l, h); h += w; var y = l[h++]; b.mmr = !!(1 & y); b.template = y >> 1 & 3; b.prediction = !!(8 & y); if (!b.mmr) { s = 0 === b.template ? 4 : 1; r = []; for (n = 0; n < s; n++) { r.push({ x: (0, i.readInt8)(l, h), y: (0, i.readInt8)(l, h + 1) }); h += 2 } b.at = r } a = [b, l, h, u]; break; case 48: var k = { width: (0, i.readUint32)(l, h), height: (0, i.readUint32)(l, h + 4), resolutionX: (0, i.readUint32)(l, h + 8), resolutionY: (0, i.readUint32)(l, h + 12) }; 4294967295 === k.height && delete k.height; var S = l[h + 16]; (0, i.readUint16)(l, h + 17); k.lossless = !!(1 & S); k.refinement = !!(2 & S); k.defaultPixelValue = S >> 2 & 1; k.combinationOperator = S >> 3 & 3; k.requiresBuffer = !!(32 & S); k.combinationOperatorOverride = !!(64 & S); a = [k]; break; case 49: case 50: case 51: break; case 53: a = [c.number, l, h, u]; break; case 62: break; default: throw new o(`segment type ${c.typeName}(${c.type})` + " is not implemented") }var C = "on" + c.typeName; C in t && t[C].apply(t, a) } function S(e, t) { for (var a = 0, r = e.length; a < r; a++)k(e[a], t) } function C() { } C.prototype = { onPageInformation: function (e) { this.currentPageInfo = e; var t = e.width + 7 >> 3, a = new Uint8ClampedArray(t * e.height); if (e.defaultPixelValue) for (var r = 0, i = a.length; r < i; r++)a[r] = 255; this.buffer = a }, drawBitmap: function (e, t) { var a, r, i, n, s = this.currentPageInfo, c = e.width, l = e.height, h = s.width + 7 >> 3, u = s.combinationOperatorOverride ? e.combinationOperator : s.combinationOperator, d = this.buffer, f = 128 >> (7 & e.x), g = e.y * h + (e.x >> 3); switch (u) { case 0: for (a = 0; a < l; a++) { i = f; n = g; for (r = 0; r < c; r++) { t[a][r] && (d[n] |= i); if (!(i >>= 1)) { i = 128; n++ } } g += h } break; case 2: for (a = 0; a < l; a++) { i = f; n = g; for (r = 0; r < c; r++) { t[a][r] && (d[n] ^= i); if (!(i >>= 1)) { i = 128; n++ } } g += h } break; default: throw new o(`operator ${u} is not supported`) } }, onImmediateGenericRegion: function (e, a, r, i) { var n = e.info, s = new t(a, r, i), o = g(e.mmr, n.width, n.height, e.template, e.prediction, null, e.at, s); this.drawBitmap(n, o) }, onImmediateLosslessGenericRegion: function () { this.onImmediateGenericRegion.apply(this, arguments) }, onSymbolDictionary: function (e, r, n, s, l, h) { let u, d; if (e.huffman) { u = function (e, t, a) { let r, i, n, s, c = 0; switch (e.huffmanDHSelector) { case 0: case 1: r = T(e.huffmanDHSelector + 4); break; case 3: r = O(c, t, a); c++; break; default: throw new o("invalid Huffman DH selector") }switch (e.huffmanDWSelector) { case 0: case 1: i = T(e.huffmanDWSelector + 2); break; case 3: i = O(c, t, a); c++; break; default: throw new o("invalid Huffman DW selector") }if (e.bitmapSizeSelector) { n = O(c, t, a); c++ } else n = T(1); s = e.aggregationInstancesSelector ? O(c, t, a) : T(1); return { tableDeltaHeight: r, tableDeltaWidth: i, tableBitmapSize: n, tableAggregateInstances: s } }(e, n, this.customTables); d = new E(s, l, h) } var f = this.symbols; f || (this.symbols = f = {}); for (var b = [], y = 0, v = n.length; y < v; y++) { const e = f[n[y]]; e && (b = b.concat(e)) } var w = new t(s, l, h); f[r] = function (e, t, r, n, s, l, h, u, d, f, b, y) { if (e && t) throw new o("symbol refinement with Huffman is not supported"); var v = [], w = 0, k = (0, i.log2)(r.length + n), S = b.decoder, C = b.contextCache; let x, A; if (e) { x = T(1); A = []; k = Math.max(k, 1) } for (; v.length < n;) { w += e ? l.tableDeltaHeight.decode(y) : a(C, "IADH", S); let i = 0, n = 0; const s = e ? A.length : 0; for (; ;) { var I, F = e ? l.tableDeltaWidth.decode(y) : a(C, "IADW", S); if (null === F) break; i += F; n += i; if (t) { var E = a(C, "IAAI", S); if (E > 1) I = p(e, t, i, w, 0, E, 1, r.concat(v), k, 0, 0, 1, 0, l, d, f, b, 0, y); else { var O = c(C, S, k), D = a(C, "IARDX", S), N = a(C, "IARDY", S); I = m(i, w, d, O < r.length ? r[O] : v[O - r.length], D, N, !1, f, b) } v.push(I) } else if (e) A.push(i); else { I = g(!1, i, w, h, !1, null, u, b); v.push(I) } } if (e && !t) { const e = l.tableBitmapSize.decode(y); y.byteAlign(); let t; if (0 === e) t = P(y, n, w); else { const a = y.end, r = y.position + e; y.end = r; t = B(y, n, w, !1); y.end = a; y.position = r } const a = A.length; if (s === a - 1) v.push(t); else { let e, r, i, n, o, c = 0; for (e = s; e < a; e++) { n = A[e]; i = c + n; o = []; for (r = 0; r < w; r++)o.push(t[r].subarray(c, i)); v.push(o); c = i } } } } for (var M = [], L = [], R = !1, U = r.length + n; L.length < U;) { for (var q = e ? x.decode(y) : a(C, "IAEX", S); q--;)L.push(R); R = !R } for (var j = 0, _ = r.length; j < _; j++)L[j] && M.push(r[j]); for (var z = 0; z < n; j++, z++)L[j] && M.push(v[z]); return M }(e.huffman, e.refinement, b, e.numberOfNewSymbols, e.numberOfExportedSymbols, u, e.template, e.at, e.refinementTemplate, e.refinementAt, w, d) }, onImmediateTextRegion: function (e, a, r, n, s) { var c = e.info; let l, h; for (var u = this.symbols, d = [], f = 0, g = a.length; f < g; f++) { const e = u[a[f]]; e && (d = d.concat(e)) } var m = (0, i.log2)(d.length); if (e.huffman) { h = new E(r, n, s); l = function (e, t, a, r, i) { const n = []; for (let e = 0; e <= 34; e++) { const t = i.readBits(4); n.push(new x([e, t, 0, 0])) } const s = new I(n, !1); n.length = 0; for (let e = 0; e < r;) { const t = s.decode(i); if (t >= 32) { let a, r, s; switch (t) { case 32: if (0 === e) throw new o("no previous value in symbol ID table"); r = i.readBits(2) + 3; a = n[e - 1].prefixLength; break; case 33: r = i.readBits(3) + 3; a = 0; break; case 34: r = i.readBits(7) + 11; a = 0; break; default: throw new o("invalid code length in symbol ID table") }for (s = 0; s < r; s++) { n.push(new x([e, a, 0, 0])); e++ } } else { n.push(new x([e, t, 0, 0])); e++ } } i.byteAlign(); const c = new I(n, !1); let l, h, u, d = 0; switch (e.huffmanFS) { case 0: case 1: l = T(e.huffmanFS + 6); break; case 3: l = O(d, t, a); d++; break; default: throw new o("invalid Huffman FS selector") }switch (e.huffmanDS) { case 0: case 1: case 2: h = T(e.huffmanDS + 8); break; case 3: h = O(d, t, a); d++; break; default: throw new o("invalid Huffman DS selector") }switch (e.huffmanDT) { case 0: case 1: case 2: u = T(e.huffmanDT + 11); break; case 3: u = O(d, t, a); d++; break; default: throw new o("invalid Huffman DT selector") }if (e.refinement) throw new o("refinement with Huffman is not supported"); return { symbolIDTable: c, tableFirstS: l, tableDeltaS: h, tableDeltaT: u } }(e, a, this.customTables, d.length, h) } var b = new t(r, n, s), y = p(e.huffman, e.refinement, c.width, c.height, e.defaultPixelValue, e.numberOfSymbolInstances, e.stripSize, d, m, e.transposed, e.dsOffset, e.referenceCorner, e.combinationOperator, l, e.refinementTemplate, e.refinementAt, b, e.logStripSize, h); this.drawBitmap(c, y) }, onImmediateLosslessTextRegion: function () { this.onImmediateTextRegion.apply(this, arguments) }, onPatternDictionary(e, a, r, i, n) { let s = this.patterns; s || (this.patterns = s = {}); const o = new t(r, i, n); s[a] = function (e, t, a, r, i, n) { const s = []; if (!e) { s.push({ x: -t, y: 0 }); if (0 === i) { s.push({ x: -3, y: -1 }); s.push({ x: 2, y: -2 }); s.push({ x: -2, y: -2 }) } } const o = g(e, (r + 1) * t, a, i, !1, null, s, n), c = []; for (let e = 0; e <= r; e++) { const r = [], i = t * e, n = i + t; for (let e = 0; e < a; e++)r.push(o[e].subarray(i, n)); c.push(r) } return c }(e.mmr, e.patternWidth, e.patternHeight, e.maxPatternIndex, e.template, o) }, onImmediateHalftoneRegion(e, a, r, n, s) { const c = this.patterns[a[0]], l = e.info, h = new t(r, n, s), u = function (e, t, a, r, n, s, c, l, h, u, d, f, m, p, b) { if (c) throw new o("skip is not supported"); if (0 !== l) throw new o("operator " + l + " is not supported in halftone region"); const y = []; let v, w, k; for (v = 0; v < n; v++) { k = new Uint8Array(r); if (s) for (w = 0; w < r; w++)k[w] = s; y.push(k) } const S = t.length, C = t[0], x = C[0].length, A = C.length, I = (0, i.log2)(S), F = []; if (!e) { F.push({ x: a <= 1 ? 3 : 2, y: -1 }); if (0 === a) { F.push({ x: -3, y: -1 }); F.push({ x: 2, y: -2 }); F.push({ x: -2, y: -2 }) } } const T = []; let O, P, D, N, M, L, R, U, q, j, _; e && (O = new E(b.data, b.start, b.end)); for (v = I - 1; v >= 0; v--) { P = e ? B(O, h, u, !0) : g(!1, h, u, a, !1, null, F, b); T[v] = P } for (D = 0; D < u; D++)for (N = 0; N < h; N++) { M = 0; L = 0; for (w = I - 1; w >= 0; w--) { M = T[w][D][N] ^ M; L |= M << w } R = t[L]; U = d + D * p + N * m >> 8; q = f + D * m - N * p >> 8; if (U >= 0 && U + x <= r && q >= 0 && q + A <= n) for (v = 0; v < A; v++) { _ = y[q + v]; j = R[v]; for (w = 0; w < x; w++)_[U + w] |= j[w] } else { let e, t; for (v = 0; v < A; v++) { t = q + v; if (!(t < 0 || t >= n)) { _ = y[t]; j = R[v]; for (w = 0; w < x; w++) { e = U + w; e >= 0 && e < r && (_[e] |= j[w]) } } } } } return y }(e.mmr, c, e.template, l.width, l.height, e.defaultPixelValue, e.enableSkip, e.combinationOperator, e.gridWidth, e.gridHeight, e.gridOffsetX, e.gridOffsetY, e.gridVectorX, e.gridVectorY, h); this.drawBitmap(l, u) }, onImmediateLosslessHalftoneRegion() { this.onImmediateHalftoneRegion.apply(this, arguments) }, onTables(e, t, a, r) { let n = this.customTables; n || (this.customTables = n = {}); n[e] = function (e, t, a) { const r = e[t], n = 4294967295 & (0, i.readUint32)(e, t + 1), s = 4294967295 & (0, i.readUint32)(e, t + 5), o = new E(e, t + 9, a), c = 1 + (r >> 1 & 7), l = 1 + (r >> 4 & 7), h = []; let u, d, f = n; do { u = o.readBits(c); d = o.readBits(l); h.push(new x([f, u, d, 0])); f += 1 << d } while (f < s); u = o.readBits(c); h.push(new x([n - 1, u, 32, 0, "lower"])); u = o.readBits(c); h.push(new x([s, u, 32, 0])); if (1 & r) { u = o.readBits(c); h.push(new x([u, 0])) } return new I(h, !1) }(t, a, r) } }; function x(e) { if (2 === e.length) { this.isOOB = !0; this.rangeLow = 0; this.prefixLength = e[0]; this.rangeLength = 0; this.prefixCode = e[1]; this.isLowerRange = !1 } else { this.isOOB = !1; this.rangeLow = e[0]; this.prefixLength = e[1]; this.rangeLength = e[2]; this.prefixCode = e[3]; this.isLowerRange = "lower" === e[4] } } function A(e) { this.children = []; if (e) { this.isLeaf = !0; this.rangeLength = e.rangeLength; this.rangeLow = e.rangeLow; this.isLowerRange = e.isLowerRange; this.isOOB = e.isOOB } else this.isLeaf = !1 } A.prototype = { buildTree(e, t) { const a = e.prefixCode >> t & 1; if (t <= 0) this.children[a] = new A(e); else { let r = this.children[a]; r || (this.children[a] = r = new A(null)); r.buildTree(e, t - 1) } }, decodeNode(e) { if (this.isLeaf) { if (this.isOOB) return null; const t = e.readBits(this.rangeLength); return this.rangeLow + (this.isLowerRange ? -t : t) } const t = this.children[e.readBit()]; if (!t) throw new o("invalid Huffman data"); return t.decodeNode(e) } }; function I(e, t) { t || this.assignPrefixCodes(e); this.rootNode = new A(null); for (let t = 0, a = e.length; t < a; t++) { const a = e[t]; a.prefixLength > 0 && this.rootNode.buildTree(a, a.prefixLength - 1) } } I.prototype = { decode(e) { return this.rootNode.decodeNode(e) }, assignPrefixCodes(e) { const t = e.length; let a = 0; for (let r = 0; r < t; r++)a = Math.max(a, e[r].prefixLength); const r = new Uint32Array(a + 1); for (let a = 0; a < t; a++)r[e[a].prefixLength]++; let i, n, s, o = 1, c = 0; r[0] = 0; for (; o <= a;) { c = c + r[o - 1] << 1; i = c; n = 0; for (; n < t;) { s = e[n]; if (s.prefixLength === o) { s.prefixCode = i; i++ } n++ } o++ } } }; const F = {}; function T(e) { let t, a = F[e]; if (a) return a; switch (e) { case 1: t = [[0, 1, 4, 0], [16, 2, 8, 2], [272, 3, 16, 6], [65808, 3, 32, 7]]; break; case 2: t = [[0, 1, 0, 0], [1, 2, 0, 2], [2, 3, 0, 6], [3, 4, 3, 14], [11, 5, 6, 30], [75, 6, 32, 62], [6, 63]]; break; case 3: t = [[-256, 8, 8, 254], [0, 1, 0, 0], [1, 2, 0, 2], [2, 3, 0, 6], [3, 4, 3, 14], [11, 5, 6, 30], [-257, 8, 32, 255, "lower"], [75, 7, 32, 126], [6, 62]]; break; case 4: t = [[1, 1, 0, 0], [2, 2, 0, 2], [3, 3, 0, 6], [4, 4, 3, 14], [12, 5, 6, 30], [76, 5, 32, 31]]; break; case 5: t = [[-255, 7, 8, 126], [1, 1, 0, 0], [2, 2, 0, 2], [3, 3, 0, 6], [4, 4, 3, 14], [12, 5, 6, 30], [-256, 7, 32, 127, "lower"], [76, 6, 32, 62]]; break; case 6: t = [[-2048, 5, 10, 28], [-1024, 4, 9, 8], [-512, 4, 8, 9], [-256, 4, 7, 10], [-128, 5, 6, 29], [-64, 5, 5, 30], [-32, 4, 5, 11], [0, 2, 7, 0], [128, 3, 7, 2], [256, 3, 8, 3], [512, 4, 9, 12], [1024, 4, 10, 13], [-2049, 6, 32, 62, "lower"], [2048, 6, 32, 63]]; break; case 7: t = [[-1024, 4, 9, 8], [-512, 3, 8, 0], [-256, 4, 7, 9], [-128, 5, 6, 26], [-64, 5, 5, 27], [-32, 4, 5, 10], [0, 4, 5, 11], [32, 5, 5, 28], [64, 5, 6, 29], [128, 4, 7, 12], [256, 3, 8, 1], [512, 3, 9, 2], [1024, 3, 10, 3], [-1025, 5, 32, 30, "lower"], [2048, 5, 32, 31]]; break; case 8: t = [[-15, 8, 3, 252], [-7, 9, 1, 508], [-5, 8, 1, 253], [-3, 9, 0, 509], [-2, 7, 0, 124], [-1, 4, 0, 10], [0, 2, 1, 0], [2, 5, 0, 26], [3, 6, 0, 58], [4, 3, 4, 4], [20, 6, 1, 59], [22, 4, 4, 11], [38, 4, 5, 12], [70, 5, 6, 27], [134, 5, 7, 28], [262, 6, 7, 60], [390, 7, 8, 125], [646, 6, 10, 61], [-16, 9, 32, 510, "lower"], [1670, 9, 32, 511], [2, 1]]; break; case 9: t = [[-31, 8, 4, 252], [-15, 9, 2, 508], [-11, 8, 2, 253], [-7, 9, 1, 509], [-5, 7, 1, 124], [-3, 4, 1, 10], [-1, 3, 1, 2], [1, 3, 1, 3], [3, 5, 1, 26], [5, 6, 1, 58], [7, 3, 5, 4], [39, 6, 2, 59], [43, 4, 5, 11], [75, 4, 6, 12], [139, 5, 7, 27], [267, 5, 8, 28], [523, 6, 8, 60], [779, 7, 9, 125], [1291, 6, 11, 61], [-32, 9, 32, 510, "lower"], [3339, 9, 32, 511], [2, 0]]; break; case 10: t = [[-21, 7, 4, 122], [-5, 8, 0, 252], [-4, 7, 0, 123], [-3, 5, 0, 24], [-2, 2, 2, 0], [2, 5, 0, 25], [3, 6, 0, 54], [4, 7, 0, 124], [5, 8, 0, 253], [6, 2, 6, 1], [70, 5, 5, 26], [102, 6, 5, 55], [134, 6, 6, 56], [198, 6, 7, 57], [326, 6, 8, 58], [582, 6, 9, 59], [1094, 6, 10, 60], [2118, 7, 11, 125], [-22, 8, 32, 254, "lower"], [4166, 8, 32, 255], [2, 2]]; break; case 11: t = [[1, 1, 0, 0], [2, 2, 1, 2], [4, 4, 0, 12], [5, 4, 1, 13], [7, 5, 1, 28], [9, 5, 2, 29], [13, 6, 2, 60], [17, 7, 2, 122], [21, 7, 3, 123], [29, 7, 4, 124], [45, 7, 5, 125], [77, 7, 6, 126], [141, 7, 32, 127]]; break; case 12: t = [[1, 1, 0, 0], [2, 2, 0, 2], [3, 3, 1, 6], [5, 5, 0, 28], [6, 5, 1, 29], [8, 6, 1, 60], [10, 7, 0, 122], [11, 7, 1, 123], [13, 7, 2, 124], [17, 7, 3, 125], [25, 7, 4, 126], [41, 8, 5, 254], [73, 8, 32, 255]]; break; case 13: t = [[1, 1, 0, 0], [2, 3, 0, 4], [3, 4, 0, 12], [4, 5, 0, 28], [5, 4, 1, 13], [7, 3, 3, 5], [15, 6, 1, 58], [17, 6, 2, 59], [21, 6, 3, 60], [29, 6, 4, 61], [45, 6, 5, 62], [77, 7, 6, 126], [141, 7, 32, 127]]; break; case 14: t = [[-2, 3, 0, 4], [-1, 3, 0, 5], [0, 1, 0, 0], [1, 3, 0, 6], [2, 3, 0, 7]]; break; case 15: t = [[-24, 7, 4, 124], [-8, 6, 2, 60], [-4, 5, 1, 28], [-2, 4, 0, 12], [-1, 3, 0, 4], [0, 1, 0, 0], [1, 3, 0, 5], [2, 4, 0, 13], [3, 5, 1, 29], [5, 6, 2, 61], [9, 7, 4, 125], [-25, 7, 32, 126, "lower"], [25, 7, 32, 127]]; break; default: throw new o(`standard table B.${e} does not exist`) }for (let e = 0, a = t.length; e < a; e++)t[e] = new x(t[e]); a = new I(t, !0); F[e] = a; return a } function E(e, t, a) { this.data = e; this.start = t; this.end = a; this.position = t; this.shift = -1; this.currentByte = 0 } E.prototype = { readBit() { if (this.shift < 0) { if (this.position >= this.end) throw new o("end of data while reading bit"); this.currentByte = this.data[this.position++]; this.shift = 7 } const e = this.currentByte >> this.shift & 1; this.shift--; return e }, readBits(e) { let t, a = 0; for (t = e - 1; t >= 0; t--)a |= this.readBit() << t; return a }, byteAlign() { this.shift = -1 }, next() { return this.position >= this.end ? -1 : this.data[this.position++] } }; function O(e, t, a) { let r = 0; for (let i = 0, n = t.length; i < n; i++) { const n = a[t[i]]; if (n) { if (e === r) return n; r++ } } throw new o("can't find custom Huffman table") } function P(e, t, a) { const r = []; for (let i = 0; i < a; i++) { const a = new Uint8Array(t); r.push(a); for (let r = 0; r < t; r++)a[r] = e.readBit(); e.byteAlign() } return r } function B(e, t, a, r) { const i = { K: -1, Columns: t, Rows: a, BlackIs1: !0, EndOfBlock: r }, n = new s.CCITTFaxDecoder(e, i), o = []; let c, l = !1; for (let e = 0; e < a; e++) { const e = new Uint8Array(t); o.push(e); let a = -1; for (let r = 0; r < t; r++) { if (a < 0) { c = n.readNextChar(); if (-1 === c) { c = 0; l = !0 } a = 7 } e[r] = c >> a & 1; a-- } } if (r && !l) { const e = 5; for (let t = 0; t < e && -1 !== n.readNextChar(); t++); } return o } function D() { } D.prototype = { parseChunks: e => function (e) { for (var t = new C, a = 0, r = e.length; a < r; a++) { var i = e[a]; S(y({}, i.data, i.start, i.end), t) } return t.buffer }(e), parse(e) { const { imgData: t, width: a, height: r } = function (e) { const t = e.length; let a = 0; if (151 !== e[a] || 74 !== e[a + 1] || 66 !== e[a + 2] || 50 !== e[a + 3] || 13 !== e[a + 4] || 10 !== e[a + 5] || 26 !== e[a + 6] || 10 !== e[a + 7]) throw new o("parseJbig2 - invalid header."); const r = Object.create(null); a += 8; const n = e[a++]; r.randomAccess = !(1 & n); if (!(2 & n)) { r.numberOfPages = (0, i.readUint32)(e, a); a += 4 } const s = y(r, e, a, t), c = new C; S(s, c); const { width: l, height: h } = c.currentPageInfo, u = c.buffer, d = new Uint8ClampedArray(l * h); let f = 0, g = 0; for (let e = 0; e < h; e++) { let e, t = 0; for (let a = 0; a < l; a++) { if (!t) { t = 128; e = u[g++] } d[f++] = e & t ? 0 : 255; t >>= 1 } } return { imgData: d, width: l, height: h } }(e); this.width = a; this.height = r; return t } }; return D }(); t.Jbig2Image = c }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.ArithmeticDecoder = void 0; const r = [{ qe: 22017, nmps: 1, nlps: 1, switchFlag: 1 }, { qe: 13313, nmps: 2, nlps: 6, switchFlag: 0 }, { qe: 6145, nmps: 3, nlps: 9, switchFlag: 0 }, { qe: 2753, nmps: 4, nlps: 12, switchFlag: 0 }, { qe: 1313, nmps: 5, nlps: 29, switchFlag: 0 }, { qe: 545, nmps: 38, nlps: 33, switchFlag: 0 }, { qe: 22017, nmps: 7, nlps: 6, switchFlag: 1 }, { qe: 21505, nmps: 8, nlps: 14, switchFlag: 0 }, { qe: 18433, nmps: 9, nlps: 14, switchFlag: 0 }, { qe: 14337, nmps: 10, nlps: 14, switchFlag: 0 }, { qe: 12289, nmps: 11, nlps: 17, switchFlag: 0 }, { qe: 9217, nmps: 12, nlps: 18, switchFlag: 0 }, { qe: 7169, nmps: 13, nlps: 20, switchFlag: 0 }, { qe: 5633, nmps: 29, nlps: 21, switchFlag: 0 }, { qe: 22017, nmps: 15, nlps: 14, switchFlag: 1 }, { qe: 21505, nmps: 16, nlps: 14, switchFlag: 0 }, { qe: 20737, nmps: 17, nlps: 15, switchFlag: 0 }, { qe: 18433, nmps: 18, nlps: 16, switchFlag: 0 }, { qe: 14337, nmps: 19, nlps: 17, switchFlag: 0 }, { qe: 13313, nmps: 20, nlps: 18, switchFlag: 0 }, { qe: 12289, nmps: 21, nlps: 19, switchFlag: 0 }, { qe: 10241, nmps: 22, nlps: 19, switchFlag: 0 }, { qe: 9217, nmps: 23, nlps: 20, switchFlag: 0 }, { qe: 8705, nmps: 24, nlps: 21, switchFlag: 0 }, { qe: 7169, nmps: 25, nlps: 22, switchFlag: 0 }, { qe: 6145, nmps: 26, nlps: 23, switchFlag: 0 }, { qe: 5633, nmps: 27, nlps: 24, switchFlag: 0 }, { qe: 5121, nmps: 28, nlps: 25, switchFlag: 0 }, { qe: 4609, nmps: 29, nlps: 26, switchFlag: 0 }, { qe: 4353, nmps: 30, nlps: 27, switchFlag: 0 }, { qe: 2753, nmps: 31, nlps: 28, switchFlag: 0 }, { qe: 2497, nmps: 32, nlps: 29, switchFlag: 0 }, { qe: 2209, nmps: 33, nlps: 30, switchFlag: 0 }, { qe: 1313, nmps: 34, nlps: 31, switchFlag: 0 }, { qe: 1089, nmps: 35, nlps: 32, switchFlag: 0 }, { qe: 673, nmps: 36, nlps: 33, switchFlag: 0 }, { qe: 545, nmps: 37, nlps: 34, switchFlag: 0 }, { qe: 321, nmps: 38, nlps: 35, switchFlag: 0 }, { qe: 273, nmps: 39, nlps: 36, switchFlag: 0 }, { qe: 133, nmps: 40, nlps: 37, switchFlag: 0 }, { qe: 73, nmps: 41, nlps: 38, switchFlag: 0 }, { qe: 37, nmps: 42, nlps: 39, switchFlag: 0 }, { qe: 21, nmps: 43, nlps: 40, switchFlag: 0 }, { qe: 9, nmps: 44, nlps: 41, switchFlag: 0 }, { qe: 5, nmps: 45, nlps: 42, switchFlag: 0 }, { qe: 1, nmps: 45, nlps: 43, switchFlag: 0 }, { qe: 22017, nmps: 46, nlps: 46, switchFlag: 0 }]; t.ArithmeticDecoder = class { constructor(e, t, a) { this.data = e; this.bp = t; this.dataEnd = a; this.chigh = e[t]; this.clow = 0; this.byteIn(); this.chigh = this.chigh << 7 & 65535 | this.clow >> 9 & 127; this.clow = this.clow << 7 & 65535; this.ct -= 7; this.a = 32768 } byteIn() { const e = this.data; let t = this.bp; if (255 === e[t]) if (e[t + 1] > 143) { this.clow += 65280; this.ct = 8 } else { t++; this.clow += e[t] << 9; this.ct = 7; this.bp = t } else { t++; this.clow += t < this.dataEnd ? e[t] << 8 : 65280; this.ct = 8; this.bp = t } if (this.clow > 65535) { this.chigh += this.clow >> 16; this.clow &= 65535 } } readBit(e, t) { let a = e[t] >> 1, i = 1 & e[t]; const n = r[a], s = n.qe; let o, c = this.a - s; if (this.chigh < s) if (c < s) { c = s; o = i; a = n.nmps } else { c = s; o = 1 ^ i; 1 === n.switchFlag && (i = o); a = n.nlps } else { this.chigh -= s; if (0 != (32768 & c)) { this.a = c; return i } if (c < s) { o = 1 ^ i; 1 === n.switchFlag && (i = o); a = n.nlps } else { o = i; a = n.nmps } } do { 0 === this.ct && this.byteIn(); c <<= 1; this.chigh = this.chigh << 1 & 65535 | this.clow >> 15 & 1; this.clow = this.clow << 1 & 65535; this.ct-- } while (0 == (32768 & c)); this.a = c; e[t] = a << 1 | i; return o } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.JpegStream = void 0; var r = a(2), i = a(11), n = a(4), s = a(18); const o = function () { function e(e, t, a, r) { let n; for (; -1 !== (n = e.getByte());)if (255 === n) { e.skip(-1); break } this.stream = e; this.maybeLength = t; this.dict = a; this.params = r; i.DecodeStream.call(this, t) } e.prototype = Object.create(i.DecodeStream.prototype); Object.defineProperty(e.prototype, "bytes", { get: function () { return (0, r.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)) }, configurable: !0 }); e.prototype.ensureBuffer = function (e) { }; e.prototype.readBlock = function () { if (this.eof) return; const e = { decodeTransform: void 0, colorTransform: void 0 }, t = this.dict.getArray("Decode", "D"); if (this.forceRGB && Array.isArray(t)) { const a = this.dict.get("BitsPerComponent") || 8, r = t.length, i = new Int32Array(r); let n = !1; const s = (1 << a) - 1; for (let e = 0; e < r; e += 2) { i[e] = 256 * (t[e + 1] - t[e]) | 0; i[e + 1] = t[e] * s | 0; 256 === i[e] && 0 === i[e + 1] || (n = !0) } n && (e.decodeTransform = i) } if ((0, n.isDict)(this.params)) { const t = this.params.get("ColorTransform"); Number.isInteger(t) && (e.colorTransform = t) } const a = new s.JpegImage(e); a.parse(this.bytes); const r = a.getData({ width: this.drawWidth, height: this.drawHeight, forceRGB: this.forceRGB, isSourcePDF: !0 }); this.buffer = r; this.bufferLength = r.length; this.eof = !0 }; Object.defineProperty(e.prototype, "maybeValidDimensions", { get: function () { const { dict: e, stream: t } = this, a = e.get("Height", "H"), i = t.pos; let n, s = !0, o = !1; for (; -1 !== (n = t.getByte());)if (255 === n) { switch (t.getByte()) { case 192: case 193: case 194: o = !0; t.pos += 2; t.pos += 1; const e = t.getUint16(); if (e === a) break; if (0 === e) { s = !1; break } if (e > 10 * a) { s = !1; break } break; case 195: case 197: case 198: case 199: case 201: case 202: case 203: case 205: case 206: case 207: o = !0; break; case 196: case 204: case 218: case 219: case 220: case 221: case 222: case 223: case 224: case 225: case 226: case 227: case 228: case 229: case 230: case 231: case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239: case 254: const r = t.getUint16(); r > 2 ? t.skip(r - 2) : t.skip(-2); break; case 255: t.skip(-1); break; case 217: o = !0 }if (o) break } t.pos = i; return (0, r.shadow)(this, "maybeValidDimensions", s) }, configurable: !0 }); e.prototype.getIR = function (e = !1) { return (0, r.createObjectURL)(this.bytes, "image/jpeg", e) }; return e }(); t.JpegStream = o }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.JpegImage = void 0; var r = a(2), i = a(7); class n extends r.BaseException { constructor(e) { super(`JPEG error: ${e}`) } } class s extends r.BaseException { constructor(e, t) { super(e); this.scanLines = t } } class o extends r.BaseException { } var c = function () { var e = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]); function t({ decodeTransform: e = null, colorTransform: t = -1 } = {}) { this._decodeTransform = e; this._colorTransform = t } function a(e, t) { for (var a, r, i = 0, n = [], s = 16; s > 0 && !e[s - 1];)s--; n.push({ children: [], index: 0 }); var o, c = n[0]; for (a = 0; a < s; a++) { for (r = 0; r < e[a]; r++) { (c = n.pop()).children[c.index] = t[i]; for (; c.index > 0;)c = n.pop(); c.index++; n.push(c); for (; n.length <= a;) { n.push(o = { children: [], index: 0 }); c.children[c.index] = o.children; c = o } i++ } if (a + 1 < s) { n.push(o = { children: [], index: 0 }); c.children[c.index] = o.children; c = o } } return n[0].children } function c(e, t, a) { return 64 * ((e.blocksPerLine + 1) * t + a) } function l(t, a, l, h, u, f, g, m, p, b = !1) { var y = l.mcusPerLine, v = l.progressive, w = a, k = 0, S = 0; function C() { if (S > 0) { S--; return k >> S & 1 } if (255 === (k = t[a++])) { var e = t[a++]; if (e) { if (220 === e && b) { a += 2; const e = (0, i.readUint16)(t, a); a += 2; if (e > 0 && e !== l.scanLines) throw new s("Found DNL marker (0xFFDC) while parsing scan data", e) } else if (217 === e) { if (b) { const e = 8 * O; if (e > 0 && e < l.scanLines / 10) throw new s("Found EOI marker (0xFFD9) while parsing scan data, possibly caused by incorrect `scanLines` parameter", e) } throw new o("Found EOI marker (0xFFD9) while parsing scan data") } throw new n(`unexpected marker ${(k << 8 | e).toString(16)}`) } } S = 7; return k >>> 7 } function x(e) { for (var t = e; ;) { switch (typeof (t = t[C()])) { case "number": return t; case "object": continue }throw new n("invalid huffman sequence") } } function A(e) { for (var t = 0; e > 0;) { t = t << 1 | C(); e-- } return t } function I(e) { if (1 === e) return 1 === C() ? 1 : -1; var t = A(e); return t >= 1 << e - 1 ? t : t + (-1 << e) + 1 } var F = 0; var T, E = 0; let O = 0; function P(e, t, a, r, i) { var n = a % y; O = (a / y | 0) * e.v + r; var s = n * e.h + i; t(e, c(e, O, s)) } function B(e, t, a) { O = a / e.blocksPerLine | 0; var r = a % e.blocksPerLine; t(e, c(e, O, r)) } var D, N, M, L, R, U, q = h.length; U = v ? 0 === f ? 0 === m ? function (e, t) { var a = x(e.huffmanTableDC), r = 0 === a ? 0 : I(a) << p; e.blockData[t] = e.pred += r } : function (e, t) { e.blockData[t] |= C() << p } : 0 === m ? function (t, a) { if (F > 0) F--; else for (var r = f, i = g; r <= i;) { var n = x(t.huffmanTableAC), s = 15 & n, o = n >> 4; if (0 !== s) { var c = e[r += o]; t.blockData[a + c] = I(s) * (1 << p); r++ } else { if (o < 15) { F = A(o) + (1 << o) - 1; break } r += 16 } } } : function (t, a) { for (var r, i, s = f, o = g, c = 0; s <= o;) { const o = a + e[s], l = t.blockData[o] < 0 ? -1 : 1; switch (E) { case 0: c = (i = x(t.huffmanTableAC)) >> 4; if (0 === (r = 15 & i)) if (c < 15) { F = A(c) + (1 << c); E = 4 } else { c = 16; E = 1 } else { if (1 !== r) throw new n("invalid ACn encoding"); T = I(r); E = c ? 2 : 3 } continue; case 1: case 2: t.blockData[o] ? t.blockData[o] += l * (C() << p) : 0 === --c && (E = 2 === E ? 3 : 0); break; case 3: if (t.blockData[o]) t.blockData[o] += l * (C() << p); else { t.blockData[o] = T << p; E = 0 } break; case 4: t.blockData[o] && (t.blockData[o] += l * (C() << p)) }s++ } 4 === E && 0 === --F && (E = 0) } : function (t, a) { var r = x(t.huffmanTableDC), i = 0 === r ? 0 : I(r); t.blockData[a] = t.pred += i; for (var n = 1; n < 64;) { var s = x(t.huffmanTableAC), o = 15 & s, c = s >> 4; if (0 !== o) { var l = e[n += c]; t.blockData[a + l] = I(o); n++ } else { if (c < 15) break; n += 16 } } }; var j, _, z, H, G = 0; _ = 1 === q ? h[0].blocksPerLine * h[0].blocksPerColumn : y * l.mcusPerColumn; for (; G < _;) { var W = u ? Math.min(_ - G, u) : _; for (N = 0; N < q; N++)h[N].pred = 0; F = 0; if (1 === q) { D = h[0]; for (R = 0; R < W; R++) { B(D, U, G); G++ } } else for (R = 0; R < W; R++) { for (N = 0; N < q; N++) { z = (D = h[N]).h; H = D.v; for (M = 0; M < H; M++)for (L = 0; L < z; L++)P(D, U, G, M, L) } G++ } S = 0; if (!(j = d(t, a))) break; if (j.invalid) { (0, r.warn)("decodeScan - unexpected MCU data, current marker is: " + j.invalid); a = j.offset } var X = j && j.marker; if (!X || X <= 65280) throw new n("decodeScan - a valid marker was not found."); if (!(X >= 65488 && X <= 65495)) break; a += 2 } if ((j = d(t, a)) && j.invalid) { (0, r.warn)("decodeScan - unexpected Scan data, current marker is: " + j.invalid); a = j.offset } return a - w } function h(e, t, a) { var r, i, s, o, c, l, h, u, d, f, g, m, p, b, y, v, w, k = e.quantizationTable, S = e.blockData; if (!k) throw new n("missing required Quantization Table."); for (var C = 0; C < 64; C += 8) { d = S[t + C]; f = S[t + C + 1]; g = S[t + C + 2]; m = S[t + C + 3]; p = S[t + C + 4]; b = S[t + C + 5]; y = S[t + C + 6]; v = S[t + C + 7]; d *= k[C]; if (0 != (f | g | m | p | b | y | v)) { f *= k[C + 1]; g *= k[C + 2]; m *= k[C + 3]; p *= k[C + 4]; b *= k[C + 5]; i = (r = (r = 5793 * d + 128 >> 8) + (i = 5793 * p + 128 >> 8) + 1 >> 1) - i; w = 3784 * (s = g) + 1567 * (o = y *= k[C + 6]) + 128 >> 8; s = 1567 * s - 3784 * o + 128 >> 8; h = (c = (c = 2896 * (f - (v *= k[C + 7])) + 128 >> 8) + (h = b << 4) + 1 >> 1) - h; l = (u = (u = 2896 * (f + v) + 128 >> 8) + (l = m << 4) + 1 >> 1) - l; o = (r = r + (o = w) + 1 >> 1) - o; s = (i = i + s + 1 >> 1) - s; w = 2276 * c + 3406 * u + 2048 >> 12; c = 3406 * c - 2276 * u + 2048 >> 12; u = w; w = 799 * l + 4017 * h + 2048 >> 12; l = 4017 * l - 799 * h + 2048 >> 12; h = w; a[C] = r + u; a[C + 7] = r - u; a[C + 1] = i + h; a[C + 6] = i - h; a[C + 2] = s + l; a[C + 5] = s - l; a[C + 3] = o + c; a[C + 4] = o - c } else { w = 5793 * d + 512 >> 10; a[C] = w; a[C + 1] = w; a[C + 2] = w; a[C + 3] = w; a[C + 4] = w; a[C + 5] = w; a[C + 6] = w; a[C + 7] = w } } for (var x = 0; x < 8; ++x) { d = a[x]; if (0 != ((f = a[x + 8]) | (g = a[x + 16]) | (m = a[x + 24]) | (p = a[x + 32]) | (b = a[x + 40]) | (y = a[x + 48]) | (v = a[x + 56]))) { i = (r = 4112 + ((r = 5793 * d + 2048 >> 12) + (i = 5793 * p + 2048 >> 12) + 1 >> 1)) - i; w = 3784 * (s = g) + 1567 * (o = y) + 2048 >> 12; s = 1567 * s - 3784 * o + 2048 >> 12; o = w; h = (c = (c = 2896 * (f - v) + 2048 >> 12) + (h = b) + 1 >> 1) - h; l = (u = (u = 2896 * (f + v) + 2048 >> 12) + (l = m) + 1 >> 1) - l; w = 2276 * c + 3406 * u + 2048 >> 12; c = 3406 * c - 2276 * u + 2048 >> 12; u = w; w = 799 * l + 4017 * h + 2048 >> 12; l = 4017 * l - 799 * h + 2048 >> 12; (d = (r = r + o + 1 >> 1) + u) < 16 ? d = 0 : d >= 4080 ? d = 255 : d >>= 4; (f = (i = i + s + 1 >> 1) + (h = w)) < 16 ? f = 0 : f >= 4080 ? f = 255 : f >>= 4; (g = (s = i - s) + l) < 16 ? g = 0 : g >= 4080 ? g = 255 : g >>= 4; (m = (o = r - o) + c) < 16 ? m = 0 : m >= 4080 ? m = 255 : m >>= 4; (p = o - c) < 16 ? p = 0 : p >= 4080 ? p = 255 : p >>= 4; (b = s - l) < 16 ? b = 0 : b >= 4080 ? b = 255 : b >>= 4; (y = i - h) < 16 ? y = 0 : y >= 4080 ? y = 255 : y >>= 4; (v = r - u) < 16 ? v = 0 : v >= 4080 ? v = 255 : v >>= 4; S[t + x] = d; S[t + x + 8] = f; S[t + x + 16] = g; S[t + x + 24] = m; S[t + x + 32] = p; S[t + x + 40] = b; S[t + x + 48] = y; S[t + x + 56] = v } else { w = (w = 5793 * d + 8192 >> 14) < -2040 ? 0 : w >= 2024 ? 255 : w + 2056 >> 4; S[t + x] = w; S[t + x + 8] = w; S[t + x + 16] = w; S[t + x + 24] = w; S[t + x + 32] = w; S[t + x + 40] = w; S[t + x + 48] = w; S[t + x + 56] = w } } } function u(e, t) { for (var a = t.blocksPerLine, r = t.blocksPerColumn, i = new Int16Array(64), n = 0; n < r; n++)for (var s = 0; s < a; s++) { h(t, c(t, n, s), i) } return t.blockData } function d(e, t, a = t) { const r = e.length - 1; var n = a < t ? a : t; if (t >= r) return null; var s = (0, i.readUint16)(e, t); if (s >= 65472 && s <= 65534) return { invalid: null, marker: s, offset: t }; for (var o = (0, i.readUint16)(e, n); !(o >= 65472 && o <= 65534);) { if (++n >= r) return null; o = (0, i.readUint16)(e, n) } return { invalid: s.toString(16), marker: o, offset: n } } t.prototype = { parse(t, { dnlScanLines: c = null } = {}) { function h() { const e = (0, i.readUint16)(t, p); let a = (p += 2) + e - 2; var n = d(t, a, p); if (n && n.invalid) { (0, r.warn)("readDataBlock - incorrect length, current marker is: " + n.invalid); a = n.offset } var s = t.subarray(p, a); p += s.length; return s } function f(e) { for (var t = Math.ceil(e.samplesPerLine / 8 / e.maxH), a = Math.ceil(e.scanLines / 8 / e.maxV), r = 0; r < e.components.length; r++) { z = e.components[r]; var i = Math.ceil(Math.ceil(e.samplesPerLine / 8) * z.h / e.maxH), n = Math.ceil(Math.ceil(e.scanLines / 8) * z.v / e.maxV), s = t * z.h, o = 64 * (a * z.v) * (s + 1); z.blockData = new Int16Array(o); z.blocksPerLine = i; z.blocksPerColumn = n } e.mcusPerLine = t; e.mcusPerColumn = a } var g, m, p = 0, b = null, y = null; let v = 0; var w = [], k = [], S = []; let C = (0, i.readUint16)(t, p); p += 2; if (65496 !== C) throw new n("SOI not found"); C = (0, i.readUint16)(t, p); p += 2; e: for (; 65497 !== C;) { var x, A, I; switch (C) { case 65504: case 65505: case 65506: case 65507: case 65508: case 65509: case 65510: case 65511: case 65512: case 65513: case 65514: case 65515: case 65516: case 65517: case 65518: case 65519: case 65534: var F = h(); 65504 === C && 74 === F[0] && 70 === F[1] && 73 === F[2] && 70 === F[3] && 0 === F[4] && (b = { version: { major: F[5], minor: F[6] }, densityUnits: F[7], xDensity: F[8] << 8 | F[9], yDensity: F[10] << 8 | F[11], thumbWidth: F[12], thumbHeight: F[13], thumbData: F.subarray(14, 14 + 3 * F[12] * F[13]) }); 65518 === C && 65 === F[0] && 100 === F[1] && 111 === F[2] && 98 === F[3] && 101 === F[4] && (y = { version: F[5] << 8 | F[6], flags0: F[7] << 8 | F[8], flags1: F[9] << 8 | F[10], transformCode: F[11] }); break; case 65499: for (var T = (0, i.readUint16)(t, p) + (p += 2) - 2; p < T;) { var E = t[p++], O = new Uint16Array(64); if (E >> 4 == 0) for (A = 0; A < 64; A++)O[e[A]] = t[p++]; else { if (E >> 4 != 1) throw new n("DQT - invalid table spec"); for (A = 0; A < 64; A++) { O[e[A]] = (0, i.readUint16)(t, p); p += 2 } } w[15 & E] = O } break; case 65472: case 65473: case 65474: if (g) throw new n("Only single frame JPEGs supported"); p += 2; (g = {}).extended = 65473 === C; g.progressive = 65474 === C; g.precision = t[p++]; const u = (0, i.readUint16)(t, p); p += 2; g.scanLines = c || u; g.samplesPerLine = (0, i.readUint16)(t, p); p += 2; g.components = []; g.componentIds = {}; var P, B = t[p++], D = 0, N = 0; for (x = 0; x < B; x++) { P = t[p]; var M = t[p + 1] >> 4, L = 15 & t[p + 1]; D < M && (D = M); N < L && (N = L); var R = t[p + 2]; I = g.components.push({ h: M, v: L, quantizationId: R, quantizationTable: null }); g.componentIds[P] = I - 1; p += 3 } g.maxH = D; g.maxV = N; f(g); break; case 65476: const J = (0, i.readUint16)(t, p); p += 2; for (x = 2; x < J;) { var U = t[p++], q = new Uint8Array(16), j = 0; for (A = 0; A < 16; A++, p++)j += q[A] = t[p]; var _ = new Uint8Array(j); for (A = 0; A < j; A++, p++)_[A] = t[p]; x += 17 + j; (U >> 4 == 0 ? S : k)[15 & U] = a(q, _) } break; case 65501: p += 2; m = (0, i.readUint16)(t, p); p += 2; break; case 65498: const Z = 1 == ++v && !c; p += 2; var z, H = t[p++], G = []; for (x = 0; x < H; x++) { var W = g.componentIds[t[p++]]; z = g.components[W]; var X = t[p++]; z.huffmanTableDC = S[X >> 4]; z.huffmanTableAC = k[15 & X]; G.push(z) } var V = t[p++], K = t[p++], Y = t[p++]; try { var $ = l(t, p, g, G, m, V, K, Y >> 4, 15 & Y, Z); p += $ } catch (e) { if (e instanceof s) { (0, r.warn)(`${e.message} -- attempting to re-parse the JPEG image.`); return this.parse(t, { dnlScanLines: e.scanLines }) } if (e instanceof o) { (0, r.warn)(`${e.message} -- ignoring the rest of the image data.`); break e } throw e } break; case 65500: p += 4; break; case 65535: 255 !== t[p] && p--; break; default: const Q = d(t, p - 2, p - 3); if (Q && Q.invalid) { (0, r.warn)("JpegImage.parse - unexpected data, current marker is: " + Q.invalid); p = Q.offset; break } if (p >= t.length - 1) { (0, r.warn)("JpegImage.parse - reached the end of the image data without finding an EOI marker (0xFFD9)."); break e } throw new n("JpegImage.parse - unknown marker: " + C.toString(16)) }C = (0, i.readUint16)(t, p); p += 2 } this.width = g.samplesPerLine; this.height = g.scanLines; this.jfif = b; this.adobe = y; this.components = []; for (x = 0; x < g.components.length; x++) { var J = w[(z = g.components[x]).quantizationId]; J && (z.quantizationTable = J); this.components.push({ output: u(0, z), scaleX: z.h / g.maxH, scaleY: z.v / g.maxV, blocksPerLine: z.blocksPerLine, blocksPerColumn: z.blocksPerColumn }) } this.numComponents = this.components.length }, _getLinearizedBlockData(e, t, a = !1) { var r, i, n, s, o, c, l, h, u, d, f, g = this.width / e, m = this.height / t, p = 0, b = this.components.length, y = e * t * b, v = new Uint8ClampedArray(y), w = new Uint32Array(e); let k; for (l = 0; l < b; l++) { i = (r = this.components[l]).scaleX * g; n = r.scaleY * m; p = l; f = r.output; s = r.blocksPerLine + 1 << 3; if (i !== k) { for (o = 0; o < e; o++) { h = 0 | o * i; w[o] = (4294967288 & h) << 3 | 7 & h } k = i } for (c = 0; c < t; c++) { d = s * (4294967288 & (h = 0 | c * n)) | (7 & h) << 3; for (o = 0; o < e; o++) { v[p] = f[d + w[o]]; p += b } } } let S = this._decodeTransform; a || 4 !== b || S || (S = new Int32Array([-256, 255, -256, 255, -256, 255, -256, 255])); if (S) for (l = 0; l < y;)for (h = 0, u = 0; h < b; h++, l++, u += 2)v[l] = (v[l] * S[u] >> 8) + S[u + 1]; return v }, get _isColorConversionNeeded() { return this.adobe ? !!this.adobe.transformCode : 3 === this.numComponents ? 0 !== this._colorTransform : 1 === this._colorTransform }, _convertYccToRgb: function (e) { for (var t, a, r, i = 0, n = e.length; i < n; i += 3) { t = e[i]; a = e[i + 1]; r = e[i + 2]; e[i] = t - 179.456 + 1.402 * r; e[i + 1] = t + 135.459 - .344 * a - .714 * r; e[i + 2] = t - 226.816 + 1.772 * a } return e }, _convertYcckToRgb: function (e) { for (var t, a, r, i, n = 0, s = 0, o = e.length; s < o; s += 4) { t = e[s]; a = e[s + 1]; r = e[s + 2]; i = e[s + 3]; e[n++] = a * (-660635669420364e-19 * a + .000437130475926232 * r - 54080610064599e-18 * t + .00048449797120281 * i - .154362151871126) - 122.67195406894 + r * (-.000957964378445773 * r + .000817076911346625 * t - .00477271405408747 * i + 1.53380253221734) + t * (.000961250184130688 * t - .00266257332283933 * i + .48357088451265) + i * (-.000336197177618394 * i + .484791561490776); e[n++] = 107.268039397724 + a * (219927104525741e-19 * a - .000640992018297945 * r + .000659397001245577 * t + .000426105652938837 * i - .176491792462875) + r * (-.000778269941513683 * r + .00130872261408275 * t + .000770482631801132 * i - .151051492775562) + t * (.00126935368114843 * t - .00265090189010898 * i + .25802910206845) + i * (-.000318913117588328 * i - .213742400323665); e[n++] = a * (-.000570115196973677 * a - 263409051004589e-19 * r + .0020741088115012 * t - .00288260236853442 * i + .814272968359295) - 20.810012546947 + r * (-153496057440975e-19 * r - .000132689043961446 * t + .000560833691242812 * i - .195152027534049) + t * (.00174418132927582 * t - .00255243321439347 * i + .116935020465145) + i * (-.000343531996510555 * i + .24165260232407) } return e.subarray(0, n) }, _convertYcckToCmyk: function (e) { for (var t, a, r, i = 0, n = e.length; i < n; i += 4) { t = e[i]; a = e[i + 1]; r = e[i + 2]; e[i] = 434.456 - t - 1.402 * r; e[i + 1] = 119.541 - t + .344 * a + .714 * r; e[i + 2] = 481.816 - t - 1.772 * a } return e }, _convertCmykToRgb: function (e) { for (var t, a, r, i, n = 0, s = 0, o = e.length; s < o; s += 4) { t = e[s]; a = e[s + 1]; r = e[s + 2]; i = e[s + 3]; e[n++] = 255 + t * (-6747147073602441e-20 * t + .0008379262121013727 * a + .0002894718188643294 * r + .003264231057537806 * i - 1.1185611867203937) + a * (26374107616089405e-21 * a - 8626949158638572e-20 * r - .0002748769067499491 * i - .02155688794978967) + r * (-3878099212869363e-20 * r - .0003267808279485286 * i + .0686742238595345) - i * (.0003361971776183937 * i + .7430659151342254); e[n++] = 255 + t * (.00013596372813588848 * t + .000924537132573585 * a + .00010567359618683593 * r + .0004791864687436512 * i - .3109689587515875) + a * (-.00023545346108370344 * a + .0002702845253534714 * r + .0020200308977307156 * i - .7488052167015494) + r * (6834815998235662e-20 * r + .00015168452363460973 * i - .09751927774728933) - i * (.0003189131175883281 * i + .7364883807733168); e[n++] = 255 + t * (13598650411385307e-21 * t + .00012423956175490851 * a + .0004751985097583589 * r - 36729317476630422e-22 * i - .05562186980264034) + a * (.00016141380598724676 * a + .0009692239130725186 * r + .0007782692450036253 * i - .44015232367526463) + r * (5.068882914068769e-7 * r + .0017778369011375071 * i - .7591454649749609) - i * (.0003435319965105553 * i + .7063770186160144) } return e.subarray(0, n) }, getData({ width: e, height: t, forceRGB: a = !1, isSourcePDF: r = !1 }) { if (this.numComponents > 4) throw new n("Unsupported color mode"); var i = this._getLinearizedBlockData(e, t, r); if (1 === this.numComponents && a) { for (var s = i.length, o = new Uint8ClampedArray(3 * s), c = 0, l = 0; l < s; l++) { var h = i[l]; o[c++] = h; o[c++] = h; o[c++] = h } return o } if (3 === this.numComponents && this._isColorConversionNeeded) return this._convertYccToRgb(i); if (4 === this.numComponents) { if (this._isColorConversionNeeded) return a ? this._convertYcckToRgb(i) : this._convertYcckToCmyk(i); if (a) return this._convertCmykToRgb(i) } return i } }; return t }(); t.JpegImage = c }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.JpxStream = void 0; var r = a(11), i = a(20), n = a(2); const s = function () { function e(e, t, a, i) { this.stream = e; this.maybeLength = t; this.dict = a; this.params = i; r.DecodeStream.call(this, t) } e.prototype = Object.create(r.DecodeStream.prototype); Object.defineProperty(e.prototype, "bytes", { get: function () { return (0, n.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)) }, configurable: !0 }); e.prototype.ensureBuffer = function (e) { }; e.prototype.readBlock = function () { if (this.eof) return; const e = new i.JpxImage; e.parse(this.bytes); const t = e.width, a = e.height, r = e.componentsCount, n = e.tiles.length; if (1 === n) this.buffer = e.tiles[0].items; else { const i = new Uint8ClampedArray(t * a * r); for (let a = 0; a < n; a++) { const n = e.tiles[a], s = n.width, o = n.height, c = n.left, l = n.top, h = n.items; let u = 0, d = (t * l + c) * r; const f = t * r, g = s * r; for (let e = 0; e < o; e++) { const e = h.subarray(u, u + g); i.set(e, d); u += g; d += f } } this.buffer = i } this.bufferLength = this.buffer.length; this.eof = !0 }; return e }(); t.JpxStream = s }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.JpxImage = void 0; var r = a(2), i = a(7), n = a(16); class s extends r.BaseException { constructor(e) { super(`JPX error: ${e}`) } } var o = function () { var e = { LL: 0, LH: 1, HL: 1, HH: 2 }; function t() { this.failOnCorruptedImage = !1 } t.prototype = { parse: function (e) { if (65359 !== (0, i.readUint16)(e, 0)) for (var t = 0, a = e.length; t < a;) { var n = 8, o = (0, i.readUint32)(e, t), c = (0, i.readUint32)(e, t + 4); t += n; if (1 === o) { o = 4294967296 * (0, i.readUint32)(e, t) + (0, i.readUint32)(e, t + 4); t += 8; n += 8 } 0 === o && (o = a - t + n); if (o < n) throw new s("Invalid box field size"); var l = o - n, h = !0; switch (c) { case 1785737832: h = !1; break; case 1668246642: var u = e[t]; if (1 === u) { var d = (0, i.readUint32)(e, t + 3); switch (d) { case 16: case 17: case 18: break; default: (0, r.warn)("Unknown colorspace " + d) } } else 2 === u && (0, r.info)("ICC profile not supported"); break; case 1785737827: this.parseCodestream(e, t, t + l); break; case 1783636e3: 218793738 !== (0, i.readUint32)(e, t) && (0, r.warn)("Invalid JP2 signature"); break; case 1783634458: case 1718909296: case 1920099697: case 1919251232: case 1768449138: break; default: var f = String.fromCharCode(c >> 24 & 255, c >> 16 & 255, c >> 8 & 255, 255 & c); (0, r.warn)("Unsupported header type " + c + " (" + f + ")") }h && (t += l) } else this.parseCodestream(e, 0, e.length) }, parseImageProperties: function (e) { for (var t = e.getByte(); t >= 0;) { if (65361 === (t << 8 | (t = e.getByte()))) { e.skip(4); var a = e.getInt32() >>> 0, r = e.getInt32() >>> 0, i = e.getInt32() >>> 0, n = e.getInt32() >>> 0; e.skip(16); var o = e.getUint16(); this.width = a - i; this.height = r - n; this.componentsCount = o; this.bitsPerComponent = 8; return } } throw new s("No size marker found in JPX stream") }, parseCodestream: function (e, t, n) { var c = {}, l = !1; try { for (var h = t; h + 1 < n;) { var u = (0, i.readUint16)(e, h); h += 2; var d, f, g, m, p, b, y = 0; switch (u) { case 65359: c.mainHeader = !0; break; case 65497: break; case 65361: y = (0, i.readUint16)(e, h); var k = {}; k.Xsiz = (0, i.readUint32)(e, h + 4); k.Ysiz = (0, i.readUint32)(e, h + 8); k.XOsiz = (0, i.readUint32)(e, h + 12); k.YOsiz = (0, i.readUint32)(e, h + 16); k.XTsiz = (0, i.readUint32)(e, h + 20); k.YTsiz = (0, i.readUint32)(e, h + 24); k.XTOsiz = (0, i.readUint32)(e, h + 28); k.YTOsiz = (0, i.readUint32)(e, h + 32); var x = (0, i.readUint16)(e, h + 36); k.Csiz = x; var A = []; d = h + 38; for (var I = 0; I < x; I++) { var F = { precision: 1 + (127 & e[d]), isSigned: !!(128 & e[d]), XRsiz: e[d + 1], YRsiz: e[d + 2] }; d += 3; a(F, k); A.push(F) } c.SIZ = k; c.components = A; o(c, A); c.QCC = []; c.COC = []; break; case 65372: y = (0, i.readUint16)(e, h); var T = {}; d = h + 2; switch (31 & (f = e[d++])) { case 0: m = 8; p = !0; break; case 1: m = 16; p = !1; break; case 2: m = 16; p = !0; break; default: throw new Error("Invalid SQcd value " + f) }T.noQuantization = 8 === m; T.scalarExpounded = p; T.guardBits = f >> 5; g = []; for (; d < y + h;) { var E = {}; if (8 === m) { E.epsilon = e[d++] >> 3; E.mu = 0 } else { E.epsilon = e[d] >> 3; E.mu = (7 & e[d]) << 8 | e[d + 1]; d += 2 } g.push(E) } T.SPqcds = g; if (c.mainHeader) c.QCD = T; else { c.currentTile.QCD = T; c.currentTile.QCC = [] } break; case 65373: y = (0, i.readUint16)(e, h); var O, P = {}; d = h + 2; if (c.SIZ.Csiz < 257) O = e[d++]; else { O = (0, i.readUint16)(e, d); d += 2 } switch (31 & (f = e[d++])) { case 0: m = 8; p = !0; break; case 1: m = 16; p = !1; break; case 2: m = 16; p = !0; break; default: throw new Error("Invalid SQcd value " + f) }P.noQuantization = 8 === m; P.scalarExpounded = p; P.guardBits = f >> 5; g = []; for (; d < y + h;) { E = {}; if (8 === m) { E.epsilon = e[d++] >> 3; E.mu = 0 } else { E.epsilon = e[d] >> 3; E.mu = (7 & e[d]) << 8 | e[d + 1]; d += 2 } g.push(E) } P.SPqcds = g; c.mainHeader ? c.QCC[O] = P : c.currentTile.QCC[O] = P; break; case 65362: y = (0, i.readUint16)(e, h); var B = {}; d = h + 2; var D = e[d++]; B.entropyCoderWithCustomPrecincts = !!(1 & D); B.sopMarkerUsed = !!(2 & D); B.ephMarkerUsed = !!(4 & D); B.progressionOrder = e[d++]; B.layersCount = (0, i.readUint16)(e, d); d += 2; B.multipleComponentTransform = e[d++]; B.decompositionLevelsCount = e[d++]; B.xcb = 2 + (15 & e[d++]); B.ycb = 2 + (15 & e[d++]); var N = e[d++]; B.selectiveArithmeticCodingBypass = !!(1 & N); B.resetContextProbabilities = !!(2 & N); B.terminationOnEachCodingPass = !!(4 & N); B.verticallyStripe = !!(8 & N); B.predictableTermination = !!(16 & N); B.segmentationSymbolUsed = !!(32 & N); B.reversibleTransformation = e[d++]; if (B.entropyCoderWithCustomPrecincts) { for (var M = []; d < y + h;) { var L = e[d++]; M.push({ PPx: 15 & L, PPy: L >> 4 }) } B.precinctsSizes = M } var R = []; B.selectiveArithmeticCodingBypass && R.push("selectiveArithmeticCodingBypass"); B.resetContextProbabilities && R.push("resetContextProbabilities"); B.terminationOnEachCodingPass && R.push("terminationOnEachCodingPass"); B.verticallyStripe && R.push("verticallyStripe"); B.predictableTermination && R.push("predictableTermination"); if (R.length > 0) { l = !0; throw new Error("Unsupported COD options (" + R.join(", ") + ")") } if (c.mainHeader) c.COD = B; else { c.currentTile.COD = B; c.currentTile.COC = [] } break; case 65424: y = (0, i.readUint16)(e, h); (b = {}).index = (0, i.readUint16)(e, h + 2); b.length = (0, i.readUint32)(e, h + 4); b.dataEnd = b.length + h - 2; b.partIndex = e[h + 8]; b.partsCount = e[h + 9]; c.mainHeader = !1; if (0 === b.partIndex) { b.COD = c.COD; b.COC = c.COC.slice(0); b.QCD = c.QCD; b.QCC = c.QCC.slice(0) } c.currentTile = b; break; case 65427: if (0 === (b = c.currentTile).partIndex) { C(c, b.index); v(c) } w(c, e, h, y = b.dataEnd - h); break; case 65365: case 65367: case 65368: case 65380: y = (0, i.readUint16)(e, h); break; case 65363: throw new Error("Codestream code 0xFF53 (COC) is not implemented"); default: throw new Error("Unknown codestream code: " + u.toString(16)) }h += y } } catch (e) { if (l || this.failOnCorruptedImage) throw new s(e.message); (0, r.warn)("JPX: Trying to recover from: " + e.message) } this.tiles = function (e) { for (var t = e.SIZ, a = e.components, r = t.Csiz, i = [], n = 0, s = e.tiles.length; n < s; n++) { var o, c = e.tiles[n], l = []; for (o = 0; o < r; o++)l[o] = S(e, c, o); var h, u, d, f, g, m, p, b = l[0], y = new Uint8ClampedArray(b.items.length * r), v = { left: b.left, top: b.top, width: b.width, height: b.height, items: y }, w = 0; if (c.codingStyleDefaultParameters.multipleComponentTransform) { var k = 4 === r, C = l[0].items, x = l[1].items, A = l[2].items, I = k ? l[3].items : null; h = a[0].precision - 8; u = .5 + (128 << h); var F = c.components[0], T = r - 3; f = C.length; if (F.codingStyleParameters.reversibleTransformation) for (d = 0; d < f; d++, w += T) { g = C[d] + u; m = x[d]; p = A[d]; const e = g - (p + m >> 2); y[w++] = e + p >> h; y[w++] = e >> h; y[w++] = e + m >> h } else for (d = 0; d < f; d++, w += T) { g = C[d] + u; m = x[d]; p = A[d]; y[w++] = g + 1.402 * p >> h; y[w++] = g - .34413 * m - .71414 * p >> h; y[w++] = g + 1.772 * m >> h } if (k) for (d = 0, w = 3; d < f; d++, w += 4)y[w] = I[d] + u >> h } else for (o = 0; o < r; o++) { var E = l[o].items; h = a[o].precision - 8; u = .5 + (128 << h); for (w = o, d = 0, f = E.length; d < f; d++) { y[w] = E[d] + u >> h; w += r } } i.push(v) } return i }(c); this.width = c.SIZ.Xsiz - c.SIZ.XOsiz; this.height = c.SIZ.Ysiz - c.SIZ.YOsiz; this.componentsCount = c.SIZ.Csiz } }; function a(e, t) { e.x0 = Math.ceil(t.XOsiz / e.XRsiz); e.x1 = Math.ceil(t.Xsiz / e.XRsiz); e.y0 = Math.ceil(t.YOsiz / e.YRsiz); e.y1 = Math.ceil(t.Ysiz / e.YRsiz); e.width = e.x1 - e.x0; e.height = e.y1 - e.y0 } function o(e, t) { for (var a, r = e.SIZ, i = [], n = Math.ceil((r.Xsiz - r.XTOsiz) / r.XTsiz), s = Math.ceil((r.Ysiz - r.YTOsiz) / r.YTsiz), o = 0; o < s; o++)for (var c = 0; c < n; c++) { (a = {}).tx0 = Math.max(r.XTOsiz + c * r.XTsiz, r.XOsiz); a.ty0 = Math.max(r.YTOsiz + o * r.YTsiz, r.YOsiz); a.tx1 = Math.min(r.XTOsiz + (c + 1) * r.XTsiz, r.Xsiz); a.ty1 = Math.min(r.YTOsiz + (o + 1) * r.YTsiz, r.Ysiz); a.width = a.tx1 - a.tx0; a.height = a.ty1 - a.ty0; a.components = []; i.push(a) } e.tiles = i; for (var l = 0, h = r.Csiz; l < h; l++)for (var u = t[l], d = 0, f = i.length; d < f; d++) { var g = {}; a = i[d]; g.tcx0 = Math.ceil(a.tx0 / u.XRsiz); g.tcy0 = Math.ceil(a.ty0 / u.YRsiz); g.tcx1 = Math.ceil(a.tx1 / u.XRsiz); g.tcy1 = Math.ceil(a.ty1 / u.YRsiz); g.width = g.tcx1 - g.tcx0; g.height = g.tcy1 - g.tcy0; a.components[l] = g } } function c(e, t, a) { var r = t.codingStyleParameters, i = {}; if (r.entropyCoderWithCustomPrecincts) { i.PPx = r.precinctsSizes[a].PPx; i.PPy = r.precinctsSizes[a].PPy } else { i.PPx = 15; i.PPy = 15 } i.xcb_ = a > 0 ? Math.min(r.xcb, i.PPx - 1) : Math.min(r.xcb, i.PPx); i.ycb_ = a > 0 ? Math.min(r.ycb, i.PPy - 1) : Math.min(r.ycb, i.PPy); return i } function l(e, t, a) { var r = 1 << a.PPx, i = 1 << a.PPy, n = 0 === t.resLevel, s = 1 << a.PPx + (n ? 0 : -1), o = 1 << a.PPy + (n ? 0 : -1), c = t.trx1 > t.trx0 ? Math.ceil(t.trx1 / r) - Math.floor(t.trx0 / r) : 0, l = t.try1 > t.try0 ? Math.ceil(t.try1 / i) - Math.floor(t.try0 / i) : 0, h = c * l; t.precinctParameters = { precinctWidth: r, precinctHeight: i, numprecinctswide: c, numprecinctshigh: l, numprecincts: h, precinctWidthInSubband: s, precinctHeightInSubband: o } } function h(e, t, a) { var r, i, n, s, o = a.xcb_, c = a.ycb_, l = 1 << o, h = 1 << c, u = t.tbx0 >> o, d = t.tby0 >> c, f = t.tbx1 + l - 1 >> o, g = t.tby1 + h - 1 >> c, m = t.resolution.precinctParameters, p = [], b = []; for (i = d; i < g; i++)for (r = u; r < f; r++) { (n = { cbx: r, cby: i, tbx0: l * r, tby0: h * i, tbx1: l * (r + 1), tby1: h * (i + 1) }).tbx0_ = Math.max(t.tbx0, n.tbx0); n.tby0_ = Math.max(t.tby0, n.tby0); n.tbx1_ = Math.min(t.tbx1, n.tbx1); n.tby1_ = Math.min(t.tby1, n.tby1); s = Math.floor((n.tbx0_ - t.tbx0) / m.precinctWidthInSubband) + Math.floor((n.tby0_ - t.tby0) / m.precinctHeightInSubband) * m.numprecinctswide; n.precinctNumber = s; n.subbandType = t.type; n.Lblock = 3; if (!(n.tbx1_ <= n.tbx0_ || n.tby1_ <= n.tby0_)) { p.push(n); var y = b[s]; if (void 0 !== y) { r < y.cbxMin ? y.cbxMin = r : r > y.cbxMax && (y.cbxMax = r); i < y.cbyMin ? y.cbxMin = i : i > y.cbyMax && (y.cbyMax = i) } else b[s] = y = { cbxMin: r, cbyMin: i, cbxMax: r, cbyMax: i }; n.precinct = y } } t.codeblockParameters = { codeblockWidth: o, codeblockHeight: c, numcodeblockwide: f - u + 1, numcodeblockhigh: g - d + 1 }; t.codeblocks = p; t.precincts = b } function u(e, t, a) { for (var r = [], i = e.subbands, n = 0, s = i.length; n < s; n++)for (var o = i[n].codeblocks, c = 0, l = o.length; c < l; c++) { var h = o[c]; h.precinctNumber === t && r.push(h) } return { layerNumber: a, codeblocks: r } } function d(e) { for (var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = r.codingStyleDefaultParameters.layersCount, n = t.Csiz, o = 0, c = 0; c < n; c++)o = Math.max(o, r.components[c].codingStyleParameters.decompositionLevelsCount); var l = 0, h = 0, d = 0, f = 0; this.nextPacket = function () { for (; l < i; l++) { for (; h <= o; h++) { for (; d < n; d++) { var e = r.components[d]; if (!(h > e.codingStyleParameters.decompositionLevelsCount)) { for (var t = e.resolutions[h], a = t.precinctParameters.numprecincts; f < a;) { var c = u(t, f, l); f++; return c } f = 0 } } d = 0 } h = 0 } throw new s("Out of packets") } } function f(e) { for (var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = r.codingStyleDefaultParameters.layersCount, n = t.Csiz, o = 0, c = 0; c < n; c++)o = Math.max(o, r.components[c].codingStyleParameters.decompositionLevelsCount); var l = 0, h = 0, d = 0, f = 0; this.nextPacket = function () { for (; l <= o; l++) { for (; h < i; h++) { for (; d < n; d++) { var e = r.components[d]; if (!(l > e.codingStyleParameters.decompositionLevelsCount)) { for (var t = e.resolutions[l], a = t.precinctParameters.numprecincts; f < a;) { var c = u(t, f, h); f++; return c } f = 0 } } d = 0 } h = 0 } throw new s("Out of packets") } } function g(e) { var t, a, r, i, n = e.SIZ, o = e.currentTile.index, c = e.tiles[o], l = c.codingStyleDefaultParameters.layersCount, h = n.Csiz, d = 0; for (r = 0; r < h; r++) { var f = c.components[r]; d = Math.max(d, f.codingStyleParameters.decompositionLevelsCount) } var g = new Int32Array(d + 1); for (a = 0; a <= d; ++a) { var m = 0; for (r = 0; r < h; ++r) { var p = c.components[r].resolutions; a < p.length && (m = Math.max(m, p[a].precinctParameters.numprecincts)) } g[a] = m } t = 0; a = 0; r = 0; i = 0; this.nextPacket = function () { for (; a <= d; a++) { for (; i < g[a]; i++) { for (; r < h; r++) { var e = c.components[r]; if (!(a > e.codingStyleParameters.decompositionLevelsCount)) { var n = e.resolutions[a], o = n.precinctParameters.numprecincts; if (!(i >= o)) { for (; t < l;) { var f = u(n, i, t); t++; return f } t = 0 } } } r = 0 } i = 0 } throw new s("Out of packets") } } function m(e) { var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = r.codingStyleDefaultParameters.layersCount, n = t.Csiz, o = y(r), c = o, l = 0, h = 0, d = 0, f = 0, g = 0; this.nextPacket = function () { for (; g < c.maxNumHigh; g++) { for (; f < c.maxNumWide; f++) { for (; d < n; d++) { for (var e = r.components[d], t = e.codingStyleParameters.decompositionLevelsCount; h <= t; h++) { var a = e.resolutions[h], m = o.components[d].resolutions[h], p = b(f, g, m, c, a); if (null !== p) { for (; l < i;) { var y = u(a, p, l); l++; return y } l = 0 } } h = 0 } d = 0 } f = 0 } throw new s("Out of packets") } } function p(e) { var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = r.codingStyleDefaultParameters.layersCount, n = t.Csiz, o = y(r), c = 0, l = 0, h = 0, d = 0, f = 0; this.nextPacket = function () { for (; h < n; ++h) { for (var e = r.components[h], t = o.components[h], a = e.codingStyleParameters.decompositionLevelsCount; f < t.maxNumHigh; f++) { for (; d < t.maxNumWide; d++) { for (; l <= a; l++) { var g = e.resolutions[l], m = t.resolutions[l], p = b(d, f, m, t, g); if (null !== p) { for (; c < i;) { var y = u(g, p, c); c++; return y } c = 0 } } l = 0 } d = 0 } f = 0 } throw new s("Out of packets") } } function b(e, t, a, r, i) { var n = e * r.minWidth, s = t * r.minHeight; if (n % a.width != 0 || s % a.height != 0) return null; var o = s / a.width * i.precinctParameters.numprecinctswide; return n / a.height + o } function y(e) { for (var t = e.components.length, a = Number.MAX_VALUE, r = Number.MAX_VALUE, i = 0, n = 0, s = new Array(t), o = 0; o < t; o++) { for (var c = e.components[o], l = c.codingStyleParameters.decompositionLevelsCount, h = new Array(l + 1), u = Number.MAX_VALUE, d = Number.MAX_VALUE, f = 0, g = 0, m = 1, p = l; p >= 0; --p) { var b = c.resolutions[p], y = m * b.precinctParameters.precinctWidth, v = m * b.precinctParameters.precinctHeight; u = Math.min(u, y); d = Math.min(d, v); f = Math.max(f, b.precinctParameters.numprecinctswide); g = Math.max(g, b.precinctParameters.numprecinctshigh); h[p] = { width: y, height: v }; m <<= 1 } a = Math.min(a, u); r = Math.min(r, d); i = Math.max(i, f); n = Math.max(n, g); s[o] = { resolutions: h, minWidth: u, minHeight: d, maxNumWide: f, maxNumHigh: g } } return { components: s, minWidth: a, minHeight: r, maxNumWide: i, maxNumHigh: n } } function v(e) { for (var t = e.SIZ, a = e.currentTile.index, r = e.tiles[a], i = t.Csiz, n = 0; n < i; n++) { for (var o = r.components[n], u = o.codingStyleParameters.decompositionLevelsCount, b = [], y = [], v = 0; v <= u; v++) { var w, k = c(0, o, v), S = {}, C = 1 << u - v; S.trx0 = Math.ceil(o.tcx0 / C); S.try0 = Math.ceil(o.tcy0 / C); S.trx1 = Math.ceil(o.tcx1 / C); S.try1 = Math.ceil(o.tcy1 / C); S.resLevel = v; l(0, S, k); b.push(S); if (0 === v) { (w = {}).type = "LL"; w.tbx0 = Math.ceil(o.tcx0 / C); w.tby0 = Math.ceil(o.tcy0 / C); w.tbx1 = Math.ceil(o.tcx1 / C); w.tby1 = Math.ceil(o.tcy1 / C); w.resolution = S; h(0, w, k); y.push(w); S.subbands = [w] } else { var x = 1 << u - v + 1, A = []; (w = {}).type = "HL"; w.tbx0 = Math.ceil(o.tcx0 / x - .5); w.tby0 = Math.ceil(o.tcy0 / x); w.tbx1 = Math.ceil(o.tcx1 / x - .5); w.tby1 = Math.ceil(o.tcy1 / x); w.resolution = S; h(0, w, k); y.push(w); A.push(w); (w = {}).type = "LH"; w.tbx0 = Math.ceil(o.tcx0 / x); w.tby0 = Math.ceil(o.tcy0 / x - .5); w.tbx1 = Math.ceil(o.tcx1 / x); w.tby1 = Math.ceil(o.tcy1 / x - .5); w.resolution = S; h(0, w, k); y.push(w); A.push(w); (w = {}).type = "HH"; w.tbx0 = Math.ceil(o.tcx0 / x - .5); w.tby0 = Math.ceil(o.tcy0 / x - .5); w.tbx1 = Math.ceil(o.tcx1 / x - .5); w.tby1 = Math.ceil(o.tcy1 / x - .5); w.resolution = S; h(0, w, k); y.push(w); A.push(w); S.subbands = A } } o.resolutions = b; o.subbands = y } var I = r.codingStyleDefaultParameters.progressionOrder; switch (I) { case 0: r.packetsIterator = new d(e); break; case 1: r.packetsIterator = new f(e); break; case 2: r.packetsIterator = new g(e); break; case 3: r.packetsIterator = new m(e); break; case 4: r.packetsIterator = new p(e); break; default: throw new s(`Unsupported progression order ${I}`) } } function w(e, t, a, r) { var n, s = 0, o = 0, c = !1; function l(e) { for (; o < e;) { var r = t[a + s]; s++; if (c) { n = n << 7 | r; o += 7; c = !1 } else { n = n << 8 | r; o += 8 } 255 === r && (c = !0) } return n >>> (o -= e) & (1 << e) - 1 } function h(e) { if (255 === t[a + s - 1] && t[a + s] === e) { u(1); return !0 } if (255 === t[a + s] && t[a + s + 1] === e) { u(2); return !0 } return !1 } function u(e) { s += e } function d() { o = 0; if (c) { s++; c = !1 } } function f() { if (0 === l(1)) return 1; if (0 === l(1)) return 2; var e = l(2); return e < 3 ? e + 3 : (e = l(5)) < 31 ? e + 6 : (e = l(7)) + 37 } for (var g = e.currentTile.index, m = e.tiles[g], p = e.COD.sopMarkerUsed, b = e.COD.ephMarkerUsed, y = m.packetsIterator; s < r;) { d(); p && h(145) && u(4); var v = y.nextPacket(); if (l(1)) { for (var w, k = v.layerNumber, S = [], C = 0, I = v.codeblocks.length; C < I; C++) { var F = (w = v.codeblocks[C]).precinct, T = w.cbx - F.cbxMin, E = w.cby - F.cbyMin, O = !1, P = !1; if (void 0 !== w.included) O = !!l(1); else { var B, D; if (void 0 !== (F = w.precinct).inclusionTree) B = F.inclusionTree; else { var N = F.cbxMax - F.cbxMin + 1, M = F.cbyMax - F.cbyMin + 1; B = new A(N, M, k); D = new x(N, M); F.inclusionTree = B; F.zeroBitPlanesTree = D } if (B.reset(T, E, k)) for (; ;) { if (!l(1)) { B.incrementValue(k); break } if (!B.nextLevel()) { w.included = !0; O = P = !0; break } } } if (O) { if (P) { (D = F.zeroBitPlanesTree).reset(T, E); for (; ;)if (l(1)) { if (!D.nextLevel()) break } else D.incrementValue(); w.zeroBitPlanes = D.value } for (var L = f(); l(1);)w.Lblock++; var R = (0, i.log2)(L), U = l((L < 1 << R ? R - 1 : R) + w.Lblock); S.push({ codeblock: w, codingpasses: L, dataLength: U }) } } d(); b && h(146); for (; S.length > 0;) { var q = S.shift(); void 0 === (w = q.codeblock).data && (w.data = []); w.data.push({ data: t, start: a + s, end: a + s + q.dataLength, codingpasses: q.codingpasses }); s += q.dataLength } } } return s } function k(e, t, a, r, i, s, o, c) { for (var l = r.tbx0, h = r.tby0, u = r.tbx1 - r.tbx0, d = r.codeblocks, f = "H" === r.type.charAt(0) ? 1 : 0, g = "H" === r.type.charAt(1) ? t : 0, m = 0, p = d.length; m < p; ++m) { var b = d[m], y = b.tbx1_ - b.tbx0_, v = b.tby1_ - b.tby0_; if (0 !== y && 0 !== v && void 0 !== b.data) { var w, k; w = new I(y, v, b.subbandType, b.zeroBitPlanes, s); k = 2; var S, C, x, A = b.data, F = 0, T = 0; for (S = 0, C = A.length; S < C; S++) { F += (x = A[S]).end - x.start; T += x.codingpasses } var E = new Uint8Array(F), O = 0; for (S = 0, C = A.length; S < C; S++) { var P = (x = A[S]).data.subarray(x.start, x.end); E.set(P, O); O += P.length } var B = new n.ArithmeticDecoder(E, 0, F); w.setDecoder(B); for (S = 0; S < T; S++) { switch (k) { case 0: w.runSignificancePropagationPass(); break; case 1: w.runMagnitudeRefinementPass(); break; case 2: w.runCleanupPass(); c && w.checkSegmentationSymbol() }k = (k + 1) % 3 } var D, N, M, L = b.tbx0_ - l + (b.tby0_ - h) * u, R = w.coefficentsSign, U = w.coefficentsMagnitude, q = w.bitsDecoded, j = o ? 0 : .5; O = 0; var _ = "LL" !== r.type; for (S = 0; S < v; S++) { var z = 2 * (L / u | 0) * (t - u) + f + g; for (D = 0; D < y; D++) { if (0 !== (N = U[O])) { N = (N + j) * i; 0 !== R[O] && (N = -N); M = q[O]; var H = _ ? z + (L << 1) : L; e[H] = o && M >= s ? N : N * (1 << s - M) } L++; O++ } L += u - y } } } } function S(t, a, r) { for (var i = a.components[r], n = i.codingStyleParameters, s = i.quantizationParameters, o = n.decompositionLevelsCount, c = s.SPqcds, l = s.scalarExpounded, h = s.guardBits, u = n.segmentationSymbolUsed, d = t.components[r].precision, f = n.reversibleTransformation, g = f ? new E : new T, m = [], p = 0, b = 0; b <= o; b++) { for (var y = i.resolutions[b], v = y.trx1 - y.trx0, w = y.try1 - y.try0, S = new Float32Array(v * w), C = 0, x = y.subbands.length; C < x; C++) { var A, I; if (l) { A = c[p].mu; I = c[p].epsilon; p++ } else { A = c[0].mu; I = c[0].epsilon + (b > 0 ? 1 - b : 0) } var F = y.subbands[C], O = e[F.type]; k(S, v, 0, F, f ? 1 : 2 ** (d + O - I) * (1 + A / 2048), h + I - 1, f, u) } m.push({ width: v, height: w, items: S }) } var P = g.calculate(m, i.tcx0, i.tcy0); return { left: i.tcx0, top: i.tcy0, width: P.width, height: P.height, items: P.items } } function C(e, t) { for (var a = e.SIZ.Csiz, r = e.tiles[t], i = 0; i < a; i++) { var n = r.components[i], s = void 0 !== e.currentTile.QCC[i] ? e.currentTile.QCC[i] : e.currentTile.QCD; n.quantizationParameters = s; var o = void 0 !== e.currentTile.COC[i] ? e.currentTile.COC[i] : e.currentTile.COD; n.codingStyleParameters = o } r.codingStyleDefaultParameters = e.currentTile.COD } var x = function () { function e(e, t) { var a = (0, i.log2)(Math.max(e, t)) + 1; this.levels = []; for (var r = 0; r < a; r++) { var n = { width: e, height: t, items: [] }; this.levels.push(n); e = Math.ceil(e / 2); t = Math.ceil(t / 2) } } e.prototype = { reset: function (e, t) { for (var a, r = 0, i = 0; r < this.levels.length;) { var n = e + t * (a = this.levels[r]).width; if (void 0 !== a.items[n]) { i = a.items[n]; break } a.index = n; e >>= 1; t >>= 1; r++ } r--; (a = this.levels[r]).items[a.index] = i; this.currentLevel = r; delete this.value }, incrementValue: function () { var e = this.levels[this.currentLevel]; e.items[e.index]++ }, nextLevel: function () { var e = this.currentLevel, t = this.levels[e], a = t.items[t.index]; if (--e < 0) { this.value = a; return !1 } this.currentLevel = e; (t = this.levels[e]).items[t.index] = a; return !0 } }; return e }(), A = function () { function e(e, t, a) { var r = (0, i.log2)(Math.max(e, t)) + 1; this.levels = []; for (var n = 0; n < r; n++) { for (var s = new Uint8Array(e * t), o = 0, c = s.length; o < c; o++)s[o] = a; var l = { width: e, height: t, items: s }; this.levels.push(l); e = Math.ceil(e / 2); t = Math.ceil(t / 2) } } e.prototype = { reset: function (e, t, a) { for (var r = 0; r < this.levels.length;) { var i = this.levels[r], n = e + t * i.width; i.index = n; var s = i.items[n]; if (255 === s) break; if (s > a) { this.currentLevel = r; this.propagateValues(); return !1 } e >>= 1; t >>= 1; r++ } this.currentLevel = r - 1; return !0 }, incrementValue: function (e) { var t = this.levels[this.currentLevel]; t.items[t.index] = e + 1; this.propagateValues() }, propagateValues: function () { for (var e = this.currentLevel, t = this.levels[e], a = t.items[t.index]; --e >= 0;)(t = this.levels[e]).items[t.index] = a }, nextLevel: function () { var e = this.currentLevel, t = this.levels[e], a = t.items[t.index]; t.items[t.index] = 255; if (--e < 0) return !1; this.currentLevel = e; (t = this.levels[e]).items[t.index] = a; return !0 } }; return e }(), I = function () { var e = new Uint8Array([0, 5, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 1, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8]), t = new Uint8Array([0, 3, 4, 0, 5, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8]), a = new Uint8Array([0, 1, 2, 0, 1, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 3, 4, 5, 0, 4, 5, 5, 0, 5, 5, 5, 0, 0, 0, 0, 0, 6, 7, 7, 0, 7, 7, 7, 0, 7, 7, 7, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8]); function r(r, i, n, s, o) { this.width = r; this.height = i; let c; c = "HH" === n ? a : "HL" === n ? t : e; this.contextLabelTable = c; var l = r * i; this.neighborsSignificance = new Uint8Array(l); this.coefficentsSign = new Uint8Array(l); let h; h = o > 14 ? new Uint32Array(l) : o > 6 ? new Uint16Array(l) : new Uint8Array(l); this.coefficentsMagnitude = h; this.processingFlags = new Uint8Array(l); var u = new Uint8Array(l); if (0 !== s) for (var d = 0; d < l; d++)u[d] = s; this.bitsDecoded = u; this.reset() } r.prototype = { setDecoder: function (e) { this.decoder = e }, reset: function () { this.contexts = new Int8Array(19); this.contexts[0] = 8; this.contexts[17] = 92; this.contexts[18] = 6 }, setNeighborsSignificance: function (e, t, a) { var r, i = this.neighborsSignificance, n = this.width, s = this.height, o = t > 0, c = t + 1 < n; if (e > 0) { r = a - n; o && (i[r - 1] += 16); c && (i[r + 1] += 16); i[r] += 4 } if (e + 1 < s) { r = a + n; o && (i[r - 1] += 16); c && (i[r + 1] += 16); i[r] += 4 } o && (i[a - 1] += 1); c && (i[a + 1] += 1); i[a] |= 128 }, runSignificancePropagationPass: function () { for (var e = this.decoder, t = this.width, a = this.height, r = this.coefficentsMagnitude, i = this.coefficentsSign, n = this.neighborsSignificance, s = this.processingFlags, o = this.contexts, c = this.contextLabelTable, l = this.bitsDecoded, h = 0; h < a; h += 4)for (var u = 0; u < t; u++)for (var d = h * t + u, f = 0; f < 4; f++, d += t) { var g = h + f; if (g >= a) break; s[d] &= -2; if (!r[d] && n[d]) { var m = c[n[d]]; if (e.readBit(o, m)) { var p = this.decodeSignBit(g, u, d); i[d] = p; r[d] = 1; this.setNeighborsSignificance(g, u, d); s[d] |= 2 } l[d]++; s[d] |= 1 } } }, decodeSignBit: function (e, t, a) { var r, i, n, s, o, c, l = this.width, h = this.height, u = this.coefficentsMagnitude, d = this.coefficentsSign; s = t > 0 && 0 !== u[a - 1]; if (t + 1 < l && 0 !== u[a + 1]) { n = d[a + 1]; r = s ? 1 - n - (i = d[a - 1]) : 1 - n - n } else r = s ? 1 - (i = d[a - 1]) - i : 0; var f = 3 * r; s = e > 0 && 0 !== u[a - l]; if (e + 1 < h && 0 !== u[a + l]) { n = d[a + l]; r = s ? 1 - n - (i = d[a - l]) + f : 1 - n - n + f } else r = s ? 1 - (i = d[a - l]) - i + f : f; if (r >= 0) { o = 9 + r; c = this.decoder.readBit(this.contexts, o) } else { o = 9 - r; c = 1 ^ this.decoder.readBit(this.contexts, o) } return c }, runMagnitudeRefinementPass: function () { for (var e, t = this.decoder, a = this.width, r = this.height, i = this.coefficentsMagnitude, n = this.neighborsSignificance, s = this.contexts, o = this.bitsDecoded, c = this.processingFlags, l = a * r, h = 4 * a, u = 0; u < l; u = e) { e = Math.min(l, u + h); for (var d = 0; d < a; d++)for (var f = u + d; f < e; f += a)if (i[f] && 0 == (1 & c[f])) { var g = 16; if (0 != (2 & c[f])) { c[f] ^= 2; g = 0 === (127 & n[f]) ? 15 : 14 } var m = t.readBit(s, g); i[f] = i[f] << 1 | m; o[f]++; c[f] |= 1 } } }, runCleanupPass: function () { for (var e, t = this.decoder, a = this.width, r = this.height, i = this.neighborsSignificance, n = this.coefficentsMagnitude, s = this.coefficentsSign, o = this.contexts, c = this.contextLabelTable, l = this.bitsDecoded, h = this.processingFlags, u = a, d = 2 * a, f = 3 * a, g = 0; g < r; g = e) { e = Math.min(g + 4, r); for (var m = g * a, p = g + 3 < r, b = 0; b < a; b++) { var y, v = m + b, w = 0, k = v, S = g; if (p && 0 === h[v] && 0 === h[v + u] && 0 === h[v + d] && 0 === h[v + f] && 0 === i[v] && 0 === i[v + u] && 0 === i[v + d] && 0 === i[v + f]) { if (!t.readBit(o, 18)) { l[v]++; l[v + u]++; l[v + d]++; l[v + f]++; continue } if (0 !== (w = t.readBit(o, 17) << 1 | t.readBit(o, 17))) { S = g + w; k += w * a } y = this.decodeSignBit(S, b, k); s[k] = y; n[k] = 1; this.setNeighborsSignificance(S, b, k); h[k] |= 2; k = v; for (var C = g; C <= S; C++, k += a)l[k]++; w++ } for (S = g + w; S < e; S++, k += a)if (!n[k] && 0 == (1 & h[k])) { var x = c[i[k]]; if (1 === t.readBit(o, x)) { y = this.decodeSignBit(S, b, k); s[k] = y; n[k] = 1; this.setNeighborsSignificance(S, b, k); h[k] |= 2 } l[k]++ } } } }, checkSegmentationSymbol: function () { var e = this.decoder, t = this.contexts; if (10 !== (e.readBit(t, 17) << 3 | e.readBit(t, 17) << 2 | e.readBit(t, 17) << 1 | e.readBit(t, 17))) throw new s("Invalid segmentation symbol") } }; return r }(), F = function () { function e() { } e.prototype.calculate = function (e, t, a) { for (var r = e[0], i = 1, n = e.length; i < n; i++)r = this.iterate(r, e[i], t, a); return r }; e.prototype.extend = function (e, t, a) { var r = t - 1, i = t + 1, n = t + a - 2, s = t + a; e[r--] = e[i++]; e[s++] = e[n--]; e[r--] = e[i++]; e[s++] = e[n--]; e[r--] = e[i++]; e[s++] = e[n--]; e[r] = e[i]; e[s] = e[n] }; e.prototype.iterate = function (e, t, a, r) { var i, n, s, o, c, l, h = e.width, u = e.height, d = e.items, f = t.width, g = t.height, m = t.items; for (s = 0, i = 0; i < u; i++) { o = 2 * i * f; for (n = 0; n < h; n++, s++, o += 2)m[o] = d[s] } d = e.items = null; var p = new Float32Array(f + 8); if (1 === f) { if (0 != (1 & a)) for (l = 0, s = 0; l < g; l++, s += f)m[s] *= .5 } else for (l = 0, s = 0; l < g; l++, s += f) { p.set(m.subarray(s, s + f), 4); this.extend(p, 4, f); this.filter(p, 4, f); m.set(p.subarray(4, 4 + f), s) } var b = 16, y = []; for (i = 0; i < b; i++)y.push(new Float32Array(g + 8)); var v, w = 0; e = 4 + g; if (1 === g) { if (0 != (1 & r)) for (c = 0; c < f; c++)m[c] *= .5 } else for (c = 0; c < f; c++) { if (0 === w) { b = Math.min(f - c, b); for (s = c, o = 4; o < e; s += f, o++)for (v = 0; v < b; v++)y[v][o] = m[s + v]; w = b } var k = y[--w]; this.extend(k, 4, g); this.filter(k, 4, g); if (0 === w) { s = c - b + 1; for (o = 4; o < e; s += f, o++)for (v = 0; v < b; v++)m[s + v] = y[v][o] } } return { width: f, height: g, items: m } }; return e }(), T = function () { function e() { F.call(this) } e.prototype = Object.create(F.prototype); e.prototype.filter = function (e, t, a) { var r, i, n, s, o = a >> 1, c = -1.586134342059924, l = -.052980118572961, h = .882911075530934, u = .443506852043971, d = 1.230174104914001; r = (t |= 0) - 3; for (i = o + 4; i--; r += 2)e[r] *= .8128930661159609; n = u * e[(r = t - 2) - 1]; for (i = o + 3; i--; r += 2) { s = u * e[r + 1]; e[r] = d * e[r] - n - s; if (!i--) break; n = u * e[(r += 2) + 1]; e[r] = d * e[r] - n - s } n = h * e[(r = t - 1) - 1]; for (i = o + 2; i--; r += 2) { s = h * e[r + 1]; e[r] -= n + s; if (!i--) break; n = h * e[(r += 2) + 1]; e[r] -= n + s } n = l * e[(r = t) - 1]; for (i = o + 1; i--; r += 2) { s = l * e[r + 1]; e[r] -= n + s; if (!i--) break; n = l * e[(r += 2) + 1]; e[r] -= n + s } if (0 !== o) { n = c * e[(r = t + 1) - 1]; for (i = o; i--; r += 2) { s = c * e[r + 1]; e[r] -= n + s; if (!i--) break; n = c * e[(r += 2) + 1]; e[r] -= n + s } } }; return e }(), E = function () { function e() { F.call(this) } e.prototype = Object.create(F.prototype); e.prototype.filter = function (e, t, a) { var r, i, n = a >> 1; for (r = t |= 0, i = n + 1; i--; r += 2)e[r] -= e[r - 1] + e[r + 1] + 2 >> 2; for (r = t + 1, i = n; i--; r += 2)e[r] += e[r - 1] + e[r + 1] >> 1 }; return e }(); return t }(); t.JpxImage = o }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.calculateSHA512 = t.calculateSHA384 = t.calculateSHA256 = t.calculateMD5 = t.PDF20 = t.PDF17 = t.CipherTransformFactory = t.ARCFourCipher = t.AES256Cipher = t.AES128Cipher = void 0; var r = a(2), i = a(4), n = a(11), s = function () { function e(e) { this.a = 0; this.b = 0; var t, a, r = new Uint8Array(256), i = 0, n = e.length; for (t = 0; t < 256; ++t)r[t] = t; for (t = 0; t < 256; ++t) { i = i + (a = r[t]) + e[t % n] & 255; r[t] = r[i]; r[i] = a } this.s = r } e.prototype = { encryptBlock: function (e) { var t, a, r, i = e.length, n = this.a, s = this.b, o = this.s, c = new Uint8Array(i); for (t = 0; t < i; ++t) { r = o[s = s + (a = o[n = n + 1 & 255]) & 255]; o[n] = r; o[s] = a; c[t] = e[t] ^ o[a + r & 255] } this.a = n; this.b = s; return c } }; e.prototype.decryptBlock = e.prototype.encryptBlock; return e }(); t.ARCFourCipher = s; var o, c, l = (o = new Uint8Array([7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]), c = new Int32Array([-680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, -145523070, -1120210379, 718787259, -343485551]), function (e, t, a) { var r, i, n, s = 1732584193, l = -271733879, h = -1732584194, u = 271733878, d = a + 72 & -64, f = new Uint8Array(d); for (r = 0; r < a; ++r)f[r] = e[t++]; f[r++] = 128; n = d - 8; for (; r < n;)f[r++] = 0; f[r++] = a << 3 & 255; f[r++] = a >> 5 & 255; f[r++] = a >> 13 & 255; f[r++] = a >> 21 & 255; f[r++] = a >>> 29 & 255; f[r++] = 0; f[r++] = 0; f[r++] = 0; var g = new Int32Array(16); for (r = 0; r < d;) { for (i = 0; i < 16; ++i, r += 4)g[i] = f[r] | f[r + 1] << 8 | f[r + 2] << 16 | f[r + 3] << 24; var m, p, b = s, y = l, v = h, w = u; for (i = 0; i < 64; ++i) { if (i < 16) { m = y & v | ~y & w; p = i } else if (i < 32) { m = w & y | ~w & v; p = 5 * i + 1 & 15 } else if (i < 48) { m = y ^ v ^ w; p = 3 * i + 5 & 15 } else { m = v ^ (y | ~w); p = 7 * i & 15 } var k = w, S = b + m + c[i] + g[p] | 0, C = o[i]; w = v; v = y; y = y + (S << C | S >>> 32 - C) | 0; b = k } s = s + b | 0; l = l + y | 0; h = h + v | 0; u = u + w | 0 } return new Uint8Array([255 & s, s >> 8 & 255, s >> 16 & 255, s >>> 24 & 255, 255 & l, l >> 8 & 255, l >> 16 & 255, l >>> 24 & 255, 255 & h, h >> 8 & 255, h >> 16 & 255, h >>> 24 & 255, 255 & u, u >> 8 & 255, u >> 16 & 255, u >>> 24 & 255]) }); t.calculateMD5 = l; var h = function () { function e(e, t) { this.high = 0 | e; this.low = 0 | t } e.prototype = { and: function (e) { this.high &= e.high; this.low &= e.low }, xor: function (e) { this.high ^= e.high; this.low ^= e.low }, or: function (e) { this.high |= e.high; this.low |= e.low }, shiftRight: function (e) { if (e >= 32) { this.low = this.high >>> e - 32 | 0; this.high = 0 } else { this.low = this.low >>> e | this.high << 32 - e; this.high = this.high >>> e | 0 } }, shiftLeft: function (e) { if (e >= 32) { this.high = this.low << e - 32; this.low = 0 } else { this.high = this.high << e | this.low >>> 32 - e; this.low = this.low << e } }, rotateRight: function (e) { var t, a; if (32 & e) { a = this.low; t = this.high } else { t = this.low; a = this.high } e &= 31; this.low = t >>> e | a << 32 - e; this.high = a >>> e | t << 32 - e }, not: function () { this.high = ~this.high; this.low = ~this.low }, add: function (e) { var t = (this.low >>> 0) + (e.low >>> 0), a = (this.high >>> 0) + (e.high >>> 0); t > 4294967295 && (a += 1); this.low = 0 | t; this.high = 0 | a }, copyTo: function (e, t) { e[t] = this.high >>> 24 & 255; e[t + 1] = this.high >> 16 & 255; e[t + 2] = this.high >> 8 & 255; e[t + 3] = 255 & this.high; e[t + 4] = this.low >>> 24 & 255; e[t + 5] = this.low >> 16 & 255; e[t + 6] = this.low >> 8 & 255; e[t + 7] = 255 & this.low }, assign: function (e) { this.high = e.high; this.low = e.low } }; return e }(), u = function () { function e(e, t) { return e >>> t | e << 32 - t } function t(e, t, a) { return e & t ^ ~e & a } function a(e, t, a) { return e & t ^ e & a ^ t & a } function r(t) { return e(t, 2) ^ e(t, 13) ^ e(t, 22) } function i(t) { return e(t, 6) ^ e(t, 11) ^ e(t, 25) } function n(t) { return e(t, 7) ^ e(t, 18) ^ t >>> 3 } var s = [1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298]; return function (o, c, l) { var h, u, d, f = 1779033703, g = 3144134277, m = 1013904242, p = 2773480762, b = 1359893119, y = 2600822924, v = 528734635, w = 1541459225, k = 64 * Math.ceil((l + 9) / 64), S = new Uint8Array(k); for (h = 0; h < l; ++h)S[h] = o[c++]; S[h++] = 128; d = k - 8; for (; h < d;)S[h++] = 0; S[h++] = 0; S[h++] = 0; S[h++] = 0; S[h++] = l >>> 29 & 255; S[h++] = l >> 21 & 255; S[h++] = l >> 13 & 255; S[h++] = l >> 5 & 255; S[h++] = l << 3 & 255; var C, x = new Uint32Array(64); for (h = 0; h < k;) { for (u = 0; u < 16; ++u) { x[u] = S[h] << 24 | S[h + 1] << 16 | S[h + 2] << 8 | S[h + 3]; h += 4 } for (u = 16; u < 64; ++u)x[u] = (e(C = x[u - 2], 17) ^ e(C, 19) ^ C >>> 10) + x[u - 7] + n(x[u - 15]) + x[u - 16] | 0; var A, I, F = f, T = g, E = m, O = p, P = b, B = y, D = v, N = w; for (u = 0; u < 64; ++u) { A = N + i(P) + t(P, B, D) + s[u] + x[u]; I = r(F) + a(F, T, E); N = D; D = B; B = P; P = O + A | 0; O = E; E = T; T = F; F = A + I | 0 } f = f + F | 0; g = g + T | 0; m = m + E | 0; p = p + O | 0; b = b + P | 0; y = y + B | 0; v = v + D | 0; w = w + N | 0 } return new Uint8Array([f >> 24 & 255, f >> 16 & 255, f >> 8 & 255, 255 & f, g >> 24 & 255, g >> 16 & 255, g >> 8 & 255, 255 & g, m >> 24 & 255, m >> 16 & 255, m >> 8 & 255, 255 & m, p >> 24 & 255, p >> 16 & 255, p >> 8 & 255, 255 & p, b >> 24 & 255, b >> 16 & 255, b >> 8 & 255, 255 & b, y >> 24 & 255, y >> 16 & 255, y >> 8 & 255, 255 & y, v >> 24 & 255, v >> 16 & 255, v >> 8 & 255, 255 & v, w >> 24 & 255, w >> 16 & 255, w >> 8 & 255, 255 & w]) } }(); t.calculateSHA256 = u; var d = function () { function e(e, t, a, r, i) { e.assign(t); e.and(a); i.assign(t); i.not(); i.and(r); e.xor(i) } function t(e, t, a, r, i) { e.assign(t); e.and(a); i.assign(t); i.and(r); e.xor(i); i.assign(a); i.and(r); e.xor(i) } function a(e, t, a) { e.assign(t); e.rotateRight(28); a.assign(t); a.rotateRight(34); e.xor(a); a.assign(t); a.rotateRight(39); e.xor(a) } function r(e, t, a) { e.assign(t); e.rotateRight(14); a.assign(t); a.rotateRight(18); e.xor(a); a.assign(t); a.rotateRight(41); e.xor(a) } function i(e, t, a) { e.assign(t); e.rotateRight(1); a.assign(t); a.rotateRight(8); e.xor(a); a.assign(t); a.shiftRight(7); e.xor(a) } function n(e, t, a) { e.assign(t); e.rotateRight(19); a.assign(t); a.rotateRight(61); e.xor(a); a.assign(t); a.shiftRight(6); e.xor(a) } var s = [new h(1116352408, 3609767458), new h(1899447441, 602891725), new h(3049323471, 3964484399), new h(3921009573, 2173295548), new h(961987163, 4081628472), new h(1508970993, 3053834265), new h(2453635748, 2937671579), new h(2870763221, 3664609560), new h(3624381080, 2734883394), new h(310598401, 1164996542), new h(607225278, 1323610764), new h(1426881987, 3590304994), new h(1925078388, 4068182383), new h(2162078206, 991336113), new h(2614888103, 633803317), new h(3248222580, 3479774868), new h(3835390401, 2666613458), new h(4022224774, 944711139), new h(264347078, 2341262773), new h(604807628, 2007800933), new h(770255983, 1495990901), new h(1249150122, 1856431235), new h(1555081692, 3175218132), new h(1996064986, 2198950837), new h(2554220882, 3999719339), new h(2821834349, 766784016), new h(2952996808, 2566594879), new h(3210313671, 3203337956), new h(3336571891, 1034457026), new h(3584528711, 2466948901), new h(113926993, 3758326383), new h(338241895, 168717936), new h(666307205, 1188179964), new h(773529912, 1546045734), new h(1294757372, 1522805485), new h(1396182291, 2643833823), new h(1695183700, 2343527390), new h(1986661051, 1014477480), new h(2177026350, 1206759142), new h(2456956037, 344077627), new h(2730485921, 1290863460), new h(2820302411, 3158454273), new h(3259730800, 3505952657), new h(3345764771, 106217008), new h(3516065817, 3606008344), new h(3600352804, 1432725776), new h(4094571909, 1467031594), new h(275423344, 851169720), new h(430227734, 3100823752), new h(506948616, 1363258195), new h(659060556, 3750685593), new h(883997877, 3785050280), new h(958139571, 3318307427), new h(1322822218, 3812723403), new h(1537002063, 2003034995), new h(1747873779, 3602036899), new h(1955562222, 1575990012), new h(2024104815, 1125592928), new h(2227730452, 2716904306), new h(2361852424, 442776044), new h(2428436474, 593698344), new h(2756734187, 3733110249), new h(3204031479, 2999351573), new h(3329325298, 3815920427), new h(3391569614, 3928383900), new h(3515267271, 566280711), new h(3940187606, 3454069534), new h(4118630271, 4000239992), new h(116418474, 1914138554), new h(174292421, 2731055270), new h(289380356, 3203993006), new h(460393269, 320620315), new h(685471733, 587496836), new h(852142971, 1086792851), new h(1017036298, 365543100), new h(1126000580, 2618297676), new h(1288033470, 3409855158), new h(1501505948, 4234509866), new h(1607167915, 987167468), new h(1816402316, 1246189591)]; return function (o, c, l, u) { var d, f, g, m, p, b, y, v; if (u = !!u) { d = new h(3418070365, 3238371032); f = new h(1654270250, 914150663); g = new h(2438529370, 812702999); m = new h(355462360, 4144912697); p = new h(1731405415, 4290775857); b = new h(2394180231, 1750603025); y = new h(3675008525, 1694076839); v = new h(1203062813, 3204075428) } else { d = new h(1779033703, 4089235720); f = new h(3144134277, 2227873595); g = new h(1013904242, 4271175723); m = new h(2773480762, 1595750129); p = new h(1359893119, 2917565137); b = new h(2600822924, 725511199); y = new h(528734635, 4215389547); v = new h(1541459225, 327033209) } var w, k, S, C = 128 * Math.ceil((l + 17) / 128), x = new Uint8Array(C); for (w = 0; w < l; ++w)x[w] = o[c++]; x[w++] = 128; S = C - 16; for (; w < S;)x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = 0; x[w++] = l >>> 29 & 255; x[w++] = l >> 21 & 255; x[w++] = l >> 13 & 255; x[w++] = l >> 5 & 255; x[w++] = l << 3 & 255; var A = new Array(80); for (w = 0; w < 80; w++)A[w] = new h(0, 0); var I, F, T = new h(0, 0), E = new h(0, 0), O = new h(0, 0), P = new h(0, 0), B = new h(0, 0), D = new h(0, 0), N = new h(0, 0), M = new h(0, 0), L = new h(0, 0), R = new h(0, 0), U = new h(0, 0), q = new h(0, 0); for (w = 0; w < C;) { for (k = 0; k < 16; ++k) { A[k].high = x[w] << 24 | x[w + 1] << 16 | x[w + 2] << 8 | x[w + 3]; A[k].low = x[w + 4] << 24 | x[w + 5] << 16 | x[w + 6] << 8 | x[w + 7]; w += 8 } for (k = 16; k < 80; ++k) { n(I = A[k], A[k - 2], q); I.add(A[k - 7]); i(U, A[k - 15], q); I.add(U); I.add(A[k - 16]) } T.assign(d); E.assign(f); O.assign(g); P.assign(m); B.assign(p); D.assign(b); N.assign(y); M.assign(v); for (k = 0; k < 80; ++k) { L.assign(M); r(U, B, q); L.add(U); e(U, B, D, N, q); L.add(U); L.add(s[k]); L.add(A[k]); a(R, T, q); t(U, T, E, O, q); R.add(U); I = M; M = N; N = D; D = B; P.add(L); B = P; P = O; O = E; E = T; I.assign(L); I.add(R); T = I } d.add(T); f.add(E); g.add(O); m.add(P); p.add(B); b.add(D); y.add(N); v.add(M) } if (u) { F = new Uint8Array(48); d.copyTo(F, 0); f.copyTo(F, 8); g.copyTo(F, 16); m.copyTo(F, 24); p.copyTo(F, 32); b.copyTo(F, 40) } else { F = new Uint8Array(64); d.copyTo(F, 0); f.copyTo(F, 8); g.copyTo(F, 16); m.copyTo(F, 24); p.copyTo(F, 32); b.copyTo(F, 40); y.copyTo(F, 48); v.copyTo(F, 56) } return F } }(); t.calculateSHA512 = d; var f = function (e, t, a) { return d(e, t, a, !0) }; t.calculateSHA384 = f; var g = function () { function e() { } e.prototype = { decryptBlock: function (e) { return e } }; return e }(); class m { constructor() { this.constructor === m && (0, r.unreachable)("Cannot initialize AESBaseCipher."); this._s = new Uint8Array([99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22]); this._inv_s = new Uint8Array([82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125]); this._mix = new Uint32Array([0, 235474187, 470948374, 303765277, 941896748, 908933415, 607530554, 708780849, 1883793496, 2118214995, 1817866830, 1649639237, 1215061108, 1181045119, 1417561698, 1517767529, 3767586992, 4003061179, 4236429990, 4069246893, 3635733660, 3602770327, 3299278474, 3400528769, 2430122216, 2664543715, 2362090238, 2193862645, 2835123396, 2801107407, 3035535058, 3135740889, 3678124923, 3576870512, 3341394285, 3374361702, 3810496343, 3977675356, 4279080257, 4043610186, 2876494627, 2776292904, 3076639029, 3110650942, 2472011535, 2640243204, 2403728665, 2169303058, 1001089995, 899835584, 666464733, 699432150, 59727847, 226906860, 530400753, 294930682, 1273168787, 1172967064, 1475418501, 1509430414, 1942435775, 2110667444, 1876241833, 1641816226, 2910219766, 2743034109, 2976151520, 3211623147, 2505202138, 2606453969, 2302690252, 2269728455, 3711829422, 3543599269, 3240894392, 3475313331, 3843699074, 3943906441, 4178062228, 4144047775, 1306967366, 1139781709, 1374988112, 1610459739, 1975683434, 2076935265, 1775276924, 1742315127, 1034867998, 866637845, 566021896, 800440835, 92987698, 193195065, 429456164, 395441711, 1984812685, 2017778566, 1784663195, 1683407248, 1315562145, 1080094634, 1383856311, 1551037884, 101039829, 135050206, 437757123, 337553864, 1042385657, 807962610, 573804783, 742039012, 2531067453, 2564033334, 2328828971, 2227573024, 2935566865, 2700099354, 3001755655, 3168937228, 3868552805, 3902563182, 4203181171, 4102977912, 3736164937, 3501741890, 3265478751, 3433712980, 1106041591, 1340463100, 1576976609, 1408749034, 2043211483, 2009195472, 1708848333, 1809054150, 832877231, 1068351396, 766945465, 599762354, 159417987, 126454664, 361929877, 463180190, 2709260871, 2943682380, 3178106961, 3009879386, 2572697195, 2538681184, 2236228733, 2336434550, 3509871135, 3745345300, 3441850377, 3274667266, 3910161971, 3877198648, 4110568485, 4211818798, 2597806476, 2497604743, 2261089178, 2295101073, 2733856160, 2902087851, 3202437046, 2968011453, 3936291284, 3835036895, 4136440770, 4169408201, 3535486456, 3702665459, 3467192302, 3231722213, 2051518780, 1951317047, 1716890410, 1750902305, 1113818384, 1282050075, 1584504582, 1350078989, 168810852, 67556463, 371049330, 404016761, 841739592, 1008918595, 775550814, 540080725, 3969562369, 3801332234, 4035489047, 4269907996, 3569255213, 3669462566, 3366754619, 3332740144, 2631065433, 2463879762, 2160117071, 2395588676, 2767645557, 2868897406, 3102011747, 3069049960, 202008497, 33778362, 270040487, 504459436, 875451293, 975658646, 675039627, 641025152, 2084704233, 1917518562, 1615861247, 1851332852, 1147550661, 1248802510, 1484005843, 1451044056, 933301370, 967311729, 733156972, 632953703, 260388950, 25965917, 328671808, 496906059, 1206477858, 1239443753, 1543208500, 1441952575, 2144161806, 1908694277, 1675577880, 1842759443, 3610369226, 3644379585, 3408119516, 3307916247, 4011190502, 3776767469, 4077384432, 4245618683, 2809771154, 2842737049, 3144396420, 3043140495, 2673705150, 2438237621, 2203032232, 2370213795]); this._mixCol = new Uint8Array(256); for (let e = 0; e < 256; e++)this._mixCol[e] = e < 128 ? e << 1 : e << 1 ^ 27; this.buffer = new Uint8Array(16); this.bufferPosition = 0 } _expandKey(e) { (0, r.unreachable)("Cannot call `_expandKey` on the base class") } _decrypt(e, t) { let a, r, i; const n = new Uint8Array(16); n.set(e); for (let e = 0, a = this._keySize; e < 16; ++e, ++a)n[e] ^= t[a]; for (let e = this._cyclesOfRepetition - 1; e >= 1; --e) { a = n[13]; n[13] = n[9]; n[9] = n[5]; n[5] = n[1]; n[1] = a; a = n[14]; r = n[10]; n[14] = n[6]; n[10] = n[2]; n[6] = a; n[2] = r; a = n[15]; r = n[11]; i = n[7]; n[15] = n[3]; n[11] = a; n[7] = r; n[3] = i; for (let e = 0; e < 16; ++e)n[e] = this._inv_s[n[e]]; for (let a = 0, r = 16 * e; a < 16; ++a, ++r)n[a] ^= t[r]; for (let e = 0; e < 16; e += 4) { const t = this._mix[n[e]], r = this._mix[n[e + 1]], i = this._mix[n[e + 2]], s = this._mix[n[e + 3]]; a = t ^ r >>> 8 ^ r << 24 ^ i >>> 16 ^ i << 16 ^ s >>> 24 ^ s << 8; n[e] = a >>> 24 & 255; n[e + 1] = a >> 16 & 255; n[e + 2] = a >> 8 & 255; n[e + 3] = 255 & a } } a = n[13]; n[13] = n[9]; n[9] = n[5]; n[5] = n[1]; n[1] = a; a = n[14]; r = n[10]; n[14] = n[6]; n[10] = n[2]; n[6] = a; n[2] = r; a = n[15]; r = n[11]; i = n[7]; n[15] = n[3]; n[11] = a; n[7] = r; n[3] = i; for (let e = 0; e < 16; ++e) { n[e] = this._inv_s[n[e]]; n[e] ^= t[e] } return n } _encrypt(e, t) { const a = this._s; let r, i, n; const s = new Uint8Array(16); s.set(e); for (let e = 0; e < 16; ++e)s[e] ^= t[e]; for (let e = 1; e < this._cyclesOfRepetition; e++) { for (let e = 0; e < 16; ++e)s[e] = a[s[e]]; n = s[1]; s[1] = s[5]; s[5] = s[9]; s[9] = s[13]; s[13] = n; n = s[2]; i = s[6]; s[2] = s[10]; s[6] = s[14]; s[10] = n; s[14] = i; n = s[3]; i = s[7]; r = s[11]; s[3] = s[15]; s[7] = n; s[11] = i; s[15] = r; for (let e = 0; e < 16; e += 4) { const t = s[e + 0], a = s[e + 1], i = s[e + 2], n = s[e + 3]; r = t ^ a ^ i ^ n; s[e + 0] ^= r ^ this._mixCol[t ^ a]; s[e + 1] ^= r ^ this._mixCol[a ^ i]; s[e + 2] ^= r ^ this._mixCol[i ^ n]; s[e + 3] ^= r ^ this._mixCol[n ^ t] } for (let a = 0, r = 16 * e; a < 16; ++a, ++r)s[a] ^= t[r] } for (let e = 0; e < 16; ++e)s[e] = a[s[e]]; n = s[1]; s[1] = s[5]; s[5] = s[9]; s[9] = s[13]; s[13] = n; n = s[2]; i = s[6]; s[2] = s[10]; s[6] = s[14]; s[10] = n; s[14] = i; n = s[3]; i = s[7]; r = s[11]; s[3] = s[15]; s[7] = n; s[11] = i; s[15] = r; for (let e = 0, a = this._keySize; e < 16; ++e, ++a)s[e] ^= t[a]; return s } _decryptBlock2(e, t) { const a = e.length; let r = this.buffer, i = this.bufferPosition; const n = []; let s = this.iv; for (let t = 0; t < a; ++t) { r[i] = e[t]; ++i; if (i < 16) continue; const a = this._decrypt(r, this._key); for (let e = 0; e < 16; ++e)a[e] ^= s[e]; s = r; n.push(a); r = new Uint8Array(16); i = 0 } this.buffer = r; this.bufferLength = i; this.iv = s; if (0 === n.length) return new Uint8Array(0); let o = 16 * n.length; if (t) { const e = n[n.length - 1]; let t = e[15]; if (t <= 16) { for (let a = 15, r = 16 - t; a >= r; --a)if (e[a] !== t) { t = 0; break } o -= t; n[n.length - 1] = e.subarray(0, 16 - t) } } const c = new Uint8Array(o); for (let e = 0, t = 0, a = n.length; e < a; ++e, t += 16)c.set(n[e], t); return c } decryptBlock(e, t, a = null) { const r = e.length, i = this.buffer; let n = this.bufferPosition; if (a) this.iv = a; else { for (let t = 0; n < 16 && t < r; ++t, ++n)i[n] = e[t]; if (n < 16) { this.bufferLength = n; return new Uint8Array(0) } this.iv = i; e = e.subarray(16) } this.buffer = new Uint8Array(16); this.bufferLength = 0; this.decryptBlock = this._decryptBlock2; return this.decryptBlock(e, t) } encrypt(e, t) { const a = e.length; let r = this.buffer, i = this.bufferPosition; const n = []; t || (t = new Uint8Array(16)); for (let s = 0; s < a; ++s) { r[i] = e[s]; ++i; if (i < 16) continue; for (let e = 0; e < 16; ++e)r[e] ^= t[e]; const a = this._encrypt(r, this._key); t = a; n.push(a); r = new Uint8Array(16); i = 0 } this.buffer = r; this.bufferLength = i; this.iv = t; if (0 === n.length) return new Uint8Array(0); const s = 16 * n.length, o = new Uint8Array(s); for (let e = 0, t = 0, a = n.length; e < a; ++e, t += 16)o.set(n[e], t); return o } } class p extends m { constructor(e) { super(); this._cyclesOfRepetition = 10; this._keySize = 160; this._rcon = new Uint8Array([141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141]); this._key = this._expandKey(e) } _expandKey(e) { const t = this._s, a = this._rcon, r = new Uint8Array(176); r.set(e); for (let e = 16, i = 1; e < 176; ++i) { let n = r[e - 3], s = r[e - 2], o = r[e - 1], c = r[e - 4]; n = t[n]; s = t[s]; o = t[o]; c = t[c]; n ^= a[i]; for (let t = 0; t < 4; ++t) { r[e] = n ^= r[e - 16]; e++; r[e] = s ^= r[e - 16]; e++; r[e] = o ^= r[e - 16]; e++; r[e] = c ^= r[e - 16]; e++ } } return r } } t.AES128Cipher = p; class b extends m { constructor(e) { super(); this._cyclesOfRepetition = 14; this._keySize = 224; this._key = this._expandKey(e) } _expandKey(e) { const t = this._s, a = new Uint8Array(240); a.set(e); let r, i, n, s, o = 1; for (let e = 32, c = 1; e < 240; ++c) { if (e % 32 == 16) { r = t[r]; i = t[i]; n = t[n]; s = t[s] } else if (e % 32 == 0) { r = a[e - 3]; i = a[e - 2]; n = a[e - 1]; s = a[e - 4]; r = t[r]; i = t[i]; n = t[n]; s = t[s]; r ^= o; (o <<= 1) >= 256 && (o = 255 & (27 ^ o)) } for (let t = 0; t < 4; ++t) { a[e] = r ^= a[e - 32]; e++; a[e] = i ^= a[e - 32]; e++; a[e] = n ^= a[e - 32]; e++; a[e] = s ^= a[e - 32]; e++ } } return a } } t.AES256Cipher = b; var y = function () { function e(e, t) { if (e.length !== t.length) return !1; for (var a = 0; a < e.length; a++)if (e[a] !== t[a]) return !1; return !0 } function t() { } t.prototype = { checkOwnerPassword: function (t, a, r, i) { var n = new Uint8Array(t.length + 56); n.set(t, 0); n.set(a, t.length); n.set(r, t.length + a.length); return e(u(n, 0, n.length), i) }, checkUserPassword: function (t, a, r) { var i = new Uint8Array(t.length + 8); i.set(t, 0); i.set(a, t.length); return e(u(i, 0, i.length), r) }, getOwnerKey: function (e, t, a, r) { var i = new Uint8Array(e.length + 56); i.set(e, 0); i.set(t, e.length); i.set(a, e.length + t.length); var n = u(i, 0, i.length); return new b(n).decryptBlock(r, !1, new Uint8Array(16)) }, getUserKey: function (e, t, a) { var r = new Uint8Array(e.length + 8); r.set(e, 0); r.set(t, e.length); var i = u(r, 0, r.length); return new b(i).decryptBlock(a, !1, new Uint8Array(16)) } }; return t }(); t.PDF17 = y; var v = function () { function e(e, t) { var a = new Uint8Array(e.length + t.length); a.set(e, 0); a.set(t, e.length); return a } function t(t, a, r) { for (var i = u(a, 0, a.length).subarray(0, 32), n = [0], s = 0; s < 64 || n[n.length - 1] > s - 32;) { var o = t.length + i.length + r.length, c = new Uint8Array(64 * o), l = e(t, i); l = e(l, r); for (var h = 0, g = 0; h < 64; h++, g += o)c.set(l, g); n = new p(i.subarray(0, 16)).encrypt(c, i.subarray(16, 32)); for (var m = 0, b = 0; b < 16; b++) { m *= 1; m %= 3; m += (n[b] >>> 0) % 3; m %= 3 } 0 === m ? i = u(n, 0, n.length) : 1 === m ? i = f(n, 0, n.length) : 2 === m && (i = d(n, 0, n.length)); s++ } return i.subarray(0, 32) } function a() { } function r(e, t) { if (e.length !== t.length) return !1; for (var a = 0; a < e.length; a++)if (e[a] !== t[a]) return !1; return !0 } a.prototype = { hash: function (e, a, r) { return t(e, a, r) }, checkOwnerPassword: function (e, a, i, n) { var s = new Uint8Array(e.length + 56); s.set(e, 0); s.set(a, e.length); s.set(i, e.length + a.length); return r(t(e, s, i), n) }, checkUserPassword: function (e, a, i) { var n = new Uint8Array(e.length + 8); n.set(e, 0); n.set(a, e.length); return r(t(e, n, []), i) }, getOwnerKey: function (e, a, r, i) { var n = new Uint8Array(e.length + 56); n.set(e, 0); n.set(a, e.length); n.set(r, e.length + a.length); var s = t(e, n, r); return new b(s).decryptBlock(i, !1, new Uint8Array(16)) }, getUserKey: function (e, a, r) { var i = new Uint8Array(e.length + 8); i.set(e, 0); i.set(a, e.length); var n = t(e, i, []); return new b(n).decryptBlock(r, !1, new Uint8Array(16)) } }; return a }(); t.PDF20 = v; var w = function () { function e(e, t) { this.StringCipherConstructor = e; this.StreamCipherConstructor = t } e.prototype = { createStream: function (e, t) { var a = new this.StreamCipherConstructor; return new n.DecryptStream(e, t, (function (e, t) { return a.decryptBlock(e, t) })) }, decryptString: function (e) { var t = new this.StringCipherConstructor, a = (0, r.stringToBytes)(e); a = t.decryptBlock(a, !0); return (0, r.bytesToString)(a) } }; return e }(), k = function () { var e = new Uint8Array([40, 191, 78, 94, 78, 117, 138, 65, 100, 0, 78, 86, 255, 250, 1, 8, 46, 46, 0, 182, 208, 104, 62, 128, 47, 12, 169, 254, 100, 83, 105, 122]); function t(t, a, r, i, n, o, c, h) { var u, d, f = 40 + r.length + t.length, g = new Uint8Array(f), m = 0; if (a) { d = Math.min(32, a.length); for (; m < d; ++m)g[m] = a[m] } u = 0; for (; m < 32;)g[m++] = e[u++]; for (u = 0, d = r.length; u < d; ++u)g[m++] = r[u]; g[m++] = 255 & n; g[m++] = n >> 8 & 255; g[m++] = n >> 16 & 255; g[m++] = n >>> 24 & 255; for (u = 0, d = t.length; u < d; ++u)g[m++] = t[u]; if (o >= 4 && !h) { g[m++] = 255; g[m++] = 255; g[m++] = 255; g[m++] = 255 } var p = l(g, 0, m), b = c >> 3; if (o >= 3) for (u = 0; u < 50; ++u)p = l(p, 0, b); var y, v = p.subarray(0, b); if (o >= 3) { for (m = 0; m < 32; ++m)g[m] = e[m]; for (u = 0, d = t.length; u < d; ++u)g[m++] = t[u]; y = new s(v).encryptBlock(l(g, 0, m)); d = v.length; var w, k = new Uint8Array(d); for (u = 1; u <= 19; ++u) { for (w = 0; w < d; ++w)k[w] = v[w] ^ u; y = new s(k).encryptBlock(y) } for (u = 0, d = y.length; u < d; ++u)if (i[u] !== y[u]) return null } else for (u = 0, d = (y = new s(v).encryptBlock(e)).length; u < d; ++u)if (i[u] !== y[u]) return null; return v } var a = i.Name.get("Identity"); function n(n, o, c) { var h = n.get("Filter"); if (!(0, i.isName)(h, "Standard")) throw new r.FormatError("unknown encryption method"); this.dict = n; var u = n.get("V"); if (!Number.isInteger(u) || 1 !== u && 2 !== u && 4 !== u && 5 !== u) throw new r.FormatError("unsupported encryption algorithm"); this.algorithm = u; var d = n.get("Length"); if (!d) if (u <= 3) d = 40; else { var f = n.get("CF"), g = n.get("StmF"); if ((0, i.isDict)(f) && (0, i.isName)(g)) { f.suppressEncryption = !0; var m = f.get(g.name); (d = m && m.get("Length") || 128) < 40 && (d <<= 3) } } if (!Number.isInteger(d) || d < 40 || d % 8 != 0) throw new r.FormatError("invalid key length"); var p = (0, r.stringToBytes)(n.get("O")).subarray(0, 32), b = (0, r.stringToBytes)(n.get("U")).subarray(0, 32), w = n.get("P"), k = n.get("R"), S = (4 === u || 5 === u) && !1 !== n.get("EncryptMetadata"); this.encryptMetadata = S; var C, x, A = (0, r.stringToBytes)(o); if (c) { if (6 === k) try { c = (0, r.utf8StringToString)(c) } catch (e) { (0, r.warn)("CipherTransformFactory: Unable to convert UTF8 encoded password.") } C = (0, r.stringToBytes)(c) } if (5 !== u) x = t(A, C, p, b, w, k, d, S); else { var I = (0, r.stringToBytes)(n.get("O")).subarray(32, 40), F = (0, r.stringToBytes)(n.get("O")).subarray(40, 48), T = (0, r.stringToBytes)(n.get("U")).subarray(0, 48), E = (0, r.stringToBytes)(n.get("U")).subarray(32, 40), O = (0, r.stringToBytes)(n.get("U")).subarray(40, 48), P = (0, r.stringToBytes)(n.get("OE")), B = (0, r.stringToBytes)(n.get("UE")); (0, r.stringToBytes)(n.get("Perms")); x = function (e, t, a, r, i, n, s, o, c, l, h, u) { if (t) { var d = Math.min(127, t.length); t = t.subarray(0, d) } else t = []; var f; return (f = 6 === e ? new v : new y).checkUserPassword(t, o, s) ? f.getUserKey(t, c, h) : t.length && f.checkOwnerPassword(t, r, n, a) ? f.getOwnerKey(t, i, n, l) : null }(k, C, p, I, F, T, b, E, O, P, B) } if (!x && !c) throw new r.PasswordException("No password given", r.PasswordResponses.NEED_PASSWORD); if (!x && c) { x = t(A, function (t, a, r, i) { var n, o, c = new Uint8Array(32), h = 0; o = Math.min(32, t.length); for (; h < o; ++h)c[h] = t[h]; n = 0; for (; h < 32;)c[h++] = e[n++]; var u, d = l(c, 0, h), f = i >> 3; if (r >= 3) for (n = 0; n < 50; ++n)d = l(d, 0, d.length); if (r >= 3) { u = a; var g, m = new Uint8Array(f); for (n = 19; n >= 0; n--) { for (g = 0; g < f; ++g)m[g] = d[g] ^ n; u = new s(m).encryptBlock(u) } } else u = new s(d.subarray(0, f)).encryptBlock(a); return u }(C, p, k, d), p, b, w, k, d, S) } if (!x) throw new r.PasswordException("Incorrect Password", r.PasswordResponses.INCORRECT_PASSWORD); this.encryptionKey = x; if (u >= 4) { var D = n.get("CF"); (0, i.isDict)(D) && (D.suppressEncryption = !0); this.cf = D; this.stmf = n.get("StmF") || a; this.strf = n.get("StrF") || a; this.eff = n.get("EFF") || this.stmf } } function o(e, t, a, r) { var i, n, s = new Uint8Array(a.length + 9); for (i = 0, n = a.length; i < n; ++i)s[i] = a[i]; s[i++] = 255 & e; s[i++] = e >> 8 & 255; s[i++] = e >> 16 & 255; s[i++] = 255 & t; s[i++] = t >> 8 & 255; if (r) { s[i++] = 115; s[i++] = 65; s[i++] = 108; s[i++] = 84 } return l(s, 0, i).subarray(0, Math.min(a.length + 5, 16)) } function c(e, t, a, n, c) { if (!(0, i.isName)(t)) throw new r.FormatError("Invalid crypt filter name."); var l, h = e.get(t.name); null != h && (l = h.get("CFM")); if (!l || "None" === l.name) return function () { return new g }; if ("V2" === l.name) return function () { return new s(o(a, n, c, !1)) }; if ("AESV2" === l.name) return function () { return new p(o(a, n, c, !0)) }; if ("AESV3" === l.name) return function () { return new b(c) }; throw new r.FormatError("Unknown crypto method") } n.prototype = { createCipherTransform: function (e, t) { if (4 === this.algorithm || 5 === this.algorithm) return new w(c(this.cf, this.stmf, e, t, this.encryptionKey), c(this.cf, this.strf, e, t, this.encryptionKey)); var a = o(e, t, this.encryptionKey, !1), r = function () { return new s(a) }; return new w(r, r) } }; return n }(); t.CipherTransformFactory = k }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.ColorSpace = void 0; var r = a(2), i = a(4); class n { constructor(e, t) { this.constructor === n && (0, r.unreachable)("Cannot initialize ColorSpace."); this.name = e; this.numComps = t } getRgb(e, t) { const a = new Uint8ClampedArray(3); this.getRgbItem(e, t, a, 0); return a } getRgbItem(e, t, a, i) { (0, r.unreachable)("Should not call ColorSpace.getRgbItem") } getRgbBuffer(e, t, a, i, n, s, o) { (0, r.unreachable)("Should not call ColorSpace.getRgbBuffer") } getOutputLength(e, t) { (0, r.unreachable)("Should not call ColorSpace.getOutputLength") } isPassthrough(e) { return !1 } isDefaultDecode(e, t) { return n.isDefaultDecode(e, this.numComps) } fillRgb(e, t, a, r, i, n, s, o, c) { const l = t * a; let h = null; const u = 1 << s, d = a !== i || t !== r; if (this.isPassthrough(s)) h = o; else if (1 === this.numComps && l > u && "DeviceGray" !== this.name && "DeviceRGB" !== this.name) { const t = s <= 8 ? new Uint8Array(u) : new Uint16Array(u); for (let e = 0; e < u; e++)t[e] = e; const a = new Uint8ClampedArray(3 * u); this.getRgbBuffer(t, 0, u, a, 0, s, 0); if (d) { h = new Uint8Array(3 * l); let e = 0; for (let t = 0; t < l; ++t) { const r = 3 * o[t]; h[e++] = a[r]; h[e++] = a[r + 1]; h[e++] = a[r + 2] } } else { let t = 0; for (let r = 0; r < l; ++r) { const i = 3 * o[r]; e[t++] = a[i]; e[t++] = a[i + 1]; e[t++] = a[i + 2]; t += c } } } else if (d) { h = new Uint8ClampedArray(3 * l); this.getRgbBuffer(o, 0, l, h, 0, s, 0) } else this.getRgbBuffer(o, 0, r * n, e, 0, s, c); if (h) if (d) !function (e, t, a, r, i, n, s) { s = 1 !== s ? 0 : s; const o = a / i, c = r / n; let l, h = 0; const u = new Uint16Array(i), d = 3 * a; for (let e = 0; e < i; e++)u[e] = 3 * Math.floor(e * o); for (let a = 0; a < n; a++) { const r = Math.floor(a * c) * d; for (let a = 0; a < i; a++) { l = r + u[a]; t[h++] = e[l++]; t[h++] = e[l++]; t[h++] = e[l++]; h += s } } }(h, e, t, a, r, i, c); else { let t = 0, a = 0; for (let i = 0, s = r * n; i < s; i++) { e[t++] = h[a++]; e[t++] = h[a++]; e[t++] = h[a++]; t += c } } } get usesZeroToOneRange() { return (0, r.shadow)(this, "usesZeroToOneRange", !0) } static parse(e, t, a, r) { const i = this.parseToIR(e, t, a, r); return this.fromIR(i) } static fromIR(e) { const t = Array.isArray(e) ? e[0] : e; let a, i, n; switch (t) { case "DeviceGrayCS": return this.singletons.gray; case "DeviceRgbCS": return this.singletons.rgb; case "DeviceCmykCS": return this.singletons.cmyk; case "CalGrayCS": a = e[1]; i = e[2]; n = e[3]; return new d(a, i, n); case "CalRGBCS": a = e[1]; i = e[2]; n = e[3]; const l = e[4]; return new f(a, i, n, l); case "PatternCS": let h = e[1]; h && (h = this.fromIR(h)); return new o(h); case "IndexedCS": const u = e[1], m = e[2], p = e[3]; return new c(this.fromIR(u), m, p); case "AlternateCS": const b = e[1], y = e[2], v = e[3]; return new s(b, this.fromIR(y), v); case "LabCS": a = e[1]; i = e[2]; const w = e[3]; return new g(a, i, w); default: throw new r.FormatError(`Unknown colorspace name: ${t}`) } } static parseToIR(e, t, a = null, n) { e = t.fetchIfRef(e); if ((0, i.isName)(e)) switch (e.name) { case "DeviceGray": case "G": return "DeviceGrayCS"; case "DeviceRGB": case "RGB": return "DeviceRgbCS"; case "DeviceCMYK": case "CMYK": return "DeviceCmykCS"; case "Pattern": return ["PatternCS", null]; default: if ((0, i.isDict)(a)) { const r = a.get("ColorSpace"); if ((0, i.isDict)(r)) { const s = r.get(e.name); if (s) { if ((0, i.isName)(s)) return this.parseToIR(s, t, a, n); e = s; break } } } throw new r.FormatError(`unrecognized colorspace ${e.name}`) }if (Array.isArray(e)) { const s = t.fetchIfRef(e[0]).name; let o, c, l, h, u, d; switch (s) { case "DeviceGray": case "G": return "DeviceGrayCS"; case "DeviceRGB": case "RGB": return "DeviceRgbCS"; case "DeviceCMYK": case "CMYK": return "DeviceCmykCS"; case "CalGray": c = t.fetchIfRef(e[1]); h = c.getArray("WhitePoint"); u = c.getArray("BlackPoint"); d = c.get("Gamma"); return ["CalGrayCS", h, u, d]; case "CalRGB": c = t.fetchIfRef(e[1]); h = c.getArray("WhitePoint"); u = c.getArray("BlackPoint"); d = c.getArray("Gamma"); return ["CalRGBCS", h, u, d, c.getArray("Matrix")]; case "ICCBased": const f = t.fetchIfRef(e[1]).dict; o = f.get("N"); l = f.get("Alternate"); if (l) { const e = this.parseToIR(l, t, a, n); if (this.fromIR(e, n).numComps === o) return e; (0, r.warn)("ICCBased color space: Ignoring incorrect /Alternate entry.") } if (1 === o) return "DeviceGrayCS"; if (3 === o) return "DeviceRgbCS"; if (4 === o) return "DeviceCmykCS"; break; case "Pattern": let g = e[1] || null; g && (g = this.parseToIR(g, t, a, n)); return ["PatternCS", g]; case "Indexed": case "I": const m = this.parseToIR(e[1], t, a, n), p = t.fetchIfRef(e[2]) + 1; let b = t.fetchIfRef(e[3]); (0, i.isStream)(b) && (b = b.getBytes()); return ["IndexedCS", m, p, b]; case "Separation": case "DeviceN": const y = t.fetchIfRef(e[1]); o = Array.isArray(y) ? y.length : 1; l = this.parseToIR(e[2], t, a, n); return ["AlternateCS", o, l, n.create(t.fetchIfRef(e[3]))]; case "Lab": c = t.fetchIfRef(e[1]); h = c.getArray("WhitePoint"); u = c.getArray("BlackPoint"); return ["LabCS", h, u, c.getArray("Range")]; default: throw new r.FormatError(`unimplemented color space object "${s}"`) } } throw new r.FormatError(`unrecognized color space object: "${e}"`) } static isDefaultDecode(e, t) { if (!Array.isArray(e)) return !0; if (2 * t !== e.length) { (0, r.warn)("The decode map is not the correct length"); return !0 } for (let t = 0, a = e.length; t < a; t += 2)if (0 !== e[t] || 1 !== e[t + 1]) return !1; return !0 } static get singletons() { return (0, r.shadow)(this, "singletons", { get gray() { return (0, r.shadow)(this, "gray", new l) }, get rgb() { return (0, r.shadow)(this, "rgb", new h) }, get cmyk() { return (0, r.shadow)(this, "cmyk", new u) } }) } } t.ColorSpace = n; class s extends n { constructor(e, t, a) { super("Alternate", e); this.base = t; this.tintFn = a; this.tmpBuf = new Float32Array(t.numComps) } getRgbItem(e, t, a, r) { const i = this.tmpBuf; this.tintFn(e, t, i, 0); this.base.getRgbItem(i, 0, a, r) } getRgbBuffer(e, t, a, r, i, n, s) { const o = this.tintFn, c = this.base, l = 1 / ((1 << n) - 1), h = c.numComps, u = c.usesZeroToOneRange, d = (c.isPassthrough(8) || !u) && 0 === s; let f = d ? i : 0; const g = d ? r : new Uint8ClampedArray(h * a), m = this.numComps, p = new Float32Array(m), b = new Float32Array(h); let y, v; for (y = 0; y < a; y++) { for (v = 0; v < m; v++)p[v] = e[t++] * l; o(p, 0, b, 0); if (u) for (v = 0; v < h; v++)g[f++] = 255 * b[v]; else { c.getRgbItem(b, 0, g, f); f += h } } d || c.getRgbBuffer(g, 0, a, r, i, 8, s) } getOutputLength(e, t) { return this.base.getOutputLength(e * this.base.numComps / this.numComps, t) } } class o extends n { constructor(e) { super("Pattern", null); this.base = e } isDefaultDecode(e, t) { (0, r.unreachable)("Should not call PatternCS.isDefaultDecode") } } class c extends n { constructor(e, t, a) { super("Indexed", 1); this.base = e; this.highVal = t; const n = e.numComps * t; if ((0, i.isStream)(a)) { this.lookup = new Uint8Array(n); const e = a.getBytes(n); this.lookup.set(e) } else if ((0, r.isString)(a)) { this.lookup = new Uint8Array(n); for (let e = 0; e < n; ++e)this.lookup[e] = a.charCodeAt(e) } else { if (!(a instanceof Uint8Array)) throw new r.FormatError(`Unrecognized lookup table: ${a}`); this.lookup = a } } getRgbItem(e, t, a, r) { const i = this.base.numComps, n = e[t] * i; this.base.getRgbBuffer(this.lookup, n, 1, a, r, 8, 0) } getRgbBuffer(e, t, a, r, i, n, s) { const o = this.base, c = o.numComps, l = o.getOutputLength(c, s), h = this.lookup; for (let n = 0; n < a; ++n) { const a = e[t++] * c; o.getRgbBuffer(h, a, 1, r, i, 8, s); i += l } } getOutputLength(e, t) { return this.base.getOutputLength(e * this.base.numComps, t) } isDefaultDecode(e, t) { if (!Array.isArray(e)) return !0; if (2 !== e.length) { (0, r.warn)("Decode map length is not correct"); return !0 } if (!Number.isInteger(t) || t < 1) { (0, r.warn)("Bits per component is not correct"); return !0 } return 0 === e[0] && e[1] === (1 << t) - 1 } } class l extends n { constructor() { super("DeviceGray", 1) } getRgbItem(e, t, a, r) { const i = 255 * e[t]; a[r] = a[r + 1] = a[r + 2] = i } getRgbBuffer(e, t, a, r, i, n, s) { const o = 255 / ((1 << n) - 1); let c = t, l = i; for (let t = 0; t < a; ++t) { const t = o * e[c++]; r[l++] = t; r[l++] = t; r[l++] = t; l += s } } getOutputLength(e, t) { return e * (3 + t) } } class h extends n { constructor() { super("DeviceRGB", 3) } getRgbItem(e, t, a, r) { a[r] = 255 * e[t]; a[r + 1] = 255 * e[t + 1]; a[r + 2] = 255 * e[t + 2] } getRgbBuffer(e, t, a, r, i, n, s) { if (8 === n && 0 === s) { r.set(e.subarray(t, t + 3 * a), i); return } const o = 255 / ((1 << n) - 1); let c = t, l = i; for (let t = 0; t < a; ++t) { r[l++] = o * e[c++]; r[l++] = o * e[c++]; r[l++] = o * e[c++]; l += s } } getOutputLength(e, t) { return e * (3 + t) / 3 | 0 } isPassthrough(e) { return 8 === e } } const u = function () { function e(e, t, a, r, i) { const n = e[t] * a, s = e[t + 1] * a, o = e[t + 2] * a, c = e[t + 3] * a; r[i] = 255 + n * (-4.387332384609988 * n + 54.48615194189176 * s + 18.82290502165302 * o + 212.25662451639585 * c - 285.2331026137004) + s * (1.7149763477362134 * s - 5.6096736904047315 * o + -17.873870861415444 * c - 5.497006427196366) + o * (-2.5217340131683033 * o - 21.248923337353073 * c + 17.5119270841813) + c * (-21.86122147463605 * c - 189.48180835922747); r[i + 1] = 255 + n * (8.841041422036149 * n + 60.118027045597366 * s + 6.871425592049007 * o + 31.159100130055922 * c - 79.2970844816548) + s * (-15.310361306967817 * s + 17.575251261109482 * o + 131.35250912493976 * c - 190.9453302588951) + o * (4.444339102852739 * o + 9.8632861493405 * c - 24.86741582555878) + c * (-20.737325471181034 * c - 187.80453709719578); r[i + 2] = 255 + n * (.8842522430003296 * n + 8.078677503112928 * s + 30.89978309703729 * o - .23883238689178934 * c - 14.183576799673286) + s * (10.49593273432072 * s + 63.02378494754052 * o + 50.606957656360734 * c - 112.23884253719248) + o * (.03296041114873217 * o + 115.60384449646641 * c - 193.58209356861505) + c * (-22.33816807309886 * c - 180.12613974708367) } return class extends n { constructor() { super("DeviceCMYK", 4) } getRgbItem(t, a, r, i) { e(t, a, 1, r, i) } getRgbBuffer(t, a, r, i, n, s, o) { const c = 1 / ((1 << s) - 1); for (let s = 0; s < r; s++) { e(t, a, c, i, n); a += 4; n += 3 + o } } getOutputLength(e, t) { return e / 4 * (3 + t) | 0 } } }(), d = function () { function e(e, t, a, r, i, n) { const s = (t[a] * n) ** e.G, o = e.YW * s, c = Math.max(295.8 * o ** .3333333333333333 - 40.8, 0); r[i] = c; r[i + 1] = c; r[i + 2] = c } return class extends n { constructor(e, t, a) { super("CalGray", 1); if (!e) throw new r.FormatError("WhitePoint missing - required for color space CalGray"); t = t || [0, 0, 0]; a = a || 1; this.XW = e[0]; this.YW = e[1]; this.ZW = e[2]; this.XB = t[0]; this.YB = t[1]; this.ZB = t[2]; this.G = a; if (this.XW < 0 || this.ZW < 0 || 1 !== this.YW) throw new r.FormatError(`Invalid WhitePoint components for ${this.name}` + ", no fallback available"); if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { (0, r.info)(`Invalid BlackPoint for ${this.name}, falling back to default.`); this.XB = this.YB = this.ZB = 0 } 0 === this.XB && 0 === this.YB && 0 === this.ZB || (0, r.warn)(`${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, ` + `ZB: ${this.ZB}, only default values are supported.`); if (this.G < 1) { (0, r.info)(`Invalid Gamma: ${this.G} for ${this.name}, ` + "falling back to default."); this.G = 1 } } getRgbItem(t, a, r, i) { e(this, t, a, r, i, 1) } getRgbBuffer(t, a, r, i, n, s, o) { const c = 1 / ((1 << s) - 1); for (let s = 0; s < r; ++s) { e(this, t, a, i, n, c); a += 1; n += 3 + o } } getOutputLength(e, t) { return e * (3 + t) } } }(), f = function () { const e = new Float32Array([.8951, .2664, -.1614, -.7502, 1.7135, .0367, .0389, -.0685, 1.0296]), t = new Float32Array([.9869929, -.1470543, .1599627, .4323053, .5183603, .0492912, -.0085287, .0400428, .9684867]), a = new Float32Array([3.2404542, -1.5371385, -.4985314, -.969266, 1.8760108, .041556, .0556434, -.2040259, 1.0572252]), i = new Float32Array([1, 1, 1]), s = new Float32Array(3), o = new Float32Array(3), c = new Float32Array(3); function l(e, t, a) { a[0] = e[0] * t[0] + e[1] * t[1] + e[2] * t[2]; a[1] = e[3] * t[0] + e[4] * t[1] + e[5] * t[2]; a[2] = e[6] * t[0] + e[7] * t[1] + e[8] * t[2] } function h(e) { return u(0, 1, e <= .0031308 ? 12.92 * e : 1.055 * e ** (1 / 2.4) - .055) } function u(e, t, a) { return Math.max(e, Math.min(t, a)) } function d(e) { return e < 0 ? -d(-e) : e > 8 ? ((e + 16) / 116) ** 3 : e * ((24 / 116) ** 3 / 8) } function f(r, n, f, g, m, p) { const b = u(0, 1, n[f] * p), y = u(0, 1, n[f + 1] * p), v = u(0, 1, n[f + 2] * p), w = b ** r.GR, k = y ** r.GG, S = v ** r.GB, C = r.MXA * w + r.MXB * k + r.MXC * S, x = r.MYA * w + r.MYB * k + r.MYC * S, A = r.MZA * w + r.MZB * k + r.MZC * S, I = o; I[0] = C; I[1] = x; I[2] = A; const F = c; !function (a, r, i) { if (1 === a[0] && 1 === a[2]) { i[0] = r[0]; i[1] = r[1]; i[2] = r[2]; return } const n = i; l(e, r, n); const o = s; !function (e, t, a) { a[0] = 1 * t[0] / e[0]; a[1] = 1 * t[1] / e[1]; a[2] = 1 * t[2] / e[2] }(a, n, o); l(t, o, i) }(r.whitePoint, I, F); const T = o; !function (e, t, a) { if (0 === e[0] && 0 === e[1] && 0 === e[2]) { a[0] = t[0]; a[1] = t[1]; a[2] = t[2]; return } const r = d(0), i = (1 - r) / (1 - d(e[0])), n = 1 - i, s = (1 - r) / (1 - d(e[1])), o = 1 - s, c = (1 - r) / (1 - d(e[2])), l = 1 - c; a[0] = t[0] * i + n; a[1] = t[1] * s + o; a[2] = t[2] * c + l }(r.blackPoint, F, T); const E = c; !function (a, r, i) { const n = i; l(e, r, n); const o = s; !function (e, t, a) { a[0] = .95047 * t[0] / e[0]; a[1] = 1 * t[1] / e[1]; a[2] = 1.08883 * t[2] / e[2] }(a, n, o); l(t, o, i) }(i, T, E); const O = o; l(a, E, O); g[m] = 255 * h(O[0]); g[m + 1] = 255 * h(O[1]); g[m + 2] = 255 * h(O[2]) } return class extends n { constructor(e, t, a, i) { super("CalRGB", 3); if (!e) throw new r.FormatError("WhitePoint missing - required for color space CalRGB"); t = t || new Float32Array(3); a = a || new Float32Array([1, 1, 1]); i = i || new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]); const n = e[0], s = e[1], o = e[2]; this.whitePoint = e; const c = t[0], l = t[1], h = t[2]; this.blackPoint = t; this.GR = a[0]; this.GG = a[1]; this.GB = a[2]; this.MXA = i[0]; this.MYA = i[1]; this.MZA = i[2]; this.MXB = i[3]; this.MYB = i[4]; this.MZB = i[5]; this.MXC = i[6]; this.MYC = i[7]; this.MZC = i[8]; if (n < 0 || o < 0 || 1 !== s) throw new r.FormatError(`Invalid WhitePoint components for ${this.name}` + ", no fallback available"); if (c < 0 || l < 0 || h < 0) { (0, r.info)(`Invalid BlackPoint for ${this.name} [${c}, ${l}, ${h}], ` + "falling back to default."); this.blackPoint = new Float32Array(3) } if (this.GR < 0 || this.GG < 0 || this.GB < 0) { (0, r.info)(`Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for ` + `${this.name}, falling back to default.`); this.GR = this.GG = this.GB = 1 } } getRgbItem(e, t, a, r) { f(this, e, t, a, r, 1) } getRgbBuffer(e, t, a, r, i, n, s) { const o = 1 / ((1 << n) - 1); for (let n = 0; n < a; ++n) { f(this, e, t, r, i, o); t += 3; i += 3 + s } } getOutputLength(e, t) { return e * (3 + t) / 3 | 0 } } }(), g = function () { function e(e) { let t; t = e >= 6 / 29 ? e * e * e : 108 / 841 * (e - 4 / 29); return t } function t(e, t, a, r) { return a + e * (r - a) / t } function a(a, r, i, n, s, o) { let c = r[i], l = r[i + 1], h = r[i + 2]; if (!1 !== n) { c = t(c, n, 0, 100); l = t(l, n, a.amin, a.amax); h = t(h, n, a.bmin, a.bmax) } l > a.amax ? l = a.amax : l < a.amin && (l = a.amin); h > a.bmax ? h = a.bmax : h < a.bmin && (h = a.bmin); const u = (c + 16) / 116, d = u + l / 500, f = u - h / 200, g = a.XW * e(d), m = a.YW * e(u), p = a.ZW * e(f); let b, y, v; if (a.ZW < 1) { b = 3.1339 * g + -1.617 * m + -.4906 * p; y = -.9785 * g + 1.916 * m + .0333 * p; v = .072 * g + -.229 * m + 1.4057 * p } else { b = 3.2406 * g + -1.5372 * m + -.4986 * p; y = -.9689 * g + 1.8758 * m + .0415 * p; v = .0557 * g + -.204 * m + 1.057 * p } s[o] = 255 * Math.sqrt(b); s[o + 1] = 255 * Math.sqrt(y); s[o + 2] = 255 * Math.sqrt(v) } return class extends n { constructor(e, t, a) { super("Lab", 3); if (!e) throw new r.FormatError("WhitePoint missing - required for color space Lab"); t = t || [0, 0, 0]; a = a || [-100, 100, -100, 100]; this.XW = e[0]; this.YW = e[1]; this.ZW = e[2]; this.amin = a[0]; this.amax = a[1]; this.bmin = a[2]; this.bmax = a[3]; this.XB = t[0]; this.YB = t[1]; this.ZB = t[2]; if (this.XW < 0 || this.ZW < 0 || 1 !== this.YW) throw new r.FormatError("Invalid WhitePoint components, no fallback available"); if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { (0, r.info)("Invalid BlackPoint, falling back to default"); this.XB = this.YB = this.ZB = 0 } if (this.amin > this.amax || this.bmin > this.bmax) { (0, r.info)("Invalid Range, falling back to defaults"); this.amin = -100; this.amax = 100; this.bmin = -100; this.bmax = 100 } } getRgbItem(e, t, r, i) { a(this, e, t, !1, r, i) } getRgbBuffer(e, t, r, i, n, s, o) { const c = (1 << s) - 1; for (let s = 0; s < r; s++) { a(this, e, t, c, i, n); t += 3; n += 3 + o } } getOutputLength(e, t) { return e * (3 + t) / 3 | 0 } isDefaultDecode(e, t) { return !0 } get usesZeroToOneRange() { return (0, r.shadow)(this, "usesZeroToOneRange", !1) } } }() }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getQuadPoints = h; t.MarkupAnnotation = t.AnnotationFactory = t.AnnotationBorderStyle = t.Annotation = void 0; var r = a(2), i = a(9), n = a(4), s = a(22), o = a(7), c = a(24), l = a(11); t.AnnotationFactory = class { static create(e, t, a, r) { return a.ensure(this, "_create", [e, t, a, r]) } static _create(e, t, a, i) { const s = e.fetchIfRef(t); if (!(0, n.isDict)(s)) return; const c = (0, n.isRef)(t) ? t.toString() : `annot_${i.createObjId()}`; let l = s.get("Subtype"); l = (0, n.isName)(l) ? l.name : null; const h = { xref: e, dict: s, subtype: l, id: c, pdfManager: a }; switch (l) { case "Link": return new v(h); case "Text": return new y(h); case "Widget": let e = (0, o.getInheritableProperty)({ dict: s, key: "FT" }); e = (0, n.isName)(e) ? e.name : null; switch (e) { case "Tx": return new m(h); case "Btn": return new p(h); case "Ch": return new b(h) }(0, r.warn)('Unimplemented widget field type "' + e + '", falling back to base field type.'); return new g(h); case "Popup": return new w(h); case "FreeText": return new k(h); case "Line": return new S(h); case "Square": return new C(h); case "Circle": return new x(h); case "PolyLine": return new A(h); case "Polygon": return new I(h); case "Caret": return new F(h); case "Ink": return new T(h); case "Highlight": return new E(h); case "Underline": return new O(h); case "Squiggly": return new P(h); case "StrikeOut": return new B(h); case "Stamp": return new D(h); case "FileAttachment": return new N(h); default: l ? (0, r.warn)('Unimplemented annotation type "' + l + '", falling back to base annotation.') : (0, r.warn)("Annotation is missing the required /Subtype."); return new u(h) } } }; function h(e, t) { if (!e.has("QuadPoints")) return null; const a = e.getArray("QuadPoints"); if (!Array.isArray(a) || a.length % 8 > 0) return null; const r = []; for (let e = 0, i = a.length / 8; e < i; e++) { r.push([]); for (let i = 8 * e, n = 8 * e + 8; i < n; i += 2) { const n = a[i], s = a[i + 1]; if (n < t[0] || n > t[2] || s < t[1] || s > t[3]) return null; r[e].push({ x: n, y: s }) } } return r } class u { constructor(e) { const t = e.dict; this.setContents(t.get("Contents")); this.setModificationDate(t.get("M")); this.setFlags(t.get("F")); this.setRectangle(t.getArray("Rect")); this.setColor(t.getArray("C")); this.setBorderStyle(t); this.setAppearance(t); this.data = { annotationFlags: this.flags, borderStyle: this.borderStyle, color: this.color, contents: this.contents, hasAppearance: !!this.appearance, id: e.id, modificationDate: this.modificationDate, rect: this.rectangle, subtype: e.subtype } } _hasFlag(e, t) { return !!(e & t) } _isViewable(e) { return !this._hasFlag(e, r.AnnotationFlag.INVISIBLE) && !this._hasFlag(e, r.AnnotationFlag.HIDDEN) && !this._hasFlag(e, r.AnnotationFlag.NOVIEW) } _isPrintable(e) { return this._hasFlag(e, r.AnnotationFlag.PRINT) && !this._hasFlag(e, r.AnnotationFlag.INVISIBLE) && !this._hasFlag(e, r.AnnotationFlag.HIDDEN) } get viewable() { return 0 === this.flags || this._isViewable(this.flags) } get printable() { return 0 !== this.flags && this._isPrintable(this.flags) } setContents(e) { this.contents = (0, r.stringToPDFString)(e || "") } setModificationDate(e) { this.modificationDate = (0, r.isString)(e) ? e : null } setFlags(e) { this.flags = Number.isInteger(e) && e > 0 ? e : 0 } hasFlag(e) { return this._hasFlag(this.flags, e) } setRectangle(e) { Array.isArray(e) && 4 === e.length ? this.rectangle = r.Util.normalizeRect(e) : this.rectangle = [0, 0, 0, 0] } setColor(e) { const t = new Uint8ClampedArray(3); if (Array.isArray(e)) switch (e.length) { case 0: this.color = null; break; case 1: s.ColorSpace.singletons.gray.getRgbItem(e, 0, t, 0); this.color = t; break; case 3: s.ColorSpace.singletons.rgb.getRgbItem(e, 0, t, 0); this.color = t; break; case 4: s.ColorSpace.singletons.cmyk.getRgbItem(e, 0, t, 0); this.color = t; break; default: this.color = t } else this.color = t } setBorderStyle(e) { this.borderStyle = new d; if ((0, n.isDict)(e)) if (e.has("BS")) { const t = e.get("BS"), a = t.get("Type"); if (!a || (0, n.isName)(a, "Border")) { this.borderStyle.setWidth(t.get("W"), this.rectangle); this.borderStyle.setStyle(t.get("S")); this.borderStyle.setDashArray(t.getArray("D")) } } else if (e.has("Border")) { const t = e.getArray("Border"); if (Array.isArray(t) && t.length >= 3) { this.borderStyle.setHorizontalCornerRadius(t[0]); this.borderStyle.setVerticalCornerRadius(t[1]); this.borderStyle.setWidth(t[2], this.rectangle); 4 === t.length && this.borderStyle.setDashArray(t[3]) } } else this.borderStyle.setWidth(0) } setAppearance(e) { this.appearance = null; const t = e.get("AP"); if (!(0, n.isDict)(t)) return; const a = t.get("N"); if ((0, n.isStream)(a)) { this.appearance = a; return } if (!(0, n.isDict)(a)) return; const r = e.get("AS"); (0, n.isName)(r) && a.has(r.name) && (this.appearance = a.get(r.name)) } loadResources(e) { return this.appearance.dict.getAsync("Resources").then(t => { if (!t) return; return new i.ObjectLoader(t, e, t.xref).load().then((function () { return t })) }) } getOperatorList(e, t, a) { if (!this.appearance) return Promise.resolve(new c.OperatorList); const i = this.data, n = this.appearance.dict, s = this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"]), o = n.getArray("BBox") || [0, 0, 1, 1], l = n.getArray("Matrix") || [1, 0, 0, 1, 0, 0], h = function (e, t, a) { const [i, n, s, o] = r.Util.getAxialAlignedBoundingBox(t, a); if (i === s || n === o) return [1, 0, 0, 1, e[0], e[1]]; const c = (e[2] - e[0]) / (s - i), l = (e[3] - e[1]) / (o - n); return [c, 0, 0, l, e[0] - i * c, e[1] - n * l] }(i.rect, o, l); return s.then(a => { const n = new c.OperatorList; n.addOp(r.OPS.beginAnnotation, [i.rect, h, l]); return e.getOperatorList({ stream: this.appearance, task: t, resources: a, operatorList: n }).then(() => { n.addOp(r.OPS.endAnnotation, []); this.appearance.reset(); return n }) }) } } t.Annotation = u; class d { constructor() { this.width = 1; this.style = r.AnnotationBorderStyleType.SOLID; this.dashArray = [3]; this.horizontalCornerRadius = 0; this.verticalCornerRadius = 0 } setWidth(e, t = [0, 0, 0, 0]) { if ((0, n.isName)(e)) this.width = 0; else if (Number.isInteger(e)) { if (e > 0) { const a = (t[2] - t[0]) / 2, i = (t[3] - t[1]) / 2; if (a > 0 && i > 0 && (e > a || e > i)) { (0, r.warn)(`AnnotationBorderStyle.setWidth - ignoring width: ${e}`); e = 1 } } this.width = e } } setStyle(e) { if ((0, n.isName)(e)) switch (e.name) { case "S": this.style = r.AnnotationBorderStyleType.SOLID; break; case "D": this.style = r.AnnotationBorderStyleType.DASHED; break; case "B": this.style = r.AnnotationBorderStyleType.BEVELED; break; case "I": this.style = r.AnnotationBorderStyleType.INSET; break; case "U": this.style = r.AnnotationBorderStyleType.UNDERLINE } } setDashArray(e) { if (Array.isArray(e) && e.length > 0) { let t = !0, a = !0; for (const r of e) { if (!(+r >= 0)) { t = !1; break } r > 0 && (a = !1) } t && !a ? this.dashArray = e : this.width = 0 } else e && (this.width = 0) } setHorizontalCornerRadius(e) { Number.isInteger(e) && (this.horizontalCornerRadius = e) } setVerticalCornerRadius(e) { Number.isInteger(e) && (this.verticalCornerRadius = e) } } t.AnnotationBorderStyle = d; class f extends u { constructor(e) { super(e); const t = e.dict; if (t.has("IRT")) { const e = t.getRaw("IRT"); this.data.inReplyTo = (0, n.isRef)(e) ? e.toString() : null; const a = t.get("RT"); this.data.replyType = (0, n.isName)(a) ? a.name : r.AnnotationReplyType.REPLY } if (this.data.replyType === r.AnnotationReplyType.GROUP) { const e = t.get("IRT"); this.data.title = (0, r.stringToPDFString)(e.get("T") || ""); this.setContents(e.get("Contents")); this.data.contents = this.contents; if (e.has("CreationDate")) { this.setCreationDate(e.get("CreationDate")); this.data.creationDate = this.creationDate } else this.data.creationDate = null; if (e.has("M")) { this.setModificationDate(e.get("M")); this.data.modificationDate = this.modificationDate } else this.data.modificationDate = null; this.data.hasPopup = e.has("Popup"); if (e.has("C")) { this.setColor(e.getArray("C")); this.data.color = this.color } else this.data.color = null } else { this.data.title = (0, r.stringToPDFString)(t.get("T") || ""); this.setCreationDate(t.get("CreationDate")); this.data.creationDate = this.creationDate; this.data.hasPopup = t.has("Popup"); t.has("C") || (this.data.color = null) } } setCreationDate(e) { this.creationDate = (0, r.isString)(e) ? e : null } } t.MarkupAnnotation = f; class g extends u { constructor(e) { super(e); const t = e.dict, a = this.data; a.annotationType = r.AnnotationType.WIDGET; a.fieldName = this._constructFieldName(t); a.fieldValue = (0, o.getInheritableProperty)({ dict: t, key: "V", getArray: !0 }); a.alternativeText = (0, r.stringToPDFString)(t.get("TU") || ""); a.defaultAppearance = (0, o.getInheritableProperty)({ dict: t, key: "DA" }) || ""; const i = (0, o.getInheritableProperty)({ dict: t, key: "FT" }); a.fieldType = (0, n.isName)(i) ? i.name : null; this.fieldResources = (0, o.getInheritableProperty)({ dict: t, key: "DR" }) || n.Dict.empty; a.fieldFlags = (0, o.getInheritableProperty)({ dict: t, key: "Ff" }); (!Number.isInteger(a.fieldFlags) || a.fieldFlags < 0) && (a.fieldFlags = 0); a.readOnly = this.hasFieldFlag(r.AnnotationFieldFlag.READONLY); if ("Sig" === a.fieldType) { a.fieldValue = null; this.setFlags(r.AnnotationFlag.HIDDEN) } } _constructFieldName(e) { if (!e.has("T") && !e.has("Parent")) { (0, r.warn)("Unknown field name, falling back to empty field name."); return "" } if (!e.has("Parent")) return (0, r.stringToPDFString)(e.get("T")); const t = []; e.has("T") && t.unshift((0, r.stringToPDFString)(e.get("T"))); let a = e; for (; a.has("Parent");) { a = a.get("Parent"); if (!(0, n.isDict)(a)) break; a.has("T") && t.unshift((0, r.stringToPDFString)(a.get("T"))) } return t.join(".") } hasFieldFlag(e) { return !!(this.data.fieldFlags & e) } getOperatorList(e, t, a) { return a ? Promise.resolve(new c.OperatorList) : super.getOperatorList(e, t, a) } } class m extends g { constructor(e) { super(e); const t = e.dict; this.data.fieldValue = (0, r.stringToPDFString)(this.data.fieldValue || ""); let a = (0, o.getInheritableProperty)({ dict: t, key: "Q" }); (!Number.isInteger(a) || a < 0 || a > 2) && (a = null); this.data.textAlignment = a; let i = (0, o.getInheritableProperty)({ dict: t, key: "MaxLen" }); (!Number.isInteger(i) || i < 0) && (i = null); this.data.maxLen = i; this.data.multiLine = this.hasFieldFlag(r.AnnotationFieldFlag.MULTILINE); this.data.comb = this.hasFieldFlag(r.AnnotationFieldFlag.COMB) && !this.hasFieldFlag(r.AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(r.AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(r.AnnotationFieldFlag.FILESELECT) && null !== this.data.maxLen } getOperatorList(e, t, a) { if (a || this.appearance) return super.getOperatorList(e, t, a); const i = new c.OperatorList; if (!this.data.defaultAppearance) return Promise.resolve(i); const n = new l.Stream((0, r.stringToBytes)(this.data.defaultAppearance)); return e.getOperatorList({ stream: n, task: t, resources: this.fieldResources, operatorList: i }).then((function () { return i })) } } class p extends g { constructor(e) { super(e); this.data.checkBox = !this.hasFieldFlag(r.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON); this.data.radioButton = this.hasFieldFlag(r.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON); this.data.pushButton = this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON); this.data.checkBox ? this._processCheckBox(e) : this.data.radioButton ? this._processRadioButton(e) : this.data.pushButton ? this._processPushButton(e) : (0, r.warn)("Invalid field flags for button widget annotation") } _processCheckBox(e) { (0, n.isName)(this.data.fieldValue) && (this.data.fieldValue = this.data.fieldValue.name); const t = e.dict.get("AP"); if (!(0, n.isDict)(t)) return; const a = t.get("D"); if (!(0, n.isDict)(a)) return; const r = a.getKeys(); 2 === r.length && (this.data.exportValue = "Off" === r[0] ? r[1] : r[0]) } _processRadioButton(e) { this.data.fieldValue = this.data.buttonValue = null; const t = e.dict.get("Parent"); if ((0, n.isDict)(t) && t.has("V")) { const e = t.get("V"); (0, n.isName)(e) && (this.data.fieldValue = e.name) } const a = e.dict.get("AP"); if (!(0, n.isDict)(a)) return; const r = a.get("N"); if ((0, n.isDict)(r)) for (const e of r.getKeys()) if ("Off" !== e) { this.data.buttonValue = e; break } } _processPushButton(e) { e.dict.has("A") ? i.Catalog.parseDestDictionary({ destDict: e.dict, resultObj: this.data, docBaseUrl: e.pdfManager.docBaseUrl }) : (0, r.warn)("Push buttons without action dictionaries are not supported") } } class b extends g { constructor(e) { super(e); this.data.options = []; const t = (0, o.getInheritableProperty)({ dict: e.dict, key: "Opt" }); if (Array.isArray(t)) { const a = e.xref; for (let e = 0, i = t.length; e < i; e++) { const i = a.fetchIfRef(t[e]), n = Array.isArray(i); this.data.options[e] = { exportValue: n ? a.fetchIfRef(i[0]) : i, displayValue: (0, r.stringToPDFString)(n ? a.fetchIfRef(i[1]) : i) } } } Array.isArray(this.data.fieldValue) || (this.data.fieldValue = [this.data.fieldValue]); this.data.combo = this.hasFieldFlag(r.AnnotationFieldFlag.COMBO); this.data.multiSelect = this.hasFieldFlag(r.AnnotationFieldFlag.MULTISELECT) } } class y extends f { constructor(e) { super(e); const t = e.dict; this.data.annotationType = r.AnnotationType.TEXT; if (this.data.hasAppearance) this.data.name = "NoIcon"; else { this.data.rect[1] = this.data.rect[3] - 22; this.data.rect[2] = this.data.rect[0] + 22; this.data.name = t.has("Name") ? t.get("Name").name : "Note" } if (t.has("State")) { this.data.state = t.get("State") || null; this.data.stateModel = t.get("StateModel") || null } else { this.data.state = null; this.data.stateModel = null } } } class v extends u { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.LINK; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t); i.Catalog.parseDestDictionary({ destDict: e.dict, resultObj: this.data, docBaseUrl: e.pdfManager.docBaseUrl }) } } class w extends u { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.POPUP; let t = e.dict.get("Parent"); if (!t) { (0, r.warn)("Popup annotation has a missing or invalid parent annotation."); return } const a = t.get("Subtype"); this.data.parentType = (0, n.isName)(a) ? a.name : null; const i = e.dict.getRaw("Parent"); this.data.parentId = (0, n.isRef)(i) ? i.toString() : null; const s = t.get("RT"); (0, n.isName)(s, r.AnnotationReplyType.GROUP) && (t = t.get("IRT")); if (t.has("M")) { this.setModificationDate(t.get("M")); this.data.modificationDate = this.modificationDate } else this.data.modificationDate = null; if (t.has("C")) { this.setColor(t.getArray("C")); this.data.color = this.color } else this.data.color = null; if (!this.viewable) { const e = t.get("F"); this._isViewable(e) && this.setFlags(e) } this.data.title = (0, r.stringToPDFString)(t.get("T") || ""); this.data.contents = (0, r.stringToPDFString)(t.get("Contents") || "") } } class k extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.FREETEXT } } class S extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.LINE; this.data.lineCoordinates = r.Util.normalizeRect(e.dict.getArray("L")) } } class C extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.SQUARE } } class x extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.CIRCLE } } class A extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.POLYLINE; const t = e.dict.getArray("Vertices"); this.data.vertices = []; for (let e = 0, a = t.length; e < a; e += 2)this.data.vertices.push({ x: t[e], y: t[e + 1] }) } } class I extends A { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.POLYGON } } class F extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.CARET } } class T extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.INK; const t = e.xref, a = e.dict.getArray("InkList"); this.data.inkLists = []; for (let e = 0, r = a.length; e < r; ++e) { this.data.inkLists.push([]); for (let r = 0, i = a[e].length; r < i; r += 2)this.data.inkLists[e].push({ x: t.fetchIfRef(a[e][r]), y: t.fetchIfRef(a[e][r + 1]) }) } } } class E extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.HIGHLIGHT; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t) } } class O extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.UNDERLINE; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t) } } class P extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.SQUIGGLY; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t) } } class B extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.STRIKEOUT; const t = h(e.dict, this.rectangle); t && (this.data.quadPoints = t) } } class D extends f { constructor(e) { super(e); this.data.annotationType = r.AnnotationType.STAMP } } class N extends f { constructor(e) { super(e); const t = new i.FileSpec(e.dict.get("FS"), e.xref); this.data.annotationType = r.AnnotationType.FILEATTACHMENT; this.data.file = t.serializable } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.OperatorList = void 0; var r = a(2), i = function () { function e(e, t, a, r, i) { for (var n = e, s = 0, o = t.length - 1; s < o; s++) { var c = t[s]; n = n[c] || (n[c] = []) } n[t[t.length - 1]] = { checkFn: a, iterateFn: r, processFn: i } } var t = []; e(t, [r.OPS.save, r.OPS.transform, r.OPS.paintInlineImageXObject, r.OPS.restore], null, (function (e, t) { var a = e.fnArray, i = (t - (e.iCurr - 3)) % 4; switch (i) { case 0: return a[t] === r.OPS.save; case 1: return a[t] === r.OPS.transform; case 2: return a[t] === r.OPS.paintInlineImageXObject; case 3: return a[t] === r.OPS.restore }throw new Error(`iterateInlineImageGroup - invalid pos: ${i}`) }), (function (e, t) { var a = e.fnArray, i = e.argsArray, n = e.iCurr, s = n - 3, o = n - 2, c = n - 1, l = Math.min(Math.floor((t - s) / 4), 200); if (l < 10) return t - (t - s) % 4; var h, u = 0, d = [], f = 0, g = 1, m = 1; for (h = 0; h < l; h++) { var p = i[o + (h << 2)], b = i[c + (h << 2)][0]; if (g + b.width > 1e3) { u = Math.max(u, g); m += f + 2; g = 0; f = 0 } d.push({ transform: p, x: g, y: m, w: b.width, h: b.height }); g += b.width + 2; f = Math.max(f, b.height) } var y = Math.max(u, g) + 1, v = m + f + 1, w = new Uint8ClampedArray(y * v * 4), k = y << 2; for (h = 0; h < l; h++) { var S = i[c + (h << 2)][0].data, C = d[h].w << 2, x = 0, A = d[h].x + d[h].y * y << 2; w.set(S.subarray(0, C), A - k); for (var I = 0, F = d[h].h; I < F; I++) { w.set(S.subarray(x, x + C), A); x += C; A += k } w.set(S.subarray(x - C, x), A); for (; A >= 0;) { S[A - 4] = S[A]; S[A - 3] = S[A + 1]; S[A - 2] = S[A + 2]; S[A - 1] = S[A + 3]; S[A + C] = S[A + C - 4]; S[A + C + 1] = S[A + C - 3]; S[A + C + 2] = S[A + C - 2]; S[A + C + 3] = S[A + C - 1]; A -= k } } a.splice(s, 4 * l, r.OPS.paintInlineImageXObjectGroup); i.splice(s, 4 * l, [{ width: y, height: v, kind: r.ImageKind.RGBA_32BPP, data: w }, d]); return s + 1 })); e(t, [r.OPS.save, r.OPS.transform, r.OPS.paintImageMaskXObject, r.OPS.restore], null, (function (e, t) { var a = e.fnArray, i = (t - (e.iCurr - 3)) % 4; switch (i) { case 0: return a[t] === r.OPS.save; case 1: return a[t] === r.OPS.transform; case 2: return a[t] === r.OPS.paintImageMaskXObject; case 3: return a[t] === r.OPS.restore }throw new Error(`iterateImageMaskGroup - invalid pos: ${i}`) }), (function (e, t) { var a, i = e.fnArray, n = e.argsArray, s = e.iCurr, o = s - 3, c = s - 2, l = s - 1, h = Math.floor((t - o) / 4); if ((h = function (e, t, a, i) { for (var n = e + 2, s = 0; s < t; s++) { var o = i[n + 4 * s], c = 1 === o.length && o[0]; if (!c || 1 !== c.width || 1 !== c.height || c.data.length && (1 !== c.data.length || 0 !== c.data[0])) break; a[n + 4 * s] = r.OPS.paintSolidColorImageMask } return t - s }(o, h, i, n)) < 10) return t - (t - o) % 4; var u, d, f = !1, g = n[l][0]; if (0 === n[c][1] && 0 === n[c][2]) { f = !0; var m = n[c][0], p = n[c][3]; u = c + 4; var b = l + 4; for (a = 1; a < h; a++, u += 4, b += 4) { d = n[u]; if (n[b][0] !== g || d[0] !== m || 0 !== d[1] || 0 !== d[2] || d[3] !== p) { a < 10 ? f = !1 : h = a; break } } } if (f) { h = Math.min(h, 1e3); var y = new Float32Array(2 * h); u = c; for (a = 0; a < h; a++, u += 4) { d = n[u]; y[a << 1] = d[4]; y[1 + (a << 1)] = d[5] } i.splice(o, 4 * h, r.OPS.paintImageMaskXObjectRepeat); n.splice(o, 4 * h, [g, m, p, y]) } else { h = Math.min(h, 100); var v = []; for (a = 0; a < h; a++) { d = n[c + (a << 2)]; var w = n[l + (a << 2)][0]; v.push({ data: w.data, width: w.width, height: w.height, transform: d }) } i.splice(o, 4 * h, r.OPS.paintImageMaskXObjectGroup); n.splice(o, 4 * h, [v]) } return o + 1 })); e(t, [r.OPS.save, r.OPS.transform, r.OPS.paintImageXObject, r.OPS.restore], (function (e) { var t = e.argsArray, a = e.iCurr - 2; return 0 === t[a][1] && 0 === t[a][2] }), (function (e, t) { var a = e.fnArray, i = e.argsArray, n = (t - (e.iCurr - 3)) % 4; switch (n) { case 0: return a[t] === r.OPS.save; case 1: if (a[t] !== r.OPS.transform) return !1; var s = e.iCurr - 2, o = i[s][0], c = i[s][3]; return i[t][0] === o && 0 === i[t][1] && 0 === i[t][2] && i[t][3] === c; case 2: if (a[t] !== r.OPS.paintImageXObject) return !1; var l = i[e.iCurr - 1][0]; return i[t][0] === l; case 3: return a[t] === r.OPS.restore }throw new Error(`iterateImageGroup - invalid pos: ${n}`) }), (function (e, t) { var a = e.fnArray, i = e.argsArray, n = e.iCurr, s = n - 3, o = n - 2, c = i[n - 1][0], l = i[o][0], h = i[o][3], u = Math.min(Math.floor((t - s) / 4), 1e3); if (u < 3) return t - (t - s) % 4; for (var d = new Float32Array(2 * u), f = o, g = 0; g < u; g++, f += 4) { var m = i[f]; d[g << 1] = m[4]; d[1 + (g << 1)] = m[5] } var p = [c, l, h, d]; a.splice(s, 4 * u, r.OPS.paintImageXObjectRepeat); i.splice(s, 4 * u, p); return s + 1 })); e(t, [r.OPS.beginText, r.OPS.setFont, r.OPS.setTextMatrix, r.OPS.showText, r.OPS.endText], null, (function (e, t) { var a = e.fnArray, i = e.argsArray, n = (t - (e.iCurr - 4)) % 5; switch (n) { case 0: return a[t] === r.OPS.beginText; case 1: return a[t] === r.OPS.setFont; case 2: return a[t] === r.OPS.setTextMatrix; case 3: if (a[t] !== r.OPS.showText) return !1; var s = e.iCurr - 3, o = i[s][0], c = i[s][1]; return i[t][0] === o && i[t][1] === c; case 4: return a[t] === r.OPS.endText }throw new Error(`iterateShowTextGroup - invalid pos: ${n}`) }), (function (e, t) { var a = e.fnArray, r = e.argsArray, i = e.iCurr, n = i - 4, s = i - 3, o = i - 2, c = i - 1, l = i, h = r[s][0], u = r[s][1], d = Math.min(Math.floor((t - n) / 5), 1e3); if (d < 3) return t - (t - n) % 5; var f = n; if (n >= 4 && a[n - 4] === a[s] && a[n - 3] === a[o] && a[n - 2] === a[c] && a[n - 1] === a[l] && r[n - 4][0] === h && r[n - 4][1] === u) { d++; f -= 5 } for (var g = f + 4, m = 1; m < d; m++) { a.splice(g, 3); r.splice(g, 3); g += 2 } return g + 1 })); function a(e) { this.queue = e; this.state = null; this.context = { iCurr: 0, fnArray: e.fnArray, argsArray: e.argsArray }; this.match = null; this.lastProcessed = 0 } a.prototype = { _optimize() { const e = this.queue.fnArray; let a = this.lastProcessed, r = e.length, i = this.state, n = this.match; if (!i && !n && a + 1 === r && !t[e[a]]) { this.lastProcessed = r; return } const s = this.context; for (; a < r;) { if (n) { if ((0, n.iterateFn)(s, a)) { a++; continue } a = (0, n.processFn)(s, a + 1); r = e.length; n = null; i = null; if (a >= r) break } i = (i || t)[e[a]]; if (i && !Array.isArray(i)) { s.iCurr = a; a++; if (!i.checkFn || (0, i.checkFn)(s)) { n = i; i = null } else i = null } else a++ } this.state = i; this.match = n; this.lastProcessed = a }, push(e, t) { this.queue.fnArray.push(e); this.queue.argsArray.push(t); this._optimize() }, flush() { for (; this.match;) { const e = this.queue.fnArray.length; this.lastProcessed = (0, this.match.processFn)(this.context, e); this.match = null; this.state = null; this._optimize() } }, reset() { this.state = null; this.match = null; this.lastProcessed = 0 } }; return a }(), n = function () { function e(e) { this.queue = e } e.prototype = { push(e, t) { this.queue.fnArray.push(e); this.queue.argsArray.push(t) }, flush() { }, reset() { } }; return e }(), s = function () { function e(e, t, a) { this._streamSink = t; this.fnArray = []; this.argsArray = []; this.optimizer = t && "oplist" !== e ? new i(this) : new n(this); this.dependencies = Object.create(null); this._totalLength = 0; this.pageIndex = a; this.intent = e; this.weight = 0; this._resolved = t ? null : Promise.resolve() } e.prototype = { get length() { return this.argsArray.length }, get ready() { return this._resolved || this._streamSink.ready }, get totalLength() { return this._totalLength + this.length }, addOp(e, t) { this.optimizer.push(e, t); this.weight++; this._streamSink && (this.weight >= 1e3 || this.weight >= 995 && (e === r.OPS.restore || e === r.OPS.endText)) && this.flush() }, addDependency(e) { if (!(e in this.dependencies)) { this.dependencies[e] = !0; this.addOp(r.OPS.dependency, [e]) } }, addDependencies(e) { for (var t in e) this.addDependency(t) }, addOpList(e) { Object.assign(this.dependencies, e.dependencies); for (var t = 0, a = e.length; t < a; t++)this.addOp(e.fnArray[t], e.argsArray[t]) }, getIR() { return { fnArray: this.fnArray, argsArray: this.argsArray, length: this.length } }, get _transfers() { const e = [], { fnArray: t, argsArray: a, length: i } = this; for (let n = 0; n < i; n++)switch (t[n]) { case r.OPS.paintInlineImageXObject: case r.OPS.paintInlineImageXObjectGroup: case r.OPS.paintImageMaskXObject: const t = a[n][0]; t.cached || e.push(t.data.buffer) }return e }, flush(e = !1) { this.optimizer.flush(); const t = this.length; this._totalLength += t; this._streamSink.enqueue({ fnArray: this.fnArray, argsArray: this.argsArray, lastChunk: e, length: t }, 1, this._transfers); this.dependencies = Object.create(null); this.fnArray.length = 0; this.argsArray.length = 0; this.weight = 0; this.optimizer.reset() } }; return e }(); t.OperatorList = s }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PartialEvaluator = void 0; var r = a(2), i = a(26), n = a(4), s = a(27), o = a(30), c = a(7), l = a(33), h = a(32), u = a(36), d = a(10), f = a(37), g = a(22), m = a(11), p = a(31), b = a(38), y = a(39), v = a(17), w = a(41), k = a(42), S = a(24), C = a(43), x = function () { const e = { forceDataSchema: !1, maxImageSize: -1, disableFontFace: !1, nativeImageDecoderSupport: r.NativeImageDecoding.DECODE, ignoreErrors: !1, isEvalSupported: !0 }; function t({ xref: t, handler: a, pageIndex: i, idFactory: n, fontCache: s, builtInCMapCache: o, options: c = null, pdfFunctionFactory: l }) { this.xref = t; this.handler = a; this.pageIndex = i; this.idFactory = n; this.fontCache = s; this.builtInCMapCache = o; this.options = c || e; this.pdfFunctionFactory = l; this.parsingType3Font = !1; this.fetchBuiltInCMap = async e => { if (this.builtInCMapCache.has(e)) return this.builtInCMapCache.get(e); const t = this.handler.sendWithStream("FetchBuiltInCMap", { name: e }).getReader(), a = await new Promise((function (e, a) { !function r() { t.read().then((function ({ value: t, done: a }) { if (!a) { e(t); r() } }), a) }() })); a.compressionType !== r.CMapCompressionType.NONE && this.builtInCMapCache.set(e, a); return a } } function a() { this.reset() } a.prototype = { check: function () { if (++this.checked < 100) return !1; this.checked = 0; return this.endTime <= Date.now() }, reset: function () { this.endTime = Date.now() + 20; this.checked = 0 } }; function d(e, t = !1) { if (Array.isArray(e)) { for (let t = 0, a = e.length; t < a; t++) { const a = d(e[t], !0); if (a) return a } (0, r.warn)(`Unsupported blend mode Array: ${e}`); return "source-over" } if (!(0, n.isName)(e)) return t ? null : "source-over"; switch (e.name) { case "Normal": case "Compatible": return "source-over"; case "Multiply": return "multiply"; case "Screen": return "screen"; case "Overlay": return "overlay"; case "Darken": return "darken"; case "Lighten": return "lighten"; case "ColorDodge": return "color-dodge"; case "ColorBurn": return "color-burn"; case "HardLight": return "hard-light"; case "SoftLight": return "soft-light"; case "Difference": return "difference"; case "Exclusion": return "exclusion"; case "Hue": return "hue"; case "Saturation": return "saturation"; case "Color": return "color"; case "Luminosity": return "luminosity" }if (t) return null; (0, r.warn)(`Unsupported blend mode: ${e.name}`); return "source-over" } var x = Promise.resolve(); t.prototype = { clone(t = e) { var a = Object.create(this); a.options = t; return a }, hasBlendModes: function (e) { if (!(e instanceof n.Dict)) return !1; var t = Object.create(null); e.objId && (t[e.objId] = !0); for (var a = [e], i = this.xref; a.length;) { var s = a.shift(), o = s.get("ExtGState"); if (o instanceof n.Dict) { var l = o.getKeys(); for (let e = 0, a = l.length; e < a; e++) { const a = l[e]; let s = o.getRaw(a); if (s instanceof n.Ref) { if (t[s.toString()]) continue; try { s = i.fetch(s) } catch (e) { if (e instanceof c.MissingDataException) throw e; if (this.options.ignoreErrors) { s instanceof n.Ref && (t[s.toString()] = !0); this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`hasBlendModes - ignoring ExtGState: "${e}".`); continue } throw e } } if (!(s instanceof n.Dict)) continue; s.objId && (t[s.objId] = !0); const h = s.get("BM"); if (h instanceof n.Name) { if ("Normal" !== h.name) return !0 } else if (void 0 !== h && Array.isArray(h)) for (let e = 0, t = h.length; e < t; e++)if (h[e] instanceof n.Name && "Normal" !== h[e].name) return !0 } } var h = s.get("XObject"); if (h instanceof n.Dict) { var u = h.getKeys(); for (let e = 0, s = u.length; e < s; e++) { const s = u[e]; var d = h.getRaw(s); if (d instanceof n.Ref) { if (t[d.toString()]) continue; try { d = i.fetch(d) } catch (e) { if (e instanceof c.MissingDataException) throw e; if (this.options.ignoreErrors) { d instanceof n.Ref && (t[d.toString()] = !0); this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`hasBlendModes - ignoring XObject: "${e}".`); continue } throw e } } if ((0, n.isStream)(d)) { if (d.dict.objId) { if (t[d.dict.objId]) continue; t[d.dict.objId] = !0 } var f = d.dict.get("Resources"); if (f instanceof n.Dict && (!f.objId || !t[f.objId])) { a.push(f); f.objId && (t[f.objId] = !0) } } } } } return !1 }, async buildFormXObject(e, t, a, i, s, o) { var c = t.dict, l = c.getArray("Matrix"), h = c.getArray("BBox"); h = Array.isArray(h) && 4 === h.length ? r.Util.normalizeRect(h) : null; var u = c.get("Group"); if (u) { var d = { matrix: l, bbox: h, smask: a, isolated: !1, knockout: !1 }, f = u.get("S"), m = null; if ((0, n.isName)(f, "Transparency")) { d.isolated = u.get("I") || !1; d.knockout = u.get("K") || !1; u.has("CS") && (m = await this.parseColorSpace({ cs: u.get("CS"), resources: e })) } if (a && a.backdrop) { m = m || g.ColorSpace.singletons.rgb; a.backdrop = m.getRgb(a.backdrop, 0) } i.addOp(r.OPS.beginGroup, [d]) } i.addOp(r.OPS.paintFormXObjectBegin, [l, h]); return this.getOperatorList({ stream: t, task: s, resources: c.get("Resources") || e, operatorList: i, initialState: o }).then((function () { i.addOp(r.OPS.paintFormXObjectEnd, []); u && i.addOp(r.OPS.endGroup, [d]) })) }, async buildPaintImageXObject({ resources: e, image: t, isInline: a = !1, operatorList: i, cacheKey: n, imageCache: s, forceDisableNativeImageDecoder: o = !1 }) { var c = t.dict, l = c.get("Width", "W"), h = c.get("Height", "H"); if (!(l && (0, r.isNum)(l) && h && (0, r.isNum)(h))) { (0, r.warn)("Image dimensions are missing, or not numbers."); return } var u, d, f = this.options.maxImageSize; if (-1 !== f && l * h > f) { (0, r.warn)("Image exceeded maximum allowed size and was removed."); return } if (c.get("ImageMask", "IM") || !1) { var g = c.get("Width", "W"), p = c.get("Height", "H"), b = g + 7 >> 3, y = t.getBytes(b * p, !0), w = c.getArray("Decode", "D"); (u = C.PDFImage.createMask({ imgArray: y, width: g, height: p, imageIsFromDecodeStream: t instanceof m.DecodeStream, inverseDecode: !!w && w[0] > 0 })).cached = !!n; d = [u]; i.addOp(r.OPS.paintImageMaskXObject, d); n && (s[n] = { fn: r.OPS.paintImageMaskXObject, args: d }); return } var S = c.get("SMask", "SM") || !1, x = c.get("Mask") || !1; if (a && !S && !x && !(t instanceof v.JpegStream) && l + h < 200) { u = new C.PDFImage({ xref: this.xref, res: e, image: t, isInline: a, pdfFunctionFactory: this.pdfFunctionFactory }).createImageData(!0); i.addOp(r.OPS.paintInlineImageXObject, [u]); return } const A = o ? r.NativeImageDecoding.NONE : this.options.nativeImageDecoderSupport; let I = `img_${this.idFactory.createObjId()}`; if (this.parsingType3Font) { (0, r.assert)(A === r.NativeImageDecoding.NONE, "Type3 image resources should be completely decoded in the worker."); I = `${this.idFactory.getDocId()}_type3res_${I}` } if (A !== r.NativeImageDecoding.NONE && !S && !x && t instanceof v.JpegStream && k.NativeImageDecoder.isSupported(t, this.xref, e, this.pdfFunctionFactory) && t.maybeValidDimensions) return this.handler.sendWithPromise("obj", [I, this.pageIndex, "JpegStream", t.getIR(this.options.forceDataSchema)]).then((function () { i.addDependency(I); d = [I, l, h]; i.addOp(r.OPS.paintJpegXObject, d); n && (s[n] = { fn: r.OPS.paintJpegXObject, args: d }) }), o => { (0, r.warn)("Native JPEG decoding failed -- trying to recover: " + (o && o.message)); return this.buildPaintImageXObject({ resources: e, image: t, isInline: a, operatorList: i, cacheKey: n, imageCache: s, forceDisableNativeImageDecoder: !0 }) }); var F = null; A === r.NativeImageDecoding.DECODE && (t instanceof v.JpegStream || x instanceof v.JpegStream || S instanceof v.JpegStream) && (F = new k.NativeImageDecoder({ xref: this.xref, resources: e, handler: this.handler, forceDataSchema: this.options.forceDataSchema, pdfFunctionFactory: this.pdfFunctionFactory })); i.addDependency(I); d = [I, l, h]; const T = C.PDFImage.buildImage({ handler: this.handler, xref: this.xref, res: e, image: t, isInline: a, nativeDecoder: F, pdfFunctionFactory: this.pdfFunctionFactory }).then(e => { var t = e.createImageData(!1); if (this.parsingType3Font) return this.handler.sendWithPromise("commonobj", [I, "FontType3Res", t], [t.data.buffer]); this.handler.send("obj", [I, this.pageIndex, "Image", t], [t.data.buffer]) }).catch(e => { (0, r.warn)("Unable to decode image: " + e); if (this.parsingType3Font) return this.handler.sendWithPromise("commonobj", [I, "FontType3Res", null]); this.handler.send("obj", [I, this.pageIndex, "Image", null]) }); this.parsingType3Font && await T; i.addOp(r.OPS.paintImageXObject, d); n && (s[n] = { fn: r.OPS.paintImageXObject, args: d }) }, handleSMask: function (e, t, a, r, i) { var n = e.get("G"), s = { subtype: e.get("S").name, backdrop: e.get("BC") }, o = e.get("TR"); if ((0, y.isPDFFunction)(o)) { const e = this.pdfFunctionFactory.create(o); for (var c = new Uint8Array(256), l = new Float32Array(1), h = 0; h < 256; h++) { l[0] = h / 255; e(l, 0, l, 0); c[h] = 255 * l[0] | 0 } s.transferMap = c } return this.buildFormXObject(t, n, s, a, r, i.state.clone()) }, handleTilingType(e, t, a, i, s, o, c) { const l = new S.OperatorList, h = [s.get("Resources"), a], d = n.Dict.merge(this.xref, h); return this.getOperatorList({ stream: i, task: c, resources: d, operatorList: l }).then((function () { return (0, u.getTilingPatternIR)({ fnArray: l.fnArray, argsArray: l.argsArray }, s, t) })).then((function (t) { o.addDependencies(l.dependencies); o.addOp(e, t) }), e => { if (!(e instanceof r.AbortException)) { if (!this.options.ignoreErrors) throw e; this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`handleTilingType - ignoring pattern: "${e}".`) } }) }, handleSetFont: function (e, t, a, i, n, o) { var c; t && (c = (t = t.slice())[0].name); return this.loadFont(c, a, e).then(t => t.font.isType3Font ? t.loadType3Data(this, e, i, n).then((function () { return t })).catch(e => { this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); return new A("g_font_error", new s.ErrorFont("Type3 font load error: " + e), t.font) }) : t).then(e => { o.font = e.font; e.send(this.handler); return e.loadedName }) }, handleText(e, a) { const i = a.font, n = i.charsToGlyphs(e); if (i.data) { (!!(a.textRenderingMode & r.TextRenderingMode.ADD_TO_PATH_FLAG) || "Pattern" === a.fillColorSpace.name || i.disableFontFace || this.options.disableFontFace) && t.buildFontPaths(i, n, this.handler) } return n }, ensureStateFont(e) { if (e.font) return; const t = new r.FormatError("Missing setFont (Tf) operator before text rendering operator."); if (!this.options.ignoreErrors) throw t; this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); (0, r.warn)(`ensureStateFont: "${t}".`) }, setGState: function (e, t, a, i, s) { for (var o = [], c = t.getKeys(), l = Promise.resolve(), h = 0, u = c.length; h < u; h++) { const u = c[h], f = t.get(u); switch (u) { case "Type": break; case "LW": case "LC": case "LJ": case "ML": case "D": case "RI": case "FL": case "CA": case "ca": o.push([u, f]); break; case "Font": l = l.then(() => this.handleSetFont(e, null, f[0], a, i, s.state).then((function (e) { a.addDependency(e); o.push([u, [e, f[1]]]) }))); break; case "BM": o.push([u, d(f)]); break; case "SMask": if ((0, n.isName)(f, "None")) { o.push([u, !1]); break } if ((0, n.isDict)(f)) { l = l.then(() => this.handleSMask(f, e, a, i, s)); o.push([u, !0]) } else (0, r.warn)("Unsupported SMask type"); break; case "OP": case "op": case "OPM": case "BG": case "BG2": case "UCR": case "UCR2": case "TR": case "TR2": case "HT": case "SM": case "SA": case "AIS": case "TK": (0, r.info)("graphic state operator " + u); break; default: (0, r.info)("Unknown graphic state operator " + u) } } return l.then((function () { o.length > 0 && a.addOp(r.OPS.setGState, [o]) })) }, loadFont: function (e, a, i) { function o() { return Promise.resolve(new A("g_font_error", new s.ErrorFont("Font " + e + " is not available"), a)) } var c, l = this.xref; if (a) { if (!(0, n.isRef)(a)) throw new r.FormatError('The "font" object should be a reference.'); c = a } else { var h = i.get("Font"); h && (c = h.getRaw(e)) } if (!c) { const i = `Font "${e || a && a.toString()}" is not available`; if (!this.options.ignoreErrors && !this.parsingType3Font) { (0, r.warn)(`${i}.`); return o() } this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); (0, r.warn)(`${i} -- attempting to fallback to a default font.`); c = t.getFallbackFontDict() } if (this.fontCache.has(c)) return this.fontCache.get(c); a = l.fetchIfRef(c); if (!(0, n.isDict)(a)) return o(); if (a.translated) return a.translated; var u = (0, r.createPromiseCapability)(), d = this.preEvaluateFont(a); const { descriptor: f, hash: g } = d; var m, p, b = (0, n.isRef)(c); b && (m = c.toString()); if (g && (0, n.isDict)(f)) { f.fontAliases || (f.fontAliases = Object.create(null)); var y = f.fontAliases; if (y[g]) { var v = y[g].aliasRef; if (b && v && this.fontCache.has(v)) { this.fontCache.putAlias(c, v); return this.fontCache.get(c) } } else y[g] = { fontID: s.Font.getFontID() }; b && (y[g].aliasRef = c); m = y[g].fontID } if (b) this.fontCache.put(c, u.promise); else { m || (m = this.idFactory.createObjId()); this.fontCache.put(`id_${m}`, u.promise) } (0, r.assert)(m, 'The "fontID" must be defined.'); a.loadedName = `${this.idFactory.getDocId()}_f${m}`; a.translated = u.promise; try { p = this.translateFont(d) } catch (e) { p = Promise.reject(e) } p.then((function (e) { if (void 0 !== e.fontType) { l.stats.fontTypes[e.fontType] = !0 } u.resolve(new A(a.loadedName, e, a)) })).catch(e => { this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); try { var t = f && f.get("FontFile3"), i = t && t.get("Subtype"), n = (0, s.getFontType)(d.type, i && i.name); l.stats.fontTypes[n] = !0 } catch (e) { } u.resolve(new A(a.loadedName, new s.ErrorFont(e instanceof Error ? e.message : e), a)) }); return u.promise }, buildPath(e, t, a, i = !1) { var n = e.length - 1; a || (a = []); if (n < 0 || e.fnArray[n] !== r.OPS.constructPath) { if (i) { (0, r.warn)(`Encountered path operator "${t}" inside of a text object.`); e.addOp(r.OPS.save, null) } e.addOp(r.OPS.constructPath, [[t], a]); i && e.addOp(r.OPS.restore, null) } else { var s = e.argsArray[n]; s[0].push(t); Array.prototype.push.apply(s[1], a) } }, parseColorSpace({ cs: e, resources: t }) { return new Promise(a => { a(g.ColorSpace.parse(e, this.xref, t, this.pdfFunctionFactory)) }).catch(e => { if (e instanceof r.AbortException) return null; if (this.options.ignoreErrors) { this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`parseColorSpace - ignoring ColorSpace: "${e}".`); return null } throw e }) }, async handleColorN(e, t, a, i, s, o, c) { var l, h = a[a.length - 1]; if ((0, n.isName)(h) && (l = s.get(h.name))) { var d = (0, n.isStream)(l) ? l.dict : l, f = d.get("PatternType"); if (1 === f) { var g = i.base ? i.base.getRgb(a, 0) : null; return this.handleTilingType(t, g, o, l, d, e, c) } if (2 === f) { var m = d.get("Shading"), p = d.getArray("Matrix"); l = u.Pattern.parseShading(m, p, this.xref, o, this.handler, this.pdfFunctionFactory); e.addOp(t, l.getIR()); return } throw new r.FormatError(`Unknown PatternType: ${f}`) } throw new r.FormatError(`Unknown PatternName: ${h}`) }, getOperatorList({ stream: e, task: t, resources: i, operatorList: s, initialState: o = null }) { i = i || n.Dict.empty; o = o || new T; if (!s) throw new Error('getOperatorList: missing "operatorList" parameter'); var c = this, l = this.xref; let h = !1; var d = Object.create(null), f = i.get("XObject") || n.Dict.empty, m = i.get("Pattern") || n.Dict.empty, p = new I(o), b = new E(e, l, p), y = new a; function v(e) { for (var t = 0, a = b.savedStatesDepth; t < a; t++)s.addOp(r.OPS.restore, []) } return new Promise((function e(a, o) { const w = function (t) { Promise.all([t, s.ready]).then((function () { try { e(a, o) } catch (e) { o(e) } }), o) }; t.ensureNotTerminated(); y.reset(); for (var k, S, C, A, I = {}; !(k = y.check());) { I.args = null; if (!b.read(I)) break; var F = I.args, T = I.fn; switch (0 | T) { case r.OPS.paintXObject: var E = F[0].name; if (E && void 0 !== d[E]) { s.addOp(d[E].fn, d[E].args); F = null; continue } w(new Promise((function (e, a) { if (!E) throw new r.FormatError("XObject must be referred to by name."); const o = f.get(E); if (!o) { s.addOp(T, F); e(); return } if (!(0, n.isStream)(o)) throw new r.FormatError("XObject should be a stream"); const l = o.dict.get("Subtype"); if (!(0, n.isName)(l)) throw new r.FormatError("XObject should have a Name subtype"); if ("Form" !== l.name) if ("Image" !== l.name) { if ("PS" !== l.name) throw new r.FormatError(`Unhandled XObject subtype ${l.name}`); (0, r.info)("Ignored XObject subtype PS"); e() } else c.buildPaintImageXObject({ resources: i, image: o, operatorList: s, cacheKey: E, imageCache: d }).then(e, a); else { p.save(); c.buildFormXObject(i, o, null, s, t, p.state.clone()).then((function () { p.restore(); e() }), a) } })).catch((function (e) { if (!(e instanceof r.AbortException)) { if (!c.options.ignoreErrors) throw e; c.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`getOperatorList - ignoring XObject: "${e}".`) } }))); return; case r.OPS.setFont: var O = F[1]; w(c.handleSetFont(i, F, null, s, t, p.state).then((function (e) { s.addDependency(e); s.addOp(r.OPS.setFont, [e, O]) }))); return; case r.OPS.beginText: h = !0; break; case r.OPS.endText: h = !1; break; case r.OPS.endInlineImage: var P = F[0].cacheKey; if (P) { var B = d[P]; if (void 0 !== B) { s.addOp(B.fn, B.args); F = null; continue } } w(c.buildPaintImageXObject({ resources: i, image: F[0], isInline: !0, operatorList: s, cacheKey: P, imageCache: d })); return; case r.OPS.showText: if (!p.state.font) { c.ensureStateFont(p.state); continue } F[0] = c.handleText(F[0], p.state); break; case r.OPS.showSpacedText: if (!p.state.font) { c.ensureStateFont(p.state); continue } var D = F[0], N = [], M = D.length, L = p.state; for (S = 0; S < M; ++S) { var R = D[S]; (0, r.isString)(R) ? Array.prototype.push.apply(N, c.handleText(R, L)) : (0, r.isNum)(R) && N.push(R) } F[0] = N; T = r.OPS.showText; break; case r.OPS.nextLineShowText: if (!p.state.font) { c.ensureStateFont(p.state); continue } s.addOp(r.OPS.nextLine); F[0] = c.handleText(F[0], p.state); T = r.OPS.showText; break; case r.OPS.nextLineSetSpacingShowText: if (!p.state.font) { c.ensureStateFont(p.state); continue } s.addOp(r.OPS.nextLine); s.addOp(r.OPS.setWordSpacing, [F.shift()]); s.addOp(r.OPS.setCharSpacing, [F.shift()]); F[0] = c.handleText(F[0], p.state); T = r.OPS.showText; break; case r.OPS.setTextRenderingMode: p.state.textRenderingMode = F[0]; break; case r.OPS.setFillColorSpace: w(c.parseColorSpace({ cs: F[0], resources: i }).then((function (e) { e && (p.state.fillColorSpace = e) }))); return; case r.OPS.setStrokeColorSpace: w(c.parseColorSpace({ cs: F[0], resources: i }).then((function (e) { e && (p.state.strokeColorSpace = e) }))); return; case r.OPS.setFillColor: A = p.state.fillColorSpace; F = A.getRgb(F, 0); T = r.OPS.setFillRGBColor; break; case r.OPS.setStrokeColor: A = p.state.strokeColorSpace; F = A.getRgb(F, 0); T = r.OPS.setStrokeRGBColor; break; case r.OPS.setFillGray: p.state.fillColorSpace = g.ColorSpace.singletons.gray; F = g.ColorSpace.singletons.gray.getRgb(F, 0); T = r.OPS.setFillRGBColor; break; case r.OPS.setStrokeGray: p.state.strokeColorSpace = g.ColorSpace.singletons.gray; F = g.ColorSpace.singletons.gray.getRgb(F, 0); T = r.OPS.setStrokeRGBColor; break; case r.OPS.setFillCMYKColor: p.state.fillColorSpace = g.ColorSpace.singletons.cmyk; F = g.ColorSpace.singletons.cmyk.getRgb(F, 0); T = r.OPS.setFillRGBColor; break; case r.OPS.setStrokeCMYKColor: p.state.strokeColorSpace = g.ColorSpace.singletons.cmyk; F = g.ColorSpace.singletons.cmyk.getRgb(F, 0); T = r.OPS.setStrokeRGBColor; break; case r.OPS.setFillRGBColor: p.state.fillColorSpace = g.ColorSpace.singletons.rgb; F = g.ColorSpace.singletons.rgb.getRgb(F, 0); break; case r.OPS.setStrokeRGBColor: p.state.strokeColorSpace = g.ColorSpace.singletons.rgb; F = g.ColorSpace.singletons.rgb.getRgb(F, 0); break; case r.OPS.setFillColorN: if ("Pattern" === (A = p.state.fillColorSpace).name) { w(c.handleColorN(s, r.OPS.setFillColorN, F, A, m, i, t)); return } F = A.getRgb(F, 0); T = r.OPS.setFillRGBColor; break; case r.OPS.setStrokeColorN: if ("Pattern" === (A = p.state.strokeColorSpace).name) { w(c.handleColorN(s, r.OPS.setStrokeColorN, F, A, m, i, t)); return } F = A.getRgb(F, 0); T = r.OPS.setStrokeRGBColor; break; case r.OPS.shadingFill: var U = i.get("Shading"); if (!U) throw new r.FormatError("No shading resource found"); var q = U.get(F[0].name); if (!q) throw new r.FormatError("No shading object found"); var j = u.Pattern.parseShading(q, null, l, i, c.handler, c.pdfFunctionFactory).getIR(); F = [j]; T = r.OPS.shadingFill; break; case r.OPS.setGState: var _ = F[0], z = i.get("ExtGState"); if (!(0, n.isDict)(z) || !z.has(_.name)) break; var H = z.get(_.name); w(c.setGState(i, H, s, t, p)); return; case r.OPS.moveTo: case r.OPS.lineTo: case r.OPS.curveTo: case r.OPS.curveTo2: case r.OPS.curveTo3: case r.OPS.closePath: case r.OPS.rectangle: c.buildPath(s, T, F, h); continue; case r.OPS.markPoint: case r.OPS.markPointProps: case r.OPS.beginMarkedContent: case r.OPS.beginMarkedContentProps: case r.OPS.endMarkedContent: case r.OPS.beginCompat: case r.OPS.endCompat: continue; default: if (null !== F) { for (S = 0, C = F.length; S < C && !(F[S] instanceof n.Dict); S++); if (S < C) { (0, r.warn)("getOperatorList - ignoring operator: " + T); continue } } }s.addOp(T, F) } if (k) w(x); else { v(); a() } })).catch(e => { if (!(e instanceof r.AbortException)) { if (!this.options.ignoreErrors) throw e; this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.unknown }); (0, r.warn)(`getOperatorList - ignoring errors during "${t.name}" ` + `task: "${e}".`); v() } }) }, getTextContent({ stream: e, task: t, resources: i, stateManager: s = null, normalizeWhitespace: o = !1, combineTextItems: c = !1, sink: h, seenStyles: u = Object.create(null) }) { i = i || n.Dict.empty; s = s || new I(new F); var d, g = /\s/g, m = { items: [], styles: Object.create(null) }, p = { initialized: !1, str: [], width: 0, height: 0, vertical: !1, lastAdvanceWidth: 0, lastAdvanceHeight: 0, textAdvanceScale: 0, spaceWidth: 0, fakeSpaceMin: 1 / 0, fakeMultiSpaceMin: 1 / 0, fakeMultiSpaceMax: -0, textRunBreakAllowed: !1, transform: null, fontName: null }, b = this, y = this.xref, v = null, w = Object.create(null), k = new E(e, y, s); function S() { if (p.initialized) return p; var e = d.font; if (!(e.loadedName in u)) { u[e.loadedName] = !0; m.styles[e.loadedName] = { fontFamily: e.fallbackName, ascent: e.ascent, descent: e.descent, vertical: !!e.vertical } } p.fontName = e.loadedName; var t = [d.fontSize * d.textHScale, 0, 0, d.fontSize, 0, d.textRise]; if (e.isType3Font && d.fontSize <= 1 && !(0, r.isArrayEqual)(d.fontMatrix, r.FONT_IDENTITY_MATRIX)) { const a = e.bbox[3] - e.bbox[1]; a > 0 && (t[3] *= a * d.fontMatrix[3]) } var a = r.Util.transform(d.ctm, r.Util.transform(d.textMatrix, t)); p.transform = a; if (e.vertical) { p.width = Math.sqrt(a[0] * a[0] + a[1] * a[1]); p.height = 0; p.vertical = !0 } else { p.width = 0; p.height = Math.sqrt(a[2] * a[2] + a[3] * a[3]); p.vertical = !1 } var i = d.textLineMatrix[0], n = d.textLineMatrix[1], s = Math.sqrt(i * i + n * n); i = d.ctm[0]; n = d.ctm[1]; var o = Math.sqrt(i * i + n * n); p.textAdvanceScale = o * s; p.lastAdvanceWidth = 0; p.lastAdvanceHeight = 0; var c = e.spaceWidth / 1e3 * d.fontSize; if (c) { p.spaceWidth = c; p.fakeSpaceMin = .3 * c; p.fakeMultiSpaceMin = 1.5 * c; p.fakeMultiSpaceMax = 4 * c; p.textRunBreakAllowed = !e.isMonospace } else { p.spaceWidth = 0; p.fakeSpaceMin = 1 / 0; p.fakeMultiSpaceMin = 1 / 0; p.fakeMultiSpaceMax = 0; p.textRunBreakAllowed = !1 } p.initialized = !0; return p } function C(e) { for (var t, a = 0, r = e.length; a < r && (t = e.charCodeAt(a)) >= 32 && t <= 127;)a++; return a < r ? e.replace(g, " ") : e } function A(e, t) { return b.loadFont(e, t, i).then((function (e) { d.font = e.font; d.fontMatrix = e.font.fontMatrix || r.FONT_IDENTITY_MATRIX })) } function T(e) { for (var t = d.font, a = S(), r = 0, i = 0, n = t.charsToGlyphs(e), s = 0; s < n.length; s++) { var o = n[s], c = null; c = t.vertical && o.vmetric ? o.vmetric[0] : o.width; var h = o.unicode, u = (0, l.getNormalizedUnicodes)(); void 0 !== u[h] && (h = u[h]); h = (0, l.reverseIfRtl)(h); var f = d.charSpacing; if (o.isSpace) { var g = d.wordSpacing; f += g; g > 0 && O(g, a.str) } var m = 0, p = 0; if (t.vertical) { i += p = c * d.fontMatrix[0] * d.fontSize + f } else { r += m = (c * d.fontMatrix[0] * d.fontSize + f) * d.textHScale } d.translateTextMatrix(m, p); a.str.push(h) } if (t.vertical) { a.lastAdvanceHeight = i; a.height += Math.abs(i) } else { a.lastAdvanceWidth = r; a.width += r } return a } function O(e, t) { if (!(e < p.fakeSpaceMin)) if (e < p.fakeMultiSpaceMin) t.push(" "); else for (var a = Math.round(e / p.spaceWidth); a-- > 0;)t.push(" ") } function P() { if (p.initialized) { p.vertical ? p.height *= p.textAdvanceScale : p.width *= p.textAdvanceScale; m.items.push((t = (e = p).str.join(""), a = (0, f.bidi)(t, -1, e.vertical), { str: o ? C(a.str) : a.str, dir: a.dir, width: e.width, height: e.height, transform: e.transform, fontName: e.fontName })); var e, t, a; p.initialized = !1; p.str.length = 0 } } function B() { const e = m.items.length; if (e > 0) { h.enqueue(m, e); m.items = []; m.styles = Object.create(null) } } var D = new a; return new Promise((function e(a, l) { const f = function (t) { B(); Promise.all([t, h.ready]).then((function () { try { e(a, l) } catch (e) { l(e) } }), l) }; t.ensureNotTerminated(); D.reset(); for (var g, y = {}, C = []; !(g = D.check());) { C.length = 0; y.args = C; if (!k.read(y)) break; d = s.state; var F, E = y.fn; C = y.args; switch (0 | E) { case r.OPS.setFont: var N = C[0].name, M = C[1]; if (d.font && N === d.fontName && M === d.fontSize) break; P(); d.fontName = N; d.fontSize = M; f(A(N, null)); return; case r.OPS.setTextRise: P(); d.textRise = C[0]; break; case r.OPS.setHScale: P(); d.textHScale = C[0] / 100; break; case r.OPS.setLeading: P(); d.leading = C[0]; break; case r.OPS.moveText: var L = !!d.font && 0 === (d.font.vertical ? C[0] : C[1]); F = C[0] - C[1]; if (c && L && p.initialized && F > 0 && F <= p.fakeMultiSpaceMax) { d.translateTextLineMatrix(C[0], C[1]); p.width += C[0] - p.lastAdvanceWidth; p.height += C[1] - p.lastAdvanceHeight; O(C[0] - p.lastAdvanceWidth - (C[1] - p.lastAdvanceHeight), p.str); break } P(); d.translateTextLineMatrix(C[0], C[1]); d.textMatrix = d.textLineMatrix.slice(); break; case r.OPS.setLeadingMoveText: P(); d.leading = -C[1]; d.translateTextLineMatrix(C[0], C[1]); d.textMatrix = d.textLineMatrix.slice(); break; case r.OPS.nextLine: P(); d.carriageReturn(); break; case r.OPS.setTextMatrix: F = d.calcTextLineMatrixAdvance(C[0], C[1], C[2], C[3], C[4], C[5]); if (c && null !== F && p.initialized && F.value > 0 && F.value <= p.fakeMultiSpaceMax) { d.translateTextLineMatrix(F.width, F.height); p.width += F.width - p.lastAdvanceWidth; p.height += F.height - p.lastAdvanceHeight; O(F.width - p.lastAdvanceWidth - (F.height - p.lastAdvanceHeight), p.str); break } P(); d.setTextMatrix(C[0], C[1], C[2], C[3], C[4], C[5]); d.setTextLineMatrix(C[0], C[1], C[2], C[3], C[4], C[5]); break; case r.OPS.setCharSpacing: d.charSpacing = C[0]; break; case r.OPS.setWordSpacing: d.wordSpacing = C[0]; break; case r.OPS.beginText: P(); d.textMatrix = r.IDENTITY_MATRIX.slice(); d.textLineMatrix = r.IDENTITY_MATRIX.slice(); break; case r.OPS.showSpacedText: if (!s.state.font) { b.ensureStateFont(s.state); continue } for (var R, U = C[0], q = 0, j = U.length; q < j; q++)if ("string" == typeof U[q]) T(U[q]); else if ((0, r.isNum)(U[q])) { S(); F = U[q] * d.fontSize / 1e3; var _ = !1; if (d.font.vertical) { R = F; d.translateTextMatrix(0, R); (_ = p.textRunBreakAllowed && F > p.fakeMultiSpaceMax) || (p.height += R) } else { R = (F = -F) * d.textHScale; d.translateTextMatrix(R, 0); (_ = p.textRunBreakAllowed && F > p.fakeMultiSpaceMax) || (p.width += R) } _ ? P() : F > 0 && O(F, p.str) } break; case r.OPS.showText: if (!s.state.font) { b.ensureStateFont(s.state); continue } T(C[0]); break; case r.OPS.nextLineShowText: if (!s.state.font) { b.ensureStateFont(s.state); continue } P(); d.carriageReturn(); T(C[0]); break; case r.OPS.nextLineSetSpacingShowText: if (!s.state.font) { b.ensureStateFont(s.state); continue } P(); d.wordSpacing = C[0]; d.charSpacing = C[1]; d.carriageReturn(); T(C[2]); break; case r.OPS.paintXObject: P(); v || (v = i.get("XObject") || n.Dict.empty); var z = C[0].name; if (z && void 0 !== w[z]) break; f(new Promise((function (e, a) { if (!z) throw new r.FormatError("XObject must be referred to by name."); const l = v.get(z); if (!l) { e(); return } if (!(0, n.isStream)(l)) throw new r.FormatError("XObject should be a stream"); const d = l.dict.get("Subtype"); if (!(0, n.isName)(d)) throw new r.FormatError("XObject should have a Name subtype"); if ("Form" !== d.name) { w[z] = !0; e(); return } const f = s.state.clone(), g = new I(f), m = l.dict.getArray("Matrix"); Array.isArray(m) && 6 === m.length && g.transform(m); B(); const p = { enqueueInvoked: !1, enqueue(e, t) { this.enqueueInvoked = !0; h.enqueue(e, t) }, get desiredSize() { return h.desiredSize }, get ready() { return h.ready } }; b.getTextContent({ stream: l, task: t, resources: l.dict.get("Resources") || i, stateManager: g, normalizeWhitespace: o, combineTextItems: c, sink: p, seenStyles: u }).then((function () { p.enqueueInvoked || (w[z] = !0); e() }), a) })).catch((function (e) { if (!(e instanceof r.AbortException)) { if (!b.options.ignoreErrors) throw e; (0, r.warn)(`getTextContent - ignoring XObject: "${e}".`) } }))); return; case r.OPS.setGState: P(); var H = C[0], G = i.get("ExtGState"); if (!(0, n.isDict)(G) || !(0, n.isName)(H)) break; var W = G.get(H.name); if (!(0, n.isDict)(W)) break; var X = W.get("Font"); if (X) { d.fontName = null; d.fontSize = X[1]; f(A(null, X[0])); return } }if (m.items.length >= h.desiredSize) { g = !0; break } } if (g) f(x); else { P(); B(); a() } })).catch(e => { if (!(e instanceof r.AbortException)) { if (!this.options.ignoreErrors) throw e; (0, r.warn)(`getTextContent - ignoring errors during "${t.name}" ` + `task: "${e}".`); P(); B() } }) }, extractDataStructures: function (e, t, a) { const i = this.xref; let c; var l = e.get("ToUnicode") || t.get("ToUnicode"), h = l ? this.readToUnicode(l) : Promise.resolve(void 0); if (a.composite) { var u = e.get("CIDSystemInfo"); (0, n.isDict)(u) && (a.cidSystemInfo = { registry: (0, r.stringToPDFString)(u.get("Registry")), ordering: (0, r.stringToPDFString)(u.get("Ordering")), supplement: u.get("Supplement") }); var d = e.get("CIDToGIDMap"); (0, n.isStream)(d) && (c = d.getBytes()) } var f, g = [], m = null; if (e.has("Encoding")) { f = e.get("Encoding"); if ((0, n.isDict)(f)) { m = f.get("BaseEncoding"); m = (0, n.isName)(m) ? m.name : null; if (f.has("Differences")) for (var p = f.get("Differences"), b = 0, y = 0, v = p.length; y < v; y++) { var w = i.fetchIfRef(p[y]); if ((0, r.isNum)(w)) b = w; else { if (!(0, n.isName)(w)) throw new r.FormatError(`Invalid entry in 'Differences' array: ${w}`); g[b++] = w.name } } } else { if (!(0, n.isName)(f)) throw new r.FormatError("Encoding is not a Name nor a Dict"); m = f.name } "MacRomanEncoding" !== m && "MacExpertEncoding" !== m && "WinAnsiEncoding" !== m && (m = null) } if (m) a.defaultEncoding = (0, o.getEncoding)(m).slice(); else { var k = !!(a.flags & s.FontFlags.Symbolic), S = !!(a.flags & s.FontFlags.Nonsymbolic); f = o.StandardEncoding; "TrueType" !== a.type || S || (f = o.WinAnsiEncoding); if (k) { f = o.MacRomanEncoding; a.file || (/Symbol/i.test(a.name) ? f = o.SymbolSetEncoding : /Dingbats|Wingdings/i.test(a.name) && (f = o.ZapfDingbatsEncoding)) } a.defaultEncoding = f } a.differences = g; a.baseEncodingName = m; a.hasEncoding = !!m || g.length > 0; a.dict = e; return h.then(e => { a.toUnicode = e; return this.buildToUnicode(a) }).then(e => { a.toUnicode = e; c && (a.cidToGidMap = this.readCidToGidMap(c, e)); return a }) }, _buildSimpleFontToUnicode(e, t = !1) { (0, r.assert)(!e.composite, "Must be a simple font."); const a = [], i = e.defaultEncoding.slice(), n = e.baseEncodingName, c = e.differences; for (const e in c) { const t = c[e]; ".notdef" !== t && (i[e] = t) } const h = (0, p.getGlyphsUnicode)(); for (const r in i) { let s = i[r]; if ("" !== s) if (void 0 !== h[s]) a[r] = String.fromCharCode(h[s]); else { let i = 0; switch (s[0]) { case "G": 3 === s.length && (i = parseInt(s.substring(1), 16)); break; case "g": 5 === s.length && (i = parseInt(s.substring(1), 16)); break; case "C": case "c": if (s.length >= 3 && s.length <= 4) { const a = s.substring(1); if (t) { i = parseInt(a, 16); break } i = +a; if (Number.isNaN(i) && Number.isInteger(parseInt(a, 16))) return this._buildSimpleFontToUnicode(e, !0) } break; default: const a = (0, l.getUnicodeForGlyph)(s, h); -1 !== a && (i = a) }if (i > 0 && Number.isInteger(i)) { if (n && i === +r) { const e = (0, o.getEncoding)(n); if (e && (s = e[r])) { a[r] = String.fromCharCode(h[s]); continue } } a[r] = String.fromCodePoint(i) } } } return new s.ToUnicodeMap(a) }, buildToUnicode(e) { e.hasIncludedToUnicodeMap = !!e.toUnicode && e.toUnicode.length > 0; if (e.hasIncludedToUnicodeMap) { !e.composite && e.hasEncoding && (e.fallbackToUnicode = this._buildSimpleFontToUnicode(e)); return Promise.resolve(e.toUnicode) } if (!e.composite) return Promise.resolve(this._buildSimpleFontToUnicode(e)); if (e.composite && (e.cMap.builtInCMap && !(e.cMap instanceof i.IdentityCMap) || "Adobe" === e.cidSystemInfo.registry && ("GB1" === e.cidSystemInfo.ordering || "CNS1" === e.cidSystemInfo.ordering || "Japan1" === e.cidSystemInfo.ordering || "Korea1" === e.cidSystemInfo.ordering))) { const t = e.cidSystemInfo.registry, a = e.cidSystemInfo.ordering, o = n.Name.get(t + "-" + a + "-UCS2"); return i.CMapFactory.create({ encoding: o, fetchBuiltInCMap: this.fetchBuiltInCMap, useCMap: null }).then((function (t) { const a = e.cMap, i = []; a.forEach((function (e, a) { if (a > 65535) throw new r.FormatError("Max size of CID is 65,535"); const n = t.lookup(a); n && (i[e] = String.fromCharCode((n.charCodeAt(0) << 8) + n.charCodeAt(1))) })); return new s.ToUnicodeMap(i) })) } return Promise.resolve(new s.IdentityToUnicodeMap(e.firstChar, e.lastChar)) }, readToUnicode: function (e) { var t = e; return (0, n.isName)(t) ? i.CMapFactory.create({ encoding: t, fetchBuiltInCMap: this.fetchBuiltInCMap, useCMap: null }).then((function (e) { return e instanceof i.IdentityCMap ? new s.IdentityToUnicodeMap(0, 65535) : new s.ToUnicodeMap(e.getMap()) })) : (0, n.isStream)(t) ? i.CMapFactory.create({ encoding: t, fetchBuiltInCMap: this.fetchBuiltInCMap, useCMap: null }).then((function (e) { if (e instanceof i.IdentityCMap) return new s.IdentityToUnicodeMap(0, 65535); var t = new Array(e.length); e.forEach((function (e, a) { for (var r = [], i = 0; i < a.length; i += 2) { var n = a.charCodeAt(i) << 8 | a.charCodeAt(i + 1); if (55296 == (63488 & n)) { i += 2; var s = a.charCodeAt(i) << 8 | a.charCodeAt(i + 1); r.push(((1023 & n) << 10) + (1023 & s) + 65536) } else r.push(n) } t[e] = String.fromCodePoint.apply(String, r) })); return new s.ToUnicodeMap(t) }), e => { if (e instanceof r.AbortException) return null; if (this.options.ignoreErrors) { this.handler.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.font }); (0, r.warn)(`readToUnicode - ignoring ToUnicode data: "${e}".`); return null } throw e }) : Promise.resolve(null) }, readCidToGidMap(e, t) { for (var a = [], r = 0, i = e.length; r < i; r++) { var n = e[r++] << 8 | e[r]; const i = r >> 1; (0 !== n || t.has(i)) && (a[i] = n) } return a }, extractWidths: function (e, t, a) { var r, i, o, c, l, h, u, d, f = this.xref, g = [], m = 0, p = []; if (a.composite) { m = e.has("DW") ? e.get("DW") : 1e3; if (d = e.get("W")) for (i = 0, o = d.length; i < o; i++) { h = f.fetchIfRef(d[i++]); u = f.fetchIfRef(d[i]); if (Array.isArray(u)) for (c = 0, l = u.length; c < l; c++)g[h++] = f.fetchIfRef(u[c]); else { var b = f.fetchIfRef(d[++i]); for (c = h; c <= u; c++)g[c] = b } } if (a.vertical) { var y = e.getArray("DW2") || [880, -1e3]; r = [y[1], .5 * m, y[0]]; if (y = e.get("W2")) for (i = 0, o = y.length; i < o; i++) { h = f.fetchIfRef(y[i++]); u = f.fetchIfRef(y[i]); if (Array.isArray(u)) for (c = 0, l = u.length; c < l; c++)p[h++] = [f.fetchIfRef(u[c++]), f.fetchIfRef(u[c++]), f.fetchIfRef(u[c])]; else { var v = [f.fetchIfRef(y[++i]), f.fetchIfRef(y[++i]), f.fetchIfRef(y[++i])]; for (c = h; c <= u; c++)p[c] = v } } } } else { var w = a.firstChar; if (d = e.get("Widths")) { c = w; for (i = 0, o = d.length; i < o; i++)g[c++] = f.fetchIfRef(d[i]); m = parseFloat(t.get("MissingWidth")) || 0 } else { var k = e.get("BaseFont"); if ((0, n.isName)(k)) { var S = this.getBaseFontMetrics(k.name); g = this.buildCharCodeToWidth(S.widths, a); m = S.defaultWidth } } } var C = !0, x = m; for (var A in g) { var I = g[A]; if (I) if (x) { if (x !== I) { C = !1; break } } else x = I } C && (a.flags |= s.FontFlags.FixedPitch); a.defaultWidth = m; a.widths = g; a.defaultVMetrics = r; a.vmetrics = p }, isSerifFont: function (e) { var t = e.split("-")[0]; return t in (0, h.getSerifFonts)() || -1 !== t.search(/serif/gi) }, getBaseFontMetrics: function (e) { var t = 0, a = [], i = !1, n = (0, h.getStdFontMap)()[e] || e, s = (0, b.getMetrics)(); n in s || (n = this.isSerifFont(e) ? "Times-Roman" : "Helvetica"); var o = s[n]; if ((0, r.isNum)(o)) { t = o; i = !0 } else a = o(); return { defaultWidth: t, monospace: i, widths: a } }, buildCharCodeToWidth: function (e, t) { for (var a = Object.create(null), r = t.differences, i = t.defaultEncoding, n = 0; n < 256; n++)n in r && e[r[n]] ? a[n] = e[r[n]] : n in i && e[i[n]] && (a[n] = e[i[n]]); return a }, preEvaluateFont: function (e) { var t = e, a = e.get("Subtype"); if (!(0, n.isName)(a)) throw new r.FormatError("invalid font Subtype"); var i, s = !1; if ("Type0" === a.name) { var o = e.get("DescendantFonts"); if (!o) throw new r.FormatError("Descendant fonts are not specified"); a = (e = Array.isArray(o) ? this.xref.fetchIfRef(o[0]) : o).get("Subtype"); if (!(0, n.isName)(a)) throw new r.FormatError("invalid font Subtype"); s = !0 } var c = e.get("FontDescriptor"); if (c) { var l = new w.MurmurHash3_64, h = t.getRaw("Encoding"); if ((0, n.isName)(h)) l.update(h.name); else if ((0, n.isRef)(h)) l.update(h.toString()); else if ((0, n.isDict)(h)) for (var u = h.getKeys(), d = 0, f = u.length; d < f; d++) { var g = h.getRaw(u[d]); if ((0, n.isName)(g)) l.update(g.name); else if ((0, n.isRef)(g)) l.update(g.toString()); else if (Array.isArray(g)) { for (var m = g.length, p = new Array(m), b = 0; b < m; b++) { var y = g[b]; (0, n.isName)(y) ? p[b] = y.name : ((0, r.isNum)(y) || (0, n.isRef)(y)) && (p[b] = y.toString()) } l.update(p.join()) } } const a = e.get("FirstChar") || 0, o = e.get("LastChar") || (s ? 65535 : 255); l.update(`${a}-${o}`); var v = e.get("ToUnicode") || t.get("ToUnicode"); if ((0, n.isStream)(v)) { var k = v.str || v; i = k.buffer ? new Uint8Array(k.buffer.buffer, 0, k.bufferLength) : new Uint8Array(k.bytes.buffer, k.start, k.end - k.start); l.update(i) } else (0, n.isName)(v) && l.update(v.name); var S = e.get("Widths") || t.get("Widths"); if (S) { i = new Uint8Array(new Uint32Array(S).buffer); l.update(i) } } return { descriptor: c, dict: e, baseDict: t, composite: s, type: a.name, hash: l ? l.hexdigest() : "" } }, translateFont: function (e) { var t, a = e.baseDict, o = e.dict, c = e.composite, l = e.descriptor, u = e.type, d = c ? 65535 : 255; const f = o.get("FirstChar") || 0, g = o.get("LastChar") || d; if (!l) { if ("Type3" !== u) { var m = o.get("BaseFont"); if (!(0, n.isName)(m)) throw new r.FormatError("Base font is not specified"); m = m.name.replace(/[,_]/g, "-"); var p = this.getBaseFontMetrics(m), b = m.split("-")[0], y = (this.isSerifFont(b) ? s.FontFlags.Serif : 0) | (p.monospace ? s.FontFlags.FixedPitch : 0) | ((0, h.getSymbolsFonts)()[b] ? s.FontFlags.Symbolic : s.FontFlags.Nonsymbolic); t = { type: u, name: m, widths: p.widths, defaultWidth: p.defaultWidth, flags: y, firstChar: f, lastChar: g }; const e = o.get("Widths"); return this.extractDataStructures(o, o, t).then(t => { if (e) { const a = []; let r = f; for (let t = 0, i = e.length; t < i; t++)a[r++] = this.xref.fetchIfRef(e[t]); t.widths = a } else t.widths = this.buildCharCodeToWidth(p.widths, t); return new s.Font(m, null, t) }) } (l = new n.Dict(null)).set("FontName", n.Name.get(u)); l.set("FontBBox", o.getArray("FontBBox") || [0, 0, 0, 0]) } var v = l.get("FontName"), w = o.get("BaseFont"); (0, r.isString)(v) && (v = n.Name.get(v)); (0, r.isString)(w) && (w = n.Name.get(w)); if ("Type3" !== u) { var k = v && v.name, S = w && w.name; if (k !== S) { (0, r.info)(`The FontDescriptor's FontName is "${k}" but ` + `should be the same as the Font's BaseFont "${S}".`); k && S && S.startsWith(k) && (v = w) } } v = v || w; if (!(0, n.isName)(v)) throw new r.FormatError("invalid font name"); var C, x = l.get("FontFile", "FontFile2", "FontFile3"); if (x && x.dict) { var A = x.dict.get("Subtype"); A && (A = A.name); var I = x.dict.get("Length1"), F = x.dict.get("Length2"), T = x.dict.get("Length3") } t = { type: u, name: v.name, subtype: A, file: x, length1: I, length2: F, length3: T, loadedName: a.loadedName, composite: c, wideChars: c, fixedPitch: !1, fontMatrix: o.getArray("FontMatrix") || r.FONT_IDENTITY_MATRIX, firstChar: f || 0, lastChar: g || d, bbox: l.getArray("FontBBox"), ascent: l.get("Ascent"), descent: l.get("Descent"), xHeight: l.get("XHeight"), capHeight: l.get("CapHeight"), flags: l.get("Flags"), italicAngle: l.get("ItalicAngle"), isType3Font: !1 }; if (c) { var E = a.get("Encoding"); (0, n.isName)(E) && (t.cidEncoding = E.name); C = i.CMapFactory.create({ encoding: E, fetchBuiltInCMap: this.fetchBuiltInCMap, useCMap: null }).then((function (e) { t.cMap = e; t.vertical = t.cMap.vertical })) } else C = Promise.resolve(void 0); return C.then(() => this.extractDataStructures(o, a, t)).then(e => { this.extractWidths(o, l, e); "Type3" === u && (e.isType3Font = !0); return new s.Font(v.name, x, e) }) } }; t.buildFontPaths = function (e, t, a) { function r(t) { e.renderer.hasBuiltPath(t) || a.send("commonobj", [`${e.loadedName}_path_${t}`, "FontPath", e.renderer.getPathJs(t)]) } for (const e of t) { r(e.fontChar); const t = e.accent; t && t.fontChar && r(t.fontChar) } }; t.getFallbackFontDict = function () { if (this._fallbackFontDict) return this._fallbackFontDict; const e = new n.Dict; e.set("BaseFont", n.Name.get("PDFJS-FallbackFont")); e.set("Type", n.Name.get("FallbackType")); e.set("Subtype", n.Name.get("FallbackType")); e.set("Encoding", n.Name.get("WinAnsiEncoding")); return this._fallbackFontDict = e }; return t }(); t.PartialEvaluator = x; var A = function () { function e(e, t, a) { this.loadedName = e; this.font = t; this.dict = a; this.type3Loaded = null; this.sent = !1 } e.prototype = { send(e) { if (!this.sent) { this.sent = !0; e.send("commonobj", [this.loadedName, "Font", this.font.exportData()]) } }, fallback(e) { if (!this.font.data) return; this.font.disableFontFace = !0; const t = this.font.glyphCacheValues; x.buildFontPaths(this.font, t, e) }, loadType3Data(e, t, a, i) { if (!this.font.isType3Font) throw new Error("Must be a Type3 font."); if (this.type3Loaded) return this.type3Loaded; var n = Object.create(e.options); n.ignoreErrors = !1; n.nativeImageDecoderSupport = r.NativeImageDecoding.NONE; var s = e.clone(n); s.parsingType3Font = !0; for (var o = this.font, c = Promise.resolve(), l = this.dict.get("CharProcs"), h = this.dict.get("Resources") || t, u = l.getKeys(), d = Object.create(null), f = 0, g = u.length; f < g; ++f) { const e = u[f]; c = c.then((function () { var t = l.get(e), n = new S.OperatorList; return s.getOperatorList({ stream: t, task: i, resources: h, operatorList: n }).then((function () { d[e] = n.getIR(); a.addDependencies(n.dependencies) })).catch((function (t) { (0, r.warn)(`Type3 font resource "${e}" is not available.`); var a = new S.OperatorList; d[e] = a.getIR() })) })) } this.type3Loaded = c.then((function () { o.charProcOperatorList = d })); return this.type3Loaded } }; return e }(), I = function () { function e(e) { this.state = e; this.stateStack = [] } e.prototype = { save() { var e = this.state; this.stateStack.push(this.state); this.state = e.clone() }, restore() { var e = this.stateStack.pop(); e && (this.state = e) }, transform(e) { this.state.ctm = r.Util.transform(this.state.ctm, e) } }; return e }(), F = function () { function e() { this.ctm = new Float32Array(r.IDENTITY_MATRIX); this.fontName = null; this.fontSize = 0; this.font = null; this.fontMatrix = r.FONT_IDENTITY_MATRIX; this.textMatrix = r.IDENTITY_MATRIX.slice(); this.textLineMatrix = r.IDENTITY_MATRIX.slice(); this.charSpacing = 0; this.wordSpacing = 0; this.leading = 0; this.textHScale = 1; this.textRise = 0 } e.prototype = { setTextMatrix: function (e, t, a, r, i, n) { var s = this.textMatrix; s[0] = e; s[1] = t; s[2] = a; s[3] = r; s[4] = i; s[5] = n }, setTextLineMatrix: function (e, t, a, r, i, n) { var s = this.textLineMatrix; s[0] = e; s[1] = t; s[2] = a; s[3] = r; s[4] = i; s[5] = n }, translateTextMatrix: function (e, t) { var a = this.textMatrix; a[4] = a[0] * e + a[2] * t + a[4]; a[5] = a[1] * e + a[3] * t + a[5] }, translateTextLineMatrix: function (e, t) { var a = this.textLineMatrix; a[4] = a[0] * e + a[2] * t + a[4]; a[5] = a[1] * e + a[3] * t + a[5] }, calcTextLineMatrixAdvance: function (e, t, a, r, i, n) { var s = this.font; if (!s) return null; var o = this.textLineMatrix; if (e !== o[0] || t !== o[1] || a !== o[2] || r !== o[3]) return null; var c = i - o[4], l = n - o[5]; if (s.vertical && 0 !== c || !s.vertical && 0 !== l) return null; var h, u, d = e * r - t * a; if (s.vertical) { h = -l * a / d; u = l * e / d } else { h = c * r / d; u = -c * t / d } return { width: h, height: u, value: s.vertical ? u : h } }, calcRenderMatrix: function (e) { var t = [this.fontSize * this.textHScale, 0, 0, this.fontSize, 0, this.textRise]; return r.Util.transform(e, r.Util.transform(this.textMatrix, t)) }, carriageReturn: function () { this.translateTextLineMatrix(0, -this.leading); this.textMatrix = this.textLineMatrix.slice() }, clone: function () { var e = Object.create(this); e.textMatrix = this.textMatrix.slice(); e.textLineMatrix = this.textLineMatrix.slice(); e.fontMatrix = this.fontMatrix.slice(); return e } }; return e }(), T = function () { function e() { this.ctm = new Float32Array(r.IDENTITY_MATRIX); this.font = null; this.textRenderingMode = r.TextRenderingMode.FILL; this.fillColorSpace = g.ColorSpace.singletons.gray; this.strokeColorSpace = g.ColorSpace.singletons.gray } e.prototype = { clone: function () { return Object.create(this) } }; return e }(), E = function () { var e = (0, c.getLookupTableFactory)((function (e) { e.w = { id: r.OPS.setLineWidth, numArgs: 1, variableArgs: !1 }; e.J = { id: r.OPS.setLineCap, numArgs: 1, variableArgs: !1 }; e.j = { id: r.OPS.setLineJoin, numArgs: 1, variableArgs: !1 }; e.M = { id: r.OPS.setMiterLimit, numArgs: 1, variableArgs: !1 }; e.d = { id: r.OPS.setDash, numArgs: 2, variableArgs: !1 }; e.ri = { id: r.OPS.setRenderingIntent, numArgs: 1, variableArgs: !1 }; e.i = { id: r.OPS.setFlatness, numArgs: 1, variableArgs: !1 }; e.gs = { id: r.OPS.setGState, numArgs: 1, variableArgs: !1 }; e.q = { id: r.OPS.save, numArgs: 0, variableArgs: !1 }; e.Q = { id: r.OPS.restore, numArgs: 0, variableArgs: !1 }; e.cm = { id: r.OPS.transform, numArgs: 6, variableArgs: !1 }; e.m = { id: r.OPS.moveTo, numArgs: 2, variableArgs: !1 }; e.l = { id: r.OPS.lineTo, numArgs: 2, variableArgs: !1 }; e.c = { id: r.OPS.curveTo, numArgs: 6, variableArgs: !1 }; e.v = { id: r.OPS.curveTo2, numArgs: 4, variableArgs: !1 }; e.y = { id: r.OPS.curveTo3, numArgs: 4, variableArgs: !1 }; e.h = { id: r.OPS.closePath, numArgs: 0, variableArgs: !1 }; e.re = { id: r.OPS.rectangle, numArgs: 4, variableArgs: !1 }; e.S = { id: r.OPS.stroke, numArgs: 0, variableArgs: !1 }; e.s = { id: r.OPS.closeStroke, numArgs: 0, variableArgs: !1 }; e.f = { id: r.OPS.fill, numArgs: 0, variableArgs: !1 }; e.F = { id: r.OPS.fill, numArgs: 0, variableArgs: !1 }; e["f*"] = { id: r.OPS.eoFill, numArgs: 0, variableArgs: !1 }; e.B = { id: r.OPS.fillStroke, numArgs: 0, variableArgs: !1 }; e["B*"] = { id: r.OPS.eoFillStroke, numArgs: 0, variableArgs: !1 }; e.b = { id: r.OPS.closeFillStroke, numArgs: 0, variableArgs: !1 }; e["b*"] = { id: r.OPS.closeEOFillStroke, numArgs: 0, variableArgs: !1 }; e.n = { id: r.OPS.endPath, numArgs: 0, variableArgs: !1 }; e.W = { id: r.OPS.clip, numArgs: 0, variableArgs: !1 }; e["W*"] = { id: r.OPS.eoClip, numArgs: 0, variableArgs: !1 }; e.BT = { id: r.OPS.beginText, numArgs: 0, variableArgs: !1 }; e.ET = { id: r.OPS.endText, numArgs: 0, variableArgs: !1 }; e.Tc = { id: r.OPS.setCharSpacing, numArgs: 1, variableArgs: !1 }; e.Tw = { id: r.OPS.setWordSpacing, numArgs: 1, variableArgs: !1 }; e.Tz = { id: r.OPS.setHScale, numArgs: 1, variableArgs: !1 }; e.TL = { id: r.OPS.setLeading, numArgs: 1, variableArgs: !1 }; e.Tf = { id: r.OPS.setFont, numArgs: 2, variableArgs: !1 }; e.Tr = { id: r.OPS.setTextRenderingMode, numArgs: 1, variableArgs: !1 }; e.Ts = { id: r.OPS.setTextRise, numArgs: 1, variableArgs: !1 }; e.Td = { id: r.OPS.moveText, numArgs: 2, variableArgs: !1 }; e.TD = { id: r.OPS.setLeadingMoveText, numArgs: 2, variableArgs: !1 }; e.Tm = { id: r.OPS.setTextMatrix, numArgs: 6, variableArgs: !1 }; e["T*"] = { id: r.OPS.nextLine, numArgs: 0, variableArgs: !1 }; e.Tj = { id: r.OPS.showText, numArgs: 1, variableArgs: !1 }; e.TJ = { id: r.OPS.showSpacedText, numArgs: 1, variableArgs: !1 }; e["'"] = { id: r.OPS.nextLineShowText, numArgs: 1, variableArgs: !1 }; e['"'] = { id: r.OPS.nextLineSetSpacingShowText, numArgs: 3, variableArgs: !1 }; e.d0 = { id: r.OPS.setCharWidth, numArgs: 2, variableArgs: !1 }; e.d1 = { id: r.OPS.setCharWidthAndBounds, numArgs: 6, variableArgs: !1 }; e.CS = { id: r.OPS.setStrokeColorSpace, numArgs: 1, variableArgs: !1 }; e.cs = { id: r.OPS.setFillColorSpace, numArgs: 1, variableArgs: !1 }; e.SC = { id: r.OPS.setStrokeColor, numArgs: 4, variableArgs: !0 }; e.SCN = { id: r.OPS.setStrokeColorN, numArgs: 33, variableArgs: !0 }; e.sc = { id: r.OPS.setFillColor, numArgs: 4, variableArgs: !0 }; e.scn = { id: r.OPS.setFillColorN, numArgs: 33, variableArgs: !0 }; e.G = { id: r.OPS.setStrokeGray, numArgs: 1, variableArgs: !1 }; e.g = { id: r.OPS.setFillGray, numArgs: 1, variableArgs: !1 }; e.RG = { id: r.OPS.setStrokeRGBColor, numArgs: 3, variableArgs: !1 }; e.rg = { id: r.OPS.setFillRGBColor, numArgs: 3, variableArgs: !1 }; e.K = { id: r.OPS.setStrokeCMYKColor, numArgs: 4, variableArgs: !1 }; e.k = { id: r.OPS.setFillCMYKColor, numArgs: 4, variableArgs: !1 }; e.sh = { id: r.OPS.shadingFill, numArgs: 1, variableArgs: !1 }; e.BI = { id: r.OPS.beginInlineImage, numArgs: 0, variableArgs: !1 }; e.ID = { id: r.OPS.beginImageData, numArgs: 0, variableArgs: !1 }; e.EI = { id: r.OPS.endInlineImage, numArgs: 1, variableArgs: !1 }; e.Do = { id: r.OPS.paintXObject, numArgs: 1, variableArgs: !1 }; e.MP = { id: r.OPS.markPoint, numArgs: 1, variableArgs: !1 }; e.DP = { id: r.OPS.markPointProps, numArgs: 2, variableArgs: !1 }; e.BMC = { id: r.OPS.beginMarkedContent, numArgs: 1, variableArgs: !1 }; e.BDC = { id: r.OPS.beginMarkedContentProps, numArgs: 2, variableArgs: !1 }; e.EMC = { id: r.OPS.endMarkedContent, numArgs: 0, variableArgs: !1 }; e.BX = { id: r.OPS.beginCompat, numArgs: 0, variableArgs: !1 }; e.EX = { id: r.OPS.endCompat, numArgs: 0, variableArgs: !1 }; e.BM = null; e.BD = null; e.true = null; e.fa = null; e.fal = null; e.fals = null; e.false = null; e.nu = null; e.nul = null; e.null = null })); function t(t, a, r) { this.opMap = e(); this.parser = new d.Parser({ lexer: new d.Lexer(t, this.opMap), xref: a }); this.stateManager = r; this.nonProcessedArgs = []; this._numInvalidPathOPS = 0 } t.prototype = { get savedStatesDepth() { return this.stateManager.stateStack.length }, read: function (e) { for (var t = e.args; ;) { var a = this.parser.getObj(); if (a instanceof n.Cmd) { var i = a.cmd, s = this.opMap[i]; if (!s) { (0, r.warn)(`Unknown command "${i}".`); continue } var o = s.id, c = s.numArgs, l = null !== t ? t.length : 0; if (s.variableArgs) l > c && (0, r.info)(`Command ${i}: expected [0, ${c}] args, ` + `but received ${l} args.`); else { if (l !== c) { for (var h = this.nonProcessedArgs; l > c;) { h.push(t.shift()); l-- } for (; l < c && 0 !== h.length;) { null === t && (t = []); t.unshift(h.pop()); l++ } } if (l < c) { const e = `command ${i}: expected ${c} args, ` + `but received ${l} args.`; if (o >= r.OPS.moveTo && o <= r.OPS.endPath && ++this._numInvalidPathOPS > 20) throw new r.FormatError(`Invalid ${e}`); (0, r.warn)(`Skipping ${e}`); null !== t && (t.length = 0); continue } } this.preprocessCommand(o, t); e.fn = o; e.args = t; return !0 } if (a === n.EOF) return !1; if (null !== a) { null === t && (t = []); t.push(a); if (t.length > 33) throw new r.FormatError("Too many arguments") } } }, preprocessCommand: function (e, t) { switch (0 | e) { case r.OPS.save: this.stateManager.save(); break; case r.OPS.restore: this.stateManager.restore(); break; case r.OPS.transform: this.stateManager.transform(t) } } }; return t }() }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.CMapFactory = t.IdentityCMap = t.CMap = void 0; var r = a(2), i = a(4), n = a(10), s = a(7), o = a(11), c = ["Adobe-GB1-UCS2", "Adobe-CNS1-UCS2", "Adobe-Japan1-UCS2", "Adobe-Korea1-UCS2", "78-EUC-H", "78-EUC-V", "78-H", "78-RKSJ-H", "78-RKSJ-V", "78-V", "78ms-RKSJ-H", "78ms-RKSJ-V", "83pv-RKSJ-H", "90ms-RKSJ-H", "90ms-RKSJ-V", "90msp-RKSJ-H", "90msp-RKSJ-V", "90pv-RKSJ-H", "90pv-RKSJ-V", "Add-H", "Add-RKSJ-H", "Add-RKSJ-V", "Add-V", "Adobe-CNS1-0", "Adobe-CNS1-1", "Adobe-CNS1-2", "Adobe-CNS1-3", "Adobe-CNS1-4", "Adobe-CNS1-5", "Adobe-CNS1-6", "Adobe-GB1-0", "Adobe-GB1-1", "Adobe-GB1-2", "Adobe-GB1-3", "Adobe-GB1-4", "Adobe-GB1-5", "Adobe-Japan1-0", "Adobe-Japan1-1", "Adobe-Japan1-2", "Adobe-Japan1-3", "Adobe-Japan1-4", "Adobe-Japan1-5", "Adobe-Japan1-6", "Adobe-Korea1-0", "Adobe-Korea1-1", "Adobe-Korea1-2", "B5-H", "B5-V", "B5pc-H", "B5pc-V", "CNS-EUC-H", "CNS-EUC-V", "CNS1-H", "CNS1-V", "CNS2-H", "CNS2-V", "ETHK-B5-H", "ETHK-B5-V", "ETen-B5-H", "ETen-B5-V", "ETenms-B5-H", "ETenms-B5-V", "EUC-H", "EUC-V", "Ext-H", "Ext-RKSJ-H", "Ext-RKSJ-V", "Ext-V", "GB-EUC-H", "GB-EUC-V", "GB-H", "GB-V", "GBK-EUC-H", "GBK-EUC-V", "GBK2K-H", "GBK2K-V", "GBKp-EUC-H", "GBKp-EUC-V", "GBT-EUC-H", "GBT-EUC-V", "GBT-H", "GBT-V", "GBTpc-EUC-H", "GBTpc-EUC-V", "GBpc-EUC-H", "GBpc-EUC-V", "H", "HKdla-B5-H", "HKdla-B5-V", "HKdlb-B5-H", "HKdlb-B5-V", "HKgccs-B5-H", "HKgccs-B5-V", "HKm314-B5-H", "HKm314-B5-V", "HKm471-B5-H", "HKm471-B5-V", "HKscs-B5-H", "HKscs-B5-V", "Hankaku", "Hiragana", "KSC-EUC-H", "KSC-EUC-V", "KSC-H", "KSC-Johab-H", "KSC-Johab-V", "KSC-V", "KSCms-UHC-H", "KSCms-UHC-HW-H", "KSCms-UHC-HW-V", "KSCms-UHC-V", "KSCpc-EUC-H", "KSCpc-EUC-V", "Katakana", "NWP-H", "NWP-V", "RKSJ-H", "RKSJ-V", "Roman", "UniCNS-UCS2-H", "UniCNS-UCS2-V", "UniCNS-UTF16-H", "UniCNS-UTF16-V", "UniCNS-UTF32-H", "UniCNS-UTF32-V", "UniCNS-UTF8-H", "UniCNS-UTF8-V", "UniGB-UCS2-H", "UniGB-UCS2-V", "UniGB-UTF16-H", "UniGB-UTF16-V", "UniGB-UTF32-H", "UniGB-UTF32-V", "UniGB-UTF8-H", "UniGB-UTF8-V", "UniJIS-UCS2-H", "UniJIS-UCS2-HW-H", "UniJIS-UCS2-HW-V", "UniJIS-UCS2-V", "UniJIS-UTF16-H", "UniJIS-UTF16-V", "UniJIS-UTF32-H", "UniJIS-UTF32-V", "UniJIS-UTF8-H", "UniJIS-UTF8-V", "UniJIS2004-UTF16-H", "UniJIS2004-UTF16-V", "UniJIS2004-UTF32-H", "UniJIS2004-UTF32-V", "UniJIS2004-UTF8-H", "UniJIS2004-UTF8-V", "UniJISPro-UCS2-HW-V", "UniJISPro-UCS2-V", "UniJISPro-UTF8-V", "UniJISX0213-UTF32-H", "UniJISX0213-UTF32-V", "UniJISX02132004-UTF32-H", "UniJISX02132004-UTF32-V", "UniKS-UCS2-H", "UniKS-UCS2-V", "UniKS-UTF16-H", "UniKS-UTF16-V", "UniKS-UTF32-H", "UniKS-UTF32-V", "UniKS-UTF8-H", "UniKS-UTF8-V", "V", "WP-Symbol"]; class l { constructor(e = !1) { this.codespaceRanges = [[], [], [], []]; this.numCodespaceRanges = 0; this._map = []; this.name = ""; this.vertical = !1; this.useCMap = null; this.builtInCMap = e } addCodespaceRange(e, t, a) { this.codespaceRanges[e - 1].push(t, a); this.numCodespaceRanges++ } mapCidRange(e, t, a) { for (; e <= t;)this._map[e++] = a++ } mapBfRange(e, t, a) { for (var r = a.length - 1; e <= t;) { this._map[e++] = a; a = a.substring(0, r) + String.fromCharCode(a.charCodeAt(r) + 1) } } mapBfRangeToArray(e, t, a) { const r = a.length; let i = 0; for (; e <= t && i < r;) { this._map[e] = a[i++]; ++e } } mapOne(e, t) { this._map[e] = t } lookup(e) { return this._map[e] } contains(e) { return void 0 !== this._map[e] } forEach(e) { const t = this._map, a = t.length; if (a <= 65536) for (let r = 0; r < a; r++)void 0 !== t[r] && e(r, t[r]); else for (const a in t) e(a, t[a]) } charCodeOf(e) { const t = this._map; if (t.length <= 65536) return t.indexOf(e); for (const a in t) if (t[a] === e) return 0 | a; return -1 } getMap() { return this._map } readCharCode(e, t, a) { let r = 0; const i = this.codespaceRanges; for (let n = 0, s = i.length; n < s; n++) { r = (r << 8 | e.charCodeAt(t + n)) >>> 0; const s = i[n]; for (let e = 0, t = s.length; e < t;) { const t = s[e++], i = s[e++]; if (r >= t && r <= i) { a.charcode = r; a.length = n + 1; return } } } a.charcode = 0; a.length = 1 } get length() { return this._map.length } get isIdentityCMap() { if ("Identity-H" !== this.name && "Identity-V" !== this.name) return !1; if (65536 !== this._map.length) return !1; for (let e = 0; e < 65536; e++)if (this._map[e] !== e) return !1; return !0 } } t.CMap = l; class h extends l { constructor(e, t) { super(); this.vertical = e; this.addCodespaceRange(t, 0, 65535) } mapCidRange(e, t, a) { (0, r.unreachable)("should not call mapCidRange") } mapBfRange(e, t, a) { (0, r.unreachable)("should not call mapBfRange") } mapBfRangeToArray(e, t, a) { (0, r.unreachable)("should not call mapBfRangeToArray") } mapOne(e, t) { (0, r.unreachable)("should not call mapCidOne") } lookup(e) { return Number.isInteger(e) && e <= 65535 ? e : void 0 } contains(e) { return Number.isInteger(e) && e <= 65535 } forEach(e) { for (let t = 0; t <= 65535; t++)e(t, t) } charCodeOf(e) { return Number.isInteger(e) && e <= 65535 ? e : -1 } getMap() { const e = new Array(65536); for (let t = 0; t <= 65535; t++)e[t] = t; return e } get length() { return 65536 } get isIdentityCMap() { (0, r.unreachable)("should not access .isIdentityCMap") } } t.IdentityCMap = h; var u = function () { function e(e, t) { for (var a = 0, r = 0; r <= t; r++)a = a << 8 | e[r]; return a >>> 0 } function t(e, t) { return 1 === t ? String.fromCharCode(e[0], e[1]) : 3 === t ? String.fromCharCode(e[0], e[1], e[2], e[3]) : String.fromCharCode.apply(null, e.subarray(0, t + 1)) } function a(e, t, a) { for (var r = 0, i = a; i >= 0; i--) { r += e[i] + t[i]; e[i] = 255 & r; r >>= 8 } } function i(e, t) { for (var a = 1, r = t; r >= 0 && a > 0; r--) { a += e[r]; e[r] = 255 & a; a >>= 8 } } function n(e) { this.buffer = e; this.pos = 0; this.end = e.length; this.tmpBuf = new Uint8Array(19) } n.prototype = { readByte() { return this.pos >= this.end ? -1 : this.buffer[this.pos++] }, readNumber() { var e, t = 0; do { var a = this.readByte(); if (a < 0) throw new r.FormatError("unexpected EOF in bcmap"); e = !(128 & a); t = t << 7 | 127 & a } while (!e); return t }, readSigned() { var e = this.readNumber(); return 1 & e ? ~(e >>> 1) : e >>> 1 }, readHex(e, t) { e.set(this.buffer.subarray(this.pos, this.pos + t + 1)); this.pos += t + 1 }, readHexNumber(e, t) { var a, i = this.tmpBuf, n = 0; do { var s = this.readByte(); if (s < 0) throw new r.FormatError("unexpected EOF in bcmap"); a = !(128 & s); i[n++] = 127 & s } while (!a); for (var o = t, c = 0, l = 0; o >= 0;) { for (; l < 8 && i.length > 0;) { c = i[--n] << l | c; l += 7 } e[o] = 255 & c; o--; c >>= 8; l -= 8 } }, readHexSigned(e, t) { this.readHexNumber(e, t); for (var a = 1 & e[t] ? 255 : 0, r = 0, i = 0; i <= t; i++) { r = (1 & r) << 8 | e[i]; e[i] = r >> 1 ^ a } }, readString() { for (var e = this.readNumber(), t = "", a = 0; a < e; a++)t += String.fromCharCode(this.readNumber()); return t } }; function s() { } s.prototype = { process: function (r, s, o) { return new Promise((function (c, l) { var h = new n(r), u = h.readByte(); s.vertical = !!(1 & u); for (var d, f, g = null, m = new Uint8Array(16), p = new Uint8Array(16), b = new Uint8Array(16), y = new Uint8Array(16), v = new Uint8Array(16); (f = h.readByte()) >= 0;) { var w = f >> 5; if (7 !== w) { var k = !!(16 & f), S = 15 & f; if (S + 1 > 16) throw new Error("processBinaryCMap: Invalid dataSize."); var C, x = h.readNumber(); switch (w) { case 0: h.readHex(m, S); h.readHexNumber(p, S); a(p, m, S); s.addCodespaceRange(S + 1, e(m, S), e(p, S)); for (C = 1; C < x; C++) { i(p, S); h.readHexNumber(m, S); a(m, p, S); h.readHexNumber(p, S); a(p, m, S); s.addCodespaceRange(S + 1, e(m, S), e(p, S)) } break; case 1: h.readHex(m, S); h.readHexNumber(p, S); a(p, m, S); h.readNumber(); for (C = 1; C < x; C++) { i(p, S); h.readHexNumber(m, S); a(m, p, S); h.readHexNumber(p, S); a(p, m, S); h.readNumber() } break; case 2: h.readHex(b, S); d = h.readNumber(); s.mapOne(e(b, S), d); for (C = 1; C < x; C++) { i(b, S); if (!k) { h.readHexNumber(v, S); a(b, v, S) } d = h.readSigned() + (d + 1); s.mapOne(e(b, S), d) } break; case 3: h.readHex(m, S); h.readHexNumber(p, S); a(p, m, S); d = h.readNumber(); s.mapCidRange(e(m, S), e(p, S), d); for (C = 1; C < x; C++) { i(p, S); if (k) m.set(p); else { h.readHexNumber(m, S); a(m, p, S) } h.readHexNumber(p, S); a(p, m, S); d = h.readNumber(); s.mapCidRange(e(m, S), e(p, S), d) } break; case 4: h.readHex(b, 1); h.readHex(y, S); s.mapOne(e(b, 1), t(y, S)); for (C = 1; C < x; C++) { i(b, 1); if (!k) { h.readHexNumber(v, 1); a(b, v, 1) } i(y, S); h.readHexSigned(v, S); a(y, v, S); s.mapOne(e(b, 1), t(y, S)) } break; case 5: h.readHex(m, 1); h.readHexNumber(p, 1); a(p, m, 1); h.readHex(y, S); s.mapBfRange(e(m, 1), e(p, 1), t(y, S)); for (C = 1; C < x; C++) { i(p, 1); if (k) m.set(p); else { h.readHexNumber(m, 1); a(m, p, 1) } h.readHexNumber(p, 1); a(p, m, 1); h.readHex(y, S); s.mapBfRange(e(m, 1), e(p, 1), t(y, S)) } break; default: l(new Error("processBinaryCMap: Unknown type: " + w)); return } } else switch (31 & f) { case 0: h.readString(); break; case 1: g = h.readString() } } c(g ? o(g) : s) })) } }; return s }(), d = function () { function e(e) { for (var t = 0, a = 0; a < e.length; a++)t = t << 8 | e.charCodeAt(a); return t >>> 0 } function t(e) { if (!(0, r.isString)(e)) throw new r.FormatError("Malformed CMap: expected string.") } function a(e) { if (!Number.isInteger(e)) throw new r.FormatError("Malformed CMap: expected int.") } function d(a, r) { for (; ;) { var n = r.getObj(); if ((0, i.isEOF)(n)) break; if ((0, i.isCmd)(n, "endbfchar")) return; t(n); var s = e(n); t(n = r.getObj()); var o = n; a.mapOne(s, o) } } function f(a, n) { for (; ;) { var s = n.getObj(); if ((0, i.isEOF)(s)) break; if ((0, i.isCmd)(s, "endbfrange")) return; t(s); var o = e(s); t(s = n.getObj()); var c = e(s); s = n.getObj(); if (Number.isInteger(s) || (0, r.isString)(s)) { var l = Number.isInteger(s) ? String.fromCharCode(s) : s; a.mapBfRange(o, c, l) } else { if (!(0, i.isCmd)(s, "[")) break; s = n.getObj(); for (var h = []; !(0, i.isCmd)(s, "]") && !(0, i.isEOF)(s);) { h.push(s); s = n.getObj() } a.mapBfRangeToArray(o, c, h) } } throw new r.FormatError("Invalid bf range.") } function g(r, n) { for (; ;) { var s = n.getObj(); if ((0, i.isEOF)(s)) break; if ((0, i.isCmd)(s, "endcidchar")) return; t(s); var o = e(s); a(s = n.getObj()); var c = s; r.mapOne(o, c) } } function m(r, n) { for (; ;) { var s = n.getObj(); if ((0, i.isEOF)(s)) break; if ((0, i.isCmd)(s, "endcidrange")) return; t(s); var o = e(s); t(s = n.getObj()); var c = e(s); a(s = n.getObj()); var l = s; r.mapCidRange(o, c, l) } } function p(t, a) { for (; ;) { var n = a.getObj(); if ((0, i.isEOF)(n)) break; if ((0, i.isCmd)(n, "endcodespacerange")) return; if (!(0, r.isString)(n)) break; var s = e(n); n = a.getObj(); if (!(0, r.isString)(n)) break; var o = e(n); t.addCodespaceRange(n.length, s, o) } throw new r.FormatError("Invalid codespace range.") } function b(e, t) { var a = t.getObj(); Number.isInteger(a) && (e.vertical = !!a) } function y(e, t) { var a = t.getObj(); (0, i.isName)(a) && (0, r.isString)(a.name) && (e.name = a.name) } function v(e, t, a, n) { var o, c; e: for (; ;)try { var l = t.getObj(); if ((0, i.isEOF)(l)) break; if ((0, i.isName)(l)) { "WMode" === l.name ? b(e, t) : "CMapName" === l.name && y(e, t); o = l } else if ((0, i.isCmd)(l)) switch (l.cmd) { case "endcmap": break e; case "usecmap": (0, i.isName)(o) && (c = o.name); break; case "begincodespacerange": p(e, t); break; case "beginbfchar": d(e, t); break; case "begincidchar": g(e, t); break; case "beginbfrange": f(e, t); break; case "begincidrange": m(e, t) } } catch (e) { if (e instanceof s.MissingDataException) throw e; (0, r.warn)("Invalid cMap data: " + e); continue } !n && c && (n = c); return n ? w(e, a, n) : Promise.resolve(e) } function w(e, t, a) { return k(a, t).then((function (t) { e.useCMap = t; if (0 === e.numCodespaceRanges) { for (var a = e.useCMap.codespaceRanges, r = 0; r < a.length; r++)e.codespaceRanges[r] = a[r].slice(); e.numCodespaceRanges = e.useCMap.numCodespaceRanges } e.useCMap.forEach((function (t, a) { e.contains(t) || e.mapOne(t, e.useCMap.lookup(t)) })); return e })) } function k(e, t) { return "Identity-H" === e ? Promise.resolve(new h(!1, 2)) : "Identity-V" === e ? Promise.resolve(new h(!0, 2)) : c.includes(e) ? t ? t(e).then((function (e) { var a = e.cMapData, i = e.compressionType, s = new l(!0); if (i === r.CMapCompressionType.BINARY) return (new u).process(a, s, (function (e) { return w(s, t, e) })); if (i === r.CMapCompressionType.NONE) { var c = new n.Lexer(new o.Stream(a)); return v(s, c, t, null) } return Promise.reject(new Error("TODO: Only BINARY/NONE CMap compression is currently supported.")) })) : Promise.reject(new Error("Built-in CMap parameters are not provided.")) : Promise.reject(new Error("Unknown CMap name: " + e)) } return { async create(e) { var t = e.encoding, a = e.fetchBuiltInCMap, r = e.useCMap; if ((0, i.isName)(t)) return k(t.name, a); if ((0, i.isStream)(t)) { return v(new l, new n.Lexer(t), a, r).then((function (e) { return e.isIdentityCMap ? k(e.name, a) : e })) } throw new Error("Encoding required.") } } }(); t.CMapFactory = d }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getFontType = y; t.IdentityToUnicodeMap = t.ToUnicodeMap = t.FontFlags = t.Font = t.ErrorFont = t.SEAC_ANALYSIS_ENABLED = void 0; var r = a(2), i = a(28), n = a(31), s = a(30), o = a(32), c = a(33), l = a(7), h = a(34), u = a(26), d = a(11), f = a(35); const g = [[57344, 63743], [1048576, 1114109]]; t.SEAC_ANALYSIS_ENABLED = !0; var m = { FixedPitch: 1, Serif: 2, Symbolic: 4, Script: 8, Nonsymbolic: 32, Italic: 64, AllCap: 65536, SmallCap: 131072, ForceBold: 262144 }; t.FontFlags = m; var p = [".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron", "dcroat"]; function b(e) { if (e.fontMatrix && e.fontMatrix[0] !== r.FONT_IDENTITY_MATRIX[0]) { var t = .001 / e.fontMatrix[0], a = e.widths; for (var i in a) a[i] *= t; e.defaultWidth *= t } } function y(e, t) { switch (e) { case "Type1": return "Type1C" === t ? r.FontType.TYPE1C : r.FontType.TYPE1; case "CIDFontType0": return "CIDFontType0C" === t ? r.FontType.CIDFONTTYPE0C : r.FontType.CIDFONTTYPE0; case "OpenType": return r.FontType.OPENTYPE; case "TrueType": return r.FontType.TRUETYPE; case "CIDFontType2": return r.FontType.CIDFONTTYPE2; case "MMType1": return r.FontType.MMTYPE1; case "Type0": return r.FontType.TYPE0; default: return r.FontType.UNKNOWN } } function v(e, t) { if (void 0 !== t[e]) return e; var a = (0, c.getUnicodeForGlyph)(e, t); if (-1 !== a) for (var i in t) if (t[i] === a) return i; (0, r.info)("Unable to recover a standard glyph name for: " + e); return e } var w = function () { function e(e, t, a, r, i, n, s, o) { this.fontChar = e; this.unicode = t; this.accent = a; this.width = r; this.vmetric = i; this.operatorListId = n; this.isSpace = s; this.isInFont = o } e.prototype.matchesForCache = function (e, t, a, r, i, n, s, o) { return this.fontChar === e && this.unicode === t && this.accent === a && this.width === r && this.vmetric === i && this.operatorListId === n && this.isSpace === s && this.isInFont === o }; return e }(), k = function () { function e(e = []) { this._map = e } e.prototype = { get length() { return this._map.length }, forEach(e) { for (var t in this._map) e(t, this._map[t].charCodeAt(0)) }, has(e) { return void 0 !== this._map[e] }, get(e) { return this._map[e] }, charCodeOf(e) { const t = this._map; if (t.length <= 65536) return t.indexOf(e); for (const a in t) if (t[a] === e) return 0 | a; return -1 }, amend(e) { for (var t in e) this._map[t] = e[t] } }; return e }(); t.ToUnicodeMap = k; var S = function () { function e(e, t) { this.firstChar = e; this.lastChar = t } e.prototype = { get length() { return this.lastChar + 1 - this.firstChar }, forEach(e) { for (var t = this.firstChar, a = this.lastChar; t <= a; t++)e(t, t) }, has(e) { return this.firstChar <= e && e <= this.lastChar }, get(e) { if (this.firstChar <= e && e <= this.lastChar) return String.fromCharCode(e) }, charCodeOf(e) { return Number.isInteger(e) && e >= this.firstChar && e <= this.lastChar ? e : -1 }, amend(e) { (0, r.unreachable)("Should not call amend()") } }; return e }(); t.IdentityToUnicodeMap = S; var C = function () { function e(e, t, a) { e[t] = a >> 8 & 255; e[t + 1] = 255 & a } function t(e, t, a) { e[t] = a >> 24 & 255; e[t + 1] = a >> 16 & 255; e[t + 2] = a >> 8 & 255; e[t + 3] = 255 & a } function a(e, t, a) { var r, i; if (a instanceof Uint8Array) e.set(a, t); else if ("string" == typeof a) for (r = 0, i = a.length; r < i; r++)e[t++] = 255 & a.charCodeAt(r); else for (r = 0, i = a.length; r < i; r++)e[t++] = 255 & a[r] } function i(e) { this.sfnt = e; this.tables = Object.create(null) } i.getSearchParams = function (e, t) { for (var a = 1, r = 0; (a ^ e) > a;) { a <<= 1; r++ } var i = a * t; return { range: i, entry: r, rangeShift: t * e - i } }; i.prototype = { toArray: function () { var n = this.sfnt, s = this.tables, o = Object.keys(s); o.sort(); var c, h, u, d, f, g = o.length, m = 12 + 16 * g, p = [m]; for (c = 0; c < g; c++) { m += ((d = s[o[c]]).length + 3 & -4) >>> 0; p.push(m) } var b = new Uint8Array(m); for (c = 0; c < g; c++) { d = s[o[c]]; a(b, p[c], d) } "true" === n && (n = (0, r.string32)(65536)); b[0] = 255 & n.charCodeAt(0); b[1] = 255 & n.charCodeAt(1); b[2] = 255 & n.charCodeAt(2); b[3] = 255 & n.charCodeAt(3); e(b, 4, g); var y = i.getSearchParams(g, 16); e(b, 6, y.range); e(b, 8, y.entry); e(b, 10, y.rangeShift); m = 12; for (c = 0; c < g; c++) { f = o[c]; b[m] = 255 & f.charCodeAt(0); b[m + 1] = 255 & f.charCodeAt(1); b[m + 2] = 255 & f.charCodeAt(2); b[m + 3] = 255 & f.charCodeAt(3); var v = 0; for (h = p[c], u = p[c + 1]; h < u; h += 4) { v = v + (0, l.readUint32)(b, h) >>> 0 } t(b, m + 4, v); t(b, m + 8, p[c]); t(b, m + 12, s[f].length); m += 16 } return b }, addTable: function (e, t) { if (e in this.tables) throw new Error("Table " + e + " already exists"); this.tables[e] = t } }; return i }(), x = function () { function e(e, t, a) { var i; this.name = e; this.loadedName = a.loadedName; this.isType3Font = a.isType3Font; this.sizes = []; this.missingFile = !1; this.glyphCache = Object.create(null); this.isSerifFont = !!(a.flags & m.Serif); this.isSymbolicFont = !!(a.flags & m.Symbolic); this.isMonospace = !!(a.flags & m.FixedPitch); var n = a.type, s = a.subtype; this.type = n; this.subtype = s; let o = "sans-serif"; this.isMonospace ? o = "monospace" : this.isSerifFont && (o = "serif"); this.fallbackName = o; this.differences = a.differences; this.widths = a.widths; this.defaultWidth = a.defaultWidth; this.composite = a.composite; this.wideChars = a.wideChars; this.cMap = a.cMap; this.ascent = a.ascent / 1e3; this.descent = a.descent / 1e3; this.fontMatrix = a.fontMatrix; this.bbox = a.bbox; this.defaultEncoding = a.defaultEncoding; this.toUnicode = a.toUnicode; this.fallbackToUnicode = a.fallbackToUnicode || new k; this.toFontChar = []; if ("Type3" !== a.type) { this.cidEncoding = a.cidEncoding; this.vertical = a.vertical; if (this.vertical) { this.vmetrics = a.vmetrics; this.defaultVMetrics = a.defaultVMetrics } if (t && !t.isEmpty) { [n, s] = function (e, { type: t, subtype: a, composite: i }) { let n, s; if (function (e) { var t = e.peekBytes(4); return 65536 === (0, l.readUint32)(t, 0) || "true" === (0, r.bytesToString)(t) }(e) || I(e)) n = i ? "CIDFontType2" : "TrueType"; else if (function (e) { var t = e.peekBytes(4); return "OTTO" === (0, r.bytesToString)(t) }(e)) n = i ? "CIDFontType2" : "OpenType"; else if (function (e) { var t = e.peekBytes(2); if (37 === t[0] && 33 === t[1]) return !0; if (128 === t[0] && 1 === t[1]) return !0; return !1 }(e)) n = i ? "CIDFontType0" : "MMType1" === t ? "MMType1" : "Type1"; else if (function (e) { const t = e.peekBytes(4); if (t[0] >= 1 && t[3] >= 1 && t[3] <= 4) return !0; return !1 }(e)) if (i) { n = "CIDFontType0"; s = "CIDFontType0C" } else { n = "MMType1" === t ? "MMType1" : "Type1"; s = "Type1C" } else { (0, r.warn)("getFontFileType: Unable to detect correct font file Type/Subtype."); n = t; s = a } return [n, s] }(t, a); n === this.type && s === this.subtype || (0, r.info)("Inconsistent font file Type/SubType, expected: " + `${this.type}/${this.subtype} but found: ${n}/${s}.`); try { var c; switch (n) { case "MMType1": (0, r.info)("MMType1 font (" + e + "), falling back to Type1."); case "Type1": case "CIDFontType0": this.mimetype = "font/opentype"; var h = "Type1C" === s || "CIDFontType0C" === s ? new T(t, a) : new F(e, t, a); b(a); c = this.convert(e, h, a); break; case "OpenType": case "TrueType": case "CIDFontType2": this.mimetype = "font/opentype"; c = this.checkAndRepair(e, t, a); if (this.isOpenType) { b(a); n = "OpenType" } break; default: throw new r.FormatError(`Font ${n} is not supported`) } } catch (e) { (0, r.warn)(e); this.fallbackToSystemFont(); return } this.data = c; this.fontType = y(n, s); this.fontMatrix = a.fontMatrix; this.widths = a.widths; this.defaultWidth = a.defaultWidth; this.toUnicode = a.toUnicode; this.encoding = a.baseEncoding; this.seacMap = a.seacMap } else { t && (0, r.warn)('Font file is empty in "' + e + '" (' + this.loadedName + ")"); this.fallbackToSystemFont() } } else { for (i = 0; i < 256; i++)this.toFontChar[i] = this.differences[i] || a.defaultEncoding[i]; this.fontType = r.FontType.TYPE3 } } e.getFontID = (t = 1, function () { return String(t++) }); var t; function a(e, t) { return (e << 8) + t } function f(e, t) { var a = (e << 8) + t; return 32768 & a ? a - 65536 : a } function x(e) { return String.fromCharCode(e >> 8 & 255, 255 & e) } function A(e) { e > 32767 ? e = 32767 : e < -32768 && (e = -32768); return String.fromCharCode(e >> 8 & 255, 255 & e) } function I(e) { const t = e.peekBytes(4); return "ttcf" === (0, r.bytesToString)(t) } function E(e, t, a) { for (var r, i = [], n = 0, s = e.length; n < s; n++)-1 !== (r = (0, c.getUnicodeForGlyph)(e[n], t)) && (i[n] = r); for (var o in a) -1 !== (r = (0, c.getUnicodeForGlyph)(a[o], t)) && (i[+o] = r); return i } function O(e, t, a) { var i = Object.create(null), n = [], s = 0, o = g[s][0], c = g[s][1]; for (var l in e) { var h = e[l |= 0]; if (t(h)) { if (o > c) { if (++s >= g.length) { (0, r.warn)("Ran out of space in font private use area."); break } o = g[s][0]; c = g[s][1] } var u = o++; 0 === h && (h = a); i[u] = h; n[l] = u } } return { toFontChar: n, charCodeToGlyphId: i, nextAvailableFontCharCode: o } } function P(e, t) { var a, i, n, s, o = function (e, t) { var a = []; for (var r in e) e[r] >= t || a.push({ fontCharCode: 0 | r, glyphId: e[r] }); 0 === a.length && a.push({ fontCharCode: 0, glyphId: 0 }); a.sort((function (e, t) { return e.fontCharCode - t.fontCharCode })); for (var i = [], n = a.length, s = 0; s < n;) { var o = a[s].fontCharCode, c = [a[s].glyphId]; ++s; for (var l = o; s < n && l + 1 === a[s].fontCharCode;) { c.push(a[s].glyphId); ++s; if (65535 === ++l) break } i.push([o, l, c]) } return i }(e, t), c = o[o.length - 1][1] > 65535 ? 2 : 1, l = "\0\0" + x(c) + "\0\0" + (0, r.string32)(4 + 8 * c); for (a = o.length - 1; a >= 0 && !(o[a][0] <= 65535); --a); var h = a + 1; o[a][0] < 65535 && 65535 === o[a][1] && (o[a][1] = 65534); var u, d, f, g, m = o[a][1] < 65535 ? 1 : 0, p = h + m, b = C.getSearchParams(p, 2), y = "", v = "", w = "", k = "", S = "", A = 0; for (a = 0, i = h; a < i; a++) { d = (u = o[a])[0]; f = u[1]; y += x(d); v += x(f); var I = !0; for (n = 1, s = (g = u[2]).length; n < s; ++n)if (g[n] !== g[n - 1] + 1) { I = !1; break } if (I) { w += x(g[0] - d & 65535); k += x(0) } else { var F = 2 * (p - a) + 2 * A; A += f - d + 1; w += x(0); k += x(F); for (n = 0, s = g.length; n < s; ++n)S += x(g[n]) } } if (m > 0) { v += "ÿÿ"; y += "ÿÿ"; w += "\0"; k += "\0\0" } var T = "\0\0" + x(2 * p) + x(b.range) + x(b.entry) + x(b.rangeShift) + v + "\0\0" + y + w + k + S, E = "", O = ""; if (c > 1) { l += "\0\0\n" + (0, r.string32)(4 + 8 * c + 4 + T.length); E = ""; for (a = 0, i = o.length; a < i; a++) { d = (u = o[a])[0]; var P = (g = u[2])[0]; for (n = 1, s = g.length; n < s; ++n)if (g[n] !== g[n - 1] + 1) { f = u[0] + n - 1; E += (0, r.string32)(d) + (0, r.string32)(f) + (0, r.string32)(P); d = f + 1; P = g[n] } E += (0, r.string32)(d) + (0, r.string32)(u[1]) + (0, r.string32)(P) } O = "\0\f\0\0" + (0, r.string32)(E.length + 16) + "\0\0\0\0" + (0, r.string32)(E.length / 12) } return l + "\0" + x(T.length + 4) + T + O + E } function B(e, t, a) { a = a || { unitsPerEm: 0, yMax: 0, yMin: 0, ascent: 0, descent: 0 }; var i = 0, n = 0, s = 0, o = 0, l = null, h = 0; if (t) { for (var u in t) { (l > (u |= 0) || !l) && (l = u); h < u && (h = u); var d = (0, c.getUnicodeRangeFor)(u); if (d < 32) i |= 1 << d; else if (d < 64) n |= 1 << d - 32; else if (d < 96) s |= 1 << d - 64; else { if (!(d < 123)) throw new r.FormatError("Unicode ranges Bits > 123 are reserved for internal usage"); o |= 1 << d - 96 } } h > 65535 && (h = 65535) } else { l = 0; h = 255 } var f = e.bbox || [0, 0, 0, 0], g = a.unitsPerEm || 1 / (e.fontMatrix || r.FONT_IDENTITY_MATRIX)[0], m = e.ascentScaled ? 1 : g / 1e3, p = a.ascent || Math.round(m * (e.ascent || f[3])), b = a.descent || Math.round(m * (e.descent || f[1])); b > 0 && e.descent > 0 && f[1] < 0 && (b = -b); var y = a.yMax || p, v = -a.yMin || -b; return "\0$ô\0\0\0Š»\0\0\0ŒŠ»\0\0ß\x001\0\0\0\0" + String.fromCharCode(e.fixedPitch ? 9 : 0) + "\0\0\0\0\0\0" + (0, r.string32)(i) + (0, r.string32)(n) + (0, r.string32)(s) + (0, r.string32)(o) + "*21*" + x(e.italicAngle ? 1 : 0) + x(l || e.firstChar) + x(h || e.lastChar) + x(p) + x(b) + "\0d" + x(y) + x(v) + "\0\0\0\0\0\0\0\0" + x(e.xHeight) + x(e.capHeight) + x(0) + x(l || e.firstChar) + "\0" } function D(e) { var t = Math.floor(65536 * e.italicAngle); return "\0\0\0" + (0, r.string32)(t) + "\0\0\0\0" + (0, r.string32)(e.fixedPitch) + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" } function N(e, t) { t || (t = [[], []]); var a, r, i, n, s, o = [t[0][0] || "Original licence", t[0][1] || e, t[0][2] || "Unknown", t[0][3] || "uniqueID", t[0][4] || e, t[0][5] || "Version 0.11", t[0][6] || "", t[0][7] || "Unknown", t[0][8] || "Unknown", t[0][9] || "Unknown"], c = []; for (a = 0, r = o.length; a < r; a++) { var l = []; for (i = 0, n = (s = t[1][a] || o[a]).length; i < n; i++)l.push(x(s.charCodeAt(i))); c.push(l.join("")) } var h = [o, c], u = ["\0", "\0"], d = ["\0\0", "\0"], f = ["\0\0", "\t"], g = o.length * u.length, m = "\0\0" + x(g) + x(12 * g + 6), p = 0; for (a = 0, r = u.length; a < r; a++) { var b = h[a]; for (i = 0, n = b.length; i < n; i++) { s = b[i]; m += u[a] + d[a] + f[a] + x(i) + x(s.length) + x(p); p += s.length } } return m += o.join("") + c.join("") } e.prototype = { name: null, font: null, mimetype: null, encoding: null, disableFontFace: !1, get renderer() { var e = h.FontRendererFactory.create(this, !0); return (0, r.shadow)(this, "renderer", e) }, exportData: function () { var e = {}; for (var t in this) this.hasOwnProperty(t) && (e[t] = this[t]); return e }, fallbackToSystemFont: function () { this.missingFile = !0; var e, t, a = this.name, i = this.type, l = this.subtype; let h = a.replace(/[,_]/g, "-").replace(/\s/g, ""); var u = (0, o.getStdFontMap)(), d = (0, o.getNonStdFontMap)(), f = !!u[h] || !(!d[h] || !u[d[h]]); h = u[h] || d[h] || h; this.bold = -1 !== h.search(/bold/gi); this.italic = -1 !== h.search(/oblique/gi) || -1 !== h.search(/italic/gi); this.black = -1 !== a.search(/Black/g); this.remeasure = Object.keys(this.widths).length > 0; if (f && "CIDFontType2" === i && this.cidEncoding.startsWith("Identity-")) { const t = (0, o.getGlyphMapForStandardFonts)(), r = []; for (e in t) r[+e] = t[e]; if (/Arial-?Black/i.test(a)) { var g = (0, o.getSupplementalGlyphMapForArialBlack)(); for (e in g) r[+e] = g[e] } else if (/Calibri/i.test(a)) { const t = (0, o.getSupplementalGlyphMapForCalibri)(); for (e in t) r[+e] = t[e] } this.toUnicode instanceof S || this.toUnicode.forEach((function (e, t) { r[+e] = t })); this.toFontChar = r; this.toUnicode = new k(r) } else if (/Symbol/i.test(h)) this.toFontChar = E(s.SymbolSetEncoding, (0, n.getGlyphsUnicode)(), this.differences); else if (/Dingbats/i.test(h)) { /Wingdings/i.test(a) && (0, r.warn)("Non-embedded Wingdings font, falling back to ZapfDingbats."); this.toFontChar = E(s.ZapfDingbatsEncoding, (0, n.getDingbatsGlyphsUnicode)(), this.differences) } else if (f) this.toFontChar = E(this.defaultEncoding, (0, n.getGlyphsUnicode)(), this.differences); else { const r = (0, n.getGlyphsUnicode)(), i = []; this.toUnicode.forEach((e, a) => { if (!this.composite) { var n = this.differences[e] || this.defaultEncoding[e]; -1 !== (t = (0, c.getUnicodeForGlyph)(n, r)) && (a = t) } i[+e] = a }); if (this.composite && this.toUnicode instanceof S && /Verdana/i.test(a)) { const t = (0, o.getGlyphMapForStandardFonts)(); for (e in t) i[+e] = t[e] } this.toFontChar = i } this.loadedName = h.split("-")[0]; this.fontType = y(i, l) }, checkAndRepair: function (e, t, o) { const c = ["OS/2", "cmap", "head", "hhea", "hmtx", "maxp", "name", "post", "loca", "glyf", "fpgm", "prep", "cvt ", "CFF "]; function l(e, a) { const r = Object.create(null); r["OS/2"] = null; r.cmap = null; r.head = null; r.hhea = null; r.hmtx = null; r.maxp = null; r.name = null; r.post = null; for (let e = 0; e < a; e++) { const e = h(t); c.includes(e.tag) && (0 !== e.length && (r[e.tag] = e)) } return r } function h(e) { var t = (0, r.bytesToString)(e.getBytes(4)), a = e.getInt32() >>> 0, i = e.getInt32() >>> 0, n = e.getInt32() >>> 0, s = e.pos; e.pos = e.start ? e.start : 0; e.skip(i); var o = e.getBytes(n); e.pos = s; if ("head" === t) { o[8] = o[9] = o[10] = o[11] = 0; o[17] |= 32 } return { tag: t, checksum: a, length: n, offset: i, data: o } } function g(e) { return { version: (0, r.bytesToString)(e.getBytes(4)), numTables: e.getUint16(), searchRange: e.getUint16(), entrySelector: e.getUint16(), rangeShift: e.getUint16() } } function m(e, t, a, r, i, n) { var s = { length: 0, sizeOfInstructions: 0 }; if (a - t <= 12) return s; var o = e.subarray(t, a), c = f(o[0], o[1]); if (c < 0) { !function (e, t, a) { e[t + 1] = a; e[t] = a >>> 8 }(o, 0, c = -1); r.set(o, i); s.length = o.length; return s } var l, h = 10, u = 0; for (l = 0; l < c; l++) { u = (o[h] << 8 | o[h + 1]) + 1; h += 2 } var d = h, g = o[h] << 8 | o[h + 1]; s.sizeOfInstructions = g; var m = h += 2 + g, p = 0; for (l = 0; l < u; l++) { var b = o[h++]; 192 & b && (o[h - 1] = 63 & b); let e = 2; 2 & b ? e = 1 : 16 & b && (e = 0); let t = 2; 4 & b ? t = 1 : 32 & b && (t = 0); const a = e + t; p += a; if (8 & b) { var y = o[h++]; l += y; p += y * a } } if (0 === p) return s; var v = h + p; if (v > o.length) return s; if (!n && g > 0) { r.set(o.subarray(0, d), i); r.set([0, 0], i + d); r.set(o.subarray(m, v), i + d + 2); v -= g; o.length - v > 3 && (v = v + 3 & -4); s.length = v; return s } if (o.length - v > 3) { v = v + 3 & -4; r.set(o.subarray(0, v), i); s.length = v; return s } r.set(o, i); s.length = o.length; return s } function y(e) { var a = (t.start ? t.start : 0) + e.offset; t.pos = a; var i = [[], []], n = e.length, s = a + n; if (0 !== t.getUint16() || n < 6) return i; var o, c, l = t.getUint16(), h = t.getUint16(), u = []; for (o = 0; o < l && t.pos + 12 <= s; o++) { var d = { platform: t.getUint16(), encoding: t.getUint16(), language: t.getUint16(), name: t.getUint16(), length: t.getUint16(), offset: t.getUint16() }; (1 === d.platform && 0 === d.encoding && 0 === d.language || 3 === d.platform && 1 === d.encoding && 1033 === d.language) && u.push(d) } for (o = 0, c = u.length; o < c; o++) { var f = u[o]; if (!(f.length <= 0)) { var g = a + h + f.offset; if (!(g + f.length > s)) { t.pos = g; var m = f.name; if (f.encoding) { for (var p = "", b = 0, y = f.length; b < y; b += 2)p += String.fromCharCode(t.getUint16()); i[1][m] = p } else i[0][m] = (0, r.bytesToString)(t.getBytes(f.length)) } } } return i } var w = [0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, 0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, 0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2]; function k(e, t) { for (var a, i, n, s, o, c = e.data, l = 0, h = 0, u = 0, d = [], f = [], g = [], m = t.tooComplexToFollowFunctions, p = !1, b = 0, y = 0, v = c.length; l < v;) { var k = c[l++]; if (64 === k) { i = c[l++]; if (p || y) l += i; else for (a = 0; a < i; a++)d.push(c[l++]) } else if (65 === k) { i = c[l++]; if (p || y) l += 2 * i; else for (a = 0; a < i; a++) { n = c[l++]; d.push(n << 8 | c[l++]) } } else if (176 == (248 & k)) { i = k - 176 + 1; if (p || y) l += i; else for (a = 0; a < i; a++)d.push(c[l++]) } else if (184 == (248 & k)) { i = k - 184 + 1; if (p || y) l += 2 * i; else for (a = 0; a < i; a++) { n = c[l++]; d.push(n << 8 | c[l++]) } } else if (43 !== k || m) if (44 !== k || m) { if (45 === k) if (p) { p = !1; h = l } else { if (!(o = f.pop())) { (0, r.warn)("TT: ENDF bad stack"); t.hintsValid = !1; return } s = g.pop(); c = o.data; l = o.i; t.functionsStackDeltas[s] = d.length - o.stackTop } else if (137 === k) { if (p || y) { (0, r.warn)("TT: nested IDEFs not allowed"); m = !0 } p = !0; u = l } else if (88 === k) ++b; else if (27 === k) y = b; else if (89 === k) { y === b && (y = 0); --b } else if (28 === k && !p && !y) { var S = d[d.length - 1]; S > 0 && (l += S - 1) } } else { if (p || y) { (0, r.warn)("TT: nested FDEFs not allowed"); m = !0 } p = !0; u = l; s = d.pop(); t.functionsDefined[s] = { data: c, i: l } } else if (!p && !y) { s = d[d.length - 1]; if (isNaN(s)) (0, r.info)("TT: CALL empty stack (or invalid entry)."); else { t.functionsUsed[s] = !0; if (s in t.functionsStackDeltas) { const e = d.length + t.functionsStackDeltas[s]; if (e < 0) { (0, r.warn)("TT: CALL invalid functions stack delta."); t.hintsValid = !1; return } d.length = e } else if (s in t.functionsDefined && !g.includes(s)) { f.push({ data: c, i: l, stackTop: d.length - 1 }); g.push(s); if (!(o = t.functionsDefined[s])) { (0, r.warn)("TT: CALL non-existent function"); t.hintsValid = !1; return } c = o.data; l = o.i } } } if (!p && !y) { let e = 0; k <= 142 ? e = w[k] : k >= 192 && k <= 223 ? e = -1 : k >= 224 && (e = -2); if (k >= 113 && k <= 117) { i = d.pop(); isNaN(i) || (e = 2 * -i) } for (; e < 0 && d.length > 0;) { d.pop(); e++ } for (; e > 0;) { d.push(NaN); e-- } } } t.tooComplexToFollowFunctions = m; var C = [c]; l > c.length && C.push(new Uint8Array(l - c.length)); if (u > h) { (0, r.warn)("TT: complementing a missing function tail"); C.push(new Uint8Array([34, 45])) } !function (e, t) { if (t.length > 1) { var a, r, i = 0; for (a = 0, r = t.length; a < r; a++)i += t[a].length; i = i + 3 & -4; var n = new Uint8Array(i), s = 0; for (a = 0, r = t.length; a < r; a++) { n.set(t[a], s); s += t[a].length } e.data = n; e.length = i } }(e, C) } let S, x, A, F; if (I(t = new d.Stream(new Uint8Array(t.getBytes())))) { const e = function (e, t) { const { numFonts: a, offsetTable: i } = function (e) { const t = (0, r.bytesToString)(e.getBytes(4)); (0, r.assert)("ttcf" === t, "Must be a TrueType Collection font."); const a = e.getUint16(), i = e.getUint16(), n = e.getInt32() >>> 0, s = []; for (let t = 0; t < n; t++)s.push(e.getInt32() >>> 0); const o = { ttcTag: t, majorVersion: a, minorVersion: i, numFonts: n, offsetTable: s }; switch (a) { case 1: return o; case 2: o.dsigTag = e.getInt32() >>> 0; o.dsigLength = e.getInt32() >>> 0; o.dsigOffset = e.getInt32() >>> 0; return o }throw new r.FormatError(`Invalid TrueType Collection majorVersion: ${a}.`) }(e); for (let n = 0; n < a; n++) { e.pos = (e.start || 0) + i[n]; const a = g(e), s = l(0, a.numTables); if (!s.name) throw new r.FormatError('TrueType Collection font must contain a "name" table.'); const o = y(s.name); for (let e = 0, r = o.length; e < r; e++)for (let r = 0, i = o[e].length; r < i; r++) { const i = o[e][r]; if (i && i.replace(/\s/g, "") === t) return { header: a, tables: s } } } throw new r.FormatError(`TrueType Collection does not contain "${t}" font.`) }(t, this.name); S = e.header; x = e.tables } else { S = g(t); x = l(0, S.numTables) } var E = !x["CFF "]; if (E) { if (!x.loca) throw new r.FormatError('Required "loca" table is not found'); if (!x.glyf) { (0, r.warn)('Required "glyf" table is not found -- trying to recover.'); x.glyf = { tag: "glyf", data: new Uint8Array(0) } } this.isOpenType = !1 } else { const t = o.composite && ((o.cidToGidMap || []).length > 0 || !(o.cMap instanceof u.IdentityCMap)); if ("OTTO" === S.version && !t || !x.head || !x.hhea || !x.maxp || !x.post) { F = new d.Stream(x["CFF "].data); A = new T(F, o); b(o); return this.convert(e, A, o) } delete x.glyf; delete x.loca; delete x.fpgm; delete x.prep; delete x["cvt "]; this.isOpenType = !0 } if (!x.maxp) throw new r.FormatError('Required "maxp" table is not found'); t.pos = (t.start || 0) + x.maxp.offset; var M = t.getInt32(); const L = t.getUint16(); let R = L + 1, U = !0; if (R > 65535) { U = !1; R = L; (0, r.warn)("Not enough space in glyfs to duplicate first glyph.") } var q = 0, j = 0; if (M >= 65536 && x.maxp.length >= 22) { t.pos += 8; if (t.getUint16() > 2) { x.maxp.data[14] = 0; x.maxp.data[15] = 2 } t.pos += 4; q = t.getUint16(); t.pos += 4; j = t.getUint16() } x.maxp.data[4] = R >> 8; x.maxp.data[5] = 255 & R; var _ = function (e, t, a, i) { var n = { functionsDefined: [], functionsUsed: [], functionsStackDeltas: [], tooComplexToFollowFunctions: !1, hintsValid: !0 }; e && k(e, n); t && k(t, n); e && function (e, t) { if (!e.tooComplexToFollowFunctions) if (e.functionsDefined.length > t) { (0, r.warn)("TT: more functions defined than expected"); e.hintsValid = !1 } else for (var a = 0, i = e.functionsUsed.length; a < i; a++) { if (a > t) { (0, r.warn)("TT: invalid function id: " + a); e.hintsValid = !1; return } if (e.functionsUsed[a] && !e.functionsDefined[a]) { (0, r.warn)("TT: undefined function: " + a); e.hintsValid = !1; return } } }(n, i); if (a && 1 & a.length) { var s = new Uint8Array(a.length + 1); s.set(a.data); a.data = s } return n.hintsValid }(x.fpgm, x.prep, x["cvt "], q); if (!_) { delete x.fpgm; delete x.prep; delete x["cvt "] } !function (e, t, a, i, n) { if (t) { e.pos = (e.start ? e.start : 0) + t.offset; e.pos += 4; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 2; e.pos += 8; e.pos += 2; var s = e.getUint16(); if (s > i) { (0, r.info)("The numOfMetrics (" + s + ") should not be greater than the numGlyphs (" + i + ")"); s = i; t.data[34] = (65280 & s) >> 8; t.data[35] = 255 & s } var o = i - s - (a.length - 4 * s >> 1); if (o > 0) { var c = new Uint8Array(a.length + 2 * o); c.set(a.data); if (n) { c[a.length] = a.data[2]; c[a.length + 1] = a.data[3] } a.data = c } } else a && (a.data = null) }(t, x.hhea, x.hmtx, R, U); if (!x.head) throw new r.FormatError('Required "head" table is not found'); !function (e, t, i) { var n, s, o, c, l = e.data, h = (n = l[0], s = l[1], o = l[2], c = l[3], (n << 24) + (s << 16) + (o << 8) + c); if (h >> 16 != 1) { (0, r.info)("Attempting to fix invalid version in head table: " + h); l[0] = 0; l[1] = 1; l[2] = 0; l[3] = 0 } var u = a(l[50], l[51]); if (u < 0 || u > 1) { (0, r.info)("Attempting to fix invalid indexToLocFormat in head table: " + u); var d = t + 1; if (i === d << 1) { l[50] = 0; l[51] = 0 } else { if (i !== d << 2) throw new r.FormatError("Could not fix indexToLocFormat: " + u); l[50] = 0; l[51] = 1 } } }(x.head, L, E ? x.loca.length : 0); var z = Object.create(null); if (E) { var H = a(x.head.data[50], x.head.data[51]), G = function (e, t, a, r, i, n, s) { var o, c, l; if (r) { o = 4; c = function (e, t) { return e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3] }; l = function (e, t, a) { e[t] = a >>> 24 & 255; e[t + 1] = a >> 16 & 255; e[t + 2] = a >> 8 & 255; e[t + 3] = 255 & a } } else { o = 2; c = function (e, t) { return e[t] << 9 | e[t + 1] << 1 }; l = function (e, t, a) { e[t] = a >> 9 & 255; e[t + 1] = a >> 1 & 255 } } var h = n ? a + 1 : a, u = o * (1 + h), d = new Uint8Array(u); d.set(e.data.subarray(0, u)); e.data = d; var f, g, p = t.data, b = p.length, y = new Uint8Array(b), v = c(d, 0), w = 0, k = Object.create(null); l(d, 0, w); for (f = 0, g = o; f < a; f++, g += o) { var S = c(d, g); 0 === S && (S = v); S > b && (b + 3 & -4) === S && (S = b); S > b && (v = S); var C = m(p, v, S, y, w, i), x = C.length; 0 === x && (k[f] = !0); C.sizeOfInstructions > s && (s = C.sizeOfInstructions); l(d, g, w += x); v = S } if (0 === w) { var A = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]); for (f = 0, g = o; f < h; f++, g += o)l(d, g, A.length); t.data = A } else if (n) { var I = c(d, o); if (y.length > I + w) t.data = y.subarray(0, I + w); else { t.data = new Uint8Array(I + w); t.data.set(y.subarray(0, w)) } t.data.set(y.subarray(0, I), w); l(e.data, d.length - o, w + I) } else t.data = y.subarray(0, w); return { missingGlyphs: k, maxSizeOfInstructions: s } }(x.loca, x.glyf, L, H, _, U, j); z = G.missingGlyphs; if (M >= 65536 && x.maxp.length >= 22) { x.maxp.data[26] = G.maxSizeOfInstructions >> 8; x.maxp.data[27] = 255 & G.maxSizeOfInstructions } } if (!x.hhea) throw new r.FormatError('Required "hhea" table is not found'); if (0 === x.hhea.data[10] && 0 === x.hhea.data[11]) { x.hhea.data[10] = 255; x.hhea.data[11] = 255 } var W = { unitsPerEm: a(x.head.data[18], x.head.data[19]), yMax: a(x.head.data[42], x.head.data[43]), yMin: f(x.head.data[38], x.head.data[39]), ascent: a(x.hhea.data[4], x.hhea.data[5]), descent: f(x.hhea.data[6], x.hhea.data[7]) }; this.ascent = W.ascent / W.unitsPerEm; this.descent = W.descent / W.unitsPerEm; x.post && function (e, a, i) { var n = (t.start ? t.start : 0) + e.offset; t.pos = n; var s, o = n + e.length, c = t.getInt32(); t.getBytes(28); var l, h = !0; switch (c) { case 65536: s = p; break; case 131072: var u = t.getUint16(); if (u !== i) { h = !1; break } var d = []; for (l = 0; l < u; ++l) { var f = t.getUint16(); if (f >= 32768) { h = !1; break } d.push(f) } if (!h) break; for (var g = [], m = []; t.pos < o;) { var b = t.getByte(); m.length = b; for (l = 0; l < b; ++l)m[l] = String.fromCharCode(t.getByte()); g.push(m.join("")) } s = []; for (l = 0; l < u; ++l) { var y = d[l]; y < 258 ? s.push(p[y]) : s.push(g[y - 258]) } break; case 196608: break; default: (0, r.warn)("Unknown/unsupported post table version " + c); h = !1; a.defaultEncoding && (s = a.defaultEncoding) }a.glyphNames = s }(x.post, o, L); x.post = { tag: "post", data: D(o) }; var X, V = []; function K(e) { return !z[e] } if (o.composite) { var Y = o.cidToGidMap || [], $ = 0 === Y.length; o.cMap.forEach((function (e, t) { if (t > 65535) throw new r.FormatError("Max size of CID is 65,535"); var a = -1; $ ? a = t : void 0 !== Y[t] && (a = Y[t]); a >= 0 && a < L && K(a) && (V[e] = a) })) } else { var J = function (e, t, a, i) { if (!e) { (0, r.warn)("No cmap table available."); return { platformId: -1, encodingId: -1, mappings: [], hasShortCmap: !1 } } var n, s = (t.start ? t.start : 0) + e.offset; t.pos = s; t.getUint16(); for (var o, c = t.getUint16(), l = !1, h = 0; h < c; h++) { var u = t.getUint16(), d = t.getUint16(), f = t.getInt32() >>> 0, g = !1; if (!o || o.platformId !== u || o.encodingId !== d) { if (0 === u && 0 === d) g = !0; else if (1 === u && 0 === d) g = !0; else if (3 !== u || 1 !== d || !i && o) { if (a && 3 === u && 0 === d) { g = !0; l = !0 } } else { g = !0; a || (l = !0) } g && (o = { platformId: u, encodingId: d, offset: f }); if (l) break } } o && (t.pos = s + o.offset); if (!o || -1 === t.peekByte()) { (0, r.warn)("Could not find a preferred cmap table."); return { platformId: -1, encodingId: -1, mappings: [], hasShortCmap: !1 } } var m = t.getUint16(); t.getUint16(); t.getUint16(); var p, b, y = !1, v = []; if (0 === m) { for (p = 0; p < 256; p++) { var w = t.getByte(); w && v.push({ charCode: p, glyphId: w }) } y = !0 } else if (4 === m) { var k = t.getUint16() >> 1; t.getBytes(6); var S, C = []; for (S = 0; S < k; S++)C.push({ end: t.getUint16() }); t.getUint16(); for (S = 0; S < k; S++)C[S].start = t.getUint16(); for (S = 0; S < k; S++)C[S].delta = t.getUint16(); var x = 0; for (S = 0; S < k; S++) { n = C[S]; var A = t.getUint16(); if (A) { var I = (A >> 1) - (k - S); n.offsetIndex = I; x = Math.max(x, I + n.end - n.start + 1) } else n.offsetIndex = -1 } var F = []; for (p = 0; p < x; p++)F.push(t.getUint16()); for (S = 0; S < k; S++) { s = (n = C[S]).start; var T = n.end, E = n.delta; I = n.offsetIndex; for (p = s; p <= T; p++)if (65535 !== p) { b = (b = I < 0 ? p : F[I + p - s]) + E & 65535; v.push({ charCode: p, glyphId: b }) } } } else { if (6 !== m) { (0, r.warn)("cmap table has unsupported format: " + m); return { platformId: -1, encodingId: -1, mappings: [], hasShortCmap: !1 } } var O = t.getUint16(), P = t.getUint16(); for (p = 0; p < P; p++) { b = t.getUint16(); var B = O + p; v.push({ charCode: B, glyphId: b }) } } v.sort((function (e, t) { return e.charCode - t.charCode })); for (h = 1; h < v.length; h++)if (v[h - 1].charCode === v[h].charCode) { v.splice(h, 1); h-- } return { platformId: o.platformId, encodingId: o.encodingId, mappings: v, hasShortCmap: y } }(x.cmap, t, this.isSymbolicFont, o.hasEncoding), Z = J.platformId, Q = J.encodingId, ee = J.mappings, te = ee.length; if (o.hasEncoding && (3 === Z && 1 === Q || 1 === Z && 0 === Q) || -1 === Z && -1 === Q && (0, s.getEncoding)(o.baseEncodingName)) { var ae = []; "MacRomanEncoding" !== o.baseEncodingName && "WinAnsiEncoding" !== o.baseEncodingName || (ae = (0, s.getEncoding)(o.baseEncodingName)); var re = (0, n.getGlyphsUnicode)(); for (X = 0; X < 256; X++) { var ie, ne; if (ie = this.differences && X in this.differences ? this.differences[X] : X in ae && "" !== ae[X] ? ae[X] : s.StandardEncoding[X]) { ne = v(ie, re); var se; 3 === Z && 1 === Q ? se = re[ne] : 1 === Z && 0 === Q && (se = s.MacRomanEncoding.indexOf(ne)); var oe = !1; for (let e = 0; e < te; ++e)if (ee[e].charCode === se) { V[X] = ee[e].glyphId; oe = !0; break } if (!oe && o.glyphNames) { var ce = o.glyphNames.indexOf(ie); -1 === ce && ne !== ie && (ce = o.glyphNames.indexOf(ne)); ce > 0 && K(ce) && (V[X] = ce) } } } } else if (0 === Z && 0 === Q) for (let e = 0; e < te; ++e)V[ee[e].charCode] = ee[e].glyphId; else for (let e = 0; e < te; ++e) { X = ee[e].charCode; 3 === Z && X >= 61440 && X <= 61695 && (X &= 255); V[X] = ee[e].glyphId } } 0 === V.length && (V[0] = 0); let le = R - 1; U || (le = 0); var he = O(V, K, le); this.toFontChar = he.toFontChar; x.cmap = { tag: "cmap", data: P(he.charCodeToGlyphId, R) }; x["OS/2"] && function (e) { var t = new d.Stream(e.data), a = t.getUint16(); t.getBytes(60); var r = t.getUint16(); if (a < 4 && 768 & r) return !1; if (t.getUint16() > t.getUint16()) return !1; t.getBytes(6); if (0 === t.getUint16()) return !1; e.data[8] = e.data[9] = 0; return !0 }(x["OS/2"]) || (x["OS/2"] = { tag: "OS/2", data: B(o, he.charCodeToGlyphId, W) }); if (!E) try { F = new d.Stream(x["CFF "].data); A = new i.CFFParser(F, o, !0).parse(); A.duplicateFirstGlyph(); var ue = new i.CFFCompiler(A); x["CFF "].data = ue.compile() } catch (e) { (0, r.warn)("Failed to compile font " + o.loadedName) } if (x.name) { var de = y(x.name); x.name.data = N(e, de) } else x.name = { tag: "name", data: N(this.name) }; var fe = new C(S.version); for (var ge in x) fe.addTable(ge, x[ge].data); return fe.toArray() }, convert: function (e, t, a) { a.fixedPitch = !1; a.builtInEncoding && function (e, t) { if (!e.hasIncludedToUnicodeMap && !(e.hasEncoding || t === e.defaultEncoding || e.toUnicode instanceof S)) { var a = [], r = (0, n.getGlyphsUnicode)(); for (var i in t) { var s = t[i], o = (0, c.getUnicodeForGlyph)(s, r); -1 !== o && (a[i] = String.fromCharCode(o)) } e.toUnicode.amend(a) } }(a, a.builtInEncoding); let i = 1; t instanceof T && (i = t.numGlyphs - 1); var o = t.getGlyphMapping(a), l = O(o, t.hasGlyphId.bind(t), i); this.toFontChar = l.toFontChar; var h = t.numGlyphs; function u(e, t) { var a = null; for (var r in e) if (t === e[r]) { a || (a = []); a.push(0 | r) } return a } function d(e, t) { for (var a in e) if (t === e[a]) return 0 | a; l.charCodeToGlyphId[l.nextAvailableFontCharCode] = t; return l.nextAvailableFontCharCode++ } var f = t.seacs; if (f && f.length) { var g = a.fontMatrix || r.FONT_IDENTITY_MATRIX, m = t.getCharset(), p = Object.create(null); for (var b in f) { var y = f[b |= 0], v = s.StandardEncoding[y[2]], w = s.StandardEncoding[y[3]], k = m.indexOf(v), I = m.indexOf(w); if (!(k < 0 || I < 0)) { var F = { x: y[0] * g[0] + y[1] * g[2] + g[4], y: y[0] * g[1] + y[1] * g[3] + g[5] }, E = u(o, b); if (E) for (var M = 0, L = E.length; M < L; M++) { var R = E[M], U = l.charCodeToGlyphId, q = d(U, k), j = d(U, I); p[R] = { baseFontCharCode: q, accentFontCharCode: j, accentOffset: F } } } } a.seacMap = p } var _ = 1 / (a.fontMatrix || r.FONT_IDENTITY_MATRIX)[0], z = new C("OTTO"); z.addTable("CFF ", t.data); z.addTable("OS/2", B(a, l.charCodeToGlyphId)); z.addTable("cmap", P(l.charCodeToGlyphId, h)); z.addTable("head", "\0\0\0\0\0\0\0\0\0\0_<õ\0\0" + A(_) + "\0\0\0\0ž\v~'\0\0\0\0ž\v~'\0\0" + A(a.descent) + "ÿ" + A(a.ascent) + x(a.italicAngle ? 2 : 0) + "\0\0\0\0\0\0\0"); z.addTable("hhea", "\0\0\0" + A(a.ascent) + A(a.descent) + "\0\0ÿÿ\0\0\0\0\0\0" + A(a.capHeight) + A(Math.tan(a.italicAngle) * a.xHeight) + "\0\0\0\0\0\0\0\0\0\0\0\0" + x(h)); z.addTable("hmtx", function () { for (var e = t.charstrings, a = t.cff ? t.cff.widths : null, r = "\0\0\0\0", i = 1, n = h; i < n; i++) { var s = 0; if (e) { var o = e[i - 1]; s = "width" in o ? o.width : 0 } else a && (s = Math.ceil(a[i] || 0)); r += x(s) + x(0) } return r }()); z.addTable("maxp", "\0\0P\0" + x(h)); z.addTable("name", N(e)); z.addTable("post", D(a)); return z.toArray() }, get spaceWidth() { if ("_shadowWidth" in this) return this._shadowWidth; for (var e, t = ["space", "minus", "one", "i", "I"], a = 0, r = t.length; a < r; a++) { var i = t[a]; if (i in this.widths) { e = this.widths[i]; break } var s = (0, n.getGlyphsUnicode)()[i], o = 0; this.composite && this.cMap.contains(s) && (o = this.cMap.lookup(s)); !o && this.toUnicode && (o = this.toUnicode.charCodeOf(s)); o <= 0 && (o = s); if (e = this.widths[o]) break } e = e || this.defaultWidth; this._shadowWidth = e; return e }, charToGlyph: function (e, t) { var a, i, n, s = e; this.cMap && this.cMap.contains(e) && (s = this.cMap.lookup(e)); i = this.widths[s]; i = (0, r.isNum)(i) ? i : this.defaultWidth; var o = this.vmetrics && this.vmetrics[s]; let l = this.toUnicode.get(e) || this.fallbackToUnicode.get(e) || e; "number" == typeof l && (l = String.fromCharCode(l)); var h = e in this.toFontChar; a = this.toFontChar[e] || e; if (this.missingFile) { const t = this.differences[e] || this.defaultEncoding[e]; ".notdef" !== t && "" !== t || "Type1" !== this.type || (a = 32); a = (0, c.mapSpecialUnicodeValues)(a) } this.isType3Font && (n = a); var u = null; if (this.seacMap && this.seacMap[e]) { h = !0; var d = this.seacMap[e]; a = d.baseFontCharCode; u = { fontChar: String.fromCodePoint(d.accentFontCharCode), offset: d.accentOffset } } var f = "number" == typeof a ? String.fromCodePoint(a) : "", g = this.glyphCache[e]; if (!g || !g.matchesForCache(f, l, u, i, o, n, t, h)) { g = new w(f, l, u, i, o, n, t, h); this.glyphCache[e] = g } return g }, charsToGlyphs: function (e) { var t, a, r, i = this.charsCache; if (i && (t = i[e])) return t; i || (i = this.charsCache = Object.create(null)); t = []; var n, s = e, o = 0; if (this.cMap) for (var c = Object.create(null); o < e.length;) { this.cMap.readCharCode(e, o, c); r = c.charcode; var l = c.length; o += l; var h = 1 === l && 32 === e.charCodeAt(o - 1); a = this.charToGlyph(r, h); t.push(a) } else for (o = 0, n = e.length; o < n; ++o) { r = e.charCodeAt(o); a = this.charToGlyph(r, 32 === r); t.push(a) } return i[s] = t }, get glyphCacheValues() { return Object.values(this.glyphCache) } }; return e }(); t.Font = x; var A = function () { function e(e) { this.error = e; this.loadedName = "g_font_error"; this.missingFile = !0 } e.prototype = { charsToGlyphs: function () { return [] }, exportData: function () { return { error: this.error } } }; return e }(); t.ErrorFont = A; function I(e, t, a) { var r, i, o, c = Object.create(null), l = !!(e.flags & m.Symbolic); if (e.baseEncodingName) { o = (0, s.getEncoding)(e.baseEncodingName); for (i = 0; i < o.length; i++) { r = a.indexOf(o[i]); c[i] = r >= 0 ? r : 0 } } else if (l) for (i in t) c[i] = t[i]; else { o = s.StandardEncoding; for (i = 0; i < o.length; i++) { r = a.indexOf(o[i]); c[i] = r >= 0 ? r : 0 } } var h, u = e.differences; if (u) for (i in u) { var d = u[i]; if (-1 === (r = a.indexOf(d))) { h || (h = (0, n.getGlyphsUnicode)()); var f = v(d, h); f !== d && (r = a.indexOf(f)) } c[i] = r >= 0 ? r : 0 } return c } var F = function () { function e(e, t, a) { for (var r, i = e.length, n = t.length, s = i - n, o = a, c = !1; o < s;) { r = 0; for (; r < n && e[o + r] === t[r];)r++; if (r >= n) { o += r; for (; o < i && (0, l.isWhiteSpace)(e[o]);)o++; c = !0; break } o++ } return { found: c, length: o } } function t(t, a, i) { var n = i.length1, s = (i.length2, a.peekBytes(6)), o = 128 === s[0] && 1 === s[1]; if (o) { a.skip(6); n = s[5] << 24 | s[4] << 16 | s[3] << 8 | s[2] } var c = function (t, a) { var i, n, s, o, c = [101, 101, 120, 101, 99], h = t.pos; try { n = (i = t.getBytes(a)).length } catch (e) { if (e instanceof l.MissingDataException) throw e } if (n === a && (s = e(i, c, a - 2 * c.length)).found && s.length === a) return { stream: new d.Stream(i), length: a }; (0, r.warn)('Invalid "Length1" property in Type1 font -- trying to recover.'); t.pos = h; for (; ;) { if (0 === (s = e(t.peekBytes(2048), c, 0)).length) break; t.pos += s.length; if (s.found) { o = t.pos - h; break } } t.pos = h; if (o) return { stream: new d.Stream(t.getBytes(o)), length: o }; (0, r.warn)('Unable to recover "Length1" property in Type1 font -- using as is.'); return { stream: new d.Stream(t.getBytes(a)), length: a } }(a, n); new f.Type1Parser(c.stream, !1, !0).extractFontHeader(i); o && (s = a.getBytes(6))[5] << 24 | s[4] << 16 | s[3] << 8 | s[2]; var h, u = (h = a.getBytes(), { stream: new d.Stream(h), length: h.length }), g = new f.Type1Parser(u.stream, !0, !0).extractFontProgram(i); for (var m in g.properties) i[m] = g.properties[m]; var p = g.charstrings, b = this.getType2Charstrings(p), y = this.getType2Subrs(g.subrs); this.charstrings = p; this.data = this.wrap(t, b, this.charstrings, y, i); this.seacs = this.getSeacs(g.charstrings) } t.prototype = { get numGlyphs() { return this.charstrings.length + 1 }, getCharset: function () { for (var e = [".notdef"], t = this.charstrings, a = 0; a < t.length; a++)e.push(t[a].glyphName); return e }, getGlyphMapping: function (e) { var t, a = this.charstrings, r = [".notdef"]; for (t = 0; t < a.length; t++)r.push(a[t].glyphName); var i = e.builtInEncoding; if (i) { var n = Object.create(null); for (var s in i) (t = r.indexOf(i[s])) >= 0 && (n[s] = t) } return I(e, n, r) }, hasGlyphId: function (e) { return !(e < 0 || e >= this.numGlyphs) && (0 === e || this.charstrings[e - 1].charstring.length > 0) }, getSeacs: function (e) { var t, a, r = []; for (t = 0, a = e.length; t < a; t++) { var i = e[t]; i.seac && (r[t + 1] = i.seac) } return r }, getType2Charstrings: function (e) { for (var t = [], a = 0, r = e.length; a < r; a++)t.push(e[a].charstring); return t }, getType2Subrs: function (e) { var t = 0, a = e.length; t = a < 1133 ? 107 : a < 33769 ? 1131 : 32768; var r, i = []; for (r = 0; r < t; r++)i.push([11]); for (r = 0; r < a; r++)i.push(e[r]); return i }, wrap: function (e, t, a, r, n) { var s = new i.CFF; s.header = new i.CFFHeader(1, 0, 4, 4); s.names = [e]; var o = new i.CFFTopDict; o.setByName("version", 391); o.setByName("Notice", 392); o.setByName("FullName", 393); o.setByName("FamilyName", 394); o.setByName("Weight", 395); o.setByName("Encoding", null); o.setByName("FontMatrix", n.fontMatrix); o.setByName("FontBBox", n.bbox); o.setByName("charset", null); o.setByName("CharStrings", null); o.setByName("Private", null); s.topDict = o; var c = new i.CFFStrings; c.add("Version 0.11"); c.add("See original notice"); c.add(e); c.add(e); c.add("Medium"); s.strings = c; s.globalSubrIndex = new i.CFFIndex; var l, h, u = t.length, d = [".notdef"]; for (l = 0; l < u; l++) { const e = a[l].glyphName; -1 === i.CFFStandardStrings.indexOf(e) && c.add(e); d.push(e) } s.charset = new i.CFFCharset(!1, 0, d); var f = new i.CFFIndex; f.add([139, 14]); for (l = 0; l < u; l++)f.add(t[l]); s.charStrings = f; var g = new i.CFFPrivateDict; g.setByName("Subrs", null); var m = ["BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StemSnapH", "StemSnapV", "BlueShift", "BlueFuzz", "BlueScale", "LanguageGroup", "ExpansionFactor", "ForceBold", "StdHW", "StdVW"]; for (l = 0, h = m.length; l < h; l++) { var p = m[l]; if (p in n.privateData) { var b = n.privateData[p]; if (Array.isArray(b)) for (var y = b.length - 1; y > 0; y--)b[y] -= b[y - 1]; g.setByName(p, b) } } s.topDict.privateDict = g; var v = new i.CFFIndex; for (l = 0, h = r.length; l < h; l++)v.add(r[l]); g.subrsIndex = v; return new i.CFFCompiler(s).compile() } }; return t }(), T = function () { function e(e, t) { this.properties = t; var a = new i.CFFParser(e, t, !0); this.cff = a.parse(); this.cff.duplicateFirstGlyph(); var n = new i.CFFCompiler(this.cff); this.seacs = this.cff.seacs; try { this.data = n.compile() } catch (a) { (0, r.warn)("Failed to compile font " + t.loadedName); this.data = e } } e.prototype = { get numGlyphs() { return this.cff.charStrings.count }, getCharset: function () { return this.cff.charset.charset }, getGlyphMapping: function () { var e, t, a = this.cff, r = this.properties, i = a.charset.charset; if (r.composite) { e = Object.create(null); let s; if (a.isCIDFont) for (t = 0; t < i.length; t++) { var n = i[t]; s = r.cMap.charCodeOf(n); e[s] = t } else for (t = 0; t < a.charStrings.count; t++) { s = r.cMap.charCodeOf(t); e[s] = t } return e } return e = I(r, a.encoding ? a.encoding.encoding : null, i) }, hasGlyphId: function (e) { return this.cff.hasGlyphId(e) } }; return e }() }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.CFFFDSelect = t.CFFCompiler = t.CFFPrivateDict = t.CFFTopDict = t.CFFCharset = t.CFFIndex = t.CFFStrings = t.CFFHeader = t.CFF = t.CFFParser = t.CFFStandardStrings = void 0; var r = a(2), i = a(29), n = a(30), s = [".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold"]; t.CFFStandardStrings = s; var o = function () { var e = [null, { id: "hstem", min: 2, stackClearing: !0, stem: !0 }, null, { id: "vstem", min: 2, stackClearing: !0, stem: !0 }, { id: "vmoveto", min: 1, stackClearing: !0 }, { id: "rlineto", min: 2, resetStack: !0 }, { id: "hlineto", min: 1, resetStack: !0 }, { id: "vlineto", min: 1, resetStack: !0 }, { id: "rrcurveto", min: 6, resetStack: !0 }, null, { id: "callsubr", min: 1, undefStack: !0 }, { id: "return", min: 0, undefStack: !0 }, null, null, { id: "endchar", min: 0, stackClearing: !0 }, null, null, null, { id: "hstemhm", min: 2, stackClearing: !0, stem: !0 }, { id: "hintmask", min: 0, stackClearing: !0 }, { id: "cntrmask", min: 0, stackClearing: !0 }, { id: "rmoveto", min: 2, stackClearing: !0 }, { id: "hmoveto", min: 1, stackClearing: !0 }, { id: "vstemhm", min: 2, stackClearing: !0, stem: !0 }, { id: "rcurveline", min: 8, resetStack: !0 }, { id: "rlinecurve", min: 8, resetStack: !0 }, { id: "vvcurveto", min: 4, resetStack: !0 }, { id: "hhcurveto", min: 4, resetStack: !0 }, null, { id: "callgsubr", min: 1, undefStack: !0 }, { id: "vhcurveto", min: 4, resetStack: !0 }, { id: "hvcurveto", min: 4, resetStack: !0 }], t = [null, null, null, { id: "and", min: 2, stackDelta: -1 }, { id: "or", min: 2, stackDelta: -1 }, { id: "not", min: 1, stackDelta: 0 }, null, null, null, { id: "abs", min: 1, stackDelta: 0 }, { id: "add", min: 2, stackDelta: -1, stackFn: function (e, t) { e[t - 2] = e[t - 2] + e[t - 1] } }, { id: "sub", min: 2, stackDelta: -1, stackFn: function (e, t) { e[t - 2] = e[t - 2] - e[t - 1] } }, { id: "div", min: 2, stackDelta: -1, stackFn: function (e, t) { e[t - 2] = e[t - 2] / e[t - 1] } }, null, { id: "neg", min: 1, stackDelta: 0, stackFn: function (e, t) { e[t - 1] = -e[t - 1] } }, { id: "eq", min: 2, stackDelta: -1 }, null, null, { id: "drop", min: 1, stackDelta: -1 }, null, { id: "put", min: 2, stackDelta: -2 }, { id: "get", min: 1, stackDelta: 0 }, { id: "ifelse", min: 4, stackDelta: -3 }, { id: "random", min: 0, stackDelta: 1 }, { id: "mul", min: 2, stackDelta: -1, stackFn: function (e, t) { e[t - 2] = e[t - 2] * e[t - 1] } }, null, { id: "sqrt", min: 1, stackDelta: 0 }, { id: "dup", min: 1, stackDelta: 1 }, { id: "exch", min: 2, stackDelta: 0 }, { id: "index", min: 2, stackDelta: 0 }, { id: "roll", min: 3, stackDelta: -2 }, null, null, null, { id: "hflex", min: 7, resetStack: !0 }, { id: "flex", min: 13, resetStack: !0 }, { id: "hflex1", min: 9, resetStack: !0 }, { id: "flex1", min: 11, resetStack: !0 }]; function a(e, t, a) { this.bytes = e.getBytes(); this.properties = t; this.seacAnalysisEnabled = !!a } a.prototype = { parse: function () { var e = this.properties, t = new c; this.cff = t; var a = this.parseHeader(), r = this.parseIndex(a.endPos), i = this.parseIndex(r.endPos), n = this.parseIndex(i.endPos), s = this.parseIndex(n.endPos), o = this.parseDict(i.obj.get(0)), l = this.createDict(f, o, t.strings); t.header = a.obj; t.names = this.parseNameIndex(r.obj); t.strings = this.parseStringIndex(n.obj); t.topDict = l; t.globalSubrIndex = s.obj; this.parsePrivateDict(t.topDict); t.isCIDFont = l.hasName("ROS"); var h = l.getByName("CharStrings"), u = this.parseIndex(h).obj, d = l.getByName("FontMatrix"); d && (e.fontMatrix = d); var g, m, p = l.getByName("FontBBox"); if (p) { e.ascent = Math.max(p[3], p[1]); e.descent = Math.min(p[1], p[3]); e.ascentScaled = !0 } if (t.isCIDFont) { for (var b = this.parseIndex(l.getByName("FDArray")).obj, y = 0, v = b.count; y < v; ++y) { var w = b.get(y), k = this.createDict(f, this.parseDict(w), t.strings); this.parsePrivateDict(k); t.fdArray.push(k) } m = null; g = this.parseCharsets(l.getByName("charset"), u.count, t.strings, !0); t.fdSelect = this.parseFDSelect(l.getByName("FDSelect"), u.count) } else { g = this.parseCharsets(l.getByName("charset"), u.count, t.strings, !1); m = this.parseEncoding(l.getByName("Encoding"), e, t.strings, g.charset) } t.charset = g; t.encoding = m; var S = this.parseCharStrings({ charStrings: u, localSubrIndex: l.privateDict.subrsIndex, globalSubrIndex: s.obj, fdSelect: t.fdSelect, fdArray: t.fdArray, privateDict: l.privateDict }); t.charStrings = S.charStrings; t.seacs = S.seacs; t.widths = S.widths; return t }, parseHeader: function () { for (var e = this.bytes, t = e.length, a = 0; a < t && 1 !== e[a];)++a; if (a >= t) throw new r.FormatError("Invalid CFF header"); if (0 !== a) { (0, r.info)("cff data is shifted"); e = e.subarray(a); this.bytes = e } var i = e[0], n = e[1], s = e[2], o = e[3]; return { obj: new l(i, n, s, o), endPos: s } }, parseDict: function (e) { var t = 0; function a() { var a = e[t++]; if (30 === a) return function () { var a = ""; const r = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "E", "E-", null, "-"]; var i = e.length; for (; t < i;) { var n = e[t++], s = n >> 4, o = 15 & n; if (15 === s) break; a += r[s]; if (15 === o) break; a += r[o] } return parseFloat(a) }(); if (28 === a) return a = ((a = e[t++]) << 24 | e[t++] << 16) >> 16; if (29 === a) return a = (a = (a = (a = e[t++]) << 8 | e[t++]) << 8 | e[t++]) << 8 | e[t++]; if (a >= 32 && a <= 246) return a - 139; if (a >= 247 && a <= 250) return 256 * (a - 247) + e[t++] + 108; if (a >= 251 && a <= 254) return -256 * (a - 251) - e[t++] - 108; (0, r.warn)('CFFParser_parseDict: "' + a + '" is a reserved command.'); return NaN } var i = [], n = []; t = 0; for (var s = e.length; t < s;) { var o = e[t]; if (o <= 21) { 12 === o && (o = o << 8 | e[++t]); n.push([o, i]); i = []; ++t } else i.push(a()) } return n }, parseIndex: function (e) { var t, a, r = new u, i = this.bytes, n = i[e++] << 8 | i[e++], s = [], o = e; if (0 !== n) { var c = i[e++], l = e + (n + 1) * c - 1; for (t = 0, a = n + 1; t < a; ++t) { for (var h = 0, d = 0; d < c; ++d) { h <<= 8; h += i[e++] } s.push(l + h) } o = s[n] } for (t = 0, a = s.length - 1; t < a; ++t) { var f = s[t], g = s[t + 1]; r.add(i.subarray(f, g)) } return { obj: r, endPos: o } }, parseNameIndex: function (e) { for (var t = [], a = 0, i = e.count; a < i; ++a) { var n = e.get(a); t.push((0, r.bytesToString)(n)) } return t }, parseStringIndex: function (e) { for (var t = new h, a = 0, i = e.count; a < i; ++a) { var n = e.get(a); t.add((0, r.bytesToString)(n)) } return t }, createDict: function (e, t, a) { for (var r = new e(a), i = 0, n = t.length; i < n; ++i) { var s = t[i], o = s[0], c = s[1]; r.setByKey(o, c) } return r }, parseCharString: function (a, i, n, s) { if (!i || a.callDepth > 10) return !1; for (var o = a.stackSize, c = a.stack, l = i.length, h = 0; h < l;) { var u = i[h++], d = null; if (12 === u) { var f = i[h++]; if (0 === f) { i[h - 2] = 139; i[h - 1] = 22; o = 0 } else d = t[f] } else if (28 === u) { c[o] = (i[h] << 24 | i[h + 1] << 16) >> 16; h += 2; o++ } else if (14 === u) { if (o >= 4) { o -= 4; if (this.seacAnalysisEnabled) { a.seac = c.slice(o, o + 4); return !1 } } d = e[u] } else if (u >= 32 && u <= 246) { c[o] = u - 139; o++ } else if (u >= 247 && u <= 254) { c[o] = u < 251 ? (u - 247 << 8) + i[h] + 108 : -(u - 251 << 8) - i[h] - 108; h++; o++ } else if (255 === u) { c[o] = (i[h] << 24 | i[h + 1] << 16 | i[h + 2] << 8 | i[h + 3]) / 65536; h += 4; o++ } else if (19 === u || 20 === u) { a.hints += o >> 1; h += a.hints + 7 >> 3; o %= 2; d = e[u] } else { if (10 === u || 29 === u) { var g; if (!(g = 10 === u ? n : s)) { d = e[u]; (0, r.warn)("Missing subrsIndex for " + d.id); return !1 } var m = 32768; g.count < 1240 ? m = 107 : g.count < 33900 && (m = 1131); var p = c[--o] + m; if (p < 0 || p >= g.count || isNaN(p)) { d = e[u]; (0, r.warn)("Out of bounds subrIndex for " + d.id); return !1 } a.stackSize = o; a.callDepth++; if (!this.parseCharString(a, g.get(p), n, s)) return !1; a.callDepth--; o = a.stackSize; continue } if (11 === u) { a.stackSize = o; return !0 } d = e[u] } if (d) { if (d.stem) { a.hints += o >> 1; if (3 === u || 23 === u) a.hasVStems = !0; else if (a.hasVStems && (1 === u || 18 === u)) { (0, r.warn)("CFF stem hints are in wrong order"); i[h - 1] = 1 === u ? 3 : 23 } } if ("min" in d && !a.undefStack && o < d.min) { (0, r.warn)("Not enough parameters for " + d.id + "; actual: " + o + ", expected: " + d.min); return !1 } if (a.firstStackClearing && d.stackClearing) { a.firstStackClearing = !1; (o -= d.min) >= 2 && d.stem ? o %= 2 : o > 1 && (0, r.warn)("Found too many parameters for stack-clearing command"); o > 0 && c[o - 1] >= 0 && (a.width = c[o - 1]) } if ("stackDelta" in d) { "stackFn" in d && d.stackFn(c, o); o += d.stackDelta } else if (d.stackClearing) o = 0; else if (d.resetStack) { o = 0; a.undefStack = !1 } else if (d.undefStack) { o = 0; a.undefStack = !0; a.firstStackClearing = !1 } } } a.stackSize = o; return !0 }, parseCharStrings({ charStrings: e, localSubrIndex: t, globalSubrIndex: a, fdSelect: i, fdArray: n, privateDict: s }) { for (var o = [], c = [], l = e.count, h = 0; h < l; h++) { var u = e.get(h), d = { callDepth: 0, stackSize: 0, stack: [], undefStack: !0, hints: 0, firstStackClearing: !0, seac: null, width: null, hasVStems: !1 }, f = !0, g = null, m = s; if (i && n.length) { var p = i.getFDIndex(h); if (-1 === p) { (0, r.warn)("Glyph index is not in fd select."); f = !1 } if (p >= n.length) { (0, r.warn)("Invalid fd index for glyph index."); f = !1 } f && (g = (m = n[p].privateDict).subrsIndex) } else t && (g = t); f && (f = this.parseCharString(d, u, g, a)); if (null !== d.width) { const e = m.getByName("nominalWidthX"); c[h] = e + d.width } else { const e = m.getByName("defaultWidthX"); c[h] = e } null !== d.seac && (o[h] = d.seac); f || e.set(h, new Uint8Array([14])) } return { charStrings: e, seacs: o, widths: c } }, emptyPrivateDictionary: function (e) { var t = this.createDict(g, [], e.strings); e.setByKey(18, [0, 0]); e.privateDict = t }, parsePrivateDict: function (e) { if (e.hasName("Private")) { var t = e.getByName("Private"); if (Array.isArray(t) && 2 === t.length) { var a = t[0], r = t[1]; if (0 === a || r >= this.bytes.length) this.emptyPrivateDictionary(e); else { var i = r + a, n = this.bytes.subarray(r, i), s = this.parseDict(n), o = this.createDict(g, s, e.strings); e.privateDict = o; if (o.getByName("Subrs")) { var c = o.getByName("Subrs"), l = r + c; if (0 === c || l >= this.bytes.length) this.emptyPrivateDictionary(e); else { var h = this.parseIndex(l); o.subrsIndex = h.obj } } } } else e.removeByName("Private") } else this.emptyPrivateDictionary(e) }, parseCharsets: function (e, t, a, n) { if (0 === e) return new p(!0, m.ISO_ADOBE, i.ISOAdobeCharset); if (1 === e) return new p(!0, m.EXPERT, i.ExpertCharset); if (2 === e) return new p(!0, m.EXPERT_SUBSET, i.ExpertSubsetCharset); var s, o, c, l = this.bytes, h = e, u = l[e++], d = [".notdef"]; t -= 1; switch (u) { case 0: for (c = 0; c < t; c++) { s = l[e++] << 8 | l[e++]; d.push(n ? s : a.get(s)) } break; case 1: for (; d.length <= t;) { s = l[e++] << 8 | l[e++]; o = l[e++]; for (c = 0; c <= o; c++)d.push(n ? s++ : a.get(s++)) } break; case 2: for (; d.length <= t;) { s = l[e++] << 8 | l[e++]; o = l[e++] << 8 | l[e++]; for (c = 0; c <= o; c++)d.push(n ? s++ : a.get(s++)) } break; default: throw new r.FormatError("Unknown charset format") }var f = e, g = l.subarray(h, f); return new p(!1, u, d, g) }, parseEncoding: function (e, t, a, i) { var s, o, c, l = Object.create(null), h = this.bytes, u = !1, d = null; if (0 === e || 1 === e) { u = !0; s = e; var f = e ? n.ExpertEncoding : n.StandardEncoding; for (o = 0, c = i.length; o < c; o++) { var g = f.indexOf(i[o]); -1 !== g && (l[g] = o) } } else { var m = e; switch (127 & (s = h[e++])) { case 0: var p = h[e++]; for (o = 1; o <= p; o++)l[h[e++]] = o; break; case 1: var y = h[e++], v = 1; for (o = 0; o < y; o++)for (var w = h[e++], k = h[e++], S = w; S <= w + k; S++)l[S] = v++; break; default: throw new r.FormatError(`Unknown encoding format: ${s} in CFF`) }var C = e; if (128 & s) { h[m] &= 127; !function () { var t = h[e++]; for (o = 0; o < t; o++) { var r = h[e++], n = (h[e++] << 8) + (255 & h[e++]); l[r] = i.indexOf(a.get(n)) } }() } d = h.subarray(m, C) } return new b(u, s &= 127, l, d) }, parseFDSelect: function (e, t) { var a, i = this.bytes, n = i[e++], s = []; switch (n) { case 0: for (a = 0; a < t; ++a) { var o = i[e++]; s.push(o) } break; case 3: var c = i[e++] << 8 | i[e++]; for (a = 0; a < c; ++a) { var l = i[e++] << 8 | i[e++]; if (0 === a && 0 !== l) { (0, r.warn)("parseFDSelect: The first range must have a first GID of 0 -- trying to recover."); l = 0 } for (var h = i[e++], u = i[e] << 8 | i[e + 1], d = l; d < u; ++d)s.push(h) } e += 2; break; default: throw new r.FormatError(`parseFDSelect: Unknown format "${n}".`) }if (s.length !== t) throw new r.FormatError("parseFDSelect: Invalid font data."); return new y(n, s) } }; return a }(); t.CFFParser = o; var c = function () { function e() { this.header = null; this.names = []; this.topDict = null; this.strings = new h; this.globalSubrIndex = null; this.encoding = null; this.charset = null; this.charStrings = null; this.fdArray = []; this.fdSelect = null; this.isCIDFont = !1 } e.prototype = { duplicateFirstGlyph: function () { if (this.charStrings.count >= 65535) (0, r.warn)("Not enough space in charstrings to duplicate first glyph."); else { var e = this.charStrings.get(0); this.charStrings.add(e); this.isCIDFont && this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0]) } }, hasGlyphId: function (e) { return !(e < 0 || e >= this.charStrings.count) && this.charStrings.get(e).length > 0 } }; return e }(); t.CFF = c; var l = function (e, t, a, r) { this.major = e; this.minor = t; this.hdrSize = a; this.offSize = r }; t.CFFHeader = l; var h = function () { function e() { this.strings = [] } e.prototype = { get: function (e) { return e >= 0 && e <= 390 ? s[e] : e - 391 <= this.strings.length ? this.strings[e - 391] : s[0] }, getSID: function (e) { let t = s.indexOf(e); if (-1 !== t) return t; t = this.strings.indexOf(e); return -1 !== t ? t + 391 : -1 }, add: function (e) { this.strings.push(e) }, get count() { return this.strings.length } }; return e }(); t.CFFStrings = h; var u = function () { function e() { this.objects = []; this.length = 0 } e.prototype = { add: function (e) { this.length += e.length; this.objects.push(e) }, set: function (e, t) { this.length += t.length - this.objects[e].length; this.objects[e] = t }, get: function (e) { return this.objects[e] }, get count() { return this.objects.length } }; return e }(); t.CFFIndex = u; var d = function () { function e(e, t) { this.keyToNameMap = e.keyToNameMap; this.nameToKeyMap = e.nameToKeyMap; this.defaults = e.defaults; this.types = e.types; this.opcodes = e.opcodes; this.order = e.order; this.strings = t; this.values = Object.create(null) } e.prototype = { setByKey: function (e, t) { if (!(e in this.keyToNameMap)) return !1; var a = t.length; if (0 === a) return !0; for (var i = 0; i < a; i++)if (isNaN(t[i])) { (0, r.warn)('Invalid CFFDict value: "' + t + '" for key "' + e + '".'); return !0 } var n = this.types[e]; "num" !== n && "sid" !== n && "offset" !== n || (t = t[0]); this.values[e] = t; return !0 }, setByName: function (e, t) { if (!(e in this.nameToKeyMap)) throw new r.FormatError(`Invalid dictionary name "${e}"`); this.values[this.nameToKeyMap[e]] = t }, hasName: function (e) { return this.nameToKeyMap[e] in this.values }, getByName: function (e) { if (!(e in this.nameToKeyMap)) throw new r.FormatError(`Invalid dictionary name ${e}"`); var t = this.nameToKeyMap[e]; return t in this.values ? this.values[t] : this.defaults[t] }, removeByName: function (e) { delete this.values[this.nameToKeyMap[e]] } }; e.createTables = function (e) { for (var t = { keyToNameMap: {}, nameToKeyMap: {}, defaults: {}, types: {}, opcodes: {}, order: [] }, a = 0, r = e.length; a < r; ++a) { var i = e[a], n = Array.isArray(i[0]) ? (i[0][0] << 8) + i[0][1] : i[0]; t.keyToNameMap[n] = i[1]; t.nameToKeyMap[i[1]] = n; t.types[n] = i[2]; t.defaults[n] = i[3]; t.opcodes[n] = Array.isArray(i[0]) ? i[0] : [i[0]]; t.order.push(n) } return t }; return e }(), f = function () { var e = [[[12, 30], "ROS", ["sid", "sid", "num"], null], [[12, 20], "SyntheticBase", "num", null], [0, "version", "sid", null], [1, "Notice", "sid", null], [[12, 0], "Copyright", "sid", null], [2, "FullName", "sid", null], [3, "FamilyName", "sid", null], [4, "Weight", "sid", null], [[12, 1], "isFixedPitch", "num", 0], [[12, 2], "ItalicAngle", "num", 0], [[12, 3], "UnderlinePosition", "num", -100], [[12, 4], "UnderlineThickness", "num", 50], [[12, 5], "PaintType", "num", 0], [[12, 6], "CharstringType", "num", 2], [[12, 7], "FontMatrix", ["num", "num", "num", "num", "num", "num"], [.001, 0, 0, .001, 0, 0]], [13, "UniqueID", "num", null], [5, "FontBBox", ["num", "num", "num", "num"], [0, 0, 0, 0]], [[12, 8], "StrokeWidth", "num", 0], [14, "XUID", "array", null], [15, "charset", "offset", 0], [16, "Encoding", "offset", 0], [17, "CharStrings", "offset", 0], [18, "Private", ["offset", "offset"], null], [[12, 21], "PostScript", "sid", null], [[12, 22], "BaseFontName", "sid", null], [[12, 23], "BaseFontBlend", "delta", null], [[12, 31], "CIDFontVersion", "num", 0], [[12, 32], "CIDFontRevision", "num", 0], [[12, 33], "CIDFontType", "num", 0], [[12, 34], "CIDCount", "num", 8720], [[12, 35], "UIDBase", "num", null], [[12, 37], "FDSelect", "offset", null], [[12, 36], "FDArray", "offset", null], [[12, 38], "FontName", "sid", null]], t = null; function a(a) { null === t && (t = d.createTables(e)); d.call(this, t, a); this.privateDict = null } a.prototype = Object.create(d.prototype); return a }(); t.CFFTopDict = f; var g = function () { var e = [[6, "BlueValues", "delta", null], [7, "OtherBlues", "delta", null], [8, "FamilyBlues", "delta", null], [9, "FamilyOtherBlues", "delta", null], [[12, 9], "BlueScale", "num", .039625], [[12, 10], "BlueShift", "num", 7], [[12, 11], "BlueFuzz", "num", 1], [10, "StdHW", "num", null], [11, "StdVW", "num", null], [[12, 12], "StemSnapH", "delta", null], [[12, 13], "StemSnapV", "delta", null], [[12, 14], "ForceBold", "num", 0], [[12, 17], "LanguageGroup", "num", 0], [[12, 18], "ExpansionFactor", "num", .06], [[12, 19], "initialRandomSeed", "num", 0], [20, "defaultWidthX", "num", 0], [21, "nominalWidthX", "num", 0], [19, "Subrs", "offset", null]], t = null; function a(a) { null === t && (t = d.createTables(e)); d.call(this, t, a); this.subrsIndex = null } a.prototype = Object.create(d.prototype); return a }(); t.CFFPrivateDict = g; var m = { ISO_ADOBE: 0, EXPERT: 1, EXPERT_SUBSET: 2 }, p = function (e, t, a, r) { this.predefined = e; this.format = t; this.charset = a; this.raw = r }; t.CFFCharset = p; var b = function (e, t, a, r) { this.predefined = e; this.format = t; this.encoding = a; this.raw = r }, y = function () { function e(e, t) { this.format = e; this.fdSelect = t } e.prototype = { getFDIndex: function (e) { return e < 0 || e >= this.fdSelect.length ? -1 : this.fdSelect[e] } }; return e }(); t.CFFFDSelect = y; var v = function () { function e() { this.offsets = Object.create(null) } e.prototype = { isTracking: function (e) { return e in this.offsets }, track: function (e, t) { if (e in this.offsets) throw new r.FormatError(`Already tracking location of ${e}`); this.offsets[e] = t }, offset: function (e) { for (var t in this.offsets) this.offsets[t] += e }, setEntryLocation: function (e, t, a) { if (!(e in this.offsets)) throw new r.FormatError(`Not tracking location of ${e}`); for (var i = a.data, n = this.offsets[e], s = 0, o = t.length; s < o; ++s) { var c = 5 * s + n, l = c + 1, h = c + 2, u = c + 3, d = c + 4; if (29 !== i[c] || 0 !== i[l] || 0 !== i[h] || 0 !== i[u] || 0 !== i[d]) throw new r.FormatError("writing to an offset that is not empty"); var f = t[s]; i[c] = 29; i[l] = f >> 24 & 255; i[h] = f >> 16 & 255; i[u] = f >> 8 & 255; i[d] = 255 & f } } }; return e }(), w = function () { function e(e) { this.cff = e } e.prototype = { compile: function () { var e = this.cff, t = { data: [], length: 0, add: function (e) { this.data = this.data.concat(e); this.length = this.data.length } }, a = this.compileHeader(e.header); t.add(a); var i = this.compileNameIndex(e.names); t.add(i); if (e.isCIDFont && e.topDict.hasName("FontMatrix")) { var n = e.topDict.getByName("FontMatrix"); e.topDict.removeByName("FontMatrix"); for (var s = 0, o = e.fdArray.length; s < o; s++) { var c = e.fdArray[s], l = n.slice(0); c.hasName("FontMatrix") && (l = r.Util.transform(l, c.getByName("FontMatrix"))); c.setByName("FontMatrix", l) } } e.topDict.setByName("charset", 0); var h = this.compileTopDicts([e.topDict], t.length, e.isCIDFont); t.add(h.output); var u = h.trackers[0], d = this.compileStringIndex(e.strings.strings); t.add(d); var f = this.compileIndex(e.globalSubrIndex); t.add(f); if (e.encoding && e.topDict.hasName("Encoding")) if (e.encoding.predefined) u.setEntryLocation("Encoding", [e.encoding.format], t); else { var g = this.compileEncoding(e.encoding); u.setEntryLocation("Encoding", [t.length], t); t.add(g) } var m = this.compileCharset(e.charset, e.charStrings.count, e.strings, e.isCIDFont); u.setEntryLocation("charset", [t.length], t); t.add(m); var p = this.compileCharStrings(e.charStrings); u.setEntryLocation("CharStrings", [t.length], t); t.add(p); if (e.isCIDFont) { u.setEntryLocation("FDSelect", [t.length], t); var b = this.compileFDSelect(e.fdSelect); t.add(b); h = this.compileTopDicts(e.fdArray, t.length, !0); u.setEntryLocation("FDArray", [t.length], t); t.add(h.output); var y = h.trackers; this.compilePrivateDicts(e.fdArray, y, t) } this.compilePrivateDicts([e.topDict], [u], t); t.add([0]); return t.data }, encodeNumber: function (e) { return parseFloat(e) !== parseInt(e, 10) || isNaN(e) ? this.encodeFloat(e) : this.encodeInteger(e) }, encodeFloat: function (e) { var t = e.toString(), a = /\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(t); if (a) { var r = parseFloat("1e" + ((a[2] ? +a[2] : 0) + a[1].length)); t = (Math.round(e * r) / r).toString() } var i, n, s = ""; for (i = 0, n = t.length; i < n; ++i) { var o = t[i]; s += "e" === o ? "-" === t[++i] ? "c" : "b" : "." === o ? "a" : "-" === o ? "e" : o } var c = [30]; for (i = 0, n = (s += 1 & s.length ? "f" : "ff").length; i < n; i += 2)c.push(parseInt(s.substring(i, i + 2), 16)); return c }, encodeInteger: function (e) { return e >= -107 && e <= 107 ? [e + 139] : e >= 108 && e <= 1131 ? [247 + ((e -= 108) >> 8), 255 & e] : e >= -1131 && e <= -108 ? [251 + ((e = -e - 108) >> 8), 255 & e] : e >= -32768 && e <= 32767 ? [28, e >> 8 & 255, 255 & e] : [29, e >> 24 & 255, e >> 16 & 255, e >> 8 & 255, 255 & e] }, compileHeader: function (e) { return [e.major, e.minor, e.hdrSize, e.offSize] }, compileNameIndex: function (e) { for (var t = new u, a = 0, i = e.length; a < i; ++a) { for (var n = e[a], s = Math.min(n.length, 127), o = new Array(s), c = 0; c < s; c++) { var l = n[c]; (l < "!" || l > "~" || "[" === l || "]" === l || "(" === l || ")" === l || "{" === l || "}" === l || "<" === l || ">" === l || "/" === l || "%" === l) && (l = "_"); o[c] = l } "" === (o = o.join("")) && (o = "Bad_Font_Name"); t.add((0, r.stringToBytes)(o)) } return this.compileIndex(t) }, compileTopDicts: function (e, t, a) { for (var r = [], i = new u, n = 0, s = e.length; n < s; ++n) { var o = e[n]; if (a) { o.removeByName("CIDFontVersion"); o.removeByName("CIDFontRevision"); o.removeByName("CIDFontType"); o.removeByName("CIDCount"); o.removeByName("UIDBase") } var c = new v, l = this.compileDict(o, c); r.push(c); i.add(l); c.offset(t) } return { trackers: r, output: i = this.compileIndex(i, r) } }, compilePrivateDicts: function (e, t, a) { for (var i = 0, n = e.length; i < n; ++i) { var s = e[i], o = s.privateDict; if (!o || !s.hasName("Private")) throw new r.FormatError("There must be a private dictionary."); var c = new v, l = this.compileDict(o, c), h = a.length; c.offset(h); l.length || (h = 0); t[i].setEntryLocation("Private", [l.length, h], a); a.add(l); if (o.subrsIndex && o.hasName("Subrs")) { var u = this.compileIndex(o.subrsIndex); c.setEntryLocation("Subrs", [l.length], a); a.add(u) } } }, compileDict: function (e, t) { for (var a = [], i = e.order, n = 0; n < i.length; ++n) { var s = i[n]; if (s in e.values) { var o = e.values[s], c = e.types[s]; Array.isArray(c) || (c = [c]); Array.isArray(o) || (o = [o]); if (0 !== o.length) { for (var l = 0, h = c.length; l < h; ++l) { var u = c[l], d = o[l]; switch (u) { case "num": case "sid": a = a.concat(this.encodeNumber(d)); break; case "offset": var f = e.keyToNameMap[s]; t.isTracking(f) || t.track(f, a.length); a = a.concat([29, 0, 0, 0, 0]); break; case "array": case "delta": a = a.concat(this.encodeNumber(d)); for (var g = 1, m = o.length; g < m; ++g)a = a.concat(this.encodeNumber(o[g])); break; default: throw new r.FormatError(`Unknown data type of ${u}`) } } a = a.concat(e.opcodes[s]) } } } return a }, compileStringIndex: function (e) { for (var t = new u, a = 0, i = e.length; a < i; ++a)t.add((0, r.stringToBytes)(e[a])); return this.compileIndex(t) }, compileGlobalSubrIndex: function () { var e = this.cff.globalSubrIndex; this.out.writeByteArray(this.compileIndex(e)) }, compileCharStrings: function (e) { for (var t = new u, a = 0; a < e.count; a++) { var r = e.get(a); 0 !== r.length ? t.add(r) : t.add(new Uint8Array([139, 14])) } return this.compileIndex(t) }, compileCharset: function (e, t, a, i) { let n; const s = t - 1; if (i) n = new Uint8Array([2, 0, 0, s >> 8 & 255, 255 & s]); else { n = new Uint8Array(1 + 2 * s); n[0] = 0; let t = 0; const i = e.charset.length; let o = !1; for (let s = 1; s < n.length; s += 2) { let c = 0; if (t < i) { const i = e.charset[t++]; c = a.getSID(i); if (-1 === c) { c = 0; if (!o) { o = !0; (0, r.warn)(`Couldn't find ${i} in CFF strings`) } } } n[s] = c >> 8 & 255; n[s + 1] = 255 & c } } return this.compileTypedArray(n) }, compileEncoding: function (e) { return this.compileTypedArray(e.raw) }, compileFDSelect: function (e) { const t = e.format; let a, r; switch (t) { case 0: a = new Uint8Array(1 + e.fdSelect.length); a[0] = t; for (r = 0; r < e.fdSelect.length; r++)a[r + 1] = e.fdSelect[r]; break; case 3: const i = 0; let n = e.fdSelect[0]; const s = [t, 0, 0, i >> 8 & 255, 255 & i, n]; for (r = 1; r < e.fdSelect.length; r++) { const t = e.fdSelect[r]; if (t !== n) { s.push(r >> 8 & 255, 255 & r, t); n = t } } const o = (s.length - 3) / 3; s[1] = o >> 8 & 255; s[2] = 255 & o; s.push(r >> 8 & 255, 255 & r); a = new Uint8Array(s) }return this.compileTypedArray(a) }, compileTypedArray: function (e) { for (var t = [], a = 0, r = e.length; a < r; ++a)t[a] = e[a]; return t }, compileIndex: function (e, t) { t = t || []; var a = e.objects, r = a.length; if (0 === r) return [0, 0, 0]; var i, n, s = [r >> 8 & 255, 255 & r], o = 1; for (i = 0; i < r; ++i)o += a[i].length; n = o < 256 ? 1 : o < 65536 ? 2 : o < 16777216 ? 3 : 4; s.push(n); var c = 1; for (i = 0; i < r + 1; i++) { 1 === n ? s.push(255 & c) : 2 === n ? s.push(c >> 8 & 255, 255 & c) : 3 === n ? s.push(c >> 16 & 255, c >> 8 & 255, 255 & c) : s.push(c >>> 24 & 255, c >> 16 & 255, c >> 8 & 255, 255 & c); a[i] && (c += a[i].length) } for (i = 0; i < r; i++) { t[i] && t[i].offset(s.length); for (var l = 0, h = a[i].length; l < h; l++)s.push(a[i][l]) } return s } }; return e }(); t.CFFCompiler = w }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.ExpertSubsetCharset = t.ExpertCharset = t.ISOAdobeCharset = void 0; t.ISOAdobeCharset = [".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron"]; t.ExpertCharset = [".notdef", "space", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall"]; t.ExpertSubsetCharset = [".notdef", "space", "dollaroldstyle", "dollarsuperior", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "hyphensuperior", "colonmonetary", "onefitted", "rupiah", "centoldstyle", "figuredash", "hypheninferior", "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior"] }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getEncoding = function (e) { switch (e) { case "WinAnsiEncoding": return o; case "StandardEncoding": return s; case "MacRomanEncoding": return n; case "SymbolSetEncoding": return c; case "ZapfDingbatsEncoding": return l; case "ExpertEncoding": return r; case "MacExpertEncoding": return i; default: return null } }; t.ExpertEncoding = t.ZapfDingbatsEncoding = t.SymbolSetEncoding = t.MacRomanEncoding = t.StandardEncoding = t.WinAnsiEncoding = void 0; const r = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclamsmall", "Hungarumlautsmall", "", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "", "", "", "isuperior", "", "", "lsuperior", "msuperior", "nsuperior", "osuperior", "", "", "rsuperior", "ssuperior", "tsuperior", "", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdownsmall", "centoldstyle", "Lslashsmall", "", "", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "", "Dotaccentsmall", "", "", "Macronsmall", "", "", "figuredash", "hypheninferior", "", "", "Ogoneksmall", "Ringsmall", "Cedillasmall", "", "", "", "onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "", "", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall"]; t.ExpertEncoding = r; const i = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclamsmall", "Hungarumlautsmall", "centoldstyle", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "", "threequartersemdash", "", "questionsmall", "", "", "", "", "Ethsmall", "", "", "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "", "", "", "", "", "", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior", "Circumflexsmall", "hypheninferior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "", "", "asuperior", "centsuperior", "", "", "", "", "Aacutesmall", "Agravesmall", "Acircumflexsmall", "Adieresissmall", "Atildesmall", "Aringsmall", "Ccedillasmall", "Eacutesmall", "Egravesmall", "Ecircumflexsmall", "Edieresissmall", "Iacutesmall", "Igravesmall", "Icircumflexsmall", "Idieresissmall", "Ntildesmall", "Oacutesmall", "Ogravesmall", "Ocircumflexsmall", "Odieresissmall", "Otildesmall", "Uacutesmall", "Ugravesmall", "Ucircumflexsmall", "Udieresissmall", "", "eightsuperior", "fourinferior", "threeinferior", "sixinferior", "eightinferior", "seveninferior", "Scaronsmall", "", "centinferior", "twoinferior", "", "Dieresissmall", "", "Caronsmall", "osuperior", "fiveinferior", "", "commainferior", "periodinferior", "Yacutesmall", "", "dollarinferior", "", "", "Thornsmall", "", "nineinferior", "zeroinferior", "Zcaronsmall", "AEsmall", "Oslashsmall", "questiondownsmall", "oneinferior", "Lslashsmall", "", "", "", "", "", "", "Cedillasmall", "", "", "", "", "", "OEsmall", "figuredash", "hyphensuperior", "", "", "", "", "exclamdownsmall", "", "Ydieresissmall", "", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "ninesuperior", "zerosuperior", "", "esuperior", "rsuperior", "tsuperior", "", "", "isuperior", "ssuperior", "dsuperior", "", "", "", "", "", "lsuperior", "Ogoneksmall", "Brevesmall", "Macronsmall", "bsuperior", "nsuperior", "msuperior", "commasuperior", "periodsuperior", "Dotaccentsmall", "Ringsmall", "", "", "", ""], n = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "space", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron"]; t.MacRomanEncoding = n; const s = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "", "endash", "dagger", "daggerdbl", "periodcentered", "", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "", "questiondown", "", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "", "ring", "cedilla", "", "hungarumlaut", "ogonek", "caron", "emdash", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AE", "", "ordfeminine", "", "", "", "", "Lslash", "Oslash", "OE", "ordmasculine", "", "", "", "", "", "ae", "", "", "", "dotlessi", "", "", "lslash", "oslash", "oe", "germandbls", "", "", "", ""]; t.StandardEncoding = s; const o = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "bullet", "Euro", "bullet", "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", "bullet", "Zcaron", "bullet", "bullet", "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", "endash", "emdash", "tilde", "trademark", "scaron", "guilsinglright", "oe", "bullet", "zcaron", "Ydieresis", "space", "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section", "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron", "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered", "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis"]; t.WinAnsiEncoding = o; const c = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "universal", "numbersign", "existential", "percent", "ampersand", "suchthat", "parenleft", "parenright", "asteriskmath", "plus", "comma", "minus", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "congruent", "Alpha", "Beta", "Chi", "Delta", "Epsilon", "Phi", "Gamma", "Eta", "Iota", "theta1", "Kappa", "Lambda", "Mu", "Nu", "Omicron", "Pi", "Theta", "Rho", "Sigma", "Tau", "Upsilon", "sigma1", "Omega", "Xi", "Psi", "Zeta", "bracketleft", "therefore", "bracketright", "perpendicular", "underscore", "radicalex", "alpha", "beta", "chi", "delta", "epsilon", "phi", "gamma", "eta", "iota", "phi1", "kappa", "lambda", "mu", "nu", "omicron", "pi", "theta", "rho", "sigma", "tau", "upsilon", "omega1", "omega", "xi", "psi", "zeta", "braceleft", "bar", "braceright", "similar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Euro", "Upsilon1", "minute", "lessequal", "fraction", "infinity", "florin", "club", "diamond", "heart", "spade", "arrowboth", "arrowleft", "arrowup", "arrowright", "arrowdown", "degree", "plusminus", "second", "greaterequal", "multiply", "proportional", "partialdiff", "bullet", "divide", "notequal", "equivalence", "approxequal", "ellipsis", "arrowvertex", "arrowhorizex", "carriagereturn", "aleph", "Ifraktur", "Rfraktur", "weierstrass", "circlemultiply", "circleplus", "emptyset", "intersection", "union", "propersuperset", "reflexsuperset", "notsubset", "propersubset", "reflexsubset", "element", "notelement", "angle", "gradient", "registerserif", "copyrightserif", "trademarkserif", "product", "radical", "dotmath", "logicalnot", "logicaland", "logicalor", "arrowdblboth", "arrowdblleft", "arrowdblup", "arrowdblright", "arrowdbldown", "lozenge", "angleleft", "registersans", "copyrightsans", "trademarksans", "summation", "parenlefttp", "parenleftex", "parenleftbt", "bracketlefttp", "bracketleftex", "bracketleftbt", "bracelefttp", "braceleftmid", "braceleftbt", "braceex", "", "angleright", "integral", "integraltp", "integralex", "integralbt", "parenrighttp", "parenrightex", "parenrightbt", "bracketrighttp", "bracketrightex", "bracketrightbt", "bracerighttp", "bracerightmid", "bracerightbt", ""]; t.SymbolSetEncoding = c; const l = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", "a118", "a117", "a11", "a12", "a13", "a14", "a15", "a16", "a105", "a17", "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26", "a27", "a28", "a6", "a7", "a8", "a9", "a10", "a29", "a30", "a31", "a32", "a33", "a34", "a35", "a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44", "a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53", "a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62", "a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71", "a72", "a73", "a74", "a203", "a75", "a204", "a76", "a77", "a78", "a79", "a81", "a82", "a83", "a84", "a97", "a98", "a99", "a100", "", "a89", "a90", "a93", "a94", "a91", "a92", "a205", "a85", "a206", "a86", "a87", "a88", "a95", "a96", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "a101", "a102", "a103", "a104", "a106", "a107", "a108", "a112", "a111", "a110", "a109", "a120", "a121", "a122", "a123", "a124", "a125", "a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134", "a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143", "a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152", "a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161", "a163", "a164", "a196", "a165", "a192", "a166", "a167", "a168", "a169", "a170", "a171", "a172", "a173", "a162", "a174", "a175", "a176", "a177", "a178", "a179", "a193", "a180", "a199", "a181", "a200", "a182", "", "a201", "a183", "a184", "a197", "a185", "a194", "a198", "a186", "a195", "a187", "a188", "a189", "a190", "a191", ""]; t.ZapfDingbatsEncoding = l }, function (e, t, a) { var r = a(7).getLookupTableFactory, i = r((function (e) { e.A = 65; e.AE = 198; e.AEacute = 508; e.AEmacron = 482; e.AEsmall = 63462; e.Aacute = 193; e.Aacutesmall = 63457; e.Abreve = 258; e.Abreveacute = 7854; e.Abrevecyrillic = 1232; e.Abrevedotbelow = 7862; e.Abrevegrave = 7856; e.Abrevehookabove = 7858; e.Abrevetilde = 7860; e.Acaron = 461; e.Acircle = 9398; e.Acircumflex = 194; e.Acircumflexacute = 7844; e.Acircumflexdotbelow = 7852; e.Acircumflexgrave = 7846; e.Acircumflexhookabove = 7848; e.Acircumflexsmall = 63458; e.Acircumflextilde = 7850; e.Acute = 63177; e.Acutesmall = 63412; e.Acyrillic = 1040; e.Adblgrave = 512; e.Adieresis = 196; e.Adieresiscyrillic = 1234; e.Adieresismacron = 478; e.Adieresissmall = 63460; e.Adotbelow = 7840; e.Adotmacron = 480; e.Agrave = 192; e.Agravesmall = 63456; e.Ahookabove = 7842; e.Aiecyrillic = 1236; e.Ainvertedbreve = 514; e.Alpha = 913; e.Alphatonos = 902; e.Amacron = 256; e.Amonospace = 65313; e.Aogonek = 260; e.Aring = 197; e.Aringacute = 506; e.Aringbelow = 7680; e.Aringsmall = 63461; e.Asmall = 63329; e.Atilde = 195; e.Atildesmall = 63459; e.Aybarmenian = 1329; e.B = 66; e.Bcircle = 9399; e.Bdotaccent = 7682; e.Bdotbelow = 7684; e.Becyrillic = 1041; e.Benarmenian = 1330; e.Beta = 914; e.Bhook = 385; e.Blinebelow = 7686; e.Bmonospace = 65314; e.Brevesmall = 63220; e.Bsmall = 63330; e.Btopbar = 386; e.C = 67; e.Caarmenian = 1342; e.Cacute = 262; e.Caron = 63178; e.Caronsmall = 63221; e.Ccaron = 268; e.Ccedilla = 199; e.Ccedillaacute = 7688; e.Ccedillasmall = 63463; e.Ccircle = 9400; e.Ccircumflex = 264; e.Cdot = 266; e.Cdotaccent = 266; e.Cedillasmall = 63416; e.Chaarmenian = 1353; e.Cheabkhasiancyrillic = 1212; e.Checyrillic = 1063; e.Chedescenderabkhasiancyrillic = 1214; e.Chedescendercyrillic = 1206; e.Chedieresiscyrillic = 1268; e.Cheharmenian = 1347; e.Chekhakassiancyrillic = 1227; e.Cheverticalstrokecyrillic = 1208; e.Chi = 935; e.Chook = 391; e.Circumflexsmall = 63222; e.Cmonospace = 65315; e.Coarmenian = 1361; e.Csmall = 63331; e.D = 68; e.DZ = 497; e.DZcaron = 452; e.Daarmenian = 1332; e.Dafrican = 393; e.Dcaron = 270; e.Dcedilla = 7696; e.Dcircle = 9401; e.Dcircumflexbelow = 7698; e.Dcroat = 272; e.Ddotaccent = 7690; e.Ddotbelow = 7692; e.Decyrillic = 1044; e.Deicoptic = 1006; e.Delta = 8710; e.Deltagreek = 916; e.Dhook = 394; e.Dieresis = 63179; e.DieresisAcute = 63180; e.DieresisGrave = 63181; e.Dieresissmall = 63400; e.Digammagreek = 988; e.Djecyrillic = 1026; e.Dlinebelow = 7694; e.Dmonospace = 65316; e.Dotaccentsmall = 63223; e.Dslash = 272; e.Dsmall = 63332; e.Dtopbar = 395; e.Dz = 498; e.Dzcaron = 453; e.Dzeabkhasiancyrillic = 1248; e.Dzecyrillic = 1029; e.Dzhecyrillic = 1039; e.E = 69; e.Eacute = 201; e.Eacutesmall = 63465; e.Ebreve = 276; e.Ecaron = 282; e.Ecedillabreve = 7708; e.Echarmenian = 1333; e.Ecircle = 9402; e.Ecircumflex = 202; e.Ecircumflexacute = 7870; e.Ecircumflexbelow = 7704; e.Ecircumflexdotbelow = 7878; e.Ecircumflexgrave = 7872; e.Ecircumflexhookabove = 7874; e.Ecircumflexsmall = 63466; e.Ecircumflextilde = 7876; e.Ecyrillic = 1028; e.Edblgrave = 516; e.Edieresis = 203; e.Edieresissmall = 63467; e.Edot = 278; e.Edotaccent = 278; e.Edotbelow = 7864; e.Efcyrillic = 1060; e.Egrave = 200; e.Egravesmall = 63464; e.Eharmenian = 1335; e.Ehookabove = 7866; e.Eightroman = 8551; e.Einvertedbreve = 518; e.Eiotifiedcyrillic = 1124; e.Elcyrillic = 1051; e.Elevenroman = 8554; e.Emacron = 274; e.Emacronacute = 7702; e.Emacrongrave = 7700; e.Emcyrillic = 1052; e.Emonospace = 65317; e.Encyrillic = 1053; e.Endescendercyrillic = 1186; e.Eng = 330; e.Enghecyrillic = 1188; e.Enhookcyrillic = 1223; e.Eogonek = 280; e.Eopen = 400; e.Epsilon = 917; e.Epsilontonos = 904; e.Ercyrillic = 1056; e.Ereversed = 398; e.Ereversedcyrillic = 1069; e.Escyrillic = 1057; e.Esdescendercyrillic = 1194; e.Esh = 425; e.Esmall = 63333; e.Eta = 919; e.Etarmenian = 1336; e.Etatonos = 905; e.Eth = 208; e.Ethsmall = 63472; e.Etilde = 7868; e.Etildebelow = 7706; e.Euro = 8364; e.Ezh = 439; e.Ezhcaron = 494; e.Ezhreversed = 440; e.F = 70; e.Fcircle = 9403; e.Fdotaccent = 7710; e.Feharmenian = 1366; e.Feicoptic = 996; e.Fhook = 401; e.Fitacyrillic = 1138; e.Fiveroman = 8548; e.Fmonospace = 65318; e.Fourroman = 8547; e.Fsmall = 63334; e.G = 71; e.GBsquare = 13191; e.Gacute = 500; e.Gamma = 915; e.Gammaafrican = 404; e.Gangiacoptic = 1002; e.Gbreve = 286; e.Gcaron = 486; e.Gcedilla = 290; e.Gcircle = 9404; e.Gcircumflex = 284; e.Gcommaaccent = 290; e.Gdot = 288; e.Gdotaccent = 288; e.Gecyrillic = 1043; e.Ghadarmenian = 1346; e.Ghemiddlehookcyrillic = 1172; e.Ghestrokecyrillic = 1170; e.Gheupturncyrillic = 1168; e.Ghook = 403; e.Gimarmenian = 1331; e.Gjecyrillic = 1027; e.Gmacron = 7712; e.Gmonospace = 65319; e.Grave = 63182; e.Gravesmall = 63328; e.Gsmall = 63335; e.Gsmallhook = 667; e.Gstroke = 484; e.H = 72; e.H18533 = 9679; e.H18543 = 9642; e.H18551 = 9643; e.H22073 = 9633; e.HPsquare = 13259; e.Haabkhasiancyrillic = 1192; e.Hadescendercyrillic = 1202; e.Hardsigncyrillic = 1066; e.Hbar = 294; e.Hbrevebelow = 7722; e.Hcedilla = 7720; e.Hcircle = 9405; e.Hcircumflex = 292; e.Hdieresis = 7718; e.Hdotaccent = 7714; e.Hdotbelow = 7716; e.Hmonospace = 65320; e.Hoarmenian = 1344; e.Horicoptic = 1e3; e.Hsmall = 63336; e.Hungarumlaut = 63183; e.Hungarumlautsmall = 63224; e.Hzsquare = 13200; e.I = 73; e.IAcyrillic = 1071; e.IJ = 306; e.IUcyrillic = 1070; e.Iacute = 205; e.Iacutesmall = 63469; e.Ibreve = 300; e.Icaron = 463; e.Icircle = 9406; e.Icircumflex = 206; e.Icircumflexsmall = 63470; e.Icyrillic = 1030; e.Idblgrave = 520; e.Idieresis = 207; e.Idieresisacute = 7726; e.Idieresiscyrillic = 1252; e.Idieresissmall = 63471; e.Idot = 304; e.Idotaccent = 304; e.Idotbelow = 7882; e.Iebrevecyrillic = 1238; e.Iecyrillic = 1045; e.Ifraktur = 8465; e.Igrave = 204; e.Igravesmall = 63468; e.Ihookabove = 7880; e.Iicyrillic = 1048; e.Iinvertedbreve = 522; e.Iishortcyrillic = 1049; e.Imacron = 298; e.Imacroncyrillic = 1250; e.Imonospace = 65321; e.Iniarmenian = 1339; e.Iocyrillic = 1025; e.Iogonek = 302; e.Iota = 921; e.Iotaafrican = 406; e.Iotadieresis = 938; e.Iotatonos = 906; e.Ismall = 63337; e.Istroke = 407; e.Itilde = 296; e.Itildebelow = 7724; e.Izhitsacyrillic = 1140; e.Izhitsadblgravecyrillic = 1142; e.J = 74; e.Jaarmenian = 1345; e.Jcircle = 9407; e.Jcircumflex = 308; e.Jecyrillic = 1032; e.Jheharmenian = 1355; e.Jmonospace = 65322; e.Jsmall = 63338; e.K = 75; e.KBsquare = 13189; e.KKsquare = 13261; e.Kabashkircyrillic = 1184; e.Kacute = 7728; e.Kacyrillic = 1050; e.Kadescendercyrillic = 1178; e.Kahookcyrillic = 1219; e.Kappa = 922; e.Kastrokecyrillic = 1182; e.Kaverticalstrokecyrillic = 1180; e.Kcaron = 488; e.Kcedilla = 310; e.Kcircle = 9408; e.Kcommaaccent = 310; e.Kdotbelow = 7730; e.Keharmenian = 1364; e.Kenarmenian = 1343; e.Khacyrillic = 1061; e.Kheicoptic = 998; e.Khook = 408; e.Kjecyrillic = 1036; e.Klinebelow = 7732; e.Kmonospace = 65323; e.Koppacyrillic = 1152; e.Koppagreek = 990; e.Ksicyrillic = 1134; e.Ksmall = 63339; e.L = 76; e.LJ = 455; e.LL = 63167; e.Lacute = 313; e.Lambda = 923; e.Lcaron = 317; e.Lcedilla = 315; e.Lcircle = 9409; e.Lcircumflexbelow = 7740; e.Lcommaaccent = 315; e.Ldot = 319; e.Ldotaccent = 319; e.Ldotbelow = 7734; e.Ldotbelowmacron = 7736; e.Liwnarmenian = 1340; e.Lj = 456; e.Ljecyrillic = 1033; e.Llinebelow = 7738; e.Lmonospace = 65324; e.Lslash = 321; e.Lslashsmall = 63225; e.Lsmall = 63340; e.M = 77; e.MBsquare = 13190; e.Macron = 63184; e.Macronsmall = 63407; e.Macute = 7742; e.Mcircle = 9410; e.Mdotaccent = 7744; e.Mdotbelow = 7746; e.Menarmenian = 1348; e.Mmonospace = 65325; e.Msmall = 63341; e.Mturned = 412; e.Mu = 924; e.N = 78; e.NJ = 458; e.Nacute = 323; e.Ncaron = 327; e.Ncedilla = 325; e.Ncircle = 9411; e.Ncircumflexbelow = 7754; e.Ncommaaccent = 325; e.Ndotaccent = 7748; e.Ndotbelow = 7750; e.Nhookleft = 413; e.Nineroman = 8552; e.Nj = 459; e.Njecyrillic = 1034; e.Nlinebelow = 7752; e.Nmonospace = 65326; e.Nowarmenian = 1350; e.Nsmall = 63342; e.Ntilde = 209; e.Ntildesmall = 63473; e.Nu = 925; e.O = 79; e.OE = 338; e.OEsmall = 63226; e.Oacute = 211; e.Oacutesmall = 63475; e.Obarredcyrillic = 1256; e.Obarreddieresiscyrillic = 1258; e.Obreve = 334; e.Ocaron = 465; e.Ocenteredtilde = 415; e.Ocircle = 9412; e.Ocircumflex = 212; e.Ocircumflexacute = 7888; e.Ocircumflexdotbelow = 7896; e.Ocircumflexgrave = 7890; e.Ocircumflexhookabove = 7892; e.Ocircumflexsmall = 63476; e.Ocircumflextilde = 7894; e.Ocyrillic = 1054; e.Odblacute = 336; e.Odblgrave = 524; e.Odieresis = 214; e.Odieresiscyrillic = 1254; e.Odieresissmall = 63478; e.Odotbelow = 7884; e.Ogoneksmall = 63227; e.Ograve = 210; e.Ogravesmall = 63474; e.Oharmenian = 1365; e.Ohm = 8486; e.Ohookabove = 7886; e.Ohorn = 416; e.Ohornacute = 7898; e.Ohorndotbelow = 7906; e.Ohorngrave = 7900; e.Ohornhookabove = 7902; e.Ohorntilde = 7904; e.Ohungarumlaut = 336; e.Oi = 418; e.Oinvertedbreve = 526; e.Omacron = 332; e.Omacronacute = 7762; e.Omacrongrave = 7760; e.Omega = 8486; e.Omegacyrillic = 1120; e.Omegagreek = 937; e.Omegaroundcyrillic = 1146; e.Omegatitlocyrillic = 1148; e.Omegatonos = 911; e.Omicron = 927; e.Omicrontonos = 908; e.Omonospace = 65327; e.Oneroman = 8544; e.Oogonek = 490; e.Oogonekmacron = 492; e.Oopen = 390; e.Oslash = 216; e.Oslashacute = 510; e.Oslashsmall = 63480; e.Osmall = 63343; e.Ostrokeacute = 510; e.Otcyrillic = 1150; e.Otilde = 213; e.Otildeacute = 7756; e.Otildedieresis = 7758; e.Otildesmall = 63477; e.P = 80; e.Pacute = 7764; e.Pcircle = 9413; e.Pdotaccent = 7766; e.Pecyrillic = 1055; e.Peharmenian = 1354; e.Pemiddlehookcyrillic = 1190; e.Phi = 934; e.Phook = 420; e.Pi = 928; e.Piwrarmenian = 1363; e.Pmonospace = 65328; e.Psi = 936; e.Psicyrillic = 1136; e.Psmall = 63344; e.Q = 81; e.Qcircle = 9414; e.Qmonospace = 65329; e.Qsmall = 63345; e.R = 82; e.Raarmenian = 1356; e.Racute = 340; e.Rcaron = 344; e.Rcedilla = 342; e.Rcircle = 9415; e.Rcommaaccent = 342; e.Rdblgrave = 528; e.Rdotaccent = 7768; e.Rdotbelow = 7770; e.Rdotbelowmacron = 7772; e.Reharmenian = 1360; e.Rfraktur = 8476; e.Rho = 929; e.Ringsmall = 63228; e.Rinvertedbreve = 530; e.Rlinebelow = 7774; e.Rmonospace = 65330; e.Rsmall = 63346; e.Rsmallinverted = 641; e.Rsmallinvertedsuperior = 694; e.S = 83; e.SF010000 = 9484; e.SF020000 = 9492; e.SF030000 = 9488; e.SF040000 = 9496; e.SF050000 = 9532; e.SF060000 = 9516; e.SF070000 = 9524; e.SF080000 = 9500; e.SF090000 = 9508; e.SF100000 = 9472; e.SF110000 = 9474; e.SF190000 = 9569; e.SF200000 = 9570; e.SF210000 = 9558; e.SF220000 = 9557; e.SF230000 = 9571; e.SF240000 = 9553; e.SF250000 = 9559; e.SF260000 = 9565; e.SF270000 = 9564; e.SF280000 = 9563; e.SF360000 = 9566; e.SF370000 = 9567; e.SF380000 = 9562; e.SF390000 = 9556; e.SF400000 = 9577; e.SF410000 = 9574; e.SF420000 = 9568; e.SF430000 = 9552; e.SF440000 = 9580; e.SF450000 = 9575; e.SF460000 = 9576; e.SF470000 = 9572; e.SF480000 = 9573; e.SF490000 = 9561; e.SF500000 = 9560; e.SF510000 = 9554; e.SF520000 = 9555; e.SF530000 = 9579; e.SF540000 = 9578; e.Sacute = 346; e.Sacutedotaccent = 7780; e.Sampigreek = 992; e.Scaron = 352; e.Scarondotaccent = 7782; e.Scaronsmall = 63229; e.Scedilla = 350; e.Schwa = 399; e.Schwacyrillic = 1240; e.Schwadieresiscyrillic = 1242; e.Scircle = 9416; e.Scircumflex = 348; e.Scommaaccent = 536; e.Sdotaccent = 7776; e.Sdotbelow = 7778; e.Sdotbelowdotaccent = 7784; e.Seharmenian = 1357; e.Sevenroman = 8550; e.Shaarmenian = 1351; e.Shacyrillic = 1064; e.Shchacyrillic = 1065; e.Sheicoptic = 994; e.Shhacyrillic = 1210; e.Shimacoptic = 1004; e.Sigma = 931; e.Sixroman = 8549; e.Smonospace = 65331; e.Softsigncyrillic = 1068; e.Ssmall = 63347; e.Stigmagreek = 986; e.T = 84; e.Tau = 932; e.Tbar = 358; e.Tcaron = 356; e.Tcedilla = 354; e.Tcircle = 9417; e.Tcircumflexbelow = 7792; e.Tcommaaccent = 354; e.Tdotaccent = 7786; e.Tdotbelow = 7788; e.Tecyrillic = 1058; e.Tedescendercyrillic = 1196; e.Tenroman = 8553; e.Tetsecyrillic = 1204; e.Theta = 920; e.Thook = 428; e.Thorn = 222; e.Thornsmall = 63486; e.Threeroman = 8546; e.Tildesmall = 63230; e.Tiwnarmenian = 1359; e.Tlinebelow = 7790; e.Tmonospace = 65332; e.Toarmenian = 1337; e.Tonefive = 444; e.Tonesix = 388; e.Tonetwo = 423; e.Tretroflexhook = 430; e.Tsecyrillic = 1062; e.Tshecyrillic = 1035; e.Tsmall = 63348; e.Twelveroman = 8555; e.Tworoman = 8545; e.U = 85; e.Uacute = 218; e.Uacutesmall = 63482; e.Ubreve = 364; e.Ucaron = 467; e.Ucircle = 9418; e.Ucircumflex = 219; e.Ucircumflexbelow = 7798; e.Ucircumflexsmall = 63483; e.Ucyrillic = 1059; e.Udblacute = 368; e.Udblgrave = 532; e.Udieresis = 220; e.Udieresisacute = 471; e.Udieresisbelow = 7794; e.Udieresiscaron = 473; e.Udieresiscyrillic = 1264; e.Udieresisgrave = 475; e.Udieresismacron = 469; e.Udieresissmall = 63484; e.Udotbelow = 7908; e.Ugrave = 217; e.Ugravesmall = 63481; e.Uhookabove = 7910; e.Uhorn = 431; e.Uhornacute = 7912; e.Uhorndotbelow = 7920; e.Uhorngrave = 7914; e.Uhornhookabove = 7916; e.Uhorntilde = 7918; e.Uhungarumlaut = 368; e.Uhungarumlautcyrillic = 1266; e.Uinvertedbreve = 534; e.Ukcyrillic = 1144; e.Umacron = 362; e.Umacroncyrillic = 1262; e.Umacrondieresis = 7802; e.Umonospace = 65333; e.Uogonek = 370; e.Upsilon = 933; e.Upsilon1 = 978; e.Upsilonacutehooksymbolgreek = 979; e.Upsilonafrican = 433; e.Upsilondieresis = 939; e.Upsilondieresishooksymbolgreek = 980; e.Upsilonhooksymbol = 978; e.Upsilontonos = 910; e.Uring = 366; e.Ushortcyrillic = 1038; e.Usmall = 63349; e.Ustraightcyrillic = 1198; e.Ustraightstrokecyrillic = 1200; e.Utilde = 360; e.Utildeacute = 7800; e.Utildebelow = 7796; e.V = 86; e.Vcircle = 9419; e.Vdotbelow = 7806; e.Vecyrillic = 1042; e.Vewarmenian = 1358; e.Vhook = 434; e.Vmonospace = 65334; e.Voarmenian = 1352; e.Vsmall = 63350; e.Vtilde = 7804; e.W = 87; e.Wacute = 7810; e.Wcircle = 9420; e.Wcircumflex = 372; e.Wdieresis = 7812; e.Wdotaccent = 7814; e.Wdotbelow = 7816; e.Wgrave = 7808; e.Wmonospace = 65335; e.Wsmall = 63351; e.X = 88; e.Xcircle = 9421; e.Xdieresis = 7820; e.Xdotaccent = 7818; e.Xeharmenian = 1341; e.Xi = 926; e.Xmonospace = 65336; e.Xsmall = 63352; e.Y = 89; e.Yacute = 221; e.Yacutesmall = 63485; e.Yatcyrillic = 1122; e.Ycircle = 9422; e.Ycircumflex = 374; e.Ydieresis = 376; e.Ydieresissmall = 63487; e.Ydotaccent = 7822; e.Ydotbelow = 7924; e.Yericyrillic = 1067; e.Yerudieresiscyrillic = 1272; e.Ygrave = 7922; e.Yhook = 435; e.Yhookabove = 7926; e.Yiarmenian = 1349; e.Yicyrillic = 1031; e.Yiwnarmenian = 1362; e.Ymonospace = 65337; e.Ysmall = 63353; e.Ytilde = 7928; e.Yusbigcyrillic = 1130; e.Yusbigiotifiedcyrillic = 1132; e.Yuslittlecyrillic = 1126; e.Yuslittleiotifiedcyrillic = 1128; e.Z = 90; e.Zaarmenian = 1334; e.Zacute = 377; e.Zcaron = 381; e.Zcaronsmall = 63231; e.Zcircle = 9423; e.Zcircumflex = 7824; e.Zdot = 379; e.Zdotaccent = 379; e.Zdotbelow = 7826; e.Zecyrillic = 1047; e.Zedescendercyrillic = 1176; e.Zedieresiscyrillic = 1246; e.Zeta = 918; e.Zhearmenian = 1338; e.Zhebrevecyrillic = 1217; e.Zhecyrillic = 1046; e.Zhedescendercyrillic = 1174; e.Zhedieresiscyrillic = 1244; e.Zlinebelow = 7828; e.Zmonospace = 65338; e.Zsmall = 63354; e.Zstroke = 437; e.a = 97; e.aabengali = 2438; e.aacute = 225; e.aadeva = 2310; e.aagujarati = 2694; e.aagurmukhi = 2566; e.aamatragurmukhi = 2622; e.aarusquare = 13059; e.aavowelsignbengali = 2494; e.aavowelsigndeva = 2366; e.aavowelsigngujarati = 2750; e.abbreviationmarkarmenian = 1375; e.abbreviationsigndeva = 2416; e.abengali = 2437; e.abopomofo = 12570; e.abreve = 259; e.abreveacute = 7855; e.abrevecyrillic = 1233; e.abrevedotbelow = 7863; e.abrevegrave = 7857; e.abrevehookabove = 7859; e.abrevetilde = 7861; e.acaron = 462; e.acircle = 9424; e.acircumflex = 226; e.acircumflexacute = 7845; e.acircumflexdotbelow = 7853; e.acircumflexgrave = 7847; e.acircumflexhookabove = 7849; e.acircumflextilde = 7851; e.acute = 180; e.acutebelowcmb = 791; e.acutecmb = 769; e.acutecomb = 769; e.acutedeva = 2388; e.acutelowmod = 719; e.acutetonecmb = 833; e.acyrillic = 1072; e.adblgrave = 513; e.addakgurmukhi = 2673; e.adeva = 2309; e.adieresis = 228; e.adieresiscyrillic = 1235; e.adieresismacron = 479; e.adotbelow = 7841; e.adotmacron = 481; e.ae = 230; e.aeacute = 509; e.aekorean = 12624; e.aemacron = 483; e.afii00208 = 8213; e.afii08941 = 8356; e.afii10017 = 1040; e.afii10018 = 1041; e.afii10019 = 1042; e.afii10020 = 1043; e.afii10021 = 1044; e.afii10022 = 1045; e.afii10023 = 1025; e.afii10024 = 1046; e.afii10025 = 1047; e.afii10026 = 1048; e.afii10027 = 1049; e.afii10028 = 1050; e.afii10029 = 1051; e.afii10030 = 1052; e.afii10031 = 1053; e.afii10032 = 1054; e.afii10033 = 1055; e.afii10034 = 1056; e.afii10035 = 1057; e.afii10036 = 1058; e.afii10037 = 1059; e.afii10038 = 1060; e.afii10039 = 1061; e.afii10040 = 1062; e.afii10041 = 1063; e.afii10042 = 1064; e.afii10043 = 1065; e.afii10044 = 1066; e.afii10045 = 1067; e.afii10046 = 1068; e.afii10047 = 1069; e.afii10048 = 1070; e.afii10049 = 1071; e.afii10050 = 1168; e.afii10051 = 1026; e.afii10052 = 1027; e.afii10053 = 1028; e.afii10054 = 1029; e.afii10055 = 1030; e.afii10056 = 1031; e.afii10057 = 1032; e.afii10058 = 1033; e.afii10059 = 1034; e.afii10060 = 1035; e.afii10061 = 1036; e.afii10062 = 1038; e.afii10063 = 63172; e.afii10064 = 63173; e.afii10065 = 1072; e.afii10066 = 1073; e.afii10067 = 1074; e.afii10068 = 1075; e.afii10069 = 1076; e.afii10070 = 1077; e.afii10071 = 1105; e.afii10072 = 1078; e.afii10073 = 1079; e.afii10074 = 1080; e.afii10075 = 1081; e.afii10076 = 1082; e.afii10077 = 1083; e.afii10078 = 1084; e.afii10079 = 1085; e.afii10080 = 1086; e.afii10081 = 1087; e.afii10082 = 1088; e.afii10083 = 1089; e.afii10084 = 1090; e.afii10085 = 1091; e.afii10086 = 1092; e.afii10087 = 1093; e.afii10088 = 1094; e.afii10089 = 1095; e.afii10090 = 1096; e.afii10091 = 1097; e.afii10092 = 1098; e.afii10093 = 1099; e.afii10094 = 1100; e.afii10095 = 1101; e.afii10096 = 1102; e.afii10097 = 1103; e.afii10098 = 1169; e.afii10099 = 1106; e.afii10100 = 1107; e.afii10101 = 1108; e.afii10102 = 1109; e.afii10103 = 1110; e.afii10104 = 1111; e.afii10105 = 1112; e.afii10106 = 1113; e.afii10107 = 1114; e.afii10108 = 1115; e.afii10109 = 1116; e.afii10110 = 1118; e.afii10145 = 1039; e.afii10146 = 1122; e.afii10147 = 1138; e.afii10148 = 1140; e.afii10192 = 63174; e.afii10193 = 1119; e.afii10194 = 1123; e.afii10195 = 1139; e.afii10196 = 1141; e.afii10831 = 63175; e.afii10832 = 63176; e.afii10846 = 1241; e.afii299 = 8206; e.afii300 = 8207; e.afii301 = 8205; e.afii57381 = 1642; e.afii57388 = 1548; e.afii57392 = 1632; e.afii57393 = 1633; e.afii57394 = 1634; e.afii57395 = 1635; e.afii57396 = 1636; e.afii57397 = 1637; e.afii57398 = 1638; e.afii57399 = 1639; e.afii57400 = 1640; e.afii57401 = 1641; e.afii57403 = 1563; e.afii57407 = 1567; e.afii57409 = 1569; e.afii57410 = 1570; e.afii57411 = 1571; e.afii57412 = 1572; e.afii57413 = 1573; e.afii57414 = 1574; e.afii57415 = 1575; e.afii57416 = 1576; e.afii57417 = 1577; e.afii57418 = 1578; e.afii57419 = 1579; e.afii57420 = 1580; e.afii57421 = 1581; e.afii57422 = 1582; e.afii57423 = 1583; e.afii57424 = 1584; e.afii57425 = 1585; e.afii57426 = 1586; e.afii57427 = 1587; e.afii57428 = 1588; e.afii57429 = 1589; e.afii57430 = 1590; e.afii57431 = 1591; e.afii57432 = 1592; e.afii57433 = 1593; e.afii57434 = 1594; e.afii57440 = 1600; e.afii57441 = 1601; e.afii57442 = 1602; e.afii57443 = 1603; e.afii57444 = 1604; e.afii57445 = 1605; e.afii57446 = 1606; e.afii57448 = 1608; e.afii57449 = 1609; e.afii57450 = 1610; e.afii57451 = 1611; e.afii57452 = 1612; e.afii57453 = 1613; e.afii57454 = 1614; e.afii57455 = 1615; e.afii57456 = 1616; e.afii57457 = 1617; e.afii57458 = 1618; e.afii57470 = 1607; e.afii57505 = 1700; e.afii57506 = 1662; e.afii57507 = 1670; e.afii57508 = 1688; e.afii57509 = 1711; e.afii57511 = 1657; e.afii57512 = 1672; e.afii57513 = 1681; e.afii57514 = 1722; e.afii57519 = 1746; e.afii57534 = 1749; e.afii57636 = 8362; e.afii57645 = 1470; e.afii57658 = 1475; e.afii57664 = 1488; e.afii57665 = 1489; e.afii57666 = 1490; e.afii57667 = 1491; e.afii57668 = 1492; e.afii57669 = 1493; e.afii57670 = 1494; e.afii57671 = 1495; e.afii57672 = 1496; e.afii57673 = 1497; e.afii57674 = 1498; e.afii57675 = 1499; e.afii57676 = 1500; e.afii57677 = 1501; e.afii57678 = 1502; e.afii57679 = 1503; e.afii57680 = 1504; e.afii57681 = 1505; e.afii57682 = 1506; e.afii57683 = 1507; e.afii57684 = 1508; e.afii57685 = 1509; e.afii57686 = 1510; e.afii57687 = 1511; e.afii57688 = 1512; e.afii57689 = 1513; e.afii57690 = 1514; e.afii57694 = 64298; e.afii57695 = 64299; e.afii57700 = 64331; e.afii57705 = 64287; e.afii57716 = 1520; e.afii57717 = 1521; e.afii57718 = 1522; e.afii57723 = 64309; e.afii57793 = 1460; e.afii57794 = 1461; e.afii57795 = 1462; e.afii57796 = 1467; e.afii57797 = 1464; e.afii57798 = 1463; e.afii57799 = 1456; e.afii57800 = 1458; e.afii57801 = 1457; e.afii57802 = 1459; e.afii57803 = 1474; e.afii57804 = 1473; e.afii57806 = 1465; e.afii57807 = 1468; e.afii57839 = 1469; e.afii57841 = 1471; e.afii57842 = 1472; e.afii57929 = 700; e.afii61248 = 8453; e.afii61289 = 8467; e.afii61352 = 8470; e.afii61573 = 8236; e.afii61574 = 8237; e.afii61575 = 8238; e.afii61664 = 8204; e.afii63167 = 1645; e.afii64937 = 701; e.agrave = 224; e.agujarati = 2693; e.agurmukhi = 2565; e.ahiragana = 12354; e.ahookabove = 7843; e.aibengali = 2448; e.aibopomofo = 12574; e.aideva = 2320; e.aiecyrillic = 1237; e.aigujarati = 2704; e.aigurmukhi = 2576; e.aimatragurmukhi = 2632; e.ainarabic = 1593; e.ainfinalarabic = 65226; e.aininitialarabic = 65227; e.ainmedialarabic = 65228; e.ainvertedbreve = 515; e.aivowelsignbengali = 2504; e.aivowelsigndeva = 2376; e.aivowelsigngujarati = 2760; e.akatakana = 12450; e.akatakanahalfwidth = 65393; e.akorean = 12623; e.alef = 1488; e.alefarabic = 1575; e.alefdageshhebrew = 64304; e.aleffinalarabic = 65166; e.alefhamzaabovearabic = 1571; e.alefhamzaabovefinalarabic = 65156; e.alefhamzabelowarabic = 1573; e.alefhamzabelowfinalarabic = 65160; e.alefhebrew = 1488; e.aleflamedhebrew = 64335; e.alefmaddaabovearabic = 1570; e.alefmaddaabovefinalarabic = 65154; e.alefmaksuraarabic = 1609; e.alefmaksurafinalarabic = 65264; e.alefmaksurainitialarabic = 65267; e.alefmaksuramedialarabic = 65268; e.alefpatahhebrew = 64302; e.alefqamatshebrew = 64303; e.aleph = 8501; e.allequal = 8780; e.alpha = 945; e.alphatonos = 940; e.amacron = 257; e.amonospace = 65345; e.ampersand = 38; e.ampersandmonospace = 65286; e.ampersandsmall = 63270; e.amsquare = 13250; e.anbopomofo = 12578; e.angbopomofo = 12580; e.angbracketleft = 12296; e.angbracketright = 12297; e.angkhankhuthai = 3674; e.angle = 8736; e.anglebracketleft = 12296; e.anglebracketleftvertical = 65087; e.anglebracketright = 12297; e.anglebracketrightvertical = 65088; e.angleleft = 9001; e.angleright = 9002; e.angstrom = 8491; e.anoteleia = 903; e.anudattadeva = 2386; e.anusvarabengali = 2434; e.anusvaradeva = 2306; e.anusvaragujarati = 2690; e.aogonek = 261; e.apaatosquare = 13056; e.aparen = 9372; e.apostrophearmenian = 1370; e.apostrophemod = 700; e.apple = 63743; e.approaches = 8784; e.approxequal = 8776; e.approxequalorimage = 8786; e.approximatelyequal = 8773; e.araeaekorean = 12686; e.araeakorean = 12685; e.arc = 8978; e.arighthalfring = 7834; e.aring = 229; e.aringacute = 507; e.aringbelow = 7681; e.arrowboth = 8596; e.arrowdashdown = 8675; e.arrowdashleft = 8672; e.arrowdashright = 8674; e.arrowdashup = 8673; e.arrowdblboth = 8660; e.arrowdbldown = 8659; e.arrowdblleft = 8656; e.arrowdblright = 8658; e.arrowdblup = 8657; e.arrowdown = 8595; e.arrowdownleft = 8601; e.arrowdownright = 8600; e.arrowdownwhite = 8681; e.arrowheaddownmod = 709; e.arrowheadleftmod = 706; e.arrowheadrightmod = 707; e.arrowheadupmod = 708; e.arrowhorizex = 63719; e.arrowleft = 8592; e.arrowleftdbl = 8656; e.arrowleftdblstroke = 8653; e.arrowleftoverright = 8646; e.arrowleftwhite = 8678; e.arrowright = 8594; e.arrowrightdblstroke = 8655; e.arrowrightheavy = 10142; e.arrowrightoverleft = 8644; e.arrowrightwhite = 8680; e.arrowtableft = 8676; e.arrowtabright = 8677; e.arrowup = 8593; e.arrowupdn = 8597; e.arrowupdnbse = 8616; e.arrowupdownbase = 8616; e.arrowupleft = 8598; e.arrowupleftofdown = 8645; e.arrowupright = 8599; e.arrowupwhite = 8679; e.arrowvertex = 63718; e.asciicircum = 94; e.asciicircummonospace = 65342; e.asciitilde = 126; e.asciitildemonospace = 65374; e.ascript = 593; e.ascriptturned = 594; e.asmallhiragana = 12353; e.asmallkatakana = 12449; e.asmallkatakanahalfwidth = 65383; e.asterisk = 42; e.asteriskaltonearabic = 1645; e.asteriskarabic = 1645; e.asteriskmath = 8727; e.asteriskmonospace = 65290; e.asterisksmall = 65121; e.asterism = 8258; e.asuperior = 63209; e.asymptoticallyequal = 8771; e.at = 64; e.atilde = 227; e.atmonospace = 65312; e.atsmall = 65131; e.aturned = 592; e.aubengali = 2452; e.aubopomofo = 12576; e.audeva = 2324; e.augujarati = 2708; e.augurmukhi = 2580; e.aulengthmarkbengali = 2519; e.aumatragurmukhi = 2636; e.auvowelsignbengali = 2508; e.auvowelsigndeva = 2380; e.auvowelsigngujarati = 2764; e.avagrahadeva = 2365; e.aybarmenian = 1377; e.ayin = 1506; e.ayinaltonehebrew = 64288; e.ayinhebrew = 1506; e.b = 98; e.babengali = 2476; e.backslash = 92; e.backslashmonospace = 65340; e.badeva = 2348; e.bagujarati = 2732; e.bagurmukhi = 2604; e.bahiragana = 12400; e.bahtthai = 3647; e.bakatakana = 12496; e.bar = 124; e.barmonospace = 65372; e.bbopomofo = 12549; e.bcircle = 9425; e.bdotaccent = 7683; e.bdotbelow = 7685; e.beamedsixteenthnotes = 9836; e.because = 8757; e.becyrillic = 1073; e.beharabic = 1576; e.behfinalarabic = 65168; e.behinitialarabic = 65169; e.behiragana = 12409; e.behmedialarabic = 65170; e.behmeeminitialarabic = 64671; e.behmeemisolatedarabic = 64520; e.behnoonfinalarabic = 64621; e.bekatakana = 12505; e.benarmenian = 1378; e.bet = 1489; e.beta = 946; e.betasymbolgreek = 976; e.betdagesh = 64305; e.betdageshhebrew = 64305; e.bethebrew = 1489; e.betrafehebrew = 64332; e.bhabengali = 2477; e.bhadeva = 2349; e.bhagujarati = 2733; e.bhagurmukhi = 2605; e.bhook = 595; e.bihiragana = 12403; e.bikatakana = 12499; e.bilabialclick = 664; e.bindigurmukhi = 2562; e.birusquare = 13105; e.blackcircle = 9679; e.blackdiamond = 9670; e.blackdownpointingtriangle = 9660; e.blackleftpointingpointer = 9668; e.blackleftpointingtriangle = 9664; e.blacklenticularbracketleft = 12304; e.blacklenticularbracketleftvertical = 65083; e.blacklenticularbracketright = 12305; e.blacklenticularbracketrightvertical = 65084; e.blacklowerlefttriangle = 9699; e.blacklowerrighttriangle = 9698; e.blackrectangle = 9644; e.blackrightpointingpointer = 9658; e.blackrightpointingtriangle = 9654; e.blacksmallsquare = 9642; e.blacksmilingface = 9787; e.blacksquare = 9632; e.blackstar = 9733; e.blackupperlefttriangle = 9700; e.blackupperrighttriangle = 9701; e.blackuppointingsmalltriangle = 9652; e.blackuppointingtriangle = 9650; e.blank = 9251; e.blinebelow = 7687; e.block = 9608; e.bmonospace = 65346; e.bobaimaithai = 3610; e.bohiragana = 12412; e.bokatakana = 12508; e.bparen = 9373; e.bqsquare = 13251; e.braceex = 63732; e.braceleft = 123; e.braceleftbt = 63731; e.braceleftmid = 63730; e.braceleftmonospace = 65371; e.braceleftsmall = 65115; e.bracelefttp = 63729; e.braceleftvertical = 65079; e.braceright = 125; e.bracerightbt = 63742; e.bracerightmid = 63741; e.bracerightmonospace = 65373; e.bracerightsmall = 65116; e.bracerighttp = 63740; e.bracerightvertical = 65080; e.bracketleft = 91; e.bracketleftbt = 63728; e.bracketleftex = 63727; e.bracketleftmonospace = 65339; e.bracketlefttp = 63726; e.bracketright = 93; e.bracketrightbt = 63739; e.bracketrightex = 63738; e.bracketrightmonospace = 65341; e.bracketrighttp = 63737; e.breve = 728; e.brevebelowcmb = 814; e.brevecmb = 774; e.breveinvertedbelowcmb = 815; e.breveinvertedcmb = 785; e.breveinverteddoublecmb = 865; e.bridgebelowcmb = 810; e.bridgeinvertedbelowcmb = 826; e.brokenbar = 166; e.bstroke = 384; e.bsuperior = 63210; e.btopbar = 387; e.buhiragana = 12406; e.bukatakana = 12502; e.bullet = 8226; e.bulletinverse = 9688; e.bulletoperator = 8729; e.bullseye = 9678; e.c = 99; e.caarmenian = 1390; e.cabengali = 2458; e.cacute = 263; e.cadeva = 2330; e.cagujarati = 2714; e.cagurmukhi = 2586; e.calsquare = 13192; e.candrabindubengali = 2433; e.candrabinducmb = 784; e.candrabindudeva = 2305; e.candrabindugujarati = 2689; e.capslock = 8682; e.careof = 8453; e.caron = 711; e.caronbelowcmb = 812; e.caroncmb = 780; e.carriagereturn = 8629; e.cbopomofo = 12568; e.ccaron = 269; e.ccedilla = 231; e.ccedillaacute = 7689; e.ccircle = 9426; e.ccircumflex = 265; e.ccurl = 597; e.cdot = 267; e.cdotaccent = 267; e.cdsquare = 13253; e.cedilla = 184; e.cedillacmb = 807; e.cent = 162; e.centigrade = 8451; e.centinferior = 63199; e.centmonospace = 65504; e.centoldstyle = 63394; e.centsuperior = 63200; e.chaarmenian = 1401; e.chabengali = 2459; e.chadeva = 2331; e.chagujarati = 2715; e.chagurmukhi = 2587; e.chbopomofo = 12564; e.cheabkhasiancyrillic = 1213; e.checkmark = 10003; e.checyrillic = 1095; e.chedescenderabkhasiancyrillic = 1215; e.chedescendercyrillic = 1207; e.chedieresiscyrillic = 1269; e.cheharmenian = 1395; e.chekhakassiancyrillic = 1228; e.cheverticalstrokecyrillic = 1209; e.chi = 967; e.chieuchacirclekorean = 12919; e.chieuchaparenkorean = 12823; e.chieuchcirclekorean = 12905; e.chieuchkorean = 12618; e.chieuchparenkorean = 12809; e.chochangthai = 3594; e.chochanthai = 3592; e.chochingthai = 3593; e.chochoethai = 3596; e.chook = 392; e.cieucacirclekorean = 12918; e.cieucaparenkorean = 12822; e.cieuccirclekorean = 12904; e.cieuckorean = 12616; e.cieucparenkorean = 12808; e.cieucuparenkorean = 12828; e.circle = 9675; e.circlecopyrt = 169; e.circlemultiply = 8855; e.circleot = 8857; e.circleplus = 8853; e.circlepostalmark = 12342; e.circlewithlefthalfblack = 9680; e.circlewithrighthalfblack = 9681; e.circumflex = 710; e.circumflexbelowcmb = 813; e.circumflexcmb = 770; e.clear = 8999; e.clickalveolar = 450; e.clickdental = 448; e.clicklateral = 449; e.clickretroflex = 451; e.club = 9827; e.clubsuitblack = 9827; e.clubsuitwhite = 9831; e.cmcubedsquare = 13220; e.cmonospace = 65347; e.cmsquaredsquare = 13216; e.coarmenian = 1409; e.colon = 58; e.colonmonetary = 8353; e.colonmonospace = 65306; e.colonsign = 8353; e.colonsmall = 65109; e.colontriangularhalfmod = 721; e.colontriangularmod = 720; e.comma = 44; e.commaabovecmb = 787; e.commaaboverightcmb = 789; e.commaaccent = 63171; e.commaarabic = 1548; e.commaarmenian = 1373; e.commainferior = 63201; e.commamonospace = 65292; e.commareversedabovecmb = 788; e.commareversedmod = 701; e.commasmall = 65104; e.commasuperior = 63202; e.commaturnedabovecmb = 786; e.commaturnedmod = 699; e.compass = 9788; e.congruent = 8773; e.contourintegral = 8750; e.control = 8963; e.controlACK = 6; e.controlBEL = 7; e.controlBS = 8; e.controlCAN = 24; e.controlCR = 13; e.controlDC1 = 17; e.controlDC2 = 18; e.controlDC3 = 19; e.controlDC4 = 20; e.controlDEL = 127; e.controlDLE = 16; e.controlEM = 25; e.controlENQ = 5; e.controlEOT = 4; e.controlESC = 27; e.controlETB = 23; e.controlETX = 3; e.controlFF = 12; e.controlFS = 28; e.controlGS = 29; e.controlHT = 9; e.controlLF = 10; e.controlNAK = 21; e.controlNULL = 0; e.controlRS = 30; e.controlSI = 15; e.controlSO = 14; e.controlSOT = 2; e.controlSTX = 1; e.controlSUB = 26; e.controlSYN = 22; e.controlUS = 31; e.controlVT = 11; e.copyright = 169; e.copyrightsans = 63721; e.copyrightserif = 63193; e.cornerbracketleft = 12300; e.cornerbracketlefthalfwidth = 65378; e.cornerbracketleftvertical = 65089; e.cornerbracketright = 12301; e.cornerbracketrighthalfwidth = 65379; e.cornerbracketrightvertical = 65090; e.corporationsquare = 13183; e.cosquare = 13255; e.coverkgsquare = 13254; e.cparen = 9374; e.cruzeiro = 8354; e.cstretched = 663; e.curlyand = 8911; e.curlyor = 8910; e.currency = 164; e.cyrBreve = 63185; e.cyrFlex = 63186; e.cyrbreve = 63188; e.cyrflex = 63189; e.d = 100; e.daarmenian = 1380; e.dabengali = 2470; e.dadarabic = 1590; e.dadeva = 2342; e.dadfinalarabic = 65214; e.dadinitialarabic = 65215; e.dadmedialarabic = 65216; e.dagesh = 1468; e.dageshhebrew = 1468; e.dagger = 8224; e.daggerdbl = 8225; e.dagujarati = 2726; e.dagurmukhi = 2598; e.dahiragana = 12384; e.dakatakana = 12480; e.dalarabic = 1583; e.dalet = 1491; e.daletdagesh = 64307; e.daletdageshhebrew = 64307; e.dalethebrew = 1491; e.dalfinalarabic = 65194; e.dammaarabic = 1615; e.dammalowarabic = 1615; e.dammatanaltonearabic = 1612; e.dammatanarabic = 1612; e.danda = 2404; e.dargahebrew = 1447; e.dargalefthebrew = 1447; e.dasiapneumatacyrilliccmb = 1157; e.dblGrave = 63187; e.dblanglebracketleft = 12298; e.dblanglebracketleftvertical = 65085; e.dblanglebracketright = 12299; e.dblanglebracketrightvertical = 65086; e.dblarchinvertedbelowcmb = 811; e.dblarrowleft = 8660; e.dblarrowright = 8658; e.dbldanda = 2405; e.dblgrave = 63190; e.dblgravecmb = 783; e.dblintegral = 8748; e.dbllowline = 8215; e.dbllowlinecmb = 819; e.dbloverlinecmb = 831; e.dblprimemod = 698; e.dblverticalbar = 8214; e.dblverticallineabovecmb = 782; e.dbopomofo = 12553; e.dbsquare = 13256; e.dcaron = 271; e.dcedilla = 7697; e.dcircle = 9427; e.dcircumflexbelow = 7699; e.dcroat = 273; e.ddabengali = 2465; e.ddadeva = 2337; e.ddagujarati = 2721; e.ddagurmukhi = 2593; e.ddalarabic = 1672; e.ddalfinalarabic = 64393; e.dddhadeva = 2396; e.ddhabengali = 2466; e.ddhadeva = 2338; e.ddhagujarati = 2722; e.ddhagurmukhi = 2594; e.ddotaccent = 7691; e.ddotbelow = 7693; e.decimalseparatorarabic = 1643; e.decimalseparatorpersian = 1643; e.decyrillic = 1076; e.degree = 176; e.dehihebrew = 1453; e.dehiragana = 12391; e.deicoptic = 1007; e.dekatakana = 12487; e.deleteleft = 9003; e.deleteright = 8998; e.delta = 948; e.deltaturned = 397; e.denominatorminusonenumeratorbengali = 2552; e.dezh = 676; e.dhabengali = 2471; e.dhadeva = 2343; e.dhagujarati = 2727; e.dhagurmukhi = 2599; e.dhook = 599; e.dialytikatonos = 901; e.dialytikatonoscmb = 836; e.diamond = 9830; e.diamondsuitwhite = 9826; e.dieresis = 168; e.dieresisacute = 63191; e.dieresisbelowcmb = 804; e.dieresiscmb = 776; e.dieresisgrave = 63192; e.dieresistonos = 901; e.dihiragana = 12386; e.dikatakana = 12482; e.dittomark = 12291; e.divide = 247; e.divides = 8739; e.divisionslash = 8725; e.djecyrillic = 1106; e.dkshade = 9619; e.dlinebelow = 7695; e.dlsquare = 13207; e.dmacron = 273; e.dmonospace = 65348; e.dnblock = 9604; e.dochadathai = 3598; e.dodekthai = 3604; e.dohiragana = 12393; e.dokatakana = 12489; e.dollar = 36; e.dollarinferior = 63203; e.dollarmonospace = 65284; e.dollaroldstyle = 63268; e.dollarsmall = 65129; e.dollarsuperior = 63204; e.dong = 8363; e.dorusquare = 13094; e.dotaccent = 729; e.dotaccentcmb = 775; e.dotbelowcmb = 803; e.dotbelowcomb = 803; e.dotkatakana = 12539; e.dotlessi = 305; e.dotlessj = 63166; e.dotlessjstrokehook = 644; e.dotmath = 8901; e.dottedcircle = 9676; e.doubleyodpatah = 64287; e.doubleyodpatahhebrew = 64287; e.downtackbelowcmb = 798; e.downtackmod = 725; e.dparen = 9375; e.dsuperior = 63211; e.dtail = 598; e.dtopbar = 396; e.duhiragana = 12389; e.dukatakana = 12485; e.dz = 499; e.dzaltone = 675; e.dzcaron = 454; e.dzcurl = 677; e.dzeabkhasiancyrillic = 1249; e.dzecyrillic = 1109; e.dzhecyrillic = 1119; e.e = 101; e.eacute = 233; e.earth = 9793; e.ebengali = 2447; e.ebopomofo = 12572; e.ebreve = 277; e.ecandradeva = 2317; e.ecandragujarati = 2701; e.ecandravowelsigndeva = 2373; e.ecandravowelsigngujarati = 2757; e.ecaron = 283; e.ecedillabreve = 7709; e.echarmenian = 1381; e.echyiwnarmenian = 1415; e.ecircle = 9428; e.ecircumflex = 234; e.ecircumflexacute = 7871; e.ecircumflexbelow = 7705; e.ecircumflexdotbelow = 7879; e.ecircumflexgrave = 7873; e.ecircumflexhookabove = 7875; e.ecircumflextilde = 7877; e.ecyrillic = 1108; e.edblgrave = 517; e.edeva = 2319; e.edieresis = 235; e.edot = 279; e.edotaccent = 279; e.edotbelow = 7865; e.eegurmukhi = 2575; e.eematragurmukhi = 2631; e.efcyrillic = 1092; e.egrave = 232; e.egujarati = 2703; e.eharmenian = 1383; e.ehbopomofo = 12573; e.ehiragana = 12360; e.ehookabove = 7867; e.eibopomofo = 12575; e.eight = 56; e.eightarabic = 1640; e.eightbengali = 2542; e.eightcircle = 9319; e.eightcircleinversesansserif = 10129; e.eightdeva = 2414; e.eighteencircle = 9329; e.eighteenparen = 9349; e.eighteenperiod = 9369; e.eightgujarati = 2798; e.eightgurmukhi = 2670; e.eighthackarabic = 1640; e.eighthangzhou = 12328; e.eighthnotebeamed = 9835; e.eightideographicparen = 12839; e.eightinferior = 8328; e.eightmonospace = 65304; e.eightoldstyle = 63288; e.eightparen = 9339; e.eightperiod = 9359; e.eightpersian = 1784; e.eightroman = 8567; e.eightsuperior = 8312; e.eightthai = 3672; e.einvertedbreve = 519; e.eiotifiedcyrillic = 1125; e.ekatakana = 12456; e.ekatakanahalfwidth = 65396; e.ekonkargurmukhi = 2676; e.ekorean = 12628; e.elcyrillic = 1083; e.element = 8712; e.elevencircle = 9322; e.elevenparen = 9342; e.elevenperiod = 9362; e.elevenroman = 8570; e.ellipsis = 8230; e.ellipsisvertical = 8942; e.emacron = 275; e.emacronacute = 7703; e.emacrongrave = 7701; e.emcyrillic = 1084; e.emdash = 8212; e.emdashvertical = 65073; e.emonospace = 65349; e.emphasismarkarmenian = 1371; e.emptyset = 8709; e.enbopomofo = 12579; e.encyrillic = 1085; e.endash = 8211; e.endashvertical = 65074; e.endescendercyrillic = 1187; e.eng = 331; e.engbopomofo = 12581; e.enghecyrillic = 1189; e.enhookcyrillic = 1224; e.enspace = 8194; e.eogonek = 281; e.eokorean = 12627; e.eopen = 603; e.eopenclosed = 666; e.eopenreversed = 604; e.eopenreversedclosed = 606; e.eopenreversedhook = 605; e.eparen = 9376; e.epsilon = 949; e.epsilontonos = 941; e.equal = 61; e.equalmonospace = 65309; e.equalsmall = 65126; e.equalsuperior = 8316; e.equivalence = 8801; e.erbopomofo = 12582; e.ercyrillic = 1088; e.ereversed = 600; e.ereversedcyrillic = 1101; e.escyrillic = 1089; e.esdescendercyrillic = 1195; e.esh = 643; e.eshcurl = 646; e.eshortdeva = 2318; e.eshortvowelsigndeva = 2374; e.eshreversedloop = 426; e.eshsquatreversed = 645; e.esmallhiragana = 12359; e.esmallkatakana = 12455; e.esmallkatakanahalfwidth = 65386; e.estimated = 8494; e.esuperior = 63212; e.eta = 951; e.etarmenian = 1384; e.etatonos = 942; e.eth = 240; e.etilde = 7869; e.etildebelow = 7707; e.etnahtafoukhhebrew = 1425; e.etnahtafoukhlefthebrew = 1425; e.etnahtahebrew = 1425; e.etnahtalefthebrew = 1425; e.eturned = 477; e.eukorean = 12641; e.euro = 8364; e.evowelsignbengali = 2503; e.evowelsigndeva = 2375; e.evowelsigngujarati = 2759; e.exclam = 33; e.exclamarmenian = 1372; e.exclamdbl = 8252; e.exclamdown = 161; e.exclamdownsmall = 63393; e.exclammonospace = 65281; e.exclamsmall = 63265; e.existential = 8707; e.ezh = 658; e.ezhcaron = 495; e.ezhcurl = 659; e.ezhreversed = 441; e.ezhtail = 442; e.f = 102; e.fadeva = 2398; e.fagurmukhi = 2654; e.fahrenheit = 8457; e.fathaarabic = 1614; e.fathalowarabic = 1614; e.fathatanarabic = 1611; e.fbopomofo = 12552; e.fcircle = 9429; e.fdotaccent = 7711; e.feharabic = 1601; e.feharmenian = 1414; e.fehfinalarabic = 65234; e.fehinitialarabic = 65235; e.fehmedialarabic = 65236; e.feicoptic = 997; e.female = 9792; e.ff = 64256; e.f_f = 64256; e.ffi = 64259; e.ffl = 64260; e.fi = 64257; e.fifteencircle = 9326; e.fifteenparen = 9346; e.fifteenperiod = 9366; e.figuredash = 8210; e.filledbox = 9632; e.filledrect = 9644; e.finalkaf = 1498; e.finalkafdagesh = 64314; e.finalkafdageshhebrew = 64314; e.finalkafhebrew = 1498; e.finalmem = 1501; e.finalmemhebrew = 1501; e.finalnun = 1503; e.finalnunhebrew = 1503; e.finalpe = 1507; e.finalpehebrew = 1507; e.finaltsadi = 1509; e.finaltsadihebrew = 1509; e.firsttonechinese = 713; e.fisheye = 9673; e.fitacyrillic = 1139; e.five = 53; e.fivearabic = 1637; e.fivebengali = 2539; e.fivecircle = 9316; e.fivecircleinversesansserif = 10126; e.fivedeva = 2411; e.fiveeighths = 8541; e.fivegujarati = 2795; e.fivegurmukhi = 2667; e.fivehackarabic = 1637; e.fivehangzhou = 12325; e.fiveideographicparen = 12836; e.fiveinferior = 8325; e.fivemonospace = 65301; e.fiveoldstyle = 63285; e.fiveparen = 9336; e.fiveperiod = 9356; e.fivepersian = 1781; e.fiveroman = 8564; e.fivesuperior = 8309; e.fivethai = 3669; e.fl = 64258; e.florin = 402; e.fmonospace = 65350; e.fmsquare = 13209; e.fofanthai = 3615; e.fofathai = 3613; e.fongmanthai = 3663; e.forall = 8704; e.four = 52; e.fourarabic = 1636; e.fourbengali = 2538; e.fourcircle = 9315; e.fourcircleinversesansserif = 10125; e.fourdeva = 2410; e.fourgujarati = 2794; e.fourgurmukhi = 2666; e.fourhackarabic = 1636; e.fourhangzhou = 12324; e.fourideographicparen = 12835; e.fourinferior = 8324; e.fourmonospace = 65300; e.fournumeratorbengali = 2551; e.fouroldstyle = 63284; e.fourparen = 9335; e.fourperiod = 9355; e.fourpersian = 1780; e.fourroman = 8563; e.foursuperior = 8308; e.fourteencircle = 9325; e.fourteenparen = 9345; e.fourteenperiod = 9365; e.fourthai = 3668; e.fourthtonechinese = 715; e.fparen = 9377; e.fraction = 8260; e.franc = 8355; e.g = 103; e.gabengali = 2455; e.gacute = 501; e.gadeva = 2327; e.gafarabic = 1711; e.gaffinalarabic = 64403; e.gafinitialarabic = 64404; e.gafmedialarabic = 64405; e.gagujarati = 2711; e.gagurmukhi = 2583; e.gahiragana = 12364; e.gakatakana = 12460; e.gamma = 947; e.gammalatinsmall = 611; e.gammasuperior = 736; e.gangiacoptic = 1003; e.gbopomofo = 12557; e.gbreve = 287; e.gcaron = 487; e.gcedilla = 291; e.gcircle = 9430; e.gcircumflex = 285; e.gcommaaccent = 291; e.gdot = 289; e.gdotaccent = 289; e.gecyrillic = 1075; e.gehiragana = 12370; e.gekatakana = 12466; e.geometricallyequal = 8785; e.gereshaccenthebrew = 1436; e.gereshhebrew = 1523; e.gereshmuqdamhebrew = 1437; e.germandbls = 223; e.gershayimaccenthebrew = 1438; e.gershayimhebrew = 1524; e.getamark = 12307; e.ghabengali = 2456; e.ghadarmenian = 1394; e.ghadeva = 2328; e.ghagujarati = 2712; e.ghagurmukhi = 2584; e.ghainarabic = 1594; e.ghainfinalarabic = 65230; e.ghaininitialarabic = 65231; e.ghainmedialarabic = 65232; e.ghemiddlehookcyrillic = 1173; e.ghestrokecyrillic = 1171; e.gheupturncyrillic = 1169; e.ghhadeva = 2394; e.ghhagurmukhi = 2650; e.ghook = 608; e.ghzsquare = 13203; e.gihiragana = 12366; e.gikatakana = 12462; e.gimarmenian = 1379; e.gimel = 1490; e.gimeldagesh = 64306; e.gimeldageshhebrew = 64306; e.gimelhebrew = 1490; e.gjecyrillic = 1107; e.glottalinvertedstroke = 446; e.glottalstop = 660; e.glottalstopinverted = 662; e.glottalstopmod = 704; e.glottalstopreversed = 661; e.glottalstopreversedmod = 705; e.glottalstopreversedsuperior = 740; e.glottalstopstroke = 673; e.glottalstopstrokereversed = 674; e.gmacron = 7713; e.gmonospace = 65351; e.gohiragana = 12372; e.gokatakana = 12468; e.gparen = 9378; e.gpasquare = 13228; e.gradient = 8711; e.grave = 96; e.gravebelowcmb = 790; e.gravecmb = 768; e.gravecomb = 768; e.gravedeva = 2387; e.gravelowmod = 718; e.gravemonospace = 65344; e.gravetonecmb = 832; e.greater = 62; e.greaterequal = 8805; e.greaterequalorless = 8923; e.greatermonospace = 65310; e.greaterorequivalent = 8819; e.greaterorless = 8823; e.greateroverequal = 8807; e.greatersmall = 65125; e.gscript = 609; e.gstroke = 485; e.guhiragana = 12368; e.guillemotleft = 171; e.guillemotright = 187; e.guilsinglleft = 8249; e.guilsinglright = 8250; e.gukatakana = 12464; e.guramusquare = 13080; e.gysquare = 13257; e.h = 104; e.haabkhasiancyrillic = 1193; e.haaltonearabic = 1729; e.habengali = 2489; e.hadescendercyrillic = 1203; e.hadeva = 2361; e.hagujarati = 2745; e.hagurmukhi = 2617; e.haharabic = 1581; e.hahfinalarabic = 65186; e.hahinitialarabic = 65187; e.hahiragana = 12399; e.hahmedialarabic = 65188; e.haitusquare = 13098; e.hakatakana = 12495; e.hakatakanahalfwidth = 65418; e.halantgurmukhi = 2637; e.hamzaarabic = 1569; e.hamzalowarabic = 1569; e.hangulfiller = 12644; e.hardsigncyrillic = 1098; e.harpoonleftbarbup = 8636; e.harpoonrightbarbup = 8640; e.hasquare = 13258; e.hatafpatah = 1458; e.hatafpatah16 = 1458; e.hatafpatah23 = 1458; e.hatafpatah2f = 1458; e.hatafpatahhebrew = 1458; e.hatafpatahnarrowhebrew = 1458; e.hatafpatahquarterhebrew = 1458; e.hatafpatahwidehebrew = 1458; e.hatafqamats = 1459; e.hatafqamats1b = 1459; e.hatafqamats28 = 1459; e.hatafqamats34 = 1459; e.hatafqamatshebrew = 1459; e.hatafqamatsnarrowhebrew = 1459; e.hatafqamatsquarterhebrew = 1459; e.hatafqamatswidehebrew = 1459; e.hatafsegol = 1457; e.hatafsegol17 = 1457; e.hatafsegol24 = 1457; e.hatafsegol30 = 1457; e.hatafsegolhebrew = 1457; e.hatafsegolnarrowhebrew = 1457; e.hatafsegolquarterhebrew = 1457; e.hatafsegolwidehebrew = 1457; e.hbar = 295; e.hbopomofo = 12559; e.hbrevebelow = 7723; e.hcedilla = 7721; e.hcircle = 9431; e.hcircumflex = 293; e.hdieresis = 7719; e.hdotaccent = 7715; e.hdotbelow = 7717; e.he = 1492; e.heart = 9829; e.heartsuitblack = 9829; e.heartsuitwhite = 9825; e.hedagesh = 64308; e.hedageshhebrew = 64308; e.hehaltonearabic = 1729; e.heharabic = 1607; e.hehebrew = 1492; e.hehfinalaltonearabic = 64423; e.hehfinalalttwoarabic = 65258; e.hehfinalarabic = 65258; e.hehhamzaabovefinalarabic = 64421; e.hehhamzaaboveisolatedarabic = 64420; e.hehinitialaltonearabic = 64424; e.hehinitialarabic = 65259; e.hehiragana = 12408; e.hehmedialaltonearabic = 64425; e.hehmedialarabic = 65260; e.heiseierasquare = 13179; e.hekatakana = 12504; e.hekatakanahalfwidth = 65421; e.hekutaarusquare = 13110; e.henghook = 615; e.herutusquare = 13113; e.het = 1495; e.hethebrew = 1495; e.hhook = 614; e.hhooksuperior = 689; e.hieuhacirclekorean = 12923; e.hieuhaparenkorean = 12827; e.hieuhcirclekorean = 12909; e.hieuhkorean = 12622; e.hieuhparenkorean = 12813; e.hihiragana = 12402; e.hikatakana = 12498; e.hikatakanahalfwidth = 65419; e.hiriq = 1460; e.hiriq14 = 1460; e.hiriq21 = 1460; e.hiriq2d = 1460; e.hiriqhebrew = 1460; e.hiriqnarrowhebrew = 1460; e.hiriqquarterhebrew = 1460; e.hiriqwidehebrew = 1460; e.hlinebelow = 7830; e.hmonospace = 65352; e.hoarmenian = 1392; e.hohipthai = 3627; e.hohiragana = 12411; e.hokatakana = 12507; e.hokatakanahalfwidth = 65422; e.holam = 1465; e.holam19 = 1465; e.holam26 = 1465; e.holam32 = 1465; e.holamhebrew = 1465; e.holamnarrowhebrew = 1465; e.holamquarterhebrew = 1465; e.holamwidehebrew = 1465; e.honokhukthai = 3630; e.hookabovecomb = 777; e.hookcmb = 777; e.hookpalatalizedbelowcmb = 801; e.hookretroflexbelowcmb = 802; e.hoonsquare = 13122; e.horicoptic = 1001; e.horizontalbar = 8213; e.horncmb = 795; e.hotsprings = 9832; e.house = 8962; e.hparen = 9379; e.hsuperior = 688; e.hturned = 613; e.huhiragana = 12405; e.huiitosquare = 13107; e.hukatakana = 12501; e.hukatakanahalfwidth = 65420; e.hungarumlaut = 733; e.hungarumlautcmb = 779; e.hv = 405; e.hyphen = 45; e.hypheninferior = 63205; e.hyphenmonospace = 65293; e.hyphensmall = 65123; e.hyphensuperior = 63206; e.hyphentwo = 8208; e.i = 105; e.iacute = 237; e.iacyrillic = 1103; e.ibengali = 2439; e.ibopomofo = 12583; e.ibreve = 301; e.icaron = 464; e.icircle = 9432; e.icircumflex = 238; e.icyrillic = 1110; e.idblgrave = 521; e.ideographearthcircle = 12943; e.ideographfirecircle = 12939; e.ideographicallianceparen = 12863; e.ideographiccallparen = 12858; e.ideographiccentrecircle = 12965; e.ideographicclose = 12294; e.ideographiccomma = 12289; e.ideographiccommaleft = 65380; e.ideographiccongratulationparen = 12855; e.ideographiccorrectcircle = 12963; e.ideographicearthparen = 12847; e.ideographicenterpriseparen = 12861; e.ideographicexcellentcircle = 12957; e.ideographicfestivalparen = 12864; e.ideographicfinancialcircle = 12950; e.ideographicfinancialparen = 12854; e.ideographicfireparen = 12843; e.ideographichaveparen = 12850; e.ideographichighcircle = 12964; e.ideographiciterationmark = 12293; e.ideographiclaborcircle = 12952; e.ideographiclaborparen = 12856; e.ideographicleftcircle = 12967; e.ideographiclowcircle = 12966; e.ideographicmedicinecircle = 12969; e.ideographicmetalparen = 12846; e.ideographicmoonparen = 12842; e.ideographicnameparen = 12852; e.ideographicperiod = 12290; e.ideographicprintcircle = 12958; e.ideographicreachparen = 12867; e.ideographicrepresentparen = 12857; e.ideographicresourceparen = 12862; e.ideographicrightcircle = 12968; e.ideographicsecretcircle = 12953; e.ideographicselfparen = 12866; e.ideographicsocietyparen = 12851; e.ideographicspace = 12288; e.ideographicspecialparen = 12853; e.ideographicstockparen = 12849; e.ideographicstudyparen = 12859; e.ideographicsunparen = 12848; e.ideographicsuperviseparen = 12860; e.ideographicwaterparen = 12844; e.ideographicwoodparen = 12845; e.ideographiczero = 12295; e.ideographmetalcircle = 12942; e.ideographmooncircle = 12938; e.ideographnamecircle = 12948; e.ideographsuncircle = 12944; e.ideographwatercircle = 12940; e.ideographwoodcircle = 12941; e.ideva = 2311; e.idieresis = 239; e.idieresisacute = 7727; e.idieresiscyrillic = 1253; e.idotbelow = 7883; e.iebrevecyrillic = 1239; e.iecyrillic = 1077; e.ieungacirclekorean = 12917; e.ieungaparenkorean = 12821; e.ieungcirclekorean = 12903; e.ieungkorean = 12615; e.ieungparenkorean = 12807; e.igrave = 236; e.igujarati = 2695; e.igurmukhi = 2567; e.ihiragana = 12356; e.ihookabove = 7881; e.iibengali = 2440; e.iicyrillic = 1080; e.iideva = 2312; e.iigujarati = 2696; e.iigurmukhi = 2568; e.iimatragurmukhi = 2624; e.iinvertedbreve = 523; e.iishortcyrillic = 1081; e.iivowelsignbengali = 2496; e.iivowelsigndeva = 2368; e.iivowelsigngujarati = 2752; e.ij = 307; e.ikatakana = 12452; e.ikatakanahalfwidth = 65394; e.ikorean = 12643; e.ilde = 732; e.iluyhebrew = 1452; e.imacron = 299; e.imacroncyrillic = 1251; e.imageorapproximatelyequal = 8787; e.imatragurmukhi = 2623; e.imonospace = 65353; e.increment = 8710; e.infinity = 8734; e.iniarmenian = 1387; e.integral = 8747; e.integralbottom = 8993; e.integralbt = 8993; e.integralex = 63733; e.integraltop = 8992; e.integraltp = 8992; e.intersection = 8745; e.intisquare = 13061; e.invbullet = 9688; e.invcircle = 9689; e.invsmileface = 9787; e.iocyrillic = 1105; e.iogonek = 303; e.iota = 953; e.iotadieresis = 970; e.iotadieresistonos = 912; e.iotalatin = 617; e.iotatonos = 943; e.iparen = 9380; e.irigurmukhi = 2674; e.ismallhiragana = 12355; e.ismallkatakana = 12451; e.ismallkatakanahalfwidth = 65384; e.issharbengali = 2554; e.istroke = 616; e.isuperior = 63213; e.iterationhiragana = 12445; e.iterationkatakana = 12541; e.itilde = 297; e.itildebelow = 7725; e.iubopomofo = 12585; e.iucyrillic = 1102; e.ivowelsignbengali = 2495; e.ivowelsigndeva = 2367; e.ivowelsigngujarati = 2751; e.izhitsacyrillic = 1141; e.izhitsadblgravecyrillic = 1143; e.j = 106; e.jaarmenian = 1393; e.jabengali = 2460; e.jadeva = 2332; e.jagujarati = 2716; e.jagurmukhi = 2588; e.jbopomofo = 12560; e.jcaron = 496; e.jcircle = 9433; e.jcircumflex = 309; e.jcrossedtail = 669; e.jdotlessstroke = 607; e.jecyrillic = 1112; e.jeemarabic = 1580; e.jeemfinalarabic = 65182; e.jeeminitialarabic = 65183; e.jeemmedialarabic = 65184; e.jeharabic = 1688; e.jehfinalarabic = 64395; e.jhabengali = 2461; e.jhadeva = 2333; e.jhagujarati = 2717; e.jhagurmukhi = 2589; e.jheharmenian = 1403; e.jis = 12292; e.jmonospace = 65354; e.jparen = 9381; e.jsuperior = 690; e.k = 107; e.kabashkircyrillic = 1185; e.kabengali = 2453; e.kacute = 7729; e.kacyrillic = 1082; e.kadescendercyrillic = 1179; e.kadeva = 2325; e.kaf = 1499; e.kafarabic = 1603; e.kafdagesh = 64315; e.kafdageshhebrew = 64315; e.kaffinalarabic = 65242; e.kafhebrew = 1499; e.kafinitialarabic = 65243; e.kafmedialarabic = 65244; e.kafrafehebrew = 64333; e.kagujarati = 2709; e.kagurmukhi = 2581; e.kahiragana = 12363; e.kahookcyrillic = 1220; e.kakatakana = 12459; e.kakatakanahalfwidth = 65398; e.kappa = 954; e.kappasymbolgreek = 1008; e.kapyeounmieumkorean = 12657; e.kapyeounphieuphkorean = 12676; e.kapyeounpieupkorean = 12664; e.kapyeounssangpieupkorean = 12665; e.karoriisquare = 13069; e.kashidaautoarabic = 1600; e.kashidaautonosidebearingarabic = 1600; e.kasmallkatakana = 12533; e.kasquare = 13188; e.kasraarabic = 1616; e.kasratanarabic = 1613; e.kastrokecyrillic = 1183; e.katahiraprolongmarkhalfwidth = 65392; e.kaverticalstrokecyrillic = 1181; e.kbopomofo = 12558; e.kcalsquare = 13193; e.kcaron = 489; e.kcedilla = 311; e.kcircle = 9434; e.kcommaaccent = 311; e.kdotbelow = 7731; e.keharmenian = 1412; e.kehiragana = 12369; e.kekatakana = 12465; e.kekatakanahalfwidth = 65401; e.kenarmenian = 1391; e.kesmallkatakana = 12534; e.kgreenlandic = 312; e.khabengali = 2454; e.khacyrillic = 1093; e.khadeva = 2326; e.khagujarati = 2710; e.khagurmukhi = 2582; e.khaharabic = 1582; e.khahfinalarabic = 65190; e.khahinitialarabic = 65191; e.khahmedialarabic = 65192; e.kheicoptic = 999; e.khhadeva = 2393; e.khhagurmukhi = 2649; e.khieukhacirclekorean = 12920; e.khieukhaparenkorean = 12824; e.khieukhcirclekorean = 12906; e.khieukhkorean = 12619; e.khieukhparenkorean = 12810; e.khokhaithai = 3586; e.khokhonthai = 3589; e.khokhuatthai = 3587; e.khokhwaithai = 3588; e.khomutthai = 3675; e.khook = 409; e.khorakhangthai = 3590; e.khzsquare = 13201; e.kihiragana = 12365; e.kikatakana = 12461; e.kikatakanahalfwidth = 65399; e.kiroguramusquare = 13077; e.kiromeetorusquare = 13078; e.kirosquare = 13076; e.kiyeokacirclekorean = 12910; e.kiyeokaparenkorean = 12814; e.kiyeokcirclekorean = 12896; e.kiyeokkorean = 12593; e.kiyeokparenkorean = 12800; e.kiyeoksioskorean = 12595; e.kjecyrillic = 1116; e.klinebelow = 7733; e.klsquare = 13208; e.kmcubedsquare = 13222; e.kmonospace = 65355; e.kmsquaredsquare = 13218; e.kohiragana = 12371; e.kohmsquare = 13248; e.kokaithai = 3585; e.kokatakana = 12467; e.kokatakanahalfwidth = 65402; e.kooposquare = 13086; e.koppacyrillic = 1153; e.koreanstandardsymbol = 12927; e.koroniscmb = 835; e.kparen = 9382; e.kpasquare = 13226; e.ksicyrillic = 1135; e.ktsquare = 13263; e.kturned = 670; e.kuhiragana = 12367; e.kukatakana = 12463; e.kukatakanahalfwidth = 65400; e.kvsquare = 13240; e.kwsquare = 13246; e.l = 108; e.labengali = 2482; e.lacute = 314; e.ladeva = 2354; e.lagujarati = 2738; e.lagurmukhi = 2610; e.lakkhangyaothai = 3653; e.lamaleffinalarabic = 65276; e.lamalefhamzaabovefinalarabic = 65272; e.lamalefhamzaaboveisolatedarabic = 65271; e.lamalefhamzabelowfinalarabic = 65274; e.lamalefhamzabelowisolatedarabic = 65273; e.lamalefisolatedarabic = 65275; e.lamalefmaddaabovefinalarabic = 65270; e.lamalefmaddaaboveisolatedarabic = 65269; e.lamarabic = 1604; e.lambda = 955; e.lambdastroke = 411; e.lamed = 1500; e.lameddagesh = 64316; e.lameddageshhebrew = 64316; e.lamedhebrew = 1500; e.lamfinalarabic = 65246; e.lamhahinitialarabic = 64714; e.laminitialarabic = 65247; e.lamjeeminitialarabic = 64713; e.lamkhahinitialarabic = 64715; e.lamlamhehisolatedarabic = 65010; e.lammedialarabic = 65248; e.lammeemhahinitialarabic = 64904; e.lammeeminitialarabic = 64716; e.largecircle = 9711; e.lbar = 410; e.lbelt = 620; e.lbopomofo = 12556; e.lcaron = 318; e.lcedilla = 316; e.lcircle = 9435; e.lcircumflexbelow = 7741; e.lcommaaccent = 316; e.ldot = 320; e.ldotaccent = 320; e.ldotbelow = 7735; e.ldotbelowmacron = 7737; e.leftangleabovecmb = 794; e.lefttackbelowcmb = 792; e.less = 60; e.lessequal = 8804; e.lessequalorgreater = 8922; e.lessmonospace = 65308; e.lessorequivalent = 8818; e.lessorgreater = 8822; e.lessoverequal = 8806; e.lesssmall = 65124; e.lezh = 622; e.lfblock = 9612; e.lhookretroflex = 621; e.lira = 8356; e.liwnarmenian = 1388; e.lj = 457; e.ljecyrillic = 1113; e.ll = 63168; e.lladeva = 2355; e.llagujarati = 2739; e.llinebelow = 7739; e.llladeva = 2356; e.llvocalicbengali = 2529; e.llvocalicdeva = 2401; e.llvocalicvowelsignbengali = 2531; e.llvocalicvowelsigndeva = 2403; e.lmiddletilde = 619; e.lmonospace = 65356; e.lmsquare = 13264; e.lochulathai = 3628; e.logicaland = 8743; e.logicalnot = 172; e.logicalnotreversed = 8976; e.logicalor = 8744; e.lolingthai = 3621; e.longs = 383; e.lowlinecenterline = 65102; e.lowlinecmb = 818; e.lowlinedashed = 65101; e.lozenge = 9674; e.lparen = 9383; e.lslash = 322; e.lsquare = 8467; e.lsuperior = 63214; e.ltshade = 9617; e.luthai = 3622; e.lvocalicbengali = 2444; e.lvocalicdeva = 2316; e.lvocalicvowelsignbengali = 2530; e.lvocalicvowelsigndeva = 2402; e.lxsquare = 13267; e.m = 109; e.mabengali = 2478; e.macron = 175; e.macronbelowcmb = 817; e.macroncmb = 772; e.macronlowmod = 717; e.macronmonospace = 65507; e.macute = 7743; e.madeva = 2350; e.magujarati = 2734; e.magurmukhi = 2606; e.mahapakhhebrew = 1444; e.mahapakhlefthebrew = 1444; e.mahiragana = 12414; e.maichattawalowleftthai = 63637; e.maichattawalowrightthai = 63636; e.maichattawathai = 3659; e.maichattawaupperleftthai = 63635; e.maieklowleftthai = 63628; e.maieklowrightthai = 63627; e.maiekthai = 3656; e.maiekupperleftthai = 63626; e.maihanakatleftthai = 63620; e.maihanakatthai = 3633; e.maitaikhuleftthai = 63625; e.maitaikhuthai = 3655; e.maitholowleftthai = 63631; e.maitholowrightthai = 63630; e.maithothai = 3657; e.maithoupperleftthai = 63629; e.maitrilowleftthai = 63634; e.maitrilowrightthai = 63633; e.maitrithai = 3658; e.maitriupperleftthai = 63632; e.maiyamokthai = 3654; e.makatakana = 12510; e.makatakanahalfwidth = 65423; e.male = 9794; e.mansyonsquare = 13127; e.maqafhebrew = 1470; e.mars = 9794; e.masoracirclehebrew = 1455; e.masquare = 13187; e.mbopomofo = 12551; e.mbsquare = 13268; e.mcircle = 9436; e.mcubedsquare = 13221; e.mdotaccent = 7745; e.mdotbelow = 7747; e.meemarabic = 1605; e.meemfinalarabic = 65250; e.meeminitialarabic = 65251; e.meemmedialarabic = 65252; e.meemmeeminitialarabic = 64721; e.meemmeemisolatedarabic = 64584; e.meetorusquare = 13133; e.mehiragana = 12417; e.meizierasquare = 13182; e.mekatakana = 12513; e.mekatakanahalfwidth = 65426; e.mem = 1502; e.memdagesh = 64318; e.memdageshhebrew = 64318; e.memhebrew = 1502; e.menarmenian = 1396; e.merkhahebrew = 1445; e.merkhakefulahebrew = 1446; e.merkhakefulalefthebrew = 1446; e.merkhalefthebrew = 1445; e.mhook = 625; e.mhzsquare = 13202; e.middledotkatakanahalfwidth = 65381; e.middot = 183; e.mieumacirclekorean = 12914; e.mieumaparenkorean = 12818; e.mieumcirclekorean = 12900; e.mieumkorean = 12609; e.mieumpansioskorean = 12656; e.mieumparenkorean = 12804; e.mieumpieupkorean = 12654; e.mieumsioskorean = 12655; e.mihiragana = 12415; e.mikatakana = 12511; e.mikatakanahalfwidth = 65424; e.minus = 8722; e.minusbelowcmb = 800; e.minuscircle = 8854; e.minusmod = 727; e.minusplus = 8723; e.minute = 8242; e.miribaarusquare = 13130; e.mirisquare = 13129; e.mlonglegturned = 624; e.mlsquare = 13206; e.mmcubedsquare = 13219; e.mmonospace = 65357; e.mmsquaredsquare = 13215; e.mohiragana = 12418; e.mohmsquare = 13249; e.mokatakana = 12514; e.mokatakanahalfwidth = 65427; e.molsquare = 13270; e.momathai = 3617; e.moverssquare = 13223; e.moverssquaredsquare = 13224; e.mparen = 9384; e.mpasquare = 13227; e.mssquare = 13235; e.msuperior = 63215; e.mturned = 623; e.mu = 181; e.mu1 = 181; e.muasquare = 13186; e.muchgreater = 8811; e.muchless = 8810; e.mufsquare = 13196; e.mugreek = 956; e.mugsquare = 13197; e.muhiragana = 12416; e.mukatakana = 12512; e.mukatakanahalfwidth = 65425; e.mulsquare = 13205; e.multiply = 215; e.mumsquare = 13211; e.munahhebrew = 1443; e.munahlefthebrew = 1443; e.musicalnote = 9834; e.musicalnotedbl = 9835; e.musicflatsign = 9837; e.musicsharpsign = 9839; e.mussquare = 13234; e.muvsquare = 13238; e.muwsquare = 13244; e.mvmegasquare = 13241; e.mvsquare = 13239; e.mwmegasquare = 13247; e.mwsquare = 13245; e.n = 110; e.nabengali = 2472; e.nabla = 8711; e.nacute = 324; e.nadeva = 2344; e.nagujarati = 2728; e.nagurmukhi = 2600; e.nahiragana = 12394; e.nakatakana = 12490; e.nakatakanahalfwidth = 65413; e.napostrophe = 329; e.nasquare = 13185; e.nbopomofo = 12555; e.nbspace = 160; e.ncaron = 328; e.ncedilla = 326; e.ncircle = 9437; e.ncircumflexbelow = 7755; e.ncommaaccent = 326; e.ndotaccent = 7749; e.ndotbelow = 7751; e.nehiragana = 12397; e.nekatakana = 12493; e.nekatakanahalfwidth = 65416; e.newsheqelsign = 8362; e.nfsquare = 13195; e.ngabengali = 2457; e.ngadeva = 2329; e.ngagujarati = 2713; e.ngagurmukhi = 2585; e.ngonguthai = 3591; e.nhiragana = 12435; e.nhookleft = 626; e.nhookretroflex = 627; e.nieunacirclekorean = 12911; e.nieunaparenkorean = 12815; e.nieuncieuckorean = 12597; e.nieuncirclekorean = 12897; e.nieunhieuhkorean = 12598; e.nieunkorean = 12596; e.nieunpansioskorean = 12648; e.nieunparenkorean = 12801; e.nieunsioskorean = 12647; e.nieuntikeutkorean = 12646; e.nihiragana = 12395; e.nikatakana = 12491; e.nikatakanahalfwidth = 65414; e.nikhahitleftthai = 63641; e.nikhahitthai = 3661; e.nine = 57; e.ninearabic = 1641; e.ninebengali = 2543; e.ninecircle = 9320; e.ninecircleinversesansserif = 10130; e.ninedeva = 2415; e.ninegujarati = 2799; e.ninegurmukhi = 2671; e.ninehackarabic = 1641; e.ninehangzhou = 12329; e.nineideographicparen = 12840; e.nineinferior = 8329; e.ninemonospace = 65305; e.nineoldstyle = 63289; e.nineparen = 9340; e.nineperiod = 9360; e.ninepersian = 1785; e.nineroman = 8568; e.ninesuperior = 8313; e.nineteencircle = 9330; e.nineteenparen = 9350; e.nineteenperiod = 9370; e.ninethai = 3673; e.nj = 460; e.njecyrillic = 1114; e.nkatakana = 12531; e.nkatakanahalfwidth = 65437; e.nlegrightlong = 414; e.nlinebelow = 7753; e.nmonospace = 65358; e.nmsquare = 13210; e.nnabengali = 2467; e.nnadeva = 2339; e.nnagujarati = 2723; e.nnagurmukhi = 2595; e.nnnadeva = 2345; e.nohiragana = 12398; e.nokatakana = 12494; e.nokatakanahalfwidth = 65417; e.nonbreakingspace = 160; e.nonenthai = 3603; e.nonuthai = 3609; e.noonarabic = 1606; e.noonfinalarabic = 65254; e.noonghunnaarabic = 1722; e.noonghunnafinalarabic = 64415; e.nooninitialarabic = 65255; e.noonjeeminitialarabic = 64722; e.noonjeemisolatedarabic = 64587; e.noonmedialarabic = 65256; e.noonmeeminitialarabic = 64725; e.noonmeemisolatedarabic = 64590; e.noonnoonfinalarabic = 64653; e.notcontains = 8716; e.notelement = 8713; e.notelementof = 8713; e.notequal = 8800; e.notgreater = 8815; e.notgreaternorequal = 8817; e.notgreaternorless = 8825; e.notidentical = 8802; e.notless = 8814; e.notlessnorequal = 8816; e.notparallel = 8742; e.notprecedes = 8832; e.notsubset = 8836; e.notsucceeds = 8833; e.notsuperset = 8837; e.nowarmenian = 1398; e.nparen = 9385; e.nssquare = 13233; e.nsuperior = 8319; e.ntilde = 241; e.nu = 957; e.nuhiragana = 12396; e.nukatakana = 12492; e.nukatakanahalfwidth = 65415; e.nuktabengali = 2492; e.nuktadeva = 2364; e.nuktagujarati = 2748; e.nuktagurmukhi = 2620; e.numbersign = 35; e.numbersignmonospace = 65283; e.numbersignsmall = 65119; e.numeralsigngreek = 884; e.numeralsignlowergreek = 885; e.numero = 8470; e.nun = 1504; e.nundagesh = 64320; e.nundageshhebrew = 64320; e.nunhebrew = 1504; e.nvsquare = 13237; e.nwsquare = 13243; e.nyabengali = 2462; e.nyadeva = 2334; e.nyagujarati = 2718; e.nyagurmukhi = 2590; e.o = 111; e.oacute = 243; e.oangthai = 3629; e.obarred = 629; e.obarredcyrillic = 1257; e.obarreddieresiscyrillic = 1259; e.obengali = 2451; e.obopomofo = 12571; e.obreve = 335; e.ocandradeva = 2321; e.ocandragujarati = 2705; e.ocandravowelsigndeva = 2377; e.ocandravowelsigngujarati = 2761; e.ocaron = 466; e.ocircle = 9438; e.ocircumflex = 244; e.ocircumflexacute = 7889; e.ocircumflexdotbelow = 7897; e.ocircumflexgrave = 7891; e.ocircumflexhookabove = 7893; e.ocircumflextilde = 7895; e.ocyrillic = 1086; e.odblacute = 337; e.odblgrave = 525; e.odeva = 2323; e.odieresis = 246; e.odieresiscyrillic = 1255; e.odotbelow = 7885; e.oe = 339; e.oekorean = 12634; e.ogonek = 731; e.ogonekcmb = 808; e.ograve = 242; e.ogujarati = 2707; e.oharmenian = 1413; e.ohiragana = 12362; e.ohookabove = 7887; e.ohorn = 417; e.ohornacute = 7899; e.ohorndotbelow = 7907; e.ohorngrave = 7901; e.ohornhookabove = 7903; e.ohorntilde = 7905; e.ohungarumlaut = 337; e.oi = 419; e.oinvertedbreve = 527; e.okatakana = 12458; e.okatakanahalfwidth = 65397; e.okorean = 12631; e.olehebrew = 1451; e.omacron = 333; e.omacronacute = 7763; e.omacrongrave = 7761; e.omdeva = 2384; e.omega = 969; e.omega1 = 982; e.omegacyrillic = 1121; e.omegalatinclosed = 631; e.omegaroundcyrillic = 1147; e.omegatitlocyrillic = 1149; e.omegatonos = 974; e.omgujarati = 2768; e.omicron = 959; e.omicrontonos = 972; e.omonospace = 65359; e.one = 49; e.onearabic = 1633; e.onebengali = 2535; e.onecircle = 9312; e.onecircleinversesansserif = 10122; e.onedeva = 2407; e.onedotenleader = 8228; e.oneeighth = 8539; e.onefitted = 63196; e.onegujarati = 2791; e.onegurmukhi = 2663; e.onehackarabic = 1633; e.onehalf = 189; e.onehangzhou = 12321; e.oneideographicparen = 12832; e.oneinferior = 8321; e.onemonospace = 65297; e.onenumeratorbengali = 2548; e.oneoldstyle = 63281; e.oneparen = 9332; e.oneperiod = 9352; e.onepersian = 1777; e.onequarter = 188; e.oneroman = 8560; e.onesuperior = 185; e.onethai = 3665; e.onethird = 8531; e.oogonek = 491; e.oogonekmacron = 493; e.oogurmukhi = 2579; e.oomatragurmukhi = 2635; e.oopen = 596; e.oparen = 9386; e.openbullet = 9702; e.option = 8997; e.ordfeminine = 170; e.ordmasculine = 186; e.orthogonal = 8735; e.oshortdeva = 2322; e.oshortvowelsigndeva = 2378; e.oslash = 248; e.oslashacute = 511; e.osmallhiragana = 12361; e.osmallkatakana = 12457; e.osmallkatakanahalfwidth = 65387; e.ostrokeacute = 511; e.osuperior = 63216; e.otcyrillic = 1151; e.otilde = 245; e.otildeacute = 7757; e.otildedieresis = 7759; e.oubopomofo = 12577; e.overline = 8254; e.overlinecenterline = 65098; e.overlinecmb = 773; e.overlinedashed = 65097; e.overlinedblwavy = 65100; e.overlinewavy = 65099; e.overscore = 175; e.ovowelsignbengali = 2507; e.ovowelsigndeva = 2379; e.ovowelsigngujarati = 2763; e.p = 112; e.paampssquare = 13184; e.paasentosquare = 13099; e.pabengali = 2474; e.pacute = 7765; e.padeva = 2346; e.pagedown = 8671; e.pageup = 8670; e.pagujarati = 2730; e.pagurmukhi = 2602; e.pahiragana = 12401; e.paiyannoithai = 3631; e.pakatakana = 12497; e.palatalizationcyrilliccmb = 1156; e.palochkacyrillic = 1216; e.pansioskorean = 12671; e.paragraph = 182; e.parallel = 8741; e.parenleft = 40; e.parenleftaltonearabic = 64830; e.parenleftbt = 63725; e.parenleftex = 63724; e.parenleftinferior = 8333; e.parenleftmonospace = 65288; e.parenleftsmall = 65113; e.parenleftsuperior = 8317; e.parenlefttp = 63723; e.parenleftvertical = 65077; e.parenright = 41; e.parenrightaltonearabic = 64831; e.parenrightbt = 63736; e.parenrightex = 63735; e.parenrightinferior = 8334; e.parenrightmonospace = 65289; e.parenrightsmall = 65114; e.parenrightsuperior = 8318; e.parenrighttp = 63734; e.parenrightvertical = 65078; e.partialdiff = 8706; e.paseqhebrew = 1472; e.pashtahebrew = 1433; e.pasquare = 13225; e.patah = 1463; e.patah11 = 1463; e.patah1d = 1463; e.patah2a = 1463; e.patahhebrew = 1463; e.patahnarrowhebrew = 1463; e.patahquarterhebrew = 1463; e.patahwidehebrew = 1463; e.pazerhebrew = 1441; e.pbopomofo = 12550; e.pcircle = 9439; e.pdotaccent = 7767; e.pe = 1508; e.pecyrillic = 1087; e.pedagesh = 64324; e.pedageshhebrew = 64324; e.peezisquare = 13115; e.pefinaldageshhebrew = 64323; e.peharabic = 1662; e.peharmenian = 1402; e.pehebrew = 1508; e.pehfinalarabic = 64343; e.pehinitialarabic = 64344; e.pehiragana = 12410; e.pehmedialarabic = 64345; e.pekatakana = 12506; e.pemiddlehookcyrillic = 1191; e.perafehebrew = 64334; e.percent = 37; e.percentarabic = 1642; e.percentmonospace = 65285; e.percentsmall = 65130; e.period = 46; e.periodarmenian = 1417; e.periodcentered = 183; e.periodhalfwidth = 65377; e.periodinferior = 63207; e.periodmonospace = 65294; e.periodsmall = 65106; e.periodsuperior = 63208; e.perispomenigreekcmb = 834; e.perpendicular = 8869; e.perthousand = 8240; e.peseta = 8359; e.pfsquare = 13194; e.phabengali = 2475; e.phadeva = 2347; e.phagujarati = 2731; e.phagurmukhi = 2603; e.phi = 966; e.phi1 = 981; e.phieuphacirclekorean = 12922; e.phieuphaparenkorean = 12826; e.phieuphcirclekorean = 12908; e.phieuphkorean = 12621; e.phieuphparenkorean = 12812; e.philatin = 632; e.phinthuthai = 3642; e.phisymbolgreek = 981; e.phook = 421; e.phophanthai = 3614; e.phophungthai = 3612; e.phosamphaothai = 3616; e.pi = 960; e.pieupacirclekorean = 12915; e.pieupaparenkorean = 12819; e.pieupcieuckorean = 12662; e.pieupcirclekorean = 12901; e.pieupkiyeokkorean = 12658; e.pieupkorean = 12610; e.pieupparenkorean = 12805; e.pieupsioskiyeokkorean = 12660; e.pieupsioskorean = 12612; e.pieupsiostikeutkorean = 12661; e.pieupthieuthkorean = 12663; e.pieuptikeutkorean = 12659; e.pihiragana = 12404; e.pikatakana = 12500; e.pisymbolgreek = 982; e.piwrarmenian = 1411; e.plus = 43; e.plusbelowcmb = 799; e.pluscircle = 8853; e.plusminus = 177; e.plusmod = 726; e.plusmonospace = 65291; e.plussmall = 65122; e.plussuperior = 8314; e.pmonospace = 65360; e.pmsquare = 13272; e.pohiragana = 12413; e.pointingindexdownwhite = 9759; e.pointingindexleftwhite = 9756; e.pointingindexrightwhite = 9758; e.pointingindexupwhite = 9757; e.pokatakana = 12509; e.poplathai = 3611; e.postalmark = 12306; e.postalmarkface = 12320; e.pparen = 9387; e.precedes = 8826; e.prescription = 8478; e.primemod = 697; e.primereversed = 8245; e.product = 8719; e.projective = 8965; e.prolongedkana = 12540; e.propellor = 8984; e.propersubset = 8834; e.propersuperset = 8835; e.proportion = 8759; e.proportional = 8733; e.psi = 968; e.psicyrillic = 1137; e.psilipneumatacyrilliccmb = 1158; e.pssquare = 13232; e.puhiragana = 12407; e.pukatakana = 12503; e.pvsquare = 13236; e.pwsquare = 13242; e.q = 113; e.qadeva = 2392; e.qadmahebrew = 1448; e.qafarabic = 1602; e.qaffinalarabic = 65238; e.qafinitialarabic = 65239; e.qafmedialarabic = 65240; e.qamats = 1464; e.qamats10 = 1464; e.qamats1a = 1464; e.qamats1c = 1464; e.qamats27 = 1464; e.qamats29 = 1464; e.qamats33 = 1464; e.qamatsde = 1464; e.qamatshebrew = 1464; e.qamatsnarrowhebrew = 1464; e.qamatsqatanhebrew = 1464; e.qamatsqatannarrowhebrew = 1464; e.qamatsqatanquarterhebrew = 1464; e.qamatsqatanwidehebrew = 1464; e.qamatsquarterhebrew = 1464; e.qamatswidehebrew = 1464; e.qarneyparahebrew = 1439; e.qbopomofo = 12561; e.qcircle = 9440; e.qhook = 672; e.qmonospace = 65361; e.qof = 1511; e.qofdagesh = 64327; e.qofdageshhebrew = 64327; e.qofhebrew = 1511; e.qparen = 9388; e.quarternote = 9833; e.qubuts = 1467; e.qubuts18 = 1467; e.qubuts25 = 1467; e.qubuts31 = 1467; e.qubutshebrew = 1467; e.qubutsnarrowhebrew = 1467; e.qubutsquarterhebrew = 1467; e.qubutswidehebrew = 1467; e.question = 63; e.questionarabic = 1567; e.questionarmenian = 1374; e.questiondown = 191; e.questiondownsmall = 63423; e.questiongreek = 894; e.questionmonospace = 65311; e.questionsmall = 63295; e.quotedbl = 34; e.quotedblbase = 8222; e.quotedblleft = 8220; e.quotedblmonospace = 65282; e.quotedblprime = 12318; e.quotedblprimereversed = 12317; e.quotedblright = 8221; e.quoteleft = 8216; e.quoteleftreversed = 8219; e.quotereversed = 8219; e.quoteright = 8217; e.quoterightn = 329; e.quotesinglbase = 8218; e.quotesingle = 39; e.quotesinglemonospace = 65287; e.r = 114; e.raarmenian = 1404; e.rabengali = 2480; e.racute = 341; e.radeva = 2352; e.radical = 8730; e.radicalex = 63717; e.radoverssquare = 13230; e.radoverssquaredsquare = 13231; e.radsquare = 13229; e.rafe = 1471; e.rafehebrew = 1471; e.ragujarati = 2736; e.ragurmukhi = 2608; e.rahiragana = 12425; e.rakatakana = 12521; e.rakatakanahalfwidth = 65431; e.ralowerdiagonalbengali = 2545; e.ramiddlediagonalbengali = 2544; e.ramshorn = 612; e.ratio = 8758; e.rbopomofo = 12566; e.rcaron = 345; e.rcedilla = 343; e.rcircle = 9441; e.rcommaaccent = 343; e.rdblgrave = 529; e.rdotaccent = 7769; e.rdotbelow = 7771; e.rdotbelowmacron = 7773; e.referencemark = 8251; e.reflexsubset = 8838; e.reflexsuperset = 8839; e.registered = 174; e.registersans = 63720; e.registerserif = 63194; e.reharabic = 1585; e.reharmenian = 1408; e.rehfinalarabic = 65198; e.rehiragana = 12428; e.rekatakana = 12524; e.rekatakanahalfwidth = 65434; e.resh = 1512; e.reshdageshhebrew = 64328; e.reshhebrew = 1512; e.reversedtilde = 8765; e.reviahebrew = 1431; e.reviamugrashhebrew = 1431; e.revlogicalnot = 8976; e.rfishhook = 638; e.rfishhookreversed = 639; e.rhabengali = 2525; e.rhadeva = 2397; e.rho = 961; e.rhook = 637; e.rhookturned = 635; e.rhookturnedsuperior = 693; e.rhosymbolgreek = 1009; e.rhotichookmod = 734; e.rieulacirclekorean = 12913; e.rieulaparenkorean = 12817; e.rieulcirclekorean = 12899; e.rieulhieuhkorean = 12608; e.rieulkiyeokkorean = 12602; e.rieulkiyeoksioskorean = 12649; e.rieulkorean = 12601; e.rieulmieumkorean = 12603; e.rieulpansioskorean = 12652; e.rieulparenkorean = 12803; e.rieulphieuphkorean = 12607; e.rieulpieupkorean = 12604; e.rieulpieupsioskorean = 12651; e.rieulsioskorean = 12605; e.rieulthieuthkorean = 12606; e.rieultikeutkorean = 12650; e.rieulyeorinhieuhkorean = 12653; e.rightangle = 8735; e.righttackbelowcmb = 793; e.righttriangle = 8895; e.rihiragana = 12426; e.rikatakana = 12522; e.rikatakanahalfwidth = 65432; e.ring = 730; e.ringbelowcmb = 805; e.ringcmb = 778; e.ringhalfleft = 703; e.ringhalfleftarmenian = 1369; e.ringhalfleftbelowcmb = 796; e.ringhalfleftcentered = 723; e.ringhalfright = 702; e.ringhalfrightbelowcmb = 825; e.ringhalfrightcentered = 722; e.rinvertedbreve = 531; e.rittorusquare = 13137; e.rlinebelow = 7775; e.rlongleg = 636; e.rlonglegturned = 634; e.rmonospace = 65362; e.rohiragana = 12429; e.rokatakana = 12525; e.rokatakanahalfwidth = 65435; e.roruathai = 3619; e.rparen = 9389; e.rrabengali = 2524; e.rradeva = 2353; e.rragurmukhi = 2652; e.rreharabic = 1681; e.rrehfinalarabic = 64397; e.rrvocalicbengali = 2528; e.rrvocalicdeva = 2400; e.rrvocalicgujarati = 2784; e.rrvocalicvowelsignbengali = 2500; e.rrvocalicvowelsigndeva = 2372; e.rrvocalicvowelsigngujarati = 2756; e.rsuperior = 63217; e.rtblock = 9616; e.rturned = 633; e.rturnedsuperior = 692; e.ruhiragana = 12427; e.rukatakana = 12523; e.rukatakanahalfwidth = 65433; e.rupeemarkbengali = 2546; e.rupeesignbengali = 2547; e.rupiah = 63197; e.ruthai = 3620; e.rvocalicbengali = 2443; e.rvocalicdeva = 2315; e.rvocalicgujarati = 2699; e.rvocalicvowelsignbengali = 2499; e.rvocalicvowelsigndeva = 2371; e.rvocalicvowelsigngujarati = 2755; e.s = 115; e.sabengali = 2488; e.sacute = 347; e.sacutedotaccent = 7781; e.sadarabic = 1589; e.sadeva = 2360; e.sadfinalarabic = 65210; e.sadinitialarabic = 65211; e.sadmedialarabic = 65212; e.sagujarati = 2744; e.sagurmukhi = 2616; e.sahiragana = 12373; e.sakatakana = 12469; e.sakatakanahalfwidth = 65403; e.sallallahoualayhewasallamarabic = 65018; e.samekh = 1505; e.samekhdagesh = 64321; e.samekhdageshhebrew = 64321; e.samekhhebrew = 1505; e.saraaathai = 3634; e.saraaethai = 3649; e.saraaimaimalaithai = 3652; e.saraaimaimuanthai = 3651; e.saraamthai = 3635; e.saraathai = 3632; e.saraethai = 3648; e.saraiileftthai = 63622; e.saraiithai = 3637; e.saraileftthai = 63621; e.saraithai = 3636; e.saraothai = 3650; e.saraueeleftthai = 63624; e.saraueethai = 3639; e.saraueleftthai = 63623; e.sarauethai = 3638; e.sarauthai = 3640; e.sarauuthai = 3641; e.sbopomofo = 12569; e.scaron = 353; e.scarondotaccent = 7783; e.scedilla = 351; e.schwa = 601; e.schwacyrillic = 1241; e.schwadieresiscyrillic = 1243; e.schwahook = 602; e.scircle = 9442; e.scircumflex = 349; e.scommaaccent = 537; e.sdotaccent = 7777; e.sdotbelow = 7779; e.sdotbelowdotaccent = 7785; e.seagullbelowcmb = 828; e.second = 8243; e.secondtonechinese = 714; e.section = 167; e.seenarabic = 1587; e.seenfinalarabic = 65202; e.seeninitialarabic = 65203; e.seenmedialarabic = 65204; e.segol = 1462; e.segol13 = 1462; e.segol1f = 1462; e.segol2c = 1462; e.segolhebrew = 1462; e.segolnarrowhebrew = 1462; e.segolquarterhebrew = 1462; e.segoltahebrew = 1426; e.segolwidehebrew = 1462; e.seharmenian = 1405; e.sehiragana = 12379; e.sekatakana = 12475; e.sekatakanahalfwidth = 65406; e.semicolon = 59; e.semicolonarabic = 1563; e.semicolonmonospace = 65307; e.semicolonsmall = 65108; e.semivoicedmarkkana = 12444; e.semivoicedmarkkanahalfwidth = 65439; e.sentisquare = 13090; e.sentosquare = 13091; e.seven = 55; e.sevenarabic = 1639; e.sevenbengali = 2541; e.sevencircle = 9318; e.sevencircleinversesansserif = 10128; e.sevendeva = 2413; e.seveneighths = 8542; e.sevengujarati = 2797; e.sevengurmukhi = 2669; e.sevenhackarabic = 1639; e.sevenhangzhou = 12327; e.sevenideographicparen = 12838; e.seveninferior = 8327; e.sevenmonospace = 65303; e.sevenoldstyle = 63287; e.sevenparen = 9338; e.sevenperiod = 9358; e.sevenpersian = 1783; e.sevenroman = 8566; e.sevensuperior = 8311; e.seventeencircle = 9328; e.seventeenparen = 9348; e.seventeenperiod = 9368; e.seventhai = 3671; e.sfthyphen = 173; e.shaarmenian = 1399; e.shabengali = 2486; e.shacyrillic = 1096; e.shaddaarabic = 1617; e.shaddadammaarabic = 64609; e.shaddadammatanarabic = 64606; e.shaddafathaarabic = 64608; e.shaddakasraarabic = 64610; e.shaddakasratanarabic = 64607; e.shade = 9618; e.shadedark = 9619; e.shadelight = 9617; e.shademedium = 9618; e.shadeva = 2358; e.shagujarati = 2742; e.shagurmukhi = 2614; e.shalshelethebrew = 1427; e.shbopomofo = 12565; e.shchacyrillic = 1097; e.sheenarabic = 1588; e.sheenfinalarabic = 65206; e.sheeninitialarabic = 65207; e.sheenmedialarabic = 65208; e.sheicoptic = 995; e.sheqel = 8362; e.sheqelhebrew = 8362; e.sheva = 1456; e.sheva115 = 1456; e.sheva15 = 1456; e.sheva22 = 1456; e.sheva2e = 1456; e.shevahebrew = 1456; e.shevanarrowhebrew = 1456; e.shevaquarterhebrew = 1456; e.shevawidehebrew = 1456; e.shhacyrillic = 1211; e.shimacoptic = 1005; e.shin = 1513; e.shindagesh = 64329; e.shindageshhebrew = 64329; e.shindageshshindot = 64300; e.shindageshshindothebrew = 64300; e.shindageshsindot = 64301; e.shindageshsindothebrew = 64301; e.shindothebrew = 1473; e.shinhebrew = 1513; e.shinshindot = 64298; e.shinshindothebrew = 64298; e.shinsindot = 64299; e.shinsindothebrew = 64299; e.shook = 642; e.sigma = 963; e.sigma1 = 962; e.sigmafinal = 962; e.sigmalunatesymbolgreek = 1010; e.sihiragana = 12375; e.sikatakana = 12471; e.sikatakanahalfwidth = 65404; e.siluqhebrew = 1469; e.siluqlefthebrew = 1469; e.similar = 8764; e.sindothebrew = 1474; e.siosacirclekorean = 12916; e.siosaparenkorean = 12820; e.sioscieuckorean = 12670; e.sioscirclekorean = 12902; e.sioskiyeokkorean = 12666; e.sioskorean = 12613; e.siosnieunkorean = 12667; e.siosparenkorean = 12806; e.siospieupkorean = 12669; e.siostikeutkorean = 12668; e.six = 54; e.sixarabic = 1638; e.sixbengali = 2540; e.sixcircle = 9317; e.sixcircleinversesansserif = 10127; e.sixdeva = 2412; e.sixgujarati = 2796; e.sixgurmukhi = 2668; e.sixhackarabic = 1638; e.sixhangzhou = 12326; e.sixideographicparen = 12837; e.sixinferior = 8326; e.sixmonospace = 65302; e.sixoldstyle = 63286; e.sixparen = 9337; e.sixperiod = 9357; e.sixpersian = 1782; e.sixroman = 8565; e.sixsuperior = 8310; e.sixteencircle = 9327; e.sixteencurrencydenominatorbengali = 2553; e.sixteenparen = 9347; e.sixteenperiod = 9367; e.sixthai = 3670; e.slash = 47; e.slashmonospace = 65295; e.slong = 383; e.slongdotaccent = 7835; e.smileface = 9786; e.smonospace = 65363; e.sofpasuqhebrew = 1475; e.softhyphen = 173; e.softsigncyrillic = 1100; e.sohiragana = 12381; e.sokatakana = 12477; e.sokatakanahalfwidth = 65407; e.soliduslongoverlaycmb = 824; e.solidusshortoverlaycmb = 823; e.sorusithai = 3625; e.sosalathai = 3624; e.sosothai = 3595; e.sosuathai = 3626; e.space = 32; e.spacehackarabic = 32; e.spade = 9824; e.spadesuitblack = 9824; e.spadesuitwhite = 9828; e.sparen = 9390; e.squarebelowcmb = 827; e.squarecc = 13252; e.squarecm = 13213; e.squarediagonalcrosshatchfill = 9641; e.squarehorizontalfill = 9636; e.squarekg = 13199; e.squarekm = 13214; e.squarekmcapital = 13262; e.squareln = 13265; e.squarelog = 13266; e.squaremg = 13198; e.squaremil = 13269; e.squaremm = 13212; e.squaremsquared = 13217; e.squareorthogonalcrosshatchfill = 9638; e.squareupperlefttolowerrightfill = 9639; e.squareupperrighttolowerleftfill = 9640; e.squareverticalfill = 9637; e.squarewhitewithsmallblack = 9635; e.srsquare = 13275; e.ssabengali = 2487; e.ssadeva = 2359; e.ssagujarati = 2743; e.ssangcieuckorean = 12617; e.ssanghieuhkorean = 12677; e.ssangieungkorean = 12672; e.ssangkiyeokkorean = 12594; e.ssangnieunkorean = 12645; e.ssangpieupkorean = 12611; e.ssangsioskorean = 12614; e.ssangtikeutkorean = 12600; e.ssuperior = 63218; e.sterling = 163; e.sterlingmonospace = 65505; e.strokelongoverlaycmb = 822; e.strokeshortoverlaycmb = 821; e.subset = 8834; e.subsetnotequal = 8842; e.subsetorequal = 8838; e.succeeds = 8827; e.suchthat = 8715; e.suhiragana = 12377; e.sukatakana = 12473; e.sukatakanahalfwidth = 65405; e.sukunarabic = 1618; e.summation = 8721; e.sun = 9788; e.superset = 8835; e.supersetnotequal = 8843; e.supersetorequal = 8839; e.svsquare = 13276; e.syouwaerasquare = 13180; e.t = 116; e.tabengali = 2468; e.tackdown = 8868; e.tackleft = 8867; e.tadeva = 2340; e.tagujarati = 2724; e.tagurmukhi = 2596; e.taharabic = 1591; e.tahfinalarabic = 65218; e.tahinitialarabic = 65219; e.tahiragana = 12383; e.tahmedialarabic = 65220; e.taisyouerasquare = 13181; e.takatakana = 12479; e.takatakanahalfwidth = 65408; e.tatweelarabic = 1600; e.tau = 964; e.tav = 1514; e.tavdages = 64330; e.tavdagesh = 64330; e.tavdageshhebrew = 64330; e.tavhebrew = 1514; e.tbar = 359; e.tbopomofo = 12554; e.tcaron = 357; e.tccurl = 680; e.tcedilla = 355; e.tcheharabic = 1670; e.tchehfinalarabic = 64379; e.tchehinitialarabic = 64380; e.tchehmedialarabic = 64381; e.tcircle = 9443; e.tcircumflexbelow = 7793; e.tcommaaccent = 355; e.tdieresis = 7831; e.tdotaccent = 7787; e.tdotbelow = 7789; e.tecyrillic = 1090; e.tedescendercyrillic = 1197; e.teharabic = 1578; e.tehfinalarabic = 65174; e.tehhahinitialarabic = 64674; e.tehhahisolatedarabic = 64524; e.tehinitialarabic = 65175; e.tehiragana = 12390; e.tehjeeminitialarabic = 64673; e.tehjeemisolatedarabic = 64523; e.tehmarbutaarabic = 1577; e.tehmarbutafinalarabic = 65172; e.tehmedialarabic = 65176; e.tehmeeminitialarabic = 64676; e.tehmeemisolatedarabic = 64526; e.tehnoonfinalarabic = 64627; e.tekatakana = 12486; e.tekatakanahalfwidth = 65411; e.telephone = 8481; e.telephoneblack = 9742; e.telishagedolahebrew = 1440; e.telishaqetanahebrew = 1449; e.tencircle = 9321; e.tenideographicparen = 12841; e.tenparen = 9341; e.tenperiod = 9361; e.tenroman = 8569; e.tesh = 679; e.tet = 1496; e.tetdagesh = 64312; e.tetdageshhebrew = 64312; e.tethebrew = 1496; e.tetsecyrillic = 1205; e.tevirhebrew = 1435; e.tevirlefthebrew = 1435; e.thabengali = 2469; e.thadeva = 2341; e.thagujarati = 2725; e.thagurmukhi = 2597; e.thalarabic = 1584; e.thalfinalarabic = 65196; e.thanthakhatlowleftthai = 63640; e.thanthakhatlowrightthai = 63639; e.thanthakhatthai = 3660; e.thanthakhatupperleftthai = 63638; e.theharabic = 1579; e.thehfinalarabic = 65178; e.thehinitialarabic = 65179; e.thehmedialarabic = 65180; e.thereexists = 8707; e.therefore = 8756; e.theta = 952; e.theta1 = 977; e.thetasymbolgreek = 977; e.thieuthacirclekorean = 12921; e.thieuthaparenkorean = 12825; e.thieuthcirclekorean = 12907; e.thieuthkorean = 12620; e.thieuthparenkorean = 12811; e.thirteencircle = 9324; e.thirteenparen = 9344; e.thirteenperiod = 9364; e.thonangmonthothai = 3601; e.thook = 429; e.thophuthaothai = 3602; e.thorn = 254; e.thothahanthai = 3607; e.thothanthai = 3600; e.thothongthai = 3608; e.thothungthai = 3606; e.thousandcyrillic = 1154; e.thousandsseparatorarabic = 1644; e.thousandsseparatorpersian = 1644; e.three = 51; e.threearabic = 1635; e.threebengali = 2537; e.threecircle = 9314; e.threecircleinversesansserif = 10124; e.threedeva = 2409; e.threeeighths = 8540; e.threegujarati = 2793; e.threegurmukhi = 2665; e.threehackarabic = 1635; e.threehangzhou = 12323; e.threeideographicparen = 12834; e.threeinferior = 8323; e.threemonospace = 65299; e.threenumeratorbengali = 2550; e.threeoldstyle = 63283; e.threeparen = 9334; e.threeperiod = 9354; e.threepersian = 1779; e.threequarters = 190; e.threequartersemdash = 63198; e.threeroman = 8562; e.threesuperior = 179; e.threethai = 3667; e.thzsquare = 13204; e.tihiragana = 12385; e.tikatakana = 12481; e.tikatakanahalfwidth = 65409; e.tikeutacirclekorean = 12912; e.tikeutaparenkorean = 12816; e.tikeutcirclekorean = 12898; e.tikeutkorean = 12599; e.tikeutparenkorean = 12802; e.tilde = 732; e.tildebelowcmb = 816; e.tildecmb = 771; e.tildecomb = 771; e.tildedoublecmb = 864; e.tildeoperator = 8764; e.tildeoverlaycmb = 820; e.tildeverticalcmb = 830; e.timescircle = 8855; e.tipehahebrew = 1430; e.tipehalefthebrew = 1430; e.tippigurmukhi = 2672; e.titlocyrilliccmb = 1155; e.tiwnarmenian = 1407; e.tlinebelow = 7791; e.tmonospace = 65364; e.toarmenian = 1385; e.tohiragana = 12392; e.tokatakana = 12488; e.tokatakanahalfwidth = 65412; e.tonebarextrahighmod = 741; e.tonebarextralowmod = 745; e.tonebarhighmod = 742; e.tonebarlowmod = 744; e.tonebarmidmod = 743; e.tonefive = 445; e.tonesix = 389; e.tonetwo = 424; e.tonos = 900; e.tonsquare = 13095; e.topatakthai = 3599; e.tortoiseshellbracketleft = 12308; e.tortoiseshellbracketleftsmall = 65117; e.tortoiseshellbracketleftvertical = 65081; e.tortoiseshellbracketright = 12309; e.tortoiseshellbracketrightsmall = 65118; e.tortoiseshellbracketrightvertical = 65082; e.totaothai = 3605; e.tpalatalhook = 427; e.tparen = 9391; e.trademark = 8482; e.trademarksans = 63722; e.trademarkserif = 63195; e.tretroflexhook = 648; e.triagdn = 9660; e.triaglf = 9668; e.triagrt = 9658; e.triagup = 9650; e.ts = 678; e.tsadi = 1510; e.tsadidagesh = 64326; e.tsadidageshhebrew = 64326; e.tsadihebrew = 1510; e.tsecyrillic = 1094; e.tsere = 1461; e.tsere12 = 1461; e.tsere1e = 1461; e.tsere2b = 1461; e.tserehebrew = 1461; e.tserenarrowhebrew = 1461; e.tserequarterhebrew = 1461; e.tserewidehebrew = 1461; e.tshecyrillic = 1115; e.tsuperior = 63219; e.ttabengali = 2463; e.ttadeva = 2335; e.ttagujarati = 2719; e.ttagurmukhi = 2591; e.tteharabic = 1657; e.ttehfinalarabic = 64359; e.ttehinitialarabic = 64360; e.ttehmedialarabic = 64361; e.tthabengali = 2464; e.tthadeva = 2336; e.tthagujarati = 2720; e.tthagurmukhi = 2592; e.tturned = 647; e.tuhiragana = 12388; e.tukatakana = 12484; e.tukatakanahalfwidth = 65410; e.tusmallhiragana = 12387; e.tusmallkatakana = 12483; e.tusmallkatakanahalfwidth = 65391; e.twelvecircle = 9323; e.twelveparen = 9343; e.twelveperiod = 9363; e.twelveroman = 8571; e.twentycircle = 9331; e.twentyhangzhou = 21316; e.twentyparen = 9351; e.twentyperiod = 9371; e.two = 50; e.twoarabic = 1634; e.twobengali = 2536; e.twocircle = 9313; e.twocircleinversesansserif = 10123; e.twodeva = 2408; e.twodotenleader = 8229; e.twodotleader = 8229; e.twodotleadervertical = 65072; e.twogujarati = 2792; e.twogurmukhi = 2664; e.twohackarabic = 1634; e.twohangzhou = 12322; e.twoideographicparen = 12833; e.twoinferior = 8322; e.twomonospace = 65298; e.twonumeratorbengali = 2549; e.twooldstyle = 63282; e.twoparen = 9333; e.twoperiod = 9353; e.twopersian = 1778; e.tworoman = 8561; e.twostroke = 443; e.twosuperior = 178; e.twothai = 3666; e.twothirds = 8532; e.u = 117; e.uacute = 250; e.ubar = 649; e.ubengali = 2441; e.ubopomofo = 12584; e.ubreve = 365; e.ucaron = 468; e.ucircle = 9444; e.ucircumflex = 251; e.ucircumflexbelow = 7799; e.ucyrillic = 1091; e.udattadeva = 2385; e.udblacute = 369; e.udblgrave = 533; e.udeva = 2313; e.udieresis = 252; e.udieresisacute = 472; e.udieresisbelow = 7795; e.udieresiscaron = 474; e.udieresiscyrillic = 1265; e.udieresisgrave = 476; e.udieresismacron = 470; e.udotbelow = 7909; e.ugrave = 249; e.ugujarati = 2697; e.ugurmukhi = 2569; e.uhiragana = 12358; e.uhookabove = 7911; e.uhorn = 432; e.uhornacute = 7913; e.uhorndotbelow = 7921; e.uhorngrave = 7915; e.uhornhookabove = 7917; e.uhorntilde = 7919; e.uhungarumlaut = 369; e.uhungarumlautcyrillic = 1267; e.uinvertedbreve = 535; e.ukatakana = 12454; e.ukatakanahalfwidth = 65395; e.ukcyrillic = 1145; e.ukorean = 12636; e.umacron = 363; e.umacroncyrillic = 1263; e.umacrondieresis = 7803; e.umatragurmukhi = 2625; e.umonospace = 65365; e.underscore = 95; e.underscoredbl = 8215; e.underscoremonospace = 65343; e.underscorevertical = 65075; e.underscorewavy = 65103; e.union = 8746; e.universal = 8704; e.uogonek = 371; e.uparen = 9392; e.upblock = 9600; e.upperdothebrew = 1476; e.upsilon = 965; e.upsilondieresis = 971; e.upsilondieresistonos = 944; e.upsilonlatin = 650; e.upsilontonos = 973; e.uptackbelowcmb = 797; e.uptackmod = 724; e.uragurmukhi = 2675; e.uring = 367; e.ushortcyrillic = 1118; e.usmallhiragana = 12357; e.usmallkatakana = 12453; e.usmallkatakanahalfwidth = 65385; e.ustraightcyrillic = 1199; e.ustraightstrokecyrillic = 1201; e.utilde = 361; e.utildeacute = 7801; e.utildebelow = 7797; e.uubengali = 2442; e.uudeva = 2314; e.uugujarati = 2698; e.uugurmukhi = 2570; e.uumatragurmukhi = 2626; e.uuvowelsignbengali = 2498; e.uuvowelsigndeva = 2370; e.uuvowelsigngujarati = 2754; e.uvowelsignbengali = 2497; e.uvowelsigndeva = 2369; e.uvowelsigngujarati = 2753; e.v = 118; e.vadeva = 2357; e.vagujarati = 2741; e.vagurmukhi = 2613; e.vakatakana = 12535; e.vav = 1493; e.vavdagesh = 64309; e.vavdagesh65 = 64309; e.vavdageshhebrew = 64309; e.vavhebrew = 1493; e.vavholam = 64331; e.vavholamhebrew = 64331; e.vavvavhebrew = 1520; e.vavyodhebrew = 1521; e.vcircle = 9445; e.vdotbelow = 7807; e.vecyrillic = 1074; e.veharabic = 1700; e.vehfinalarabic = 64363; e.vehinitialarabic = 64364; e.vehmedialarabic = 64365; e.vekatakana = 12537; e.venus = 9792; e.verticalbar = 124; e.verticallineabovecmb = 781; e.verticallinebelowcmb = 809; e.verticallinelowmod = 716; e.verticallinemod = 712; e.vewarmenian = 1406; e.vhook = 651; e.vikatakana = 12536; e.viramabengali = 2509; e.viramadeva = 2381; e.viramagujarati = 2765; e.visargabengali = 2435; e.visargadeva = 2307; e.visargagujarati = 2691; e.vmonospace = 65366; e.voarmenian = 1400; e.voicediterationhiragana = 12446; e.voicediterationkatakana = 12542; e.voicedmarkkana = 12443; e.voicedmarkkanahalfwidth = 65438; e.vokatakana = 12538; e.vparen = 9393; e.vtilde = 7805; e.vturned = 652; e.vuhiragana = 12436; e.vukatakana = 12532; e.w = 119; e.wacute = 7811; e.waekorean = 12633; e.wahiragana = 12431; e.wakatakana = 12527; e.wakatakanahalfwidth = 65436; e.wakorean = 12632; e.wasmallhiragana = 12430; e.wasmallkatakana = 12526; e.wattosquare = 13143; e.wavedash = 12316; e.wavyunderscorevertical = 65076; e.wawarabic = 1608; e.wawfinalarabic = 65262; e.wawhamzaabovearabic = 1572; e.wawhamzaabovefinalarabic = 65158; e.wbsquare = 13277; e.wcircle = 9446; e.wcircumflex = 373; e.wdieresis = 7813; e.wdotaccent = 7815; e.wdotbelow = 7817; e.wehiragana = 12433; e.weierstrass = 8472; e.wekatakana = 12529; e.wekorean = 12638; e.weokorean = 12637; e.wgrave = 7809; e.whitebullet = 9702; e.whitecircle = 9675; e.whitecircleinverse = 9689; e.whitecornerbracketleft = 12302; e.whitecornerbracketleftvertical = 65091; e.whitecornerbracketright = 12303; e.whitecornerbracketrightvertical = 65092; e.whitediamond = 9671; e.whitediamondcontainingblacksmalldiamond = 9672; e.whitedownpointingsmalltriangle = 9663; e.whitedownpointingtriangle = 9661; e.whiteleftpointingsmalltriangle = 9667; e.whiteleftpointingtriangle = 9665; e.whitelenticularbracketleft = 12310; e.whitelenticularbracketright = 12311; e.whiterightpointingsmalltriangle = 9657; e.whiterightpointingtriangle = 9655; e.whitesmallsquare = 9643; e.whitesmilingface = 9786; e.whitesquare = 9633; e.whitestar = 9734; e.whitetelephone = 9743; e.whitetortoiseshellbracketleft = 12312; e.whitetortoiseshellbracketright = 12313; e.whiteuppointingsmalltriangle = 9653; e.whiteuppointingtriangle = 9651; e.wihiragana = 12432; e.wikatakana = 12528; e.wikorean = 12639; e.wmonospace = 65367; e.wohiragana = 12434; e.wokatakana = 12530; e.wokatakanahalfwidth = 65382; e.won = 8361; e.wonmonospace = 65510; e.wowaenthai = 3623; e.wparen = 9394; e.wring = 7832; e.wsuperior = 695; e.wturned = 653; e.wynn = 447; e.x = 120; e.xabovecmb = 829; e.xbopomofo = 12562; e.xcircle = 9447; e.xdieresis = 7821; e.xdotaccent = 7819; e.xeharmenian = 1389; e.xi = 958; e.xmonospace = 65368; e.xparen = 9395; e.xsuperior = 739; e.y = 121; e.yaadosquare = 13134; e.yabengali = 2479; e.yacute = 253; e.yadeva = 2351; e.yaekorean = 12626; e.yagujarati = 2735; e.yagurmukhi = 2607; e.yahiragana = 12420; e.yakatakana = 12516; e.yakatakanahalfwidth = 65428; e.yakorean = 12625; e.yamakkanthai = 3662; e.yasmallhiragana = 12419; e.yasmallkatakana = 12515; e.yasmallkatakanahalfwidth = 65388; e.yatcyrillic = 1123; e.ycircle = 9448; e.ycircumflex = 375; e.ydieresis = 255; e.ydotaccent = 7823; e.ydotbelow = 7925; e.yeharabic = 1610; e.yehbarreearabic = 1746; e.yehbarreefinalarabic = 64431; e.yehfinalarabic = 65266; e.yehhamzaabovearabic = 1574; e.yehhamzaabovefinalarabic = 65162; e.yehhamzaaboveinitialarabic = 65163; e.yehhamzaabovemedialarabic = 65164; e.yehinitialarabic = 65267; e.yehmedialarabic = 65268; e.yehmeeminitialarabic = 64733; e.yehmeemisolatedarabic = 64600; e.yehnoonfinalarabic = 64660; e.yehthreedotsbelowarabic = 1745; e.yekorean = 12630; e.yen = 165; e.yenmonospace = 65509; e.yeokorean = 12629; e.yeorinhieuhkorean = 12678; e.yerahbenyomohebrew = 1450; e.yerahbenyomolefthebrew = 1450; e.yericyrillic = 1099; e.yerudieresiscyrillic = 1273; e.yesieungkorean = 12673; e.yesieungpansioskorean = 12675; e.yesieungsioskorean = 12674; e.yetivhebrew = 1434; e.ygrave = 7923; e.yhook = 436; e.yhookabove = 7927; e.yiarmenian = 1397; e.yicyrillic = 1111; e.yikorean = 12642; e.yinyang = 9775; e.yiwnarmenian = 1410; e.ymonospace = 65369; e.yod = 1497; e.yoddagesh = 64313; e.yoddageshhebrew = 64313; e.yodhebrew = 1497; e.yodyodhebrew = 1522; e.yodyodpatahhebrew = 64287; e.yohiragana = 12424; e.yoikorean = 12681; e.yokatakana = 12520; e.yokatakanahalfwidth = 65430; e.yokorean = 12635; e.yosmallhiragana = 12423; e.yosmallkatakana = 12519; e.yosmallkatakanahalfwidth = 65390; e.yotgreek = 1011; e.yoyaekorean = 12680; e.yoyakorean = 12679; e.yoyakthai = 3618; e.yoyingthai = 3597; e.yparen = 9396; e.ypogegrammeni = 890; e.ypogegrammenigreekcmb = 837; e.yr = 422; e.yring = 7833; e.ysuperior = 696; e.ytilde = 7929; e.yturned = 654; e.yuhiragana = 12422; e.yuikorean = 12684; e.yukatakana = 12518; e.yukatakanahalfwidth = 65429; e.yukorean = 12640; e.yusbigcyrillic = 1131; e.yusbigiotifiedcyrillic = 1133; e.yuslittlecyrillic = 1127; e.yuslittleiotifiedcyrillic = 1129; e.yusmallhiragana = 12421; e.yusmallkatakana = 12517; e.yusmallkatakanahalfwidth = 65389; e.yuyekorean = 12683; e.yuyeokorean = 12682; e.yyabengali = 2527; e.yyadeva = 2399; e.z = 122; e.zaarmenian = 1382; e.zacute = 378; e.zadeva = 2395; e.zagurmukhi = 2651; e.zaharabic = 1592; e.zahfinalarabic = 65222; e.zahinitialarabic = 65223; e.zahiragana = 12374; e.zahmedialarabic = 65224; e.zainarabic = 1586; e.zainfinalarabic = 65200; e.zakatakana = 12470; e.zaqefgadolhebrew = 1429; e.zaqefqatanhebrew = 1428; e.zarqahebrew = 1432; e.zayin = 1494; e.zayindagesh = 64310; e.zayindageshhebrew = 64310; e.zayinhebrew = 1494; e.zbopomofo = 12567; e.zcaron = 382; e.zcircle = 9449; e.zcircumflex = 7825; e.zcurl = 657; e.zdot = 380; e.zdotaccent = 380; e.zdotbelow = 7827; e.zecyrillic = 1079; e.zedescendercyrillic = 1177; e.zedieresiscyrillic = 1247; e.zehiragana = 12380; e.zekatakana = 12476; e.zero = 48; e.zeroarabic = 1632; e.zerobengali = 2534; e.zerodeva = 2406; e.zerogujarati = 2790; e.zerogurmukhi = 2662; e.zerohackarabic = 1632; e.zeroinferior = 8320; e.zeromonospace = 65296; e.zerooldstyle = 63280; e.zeropersian = 1776; e.zerosuperior = 8304; e.zerothai = 3664; e.zerowidthjoiner = 65279; e.zerowidthnonjoiner = 8204; e.zerowidthspace = 8203; e.zeta = 950; e.zhbopomofo = 12563; e.zhearmenian = 1386; e.zhebrevecyrillic = 1218; e.zhecyrillic = 1078; e.zhedescendercyrillic = 1175; e.zhedieresiscyrillic = 1245; e.zihiragana = 12376; e.zikatakana = 12472; e.zinorhebrew = 1454; e.zlinebelow = 7829; e.zmonospace = 65370; e.zohiragana = 12382; e.zokatakana = 12478; e.zparen = 9397; e.zretroflexhook = 656; e.zstroke = 438; e.zuhiragana = 12378; e.zukatakana = 12474; e[".notdef"] = 0; e.angbracketleftbig = 9001; e.angbracketleftBig = 9001; e.angbracketleftbigg = 9001; e.angbracketleftBigg = 9001; e.angbracketrightBig = 9002; e.angbracketrightbig = 9002; e.angbracketrightBigg = 9002; e.angbracketrightbigg = 9002; e.arrowhookleft = 8618; e.arrowhookright = 8617; e.arrowlefttophalf = 8636; e.arrowleftbothalf = 8637; e.arrownortheast = 8599; e.arrownorthwest = 8598; e.arrowrighttophalf = 8640; e.arrowrightbothalf = 8641; e.arrowsoutheast = 8600; e.arrowsouthwest = 8601; e.backslashbig = 8726; e.backslashBig = 8726; e.backslashBigg = 8726; e.backslashbigg = 8726; e.bardbl = 8214; e.bracehtipdownleft = 65079; e.bracehtipdownright = 65079; e.bracehtipupleft = 65080; e.bracehtipupright = 65080; e.braceleftBig = 123; e.braceleftbig = 123; e.braceleftbigg = 123; e.braceleftBigg = 123; e.bracerightBig = 125; e.bracerightbig = 125; e.bracerightbigg = 125; e.bracerightBigg = 125; e.bracketleftbig = 91; e.bracketleftBig = 91; e.bracketleftbigg = 91; e.bracketleftBigg = 91; e.bracketrightBig = 93; e.bracketrightbig = 93; e.bracketrightbigg = 93; e.bracketrightBigg = 93; e.ceilingleftbig = 8968; e.ceilingleftBig = 8968; e.ceilingleftBigg = 8968; e.ceilingleftbigg = 8968; e.ceilingrightbig = 8969; e.ceilingrightBig = 8969; e.ceilingrightbigg = 8969; e.ceilingrightBigg = 8969; e.circledotdisplay = 8857; e.circledottext = 8857; e.circlemultiplydisplay = 8855; e.circlemultiplytext = 8855; e.circleplusdisplay = 8853; e.circleplustext = 8853; e.contintegraldisplay = 8750; e.contintegraltext = 8750; e.coproductdisplay = 8720; e.coproducttext = 8720; e.floorleftBig = 8970; e.floorleftbig = 8970; e.floorleftbigg = 8970; e.floorleftBigg = 8970; e.floorrightbig = 8971; e.floorrightBig = 8971; e.floorrightBigg = 8971; e.floorrightbigg = 8971; e.hatwide = 770; e.hatwider = 770; e.hatwidest = 770; e.intercal = 7488; e.integraldisplay = 8747; e.integraltext = 8747; e.intersectiondisplay = 8898; e.intersectiontext = 8898; e.logicalanddisplay = 8743; e.logicalandtext = 8743; e.logicalordisplay = 8744; e.logicalortext = 8744; e.parenleftBig = 40; e.parenleftbig = 40; e.parenleftBigg = 40; e.parenleftbigg = 40; e.parenrightBig = 41; e.parenrightbig = 41; e.parenrightBigg = 41; e.parenrightbigg = 41; e.prime = 8242; e.productdisplay = 8719; e.producttext = 8719; e.radicalbig = 8730; e.radicalBig = 8730; e.radicalBigg = 8730; e.radicalbigg = 8730; e.radicalbt = 8730; e.radicaltp = 8730; e.radicalvertex = 8730; e.slashbig = 47; e.slashBig = 47; e.slashBigg = 47; e.slashbigg = 47; e.summationdisplay = 8721; e.summationtext = 8721; e.tildewide = 732; e.tildewider = 732; e.tildewidest = 732; e.uniondisplay = 8899; e.unionmultidisplay = 8846; e.unionmultitext = 8846; e.unionsqdisplay = 8852; e.unionsqtext = 8852; e.uniontext = 8899; e.vextenddouble = 8741; e.vextendsingle = 8739 })), n = r((function (e) { e.space = 32; e.a1 = 9985; e.a2 = 9986; e.a202 = 9987; e.a3 = 9988; e.a4 = 9742; e.a5 = 9990; e.a119 = 9991; e.a118 = 9992; e.a117 = 9993; e.a11 = 9755; e.a12 = 9758; e.a13 = 9996; e.a14 = 9997; e.a15 = 9998; e.a16 = 9999; e.a105 = 1e4; e.a17 = 10001; e.a18 = 10002; e.a19 = 10003; e.a20 = 10004; e.a21 = 10005; e.a22 = 10006; e.a23 = 10007; e.a24 = 10008; e.a25 = 10009; e.a26 = 10010; e.a27 = 10011; e.a28 = 10012; e.a6 = 10013; e.a7 = 10014; e.a8 = 10015; e.a9 = 10016; e.a10 = 10017; e.a29 = 10018; e.a30 = 10019; e.a31 = 10020; e.a32 = 10021; e.a33 = 10022; e.a34 = 10023; e.a35 = 9733; e.a36 = 10025; e.a37 = 10026; e.a38 = 10027; e.a39 = 10028; e.a40 = 10029; e.a41 = 10030; e.a42 = 10031; e.a43 = 10032; e.a44 = 10033; e.a45 = 10034; e.a46 = 10035; e.a47 = 10036; e.a48 = 10037; e.a49 = 10038; e.a50 = 10039; e.a51 = 10040; e.a52 = 10041; e.a53 = 10042; e.a54 = 10043; e.a55 = 10044; e.a56 = 10045; e.a57 = 10046; e.a58 = 10047; e.a59 = 10048; e.a60 = 10049; e.a61 = 10050; e.a62 = 10051; e.a63 = 10052; e.a64 = 10053; e.a65 = 10054; e.a66 = 10055; e.a67 = 10056; e.a68 = 10057; e.a69 = 10058; e.a70 = 10059; e.a71 = 9679; e.a72 = 10061; e.a73 = 9632; e.a74 = 10063; e.a203 = 10064; e.a75 = 10065; e.a204 = 10066; e.a76 = 9650; e.a77 = 9660; e.a78 = 9670; e.a79 = 10070; e.a81 = 9687; e.a82 = 10072; e.a83 = 10073; e.a84 = 10074; e.a97 = 10075; e.a98 = 10076; e.a99 = 10077; e.a100 = 10078; e.a101 = 10081; e.a102 = 10082; e.a103 = 10083; e.a104 = 10084; e.a106 = 10085; e.a107 = 10086; e.a108 = 10087; e.a112 = 9827; e.a111 = 9830; e.a110 = 9829; e.a109 = 9824; e.a120 = 9312; e.a121 = 9313; e.a122 = 9314; e.a123 = 9315; e.a124 = 9316; e.a125 = 9317; e.a126 = 9318; e.a127 = 9319; e.a128 = 9320; e.a129 = 9321; e.a130 = 10102; e.a131 = 10103; e.a132 = 10104; e.a133 = 10105; e.a134 = 10106; e.a135 = 10107; e.a136 = 10108; e.a137 = 10109; e.a138 = 10110; e.a139 = 10111; e.a140 = 10112; e.a141 = 10113; e.a142 = 10114; e.a143 = 10115; e.a144 = 10116; e.a145 = 10117; e.a146 = 10118; e.a147 = 10119; e.a148 = 10120; e.a149 = 10121; e.a150 = 10122; e.a151 = 10123; e.a152 = 10124; e.a153 = 10125; e.a154 = 10126; e.a155 = 10127; e.a156 = 10128; e.a157 = 10129; e.a158 = 10130; e.a159 = 10131; e.a160 = 10132; e.a161 = 8594; e.a163 = 8596; e.a164 = 8597; e.a196 = 10136; e.a165 = 10137; e.a192 = 10138; e.a166 = 10139; e.a167 = 10140; e.a168 = 10141; e.a169 = 10142; e.a170 = 10143; e.a171 = 10144; e.a172 = 10145; e.a173 = 10146; e.a162 = 10147; e.a174 = 10148; e.a175 = 10149; e.a176 = 10150; e.a177 = 10151; e.a178 = 10152; e.a179 = 10153; e.a193 = 10154; e.a180 = 10155; e.a199 = 10156; e.a181 = 10157; e.a200 = 10158; e.a182 = 10159; e.a201 = 10161; e.a183 = 10162; e.a184 = 10163; e.a197 = 10164; e.a185 = 10165; e.a194 = 10166; e.a198 = 10167; e.a186 = 10168; e.a195 = 10169; e.a187 = 10170; e.a188 = 10171; e.a189 = 10172; e.a190 = 10173; e.a191 = 10174; e.a89 = 10088; e.a90 = 10089; e.a93 = 10090; e.a94 = 10091; e.a91 = 10092; e.a92 = 10093; e.a205 = 10094; e.a85 = 10095; e.a206 = 10096; e.a86 = 10097; e.a87 = 10098; e.a88 = 10099; e.a95 = 10100; e.a96 = 10101; e[".notdef"] = 0 })); t.getGlyphsUnicode = i; t.getDingbatsGlyphsUnicode = n }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getSupplementalGlyphMapForCalibri = t.getSupplementalGlyphMapForArialBlack = t.getGlyphMapForStandardFonts = t.getSymbolsFonts = t.getSerifFonts = t.getNonStdFontMap = t.getStdFontMap = void 0; var r = a(7); const i = (0, r.getLookupTableFactory)((function (e) { e.ArialNarrow = "Helvetica"; e["ArialNarrow-Bold"] = "Helvetica-Bold"; e["ArialNarrow-BoldItalic"] = "Helvetica-BoldOblique"; e["ArialNarrow-Italic"] = "Helvetica-Oblique"; e.ArialBlack = "Helvetica"; e["ArialBlack-Bold"] = "Helvetica-Bold"; e["ArialBlack-BoldItalic"] = "Helvetica-BoldOblique"; e["ArialBlack-Italic"] = "Helvetica-Oblique"; e["Arial-Black"] = "Helvetica"; e["Arial-Black-Bold"] = "Helvetica-Bold"; e["Arial-Black-BoldItalic"] = "Helvetica-BoldOblique"; e["Arial-Black-Italic"] = "Helvetica-Oblique"; e.Arial = "Helvetica"; e["Arial-Bold"] = "Helvetica-Bold"; e["Arial-BoldItalic"] = "Helvetica-BoldOblique"; e["Arial-Italic"] = "Helvetica-Oblique"; e["Arial-BoldItalicMT"] = "Helvetica-BoldOblique"; e["Arial-BoldMT"] = "Helvetica-Bold"; e["Arial-ItalicMT"] = "Helvetica-Oblique"; e.ArialMT = "Helvetica"; e["Courier-Bold"] = "Courier-Bold"; e["Courier-BoldItalic"] = "Courier-BoldOblique"; e["Courier-Italic"] = "Courier-Oblique"; e.CourierNew = "Courier"; e["CourierNew-Bold"] = "Courier-Bold"; e["CourierNew-BoldItalic"] = "Courier-BoldOblique"; e["CourierNew-Italic"] = "Courier-Oblique"; e["CourierNewPS-BoldItalicMT"] = "Courier-BoldOblique"; e["CourierNewPS-BoldMT"] = "Courier-Bold"; e["CourierNewPS-ItalicMT"] = "Courier-Oblique"; e.CourierNewPSMT = "Courier"; e.Helvetica = "Helvetica"; e["Helvetica-Bold"] = "Helvetica-Bold"; e["Helvetica-BoldItalic"] = "Helvetica-BoldOblique"; e["Helvetica-BoldOblique"] = "Helvetica-BoldOblique"; e["Helvetica-Italic"] = "Helvetica-Oblique"; e["Helvetica-Oblique"] = "Helvetica-Oblique"; e["Symbol-Bold"] = "Symbol"; e["Symbol-BoldItalic"] = "Symbol"; e["Symbol-Italic"] = "Symbol"; e.TimesNewRoman = "Times-Roman"; e["TimesNewRoman-Bold"] = "Times-Bold"; e["TimesNewRoman-BoldItalic"] = "Times-BoldItalic"; e["TimesNewRoman-Italic"] = "Times-Italic"; e.TimesNewRomanPS = "Times-Roman"; e["TimesNewRomanPS-Bold"] = "Times-Bold"; e["TimesNewRomanPS-BoldItalic"] = "Times-BoldItalic"; e["TimesNewRomanPS-BoldItalicMT"] = "Times-BoldItalic"; e["TimesNewRomanPS-BoldMT"] = "Times-Bold"; e["TimesNewRomanPS-Italic"] = "Times-Italic"; e["TimesNewRomanPS-ItalicMT"] = "Times-Italic"; e.TimesNewRomanPSMT = "Times-Roman"; e["TimesNewRomanPSMT-Bold"] = "Times-Bold"; e["TimesNewRomanPSMT-BoldItalic"] = "Times-BoldItalic"; e["TimesNewRomanPSMT-Italic"] = "Times-Italic" })); t.getStdFontMap = i; const n = (0, r.getLookupTableFactory)((function (e) { e.Calibri = "Helvetica"; e["Calibri-Bold"] = "Helvetica-Bold"; e["Calibri-BoldItalic"] = "Helvetica-BoldOblique"; e["Calibri-Italic"] = "Helvetica-Oblique"; e.CenturyGothic = "Helvetica"; e["CenturyGothic-Bold"] = "Helvetica-Bold"; e["CenturyGothic-BoldItalic"] = "Helvetica-BoldOblique"; e["CenturyGothic-Italic"] = "Helvetica-Oblique"; e.ComicSansMS = "Comic Sans MS"; e["ComicSansMS-Bold"] = "Comic Sans MS-Bold"; e["ComicSansMS-BoldItalic"] = "Comic Sans MS-BoldItalic"; e["ComicSansMS-Italic"] = "Comic Sans MS-Italic"; e.LucidaConsole = "Courier"; e["LucidaConsole-Bold"] = "Courier-Bold"; e["LucidaConsole-BoldItalic"] = "Courier-BoldOblique"; e["LucidaConsole-Italic"] = "Courier-Oblique"; e["LucidaSans-Demi"] = "Helvetica-Bold"; e["MS-Gothic"] = "MS Gothic"; e["MS-Gothic-Bold"] = "MS Gothic-Bold"; e["MS-Gothic-BoldItalic"] = "MS Gothic-BoldItalic"; e["MS-Gothic-Italic"] = "MS Gothic-Italic"; e["MS-Mincho"] = "MS Mincho"; e["MS-Mincho-Bold"] = "MS Mincho-Bold"; e["MS-Mincho-BoldItalic"] = "MS Mincho-BoldItalic"; e["MS-Mincho-Italic"] = "MS Mincho-Italic"; e["MS-PGothic"] = "MS PGothic"; e["MS-PGothic-Bold"] = "MS PGothic-Bold"; e["MS-PGothic-BoldItalic"] = "MS PGothic-BoldItalic"; e["MS-PGothic-Italic"] = "MS PGothic-Italic"; e["MS-PMincho"] = "MS PMincho"; e["MS-PMincho-Bold"] = "MS PMincho-Bold"; e["MS-PMincho-BoldItalic"] = "MS PMincho-BoldItalic"; e["MS-PMincho-Italic"] = "MS PMincho-Italic"; e.NuptialScript = "Times-Italic"; e.SegoeUISymbol = "Helvetica"; e.Wingdings = "ZapfDingbats"; e["Wingdings-Regular"] = "ZapfDingbats" })); t.getNonStdFontMap = n; const s = (0, r.getLookupTableFactory)((function (e) { e["Adobe Jenson"] = !0; e["Adobe Text"] = !0; e.Albertus = !0; e.Aldus = !0; e.Alexandria = !0; e.Algerian = !0; e["American Typewriter"] = !0; e.Antiqua = !0; e.Apex = !0; e.Arno = !0; e.Aster = !0; e.Aurora = !0; e.Baskerville = !0; e.Bell = !0; e.Bembo = !0; e["Bembo Schoolbook"] = !0; e.Benguiat = !0; e["Berkeley Old Style"] = !0; e["Bernhard Modern"] = !0; e["Berthold City"] = !0; e.Bodoni = !0; e["Bauer Bodoni"] = !0; e["Book Antiqua"] = !0; e.Bookman = !0; e["Bordeaux Roman"] = !0; e["Californian FB"] = !0; e.Calisto = !0; e.Calvert = !0; e.Capitals = !0; e.Cambria = !0; e.Cartier = !0; e.Caslon = !0; e.Catull = !0; e.Centaur = !0; e["Century Old Style"] = !0; e["Century Schoolbook"] = !0; e.Chaparral = !0; e["Charis SIL"] = !0; e.Cheltenham = !0; e["Cholla Slab"] = !0; e.Clarendon = !0; e.Clearface = !0; e.Cochin = !0; e.Colonna = !0; e["Computer Modern"] = !0; e["Concrete Roman"] = !0; e.Constantia = !0; e["Cooper Black"] = !0; e.Corona = !0; e.Ecotype = !0; e.Egyptienne = !0; e.Elephant = !0; e.Excelsior = !0; e.Fairfield = !0; e["FF Scala"] = !0; e.Folkard = !0; e.Footlight = !0; e.FreeSerif = !0; e["Friz Quadrata"] = !0; e.Garamond = !0; e.Gentium = !0; e.Georgia = !0; e.Gloucester = !0; e["Goudy Old Style"] = !0; e["Goudy Schoolbook"] = !0; e["Goudy Pro Font"] = !0; e.Granjon = !0; e["Guardian Egyptian"] = !0; e.Heather = !0; e.Hercules = !0; e["High Tower Text"] = !0; e.Hiroshige = !0; e["Hoefler Text"] = !0; e["Humana Serif"] = !0; e.Imprint = !0; e["Ionic No. 5"] = !0; e.Janson = !0; e.Joanna = !0; e.Korinna = !0; e.Lexicon = !0; e["Liberation Serif"] = !0; e["Linux Libertine"] = !0; e.Literaturnaya = !0; e.Lucida = !0; e["Lucida Bright"] = !0; e.Melior = !0; e.Memphis = !0; e.Miller = !0; e.Minion = !0; e.Modern = !0; e["Mona Lisa"] = !0; e["Mrs Eaves"] = !0; e["MS Serif"] = !0; e["Museo Slab"] = !0; e["New York"] = !0; e["Nimbus Roman"] = !0; e["NPS Rawlinson Roadway"] = !0; e.NuptialScript = !0; e.Palatino = !0; e.Perpetua = !0; e.Plantin = !0; e["Plantin Schoolbook"] = !0; e.Playbill = !0; e["Poor Richard"] = !0; e["Rawlinson Roadway"] = !0; e.Renault = !0; e.Requiem = !0; e.Rockwell = !0; e.Roman = !0; e["Rotis Serif"] = !0; e.Sabon = !0; e.Scala = !0; e.Seagull = !0; e.Sistina = !0; e.Souvenir = !0; e.STIX = !0; e["Stone Informal"] = !0; e["Stone Serif"] = !0; e.Sylfaen = !0; e.Times = !0; e.Trajan = !0; e["Trinité"] = !0; e["Trump Mediaeval"] = !0; e.Utopia = !0; e["Vale Type"] = !0; e["Bitstream Vera"] = !0; e["Vera Serif"] = !0; e.Versailles = !0; e.Wanted = !0; e.Weiss = !0; e["Wide Latin"] = !0; e.Windsor = !0; e.XITS = !0 })); t.getSerifFonts = s; const o = (0, r.getLookupTableFactory)((function (e) { e.Dingbats = !0; e.Symbol = !0; e.ZapfDingbats = !0 })); t.getSymbolsFonts = o; const c = (0, r.getLookupTableFactory)((function (e) { e[2] = 10; e[3] = 32; e[4] = 33; e[5] = 34; e[6] = 35; e[7] = 36; e[8] = 37; e[9] = 38; e[10] = 39; e[11] = 40; e[12] = 41; e[13] = 42; e[14] = 43; e[15] = 44; e[16] = 45; e[17] = 46; e[18] = 47; e[19] = 48; e[20] = 49; e[21] = 50; e[22] = 51; e[23] = 52; e[24] = 53; e[25] = 54; e[26] = 55; e[27] = 56; e[28] = 57; e[29] = 58; e[30] = 894; e[31] = 60; e[32] = 61; e[33] = 62; e[34] = 63; e[35] = 64; e[36] = 65; e[37] = 66; e[38] = 67; e[39] = 68; e[40] = 69; e[41] = 70; e[42] = 71; e[43] = 72; e[44] = 73; e[45] = 74; e[46] = 75; e[47] = 76; e[48] = 77; e[49] = 78; e[50] = 79; e[51] = 80; e[52] = 81; e[53] = 82; e[54] = 83; e[55] = 84; e[56] = 85; e[57] = 86; e[58] = 87; e[59] = 88; e[60] = 89; e[61] = 90; e[62] = 91; e[63] = 92; e[64] = 93; e[65] = 94; e[66] = 95; e[67] = 96; e[68] = 97; e[69] = 98; e[70] = 99; e[71] = 100; e[72] = 101; e[73] = 102; e[74] = 103; e[75] = 104; e[76] = 105; e[77] = 106; e[78] = 107; e[79] = 108; e[80] = 109; e[81] = 110; e[82] = 111; e[83] = 112; e[84] = 113; e[85] = 114; e[86] = 115; e[87] = 116; e[88] = 117; e[89] = 118; e[90] = 119; e[91] = 120; e[92] = 121; e[93] = 122; e[94] = 123; e[95] = 124; e[96] = 125; e[97] = 126; e[98] = 196; e[99] = 197; e[100] = 199; e[101] = 201; e[102] = 209; e[103] = 214; e[104] = 220; e[105] = 225; e[106] = 224; e[107] = 226; e[108] = 228; e[109] = 227; e[110] = 229; e[111] = 231; e[112] = 233; e[113] = 232; e[114] = 234; e[115] = 235; e[116] = 237; e[117] = 236; e[118] = 238; e[119] = 239; e[120] = 241; e[121] = 243; e[122] = 242; e[123] = 244; e[124] = 246; e[125] = 245; e[126] = 250; e[127] = 249; e[128] = 251; e[129] = 252; e[130] = 8224; e[131] = 176; e[132] = 162; e[133] = 163; e[134] = 167; e[135] = 8226; e[136] = 182; e[137] = 223; e[138] = 174; e[139] = 169; e[140] = 8482; e[141] = 180; e[142] = 168; e[143] = 8800; e[144] = 198; e[145] = 216; e[146] = 8734; e[147] = 177; e[148] = 8804; e[149] = 8805; e[150] = 165; e[151] = 181; e[152] = 8706; e[153] = 8721; e[154] = 8719; e[156] = 8747; e[157] = 170; e[158] = 186; e[159] = 8486; e[160] = 230; e[161] = 248; e[162] = 191; e[163] = 161; e[164] = 172; e[165] = 8730; e[166] = 402; e[167] = 8776; e[168] = 8710; e[169] = 171; e[170] = 187; e[171] = 8230; e[210] = 218; e[223] = 711; e[224] = 321; e[225] = 322; e[227] = 353; e[229] = 382; e[234] = 253; e[252] = 263; e[253] = 268; e[254] = 269; e[258] = 258; e[260] = 260; e[261] = 261; e[265] = 280; e[266] = 281; e[268] = 283; e[269] = 313; e[275] = 323; e[276] = 324; e[278] = 328; e[284] = 345; e[285] = 346; e[286] = 347; e[292] = 367; e[295] = 377; e[296] = 378; e[298] = 380; e[305] = 963; e[306] = 964; e[307] = 966; e[308] = 8215; e[309] = 8252; e[310] = 8319; e[311] = 8359; e[312] = 8592; e[313] = 8593; e[337] = 9552; e[493] = 1039; e[494] = 1040; e[705] = 1524; e[706] = 8362; e[710] = 64288; e[711] = 64298; e[759] = 1617; e[761] = 1776; e[763] = 1778; e[775] = 1652; e[777] = 1764; e[778] = 1780; e[779] = 1781; e[780] = 1782; e[782] = 771; e[783] = 64726; e[786] = 8363; e[788] = 8532; e[790] = 768; e[791] = 769; e[792] = 768; e[795] = 803; e[797] = 64336; e[798] = 64337; e[799] = 64342; e[800] = 64343; e[801] = 64344; e[802] = 64345; e[803] = 64362; e[804] = 64363; e[805] = 64364; e[2424] = 7821; e[2425] = 7822; e[2426] = 7823; e[2427] = 7824; e[2428] = 7825; e[2429] = 7826; e[2430] = 7827; e[2433] = 7682; e[2678] = 8045; e[2679] = 8046; e[2830] = 1552; e[2838] = 686; e[2840] = 751; e[2842] = 753; e[2843] = 754; e[2844] = 755; e[2846] = 757; e[2856] = 767; e[2857] = 848; e[2858] = 849; e[2862] = 853; e[2863] = 854; e[2864] = 855; e[2865] = 861; e[2866] = 862; e[2906] = 7460; e[2908] = 7462; e[2909] = 7463; e[2910] = 7464; e[2912] = 7466; e[2913] = 7467; e[2914] = 7468; e[2916] = 7470; e[2917] = 7471; e[2918] = 7472; e[2920] = 7474; e[2921] = 7475; e[2922] = 7476; e[2924] = 7478; e[2925] = 7479; e[2926] = 7480; e[2928] = 7482; e[2929] = 7483; e[2930] = 7484; e[2932] = 7486; e[2933] = 7487; e[2934] = 7488; e[2936] = 7490; e[2937] = 7491; e[2938] = 7492; e[2940] = 7494; e[2941] = 7495; e[2942] = 7496; e[2944] = 7498; e[2946] = 7500; e[2948] = 7502; e[2950] = 7504; e[2951] = 7505; e[2952] = 7506; e[2954] = 7508; e[2955] = 7509; e[2956] = 7510; e[2958] = 7512; e[2959] = 7513; e[2960] = 7514; e[2962] = 7516; e[2963] = 7517; e[2964] = 7518; e[2966] = 7520; e[2967] = 7521; e[2968] = 7522; e[2970] = 7524; e[2971] = 7525; e[2972] = 7526; e[2974] = 7528; e[2975] = 7529; e[2976] = 7530; e[2978] = 1537; e[2979] = 1538; e[2980] = 1539; e[2982] = 1549; e[2983] = 1551; e[2984] = 1552; e[2986] = 1554; e[2987] = 1555; e[2988] = 1556; e[2990] = 1623; e[2991] = 1624; e[2995] = 1775; e[2999] = 1791; e[3002] = 64290; e[3003] = 64291; e[3004] = 64292; e[3006] = 64294; e[3007] = 64295; e[3008] = 64296; e[3011] = 1900; e[3014] = 8223; e[3015] = 8244; e[3017] = 7532; e[3018] = 7533; e[3019] = 7534; e[3075] = 7590; e[3076] = 7591; e[3079] = 7594; e[3080] = 7595; e[3083] = 7598; e[3084] = 7599; e[3087] = 7602; e[3088] = 7603; e[3091] = 7606; e[3092] = 7607; e[3095] = 7610; e[3096] = 7611; e[3099] = 7614; e[3100] = 7615; e[3103] = 7618; e[3104] = 7619; e[3107] = 8337; e[3108] = 8338; e[3116] = 1884; e[3119] = 1885; e[3120] = 1885; e[3123] = 1886; e[3124] = 1886; e[3127] = 1887; e[3128] = 1887; e[3131] = 1888; e[3132] = 1888; e[3135] = 1889; e[3136] = 1889; e[3139] = 1890; e[3140] = 1890; e[3143] = 1891; e[3144] = 1891; e[3147] = 1892; e[3148] = 1892; e[3153] = 580; e[3154] = 581; e[3157] = 584; e[3158] = 585; e[3161] = 588; e[3162] = 589; e[3165] = 891; e[3166] = 892; e[3169] = 1274; e[3170] = 1275; e[3173] = 1278; e[3174] = 1279; e[3181] = 7622; e[3182] = 7623; e[3282] = 11799; e[3316] = 578; e[3379] = 42785; e[3393] = 1159; e[3416] = 8377 })); t.getGlyphMapForStandardFonts = c; const l = (0, r.getLookupTableFactory)((function (e) { e[227] = 322; e[264] = 261; e[291] = 346 })); t.getSupplementalGlyphMapForArialBlack = l; const h = (0, r.getLookupTableFactory)((function (e) { e[1] = 32; e[4] = 65; e[17] = 66; e[18] = 67; e[24] = 68; e[28] = 69; e[38] = 70; e[39] = 71; e[44] = 72; e[47] = 73; e[58] = 74; e[60] = 75; e[62] = 76; e[68] = 77; e[69] = 78; e[75] = 79; e[87] = 80; e[89] = 81; e[90] = 82; e[94] = 83; e[100] = 84; e[104] = 85; e[115] = 86; e[116] = 87; e[121] = 88; e[122] = 89; e[127] = 90; e[258] = 97; e[268] = 261; e[271] = 98; e[272] = 99; e[273] = 263; e[282] = 100; e[286] = 101; e[295] = 281; e[296] = 102; e[336] = 103; e[346] = 104; e[349] = 105; e[361] = 106; e[364] = 107; e[367] = 108; e[371] = 322; e[373] = 109; e[374] = 110; e[381] = 111; e[383] = 243; e[393] = 112; e[395] = 113; e[396] = 114; e[400] = 115; e[401] = 347; e[410] = 116; e[437] = 117; e[448] = 118; e[449] = 119; e[454] = 120; e[455] = 121; e[460] = 122; e[463] = 380; e[853] = 44; e[855] = 58; e[856] = 46; e[876] = 47; e[878] = 45; e[882] = 45; e[894] = 40; e[895] = 41; e[896] = 91; e[897] = 93; e[923] = 64; e[1004] = 48; e[1005] = 49; e[1006] = 50; e[1007] = 51; e[1008] = 52; e[1009] = 53; e[1010] = 54; e[1011] = 55; e[1012] = 56; e[1013] = 57; e[1081] = 37; e[1085] = 43; e[1086] = 45 })); t.getSupplementalGlyphMapForCalibri = h }, function (e, t, a) { var r = a(7).getLookupTableFactory, i = r((function (e) { e[63721] = 169; e[63193] = 169; e[63720] = 174; e[63194] = 174; e[63722] = 8482; e[63195] = 8482; e[63729] = 9127; e[63730] = 9128; e[63731] = 9129; e[63740] = 9131; e[63741] = 9132; e[63742] = 9133; e[63726] = 9121; e[63727] = 9122; e[63728] = 9123; e[63737] = 9124; e[63738] = 9125; e[63739] = 9126; e[63723] = 9115; e[63724] = 9116; e[63725] = 9117; e[63734] = 9118; e[63735] = 9119; e[63736] = 9120 })); var n = [{ begin: 0, end: 127 }, { begin: 128, end: 255 }, { begin: 256, end: 383 }, { begin: 384, end: 591 }, { begin: 592, end: 687 }, { begin: 688, end: 767 }, { begin: 768, end: 879 }, { begin: 880, end: 1023 }, { begin: 11392, end: 11519 }, { begin: 1024, end: 1279 }, { begin: 1328, end: 1423 }, { begin: 1424, end: 1535 }, { begin: 42240, end: 42559 }, { begin: 1536, end: 1791 }, { begin: 1984, end: 2047 }, { begin: 2304, end: 2431 }, { begin: 2432, end: 2559 }, { begin: 2560, end: 2687 }, { begin: 2688, end: 2815 }, { begin: 2816, end: 2943 }, { begin: 2944, end: 3071 }, { begin: 3072, end: 3199 }, { begin: 3200, end: 3327 }, { begin: 3328, end: 3455 }, { begin: 3584, end: 3711 }, { begin: 3712, end: 3839 }, { begin: 4256, end: 4351 }, { begin: 6912, end: 7039 }, { begin: 4352, end: 4607 }, { begin: 7680, end: 7935 }, { begin: 7936, end: 8191 }, { begin: 8192, end: 8303 }, { begin: 8304, end: 8351 }, { begin: 8352, end: 8399 }, { begin: 8400, end: 8447 }, { begin: 8448, end: 8527 }, { begin: 8528, end: 8591 }, { begin: 8592, end: 8703 }, { begin: 8704, end: 8959 }, { begin: 8960, end: 9215 }, { begin: 9216, end: 9279 }, { begin: 9280, end: 9311 }, { begin: 9312, end: 9471 }, { begin: 9472, end: 9599 }, { begin: 9600, end: 9631 }, { begin: 9632, end: 9727 }, { begin: 9728, end: 9983 }, { begin: 9984, end: 10175 }, { begin: 12288, end: 12351 }, { begin: 12352, end: 12447 }, { begin: 12448, end: 12543 }, { begin: 12544, end: 12591 }, { begin: 12592, end: 12687 }, { begin: 43072, end: 43135 }, { begin: 12800, end: 13055 }, { begin: 13056, end: 13311 }, { begin: 44032, end: 55215 }, { begin: 55296, end: 57343 }, { begin: 67840, end: 67871 }, { begin: 19968, end: 40959 }, { begin: 57344, end: 63743 }, { begin: 12736, end: 12783 }, { begin: 64256, end: 64335 }, { begin: 64336, end: 65023 }, { begin: 65056, end: 65071 }, { begin: 65040, end: 65055 }, { begin: 65104, end: 65135 }, { begin: 65136, end: 65279 }, { begin: 65280, end: 65519 }, { begin: 65520, end: 65535 }, { begin: 3840, end: 4095 }, { begin: 1792, end: 1871 }, { begin: 1920, end: 1983 }, { begin: 3456, end: 3583 }, { begin: 4096, end: 4255 }, { begin: 4608, end: 4991 }, { begin: 5024, end: 5119 }, { begin: 5120, end: 5759 }, { begin: 5760, end: 5791 }, { begin: 5792, end: 5887 }, { begin: 6016, end: 6143 }, { begin: 6144, end: 6319 }, { begin: 10240, end: 10495 }, { begin: 40960, end: 42127 }, { begin: 5888, end: 5919 }, { begin: 66304, end: 66351 }, { begin: 66352, end: 66383 }, { begin: 66560, end: 66639 }, { begin: 118784, end: 119039 }, { begin: 119808, end: 120831 }, { begin: 1044480, end: 1048573 }, { begin: 65024, end: 65039 }, { begin: 917504, end: 917631 }, { begin: 6400, end: 6479 }, { begin: 6480, end: 6527 }, { begin: 6528, end: 6623 }, { begin: 6656, end: 6687 }, { begin: 11264, end: 11359 }, { begin: 11568, end: 11647 }, { begin: 19904, end: 19967 }, { begin: 43008, end: 43055 }, { begin: 65536, end: 65663 }, { begin: 65856, end: 65935 }, { begin: 66432, end: 66463 }, { begin: 66464, end: 66527 }, { begin: 66640, end: 66687 }, { begin: 66688, end: 66735 }, { begin: 67584, end: 67647 }, { begin: 68096, end: 68191 }, { begin: 119552, end: 119647 }, { begin: 73728, end: 74751 }, { begin: 119648, end: 119679 }, { begin: 7040, end: 7103 }, { begin: 7168, end: 7247 }, { begin: 7248, end: 7295 }, { begin: 43136, end: 43231 }, { begin: 43264, end: 43311 }, { begin: 43312, end: 43359 }, { begin: 43520, end: 43615 }, { begin: 65936, end: 65999 }, { begin: 66e3, end: 66047 }, { begin: 66208, end: 66271 }, { begin: 127024, end: 127135 }]; var s = r((function (e) { e["¨"] = " ̈"; e["¯"] = " ̄"; e["´"] = " ́"; e["µ"] = "μ"; e["¸"] = " ̧"; e["IJ"] = "IJ"; e["ij"] = "ij"; e["Ŀ"] = "L·"; e["ŀ"] = "l·"; e["ʼn"] = "ʼn"; e["ſ"] = "s"; e["DŽ"] = "DŽ"; e["Dž"] = "Dž"; e["dž"] = "dž"; e["LJ"] = "LJ"; e["Lj"] = "Lj"; e["lj"] = "lj"; e["NJ"] = "NJ"; e["Nj"] = "Nj"; e["nj"] = "nj"; e["DZ"] = "DZ"; e["Dz"] = "Dz"; e["dz"] = "dz"; e["˘"] = " ̆"; e["˙"] = " ̇"; e["˚"] = " ̊"; e["˛"] = " ̨"; e["˜"] = " ̃"; e["˝"] = " ̋"; e["ͺ"] = " ͅ"; e["΄"] = " ́"; e["ϐ"] = "β"; e["ϑ"] = "θ"; e["ϒ"] = "Υ"; e["ϕ"] = "φ"; e["ϖ"] = "π"; e["ϰ"] = "κ"; e["ϱ"] = "ρ"; e["ϲ"] = "ς"; e["ϴ"] = "Θ"; e["ϵ"] = "ε"; e["Ϲ"] = "Σ"; e["և"] = "եւ"; e["ٵ"] = "اٴ"; e["ٶ"] = "وٴ"; e["ٷ"] = "ۇٴ"; e["ٸ"] = "يٴ"; e["ำ"] = "ํา"; e["ຳ"] = "ໍາ"; e["ໜ"] = "ຫນ"; e["ໝ"] = "ຫມ"; e["ཷ"] = "ྲཱྀ"; e["ཹ"] = "ླཱྀ"; e["ẚ"] = "aʾ"; e["᾽"] = " ̓"; e["᾿"] = " ̓"; e["῀"] = " ͂"; e["῾"] = " ̔"; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e[" "] = " "; e["‗"] = " ̳"; e["․"] = "."; e["‥"] = ".."; e["…"] = "..."; e["″"] = "′′"; e["‴"] = "′′′"; e["‶"] = "‵‵"; e["‷"] = "‵‵‵"; e["‼"] = "!!"; e["‾"] = " ̅"; e["⁇"] = "??"; e["⁈"] = "?!"; e["⁉"] = "!?"; e["⁗"] = "′′′′"; e[" "] = " "; e["₨"] = "Rs"; e["℀"] = "a/c"; e["℁"] = "a/s"; e["℃"] = "°C"; e["℅"] = "c/o"; e["℆"] = "c/u"; e["ℇ"] = "Ɛ"; e["℉"] = "°F"; e["№"] = "No"; e["℡"] = "TEL"; e["ℵ"] = "א"; e["ℶ"] = "ב"; e["ℷ"] = "ג"; e["ℸ"] = "ד"; e["℻"] = "FAX"; e["Ⅰ"] = "I"; e["Ⅱ"] = "II"; e["Ⅲ"] = "III"; e["Ⅳ"] = "IV"; e["Ⅴ"] = "V"; e["Ⅵ"] = "VI"; e["Ⅶ"] = "VII"; e["Ⅷ"] = "VIII"; e["Ⅸ"] = "IX"; e["Ⅹ"] = "X"; e["Ⅺ"] = "XI"; e["Ⅻ"] = "XII"; e["Ⅼ"] = "L"; e["Ⅽ"] = "C"; e["Ⅾ"] = "D"; e["Ⅿ"] = "M"; e["ⅰ"] = "i"; e["ⅱ"] = "ii"; e["ⅲ"] = "iii"; e["ⅳ"] = "iv"; e["ⅴ"] = "v"; e["ⅵ"] = "vi"; e["ⅶ"] = "vii"; e["ⅷ"] = "viii"; e["ⅸ"] = "ix"; e["ⅹ"] = "x"; e["ⅺ"] = "xi"; e["ⅻ"] = "xii"; e["ⅼ"] = "l"; e["ⅽ"] = "c"; e["ⅾ"] = "d"; e["ⅿ"] = "m"; e["∬"] = "∫∫"; e["∭"] = "∫∫∫"; e["∯"] = "∮∮"; e["∰"] = "∮∮∮"; e["⑴"] = "(1)"; e["⑵"] = "(2)"; e["⑶"] = "(3)"; e["⑷"] = "(4)"; e["⑸"] = "(5)"; e["⑹"] = "(6)"; e["⑺"] = "(7)"; e["⑻"] = "(8)"; e["⑼"] = "(9)"; e["⑽"] = "(10)"; e["⑾"] = "(11)"; e["⑿"] = "(12)"; e["⒀"] = "(13)"; e["⒁"] = "(14)"; e["⒂"] = "(15)"; e["⒃"] = "(16)"; e["⒄"] = "(17)"; e["⒅"] = "(18)"; e["⒆"] = "(19)"; e["⒇"] = "(20)"; e["⒈"] = "1."; e["⒉"] = "2."; e["⒊"] = "3."; e["⒋"] = "4."; e["⒌"] = "5."; e["⒍"] = "6."; e["⒎"] = "7."; e["⒏"] = "8."; e["⒐"] = "9."; e["⒑"] = "10."; e["⒒"] = "11."; e["⒓"] = "12."; e["⒔"] = "13."; e["⒕"] = "14."; e["⒖"] = "15."; e["⒗"] = "16."; e["⒘"] = "17."; e["⒙"] = "18."; e["⒚"] = "19."; e["⒛"] = "20."; e["⒜"] = "(a)"; e["⒝"] = "(b)"; e["⒞"] = "(c)"; e["⒟"] = "(d)"; e["⒠"] = "(e)"; e["⒡"] = "(f)"; e["⒢"] = "(g)"; e["⒣"] = "(h)"; e["⒤"] = "(i)"; e["⒥"] = "(j)"; e["⒦"] = "(k)"; e["⒧"] = "(l)"; e["⒨"] = "(m)"; e["⒩"] = "(n)"; e["⒪"] = "(o)"; e["⒫"] = "(p)"; e["⒬"] = "(q)"; e["⒭"] = "(r)"; e["⒮"] = "(s)"; e["⒯"] = "(t)"; e["⒰"] = "(u)"; e["⒱"] = "(v)"; e["⒲"] = "(w)"; e["⒳"] = "(x)"; e["⒴"] = "(y)"; e["⒵"] = "(z)"; e["⨌"] = "∫∫∫∫"; e["⩴"] = "::="; e["⩵"] = "=="; e["⩶"] = "==="; e["⺟"] = "母"; e["⻳"] = "龟"; e["⼀"] = "一"; e["⼁"] = "丨"; e["⼂"] = "丶"; e["⼃"] = "丿"; e["⼄"] = "乙"; e["⼅"] = "亅"; e["⼆"] = "二"; e["⼇"] = "亠"; e["⼈"] = "人"; e["⼉"] = "儿"; e["⼊"] = "入"; e["⼋"] = "八"; e["⼌"] = "冂"; e["⼍"] = "冖"; e["⼎"] = "冫"; e["⼏"] = "几"; e["⼐"] = "凵"; e["⼑"] = "刀"; e["⼒"] = "力"; e["⼓"] = "勹"; e["⼔"] = "匕"; e["⼕"] = "匚"; e["⼖"] = "匸"; e["⼗"] = "十"; e["⼘"] = "卜"; e["⼙"] = "卩"; e["⼚"] = "厂"; e["⼛"] = "厶"; e["⼜"] = "又"; e["⼝"] = "口"; e["⼞"] = "囗"; e["⼟"] = "土"; e["⼠"] = "士"; e["⼡"] = "夂"; e["⼢"] = "夊"; e["⼣"] = "夕"; e["⼤"] = "大"; e["⼥"] = "女"; e["⼦"] = "子"; e["⼧"] = "宀"; e["⼨"] = "寸"; e["⼩"] = "小"; e["⼪"] = "尢"; e["⼫"] = "尸"; e["⼬"] = "屮"; e["⼭"] = "山"; e["⼮"] = "巛"; e["⼯"] = "工"; e["⼰"] = "己"; e["⼱"] = "巾"; e["⼲"] = "干"; e["⼳"] = "幺"; e["⼴"] = "广"; e["⼵"] = "廴"; e["⼶"] = "廾"; e["⼷"] = "弋"; e["⼸"] = "弓"; e["⼹"] = "彐"; e["⼺"] = "彡"; e["⼻"] = "彳"; e["⼼"] = "心"; e["⼽"] = "戈"; e["⼾"] = "戶"; e["⼿"] = "手"; e["⽀"] = "支"; e["⽁"] = "攴"; e["⽂"] = "文"; e["⽃"] = "斗"; e["⽄"] = "斤"; e["⽅"] = "方"; e["⽆"] = "无"; e["⽇"] = "日"; e["⽈"] = "曰"; e["⽉"] = "月"; e["⽊"] = "木"; e["⽋"] = "欠"; e["⽌"] = "止"; e["⽍"] = "歹"; e["⽎"] = "殳"; e["⽏"] = "毋"; e["⽐"] = "比"; e["⽑"] = "毛"; e["⽒"] = "氏"; e["⽓"] = "气"; e["⽔"] = "水"; e["⽕"] = "火"; e["⽖"] = "爪"; e["⽗"] = "父"; e["⽘"] = "爻"; e["⽙"] = "爿"; e["⽚"] = "片"; e["⽛"] = "牙"; e["⽜"] = "牛"; e["⽝"] = "犬"; e["⽞"] = "玄"; e["⽟"] = "玉"; e["⽠"] = "瓜"; e["⽡"] = "瓦"; e["⽢"] = "甘"; e["⽣"] = "生"; e["⽤"] = "用"; e["⽥"] = "田"; e["⽦"] = "疋"; e["⽧"] = "疒"; e["⽨"] = "癶"; e["⽩"] = "白"; e["⽪"] = "皮"; e["⽫"] = "皿"; e["⽬"] = "目"; e["⽭"] = "矛"; e["⽮"] = "矢"; e["⽯"] = "石"; e["⽰"] = "示"; e["⽱"] = "禸"; e["⽲"] = "禾"; e["⽳"] = "穴"; e["⽴"] = "立"; e["⽵"] = "竹"; e["⽶"] = "米"; e["⽷"] = "糸"; e["⽸"] = "缶"; e["⽹"] = "网"; e["⽺"] = "羊"; e["⽻"] = "羽"; e["⽼"] = "老"; e["⽽"] = "而"; e["⽾"] = "耒"; e["⽿"] = "耳"; e["⾀"] = "聿"; e["⾁"] = "肉"; e["⾂"] = "臣"; e["⾃"] = "自"; e["⾄"] = "至"; e["⾅"] = "臼"; e["⾆"] = "舌"; e["⾇"] = "舛"; e["⾈"] = "舟"; e["⾉"] = "艮"; e["⾊"] = "色"; e["⾋"] = "艸"; e["⾌"] = "虍"; e["⾍"] = "虫"; e["⾎"] = "血"; e["⾏"] = "行"; e["⾐"] = "衣"; e["⾑"] = "襾"; e["⾒"] = "見"; e["⾓"] = "角"; e["⾔"] = "言"; e["⾕"] = "谷"; e["⾖"] = "豆"; e["⾗"] = "豕"; e["⾘"] = "豸"; e["⾙"] = "貝"; e["⾚"] = "赤"; e["⾛"] = "走"; e["⾜"] = "足"; e["⾝"] = "身"; e["⾞"] = "車"; e["⾟"] = "辛"; e["⾠"] = "辰"; e["⾡"] = "辵"; e["⾢"] = "邑"; e["⾣"] = "酉"; e["⾤"] = "釆"; e["⾥"] = "里"; e["⾦"] = "金"; e["⾧"] = "長"; e["⾨"] = "門"; e["⾩"] = "阜"; e["⾪"] = "隶"; e["⾫"] = "隹"; e["⾬"] = "雨"; e["⾭"] = "靑"; e["⾮"] = "非"; e["⾯"] = "面"; e["⾰"] = "革"; e["⾱"] = "韋"; e["⾲"] = "韭"; e["⾳"] = "音"; e["⾴"] = "頁"; e["⾵"] = "風"; e["⾶"] = "飛"; e["⾷"] = "食"; e["⾸"] = "首"; e["⾹"] = "香"; e["⾺"] = "馬"; e["⾻"] = "骨"; e["⾼"] = "高"; e["⾽"] = "髟"; e["⾾"] = "鬥"; e["⾿"] = "鬯"; e["⿀"] = "鬲"; e["⿁"] = "鬼"; e["⿂"] = "魚"; e["⿃"] = "鳥"; e["⿄"] = "鹵"; e["⿅"] = "鹿"; e["⿆"] = "麥"; e["⿇"] = "麻"; e["⿈"] = "黃"; e["⿉"] = "黍"; e["⿊"] = "黑"; e["⿋"] = "黹"; e["⿌"] = "黽"; e["⿍"] = "鼎"; e["⿎"] = "鼓"; e["⿏"] = "鼠"; e["⿐"] = "鼻"; e["⿑"] = "齊"; e["⿒"] = "齒"; e["⿓"] = "龍"; e["⿔"] = "龜"; e["⿕"] = "龠"; e["〶"] = "〒"; e["〸"] = "十"; e["〹"] = "卄"; e["〺"] = "卅"; e["゛"] = " ゙"; e["゜"] = " ゚"; e["ㄱ"] = "ᄀ"; e["ㄲ"] = "ᄁ"; e["ㄳ"] = "ᆪ"; e["ㄴ"] = "ᄂ"; e["ㄵ"] = "ᆬ"; e["ㄶ"] = "ᆭ"; e["ㄷ"] = "ᄃ"; e["ㄸ"] = "ᄄ"; e["ㄹ"] = "ᄅ"; e["ㄺ"] = "ᆰ"; e["ㄻ"] = "ᆱ"; e["ㄼ"] = "ᆲ"; e["ㄽ"] = "ᆳ"; e["ㄾ"] = "ᆴ"; e["ㄿ"] = "ᆵ"; e["ㅀ"] = "ᄚ"; e["ㅁ"] = "ᄆ"; e["ㅂ"] = "ᄇ"; e["ㅃ"] = "ᄈ"; e["ㅄ"] = "ᄡ"; e["ㅅ"] = "ᄉ"; e["ㅆ"] = "ᄊ"; e["ㅇ"] = "ᄋ"; e["ㅈ"] = "ᄌ"; e["ㅉ"] = "ᄍ"; e["ㅊ"] = "ᄎ"; e["ㅋ"] = "ᄏ"; e["ㅌ"] = "ᄐ"; e["ㅍ"] = "ᄑ"; e["ㅎ"] = "ᄒ"; e["ㅏ"] = "ᅡ"; e["ㅐ"] = "ᅢ"; e["ㅑ"] = "ᅣ"; e["ㅒ"] = "ᅤ"; e["ㅓ"] = "ᅥ"; e["ㅔ"] = "ᅦ"; e["ㅕ"] = "ᅧ"; e["ㅖ"] = "ᅨ"; e["ㅗ"] = "ᅩ"; e["ㅘ"] = "ᅪ"; e["ㅙ"] = "ᅫ"; e["ㅚ"] = "ᅬ"; e["ㅛ"] = "ᅭ"; e["ㅜ"] = "ᅮ"; e["ㅝ"] = "ᅯ"; e["ㅞ"] = "ᅰ"; e["ㅟ"] = "ᅱ"; e["ㅠ"] = "ᅲ"; e["ㅡ"] = "ᅳ"; e["ㅢ"] = "ᅴ"; e["ㅣ"] = "ᅵ"; e["ㅤ"] = "ᅠ"; e["ㅥ"] = "ᄔ"; e["ㅦ"] = "ᄕ"; e["ㅧ"] = "ᇇ"; e["ㅨ"] = "ᇈ"; e["ㅩ"] = "ᇌ"; e["ㅪ"] = "ᇎ"; e["ㅫ"] = "ᇓ"; e["ㅬ"] = "ᇗ"; e["ㅭ"] = "ᇙ"; e["ㅮ"] = "ᄜ"; e["ㅯ"] = "ᇝ"; e["ㅰ"] = "ᇟ"; e["ㅱ"] = "ᄝ"; e["ㅲ"] = "ᄞ"; e["ㅳ"] = "ᄠ"; e["ㅴ"] = "ᄢ"; e["ㅵ"] = "ᄣ"; e["ㅶ"] = "ᄧ"; e["ㅷ"] = "ᄩ"; e["ㅸ"] = "ᄫ"; e["ㅹ"] = "ᄬ"; e["ㅺ"] = "ᄭ"; e["ㅻ"] = "ᄮ"; e["ㅼ"] = "ᄯ"; e["ㅽ"] = "ᄲ"; e["ㅾ"] = "ᄶ"; e["ㅿ"] = "ᅀ"; e["ㆀ"] = "ᅇ"; e["ㆁ"] = "ᅌ"; e["ㆂ"] = "ᇱ"; e["ㆃ"] = "ᇲ"; e["ㆄ"] = "ᅗ"; e["ㆅ"] = "ᅘ"; e["ㆆ"] = "ᅙ"; e["ㆇ"] = "ᆄ"; e["ㆈ"] = "ᆅ"; e["ㆉ"] = "ᆈ"; e["ㆊ"] = "ᆑ"; e["ㆋ"] = "ᆒ"; e["ㆌ"] = "ᆔ"; e["ㆍ"] = "ᆞ"; e["ㆎ"] = "ᆡ"; e["㈀"] = "(ᄀ)"; e["㈁"] = "(ᄂ)"; e["㈂"] = "(ᄃ)"; e["㈃"] = "(ᄅ)"; e["㈄"] = "(ᄆ)"; e["㈅"] = "(ᄇ)"; e["㈆"] = "(ᄉ)"; e["㈇"] = "(ᄋ)"; e["㈈"] = "(ᄌ)"; e["㈉"] = "(ᄎ)"; e["㈊"] = "(ᄏ)"; e["㈋"] = "(ᄐ)"; e["㈌"] = "(ᄑ)"; e["㈍"] = "(ᄒ)"; e["㈎"] = "(가)"; e["㈏"] = "(나)"; e["㈐"] = "(다)"; e["㈑"] = "(라)"; e["㈒"] = "(마)"; e["㈓"] = "(바)"; e["㈔"] = "(사)"; e["㈕"] = "(아)"; e["㈖"] = "(자)"; e["㈗"] = "(차)"; e["㈘"] = "(카)"; e["㈙"] = "(타)"; e["㈚"] = "(파)"; e["㈛"] = "(하)"; e["㈜"] = "(주)"; e["㈝"] = "(오전)"; e["㈞"] = "(오후)"; e["㈠"] = "(一)"; e["㈡"] = "(二)"; e["㈢"] = "(三)"; e["㈣"] = "(四)"; e["㈤"] = "(五)"; e["㈥"] = "(六)"; e["㈦"] = "(七)"; e["㈧"] = "(八)"; e["㈨"] = "(九)"; e["㈩"] = "(十)"; e["㈪"] = "(月)"; e["㈫"] = "(火)"; e["㈬"] = "(水)"; e["㈭"] = "(木)"; e["㈮"] = "(金)"; e["㈯"] = "(土)"; e["㈰"] = "(日)"; e["㈱"] = "(株)"; e["㈲"] = "(有)"; e["㈳"] = "(社)"; e["㈴"] = "(名)"; e["㈵"] = "(特)"; e["㈶"] = "(財)"; e["㈷"] = "(祝)"; e["㈸"] = "(労)"; e["㈹"] = "(代)"; e["㈺"] = "(呼)"; e["㈻"] = "(学)"; e["㈼"] = "(監)"; e["㈽"] = "(企)"; e["㈾"] = "(資)"; e["㈿"] = "(協)"; e["㉀"] = "(祭)"; e["㉁"] = "(休)"; e["㉂"] = "(自)"; e["㉃"] = "(至)"; e["㋀"] = "1月"; e["㋁"] = "2月"; e["㋂"] = "3月"; e["㋃"] = "4月"; e["㋄"] = "5月"; e["㋅"] = "6月"; e["㋆"] = "7月"; e["㋇"] = "8月"; e["㋈"] = "9月"; e["㋉"] = "10月"; e["㋊"] = "11月"; e["㋋"] = "12月"; e["㍘"] = "0点"; e["㍙"] = "1点"; e["㍚"] = "2点"; e["㍛"] = "3点"; e["㍜"] = "4点"; e["㍝"] = "5点"; e["㍞"] = "6点"; e["㍟"] = "7点"; e["㍠"] = "8点"; e["㍡"] = "9点"; e["㍢"] = "10点"; e["㍣"] = "11点"; e["㍤"] = "12点"; e["㍥"] = "13点"; e["㍦"] = "14点"; e["㍧"] = "15点"; e["㍨"] = "16点"; e["㍩"] = "17点"; e["㍪"] = "18点"; e["㍫"] = "19点"; e["㍬"] = "20点"; e["㍭"] = "21点"; e["㍮"] = "22点"; e["㍯"] = "23点"; e["㍰"] = "24点"; e["㏠"] = "1日"; e["㏡"] = "2日"; e["㏢"] = "3日"; e["㏣"] = "4日"; e["㏤"] = "5日"; e["㏥"] = "6日"; e["㏦"] = "7日"; e["㏧"] = "8日"; e["㏨"] = "9日"; e["㏩"] = "10日"; e["㏪"] = "11日"; e["㏫"] = "12日"; e["㏬"] = "13日"; e["㏭"] = "14日"; e["㏮"] = "15日"; e["㏯"] = "16日"; e["㏰"] = "17日"; e["㏱"] = "18日"; e["㏲"] = "19日"; e["㏳"] = "20日"; e["㏴"] = "21日"; e["㏵"] = "22日"; e["㏶"] = "23日"; e["㏷"] = "24日"; e["㏸"] = "25日"; e["㏹"] = "26日"; e["㏺"] = "27日"; e["㏻"] = "28日"; e["㏼"] = "29日"; e["㏽"] = "30日"; e["㏾"] = "31日"; e["ff"] = "ff"; e["fi"] = "fi"; e["fl"] = "fl"; e["ffi"] = "ffi"; e["ffl"] = "ffl"; e["ſt"] = "ſt"; e["st"] = "st"; e["ﬓ"] = "մն"; e["ﬔ"] = "մե"; e["ﬕ"] = "մի"; e["ﬖ"] = "վն"; e["ﬗ"] = "մխ"; e["ﭏ"] = "אל"; e["ﭐ"] = "ٱ"; e["ﭑ"] = "ٱ"; e["ﭒ"] = "ٻ"; e["ﭓ"] = "ٻ"; e["ﭔ"] = "ٻ"; e["ﭕ"] = "ٻ"; e["ﭖ"] = "پ"; e["ﭗ"] = "پ"; e["ﭘ"] = "پ"; e["ﭙ"] = "پ"; e["ﭚ"] = "ڀ"; e["ﭛ"] = "ڀ"; e["ﭜ"] = "ڀ"; e["ﭝ"] = "ڀ"; e["ﭞ"] = "ٺ"; e["ﭟ"] = "ٺ"; e["ﭠ"] = "ٺ"; e["ﭡ"] = "ٺ"; e["ﭢ"] = "ٿ"; e["ﭣ"] = "ٿ"; e["ﭤ"] = "ٿ"; e["ﭥ"] = "ٿ"; e["ﭦ"] = "ٹ"; e["ﭧ"] = "ٹ"; e["ﭨ"] = "ٹ"; e["ﭩ"] = "ٹ"; e["ﭪ"] = "ڤ"; e["ﭫ"] = "ڤ"; e["ﭬ"] = "ڤ"; e["ﭭ"] = "ڤ"; e["ﭮ"] = "ڦ"; e["ﭯ"] = "ڦ"; e["ﭰ"] = "ڦ"; e["ﭱ"] = "ڦ"; e["ﭲ"] = "ڄ"; e["ﭳ"] = "ڄ"; e["ﭴ"] = "ڄ"; e["ﭵ"] = "ڄ"; e["ﭶ"] = "ڃ"; e["ﭷ"] = "ڃ"; e["ﭸ"] = "ڃ"; e["ﭹ"] = "ڃ"; e["ﭺ"] = "چ"; e["ﭻ"] = "چ"; e["ﭼ"] = "چ"; e["ﭽ"] = "چ"; e["ﭾ"] = "ڇ"; e["ﭿ"] = "ڇ"; e["ﮀ"] = "ڇ"; e["ﮁ"] = "ڇ"; e["ﮂ"] = "ڍ"; e["ﮃ"] = "ڍ"; e["ﮄ"] = "ڌ"; e["ﮅ"] = "ڌ"; e["ﮆ"] = "ڎ"; e["ﮇ"] = "ڎ"; e["ﮈ"] = "ڈ"; e["ﮉ"] = "ڈ"; e["ﮊ"] = "ژ"; e["ﮋ"] = "ژ"; e["ﮌ"] = "ڑ"; e["ﮍ"] = "ڑ"; e["ﮎ"] = "ک"; e["ﮏ"] = "ک"; e["ﮐ"] = "ک"; e["ﮑ"] = "ک"; e["ﮒ"] = "گ"; e["ﮓ"] = "گ"; e["ﮔ"] = "گ"; e["ﮕ"] = "گ"; e["ﮖ"] = "ڳ"; e["ﮗ"] = "ڳ"; e["ﮘ"] = "ڳ"; e["ﮙ"] = "ڳ"; e["ﮚ"] = "ڱ"; e["ﮛ"] = "ڱ"; e["ﮜ"] = "ڱ"; e["ﮝ"] = "ڱ"; e["ﮞ"] = "ں"; e["ﮟ"] = "ں"; e["ﮠ"] = "ڻ"; e["ﮡ"] = "ڻ"; e["ﮢ"] = "ڻ"; e["ﮣ"] = "ڻ"; e["ﮤ"] = "ۀ"; e["ﮥ"] = "ۀ"; e["ﮦ"] = "ہ"; e["ﮧ"] = "ہ"; e["ﮨ"] = "ہ"; e["ﮩ"] = "ہ"; e["ﮪ"] = "ھ"; e["ﮫ"] = "ھ"; e["ﮬ"] = "ھ"; e["ﮭ"] = "ھ"; e["ﮮ"] = "ے"; e["ﮯ"] = "ے"; e["ﮰ"] = "ۓ"; e["ﮱ"] = "ۓ"; e["ﯓ"] = "ڭ"; e["ﯔ"] = "ڭ"; e["ﯕ"] = "ڭ"; e["ﯖ"] = "ڭ"; e["ﯗ"] = "ۇ"; e["ﯘ"] = "ۇ"; e["ﯙ"] = "ۆ"; e["ﯚ"] = "ۆ"; e["ﯛ"] = "ۈ"; e["ﯜ"] = "ۈ"; e["ﯝ"] = "ٷ"; e["ﯞ"] = "ۋ"; e["ﯟ"] = "ۋ"; e["ﯠ"] = "ۅ"; e["ﯡ"] = "ۅ"; e["ﯢ"] = "ۉ"; e["ﯣ"] = "ۉ"; e["ﯤ"] = "ې"; e["ﯥ"] = "ې"; e["ﯦ"] = "ې"; e["ﯧ"] = "ې"; e["ﯨ"] = "ى"; e["ﯩ"] = "ى"; e["ﯪ"] = "ئا"; e["ﯫ"] = "ئا"; e["ﯬ"] = "ئە"; e["ﯭ"] = "ئە"; e["ﯮ"] = "ئو"; e["ﯯ"] = "ئو"; e["ﯰ"] = "ئۇ"; e["ﯱ"] = "ئۇ"; e["ﯲ"] = "ئۆ"; e["ﯳ"] = "ئۆ"; e["ﯴ"] = "ئۈ"; e["ﯵ"] = "ئۈ"; e["ﯶ"] = "ئې"; e["ﯷ"] = "ئې"; e["ﯸ"] = "ئې"; e["ﯹ"] = "ئى"; e["ﯺ"] = "ئى"; e["ﯻ"] = "ئى"; e["ﯼ"] = "ی"; e["ﯽ"] = "ی"; e["ﯾ"] = "ی"; e["ﯿ"] = "ی"; e["ﰀ"] = "ئج"; e["ﰁ"] = "ئح"; e["ﰂ"] = "ئم"; e["ﰃ"] = "ئى"; e["ﰄ"] = "ئي"; e["ﰅ"] = "بج"; e["ﰆ"] = "بح"; e["ﰇ"] = "بخ"; e["ﰈ"] = "بم"; e["ﰉ"] = "بى"; e["ﰊ"] = "بي"; e["ﰋ"] = "تج"; e["ﰌ"] = "تح"; e["ﰍ"] = "تخ"; e["ﰎ"] = "تم"; e["ﰏ"] = "تى"; e["ﰐ"] = "تي"; e["ﰑ"] = "ثج"; e["ﰒ"] = "ثم"; e["ﰓ"] = "ثى"; e["ﰔ"] = "ثي"; e["ﰕ"] = "جح"; e["ﰖ"] = "جم"; e["ﰗ"] = "حج"; e["ﰘ"] = "حم"; e["ﰙ"] = "خج"; e["ﰚ"] = "خح"; e["ﰛ"] = "خم"; e["ﰜ"] = "سج"; e["ﰝ"] = "سح"; e["ﰞ"] = "سخ"; e["ﰟ"] = "سم"; e["ﰠ"] = "صح"; e["ﰡ"] = "صم"; e["ﰢ"] = "ضج"; e["ﰣ"] = "ضح"; e["ﰤ"] = "ضخ"; e["ﰥ"] = "ضم"; e["ﰦ"] = "طح"; e["ﰧ"] = "طم"; e["ﰨ"] = "ظم"; e["ﰩ"] = "عج"; e["ﰪ"] = "عم"; e["ﰫ"] = "غج"; e["ﰬ"] = "غم"; e["ﰭ"] = "فج"; e["ﰮ"] = "فح"; e["ﰯ"] = "فخ"; e["ﰰ"] = "فم"; e["ﰱ"] = "فى"; e["ﰲ"] = "في"; e["ﰳ"] = "قح"; e["ﰴ"] = "قم"; e["ﰵ"] = "قى"; e["ﰶ"] = "قي"; e["ﰷ"] = "كا"; e["ﰸ"] = "كج"; e["ﰹ"] = "كح"; e["ﰺ"] = "كخ"; e["ﰻ"] = "كل"; e["ﰼ"] = "كم"; e["ﰽ"] = "كى"; e["ﰾ"] = "كي"; e["ﰿ"] = "لج"; e["ﱀ"] = "لح"; e["ﱁ"] = "لخ"; e["ﱂ"] = "لم"; e["ﱃ"] = "لى"; e["ﱄ"] = "لي"; e["ﱅ"] = "مج"; e["ﱆ"] = "مح"; e["ﱇ"] = "مخ"; e["ﱈ"] = "مم"; e["ﱉ"] = "مى"; e["ﱊ"] = "مي"; e["ﱋ"] = "نج"; e["ﱌ"] = "نح"; e["ﱍ"] = "نخ"; e["ﱎ"] = "نم"; e["ﱏ"] = "نى"; e["ﱐ"] = "ني"; e["ﱑ"] = "هج"; e["ﱒ"] = "هم"; e["ﱓ"] = "هى"; e["ﱔ"] = "هي"; e["ﱕ"] = "يج"; e["ﱖ"] = "يح"; e["ﱗ"] = "يخ"; e["ﱘ"] = "يم"; e["ﱙ"] = "يى"; e["ﱚ"] = "يي"; e["ﱛ"] = "ذٰ"; e["ﱜ"] = "رٰ"; e["ﱝ"] = "ىٰ"; e["ﱞ"] = " ٌّ"; e["ﱟ"] = " ٍّ"; e["ﱠ"] = " َّ"; e["ﱡ"] = " ُّ"; e["ﱢ"] = " ِّ"; e["ﱣ"] = " ّٰ"; e["ﱤ"] = "ئر"; e["ﱥ"] = "ئز"; e["ﱦ"] = "ئم"; e["ﱧ"] = "ئن"; e["ﱨ"] = "ئى"; e["ﱩ"] = "ئي"; e["ﱪ"] = "بر"; e["ﱫ"] = "بز"; e["ﱬ"] = "بم"; e["ﱭ"] = "بن"; e["ﱮ"] = "بى"; e["ﱯ"] = "بي"; e["ﱰ"] = "تر"; e["ﱱ"] = "تز"; e["ﱲ"] = "تم"; e["ﱳ"] = "تن"; e["ﱴ"] = "تى"; e["ﱵ"] = "تي"; e["ﱶ"] = "ثر"; e["ﱷ"] = "ثز"; e["ﱸ"] = "ثم"; e["ﱹ"] = "ثن"; e["ﱺ"] = "ثى"; e["ﱻ"] = "ثي"; e["ﱼ"] = "فى"; e["ﱽ"] = "في"; e["ﱾ"] = "قى"; e["ﱿ"] = "قي"; e["ﲀ"] = "كا"; e["ﲁ"] = "كل"; e["ﲂ"] = "كم"; e["ﲃ"] = "كى"; e["ﲄ"] = "كي"; e["ﲅ"] = "لم"; e["ﲆ"] = "لى"; e["ﲇ"] = "لي"; e["ﲈ"] = "ما"; e["ﲉ"] = "مم"; e["ﲊ"] = "نر"; e["ﲋ"] = "نز"; e["ﲌ"] = "نم"; e["ﲍ"] = "نن"; e["ﲎ"] = "نى"; e["ﲏ"] = "ني"; e["ﲐ"] = "ىٰ"; e["ﲑ"] = "ير"; e["ﲒ"] = "يز"; e["ﲓ"] = "يم"; e["ﲔ"] = "ين"; e["ﲕ"] = "يى"; e["ﲖ"] = "يي"; e["ﲗ"] = "ئج"; e["ﲘ"] = "ئح"; e["ﲙ"] = "ئخ"; e["ﲚ"] = "ئم"; e["ﲛ"] = "ئه"; e["ﲜ"] = "بج"; e["ﲝ"] = "بح"; e["ﲞ"] = "بخ"; e["ﲟ"] = "بم"; e["ﲠ"] = "به"; e["ﲡ"] = "تج"; e["ﲢ"] = "تح"; e["ﲣ"] = "تخ"; e["ﲤ"] = "تم"; e["ﲥ"] = "ته"; e["ﲦ"] = "ثم"; e["ﲧ"] = "جح"; e["ﲨ"] = "جم"; e["ﲩ"] = "حج"; e["ﲪ"] = "حم"; e["ﲫ"] = "خج"; e["ﲬ"] = "خم"; e["ﲭ"] = "سج"; e["ﲮ"] = "سح"; e["ﲯ"] = "سخ"; e["ﲰ"] = "سم"; e["ﲱ"] = "صح"; e["ﲲ"] = "صخ"; e["ﲳ"] = "صم"; e["ﲴ"] = "ضج"; e["ﲵ"] = "ضح"; e["ﲶ"] = "ضخ"; e["ﲷ"] = "ضم"; e["ﲸ"] = "طح"; e["ﲹ"] = "ظم"; e["ﲺ"] = "عج"; e["ﲻ"] = "عم"; e["ﲼ"] = "غج"; e["ﲽ"] = "غم"; e["ﲾ"] = "فج"; e["ﲿ"] = "فح"; e["ﳀ"] = "فخ"; e["ﳁ"] = "فم"; e["ﳂ"] = "قح"; e["ﳃ"] = "قم"; e["ﳄ"] = "كج"; e["ﳅ"] = "كح"; e["ﳆ"] = "كخ"; e["ﳇ"] = "كل"; e["ﳈ"] = "كم"; e["ﳉ"] = "لج"; e["ﳊ"] = "لح"; e["ﳋ"] = "لخ"; e["ﳌ"] = "لم"; e["ﳍ"] = "له"; e["ﳎ"] = "مج"; e["ﳏ"] = "مح"; e["ﳐ"] = "مخ"; e["ﳑ"] = "مم"; e["ﳒ"] = "نج"; e["ﳓ"] = "نح"; e["ﳔ"] = "نخ"; e["ﳕ"] = "نم"; e["ﳖ"] = "نه"; e["ﳗ"] = "هج"; e["ﳘ"] = "هم"; e["ﳙ"] = "هٰ"; e["ﳚ"] = "يج"; e["ﳛ"] = "يح"; e["ﳜ"] = "يخ"; e["ﳝ"] = "يم"; e["ﳞ"] = "يه"; e["ﳟ"] = "ئم"; e["ﳠ"] = "ئه"; e["ﳡ"] = "بم"; e["ﳢ"] = "به"; e["ﳣ"] = "تم"; e["ﳤ"] = "ته"; e["ﳥ"] = "ثم"; e["ﳦ"] = "ثه"; e["ﳧ"] = "سم"; e["ﳨ"] = "سه"; e["ﳩ"] = "شم"; e["ﳪ"] = "شه"; e["ﳫ"] = "كل"; e["ﳬ"] = "كم"; e["ﳭ"] = "لم"; e["ﳮ"] = "نم"; e["ﳯ"] = "نه"; e["ﳰ"] = "يم"; e["ﳱ"] = "يه"; e["ﳲ"] = "ـَّ"; e["ﳳ"] = "ـُّ"; e["ﳴ"] = "ـِّ"; e["ﳵ"] = "طى"; e["ﳶ"] = "طي"; e["ﳷ"] = "عى"; e["ﳸ"] = "عي"; e["ﳹ"] = "غى"; e["ﳺ"] = "غي"; e["ﳻ"] = "سى"; e["ﳼ"] = "سي"; e["ﳽ"] = "شى"; e["ﳾ"] = "شي"; e["ﳿ"] = "حى"; e["ﴀ"] = "حي"; e["ﴁ"] = "جى"; e["ﴂ"] = "جي"; e["ﴃ"] = "خى"; e["ﴄ"] = "خي"; e["ﴅ"] = "صى"; e["ﴆ"] = "صي"; e["ﴇ"] = "ضى"; e["ﴈ"] = "ضي"; e["ﴉ"] = "شج"; e["ﴊ"] = "شح"; e["ﴋ"] = "شخ"; e["ﴌ"] = "شم"; e["ﴍ"] = "شر"; e["ﴎ"] = "سر"; e["ﴏ"] = "صر"; e["ﴐ"] = "ضر"; e["ﴑ"] = "طى"; e["ﴒ"] = "طي"; e["ﴓ"] = "عى"; e["ﴔ"] = "عي"; e["ﴕ"] = "غى"; e["ﴖ"] = "غي"; e["ﴗ"] = "سى"; e["ﴘ"] = "سي"; e["ﴙ"] = "شى"; e["ﴚ"] = "شي"; e["ﴛ"] = "حى"; e["ﴜ"] = "حي"; e["ﴝ"] = "جى"; e["ﴞ"] = "جي"; e["ﴟ"] = "خى"; e["ﴠ"] = "خي"; e["ﴡ"] = "صى"; e["ﴢ"] = "صي"; e["ﴣ"] = "ضى"; e["ﴤ"] = "ضي"; e["ﴥ"] = "شج"; e["ﴦ"] = "شح"; e["ﴧ"] = "شخ"; e["ﴨ"] = "شم"; e["ﴩ"] = "شر"; e["ﴪ"] = "سر"; e["ﴫ"] = "صر"; e["ﴬ"] = "ضر"; e["ﴭ"] = "شج"; e["ﴮ"] = "شح"; e["ﴯ"] = "شخ"; e["ﴰ"] = "شم"; e["ﴱ"] = "سه"; e["ﴲ"] = "شه"; e["ﴳ"] = "طم"; e["ﴴ"] = "سج"; e["ﴵ"] = "سح"; e["ﴶ"] = "سخ"; e["ﴷ"] = "شج"; e["ﴸ"] = "شح"; e["ﴹ"] = "شخ"; e["ﴺ"] = "طم"; e["ﴻ"] = "ظم"; e["ﴼ"] = "اً"; e["ﴽ"] = "اً"; e["ﵐ"] = "تجم"; e["ﵑ"] = "تحج"; e["ﵒ"] = "تحج"; e["ﵓ"] = "تحم"; e["ﵔ"] = "تخم"; e["ﵕ"] = "تمج"; e["ﵖ"] = "تمح"; e["ﵗ"] = "تمخ"; e["ﵘ"] = "جمح"; e["ﵙ"] = "جمح"; e["ﵚ"] = "حمي"; e["ﵛ"] = "حمى"; e["ﵜ"] = "سحج"; e["ﵝ"] = "سجح"; e["ﵞ"] = "سجى"; e["ﵟ"] = "سمح"; e["ﵠ"] = "سمح"; e["ﵡ"] = "سمج"; e["ﵢ"] = "سمم"; e["ﵣ"] = "سمم"; e["ﵤ"] = "صحح"; e["ﵥ"] = "صحح"; e["ﵦ"] = "صمم"; e["ﵧ"] = "شحم"; e["ﵨ"] = "شحم"; e["ﵩ"] = "شجي"; e["ﵪ"] = "شمخ"; e["ﵫ"] = "شمخ"; e["ﵬ"] = "شمم"; e["ﵭ"] = "شمم"; e["ﵮ"] = "ضحى"; e["ﵯ"] = "ضخم"; e["ﵰ"] = "ضخم"; e["ﵱ"] = "طمح"; e["ﵲ"] = "طمح"; e["ﵳ"] = "طمم"; e["ﵴ"] = "طمي"; e["ﵵ"] = "عجم"; e["ﵶ"] = "عمم"; e["ﵷ"] = "عمم"; e["ﵸ"] = "عمى"; e["ﵹ"] = "غمم"; e["ﵺ"] = "غمي"; e["ﵻ"] = "غمى"; e["ﵼ"] = "فخم"; e["ﵽ"] = "فخم"; e["ﵾ"] = "قمح"; e["ﵿ"] = "قمم"; e["ﶀ"] = "لحم"; e["ﶁ"] = "لحي"; e["ﶂ"] = "لحى"; e["ﶃ"] = "لجج"; e["ﶄ"] = "لجج"; e["ﶅ"] = "لخم"; e["ﶆ"] = "لخم"; e["ﶇ"] = "لمح"; e["ﶈ"] = "لمح"; e["ﶉ"] = "محج"; e["ﶊ"] = "محم"; e["ﶋ"] = "محي"; e["ﶌ"] = "مجح"; e["ﶍ"] = "مجم"; e["ﶎ"] = "مخج"; e["ﶏ"] = "مخم"; e["ﶒ"] = "مجخ"; e["ﶓ"] = "همج"; e["ﶔ"] = "همم"; e["ﶕ"] = "نحم"; e["ﶖ"] = "نحى"; e["ﶗ"] = "نجم"; e["ﶘ"] = "نجم"; e["ﶙ"] = "نجى"; e["ﶚ"] = "نمي"; e["ﶛ"] = "نمى"; e["ﶜ"] = "يمم"; e["ﶝ"] = "يمم"; e["ﶞ"] = "بخي"; e["ﶟ"] = "تجي"; e["ﶠ"] = "تجى"; e["ﶡ"] = "تخي"; e["ﶢ"] = "تخى"; e["ﶣ"] = "تمي"; e["ﶤ"] = "تمى"; e["ﶥ"] = "جمي"; e["ﶦ"] = "جحى"; e["ﶧ"] = "جمى"; e["ﶨ"] = "سخى"; e["ﶩ"] = "صحي"; e["ﶪ"] = "شحي"; e["ﶫ"] = "ضحي"; e["ﶬ"] = "لجي"; e["ﶭ"] = "لمي"; e["ﶮ"] = "يحي"; e["ﶯ"] = "يجي"; e["ﶰ"] = "يمي"; e["ﶱ"] = "ممي"; e["ﶲ"] = "قمي"; e["ﶳ"] = "نحي"; e["ﶴ"] = "قمح"; e["ﶵ"] = "لحم"; e["ﶶ"] = "عمي"; e["ﶷ"] = "كمي"; e["ﶸ"] = "نجح"; e["ﶹ"] = "مخي"; e["ﶺ"] = "لجم"; e["ﶻ"] = "كمم"; e["ﶼ"] = "لجم"; e["ﶽ"] = "نجح"; e["ﶾ"] = "جحي"; e["ﶿ"] = "حجي"; e["ﷀ"] = "مجي"; e["ﷁ"] = "فمي"; e["ﷂ"] = "بحي"; e["ﷃ"] = "كمم"; e["ﷄ"] = "عجم"; e["ﷅ"] = "صمم"; e["ﷆ"] = "سخي"; e["ﷇ"] = "نجي"; e["﹉"] = "‾"; e["﹊"] = "‾"; e["﹋"] = "‾"; e["﹌"] = "‾"; e["﹍"] = "_"; e["﹎"] = "_"; e["﹏"] = "_"; e["ﺀ"] = "ء"; e["ﺁ"] = "آ"; e["ﺂ"] = "آ"; e["ﺃ"] = "أ"; e["ﺄ"] = "أ"; e["ﺅ"] = "ؤ"; e["ﺆ"] = "ؤ"; e["ﺇ"] = "إ"; e["ﺈ"] = "إ"; e["ﺉ"] = "ئ"; e["ﺊ"] = "ئ"; e["ﺋ"] = "ئ"; e["ﺌ"] = "ئ"; e["ﺍ"] = "ا"; e["ﺎ"] = "ا"; e["ﺏ"] = "ب"; e["ﺐ"] = "ب"; e["ﺑ"] = "ب"; e["ﺒ"] = "ب"; e["ﺓ"] = "ة"; e["ﺔ"] = "ة"; e["ﺕ"] = "ت"; e["ﺖ"] = "ت"; e["ﺗ"] = "ت"; e["ﺘ"] = "ت"; e["ﺙ"] = "ث"; e["ﺚ"] = "ث"; e["ﺛ"] = "ث"; e["ﺜ"] = "ث"; e["ﺝ"] = "ج"; e["ﺞ"] = "ج"; e["ﺟ"] = "ج"; e["ﺠ"] = "ج"; e["ﺡ"] = "ح"; e["ﺢ"] = "ح"; e["ﺣ"] = "ح"; e["ﺤ"] = "ح"; e["ﺥ"] = "خ"; e["ﺦ"] = "خ"; e["ﺧ"] = "خ"; e["ﺨ"] = "خ"; e["ﺩ"] = "د"; e["ﺪ"] = "د"; e["ﺫ"] = "ذ"; e["ﺬ"] = "ذ"; e["ﺭ"] = "ر"; e["ﺮ"] = "ر"; e["ﺯ"] = "ز"; e["ﺰ"] = "ز"; e["ﺱ"] = "س"; e["ﺲ"] = "س"; e["ﺳ"] = "س"; e["ﺴ"] = "س"; e["ﺵ"] = "ش"; e["ﺶ"] = "ش"; e["ﺷ"] = "ش"; e["ﺸ"] = "ش"; e["ﺹ"] = "ص"; e["ﺺ"] = "ص"; e["ﺻ"] = "ص"; e["ﺼ"] = "ص"; e["ﺽ"] = "ض"; e["ﺾ"] = "ض"; e["ﺿ"] = "ض"; e["ﻀ"] = "ض"; e["ﻁ"] = "ط"; e["ﻂ"] = "ط"; e["ﻃ"] = "ط"; e["ﻄ"] = "ط"; e["ﻅ"] = "ظ"; e["ﻆ"] = "ظ"; e["ﻇ"] = "ظ"; e["ﻈ"] = "ظ"; e["ﻉ"] = "ع"; e["ﻊ"] = "ع"; e["ﻋ"] = "ع"; e["ﻌ"] = "ع"; e["ﻍ"] = "غ"; e["ﻎ"] = "غ"; e["ﻏ"] = "غ"; e["ﻐ"] = "غ"; e["ﻑ"] = "ف"; e["ﻒ"] = "ف"; e["ﻓ"] = "ف"; e["ﻔ"] = "ف"; e["ﻕ"] = "ق"; e["ﻖ"] = "ق"; e["ﻗ"] = "ق"; e["ﻘ"] = "ق"; e["ﻙ"] = "ك"; e["ﻚ"] = "ك"; e["ﻛ"] = "ك"; e["ﻜ"] = "ك"; e["ﻝ"] = "ل"; e["ﻞ"] = "ل"; e["ﻟ"] = "ل"; e["ﻠ"] = "ل"; e["ﻡ"] = "م"; e["ﻢ"] = "م"; e["ﻣ"] = "م"; e["ﻤ"] = "م"; e["ﻥ"] = "ن"; e["ﻦ"] = "ن"; e["ﻧ"] = "ن"; e["ﻨ"] = "ن"; e["ﻩ"] = "ه"; e["ﻪ"] = "ه"; e["ﻫ"] = "ه"; e["ﻬ"] = "ه"; e["ﻭ"] = "و"; e["ﻮ"] = "و"; e["ﻯ"] = "ى"; e["ﻰ"] = "ى"; e["ﻱ"] = "ي"; e["ﻲ"] = "ي"; e["ﻳ"] = "ي"; e["ﻴ"] = "ي"; e["ﻵ"] = "لآ"; e["ﻶ"] = "لآ"; e["ﻷ"] = "لأ"; e["ﻸ"] = "لأ"; e["ﻹ"] = "لإ"; e["ﻺ"] = "لإ"; e["ﻻ"] = "لا"; e["ﻼ"] = "لا" })); t.mapSpecialUnicodeValues = function (e) { return e >= 65520 && e <= 65535 ? 0 : e >= 62976 && e <= 63743 ? i()[e] || e : 173 === e ? 45 : e }; t.reverseIfRtl = function (e) { var t, a, r = e.length; if (r <= 1 || !(t = e.charCodeAt(0), a = n[13], t >= a.begin && t < a.end || t >= (a = n[11]).begin && t < a.end)) return e; for (var i = "", s = r - 1; s >= 0; s--)i += e[s]; return i }; t.getUnicodeRangeFor = function (e) { for (var t = 0, a = n.length; t < a; t++) { var r = n[t]; if (e >= r.begin && e < r.end) return t } return -1 }; t.getNormalizedUnicodes = s; t.getUnicodeForGlyph = function (e, t) { var a = t[e]; if (void 0 !== a) return a; if (!e) return -1; if ("u" === e[0]) { var r, i = e.length; if (7 === i && "n" === e[1] && "i" === e[2]) r = e.substring(3); else { if (!(i >= 5 && i <= 7)) return -1; r = e.substring(1) } if (r === r.toUpperCase() && (a = parseInt(r, 16)) >= 0) return a } return -1 } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.FontRendererFactory = void 0; var r = a(2), i = a(28), n = a(31), s = a(30), o = a(11), c = function () { function e(e, t) { return e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3] } function t(e, t) { return e[t] << 8 | e[t + 1] } function a(e) { const t = e.length; let a = 32768; t < 1240 ? a = 107 : t < 33900 && (a = 1131); return a } function c(a, i, n) { var s, o, c, l = 1 === t(a, i + 2) ? e(a, i + 8) : e(a, i + 16), h = t(a, i + l); if (4 === h) { t(a, i + l + 2); var u = t(a, i + l + 6) >> 1; o = i + l + 14; s = []; for (c = 0; c < u; c++, o += 2)s[c] = { end: t(a, o) }; o += 2; for (c = 0; c < u; c++, o += 2)s[c].start = t(a, o); for (c = 0; c < u; c++, o += 2)s[c].idDelta = t(a, o); for (c = 0; c < u; c++, o += 2) { var d = t(a, o); if (0 !== d) { s[c].ids = []; for (var f = 0, g = s[c].end - s[c].start + 1; f < g; f++) { s[c].ids[f] = t(a, o + d); d += 2 } } } return s } if (12 === h) { e(a, i + l + 4); var m = e(a, i + l + 12); o = i + l + 16; s = []; for (c = 0; c < m; c++) { s.push({ start: e(a, o), end: e(a, o + 4), idDelta: e(a, o + 8) - e(a, o) }); o += 12 } return s } throw new r.FormatError(`unsupported cmap: ${h}`) } function l(e, t, a, r) { var n = new i.CFFParser(new o.Stream(e, t, a - t), {}, r).parse(); return { glyphs: n.charStrings.objects, subrs: n.topDict.privateDict && n.topDict.privateDict.subrsIndex && n.topDict.privateDict.subrsIndex.objects, gsubrs: n.globalSubrIndex && n.globalSubrIndex.objects, isCFFCIDFont: n.isCIDFont, fdSelect: n.fdSelect, fdArray: n.fdArray } } function h(e, t) { for (var a = t.codePointAt(0), r = 0, i = 0, n = e.length - 1; i < n;) { var s = i + n + 1 >> 1; a < e[s].start ? n = s - 1 : i = s } e[i].start <= a && a <= e[i].end && (r = e[i].idDelta + (e[i].ids ? e[i].ids[a - e[i].start] : a) & 65535); return { charCode: a, glyphId: r } } const u = []; class d { constructor(e) { this.constructor === d && (0, r.unreachable)("Cannot initialize CompiledFont."); this.fontMatrix = e; this.compiledGlyphs = Object.create(null); this.compiledCharCodeToGlyphId = Object.create(null) } getPathJs(e) { const t = h(this.cmap, e); let a = this.compiledGlyphs[t.glyphId]; if (!a) { a = this.compileGlyph(this.glyphs[t.glyphId], t.glyphId); this.compiledGlyphs[t.glyphId] = a } void 0 === this.compiledCharCodeToGlyphId[t.charCode] && (this.compiledCharCodeToGlyphId[t.charCode] = t.glyphId); return a } compileGlyph(e, t) { if (!e || 0 === e.length || 14 === e[0]) return u; let a = this.fontMatrix; if (this.isCFFCIDFont) { const e = this.fdSelect.getFDIndex(t); if (e >= 0 && e < this.fdArray.length) { a = this.fdArray[e].getByName("FontMatrix") || r.FONT_IDENTITY_MATRIX } else (0, r.warn)("Invalid fd index for glyph index.") } const i = []; i.push({ cmd: "save" }); i.push({ cmd: "transform", args: a.slice() }); i.push({ cmd: "scale", args: ["size", "-size"] }); this.compileGlyphImpl(e, i, t); i.push({ cmd: "restore" }); return i } compileGlyphImpl() { (0, r.unreachable)("Children classes should implement this.") } hasBuiltPath(e) { const t = h(this.cmap, e); return void 0 !== this.compiledGlyphs[t.glyphId] && void 0 !== this.compiledCharCodeToGlyphId[t.charCode] } } class f extends d { constructor(e, t, a) { super(a || [488e-6, 0, 0, 488e-6, 0, 0]); this.glyphs = e; this.cmap = t } compileGlyphImpl(e, t) { !function e(t, a, r) { function i(e, t) { a.push({ cmd: "moveTo", args: [e, t] }) } function n(e, t) { a.push({ cmd: "lineTo", args: [e, t] }) } function s(e, t, r, i) { a.push({ cmd: "quadraticCurveTo", args: [e, t, r, i] }) } var o, c = 0, l = (t[c] << 24 | t[c + 1] << 16) >> 16, h = 0, u = 0; c += 10; if (l < 0) do { o = t[c] << 8 | t[c + 1]; var d, f, g = t[c + 2] << 8 | t[c + 3]; c += 4; if (1 & o) { d = (t[c] << 24 | t[c + 1] << 16) >> 16; f = (t[c + 2] << 24 | t[c + 3] << 16) >> 16; c += 4 } else { d = t[c++]; f = t[c++] } if (2 & o) { h = d; u = f } else { h = 0; u = 0 } var m = 1, p = 1, b = 0, y = 0; if (8 & o) { m = p = (t[c] << 24 | t[c + 1] << 16) / 1073741824; c += 2 } else if (64 & o) { m = (t[c] << 24 | t[c + 1] << 16) / 1073741824; p = (t[c + 2] << 24 | t[c + 3] << 16) / 1073741824; c += 4 } else if (128 & o) { m = (t[c] << 24 | t[c + 1] << 16) / 1073741824; b = (t[c + 2] << 24 | t[c + 3] << 16) / 1073741824; y = (t[c + 4] << 24 | t[c + 5] << 16) / 1073741824; p = (t[c + 6] << 24 | t[c + 7] << 16) / 1073741824; c += 8 } var v = r.glyphs[g]; if (v) { a.push({ cmd: "save" }); a.push({ cmd: "transform", args: [m, b, y, p, h, u] }); e(v, a, r); a.push({ cmd: "restore" }) } } while (32 & o); else { var w, k, S = []; for (w = 0; w < l; w++) { S.push(t[c] << 8 | t[c + 1]); c += 2 } c += 2 + (t[c] << 8 | t[c + 1]); for (var C = S[S.length - 1] + 1, x = []; x.length < C;) { var A = 1; 8 & (o = t[c++]) && (A += t[c++]); for (; A-- > 0;)x.push({ flags: o }) } for (w = 0; w < C; w++) { switch (18 & x[w].flags) { case 0: h += (t[c] << 24 | t[c + 1] << 16) >> 16; c += 2; break; case 2: h -= t[c++]; break; case 18: h += t[c++] }x[w].x = h } for (w = 0; w < C; w++) { switch (36 & x[w].flags) { case 0: u += (t[c] << 24 | t[c + 1] << 16) >> 16; c += 2; break; case 4: u -= t[c++]; break; case 36: u += t[c++] }x[w].y = u } var I = 0; for (c = 0; c < l; c++) { var F = S[c], T = x.slice(I, F + 1); if (1 & T[0].flags) T.push(T[0]); else if (1 & T[T.length - 1].flags) T.unshift(T[T.length - 1]); else { var E = { flags: 1, x: (T[0].x + T[T.length - 1].x) / 2, y: (T[0].y + T[T.length - 1].y) / 2 }; T.unshift(E); T.push(E) } i(T[0].x, T[0].y); for (w = 1, k = T.length; w < k; w++)if (1 & T[w].flags) n(T[w].x, T[w].y); else if (1 & T[w + 1].flags) { s(T[w].x, T[w].y, T[w + 1].x, T[w + 1].y); w++ } else s(T[w].x, T[w].y, (T[w].x + T[w + 1].x) / 2, (T[w].y + T[w + 1].y) / 2); I = F + 1 } } }(e, t, this) } } class g extends d { constructor(e, t, r, i) { super(r || [.001, 0, 0, .001, 0, 0]); this.glyphs = e.glyphs; this.gsubrs = e.gsubrs || []; this.subrs = e.subrs || []; this.cmap = t; this.glyphNameMap = i || (0, n.getGlyphsUnicode)(); this.gsubrsBias = a(this.gsubrs); this.subrsBias = a(this.subrs); this.isCFFCIDFont = e.isCFFCIDFont; this.fdSelect = e.fdSelect; this.fdArray = e.fdArray } compileGlyphImpl(e, t, i) { !function e(t, i, n, o) { var c = [], l = 0, u = 0, d = 0; function f(e, t) { i.push({ cmd: "moveTo", args: [e, t] }) } function g(e, t) { i.push({ cmd: "lineTo", args: [e, t] }) } function m(e, t, a, r, n, s) { i.push({ cmd: "bezierCurveTo", args: [e, t, a, r, n, s] }) } !function t(p) { for (var b = 0; b < p.length;) { var y, v, w, k, S, C, x, A, I = !1, F = p[b++]; switch (F) { case 1: case 3: d += c.length >> 1; I = !0; break; case 4: u += c.pop(); f(l, u); I = !0; break; case 5: for (; c.length > 0;) { l += c.shift(); u += c.shift(); g(l, u) } break; case 6: for (; c.length > 0;) { g(l += c.shift(), u); if (0 === c.length) break; u += c.shift(); g(l, u) } break; case 7: for (; c.length > 0;) { u += c.shift(); g(l, u); if (0 === c.length) break; g(l += c.shift(), u) } break; case 8: for (; c.length > 0;) { y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u) } break; case 10: x = c.pop(); A = null; if (n.isCFFCIDFont) { const e = n.fdSelect.getFDIndex(o); if (e >= 0 && e < n.fdArray.length) { const t = n.fdArray[e]; let r; t.privateDict && t.privateDict.subrsIndex && (r = t.privateDict.subrsIndex.objects); r && (A = r[x += a(r)]) } else (0, r.warn)("Invalid fd index for glyph index.") } else A = n.subrs[x + n.subrsBias]; A && t(A); break; case 11: return; case 12: switch (F = p[b++]) { case 34: v = (y = l + c.shift()) + c.shift(); S = u + c.shift(); l = v + c.shift(); m(y, u, v, S, l, S); v = (y = l + c.shift()) + c.shift(); l = v + c.shift(); m(y, S, v, u, l, u); break; case 35: y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u); y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u); c.pop(); break; case 36: m(y = l + c.shift(), S = u + c.shift(), v = y + c.shift(), C = S + c.shift(), l = v + c.shift(), C); m(y = l + c.shift(), C, v = y + c.shift(), C + c.shift(), l = v + c.shift(), u); break; case 37: var T = l, E = u; y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u); y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v; u = k; Math.abs(l - T) > Math.abs(u - E) ? l += c.shift() : u += c.shift(); m(y, w, v, k, l, u); break; default: throw new r.FormatError(`unknown operator: 12 ${F}`) }break; case 14: if (c.length >= 4) { var O = c.pop(), P = c.pop(); u = c.pop(); l = c.pop(); i.push({ cmd: "save" }); i.push({ cmd: "translate", args: [l, u] }); var B = h(n.cmap, String.fromCharCode(n.glyphNameMap[s.StandardEncoding[O]])); e(n.glyphs[B.glyphId], i, n, B.glyphId); i.push({ cmd: "restore" }); B = h(n.cmap, String.fromCharCode(n.glyphNameMap[s.StandardEncoding[P]])); e(n.glyphs[B.glyphId], i, n, B.glyphId) } return; case 18: d += c.length >> 1; I = !0; break; case 19: case 20: b += (d += c.length >> 1) + 7 >> 3; I = !0; break; case 21: u += c.pop(); f(l += c.pop(), u); I = !0; break; case 22: f(l += c.pop(), u); I = !0; break; case 23: d += c.length >> 1; I = !0; break; case 24: for (; c.length > 2;) { y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u) } l += c.shift(); u += c.shift(); g(l, u); break; case 25: for (; c.length > 6;) { l += c.shift(); u += c.shift(); g(l, u) } y = l + c.shift(); w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + c.shift(); m(y, w, v, k, l, u); break; case 26: c.length % 2 && (l += c.shift()); for (; c.length > 0;) { y = l; w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v; u = k + c.shift(); m(y, w, v, k, l, u) } break; case 27: c.length % 2 && (u += c.shift()); for (; c.length > 0;)m(y = l + c.shift(), w = u, v = y + c.shift(), k = w + c.shift(), l = v + c.shift(), u = k); break; case 28: c.push((p[b] << 24 | p[b + 1] << 16) >> 16); b += 2; break; case 29: x = c.pop() + n.gsubrsBias; (A = n.gsubrs[x]) && t(A); break; case 30: for (; c.length > 0;) { y = l; w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + (1 === c.length ? c.shift() : 0); m(y, w, v, k, l, u); if (0 === c.length) break; y = l + c.shift(); w = u; v = y + c.shift(); k = w + c.shift(); u = k + c.shift(); m(y, w, v, k, l = v + (1 === c.length ? c.shift() : 0), u) } break; case 31: for (; c.length > 0;) { y = l + c.shift(); w = u; v = y + c.shift(); k = w + c.shift(); u = k + c.shift(); m(y, w, v, k, l = v + (1 === c.length ? c.shift() : 0), u); if (0 === c.length) break; y = l; w = u + c.shift(); v = y + c.shift(); k = w + c.shift(); l = v + c.shift(); u = k + (1 === c.length ? c.shift() : 0); m(y, w, v, k, l, u) } break; default: if (F < 32) throw new r.FormatError(`unknown operator: ${F}`); if (F < 247) c.push(F - 139); else if (F < 251) c.push(256 * (F - 247) + p[b++] + 108); else if (F < 255) c.push(256 * -(F - 251) - p[b++] - 108); else { c.push((p[b] << 24 | p[b + 1] << 16 | p[b + 2] << 8 | p[b + 3]) / 65536); b += 4 } }I && (c.length = 0) } }(t) }(e, t, this, i) } } return { create: function (a, i) { for (var n, s, o, h, u, d, m = new Uint8Array(a.data), p = t(m, 4), b = 0, y = 12; b < p; b++, y += 16) { var v = (0, r.bytesToString)(m.subarray(y, y + 4)), w = e(m, y + 8), k = e(m, y + 12); switch (v) { case "cmap": n = c(m, w); break; case "glyf": s = m.subarray(w, w + k); break; case "loca": o = m.subarray(w, w + k); break; case "head": d = t(m, w + 18); u = t(m, w + 50); break; case "CFF ": h = l(m, w, w + k, i) } } if (s) { var S = d ? [1 / d, 0, 0, 1 / d, 0, 0] : a.fontMatrix; return new f(function (e, t, a) { var r, i; if (a) { r = 4; i = function (e, t) { return e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3] } } else { r = 2; i = function (e, t) { return e[t] << 9 | e[t + 1] << 1 } } for (var n = [], s = i(t, 0), o = r; o < t.length; o += r) { var c = i(t, o); n.push(e.subarray(s, c)); s = c } return n }(s, o, u), n, S) } return new g(h, n, a.fontMatrix, a.glyphNameMap) } } }(); t.FontRendererFactory = c }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.Type1Parser = void 0; var r = a(30), i = a(7), n = a(11), s = a(2), o = function () { var e = [4], t = [5], a = [6], r = [7], i = [8], n = [12, 35], o = [14], c = [21], l = [22], h = [30], u = [31]; function d() { this.width = 0; this.lsb = 0; this.flexing = !1; this.output = []; this.stack = [] } d.prototype = { convert: function (d, f, g) { for (var m, p, b, y = d.length, v = !1, w = 0; w < y; w++) { var k = d[w]; if (k < 32) { 12 === k && (k = (k << 8) + d[++w]); switch (k) { case 1: case 3: this.stack = []; break; case 4: if (this.flexing) { if (this.stack.length < 1) { v = !0; break } var S = this.stack.pop(); this.stack.push(0, S); break } v = this.executeCommand(1, e); break; case 5: v = this.executeCommand(2, t); break; case 6: v = this.executeCommand(1, a); break; case 7: v = this.executeCommand(1, r); break; case 8: v = this.executeCommand(6, i); break; case 9: this.stack = []; break; case 10: if (this.stack.length < 1) { v = !0; break } if (!f[b = this.stack.pop()]) { v = !0; break } v = this.convert(f[b], f, g); break; case 11: return v; case 13: if (this.stack.length < 2) { v = !0; break } m = this.stack.pop(); p = this.stack.pop(); this.lsb = p; this.width = m; this.stack.push(m, p); v = this.executeCommand(2, l); break; case 14: this.output.push(o[0]); break; case 21: if (this.flexing) break; v = this.executeCommand(2, c); break; case 22: if (this.flexing) { this.stack.push(0); break } v = this.executeCommand(1, l); break; case 30: v = this.executeCommand(4, h); break; case 31: v = this.executeCommand(4, u); break; case 3072: case 3073: case 3074: this.stack = []; break; case 3078: if (g) { this.seac = this.stack.splice(-4, 4); v = this.executeCommand(0, o) } else v = this.executeCommand(4, o); break; case 3079: if (this.stack.length < 4) { v = !0; break } this.stack.pop(); m = this.stack.pop(); var C = this.stack.pop(); p = this.stack.pop(); this.lsb = p; this.width = m; this.stack.push(m, p, C); v = this.executeCommand(3, c); break; case 3084: if (this.stack.length < 2) { v = !0; break } var x = this.stack.pop(), A = this.stack.pop(); this.stack.push(A / x); break; case 3088: if (this.stack.length < 2) { v = !0; break } b = this.stack.pop(); var I = this.stack.pop(); if (0 === b && 3 === I) { var F = this.stack.splice(this.stack.length - 17, 17); this.stack.push(F[2] + F[0], F[3] + F[1], F[4], F[5], F[6], F[7], F[8], F[9], F[10], F[11], F[12], F[13], F[14]); v = this.executeCommand(13, n, !0); this.flexing = !1; this.stack.push(F[15], F[16]) } else 1 === b && 0 === I && (this.flexing = !0); break; case 3089: break; case 3105: this.stack = []; break; default: (0, s.warn)('Unknown type 1 charstring command of "' + k + '"') }if (v) break } else { k <= 246 ? k -= 139 : k = k <= 250 ? 256 * (k - 247) + d[++w] + 108 : k <= 254 ? -256 * (k - 251) - d[++w] - 108 : (255 & d[++w]) << 24 | (255 & d[++w]) << 16 | (255 & d[++w]) << 8 | (255 & d[++w]) << 0; this.stack.push(k) } } return v }, executeCommand(e, t, a) { var r = this.stack.length; if (e > r) return !0; for (var i = r - e, n = i; n < r; n++) { var s = this.stack[n]; if (Number.isInteger(s)) this.output.push(28, s >> 8 & 255, 255 & s); else { s = 65536 * s | 0; this.output.push(255, s >> 24 & 255, s >> 16 & 255, s >> 8 & 255, 255 & s) } } this.output.push.apply(this.output, t); a ? this.stack.splice(i, e) : this.stack.length = 0; return !1 } }; return d }(), c = function () { function e(e) { return e >= 48 && e <= 57 || e >= 65 && e <= 70 || e >= 97 && e <= 102 } function t(e, t, a) { if (a >= e.length) return new Uint8Array(0); var r, i, n = 0 | t; for (r = 0; r < a; r++)n = 52845 * (e[r] + n) + 22719 & 65535; var s = e.length - a, o = new Uint8Array(s); for (r = a, i = 0; i < s; r++, i++) { var c = e[r]; o[i] = c ^ n >> 8; n = 52845 * (c + n) + 22719 & 65535 } return o } function a(e) { return 47 === e || 91 === e || 93 === e || 123 === e || 125 === e || 40 === e || 41 === e } function s(a, r, i) { if (r) { var s = a.getBytes(), o = !(e(s[0]) && e(s[1]) && e(s[2]) && e(s[3])); a = new n.Stream(o ? t(s, 55665, 4) : function (t, a, r) { var i, n, s = 0 | a, o = t.length, c = new Uint8Array(o >>> 1); for (i = 0, n = 0; i < o; i++) { var l = t[i]; if (e(l)) { i++; for (var h; i < o && !e(h = t[i]);)i++; if (i < o) { var u = parseInt(String.fromCharCode(l, h), 16); c[n++] = u ^ s >> 8; s = 52845 * (u + s) + 22719 & 65535 } } } return Array.prototype.slice.call(c, r, n) }(s, 55665, 4)) } this.seacAnalysisEnabled = !!i; this.stream = a; this.nextChar() } s.prototype = { readNumberArray: function () { this.getToken(); for (var e = []; ;) { var t = this.getToken(); if (null === t || "]" === t || "}" === t) break; e.push(parseFloat(t || 0)) } return e }, readNumber: function () { var e = this.getToken(); return parseFloat(e || 0) }, readInt: function () { var e = this.getToken(); return 0 | parseInt(e || 0, 10) }, readBoolean: function () { return "true" === this.getToken() ? 1 : 0 }, nextChar: function () { return this.currentChar = this.stream.getByte() }, getToken: function () { for (var e = !1, t = this.currentChar; ;) { if (-1 === t) return null; if (e) 10 !== t && 13 !== t || (e = !1); else if (37 === t) e = !0; else if (!(0, i.isWhiteSpace)(t)) break; t = this.nextChar() } if (a(t)) { this.nextChar(); return String.fromCharCode(t) } var r = ""; do { r += String.fromCharCode(t); t = this.nextChar() } while (t >= 0 && !(0, i.isWhiteSpace)(t) && !a(t)); return r }, readCharStrings: function (e, a) { return -1 === a ? e : t(e, 4330, a) }, extractFontProgram: function (e) { var t = this.stream, a = [], r = [], i = Object.create(null); i.lenIV = 4; for (var n, s, c, l, h, u = { subrs: [], charstrings: [], properties: { privateData: i } }; null !== (n = this.getToken());)if ("/" === n) switch (n = this.getToken()) { case "CharStrings": this.getToken(); this.getToken(); this.getToken(); this.getToken(); for (; null !== (n = this.getToken()) && "end" !== n;)if ("/" === n) { var d = this.getToken(); s = this.readInt(); this.getToken(); c = s > 0 ? t.getBytes(s) : new Uint8Array(0); l = u.properties.privateData.lenIV; h = this.readCharStrings(c, l); this.nextChar(); "noaccess" === (n = this.getToken()) && this.getToken(); r.push({ glyph: d, encoded: h }) } break; case "Subrs": this.readInt(); this.getToken(); for (; "dup" === this.getToken();) { var f = this.readInt(); s = this.readInt(); this.getToken(); c = s > 0 ? t.getBytes(s) : new Uint8Array(0); l = u.properties.privateData.lenIV; h = this.readCharStrings(c, l); this.nextChar(); "noaccess" === (n = this.getToken()) && this.getToken(); a[f] = h } break; case "BlueValues": case "OtherBlues": case "FamilyBlues": case "FamilyOtherBlues": var g = this.readNumberArray(); g.length > 0 && g.length, 0; break; case "StemSnapH": case "StemSnapV": u.properties.privateData[n] = this.readNumberArray(); break; case "StdHW": case "StdVW": u.properties.privateData[n] = this.readNumberArray()[0]; break; case "BlueShift": case "lenIV": case "BlueFuzz": case "BlueScale": case "LanguageGroup": case "ExpansionFactor": u.properties.privateData[n] = this.readNumber(); break; case "ForceBold": u.properties.privateData[n] = this.readBoolean() }for (var m = 0; m < r.length; m++) { d = r[m].glyph; h = r[m].encoded; var p = new o, b = p.convert(h, a, this.seacAnalysisEnabled), y = p.output; b && (y = [14]); const t = { glyphName: d, charstring: y, width: p.width, lsb: p.lsb, seac: p.seac }; ".notdef" === d ? u.charstrings.unshift(t) : u.charstrings.push(t); if (e.builtInEncoding) { const t = e.builtInEncoding.indexOf(d); t > -1 && void 0 === e.widths[t] && t >= e.firstChar && t <= e.lastChar && (e.widths[t] = p.width) } } return u }, extractFontHeader: function (e) { for (var t; null !== (t = this.getToken());)if ("/" === t) switch (t = this.getToken()) { case "FontMatrix": var a = this.readNumberArray(); e.fontMatrix = a; break; case "Encoding": var i, n = this.getToken(); if (/^\d+$/.test(n)) { i = []; var s = 0 | parseInt(n, 10); this.getToken(); for (var o = 0; o < s; o++) { t = this.getToken(); for (; "dup" !== t && "def" !== t;)if (null === (t = this.getToken())) return; if ("def" === t) break; var c = this.readInt(); this.getToken(); var l = this.getToken(); i[c] = l; this.getToken() } } else i = (0, r.getEncoding)(n); e.builtInEncoding = i; break; case "FontBBox": var h = this.readNumberArray(); e.ascent = Math.max(h[3], h[1]); e.descent = Math.min(h[1], h[3]); e.ascentScaled = !0 } } }; return s }(); t.Type1Parser = c }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getTilingPatternIR = function (e, t, a) { const i = t.getArray("Matrix"), n = r.Util.normalizeRect(t.getArray("BBox")), s = t.get("XStep"), o = t.get("YStep"), c = t.get("PaintType"), l = t.get("TilingType"); if (n[2] - n[0] == 0 || n[3] - n[1] == 0) throw new r.FormatError(`Invalid getTilingPatternIR /BBox array: [${n}].`); return ["TilingPattern", a, e, i, n, s, o, c, l] }; t.Pattern = void 0; var r = a(2), i = a(22), n = a(4), s = a(7), o = 2, c = 3, l = 4, h = 5, u = 6, d = 7, f = function () { function e() { (0, r.unreachable)("should not call Pattern constructor") } e.prototype = { getPattern: function (e) { (0, r.unreachable)(`Should not call Pattern.getStyle: ${e}`) } }; e.parseShading = function (e, t, a, i, f, m) { var p = (0, n.isStream)(e) ? e.dict : e, b = p.get("ShadingType"); try { switch (b) { case o: case c: return new g.RadialAxial(p, t, a, i, m); case l: case h: case u: case d: return new g.Mesh(e, t, a, i, m); default: throw new r.FormatError("Unsupported ShadingType: " + b) } } catch (e) { if (e instanceof s.MissingDataException) throw e; f.send("UnsupportedFeature", { featureId: r.UNSUPPORTED_FEATURES.shadingPattern }); (0, r.warn)(e); return new g.Dummy } }; return e }(); t.Pattern = f; var g = { SMALL_NUMBER: 1e-6 }; g.RadialAxial = function () { function e(e, t, a, n, s) { this.matrix = t; this.coordsArr = e.getArray("Coords"); this.shadingType = e.get("ShadingType"); this.type = "Pattern"; var o = e.get("ColorSpace", "CS"); o = i.ColorSpace.parse(o, a, n, s); this.cs = o; const l = e.getArray("BBox"); Array.isArray(l) && 4 === l.length ? this.bbox = r.Util.normalizeRect(l) : this.bbox = null; var h = 0, u = 1; if (e.has("Domain")) { var d = e.getArray("Domain"); h = d[0]; u = d[1] } var f = !1, m = !1; if (e.has("Extend")) { var p = e.getArray("Extend"); f = p[0]; m = p[1] } if (!(this.shadingType !== c || f && m)) { var b = this.coordsArr[0], y = this.coordsArr[1], v = this.coordsArr[2], w = this.coordsArr[3], k = this.coordsArr[4], S = this.coordsArr[5], C = Math.sqrt((b - w) * (b - w) + (y - k) * (y - k)); v <= S + C && S <= v + C && (0, r.warn)("Unsupported radial gradient.") } this.extendStart = f; this.extendEnd = m; var x = e.get("Function"), A = s.createFromArray(x); const I = (u - h) / 10; var F = this.colorStops = []; if (h >= u || I <= 0) (0, r.info)("Bad shading domain."); else { var T, E = new Float32Array(o.numComps), O = new Float32Array(1); for (let e = 0; e <= 10; e++) { O[0] = h + e * I; A(O, 0, E, 0); T = o.getRgb(E, 0); var P = r.Util.makeCssRgb(T[0], T[1], T[2]); F.push([e / 10, P]) } var B = "transparent"; if (e.has("Background")) { T = o.getRgb(e.get("Background"), 0); B = r.Util.makeCssRgb(T[0], T[1], T[2]) } if (!f) { F.unshift([0, B]); F[1][0] += g.SMALL_NUMBER } if (!m) { F[F.length - 1][0] -= g.SMALL_NUMBER; F.push([1, B]) } this.colorStops = F } } e.prototype = { getIR: function () { var e, t, a, i, n, s = this.coordsArr, l = this.shadingType; if (l === o) { t = [s[0], s[1]]; a = [s[2], s[3]]; i = null; n = null; e = "axial" } else if (l === c) { t = [s[0], s[1]]; a = [s[3], s[4]]; i = s[2]; n = s[5]; e = "radial" } else (0, r.unreachable)(`getPattern type unknown: ${l}`); var h = this.matrix; if (h) { t = r.Util.applyTransform(t, h); a = r.Util.applyTransform(a, h); if (l === c) { var u = r.Util.singularValueDecompose2dScale(h); i *= u[0]; n *= u[1] } } return ["RadialAxial", e, this.bbox, this.colorStops, t, a, i, n] } }; return e }(); g.Mesh = function () { function e(e, t) { this.stream = e; this.context = t; this.buffer = 0; this.bufferLength = 0; var a = t.numComps; this.tmpCompsBuf = new Float32Array(a); var r = t.colorSpace.numComps; this.tmpCsCompsBuf = t.colorFn ? new Float32Array(r) : this.tmpCompsBuf } e.prototype = { get hasData() { if (this.stream.end) return this.stream.pos < this.stream.end; if (this.bufferLength > 0) return !0; var e = this.stream.getByte(); if (e < 0) return !1; this.buffer = e; this.bufferLength = 8; return !0 }, readBits: function (e) { var t = this.buffer, a = this.bufferLength; if (32 === e) { if (0 === a) return (this.stream.getByte() << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte()) >>> 0; t = t << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte(); var r = this.stream.getByte(); this.buffer = r & (1 << a) - 1; return (t << 8 - a | (255 & r) >> a) >>> 0 } if (8 === e && 0 === a) return this.stream.getByte(); for (; a < e;) { t = t << 8 | this.stream.getByte(); a += 8 } a -= e; this.bufferLength = a; this.buffer = t & (1 << a) - 1; return t >> a }, align: function () { this.buffer = 0; this.bufferLength = 0 }, readFlag: function () { return this.readBits(this.context.bitsPerFlag) }, readCoordinate: function () { var e = this.context.bitsPerCoordinate, t = this.readBits(e), a = this.readBits(e), r = this.context.decode, i = e < 32 ? 1 / ((1 << e) - 1) : 2.3283064365386963e-10; return [t * i * (r[1] - r[0]) + r[0], a * i * (r[3] - r[2]) + r[2]] }, readComponents: function () { for (var e = this.context.numComps, t = this.context.bitsPerComponent, a = t < 32 ? 1 / ((1 << t) - 1) : 2.3283064365386963e-10, r = this.context.decode, i = this.tmpCompsBuf, n = 0, s = 4; n < e; n++, s += 2) { var o = this.readBits(t); i[n] = o * a * (r[s + 1] - r[s]) + r[s] } var c = this.tmpCsCompsBuf; this.context.colorFn && this.context.colorFn(i, 0, c, 0); return this.context.colorSpace.getRgb(c, 0) } }; var t, a = (t = [], function (e) { t[e] || (t[e] = function (e) { for (var t = [], a = 0; a <= e; a++) { var r = a / e, i = 1 - r; t.push(new Float32Array([i * i * i, 3 * r * i * i, 3 * r * r * i, r * r * r])) } return t }(e)); return t[e] }); function s(e, t) { var i = e.figures[t]; (0, r.assert)("patch" === i.type, "Unexpected patch mesh figure"); var n = e.coords, s = e.colors, o = i.coords, c = i.colors, l = Math.min(n[o[0]][0], n[o[3]][0], n[o[12]][0], n[o[15]][0]), h = Math.min(n[o[0]][1], n[o[3]][1], n[o[12]][1], n[o[15]][1]), u = Math.max(n[o[0]][0], n[o[3]][0], n[o[12]][0], n[o[15]][0]), d = Math.max(n[o[0]][1], n[o[3]][1], n[o[12]][1], n[o[15]][1]), f = Math.ceil(20 * (u - l) / (e.bounds[2] - e.bounds[0])); f = Math.max(3, Math.min(20, f)); var g = Math.ceil(20 * (d - h) / (e.bounds[3] - e.bounds[1])); g = Math.max(3, Math.min(20, g)); for (var m = f + 1, p = new Int32Array((g + 1) * m), b = new Int32Array((g + 1) * m), y = 0, v = new Uint8Array(3), w = new Uint8Array(3), k = s[c[0]], S = s[c[1]], C = s[c[2]], x = s[c[3]], A = a(g), I = a(f), F = 0; F <= g; F++) { v[0] = (k[0] * (g - F) + C[0] * F) / g | 0; v[1] = (k[1] * (g - F) + C[1] * F) / g | 0; v[2] = (k[2] * (g - F) + C[2] * F) / g | 0; w[0] = (S[0] * (g - F) + x[0] * F) / g | 0; w[1] = (S[1] * (g - F) + x[1] * F) / g | 0; w[2] = (S[2] * (g - F) + x[2] * F) / g | 0; for (var T = 0; T <= f; T++, y++)if (0 !== F && F !== g || 0 !== T && T !== f) { for (var E = 0, O = 0, P = 0, B = 0; B <= 3; B++)for (var D = 0; D <= 3; D++, P++) { var N = A[F][B] * I[T][D]; E += n[o[P]][0] * N; O += n[o[P]][1] * N } p[y] = n.length; n.push([E, O]); b[y] = s.length; var M = new Uint8Array(3); M[0] = (v[0] * (f - T) + w[0] * T) / f | 0; M[1] = (v[1] * (f - T) + w[1] * T) / f | 0; M[2] = (v[2] * (f - T) + w[2] * T) / f | 0; s.push(M) } } p[0] = o[0]; b[0] = c[0]; p[f] = o[3]; b[f] = c[1]; p[m * g] = o[12]; b[m * g] = c[2]; p[m * g + f] = o[15]; b[m * g + f] = c[3]; e.figures[t] = { type: "lattice", coords: p, colors: b, verticesPerRow: m } } function o(e) { for (var t = e.coords[0][0], a = e.coords[0][1], r = t, i = a, n = 1, s = e.coords.length; n < s; n++) { var o = e.coords[n][0], c = e.coords[n][1]; t = t > o ? o : t; a = a > c ? c : a; r = r < o ? o : r; i = i < c ? c : i } e.bounds = [t, a, r, i] } function c(t, a, c, f, g) { if (!(0, n.isStream)(t)) throw new r.FormatError("Mesh data is not a stream"); var m = t.dict; this.matrix = a; this.shadingType = m.get("ShadingType"); this.type = "Pattern"; const p = m.getArray("BBox"); Array.isArray(p) && 4 === p.length ? this.bbox = r.Util.normalizeRect(p) : this.bbox = null; var b = m.get("ColorSpace", "CS"); b = i.ColorSpace.parse(b, c, f, g); this.cs = b; this.background = m.has("Background") ? b.getRgb(m.get("Background"), 0) : null; var y = m.get("Function"), v = y ? g.createFromArray(y) : null; this.coords = []; this.colors = []; this.figures = []; var w = new e(t, { bitsPerCoordinate: m.get("BitsPerCoordinate"), bitsPerComponent: m.get("BitsPerComponent"), bitsPerFlag: m.get("BitsPerFlag"), decode: m.getArray("Decode"), colorFn: v, colorSpace: b, numComps: v ? 1 : b.numComps }), k = !1; switch (this.shadingType) { case l: !function (e, t) { for (var a = e.coords, i = e.colors, n = [], s = [], o = 0; t.hasData;) { var c = t.readFlag(), l = t.readCoordinate(), h = t.readComponents(); if (0 === o) { if (!(0 <= c && c <= 2)) throw new r.FormatError("Unknown type4 flag"); switch (c) { case 0: o = 3; break; case 1: s.push(s[s.length - 2], s[s.length - 1]); o = 1; break; case 2: s.push(s[s.length - 3], s[s.length - 1]); o = 1 }n.push(c) } s.push(a.length); a.push(l); i.push(h); o--; t.align() } e.figures.push({ type: "triangles", coords: new Int32Array(s), colors: new Int32Array(s) }) }(this, w); break; case h: var S = 0 | m.get("VerticesPerRow"); if (S < 2) throw new r.FormatError("Invalid VerticesPerRow"); !function (e, t, a) { for (var r = e.coords, i = e.colors, n = []; t.hasData;) { var s = t.readCoordinate(), o = t.readComponents(); n.push(r.length); r.push(s); i.push(o) } e.figures.push({ type: "lattice", coords: new Int32Array(n), colors: new Int32Array(n), verticesPerRow: a }) }(this, w, S); break; case u: !function (e, t) { for (var a = e.coords, i = e.colors, n = new Int32Array(16), s = new Int32Array(4); t.hasData;) { var o, c, l = t.readFlag(); if (!(0 <= l && l <= 3)) throw new r.FormatError("Unknown type6 flag"); var h = a.length; for (o = 0, c = 0 !== l ? 8 : 12; o < c; o++)a.push(t.readCoordinate()); var u, d, f, g, m = i.length; for (o = 0, c = 0 !== l ? 2 : 4; o < c; o++)i.push(t.readComponents()); switch (l) { case 0: n[12] = h + 3; n[13] = h + 4; n[14] = h + 5; n[15] = h + 6; n[8] = h + 2; n[11] = h + 7; n[4] = h + 1; n[7] = h + 8; n[0] = h; n[1] = h + 11; n[2] = h + 10; n[3] = h + 9; s[2] = m + 1; s[3] = m + 2; s[0] = m; s[1] = m + 3; break; case 1: u = n[12]; d = n[13]; f = n[14]; g = n[15]; n[12] = g; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = f; n[11] = h + 3; n[4] = d; n[7] = h + 4; n[0] = u; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; u = s[2]; d = s[3]; s[2] = d; s[3] = m; s[0] = u; s[1] = m + 1; break; case 2: u = n[15]; d = n[11]; n[12] = n[3]; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = n[7]; n[11] = h + 3; n[4] = d; n[7] = h + 4; n[0] = u; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; u = s[3]; s[2] = s[1]; s[3] = m; s[0] = u; s[1] = m + 1; break; case 3: n[12] = n[0]; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = n[1]; n[11] = h + 3; n[4] = n[2]; n[7] = h + 4; n[0] = n[3]; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; s[2] = s[0]; s[3] = m; s[0] = s[1]; s[1] = m + 1 }n[5] = a.length; a.push([(-4 * a[n[0]][0] - a[n[15]][0] + 6 * (a[n[4]][0] + a[n[1]][0]) - 2 * (a[n[12]][0] + a[n[3]][0]) + 3 * (a[n[13]][0] + a[n[7]][0])) / 9, (-4 * a[n[0]][1] - a[n[15]][1] + 6 * (a[n[4]][1] + a[n[1]][1]) - 2 * (a[n[12]][1] + a[n[3]][1]) + 3 * (a[n[13]][1] + a[n[7]][1])) / 9]); n[6] = a.length; a.push([(-4 * a[n[3]][0] - a[n[12]][0] + 6 * (a[n[2]][0] + a[n[7]][0]) - 2 * (a[n[0]][0] + a[n[15]][0]) + 3 * (a[n[4]][0] + a[n[14]][0])) / 9, (-4 * a[n[3]][1] - a[n[12]][1] + 6 * (a[n[2]][1] + a[n[7]][1]) - 2 * (a[n[0]][1] + a[n[15]][1]) + 3 * (a[n[4]][1] + a[n[14]][1])) / 9]); n[9] = a.length; a.push([(-4 * a[n[12]][0] - a[n[3]][0] + 6 * (a[n[8]][0] + a[n[13]][0]) - 2 * (a[n[0]][0] + a[n[15]][0]) + 3 * (a[n[11]][0] + a[n[1]][0])) / 9, (-4 * a[n[12]][1] - a[n[3]][1] + 6 * (a[n[8]][1] + a[n[13]][1]) - 2 * (a[n[0]][1] + a[n[15]][1]) + 3 * (a[n[11]][1] + a[n[1]][1])) / 9]); n[10] = a.length; a.push([(-4 * a[n[15]][0] - a[n[0]][0] + 6 * (a[n[11]][0] + a[n[14]][0]) - 2 * (a[n[12]][0] + a[n[3]][0]) + 3 * (a[n[2]][0] + a[n[8]][0])) / 9, (-4 * a[n[15]][1] - a[n[0]][1] + 6 * (a[n[11]][1] + a[n[14]][1]) - 2 * (a[n[12]][1] + a[n[3]][1]) + 3 * (a[n[2]][1] + a[n[8]][1])) / 9]); e.figures.push({ type: "patch", coords: new Int32Array(n), colors: new Int32Array(s) }) } }(this, w); k = !0; break; case d: !function (e, t) { for (var a = e.coords, i = e.colors, n = new Int32Array(16), s = new Int32Array(4); t.hasData;) { var o, c, l = t.readFlag(); if (!(0 <= l && l <= 3)) throw new r.FormatError("Unknown type7 flag"); var h = a.length; for (o = 0, c = 0 !== l ? 12 : 16; o < c; o++)a.push(t.readCoordinate()); var u, d, f, g, m = i.length; for (o = 0, c = 0 !== l ? 2 : 4; o < c; o++)i.push(t.readComponents()); switch (l) { case 0: n[12] = h + 3; n[13] = h + 4; n[14] = h + 5; n[15] = h + 6; n[8] = h + 2; n[9] = h + 13; n[10] = h + 14; n[11] = h + 7; n[4] = h + 1; n[5] = h + 12; n[6] = h + 15; n[7] = h + 8; n[0] = h; n[1] = h + 11; n[2] = h + 10; n[3] = h + 9; s[2] = m + 1; s[3] = m + 2; s[0] = m; s[1] = m + 3; break; case 1: u = n[12]; d = n[13]; f = n[14]; g = n[15]; n[12] = g; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = f; n[9] = h + 9; n[10] = h + 10; n[11] = h + 3; n[4] = d; n[5] = h + 8; n[6] = h + 11; n[7] = h + 4; n[0] = u; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; u = s[2]; d = s[3]; s[2] = d; s[3] = m; s[0] = u; s[1] = m + 1; break; case 2: u = n[15]; d = n[11]; n[12] = n[3]; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = n[7]; n[9] = h + 9; n[10] = h + 10; n[11] = h + 3; n[4] = d; n[5] = h + 8; n[6] = h + 11; n[7] = h + 4; n[0] = u; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; u = s[3]; s[2] = s[1]; s[3] = m; s[0] = u; s[1] = m + 1; break; case 3: n[12] = n[0]; n[13] = h + 0; n[14] = h + 1; n[15] = h + 2; n[8] = n[1]; n[9] = h + 9; n[10] = h + 10; n[11] = h + 3; n[4] = n[2]; n[5] = h + 8; n[6] = h + 11; n[7] = h + 4; n[0] = n[3]; n[1] = h + 7; n[2] = h + 6; n[3] = h + 5; s[2] = s[0]; s[3] = m; s[0] = s[1]; s[1] = m + 1 }e.figures.push({ type: "patch", coords: new Int32Array(n), colors: new Int32Array(s) }) } }(this, w); k = !0; break; default: (0, r.unreachable)("Unsupported mesh type.") }if (k) { o(this); for (var C = 0, x = this.figures.length; C < x; C++)s(this, C) } o(this); !function (e) { var t, a, r, i, n = e.coords, s = new Float32Array(2 * n.length); for (t = 0, r = 0, a = n.length; t < a; t++) { var o = n[t]; s[r++] = o[0]; s[r++] = o[1] } e.coords = s; var c = e.colors, l = new Uint8Array(3 * c.length); for (t = 0, r = 0, a = c.length; t < a; t++) { var h = c[t]; l[r++] = h[0]; l[r++] = h[1]; l[r++] = h[2] } e.colors = l; var u = e.figures; for (t = 0, a = u.length; t < a; t++) { var d = u[t], f = d.coords, g = d.colors; for (r = 0, i = f.length; r < i; r++) { f[r] *= 2; g[r] *= 3 } } }(this) } c.prototype = { getIR: function () { return ["Mesh", this.shadingType, this.coords, this.colors, this.figures, this.bounds, this.matrix, this.bbox, this.background] } }; return c }(); g.Dummy = function () { function e() { this.type = "Pattern" } e.prototype = { getIR: function () { return ["Dummy"] } }; return e }() }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.bidi = function (e, t, a) { var g = !0, m = e.length; if (0 === m || a) return u(e, g, a); d.length = m; f.length = m; var p, b, y = 0; for (p = 0; p < m; ++p) { d[p] = e.charAt(p); var v = e.charCodeAt(p), w = "L"; v <= 255 ? w = i[v] : 1424 <= v && v <= 1524 ? w = "R" : 1536 <= v && v <= 1791 ? (w = n[255 & v]) || (0, r.warn)("Bidi: invalid Unicode character " + v.toString(16)) : 1792 <= v && v <= 2220 && (w = "AL"); "R" !== w && "AL" !== w && "AN" !== w || y++; f[p] = w } if (0 === y) return u(e, g = !0); if (-1 === t) if (y / m < .3) { g = !0; t = 0 } else { g = !1; t = 1 } var k = []; for (p = 0; p < m; ++p)k[p] = t; var S, C = s(t) ? "R" : "L", x = C, A = x, I = x; for (p = 0; p < m; ++p)"NSM" === f[p] ? f[p] = I : I = f[p]; I = x; for (p = 0; p < m; ++p)"EN" === (S = f[p]) ? f[p] = "AL" === I ? "AN" : "EN" : "R" !== S && "L" !== S && "AL" !== S || (I = S); for (p = 0; p < m; ++p)"AL" === (S = f[p]) && (f[p] = "R"); for (p = 1; p < m - 1; ++p) { "ES" === f[p] && "EN" === f[p - 1] && "EN" === f[p + 1] && (f[p] = "EN"); "CS" !== f[p] || "EN" !== f[p - 1] && "AN" !== f[p - 1] || f[p + 1] !== f[p - 1] || (f[p] = f[p - 1]) } for (p = 0; p < m; ++p)if ("EN" === f[p]) { var F; for (F = p - 1; F >= 0 && "ET" === f[F]; --F)f[F] = "EN"; for (F = p + 1; F < m && "ET" === f[F]; ++F)f[F] = "EN" } for (p = 0; p < m; ++p)"WS" !== (S = f[p]) && "ES" !== S && "ET" !== S && "CS" !== S || (f[p] = "ON"); I = x; for (p = 0; p < m; ++p)"EN" === (S = f[p]) ? f[p] = "L" === I ? "L" : "EN" : "R" !== S && "L" !== S || (I = S); for (p = 0; p < m; ++p)if ("ON" === f[p]) { var T = c(f, p + 1, "ON"), E = x; p > 0 && (E = f[p - 1]); var O = A; T + 1 < m && (O = f[T + 1]); "L" !== E && (E = "R"); "L" !== O && (O = "R"); E === O && l(f, p, T, E); p = T - 1 } for (p = 0; p < m; ++p)"ON" === f[p] && (f[p] = C); for (p = 0; p < m; ++p) { S = f[p]; o(k[p]) ? "R" === S ? k[p] += 1 : "AN" !== S && "EN" !== S || (k[p] += 2) : "L" !== S && "AN" !== S && "EN" !== S || (k[p] += 1) } var P, B = -1, D = 99; for (p = 0, b = k.length; p < b; ++p) { P = k[p]; B < P && (B = P); D > P && s(P) && (D = P) } for (P = B; P >= D; --P) { var N = -1; for (p = 0, b = k.length; p < b; ++p)if (k[p] < P) { if (N >= 0) { h(d, N, p); N = -1 } } else N < 0 && (N = p); N >= 0 && h(d, N, k.length) } for (p = 0, b = d.length; p < b; ++p) { var M = d[p]; "<" !== M && ">" !== M || (d[p] = "") } return u(d.join(""), g) }; var r = a(2), i = ["BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "S", "B", "S", "WS", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "B", "B", "B", "S", "WS", "ON", "ON", "ET", "ET", "ET", "ON", "ON", "ON", "ON", "ON", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON", "BN", "BN", "BN", "BN", "BN", "BN", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "CS", "ON", "ET", "ET", "ET", "ET", "ON", "ON", "ON", "ON", "L", "ON", "ON", "BN", "ON", "ON", "ET", "ET", "EN", "EN", "ON", "L", "ON", "ON", "ON", "EN", "L", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L"], n = ["AN", "AN", "AN", "AN", "AN", "AN", "ON", "ON", "AL", "ET", "ET", "AL", "CS", "AL", "ON", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "ET", "AN", "AN", "AL", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "NSM", "NSM", "ON", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "AL", "AL", "AL", "AL", "AL", "AL"]; function s(e) { return 0 != (1 & e) } function o(e) { return 0 == (1 & e) } function c(e, t, a) { for (var r = t, i = e.length; r < i; ++r)if (e[r] !== a) return r; return r } function l(e, t, a, r) { for (var i = t; i < a; ++i)e[i] = r } function h(e, t, a) { for (var r = t, i = a - 1; r < i; ++r, --i) { var n = e[r]; e[r] = e[i]; e[i] = n } } function u(e, t, a = !1) { let r = "ltr"; a ? r = "ttb" : t || (r = "rtl"); return { str: e, dir: r } } var d = [], f = [] }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.getMetrics = void 0; var r = a(7), i = (0, r.getLookupTableFactory)((function (e) { e.Courier = 600; e["Courier-Bold"] = 600; e["Courier-BoldOblique"] = 600; e["Courier-Oblique"] = 600; e.Helvetica = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.exclam = 278; e.quotedbl = 355; e.numbersign = 556; e.dollar = 556; e.percent = 889; e.ampersand = 667; e.quoteright = 222; e.parenleft = 333; e.parenright = 333; e.asterisk = 389; e.plus = 584; e.comma = 278; e.hyphen = 333; e.period = 278; e.slash = 278; e.zero = 556; e.one = 556; e.two = 556; e.three = 556; e.four = 556; e.five = 556; e.six = 556; e.seven = 556; e.eight = 556; e.nine = 556; e.colon = 278; e.semicolon = 278; e.less = 584; e.equal = 584; e.greater = 584; e.question = 556; e.at = 1015; e.A = 667; e.B = 667; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 722; e.I = 278; e.J = 500; e.K = 667; e.L = 556; e.M = 833; e.N = 722; e.O = 778; e.P = 667; e.Q = 778; e.R = 722; e.S = 667; e.T = 611; e.U = 722; e.V = 667; e.W = 944; e.X = 667; e.Y = 667; e.Z = 611; e.bracketleft = 278; e.backslash = 278; e.bracketright = 278; e.asciicircum = 469; e.underscore = 556; e.quoteleft = 222; e.a = 556; e.b = 556; e.c = 500; e.d = 556; e.e = 556; e.f = 278; e.g = 556; e.h = 556; e.i = 222; e.j = 222; e.k = 500; e.l = 222; e.m = 833; e.n = 556; e.o = 556; e.p = 556; e.q = 556; e.r = 333; e.s = 500; e.t = 278; e.u = 556; e.v = 500; e.w = 722; e.x = 500; e.y = 500; e.z = 500; e.braceleft = 334; e.bar = 260; e.braceright = 334; e.asciitilde = 584; e.exclamdown = 333; e.cent = 556; e.sterling = 556; e.fraction = 167; e.yen = 556; e.florin = 556; e.section = 556; e.currency = 556; e.quotesingle = 191; e.quotedblleft = 333; e.guillemotleft = 556; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 500; e.fl = 500; e.endash = 556; e.dagger = 556; e.daggerdbl = 556; e.periodcentered = 278; e.paragraph = 537; e.bullet = 350; e.quotesinglbase = 222; e.quotedblbase = 333; e.quotedblright = 333; e.guillemotright = 556; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 611; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 370; e.Lslash = 556; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 365; e.ae = 889; e.dotlessi = 278; e.lslash = 222; e.oslash = 611; e.oe = 944; e.germandbls = 611; e.Idieresis = 278; e.eacute = 556; e.abreve = 556; e.uhungarumlaut = 556; e.ecaron = 556; e.Ydieresis = 667; e.divide = 584; e.Yacute = 667; e.Acircumflex = 667; e.aacute = 556; e.Ucircumflex = 722; e.yacute = 500; e.scommaaccent = 500; e.ecircumflex = 556; e.Uring = 722; e.Udieresis = 722; e.aogonek = 556; e.Uacute = 722; e.uogonek = 556; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 737; e.Emacron = 667; e.ccaron = 500; e.aring = 556; e.Ncommaaccent = 722; e.lacute = 222; e.agrave = 556; e.Tcommaaccent = 611; e.Cacute = 722; e.atilde = 556; e.Edotaccent = 667; e.scaron = 500; e.scedilla = 500; e.iacute = 278; e.lozenge = 471; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 556; e.acircumflex = 556; e.Amacron = 667; e.rcaron = 333; e.ccedilla = 500; e.Zdotaccent = 611; e.Thorn = 667; e.Omacron = 778; e.Racute = 722; e.Sacute = 667; e.dcaron = 643; e.Umacron = 722; e.uring = 556; e.threesuperior = 333; e.Ograve = 778; e.Agrave = 667; e.Abreve = 667; e.multiply = 584; e.uacute = 556; e.Tcaron = 611; e.partialdiff = 476; e.ydieresis = 500; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 556; e.edieresis = 556; e.cacute = 500; e.nacute = 556; e.umacron = 556; e.Ncaron = 722; e.Iacute = 278; e.plusminus = 584; e.brokenbar = 260; e.registered = 737; e.Gbreve = 778; e.Idotaccent = 278; e.summation = 600; e.Egrave = 667; e.racute = 333; e.omacron = 556; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 222; e.tcaron = 317; e.eogonek = 556; e.Uogonek = 722; e.Aacute = 667; e.Adieresis = 667; e.egrave = 556; e.zacute = 500; e.iogonek = 222; e.Oacute = 778; e.oacute = 556; e.amacron = 556; e.sacute = 500; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 556; e.twosuperior = 333; e.Odieresis = 778; e.mu = 556; e.igrave = 278; e.ohungarumlaut = 556; e.Eogonek = 667; e.dcroat = 556; e.threequarters = 834; e.Scedilla = 667; e.lcaron = 299; e.Kcommaaccent = 667; e.Lacute = 556; e.trademark = 1e3; e.edotaccent = 556; e.Igrave = 278; e.Imacron = 278; e.Lcaron = 556; e.onehalf = 834; e.lessequal = 549; e.ocircumflex = 556; e.ntilde = 556; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 556; e.gbreve = 556; e.onequarter = 834; e.Scaron = 667; e.Scommaaccent = 667; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 556; e.Ccaron = 722; e.ugrave = 556; e.radical = 453; e.Dcaron = 722; e.rcommaaccent = 333; e.Ntilde = 722; e.otilde = 556; e.Rcommaaccent = 722; e.Lcommaaccent = 556; e.Atilde = 667; e.Aogonek = 667; e.Aring = 667; e.Otilde = 778; e.zdotaccent = 500; e.Ecaron = 667; e.Iogonek = 278; e.kcommaaccent = 500; e.minus = 584; e.Icircumflex = 278; e.ncaron = 556; e.tcommaaccent = 278; e.logicalnot = 584; e.odieresis = 556; e.udieresis = 556; e.notequal = 549; e.gcommaaccent = 556; e.eth = 556; e.zcaron = 500; e.ncommaaccent = 556; e.onesuperior = 333; e.imacron = 278; e.Euro = 556 })); e["Helvetica-Bold"] = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.exclam = 333; e.quotedbl = 474; e.numbersign = 556; e.dollar = 556; e.percent = 889; e.ampersand = 722; e.quoteright = 278; e.parenleft = 333; e.parenright = 333; e.asterisk = 389; e.plus = 584; e.comma = 278; e.hyphen = 333; e.period = 278; e.slash = 278; e.zero = 556; e.one = 556; e.two = 556; e.three = 556; e.four = 556; e.five = 556; e.six = 556; e.seven = 556; e.eight = 556; e.nine = 556; e.colon = 333; e.semicolon = 333; e.less = 584; e.equal = 584; e.greater = 584; e.question = 611; e.at = 975; e.A = 722; e.B = 722; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 722; e.I = 278; e.J = 556; e.K = 722; e.L = 611; e.M = 833; e.N = 722; e.O = 778; e.P = 667; e.Q = 778; e.R = 722; e.S = 667; e.T = 611; e.U = 722; e.V = 667; e.W = 944; e.X = 667; e.Y = 667; e.Z = 611; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 584; e.underscore = 556; e.quoteleft = 278; e.a = 556; e.b = 611; e.c = 556; e.d = 611; e.e = 556; e.f = 333; e.g = 611; e.h = 611; e.i = 278; e.j = 278; e.k = 556; e.l = 278; e.m = 889; e.n = 611; e.o = 611; e.p = 611; e.q = 611; e.r = 389; e.s = 556; e.t = 333; e.u = 611; e.v = 556; e.w = 778; e.x = 556; e.y = 556; e.z = 500; e.braceleft = 389; e.bar = 280; e.braceright = 389; e.asciitilde = 584; e.exclamdown = 333; e.cent = 556; e.sterling = 556; e.fraction = 167; e.yen = 556; e.florin = 556; e.section = 556; e.currency = 556; e.quotesingle = 238; e.quotedblleft = 500; e.guillemotleft = 556; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 611; e.fl = 611; e.endash = 556; e.dagger = 556; e.daggerdbl = 556; e.periodcentered = 278; e.paragraph = 556; e.bullet = 350; e.quotesinglbase = 278; e.quotedblbase = 500; e.quotedblright = 500; e.guillemotright = 556; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 611; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 370; e.Lslash = 611; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 365; e.ae = 889; e.dotlessi = 278; e.lslash = 278; e.oslash = 611; e.oe = 944; e.germandbls = 611; e.Idieresis = 278; e.eacute = 556; e.abreve = 556; e.uhungarumlaut = 611; e.ecaron = 556; e.Ydieresis = 667; e.divide = 584; e.Yacute = 667; e.Acircumflex = 722; e.aacute = 556; e.Ucircumflex = 722; e.yacute = 556; e.scommaaccent = 556; e.ecircumflex = 556; e.Uring = 722; e.Udieresis = 722; e.aogonek = 556; e.Uacute = 722; e.uogonek = 611; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 737; e.Emacron = 667; e.ccaron = 556; e.aring = 556; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 556; e.Tcommaaccent = 611; e.Cacute = 722; e.atilde = 556; e.Edotaccent = 667; e.scaron = 556; e.scedilla = 556; e.iacute = 278; e.lozenge = 494; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 611; e.acircumflex = 556; e.Amacron = 722; e.rcaron = 389; e.ccedilla = 556; e.Zdotaccent = 611; e.Thorn = 667; e.Omacron = 778; e.Racute = 722; e.Sacute = 667; e.dcaron = 743; e.Umacron = 722; e.uring = 611; e.threesuperior = 333; e.Ograve = 778; e.Agrave = 722; e.Abreve = 722; e.multiply = 584; e.uacute = 611; e.Tcaron = 611; e.partialdiff = 494; e.ydieresis = 556; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 556; e.edieresis = 556; e.cacute = 556; e.nacute = 611; e.umacron = 611; e.Ncaron = 722; e.Iacute = 278; e.plusminus = 584; e.brokenbar = 280; e.registered = 737; e.Gbreve = 778; e.Idotaccent = 278; e.summation = 600; e.Egrave = 667; e.racute = 389; e.omacron = 611; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 278; e.tcaron = 389; e.eogonek = 556; e.Uogonek = 722; e.Aacute = 722; e.Adieresis = 722; e.egrave = 556; e.zacute = 500; e.iogonek = 278; e.Oacute = 778; e.oacute = 611; e.amacron = 556; e.sacute = 556; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 611; e.twosuperior = 333; e.Odieresis = 778; e.mu = 611; e.igrave = 278; e.ohungarumlaut = 611; e.Eogonek = 667; e.dcroat = 611; e.threequarters = 834; e.Scedilla = 667; e.lcaron = 400; e.Kcommaaccent = 722; e.Lacute = 611; e.trademark = 1e3; e.edotaccent = 556; e.Igrave = 278; e.Imacron = 278; e.Lcaron = 611; e.onehalf = 834; e.lessequal = 549; e.ocircumflex = 611; e.ntilde = 611; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 556; e.gbreve = 611; e.onequarter = 834; e.Scaron = 667; e.Scommaaccent = 667; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 611; e.Ccaron = 722; e.ugrave = 611; e.radical = 549; e.Dcaron = 722; e.rcommaaccent = 389; e.Ntilde = 722; e.otilde = 611; e.Rcommaaccent = 722; e.Lcommaaccent = 611; e.Atilde = 722; e.Aogonek = 722; e.Aring = 722; e.Otilde = 778; e.zdotaccent = 500; e.Ecaron = 667; e.Iogonek = 278; e.kcommaaccent = 556; e.minus = 584; e.Icircumflex = 278; e.ncaron = 611; e.tcommaaccent = 333; e.logicalnot = 584; e.odieresis = 611; e.udieresis = 611; e.notequal = 549; e.gcommaaccent = 611; e.eth = 611; e.zcaron = 500; e.ncommaaccent = 611; e.onesuperior = 333; e.imacron = 278; e.Euro = 556 })); e["Helvetica-BoldOblique"] = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.exclam = 333; e.quotedbl = 474; e.numbersign = 556; e.dollar = 556; e.percent = 889; e.ampersand = 722; e.quoteright = 278; e.parenleft = 333; e.parenright = 333; e.asterisk = 389; e.plus = 584; e.comma = 278; e.hyphen = 333; e.period = 278; e.slash = 278; e.zero = 556; e.one = 556; e.two = 556; e.three = 556; e.four = 556; e.five = 556; e.six = 556; e.seven = 556; e.eight = 556; e.nine = 556; e.colon = 333; e.semicolon = 333; e.less = 584; e.equal = 584; e.greater = 584; e.question = 611; e.at = 975; e.A = 722; e.B = 722; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 722; e.I = 278; e.J = 556; e.K = 722; e.L = 611; e.M = 833; e.N = 722; e.O = 778; e.P = 667; e.Q = 778; e.R = 722; e.S = 667; e.T = 611; e.U = 722; e.V = 667; e.W = 944; e.X = 667; e.Y = 667; e.Z = 611; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 584; e.underscore = 556; e.quoteleft = 278; e.a = 556; e.b = 611; e.c = 556; e.d = 611; e.e = 556; e.f = 333; e.g = 611; e.h = 611; e.i = 278; e.j = 278; e.k = 556; e.l = 278; e.m = 889; e.n = 611; e.o = 611; e.p = 611; e.q = 611; e.r = 389; e.s = 556; e.t = 333; e.u = 611; e.v = 556; e.w = 778; e.x = 556; e.y = 556; e.z = 500; e.braceleft = 389; e.bar = 280; e.braceright = 389; e.asciitilde = 584; e.exclamdown = 333; e.cent = 556; e.sterling = 556; e.fraction = 167; e.yen = 556; e.florin = 556; e.section = 556; e.currency = 556; e.quotesingle = 238; e.quotedblleft = 500; e.guillemotleft = 556; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 611; e.fl = 611; e.endash = 556; e.dagger = 556; e.daggerdbl = 556; e.periodcentered = 278; e.paragraph = 556; e.bullet = 350; e.quotesinglbase = 278; e.quotedblbase = 500; e.quotedblright = 500; e.guillemotright = 556; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 611; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 370; e.Lslash = 611; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 365; e.ae = 889; e.dotlessi = 278; e.lslash = 278; e.oslash = 611; e.oe = 944; e.germandbls = 611; e.Idieresis = 278; e.eacute = 556; e.abreve = 556; e.uhungarumlaut = 611; e.ecaron = 556; e.Ydieresis = 667; e.divide = 584; e.Yacute = 667; e.Acircumflex = 722; e.aacute = 556; e.Ucircumflex = 722; e.yacute = 556; e.scommaaccent = 556; e.ecircumflex = 556; e.Uring = 722; e.Udieresis = 722; e.aogonek = 556; e.Uacute = 722; e.uogonek = 611; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 737; e.Emacron = 667; e.ccaron = 556; e.aring = 556; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 556; e.Tcommaaccent = 611; e.Cacute = 722; e.atilde = 556; e.Edotaccent = 667; e.scaron = 556; e.scedilla = 556; e.iacute = 278; e.lozenge = 494; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 611; e.acircumflex = 556; e.Amacron = 722; e.rcaron = 389; e.ccedilla = 556; e.Zdotaccent = 611; e.Thorn = 667; e.Omacron = 778; e.Racute = 722; e.Sacute = 667; e.dcaron = 743; e.Umacron = 722; e.uring = 611; e.threesuperior = 333; e.Ograve = 778; e.Agrave = 722; e.Abreve = 722; e.multiply = 584; e.uacute = 611; e.Tcaron = 611; e.partialdiff = 494; e.ydieresis = 556; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 556; e.edieresis = 556; e.cacute = 556; e.nacute = 611; e.umacron = 611; e.Ncaron = 722; e.Iacute = 278; e.plusminus = 584; e.brokenbar = 280; e.registered = 737; e.Gbreve = 778; e.Idotaccent = 278; e.summation = 600; e.Egrave = 667; e.racute = 389; e.omacron = 611; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 278; e.tcaron = 389; e.eogonek = 556; e.Uogonek = 722; e.Aacute = 722; e.Adieresis = 722; e.egrave = 556; e.zacute = 500; e.iogonek = 278; e.Oacute = 778; e.oacute = 611; e.amacron = 556; e.sacute = 556; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 611; e.twosuperior = 333; e.Odieresis = 778; e.mu = 611; e.igrave = 278; e.ohungarumlaut = 611; e.Eogonek = 667; e.dcroat = 611; e.threequarters = 834; e.Scedilla = 667; e.lcaron = 400; e.Kcommaaccent = 722; e.Lacute = 611; e.trademark = 1e3; e.edotaccent = 556; e.Igrave = 278; e.Imacron = 278; e.Lcaron = 611; e.onehalf = 834; e.lessequal = 549; e.ocircumflex = 611; e.ntilde = 611; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 556; e.gbreve = 611; e.onequarter = 834; e.Scaron = 667; e.Scommaaccent = 667; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 611; e.Ccaron = 722; e.ugrave = 611; e.radical = 549; e.Dcaron = 722; e.rcommaaccent = 389; e.Ntilde = 722; e.otilde = 611; e.Rcommaaccent = 722; e.Lcommaaccent = 611; e.Atilde = 722; e.Aogonek = 722; e.Aring = 722; e.Otilde = 778; e.zdotaccent = 500; e.Ecaron = 667; e.Iogonek = 278; e.kcommaaccent = 556; e.minus = 584; e.Icircumflex = 278; e.ncaron = 611; e.tcommaaccent = 333; e.logicalnot = 584; e.odieresis = 611; e.udieresis = 611; e.notequal = 549; e.gcommaaccent = 611; e.eth = 611; e.zcaron = 500; e.ncommaaccent = 611; e.onesuperior = 333; e.imacron = 278; e.Euro = 556 })); e["Helvetica-Oblique"] = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.exclam = 278; e.quotedbl = 355; e.numbersign = 556; e.dollar = 556; e.percent = 889; e.ampersand = 667; e.quoteright = 222; e.parenleft = 333; e.parenright = 333; e.asterisk = 389; e.plus = 584; e.comma = 278; e.hyphen = 333; e.period = 278; e.slash = 278; e.zero = 556; e.one = 556; e.two = 556; e.three = 556; e.four = 556; e.five = 556; e.six = 556; e.seven = 556; e.eight = 556; e.nine = 556; e.colon = 278; e.semicolon = 278; e.less = 584; e.equal = 584; e.greater = 584; e.question = 556; e.at = 1015; e.A = 667; e.B = 667; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 722; e.I = 278; e.J = 500; e.K = 667; e.L = 556; e.M = 833; e.N = 722; e.O = 778; e.P = 667; e.Q = 778; e.R = 722; e.S = 667; e.T = 611; e.U = 722; e.V = 667; e.W = 944; e.X = 667; e.Y = 667; e.Z = 611; e.bracketleft = 278; e.backslash = 278; e.bracketright = 278; e.asciicircum = 469; e.underscore = 556; e.quoteleft = 222; e.a = 556; e.b = 556; e.c = 500; e.d = 556; e.e = 556; e.f = 278; e.g = 556; e.h = 556; e.i = 222; e.j = 222; e.k = 500; e.l = 222; e.m = 833; e.n = 556; e.o = 556; e.p = 556; e.q = 556; e.r = 333; e.s = 500; e.t = 278; e.u = 556; e.v = 500; e.w = 722; e.x = 500; e.y = 500; e.z = 500; e.braceleft = 334; e.bar = 260; e.braceright = 334; e.asciitilde = 584; e.exclamdown = 333; e.cent = 556; e.sterling = 556; e.fraction = 167; e.yen = 556; e.florin = 556; e.section = 556; e.currency = 556; e.quotesingle = 191; e.quotedblleft = 333; e.guillemotleft = 556; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 500; e.fl = 500; e.endash = 556; e.dagger = 556; e.daggerdbl = 556; e.periodcentered = 278; e.paragraph = 537; e.bullet = 350; e.quotesinglbase = 222; e.quotedblbase = 333; e.quotedblright = 333; e.guillemotright = 556; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 611; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 370; e.Lslash = 556; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 365; e.ae = 889; e.dotlessi = 278; e.lslash = 222; e.oslash = 611; e.oe = 944; e.germandbls = 611; e.Idieresis = 278; e.eacute = 556; e.abreve = 556; e.uhungarumlaut = 556; e.ecaron = 556; e.Ydieresis = 667; e.divide = 584; e.Yacute = 667; e.Acircumflex = 667; e.aacute = 556; e.Ucircumflex = 722; e.yacute = 500; e.scommaaccent = 500; e.ecircumflex = 556; e.Uring = 722; e.Udieresis = 722; e.aogonek = 556; e.Uacute = 722; e.uogonek = 556; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 737; e.Emacron = 667; e.ccaron = 500; e.aring = 556; e.Ncommaaccent = 722; e.lacute = 222; e.agrave = 556; e.Tcommaaccent = 611; e.Cacute = 722; e.atilde = 556; e.Edotaccent = 667; e.scaron = 500; e.scedilla = 500; e.iacute = 278; e.lozenge = 471; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 556; e.acircumflex = 556; e.Amacron = 667; e.rcaron = 333; e.ccedilla = 500; e.Zdotaccent = 611; e.Thorn = 667; e.Omacron = 778; e.Racute = 722; e.Sacute = 667; e.dcaron = 643; e.Umacron = 722; e.uring = 556; e.threesuperior = 333; e.Ograve = 778; e.Agrave = 667; e.Abreve = 667; e.multiply = 584; e.uacute = 556; e.Tcaron = 611; e.partialdiff = 476; e.ydieresis = 500; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 556; e.edieresis = 556; e.cacute = 500; e.nacute = 556; e.umacron = 556; e.Ncaron = 722; e.Iacute = 278; e.plusminus = 584; e.brokenbar = 260; e.registered = 737; e.Gbreve = 778; e.Idotaccent = 278; e.summation = 600; e.Egrave = 667; e.racute = 333; e.omacron = 556; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 222; e.tcaron = 317; e.eogonek = 556; e.Uogonek = 722; e.Aacute = 667; e.Adieresis = 667; e.egrave = 556; e.zacute = 500; e.iogonek = 222; e.Oacute = 778; e.oacute = 556; e.amacron = 556; e.sacute = 500; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 556; e.twosuperior = 333; e.Odieresis = 778; e.mu = 556; e.igrave = 278; e.ohungarumlaut = 556; e.Eogonek = 667; e.dcroat = 556; e.threequarters = 834; e.Scedilla = 667; e.lcaron = 299; e.Kcommaaccent = 667; e.Lacute = 556; e.trademark = 1e3; e.edotaccent = 556; e.Igrave = 278; e.Imacron = 278; e.Lcaron = 556; e.onehalf = 834; e.lessequal = 549; e.ocircumflex = 556; e.ntilde = 556; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 556; e.gbreve = 556; e.onequarter = 834; e.Scaron = 667; e.Scommaaccent = 667; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 556; e.Ccaron = 722; e.ugrave = 556; e.radical = 453; e.Dcaron = 722; e.rcommaaccent = 333; e.Ntilde = 722; e.otilde = 556; e.Rcommaaccent = 722; e.Lcommaaccent = 556; e.Atilde = 667; e.Aogonek = 667; e.Aring = 667; e.Otilde = 778; e.zdotaccent = 500; e.Ecaron = 667; e.Iogonek = 278; e.kcommaaccent = 500; e.minus = 584; e.Icircumflex = 278; e.ncaron = 556; e.tcommaaccent = 278; e.logicalnot = 584; e.odieresis = 556; e.udieresis = 556; e.notequal = 549; e.gcommaaccent = 556; e.eth = 556; e.zcaron = 500; e.ncommaaccent = 556; e.onesuperior = 333; e.imacron = 278; e.Euro = 556 })); e.Symbol = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 333; e.universal = 713; e.numbersign = 500; e.existential = 549; e.percent = 833; e.ampersand = 778; e.suchthat = 439; e.parenleft = 333; e.parenright = 333; e.asteriskmath = 500; e.plus = 549; e.comma = 250; e.minus = 549; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 278; e.semicolon = 278; e.less = 549; e.equal = 549; e.greater = 549; e.question = 444; e.congruent = 549; e.Alpha = 722; e.Beta = 667; e.Chi = 722; e.Delta = 612; e.Epsilon = 611; e.Phi = 763; e.Gamma = 603; e.Eta = 722; e.Iota = 333; e.theta1 = 631; e.Kappa = 722; e.Lambda = 686; e.Mu = 889; e.Nu = 722; e.Omicron = 722; e.Pi = 768; e.Theta = 741; e.Rho = 556; e.Sigma = 592; e.Tau = 611; e.Upsilon = 690; e.sigma1 = 439; e.Omega = 768; e.Xi = 645; e.Psi = 795; e.Zeta = 611; e.bracketleft = 333; e.therefore = 863; e.bracketright = 333; e.perpendicular = 658; e.underscore = 500; e.radicalex = 500; e.alpha = 631; e.beta = 549; e.chi = 549; e.delta = 494; e.epsilon = 439; e.phi = 521; e.gamma = 411; e.eta = 603; e.iota = 329; e.phi1 = 603; e.kappa = 549; e.lambda = 549; e.mu = 576; e.nu = 521; e.omicron = 549; e.pi = 549; e.theta = 521; e.rho = 549; e.sigma = 603; e.tau = 439; e.upsilon = 576; e.omega1 = 713; e.omega = 686; e.xi = 493; e.psi = 686; e.zeta = 494; e.braceleft = 480; e.bar = 200; e.braceright = 480; e.similar = 549; e.Euro = 750; e.Upsilon1 = 620; e.minute = 247; e.lessequal = 549; e.fraction = 167; e.infinity = 713; e.florin = 500; e.club = 753; e.diamond = 753; e.heart = 753; e.spade = 753; e.arrowboth = 1042; e.arrowleft = 987; e.arrowup = 603; e.arrowright = 987; e.arrowdown = 603; e.degree = 400; e.plusminus = 549; e.second = 411; e.greaterequal = 549; e.multiply = 549; e.proportional = 713; e.partialdiff = 494; e.bullet = 460; e.divide = 549; e.notequal = 549; e.equivalence = 549; e.approxequal = 549; e.ellipsis = 1e3; e.arrowvertex = 603; e.arrowhorizex = 1e3; e.carriagereturn = 658; e.aleph = 823; e.Ifraktur = 686; e.Rfraktur = 795; e.weierstrass = 987; e.circlemultiply = 768; e.circleplus = 768; e.emptyset = 823; e.intersection = 768; e.union = 768; e.propersuperset = 713; e.reflexsuperset = 713; e.notsubset = 713; e.propersubset = 713; e.reflexsubset = 713; e.element = 713; e.notelement = 713; e.angle = 768; e.gradient = 713; e.registerserif = 790; e.copyrightserif = 790; e.trademarkserif = 890; e.product = 823; e.radical = 549; e.dotmath = 250; e.logicalnot = 713; e.logicaland = 603; e.logicalor = 603; e.arrowdblboth = 1042; e.arrowdblleft = 987; e.arrowdblup = 603; e.arrowdblright = 987; e.arrowdbldown = 603; e.lozenge = 494; e.angleleft = 329; e.registersans = 790; e.copyrightsans = 790; e.trademarksans = 786; e.summation = 713; e.parenlefttp = 384; e.parenleftex = 384; e.parenleftbt = 384; e.bracketlefttp = 384; e.bracketleftex = 384; e.bracketleftbt = 384; e.bracelefttp = 494; e.braceleftmid = 494; e.braceleftbt = 494; e.braceex = 494; e.angleright = 329; e.integral = 274; e.integraltp = 686; e.integralex = 686; e.integralbt = 686; e.parenrighttp = 384; e.parenrightex = 384; e.parenrightbt = 384; e.bracketrighttp = 384; e.bracketrightex = 384; e.bracketrightbt = 384; e.bracerighttp = 494; e.bracerightmid = 494; e.bracerightbt = 494; e.apple = 790 })); e["Times-Roman"] = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 333; e.quotedbl = 408; e.numbersign = 500; e.dollar = 500; e.percent = 833; e.ampersand = 778; e.quoteright = 333; e.parenleft = 333; e.parenright = 333; e.asterisk = 500; e.plus = 564; e.comma = 250; e.hyphen = 333; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 278; e.semicolon = 278; e.less = 564; e.equal = 564; e.greater = 564; e.question = 444; e.at = 921; e.A = 722; e.B = 667; e.C = 667; e.D = 722; e.E = 611; e.F = 556; e.G = 722; e.H = 722; e.I = 333; e.J = 389; e.K = 722; e.L = 611; e.M = 889; e.N = 722; e.O = 722; e.P = 556; e.Q = 722; e.R = 667; e.S = 556; e.T = 611; e.U = 722; e.V = 722; e.W = 944; e.X = 722; e.Y = 722; e.Z = 611; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 469; e.underscore = 500; e.quoteleft = 333; e.a = 444; e.b = 500; e.c = 444; e.d = 500; e.e = 444; e.f = 333; e.g = 500; e.h = 500; e.i = 278; e.j = 278; e.k = 500; e.l = 278; e.m = 778; e.n = 500; e.o = 500; e.p = 500; e.q = 500; e.r = 333; e.s = 389; e.t = 278; e.u = 500; e.v = 500; e.w = 722; e.x = 500; e.y = 500; e.z = 444; e.braceleft = 480; e.bar = 200; e.braceright = 480; e.asciitilde = 541; e.exclamdown = 333; e.cent = 500; e.sterling = 500; e.fraction = 167; e.yen = 500; e.florin = 500; e.section = 500; e.currency = 500; e.quotesingle = 180; e.quotedblleft = 444; e.guillemotleft = 500; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 556; e.fl = 556; e.endash = 500; e.dagger = 500; e.daggerdbl = 500; e.periodcentered = 250; e.paragraph = 453; e.bullet = 350; e.quotesinglbase = 333; e.quotedblbase = 444; e.quotedblright = 444; e.guillemotright = 500; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 444; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 889; e.ordfeminine = 276; e.Lslash = 611; e.Oslash = 722; e.OE = 889; e.ordmasculine = 310; e.ae = 667; e.dotlessi = 278; e.lslash = 278; e.oslash = 500; e.oe = 722; e.germandbls = 500; e.Idieresis = 333; e.eacute = 444; e.abreve = 444; e.uhungarumlaut = 500; e.ecaron = 444; e.Ydieresis = 722; e.divide = 564; e.Yacute = 722; e.Acircumflex = 722; e.aacute = 444; e.Ucircumflex = 722; e.yacute = 500; e.scommaaccent = 389; e.ecircumflex = 444; e.Uring = 722; e.Udieresis = 722; e.aogonek = 444; e.Uacute = 722; e.uogonek = 500; e.Edieresis = 611; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 760; e.Emacron = 611; e.ccaron = 444; e.aring = 444; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 444; e.Tcommaaccent = 611; e.Cacute = 667; e.atilde = 444; e.Edotaccent = 611; e.scaron = 389; e.scedilla = 389; e.iacute = 278; e.lozenge = 471; e.Rcaron = 667; e.Gcommaaccent = 722; e.ucircumflex = 500; e.acircumflex = 444; e.Amacron = 722; e.rcaron = 333; e.ccedilla = 444; e.Zdotaccent = 611; e.Thorn = 556; e.Omacron = 722; e.Racute = 667; e.Sacute = 556; e.dcaron = 588; e.Umacron = 722; e.uring = 500; e.threesuperior = 300; e.Ograve = 722; e.Agrave = 722; e.Abreve = 722; e.multiply = 564; e.uacute = 500; e.Tcaron = 611; e.partialdiff = 476; e.ydieresis = 500; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 611; e.adieresis = 444; e.edieresis = 444; e.cacute = 444; e.nacute = 500; e.umacron = 500; e.Ncaron = 722; e.Iacute = 333; e.plusminus = 564; e.brokenbar = 200; e.registered = 760; e.Gbreve = 722; e.Idotaccent = 333; e.summation = 600; e.Egrave = 611; e.racute = 333; e.omacron = 500; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 667; e.lcommaaccent = 278; e.tcaron = 326; e.eogonek = 444; e.Uogonek = 722; e.Aacute = 722; e.Adieresis = 722; e.egrave = 444; e.zacute = 444; e.iogonek = 278; e.Oacute = 722; e.oacute = 500; e.amacron = 444; e.sacute = 389; e.idieresis = 278; e.Ocircumflex = 722; e.Ugrave = 722; e.Delta = 612; e.thorn = 500; e.twosuperior = 300; e.Odieresis = 722; e.mu = 500; e.igrave = 278; e.ohungarumlaut = 500; e.Eogonek = 611; e.dcroat = 500; e.threequarters = 750; e.Scedilla = 556; e.lcaron = 344; e.Kcommaaccent = 722; e.Lacute = 611; e.trademark = 980; e.edotaccent = 444; e.Igrave = 333; e.Imacron = 333; e.Lcaron = 611; e.onehalf = 750; e.lessequal = 549; e.ocircumflex = 500; e.ntilde = 500; e.Uhungarumlaut = 722; e.Eacute = 611; e.emacron = 444; e.gbreve = 500; e.onequarter = 750; e.Scaron = 556; e.Scommaaccent = 556; e.Ohungarumlaut = 722; e.degree = 400; e.ograve = 500; e.Ccaron = 667; e.ugrave = 500; e.radical = 453; e.Dcaron = 722; e.rcommaaccent = 333; e.Ntilde = 722; e.otilde = 500; e.Rcommaaccent = 667; e.Lcommaaccent = 611; e.Atilde = 722; e.Aogonek = 722; e.Aring = 722; e.Otilde = 722; e.zdotaccent = 444; e.Ecaron = 611; e.Iogonek = 333; e.kcommaaccent = 500; e.minus = 564; e.Icircumflex = 333; e.ncaron = 500; e.tcommaaccent = 278; e.logicalnot = 564; e.odieresis = 500; e.udieresis = 500; e.notequal = 549; e.gcommaaccent = 500; e.eth = 500; e.zcaron = 444; e.ncommaaccent = 500; e.onesuperior = 300; e.imacron = 278; e.Euro = 500 })); e["Times-Bold"] = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 333; e.quotedbl = 555; e.numbersign = 500; e.dollar = 500; e.percent = 1e3; e.ampersand = 833; e.quoteright = 333; e.parenleft = 333; e.parenright = 333; e.asterisk = 500; e.plus = 570; e.comma = 250; e.hyphen = 333; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 333; e.semicolon = 333; e.less = 570; e.equal = 570; e.greater = 570; e.question = 500; e.at = 930; e.A = 722; e.B = 667; e.C = 722; e.D = 722; e.E = 667; e.F = 611; e.G = 778; e.H = 778; e.I = 389; e.J = 500; e.K = 778; e.L = 667; e.M = 944; e.N = 722; e.O = 778; e.P = 611; e.Q = 778; e.R = 722; e.S = 556; e.T = 667; e.U = 722; e.V = 722; e.W = 1e3; e.X = 722; e.Y = 722; e.Z = 667; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 581; e.underscore = 500; e.quoteleft = 333; e.a = 500; e.b = 556; e.c = 444; e.d = 556; e.e = 444; e.f = 333; e.g = 500; e.h = 556; e.i = 278; e.j = 333; e.k = 556; e.l = 278; e.m = 833; e.n = 556; e.o = 500; e.p = 556; e.q = 556; e.r = 444; e.s = 389; e.t = 333; e.u = 556; e.v = 500; e.w = 722; e.x = 500; e.y = 500; e.z = 444; e.braceleft = 394; e.bar = 220; e.braceright = 394; e.asciitilde = 520; e.exclamdown = 333; e.cent = 500; e.sterling = 500; e.fraction = 167; e.yen = 500; e.florin = 500; e.section = 500; e.currency = 500; e.quotesingle = 278; e.quotedblleft = 500; e.guillemotleft = 500; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 556; e.fl = 556; e.endash = 500; e.dagger = 500; e.daggerdbl = 500; e.periodcentered = 250; e.paragraph = 540; e.bullet = 350; e.quotesinglbase = 333; e.quotedblbase = 500; e.quotedblright = 500; e.guillemotright = 500; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 500; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 1e3; e.ordfeminine = 300; e.Lslash = 667; e.Oslash = 778; e.OE = 1e3; e.ordmasculine = 330; e.ae = 722; e.dotlessi = 278; e.lslash = 278; e.oslash = 500; e.oe = 722; e.germandbls = 556; e.Idieresis = 389; e.eacute = 444; e.abreve = 500; e.uhungarumlaut = 556; e.ecaron = 444; e.Ydieresis = 722; e.divide = 570; e.Yacute = 722; e.Acircumflex = 722; e.aacute = 500; e.Ucircumflex = 722; e.yacute = 500; e.scommaaccent = 389; e.ecircumflex = 444; e.Uring = 722; e.Udieresis = 722; e.aogonek = 500; e.Uacute = 722; e.uogonek = 556; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 747; e.Emacron = 667; e.ccaron = 444; e.aring = 500; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 500; e.Tcommaaccent = 667; e.Cacute = 722; e.atilde = 500; e.Edotaccent = 667; e.scaron = 389; e.scedilla = 389; e.iacute = 278; e.lozenge = 494; e.Rcaron = 722; e.Gcommaaccent = 778; e.ucircumflex = 556; e.acircumflex = 500; e.Amacron = 722; e.rcaron = 444; e.ccedilla = 444; e.Zdotaccent = 667; e.Thorn = 611; e.Omacron = 778; e.Racute = 722; e.Sacute = 556; e.dcaron = 672; e.Umacron = 722; e.uring = 556; e.threesuperior = 300; e.Ograve = 778; e.Agrave = 722; e.Abreve = 722; e.multiply = 570; e.uacute = 556; e.Tcaron = 667; e.partialdiff = 494; e.ydieresis = 500; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 500; e.edieresis = 444; e.cacute = 444; e.nacute = 556; e.umacron = 556; e.Ncaron = 722; e.Iacute = 389; e.plusminus = 570; e.brokenbar = 220; e.registered = 747; e.Gbreve = 778; e.Idotaccent = 389; e.summation = 600; e.Egrave = 667; e.racute = 444; e.omacron = 500; e.Zacute = 667; e.Zcaron = 667; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 722; e.lcommaaccent = 278; e.tcaron = 416; e.eogonek = 444; e.Uogonek = 722; e.Aacute = 722; e.Adieresis = 722; e.egrave = 444; e.zacute = 444; e.iogonek = 278; e.Oacute = 778; e.oacute = 500; e.amacron = 500; e.sacute = 389; e.idieresis = 278; e.Ocircumflex = 778; e.Ugrave = 722; e.Delta = 612; e.thorn = 556; e.twosuperior = 300; e.Odieresis = 778; e.mu = 556; e.igrave = 278; e.ohungarumlaut = 500; e.Eogonek = 667; e.dcroat = 556; e.threequarters = 750; e.Scedilla = 556; e.lcaron = 394; e.Kcommaaccent = 778; e.Lacute = 667; e.trademark = 1e3; e.edotaccent = 444; e.Igrave = 389; e.Imacron = 389; e.Lcaron = 667; e.onehalf = 750; e.lessequal = 549; e.ocircumflex = 500; e.ntilde = 556; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 444; e.gbreve = 500; e.onequarter = 750; e.Scaron = 556; e.Scommaaccent = 556; e.Ohungarumlaut = 778; e.degree = 400; e.ograve = 500; e.Ccaron = 722; e.ugrave = 556; e.radical = 549; e.Dcaron = 722; e.rcommaaccent = 444; e.Ntilde = 722; e.otilde = 500; e.Rcommaaccent = 722; e.Lcommaaccent = 667; e.Atilde = 722; e.Aogonek = 722; e.Aring = 722; e.Otilde = 778; e.zdotaccent = 444; e.Ecaron = 667; e.Iogonek = 389; e.kcommaaccent = 556; e.minus = 570; e.Icircumflex = 389; e.ncaron = 556; e.tcommaaccent = 333; e.logicalnot = 570; e.odieresis = 500; e.udieresis = 556; e.notequal = 549; e.gcommaaccent = 500; e.eth = 500; e.zcaron = 444; e.ncommaaccent = 556; e.onesuperior = 300; e.imacron = 278; e.Euro = 500 })); e["Times-BoldItalic"] = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 389; e.quotedbl = 555; e.numbersign = 500; e.dollar = 500; e.percent = 833; e.ampersand = 778; e.quoteright = 333; e.parenleft = 333; e.parenright = 333; e.asterisk = 500; e.plus = 570; e.comma = 250; e.hyphen = 333; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 333; e.semicolon = 333; e.less = 570; e.equal = 570; e.greater = 570; e.question = 500; e.at = 832; e.A = 667; e.B = 667; e.C = 667; e.D = 722; e.E = 667; e.F = 667; e.G = 722; e.H = 778; e.I = 389; e.J = 500; e.K = 667; e.L = 611; e.M = 889; e.N = 722; e.O = 722; e.P = 611; e.Q = 722; e.R = 667; e.S = 556; e.T = 611; e.U = 722; e.V = 667; e.W = 889; e.X = 667; e.Y = 611; e.Z = 611; e.bracketleft = 333; e.backslash = 278; e.bracketright = 333; e.asciicircum = 570; e.underscore = 500; e.quoteleft = 333; e.a = 500; e.b = 500; e.c = 444; e.d = 500; e.e = 444; e.f = 333; e.g = 500; e.h = 556; e.i = 278; e.j = 278; e.k = 500; e.l = 278; e.m = 778; e.n = 556; e.o = 500; e.p = 500; e.q = 500; e.r = 389; e.s = 389; e.t = 278; e.u = 556; e.v = 444; e.w = 667; e.x = 500; e.y = 444; e.z = 389; e.braceleft = 348; e.bar = 220; e.braceright = 348; e.asciitilde = 570; e.exclamdown = 389; e.cent = 500; e.sterling = 500; e.fraction = 167; e.yen = 500; e.florin = 500; e.section = 500; e.currency = 500; e.quotesingle = 278; e.quotedblleft = 500; e.guillemotleft = 500; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 556; e.fl = 556; e.endash = 500; e.dagger = 500; e.daggerdbl = 500; e.periodcentered = 250; e.paragraph = 500; e.bullet = 350; e.quotesinglbase = 333; e.quotedblbase = 500; e.quotedblright = 500; e.guillemotright = 500; e.ellipsis = 1e3; e.perthousand = 1e3; e.questiondown = 500; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 1e3; e.AE = 944; e.ordfeminine = 266; e.Lslash = 611; e.Oslash = 722; e.OE = 944; e.ordmasculine = 300; e.ae = 722; e.dotlessi = 278; e.lslash = 278; e.oslash = 500; e.oe = 722; e.germandbls = 500; e.Idieresis = 389; e.eacute = 444; e.abreve = 500; e.uhungarumlaut = 556; e.ecaron = 444; e.Ydieresis = 611; e.divide = 570; e.Yacute = 611; e.Acircumflex = 667; e.aacute = 500; e.Ucircumflex = 722; e.yacute = 444; e.scommaaccent = 389; e.ecircumflex = 444; e.Uring = 722; e.Udieresis = 722; e.aogonek = 500; e.Uacute = 722; e.uogonek = 556; e.Edieresis = 667; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 747; e.Emacron = 667; e.ccaron = 444; e.aring = 500; e.Ncommaaccent = 722; e.lacute = 278; e.agrave = 500; e.Tcommaaccent = 611; e.Cacute = 667; e.atilde = 500; e.Edotaccent = 667; e.scaron = 389; e.scedilla = 389; e.iacute = 278; e.lozenge = 494; e.Rcaron = 667; e.Gcommaaccent = 722; e.ucircumflex = 556; e.acircumflex = 500; e.Amacron = 667; e.rcaron = 389; e.ccedilla = 444; e.Zdotaccent = 611; e.Thorn = 611; e.Omacron = 722; e.Racute = 667; e.Sacute = 556; e.dcaron = 608; e.Umacron = 722; e.uring = 556; e.threesuperior = 300; e.Ograve = 722; e.Agrave = 667; e.Abreve = 667; e.multiply = 570; e.uacute = 556; e.Tcaron = 611; e.partialdiff = 494; e.ydieresis = 444; e.Nacute = 722; e.icircumflex = 278; e.Ecircumflex = 667; e.adieresis = 500; e.edieresis = 444; e.cacute = 444; e.nacute = 556; e.umacron = 556; e.Ncaron = 722; e.Iacute = 389; e.plusminus = 570; e.brokenbar = 220; e.registered = 747; e.Gbreve = 722; e.Idotaccent = 389; e.summation = 600; e.Egrave = 667; e.racute = 389; e.omacron = 500; e.Zacute = 611; e.Zcaron = 611; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 667; e.lcommaaccent = 278; e.tcaron = 366; e.eogonek = 444; e.Uogonek = 722; e.Aacute = 667; e.Adieresis = 667; e.egrave = 444; e.zacute = 389; e.iogonek = 278; e.Oacute = 722; e.oacute = 500; e.amacron = 500; e.sacute = 389; e.idieresis = 278; e.Ocircumflex = 722; e.Ugrave = 722; e.Delta = 612; e.thorn = 500; e.twosuperior = 300; e.Odieresis = 722; e.mu = 576; e.igrave = 278; e.ohungarumlaut = 500; e.Eogonek = 667; e.dcroat = 500; e.threequarters = 750; e.Scedilla = 556; e.lcaron = 382; e.Kcommaaccent = 667; e.Lacute = 611; e.trademark = 1e3; e.edotaccent = 444; e.Igrave = 389; e.Imacron = 389; e.Lcaron = 611; e.onehalf = 750; e.lessequal = 549; e.ocircumflex = 500; e.ntilde = 556; e.Uhungarumlaut = 722; e.Eacute = 667; e.emacron = 444; e.gbreve = 500; e.onequarter = 750; e.Scaron = 556; e.Scommaaccent = 556; e.Ohungarumlaut = 722; e.degree = 400; e.ograve = 500; e.Ccaron = 667; e.ugrave = 556; e.radical = 549; e.Dcaron = 722; e.rcommaaccent = 389; e.Ntilde = 722; e.otilde = 500; e.Rcommaaccent = 667; e.Lcommaaccent = 611; e.Atilde = 667; e.Aogonek = 667; e.Aring = 667; e.Otilde = 722; e.zdotaccent = 389; e.Ecaron = 667; e.Iogonek = 389; e.kcommaaccent = 500; e.minus = 606; e.Icircumflex = 389; e.ncaron = 556; e.tcommaaccent = 278; e.logicalnot = 606; e.odieresis = 500; e.udieresis = 556; e.notequal = 549; e.gcommaaccent = 500; e.eth = 500; e.zcaron = 389; e.ncommaaccent = 556; e.onesuperior = 300; e.imacron = 278; e.Euro = 500 })); e["Times-Italic"] = (0, r.getLookupTableFactory)((function (e) { e.space = 250; e.exclam = 333; e.quotedbl = 420; e.numbersign = 500; e.dollar = 500; e.percent = 833; e.ampersand = 778; e.quoteright = 333; e.parenleft = 333; e.parenright = 333; e.asterisk = 500; e.plus = 675; e.comma = 250; e.hyphen = 333; e.period = 250; e.slash = 278; e.zero = 500; e.one = 500; e.two = 500; e.three = 500; e.four = 500; e.five = 500; e.six = 500; e.seven = 500; e.eight = 500; e.nine = 500; e.colon = 333; e.semicolon = 333; e.less = 675; e.equal = 675; e.greater = 675; e.question = 500; e.at = 920; e.A = 611; e.B = 611; e.C = 667; e.D = 722; e.E = 611; e.F = 611; e.G = 722; e.H = 722; e.I = 333; e.J = 444; e.K = 667; e.L = 556; e.M = 833; e.N = 667; e.O = 722; e.P = 611; e.Q = 722; e.R = 611; e.S = 500; e.T = 556; e.U = 722; e.V = 611; e.W = 833; e.X = 611; e.Y = 556; e.Z = 556; e.bracketleft = 389; e.backslash = 278; e.bracketright = 389; e.asciicircum = 422; e.underscore = 500; e.quoteleft = 333; e.a = 500; e.b = 500; e.c = 444; e.d = 500; e.e = 444; e.f = 278; e.g = 500; e.h = 500; e.i = 278; e.j = 278; e.k = 444; e.l = 278; e.m = 722; e.n = 500; e.o = 500; e.p = 500; e.q = 500; e.r = 389; e.s = 389; e.t = 278; e.u = 500; e.v = 444; e.w = 667; e.x = 444; e.y = 444; e.z = 389; e.braceleft = 400; e.bar = 275; e.braceright = 400; e.asciitilde = 541; e.exclamdown = 389; e.cent = 500; e.sterling = 500; e.fraction = 167; e.yen = 500; e.florin = 500; e.section = 500; e.currency = 500; e.quotesingle = 214; e.quotedblleft = 556; e.guillemotleft = 500; e.guilsinglleft = 333; e.guilsinglright = 333; e.fi = 500; e.fl = 500; e.endash = 500; e.dagger = 500; e.daggerdbl = 500; e.periodcentered = 250; e.paragraph = 523; e.bullet = 350; e.quotesinglbase = 333; e.quotedblbase = 556; e.quotedblright = 556; e.guillemotright = 500; e.ellipsis = 889; e.perthousand = 1e3; e.questiondown = 500; e.grave = 333; e.acute = 333; e.circumflex = 333; e.tilde = 333; e.macron = 333; e.breve = 333; e.dotaccent = 333; e.dieresis = 333; e.ring = 333; e.cedilla = 333; e.hungarumlaut = 333; e.ogonek = 333; e.caron = 333; e.emdash = 889; e.AE = 889; e.ordfeminine = 276; e.Lslash = 556; e.Oslash = 722; e.OE = 944; e.ordmasculine = 310; e.ae = 667; e.dotlessi = 278; e.lslash = 278; e.oslash = 500; e.oe = 667; e.germandbls = 500; e.Idieresis = 333; e.eacute = 444; e.abreve = 500; e.uhungarumlaut = 500; e.ecaron = 444; e.Ydieresis = 556; e.divide = 675; e.Yacute = 556; e.Acircumflex = 611; e.aacute = 500; e.Ucircumflex = 722; e.yacute = 444; e.scommaaccent = 389; e.ecircumflex = 444; e.Uring = 722; e.Udieresis = 722; e.aogonek = 500; e.Uacute = 722; e.uogonek = 500; e.Edieresis = 611; e.Dcroat = 722; e.commaaccent = 250; e.copyright = 760; e.Emacron = 611; e.ccaron = 444; e.aring = 500; e.Ncommaaccent = 667; e.lacute = 278; e.agrave = 500; e.Tcommaaccent = 556; e.Cacute = 667; e.atilde = 500; e.Edotaccent = 611; e.scaron = 389; e.scedilla = 389; e.iacute = 278; e.lozenge = 471; e.Rcaron = 611; e.Gcommaaccent = 722; e.ucircumflex = 500; e.acircumflex = 500; e.Amacron = 611; e.rcaron = 389; e.ccedilla = 444; e.Zdotaccent = 556; e.Thorn = 611; e.Omacron = 722; e.Racute = 611; e.Sacute = 500; e.dcaron = 544; e.Umacron = 722; e.uring = 500; e.threesuperior = 300; e.Ograve = 722; e.Agrave = 611; e.Abreve = 611; e.multiply = 675; e.uacute = 500; e.Tcaron = 556; e.partialdiff = 476; e.ydieresis = 444; e.Nacute = 667; e.icircumflex = 278; e.Ecircumflex = 611; e.adieresis = 500; e.edieresis = 444; e.cacute = 444; e.nacute = 500; e.umacron = 500; e.Ncaron = 667; e.Iacute = 333; e.plusminus = 675; e.brokenbar = 275; e.registered = 760; e.Gbreve = 722; e.Idotaccent = 333; e.summation = 600; e.Egrave = 611; e.racute = 389; e.omacron = 500; e.Zacute = 556; e.Zcaron = 556; e.greaterequal = 549; e.Eth = 722; e.Ccedilla = 667; e.lcommaaccent = 278; e.tcaron = 300; e.eogonek = 444; e.Uogonek = 722; e.Aacute = 611; e.Adieresis = 611; e.egrave = 444; e.zacute = 389; e.iogonek = 278; e.Oacute = 722; e.oacute = 500; e.amacron = 500; e.sacute = 389; e.idieresis = 278; e.Ocircumflex = 722; e.Ugrave = 722; e.Delta = 612; e.thorn = 500; e.twosuperior = 300; e.Odieresis = 722; e.mu = 500; e.igrave = 278; e.ohungarumlaut = 500; e.Eogonek = 611; e.dcroat = 500; e.threequarters = 750; e.Scedilla = 500; e.lcaron = 300; e.Kcommaaccent = 667; e.Lacute = 556; e.trademark = 980; e.edotaccent = 444; e.Igrave = 333; e.Imacron = 333; e.Lcaron = 611; e.onehalf = 750; e.lessequal = 549; e.ocircumflex = 500; e.ntilde = 500; e.Uhungarumlaut = 722; e.Eacute = 611; e.emacron = 444; e.gbreve = 500; e.onequarter = 750; e.Scaron = 500; e.Scommaaccent = 500; e.Ohungarumlaut = 722; e.degree = 400; e.ograve = 500; e.Ccaron = 667; e.ugrave = 500; e.radical = 453; e.Dcaron = 722; e.rcommaaccent = 389; e.Ntilde = 667; e.otilde = 500; e.Rcommaaccent = 611; e.Lcommaaccent = 556; e.Atilde = 611; e.Aogonek = 611; e.Aring = 611; e.Otilde = 722; e.zdotaccent = 389; e.Ecaron = 611; e.Iogonek = 333; e.kcommaaccent = 444; e.minus = 675; e.Icircumflex = 333; e.ncaron = 500; e.tcommaaccent = 278; e.logicalnot = 675; e.odieresis = 500; e.udieresis = 500; e.notequal = 549; e.gcommaaccent = 500; e.eth = 500; e.zcaron = 389; e.ncommaaccent = 500; e.onesuperior = 300; e.imacron = 278; e.Euro = 500 })); e.ZapfDingbats = (0, r.getLookupTableFactory)((function (e) { e.space = 278; e.a1 = 974; e.a2 = 961; e.a202 = 974; e.a3 = 980; e.a4 = 719; e.a5 = 789; e.a119 = 790; e.a118 = 791; e.a117 = 690; e.a11 = 960; e.a12 = 939; e.a13 = 549; e.a14 = 855; e.a15 = 911; e.a16 = 933; e.a105 = 911; e.a17 = 945; e.a18 = 974; e.a19 = 755; e.a20 = 846; e.a21 = 762; e.a22 = 761; e.a23 = 571; e.a24 = 677; e.a25 = 763; e.a26 = 760; e.a27 = 759; e.a28 = 754; e.a6 = 494; e.a7 = 552; e.a8 = 537; e.a9 = 577; e.a10 = 692; e.a29 = 786; e.a30 = 788; e.a31 = 788; e.a32 = 790; e.a33 = 793; e.a34 = 794; e.a35 = 816; e.a36 = 823; e.a37 = 789; e.a38 = 841; e.a39 = 823; e.a40 = 833; e.a41 = 816; e.a42 = 831; e.a43 = 923; e.a44 = 744; e.a45 = 723; e.a46 = 749; e.a47 = 790; e.a48 = 792; e.a49 = 695; e.a50 = 776; e.a51 = 768; e.a52 = 792; e.a53 = 759; e.a54 = 707; e.a55 = 708; e.a56 = 682; e.a57 = 701; e.a58 = 826; e.a59 = 815; e.a60 = 789; e.a61 = 789; e.a62 = 707; e.a63 = 687; e.a64 = 696; e.a65 = 689; e.a66 = 786; e.a67 = 787; e.a68 = 713; e.a69 = 791; e.a70 = 785; e.a71 = 791; e.a72 = 873; e.a73 = 761; e.a74 = 762; e.a203 = 762; e.a75 = 759; e.a204 = 759; e.a76 = 892; e.a77 = 892; e.a78 = 788; e.a79 = 784; e.a81 = 438; e.a82 = 138; e.a83 = 277; e.a84 = 415; e.a97 = 392; e.a98 = 392; e.a99 = 668; e.a100 = 668; e.a89 = 390; e.a90 = 390; e.a93 = 317; e.a94 = 317; e.a91 = 276; e.a92 = 276; e.a205 = 509; e.a85 = 509; e.a206 = 410; e.a86 = 410; e.a87 = 234; e.a88 = 234; e.a95 = 334; e.a96 = 334; e.a101 = 732; e.a102 = 544; e.a103 = 544; e.a104 = 910; e.a106 = 667; e.a107 = 760; e.a108 = 760; e.a112 = 776; e.a111 = 595; e.a110 = 694; e.a109 = 626; e.a120 = 788; e.a121 = 788; e.a122 = 788; e.a123 = 788; e.a124 = 788; e.a125 = 788; e.a126 = 788; e.a127 = 788; e.a128 = 788; e.a129 = 788; e.a130 = 788; e.a131 = 788; e.a132 = 788; e.a133 = 788; e.a134 = 788; e.a135 = 788; e.a136 = 788; e.a137 = 788; e.a138 = 788; e.a139 = 788; e.a140 = 788; e.a141 = 788; e.a142 = 788; e.a143 = 788; e.a144 = 788; e.a145 = 788; e.a146 = 788; e.a147 = 788; e.a148 = 788; e.a149 = 788; e.a150 = 788; e.a151 = 788; e.a152 = 788; e.a153 = 788; e.a154 = 788; e.a155 = 788; e.a156 = 788; e.a157 = 788; e.a158 = 788; e.a159 = 788; e.a160 = 894; e.a161 = 838; e.a163 = 1016; e.a164 = 458; e.a196 = 748; e.a165 = 924; e.a192 = 748; e.a166 = 918; e.a167 = 927; e.a168 = 928; e.a169 = 928; e.a170 = 834; e.a171 = 873; e.a172 = 828; e.a173 = 924; e.a162 = 924; e.a174 = 917; e.a175 = 930; e.a176 = 931; e.a177 = 463; e.a178 = 883; e.a179 = 836; e.a193 = 836; e.a180 = 867; e.a199 = 867; e.a181 = 696; e.a200 = 696; e.a182 = 874; e.a201 = 874; e.a183 = 760; e.a184 = 946; e.a197 = 771; e.a185 = 865; e.a194 = 771; e.a198 = 888; e.a186 = 967; e.a195 = 888; e.a187 = 831; e.a188 = 873; e.a189 = 927; e.a190 = 970; e.a191 = 918 })) })); t.getMetrics = i }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.isPDFFunction = function (e) { var t; if ("object" != typeof e) return !1; if ((0, i.isDict)(e)) t = e; else { if (!(0, i.isStream)(e)) return !1; t = e.dict } return t.has("FunctionType") }; t.PostScriptCompiler = t.PostScriptEvaluator = t.PDFFunctionFactory = void 0; var r = a(2), i = a(4), n = a(40); t.PDFFunctionFactory = class { constructor({ xref: e, isEvalSupported: t = !0 }) { this.xref = e; this.isEvalSupported = !1 !== t } create(e) { return o.parse({ xref: this.xref, isEvalSupported: this.isEvalSupported, fn: e }) } createFromArray(e) { return o.parseArray({ xref: this.xref, isEvalSupported: this.isEvalSupported, fnObj: e }) } }; function s(e) { if (!Array.isArray(e)) return null; const t = e.length; for (let a = 0; a < t; a++)if ("number" != typeof e[a]) { const a = new Array(t); for (let r = 0; r < t; r++)a[r] = +e[r]; return a } return e } var o = { getSampleArray(e, t, a, r) { var i, n, s = 1; for (i = 0, n = e.length; i < n; i++)s *= e[i]; s *= t; var o = new Array(s), c = 0, l = 0, h = 1 / (2 ** a - 1), u = r.getBytes((s * a + 7) / 8), d = 0; for (i = 0; i < s; i++) { for (; c < a;) { l <<= 8; l |= u[d++]; c += 8 } c -= a; o[i] = (l >> c) * h; l &= (1 << c) - 1 } return o }, getIR({ xref: e, isEvalSupported: t, fn: a }) { var i = a.dict; i || (i = a); var n = [this.constructSampled, null, this.constructInterpolated, this.constructStiched, this.constructPostScript][i.get("FunctionType")]; if (!n) throw new r.FormatError("Unknown type of function"); return n.call(this, { xref: e, isEvalSupported: t, fn: a, dict: i }) }, fromIR({ xref: e, isEvalSupported: t, IR: a }) { switch (a[0]) { case 0: return this.constructSampledFromIR({ xref: e, isEvalSupported: t, IR: a }); case 2: return this.constructInterpolatedFromIR({ xref: e, isEvalSupported: t, IR: a }); case 3: return this.constructStichedFromIR({ xref: e, isEvalSupported: t, IR: a }); default: return this.constructPostScriptFromIR({ xref: e, isEvalSupported: t, IR: a }) } }, parse({ xref: e, isEvalSupported: t, fn: a }) { const r = this.getIR({ xref: e, isEvalSupported: t, fn: a }); return this.fromIR({ xref: e, isEvalSupported: t, IR: r }) }, parseArray({ xref: e, isEvalSupported: t, fnObj: a }) { if (!Array.isArray(a)) return this.parse({ xref: e, isEvalSupported: t, fn: a }); for (var r = [], i = 0, n = a.length; i < n; i++)r.push(this.parse({ xref: e, isEvalSupported: t, fn: e.fetchIfRef(a[i]) })); return function (e, t, a, i) { for (var n = 0, s = r.length; n < s; n++)r[n](e, t, a, i + n) } }, constructSampled({ xref: e, isEvalSupported: t, fn: a, dict: i }) { function n(e) { for (var t = e.length, a = [], r = 0, i = 0; i < t; i += 2) { a[r] = [e[i], e[i + 1]]; ++r } return a } var o = s(i.getArray("Domain")), c = s(i.getArray("Range")); if (!o || !c) throw new r.FormatError("No domain or range"); var l = o.length / 2, h = c.length / 2; o = n(o); c = n(c); var u = s(i.getArray("Size")), d = i.get("BitsPerSample"), f = i.get("Order") || 1; 1 !== f && (0, r.info)("No support for cubic spline interpolation: " + f); var g = s(i.getArray("Encode")); if (g) g = n(g); else { g = []; for (var m = 0; m < l; ++m)g.push([0, u[m] - 1]) } var p = s(i.getArray("Decode")); return [0, l, o, g, p = p ? n(p) : c, this.getSampleArray(u, h, d, a), u, h, 2 ** d - 1, c] }, constructSampledFromIR({ xref: e, isEvalSupported: t, IR: a }) { function r(e, t, a, r, i) { return r + (i - r) / (a - t) * (e - t) } return function (e, t, i, n) { var s, o, c = a[1], l = a[2], h = a[3], u = a[4], d = a[5], f = a[6], g = a[7], m = a[9], p = 1 << c, b = new Float64Array(p), y = new Uint32Array(p); for (o = 0; o < p; o++)b[o] = 1; var v = g, w = 1; for (s = 0; s < c; ++s) { var k = l[s][0], S = l[s][1], C = r(Math.min(Math.max(e[t + s], k), S), k, S, h[s][0], h[s][1]), x = f[s], A = (C = Math.min(Math.max(C, 0), x - 1)) < x - 1 ? Math.floor(C) : C - 1, I = A + 1 - C, F = C - A, T = A * v, E = T + v; for (o = 0; o < p; o++)if (o & w) { b[o] *= F; y[o] += E } else { b[o] *= I; y[o] += T } v *= x; w <<= 1 } for (o = 0; o < g; ++o) { var O = 0; for (s = 0; s < p; s++)O += d[y[s] + o] * b[s]; O = r(O, 0, 1, u[o][0], u[o][1]); i[n + o] = Math.min(Math.max(O, m[o][0]), m[o][1]) } } }, constructInterpolated({ xref: e, isEvalSupported: t, fn: a, dict: r }) { for (var i = s(r.getArray("C0")) || [0], n = s(r.getArray("C1")) || [1], o = r.get("N"), c = i.length, l = [], h = 0; h < c; ++h)l.push(n[h] - i[h]); return [2, i, l, o] }, constructInterpolatedFromIR({ xref: e, isEvalSupported: t, IR: a }) { var r = a[1], i = a[2], n = a[3], s = i.length; return function (e, t, a, o) { for (var c = 1 === n ? e[t] : e[t] ** n, l = 0; l < s; ++l)a[o + l] = r[l] + c * i[l] } }, constructStiched({ xref: e, isEvalSupported: t, fn: a, dict: i }) { var n = s(i.getArray("Domain")); if (!n) throw new r.FormatError("No domain"); if (1 != n.length / 2) throw new r.FormatError("Bad domain for stiched function"); for (var o = i.get("Functions"), c = [], l = 0, h = o.length; l < h; ++l)c.push(this.parse({ xref: e, isEvalSupported: t, fn: e.fetchIfRef(o[l]) })); return [3, n, s(i.getArray("Bounds")), s(i.getArray("Encode")), c] }, constructStichedFromIR({ xref: e, isEvalSupported: t, IR: a }) { var r = a[1], i = a[2], n = a[3], s = a[4], o = new Float32Array(1); return function (e, t, a, c) { for (var l = function (e, t, a) { e > a ? e = a : e < t && (e = t); return e }(e[t], r[0], r[1]), h = 0, u = i.length; h < u && !(l < i[h]); ++h); var d = r[0]; h > 0 && (d = i[h - 1]); var f = r[1]; h < i.length && (f = i[h]); var g = n[2 * h], m = n[2 * h + 1]; o[0] = d === f ? g : g + (l - d) * (m - g) / (f - d); s[h](o, 0, a, c) } }, constructPostScript({ xref: e, isEvalSupported: t, fn: a, dict: i }) { var o = s(i.getArray("Domain")), c = s(i.getArray("Range")); if (!o) throw new r.FormatError("No domain."); if (!c) throw new r.FormatError("No range."); var l = new n.PostScriptLexer(a); return [4, o, c, new n.PostScriptParser(l).parse()] }, constructPostScriptFromIR({ xref: e, isEvalSupported: t, IR: a }) { var i = a[1], n = a[2], s = a[3]; if (t && r.IsEvalSupportedCached.value) { const e = (new h).compile(s, i, n); if (e) return new Function("src", "srcOffset", "dest", "destOffset", e) } (0, r.info)("Unable to compile PS function"); var o = n.length >> 1, c = i.length >> 1, u = new l(s), d = Object.create(null), f = 8192, g = new Float32Array(c); return function (e, t, a, r) { var i, s, l = "", h = g; for (i = 0; i < c; i++) { s = e[t + i]; h[i] = s; l += s + "_" } var m = d[l]; if (void 0 === m) { var p = new Float32Array(o), b = u.execute(h), y = b.length - o; for (i = 0; i < o; i++) { s = b[y + i]; var v = n[2 * i]; (s < v || s > (v = n[2 * i + 1])) && (s = v); p[i] = s } if (f > 0) { f--; d[l] = p } a.set(p, r) } else a.set(m, r) } } }; var c = function () { function e(e) { this.stack = e ? Array.prototype.slice.call(e, 0) : [] } e.prototype = { push: function (e) { if (this.stack.length >= 100) throw new Error("PostScript function stack overflow."); this.stack.push(e) }, pop: function () { if (this.stack.length <= 0) throw new Error("PostScript function stack underflow."); return this.stack.pop() }, copy: function (e) { if (this.stack.length + e >= 100) throw new Error("PostScript function stack overflow."); for (var t = this.stack, a = t.length - e, r = e - 1; r >= 0; r--, a++)t.push(t[a]) }, index: function (e) { this.push(this.stack[this.stack.length - e - 1]) }, roll: function (e, t) { var a, r, i, n = this.stack, s = n.length - e, o = n.length - 1, c = s + (t - Math.floor(t / e) * e); for (a = s, r = o; a < r; a++, r--) { i = n[a]; n[a] = n[r]; n[r] = i } for (a = s, r = c - 1; a < r; a++, r--) { i = n[a]; n[a] = n[r]; n[r] = i } for (a = c, r = o; a < r; a++, r--) { i = n[a]; n[a] = n[r]; n[r] = i } } }; return e }(), l = function () { function e(e) { this.operators = e } e.prototype = { execute: function (e) { for (var t, a, i, n = new c(e), s = 0, o = this.operators, l = o.length; s < l;)if ("number" != typeof (t = o[s++])) switch (t) { case "jz": i = n.pop(); (a = n.pop()) || (s = i); break; case "j": s = a = n.pop(); break; case "abs": a = n.pop(); n.push(Math.abs(a)); break; case "add": i = n.pop(); a = n.pop(); n.push(a + i); break; case "and": i = n.pop(); a = n.pop(); (0, r.isBool)(a) && (0, r.isBool)(i) ? n.push(a && i) : n.push(a & i); break; case "atan": a = n.pop(); n.push(Math.atan(a)); break; case "bitshift": i = n.pop(); (a = n.pop()) > 0 ? n.push(a << i) : n.push(a >> i); break; case "ceiling": a = n.pop(); n.push(Math.ceil(a)); break; case "copy": a = n.pop(); n.copy(a); break; case "cos": a = n.pop(); n.push(Math.cos(a)); break; case "cvi": a = 0 | n.pop(); n.push(a); break; case "cvr": break; case "div": i = n.pop(); a = n.pop(); n.push(a / i); break; case "dup": n.copy(1); break; case "eq": i = n.pop(); a = n.pop(); n.push(a === i); break; case "exch": n.roll(2, 1); break; case "exp": i = n.pop(); a = n.pop(); n.push(a ** i); break; case "false": n.push(!1); break; case "floor": a = n.pop(); n.push(Math.floor(a)); break; case "ge": i = n.pop(); a = n.pop(); n.push(a >= i); break; case "gt": i = n.pop(); a = n.pop(); n.push(a > i); break; case "idiv": i = n.pop(); a = n.pop(); n.push(a / i | 0); break; case "index": a = n.pop(); n.index(a); break; case "le": i = n.pop(); a = n.pop(); n.push(a <= i); break; case "ln": a = n.pop(); n.push(Math.log(a)); break; case "log": a = n.pop(); n.push(Math.log(a) / Math.LN10); break; case "lt": i = n.pop(); a = n.pop(); n.push(a < i); break; case "mod": i = n.pop(); a = n.pop(); n.push(a % i); break; case "mul": i = n.pop(); a = n.pop(); n.push(a * i); break; case "ne": i = n.pop(); a = n.pop(); n.push(a !== i); break; case "neg": a = n.pop(); n.push(-a); break; case "not": a = n.pop(); (0, r.isBool)(a) ? n.push(!a) : n.push(~a); break; case "or": i = n.pop(); a = n.pop(); (0, r.isBool)(a) && (0, r.isBool)(i) ? n.push(a || i) : n.push(a | i); break; case "pop": n.pop(); break; case "roll": i = n.pop(); a = n.pop(); n.roll(a, i); break; case "round": a = n.pop(); n.push(Math.round(a)); break; case "sin": a = n.pop(); n.push(Math.sin(a)); break; case "sqrt": a = n.pop(); n.push(Math.sqrt(a)); break; case "sub": i = n.pop(); a = n.pop(); n.push(a - i); break; case "true": n.push(!0); break; case "truncate": a = (a = n.pop()) < 0 ? Math.ceil(a) : Math.floor(a); n.push(a); break; case "xor": i = n.pop(); a = n.pop(); (0, r.isBool)(a) && (0, r.isBool)(i) ? n.push(a !== i) : n.push(a ^ i); break; default: throw new r.FormatError(`Unknown operator ${t}`) } else n.push(t); return n.stack } }; return e }(); t.PostScriptEvaluator = l; var h = function () { function e(e) { this.type = e } e.prototype.visit = function (e) { (0, r.unreachable)("abstract method") }; function t(t, a, r) { e.call(this, "args"); this.index = t; this.min = a; this.max = r } t.prototype = Object.create(e.prototype); t.prototype.visit = function (e) { e.visitArgument(this) }; function a(t) { e.call(this, "literal"); this.number = t; this.min = t; this.max = t } a.prototype = Object.create(e.prototype); a.prototype.visit = function (e) { e.visitLiteral(this) }; function i(t, a, r, i, n) { e.call(this, "binary"); this.op = t; this.arg1 = a; this.arg2 = r; this.min = i; this.max = n } i.prototype = Object.create(e.prototype); i.prototype.visit = function (e) { e.visitBinaryOperation(this) }; function n(t, a) { e.call(this, "max"); this.arg = t; this.min = t.min; this.max = a } n.prototype = Object.create(e.prototype); n.prototype.visit = function (e) { e.visitMin(this) }; function s(t, a, r) { e.call(this, "var"); this.index = t; this.min = a; this.max = r } s.prototype = Object.create(e.prototype); s.prototype.visit = function (e) { e.visitVariable(this) }; function o(t, a) { e.call(this, "definition"); this.variable = t; this.arg = a } o.prototype = Object.create(e.prototype); o.prototype.visit = function (e) { e.visitVariableDefinition(this) }; function c() { this.parts = [] } c.prototype = { visitArgument(e) { this.parts.push("Math.max(", e.min, ", Math.min(", e.max, ", src[srcOffset + ", e.index, "]))") }, visitVariable(e) { this.parts.push("v", e.index) }, visitLiteral(e) { this.parts.push(e.number) }, visitBinaryOperation(e) { this.parts.push("("); e.arg1.visit(this); this.parts.push(" ", e.op, " "); e.arg2.visit(this); this.parts.push(")") }, visitVariableDefinition(e) { this.parts.push("var "); e.variable.visit(this); this.parts.push(" = "); e.arg.visit(this); this.parts.push(";") }, visitMin(e) { this.parts.push("Math.min("); e.arg.visit(this); this.parts.push(", ", e.max, ")") }, toString() { return this.parts.join("") } }; function l(e, t) { return "literal" === t.type && 0 === t.number ? e : "literal" === e.type && 0 === e.number ? t : "literal" === t.type && "literal" === e.type ? new a(e.number + t.number) : new i("+", e, t, e.min + t.min, e.max + t.max) } function h(e, t) { if ("literal" === t.type) { if (0 === t.number) return new a(0); if (1 === t.number) return e; if ("literal" === e.type) return new a(e.number * t.number) } if ("literal" === e.type) { if (0 === e.number) return new a(0); if (1 === e.number) return t } return new i("*", e, t, Math.min(e.min * t.min, e.min * t.max, e.max * t.min, e.max * t.max), Math.max(e.min * t.min, e.min * t.max, e.max * t.min, e.max * t.max)) } function u(e, t) { if ("literal" === t.type) { if (0 === t.number) return e; if ("literal" === e.type) return new a(e.number - t.number) } return "binary" === t.type && "-" === t.op && "literal" === e.type && 1 === e.number && "literal" === t.arg1.type && 1 === t.arg1.number ? t.arg2 : new i("-", e, t, e.min - t.max, e.max - t.min) } function d(e, t) { return e.min >= t ? new a(t) : e.max <= t ? e : new n(e, t) } function f() { } f.prototype = { compile: function (e, r, i) { var n, f, g, m, p, b, y, v, w, k, S = [], C = [], x = r.length >> 1, A = i.length >> 1, I = 0; for (n = 0; n < x; n++)S.push(new t(n, r[2 * n], r[2 * n + 1])); for (n = 0, f = e.length; n < f; n++)if ("number" != typeof (k = e[n])) switch (k) { case "add": if (S.length < 2) return null; b = S.pop(); p = S.pop(); S.push(l(p, b)); break; case "cvr": if (S.length < 1) return null; break; case "mul": if (S.length < 2) return null; b = S.pop(); p = S.pop(); S.push(h(p, b)); break; case "sub": if (S.length < 2) return null; b = S.pop(); p = S.pop(); S.push(u(p, b)); break; case "exch": if (S.length < 2) return null; y = S.pop(); v = S.pop(); S.push(y, v); break; case "pop": if (S.length < 1) return null; S.pop(); break; case "index": if (S.length < 1) return null; if ("literal" !== (p = S.pop()).type) return null; if ((g = p.number) < 0 || !Number.isInteger(g) || S.length < g) return null; if ("literal" === (y = S[S.length - g - 1]).type || "var" === y.type) { S.push(y); break } w = new s(I++, y.min, y.max); S[S.length - g - 1] = w; S.push(w); C.push(new o(w, y)); break; case "dup": if (S.length < 1) return null; if ("number" == typeof e[n + 1] && "gt" === e[n + 2] && e[n + 3] === n + 7 && "jz" === e[n + 4] && "pop" === e[n + 5] && e[n + 6] === e[n + 1]) { p = S.pop(); S.push(d(p, e[n + 1])); n += 6; break } if ("literal" === (y = S[S.length - 1]).type || "var" === y.type) { S.push(y); break } w = new s(I++, y.min, y.max); S[S.length - 1] = w; S.push(w); C.push(new o(w, y)); break; case "roll": if (S.length < 2) return null; b = S.pop(); p = S.pop(); if ("literal" !== b.type || "literal" !== p.type) return null; m = b.number; if ((g = p.number) <= 0 || !Number.isInteger(g) || !Number.isInteger(m) || S.length < g) return null; if (0 === (m = (m % g + g) % g)) break; Array.prototype.push.apply(S, S.splice(S.length - g, g - m)); break; default: return null } else S.push(new a(k)); if (S.length !== A) return null; var F = []; C.forEach((function (e) { var t = new c; e.visit(t); F.push(t.toString()) })); S.forEach((function (e, t) { var a = new c; e.visit(a); var r = i[2 * t], n = i[2 * t + 1], s = [a.toString()]; if (r > e.min) { s.unshift("Math.max(", r, ", "); s.push(")") } if (n < e.max) { s.unshift("Math.min(", n, ", "); s.push(")") } s.unshift("dest[destOffset + ", t, "] = "); s.push(";"); F.push(s.join("")) })); return F.join("\n") } }; return f }(); t.PostScriptCompiler = h }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PostScriptParser = t.PostScriptLexer = void 0; var r = a(2), i = a(4), n = a(7); t.PostScriptParser = class { constructor(e) { this.lexer = e; this.operators = []; this.token = null; this.prev = null } nextToken() { this.prev = this.token; this.token = this.lexer.getToken() } accept(e) { if (this.token.type === e) { this.nextToken(); return !0 } return !1 } expect(e) { if (this.accept(e)) return !0; throw new r.FormatError(`Unexpected symbol: found ${this.token.type} expected ${e}.`) } parse() { this.nextToken(); this.expect(s.LBRACE); this.parseBlock(); this.expect(s.RBRACE); return this.operators } parseBlock() { for (; ;)if (this.accept(s.NUMBER)) this.operators.push(this.prev.value); else if (this.accept(s.OPERATOR)) this.operators.push(this.prev.value); else { if (!this.accept(s.LBRACE)) return; this.parseCondition() } } parseCondition() { const e = this.operators.length; this.operators.push(null, null); this.parseBlock(); this.expect(s.RBRACE); if (this.accept(s.IF)) { this.operators[e] = this.operators.length; this.operators[e + 1] = "jz" } else { if (!this.accept(s.LBRACE)) throw new r.FormatError("PS Function: error parsing conditional."); { const t = this.operators.length; this.operators.push(null, null); const a = this.operators.length; this.parseBlock(); this.expect(s.RBRACE); this.expect(s.IFELSE); this.operators[t] = this.operators.length; this.operators[t + 1] = "j"; this.operators[e] = a; this.operators[e + 1] = "jz" } } } }; const s = { LBRACE: 0, RBRACE: 1, NUMBER: 2, OPERATOR: 3, IF: 4, IFELSE: 5 }, o = function () { const e = Object.create(null); class t { constructor(e, t) { this.type = e; this.value = t } static getOperator(a) { const r = e[a]; return r || (e[a] = new t(s.OPERATOR, a)) } static get LBRACE() { return (0, r.shadow)(this, "LBRACE", new t(s.LBRACE, "{")) } static get RBRACE() { return (0, r.shadow)(this, "RBRACE", new t(s.RBRACE, "}")) } static get IF() { return (0, r.shadow)(this, "IF", new t(s.IF, "IF")) } static get IFELSE() { return (0, r.shadow)(this, "IFELSE", new t(s.IFELSE, "IFELSE")) } } return t }(); t.PostScriptLexer = class { constructor(e) { this.stream = e; this.nextChar(); this.strBuf = [] } nextChar() { return this.currentChar = this.stream.getByte() } getToken() { let e = !1, t = this.currentChar; for (; ;) { if (t < 0) return i.EOF; if (e) 10 !== t && 13 !== t || (e = !1); else if (37 === t) e = !0; else if (!(0, n.isWhiteSpace)(t)) break; t = this.nextChar() } switch (0 | t) { case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 43: case 45: case 46: return new o(s.NUMBER, this.getNumber()); case 123: this.nextChar(); return o.LBRACE; case 125: this.nextChar(); return o.RBRACE }const a = this.strBuf; a.length = 0; a[0] = String.fromCharCode(t); for (; (t = this.nextChar()) >= 0 && (t >= 65 && t <= 90 || t >= 97 && t <= 122);)a.push(String.fromCharCode(t)); const r = a.join(""); switch (r.toLowerCase()) { case "if": return o.IF; case "ifelse": return o.IFELSE; default: return o.getOperator(r) } } getNumber() { let e = this.currentChar; const t = this.strBuf; t.length = 0; t[0] = String.fromCharCode(e); for (; (e = this.nextChar()) >= 0 && (e >= 48 && e <= 57 || 45 === e || 46 === e);)t.push(String.fromCharCode(e)); const a = parseFloat(t.join("")); if (isNaN(a)) throw new r.FormatError(`Invalid floating point number: ${a}`); return a } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.MurmurHash3_64 = void 0; var r = a(2); t.MurmurHash3_64 = class { constructor(e) { this.h1 = e ? 4294967295 & e : 3285377520; this.h2 = e ? 4294967295 & e : 3285377520 } update(e) { let t, a; if ((0, r.isString)(e)) { t = new Uint8Array(2 * e.length); a = 0; for (let r = 0, i = e.length; r < i; r++) { const i = e.charCodeAt(r); if (i <= 255) t[a++] = i; else { t[a++] = i >>> 8; t[a++] = 255 & i } } } else { if (!(0, r.isArrayBuffer)(e)) throw new Error("Wrong data format in MurmurHash3_64_update. Input must be a string or array."); t = e; a = t.byteLength } const i = a >> 2, n = a - 4 * i, s = new Uint32Array(t.buffer, 0, i); let o = 0, c = 0, l = this.h1, h = this.h2; const u = 3432918353, d = 461845907; for (let e = 0; e < i; e++)if (1 & e) { o = s[e]; o = o * u & 4294901760 | 11601 * o & 65535; o = o << 15 | o >>> 17; o = o * d & 4294901760 | 13715 * o & 65535; l ^= o; l = l << 13 | l >>> 19; l = 5 * l + 3864292196 } else { c = s[e]; c = c * u & 4294901760 | 11601 * c & 65535; c = c << 15 | c >>> 17; c = c * d & 4294901760 | 13715 * c & 65535; h ^= c; h = h << 13 | h >>> 19; h = 5 * h + 3864292196 } o = 0; switch (n) { case 3: o ^= t[4 * i + 2] << 16; case 2: o ^= t[4 * i + 1] << 8; case 1: o ^= t[4 * i]; o = o * u & 4294901760 | 11601 * o & 65535; o = o << 15 | o >>> 17; o = o * d & 4294901760 | 13715 * o & 65535; 1 & i ? l ^= o : h ^= o }this.h1 = l; this.h2 = h } hexdigest() { let e = this.h1, t = this.h2; e ^= t >>> 1; e = 3981806797 * e & 4294901760 | 36045 * e & 65535; t = 4283543511 * t & 4294901760 | (2950163797 * (t << 16 | e >>> 16) & 4294901760) >>> 16; e ^= t >>> 1; e = 444984403 * e & 4294901760 | 60499 * e & 65535; t = 3301882366 * t & 4294901760 | (3120437893 * (t << 16 | e >>> 16) & 4294901760) >>> 16; e ^= t >>> 1; const a = (e >>> 0).toString(16), r = (t >>> 0).toString(16); return a.padStart(8, "0") + r.padStart(8, "0") } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.NativeImageDecoder = void 0; var r = a(22), i = a(17), n = a(11); class s { constructor({ xref: e, resources: t, handler: a, forceDataSchema: r = !1, pdfFunctionFactory: i }) { this.xref = e; this.resources = t; this.handler = a; this.forceDataSchema = r; this.pdfFunctionFactory = i } canDecode(e) { return e instanceof i.JpegStream && s.isDecodable(e, this.xref, this.resources, this.pdfFunctionFactory) && e.maybeValidDimensions } decode(e) { const t = e.dict; let a = t.get("ColorSpace", "CS"); a = r.ColorSpace.parse(a, this.xref, this.resources, this.pdfFunctionFactory); return this.handler.sendWithPromise("JpegDecode", [e.getIR(this.forceDataSchema), a.numComps]).then((function ({ data: e, width: a, height: r }) { return new n.Stream(e, 0, e.length, t) })) } static isSupported(e, t, a, i) { const n = e.dict; if (n.has("DecodeParms") || n.has("DP")) return !1; const s = r.ColorSpace.parse(n.get("ColorSpace", "CS"), t, a, i); return ("DeviceGray" === s.name || "DeviceRGB" === s.name) && s.isDefaultDecode(n.getArray("Decode", "D")) } static isDecodable(e, t, a, i) { const n = e.dict; if (n.has("DecodeParms") || n.has("DP")) return !1; const s = r.ColorSpace.parse(n.get("ColorSpace", "CS"), t, a, i), o = n.get("BitsPerComponent", "BPC") || 1; return (1 === s.numComps || 3 === s.numComps) && s.isDefaultDecode(n.getArray("Decode", "D"), o) } } t.NativeImageDecoder = s }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PDFImage = void 0; var r = a(2), i = a(4), n = a(22), s = a(11), o = a(17), c = a(20), l = function () { function e(e, t) { return t && t.canDecode(e) ? t.decode(e).catch(t => { (0, r.warn)("Native image decoding failed -- trying to recover: " + (t && t.message)); return e }) : Promise.resolve(e) } function t(e, t, a, r) { (e = t + e * a) < 0 ? e = 0 : e > r && (e = r); return e } function a(e, t, a, r, i, n) { var s = i * n; let o; o = t <= 8 ? new Uint8Array(s) : t <= 16 ? new Uint16Array(s) : new Uint32Array(s); var c, l, h, u, d = a / i, f = r / n, g = 0, m = new Uint16Array(i), p = a; for (c = 0; c < i; c++)m[c] = Math.floor(c * d); for (c = 0; c < n; c++) { h = Math.floor(c * f) * p; for (l = 0; l < i; l++) { u = h + m[l]; o[g++] = e[u] } } return o } function l({ xref: e, res: t, image: a, isInline: s = !1, smask: o = null, mask: h = null, isMask: u = !1, pdfFunctionFactory: d }) { this.image = a; var f = a.dict; const g = f.get("Filter"); if ((0, i.isName)(g)) switch (g.name) { case "JPXDecode": var m = new c.JpxImage; m.parseImageProperties(a.stream); a.stream.reset(); a.width = m.width; a.height = m.height; a.bitsPerComponent = m.bitsPerComponent; a.numComps = m.componentsCount; break; case "JBIG2Decode": a.bitsPerComponent = 1; a.numComps = 1 }let p = f.get("Width", "W"), b = f.get("Height", "H"); if (Number.isInteger(a.width) && a.width > 0 && Number.isInteger(a.height) && a.height > 0 && (a.width !== p || a.height !== b)) { (0, r.warn)("PDFImage - using the Width/Height of the image data, rather than the image dictionary."); p = a.width; b = a.height } if (p < 1 || b < 1) throw new r.FormatError(`Invalid image width: ${p} or height: ${b}`); this.width = p; this.height = b; this.interpolate = f.get("Interpolate", "I") || !1; this.imageMask = f.get("ImageMask", "IM") || !1; this.matte = f.get("Matte") || !1; var y = a.bitsPerComponent; if (!y && !(y = f.get("BitsPerComponent", "BPC"))) { if (!this.imageMask) throw new r.FormatError(`Bits per component missing in image: ${this.imageMask}`); y = 1 } this.bpc = y; if (!this.imageMask) { var v = f.get("ColorSpace", "CS"); if (!v) { (0, r.info)("JPX images (which do not require color spaces)"); switch (a.numComps) { case 1: v = i.Name.get("DeviceGray"); break; case 3: v = i.Name.get("DeviceRGB"); break; case 4: v = i.Name.get("DeviceCMYK"); break; default: throw new Error(`JPX images with ${a.numComps} ` + "color components not supported.") } } const o = s ? t : null; this.colorSpace = n.ColorSpace.parse(v, e, o, d); this.numComps = this.colorSpace.numComps } this.decode = f.getArray("Decode", "D"); this.needsDecode = !1; if (this.decode && (this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode, y) || u && !n.ColorSpace.isDefaultDecode(this.decode, 1))) { this.needsDecode = !0; var w = (1 << y) - 1; this.decodeCoefficients = []; this.decodeAddends = []; const e = this.colorSpace && "Indexed" === this.colorSpace.name; for (var k = 0, S = 0; k < this.decode.length; k += 2, ++S) { var C = this.decode[k], x = this.decode[k + 1]; this.decodeCoefficients[S] = e ? (x - C) / w : x - C; this.decodeAddends[S] = e ? C : w * C } } if (o) this.smask = new l({ xref: e, res: t, image: o, isInline: s, pdfFunctionFactory: d }); else if (h) if ((0, i.isStream)(h)) { h.dict.get("ImageMask", "IM") ? this.mask = new l({ xref: e, res: t, image: h, isInline: s, isMask: !0, pdfFunctionFactory: d }) : (0, r.warn)("Ignoring /Mask in image without /ImageMask.") } else this.mask = h } l.buildImage = function ({ handler: t, xref: a, res: n, image: s, isInline: o = !1, nativeDecoder: c = null, pdfFunctionFactory: h }) { var u, d, f = e(s, c), g = s.dict.get("SMask"), m = s.dict.get("Mask"); if (g) { u = e(g, c); d = Promise.resolve(null) } else { u = Promise.resolve(null); if (m) if ((0, i.isStream)(m)) d = e(m, c); else if (Array.isArray(m)) d = Promise.resolve(m); else { (0, r.warn)("Unsupported mask format."); d = Promise.resolve(null) } else d = Promise.resolve(null) } return Promise.all([f, u, d]).then((function ([e, t, r]) { return new l({ xref: a, res: n, image: e, isInline: o, smask: t, mask: r, pdfFunctionFactory: h }) })) }; l.createMask = function ({ imgArray: e, width: t, height: a, imageIsFromDecodeStream: r, inverseDecode: i }) { var n, s, o = (t + 7 >> 3) * a, c = e.byteLength; if (!r || i && !(o === c)) if (i) { (n = new Uint8ClampedArray(o)).set(e); for (s = c; s < o; s++)n[s] = 255 } else (n = new Uint8ClampedArray(c)).set(e); else n = e; if (i) for (s = 0; s < c; s++)n[s] ^= 255; return { data: n, width: t, height: a } }; l.prototype = { get drawWidth() { return Math.max(this.width, this.smask && this.smask.width || 0, this.mask && this.mask.width || 0) }, get drawHeight() { return Math.max(this.height, this.smask && this.smask.height || 0, this.mask && this.mask.height || 0) }, decodeBuffer(e) { var a, r, i = this.bpc, n = this.numComps, s = this.decodeAddends, o = this.decodeCoefficients, c = (1 << i) - 1; if (1 !== i) { var l = 0; for (a = 0, r = this.width * this.height; a < r; a++)for (var h = 0; h < n; h++) { e[l] = t(e[l], s[h], o[h], c); l++ } } else for (a = 0, r = e.length; a < r; a++)e[a] = +!e[a] }, getComponents(e) { var t = this.bpc; if (8 === t) return e; var a = this.width, r = this.height, i = this.numComps, n = a * r * i, s = 0; let o; o = t <= 8 ? new Uint8Array(n) : t <= 16 ? new Uint16Array(n) : new Uint32Array(n); var c, l, h = a * i, u = (1 << t) - 1, d = 0; if (1 === t) for (var f, g, m, p = 0; p < r; p++) { g = d + (-8 & h); m = d + h; for (; d < g;) { l = e[s++]; o[d] = l >> 7 & 1; o[d + 1] = l >> 6 & 1; o[d + 2] = l >> 5 & 1; o[d + 3] = l >> 4 & 1; o[d + 4] = l >> 3 & 1; o[d + 5] = l >> 2 & 1; o[d + 6] = l >> 1 & 1; o[d + 7] = 1 & l; d += 8 } if (d < m) { l = e[s++]; f = 128; for (; d < m;) { o[d++] = +!!(l & f); f >>= 1 } } } else { var b = 0; l = 0; for (d = 0, c = n; d < c; ++d) { if (d % h == 0) { l = 0; b = 0 } for (; b < t;) { l = l << 8 | e[s++]; b += 8 } var y = b - t; let a = l >> y; a < 0 ? a = 0 : a > u && (a = u); o[d] = a; l &= (1 << y) - 1; b = y } } return o }, fillOpacity(e, t, i, n, s) { var o, c, h, u, d, f, g = this.smask, m = this.mask; if (g) { c = g.width; h = g.height; o = new Uint8ClampedArray(c * h); g.fillGrayBuffer(o); c === t && h === i || (o = a(o, g.bpc, c, h, t, i)) } else if (m) if (m instanceof l) { c = m.width; h = m.height; o = new Uint8ClampedArray(c * h); m.numComps = 1; m.fillGrayBuffer(o); for (u = 0, d = c * h; u < d; ++u)o[u] = 255 - o[u]; c === t && h === i || (o = a(o, m.bpc, c, h, t, i)) } else { if (!Array.isArray(m)) throw new r.FormatError("Unknown mask format."); o = new Uint8ClampedArray(t * i); var p = this.numComps; for (u = 0, d = t * i; u < d; ++u) { var b = 0, y = u * p; for (f = 0; f < p; ++f) { var v = s[y + f], w = 2 * f; if (v < m[w] || v > m[w + 1]) { b = 255; break } } o[u] = b } } if (o) for (u = 0, f = 3, d = t * n; u < d; ++u, f += 4)e[f] = o[u]; else for (u = 0, f = 3, d = t * n; u < d; ++u, f += 4)e[f] = 255 }, undoPreblend(e, t, a) { var r = this.smask && this.smask.matte; if (r) for (var i = this.colorSpace.getRgb(r, 0), n = i[0], s = i[1], o = i[2], c = t * a * 4, l = 0; l < c; l += 4) { var h = e[l + 3]; if (0 !== h) { var u = 255 / h; e[l] = (e[l] - n) * u + n; e[l + 1] = (e[l + 1] - s) * u + s; e[l + 2] = (e[l + 2] - o) * u + o } else { e[l] = 255; e[l + 1] = 255; e[l + 2] = 255 } } }, createImageData(e = !1) { var t, a = this.drawWidth, i = this.drawHeight, n = { width: a, height: i, kind: 0, data: null }, c = this.numComps, l = this.width, h = this.height, u = this.bpc, d = l * c * u + 7 >> 3; if (!e) { var f; "DeviceGray" === this.colorSpace.name && 1 === u ? f = r.ImageKind.GRAYSCALE_1BPP : "DeviceRGB" !== this.colorSpace.name || 8 !== u || this.needsDecode || (f = r.ImageKind.RGB_24BPP); if (f && !this.smask && !this.mask && a === l && i === h) { n.kind = f; t = this.getImageBytes(h * d); if (this.image instanceof s.DecodeStream) n.data = t; else { var g = new Uint8ClampedArray(t.length); g.set(t); n.data = g } if (this.needsDecode) { (0, r.assert)(f === r.ImageKind.GRAYSCALE_1BPP, "PDFImage.createImageData: The image must be grayscale."); for (var m = n.data, p = 0, b = m.length; p < b; p++)m[p] ^= 255 } return n } if (this.image instanceof o.JpegStream && !this.smask && !this.mask) { let e = h * d; switch (this.colorSpace.name) { case "DeviceGray": e *= 3; case "DeviceRGB": case "DeviceCMYK": n.kind = r.ImageKind.RGB_24BPP; n.data = this.getImageBytes(e, a, i, !0); return n } } } var y, v, w = 0 | (t = this.getImageBytes(h * d)).length / d * i / h, k = this.getComponents(t); if (e || this.smask || this.mask) { n.kind = r.ImageKind.RGBA_32BPP; n.data = new Uint8ClampedArray(a * i * 4); y = 1; v = !0; this.fillOpacity(n.data, a, i, w, k) } else { n.kind = r.ImageKind.RGB_24BPP; n.data = new Uint8ClampedArray(a * i * 3); y = 0; v = !1 } this.needsDecode && this.decodeBuffer(k); this.colorSpace.fillRgb(n.data, l, h, a, i, w, u, k, y); v && this.undoPreblend(n.data, a, w); return n }, fillGrayBuffer(e) { var t = this.numComps; if (1 !== t) throw new r.FormatError(`Reading gray scale from a color image: ${t}`); var a, i, n = this.width, s = this.height, o = this.bpc, c = n * t * o + 7 >> 3, l = this.getImageBytes(s * c), h = this.getComponents(l); if (1 !== o) { this.needsDecode && this.decodeBuffer(h); i = n * s; var u = 255 / ((1 << o) - 1); for (a = 0; a < i; ++a)e[a] = u * h[a] } else { i = n * s; if (this.needsDecode) for (a = 0; a < i; ++a)e[a] = h[a] - 1 & 255; else for (a = 0; a < i; ++a)e[a] = 255 & -h[a] } }, getImageBytes(e, t, a, r = !1) { this.image.reset(); this.image.drawWidth = t || this.width; this.image.drawHeight = a || this.height; this.image.forceRGB = !!r; return this.image.getBytes(e, !0) } }; return l }(); t.PDFImage = l }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.isNodeJS = void 0; const r = "object" == typeof process && process + "" == "[object process]" && !process.versions.nw && !process.versions.electron; t.isNodeJS = r }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.MessageHandler = void 0; var r = a(2); const i = 1, n = 2, s = 1, o = 2, c = 3, l = 4, h = 5, u = 6, d = 7, f = 8; function g(e) { if ("object" != typeof e || null === e) return e; switch (e.name) { case "AbortException": return new r.AbortException(e.message); case "MissingPDFException": return new r.MissingPDFException(e.message); case "UnexpectedResponseException": return new r.UnexpectedResponseException(e.message, e.status); case "UnknownErrorException": return new r.UnknownErrorException(e.message, e.details); default: return new r.UnknownErrorException(e.message, e.toString()) } } t.MessageHandler = class { constructor(e, t, a) { this.sourceName = e; this.targetName = t; this.comObj = a; this.callbackId = 1; this.streamId = 1; this.postMessageTransfers = !0; this.streamSinks = Object.create(null); this.streamControllers = Object.create(null); this.callbackCapabilities = Object.create(null); this.actionHandler = Object.create(null); this._onComObjOnMessage = e => { const t = e.data; if (t.targetName !== this.sourceName) return; if (t.stream) { this._processStreamMessage(t); return } if (t.callback) { const e = t.callbackId, a = this.callbackCapabilities[e]; if (!a) throw new Error(`Cannot resolve callback ${e}`); delete this.callbackCapabilities[e]; if (t.callback === i) a.resolve(t.data); else { if (t.callback !== n) throw new Error("Unexpected callback case"); a.reject(g(t.reason)) } return } const r = this.actionHandler[t.action]; if (!r) throw new Error(`Unknown action from worker: ${t.action}`); if (t.callbackId) { const e = this.sourceName, s = t.sourceName; new Promise((function (e) { e(r(t.data)) })).then((function (r) { a.postMessage({ sourceName: e, targetName: s, callback: i, callbackId: t.callbackId, data: r }) }), (function (r) { a.postMessage({ sourceName: e, targetName: s, callback: n, callbackId: t.callbackId, reason: g(r) }) })) } else t.streamId ? this._createStreamSink(t) : r(t.data) }; a.addEventListener("message", this._onComObjOnMessage) } on(e, t) { const a = this.actionHandler; if (a[e]) throw new Error(`There is already an actionName called "${e}"`); a[e] = t } send(e, t, a) { this._postMessage({ sourceName: this.sourceName, targetName: this.targetName, action: e, data: t }, a) } sendWithPromise(e, t, a) { const i = this.callbackId++, n = (0, r.createPromiseCapability)(); this.callbackCapabilities[i] = n; try { this._postMessage({ sourceName: this.sourceName, targetName: this.targetName, action: e, callbackId: i, data: t }, a) } catch (e) { n.reject(e) } return n.promise } sendWithStream(e, t, a, i) { const n = this.streamId++, o = this.sourceName, c = this.targetName, l = this.comObj; return new ReadableStream({ start: a => { const s = (0, r.createPromiseCapability)(); this.streamControllers[n] = { controller: a, startCall: s, pullCall: null, cancelCall: null, isClosed: !1 }; this._postMessage({ sourceName: o, targetName: c, action: e, streamId: n, data: t, desiredSize: a.desiredSize }, i); return s.promise }, pull: e => { const t = (0, r.createPromiseCapability)(); this.streamControllers[n].pullCall = t; l.postMessage({ sourceName: o, targetName: c, stream: u, streamId: n, desiredSize: e.desiredSize }); return t.promise }, cancel: e => { (0, r.assert)(e instanceof Error, "cancel must have a valid reason"); const t = (0, r.createPromiseCapability)(); this.streamControllers[n].cancelCall = t; this.streamControllers[n].isClosed = !0; l.postMessage({ sourceName: o, targetName: c, stream: s, streamId: n, reason: g(e) }); return t.promise } }, a) } _createStreamSink(e) { const t = this, a = this.actionHandler[e.action], i = e.streamId, n = this.sourceName, s = e.sourceName, o = this.comObj, u = { enqueue(e, a = 1, o) { if (this.isCancelled) return; const c = this.desiredSize; this.desiredSize -= a; if (c > 0 && this.desiredSize <= 0) { this.sinkCapability = (0, r.createPromiseCapability)(); this.ready = this.sinkCapability.promise } t._postMessage({ sourceName: n, targetName: s, stream: l, streamId: i, chunk: e }, o) }, close() { if (!this.isCancelled) { this.isCancelled = !0; o.postMessage({ sourceName: n, targetName: s, stream: c, streamId: i }); delete t.streamSinks[i] } }, error(e) { (0, r.assert)(e instanceof Error, "error must have a valid reason"); if (!this.isCancelled) { this.isCancelled = !0; o.postMessage({ sourceName: n, targetName: s, stream: h, streamId: i, reason: g(e) }) } }, sinkCapability: (0, r.createPromiseCapability)(), onPull: null, onCancel: null, isCancelled: !1, desiredSize: e.desiredSize, ready: null }; u.sinkCapability.resolve(); u.ready = u.sinkCapability.promise; this.streamSinks[i] = u; new Promise((function (t) { t(a(e.data, u)) })).then((function () { o.postMessage({ sourceName: n, targetName: s, stream: f, streamId: i, success: !0 }) }), (function (e) { o.postMessage({ sourceName: n, targetName: s, stream: f, streamId: i, reason: g(e) }) })) } _processStreamMessage(e) { const t = e.streamId, a = this.sourceName, i = e.sourceName, n = this.comObj; switch (e.stream) { case f: e.success ? this.streamControllers[t].startCall.resolve() : this.streamControllers[t].startCall.reject(g(e.reason)); break; case d: e.success ? this.streamControllers[t].pullCall.resolve() : this.streamControllers[t].pullCall.reject(g(e.reason)); break; case u: if (!this.streamSinks[t]) { n.postMessage({ sourceName: a, targetName: i, stream: d, streamId: t, success: !0 }); break } this.streamSinks[t].desiredSize <= 0 && e.desiredSize > 0 && this.streamSinks[t].sinkCapability.resolve(); this.streamSinks[t].desiredSize = e.desiredSize; const { onPull: m } = this.streamSinks[e.streamId]; new Promise((function (e) { e(m && m()) })).then((function () { n.postMessage({ sourceName: a, targetName: i, stream: d, streamId: t, success: !0 }) }), (function (e) { n.postMessage({ sourceName: a, targetName: i, stream: d, streamId: t, reason: g(e) }) })); break; case l: (0, r.assert)(this.streamControllers[t], "enqueue should have stream controller"); if (this.streamControllers[t].isClosed) break; this.streamControllers[t].controller.enqueue(e.chunk); break; case c: (0, r.assert)(this.streamControllers[t], "close should have stream controller"); if (this.streamControllers[t].isClosed) break; this.streamControllers[t].isClosed = !0; this.streamControllers[t].controller.close(); this._deleteStreamController(t); break; case h: (0, r.assert)(this.streamControllers[t], "error should have stream controller"); this.streamControllers[t].controller.error(g(e.reason)); this._deleteStreamController(t); break; case o: e.success ? this.streamControllers[t].cancelCall.resolve() : this.streamControllers[t].cancelCall.reject(g(e.reason)); this._deleteStreamController(t); break; case s: if (!this.streamSinks[t]) break; const { onCancel: p } = this.streamSinks[e.streamId]; new Promise((function (t) { t(p && p(g(e.reason))) })).then((function () { n.postMessage({ sourceName: a, targetName: i, stream: o, streamId: t, success: !0 }) }), (function (e) { n.postMessage({ sourceName: a, targetName: i, stream: o, streamId: t, reason: g(e) }) })); this.streamSinks[t].sinkCapability.reject(g(e.reason)); this.streamSinks[t].isCancelled = !0; delete this.streamSinks[t]; break; default: throw new Error("Unexpected stream case") } } async _deleteStreamController(e) { await Promise.allSettled([this.streamControllers[e].startCall, this.streamControllers[e].pullCall, this.streamControllers[e].cancelCall].map((function (e) { return e && e.promise }))); delete this.streamControllers[e] } _postMessage(e, t) { t && this.postMessageTransfers ? this.comObj.postMessage(e, t) : this.comObj.postMessage(e) } destroy() { this.comObj.removeEventListener("message", this._onComObjOnMessage) } } }, function (e, t, a) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); t.PDFWorkerStream = void 0; var r = a(2); t.PDFWorkerStream = class { constructor(e) { this._msgHandler = e; this._contentLength = null; this._fullRequestReader = null; this._rangeRequestReaders = [] } getFullReader() { (0, r.assert)(!this._fullRequestReader); this._fullRequestReader = new i(this._msgHandler); return this._fullRequestReader } getRangeReader(e, t) { const a = new n(e, t, this._msgHandler); this._rangeRequestReaders.push(a); return a } cancelAllRequests(e) { this._fullRequestReader && this._fullRequestReader.cancel(e); this._rangeRequestReaders.slice(0).forEach((function (t) { t.cancel(e) })) } }; class i { constructor(e) { this._msgHandler = e; this.onProgress = null; this._contentLength = null; this._isRangeSupported = !1; this._isStreamingSupported = !1; const t = this._msgHandler.sendWithStream("GetReader"); this._reader = t.getReader(); this._headersReady = this._msgHandler.sendWithPromise("ReaderHeadersReady").then(e => { this._isStreamingSupported = e.isStreamingSupported; this._isRangeSupported = e.isRangeSupported; this._contentLength = e.contentLength }) } get headersReady() { return this._headersReady } get contentLength() { return this._contentLength } get isStreamingSupported() { return this._isStreamingSupported } get isRangeSupported() { return this._isRangeSupported } async read() { const { value: e, done: t } = await this._reader.read(); return t ? { value: void 0, done: !0 } : { value: e.buffer, done: !1 } } cancel(e) { this._reader.cancel(e) } } class n { constructor(e, t, a) { this._msgHandler = a; this.onProgress = null; const r = this._msgHandler.sendWithStream("GetRangeReader", { begin: e, end: t }); this._reader = r.getReader() } get isStreamingSupported() { return !1 } async read() { const { value: e, done: t } = await this._reader.read(); return t ? { value: void 0, done: !0 } : { value: e.buffer, done: !1 } } cancel(e) { this._reader.cancel(e) } } }]) })); \ No newline at end of file
diff --git a/src/server/public/assets/pdf.worker.js b/src/server/public/assets/pdf.worker.js
deleted file mode 100644
index 1b4424b03..000000000
--- a/src/server/public/assets/pdf.worker.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * @licstart The following is the entire license notice for the
- * Javascript code in this page
- *
- * Copyright 2020 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * Javascript code in this page
- */
-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("pdfjs-dist/build/pdf.worker",[],t):"object"==typeof exports?exports["pdfjs-dist/build/pdf.worker"]=t():e["pdfjs-dist/build/pdf.worker"]=e.pdfjsWorker=t()}(this,(function(){return function(e){var t={};function a(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};e[r].call(i.exports,i,i.exports,a);i.l=!0;return i.exports}a.m=e;a.c=t;a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})};a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});Object.defineProperty(e,"__esModule",{value:!0})};a.t=function(e,t){1&t&&(e=a(e));if(8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);a.r(r);Object.defineProperty(r,"default",{enumerable:!0,value:e});if(2&t&&"string"!=typeof e)for(var i in e)a.d(r,i,function(t){return e[t]}.bind(null,i));return r};a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};a.d(t,"a",t);return t};a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};a.p="";return a(a.s=0)}([function(e,t,a){"use strict";const r=a(1);t.WorkerMessageHandler=r.WorkerMessageHandler},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.WorkerMessageHandler=t.WorkerTask=void 0;var r=a(2),i=a(4),n=a(5),s=a(44),o=a(45),c=a(46),l=a(7),h=function(){function e(e){this.name=e;this.terminated=!1;this._capability=(0,r.createPromiseCapability)()}e.prototype={get finished(){return this._capability.promise},finish(){this._capability.resolve()},terminate(){this.terminated=!0},ensureNotTerminated(){if(this.terminated)throw new Error("Worker task was terminated")}};return e}();t.WorkerTask=h;var u,d={setup(e,t){var a=!1;e.on("test",(function(t){if(a)return;a=!0;if(!(t instanceof Uint8Array)){e.send("test",null);return}const r=255===t[0];e.postMessageTransfers=r;e.send("test",{supportTransfers:r})}));e.on("configure",(function(e){(0,r.setVerbosityLevel)(e.verbosity)}));e.on("GetDocRequest",(function(e){return d.createDocumentHandler(e,t)}))},createDocumentHandler(e,t){var a,s=!1,u=null,d=[];const f=(0,r.getVerbosityLevel)(),g=e.apiVersion;if("2.4.456"!==g)throw new Error(`The API version "${g}" does not match `+'the Worker version "2.4.456".');const m=[];for(const e in[])m.push(e);if(m.length)throw new Error("The `Array.prototype` contains unexpected enumerable properties: "+m.join(", ")+"; thus breaking e.g. `for...in` iteration of `Array`s.");var p=e.docId,b=e.docBaseUrl,y=e.docId+"_worker",v=new o.MessageHandler(y,p,t);v.postMessageTransfers=e.postMessageTransfers;function w(){if(s)throw new Error("Worker was terminated")}function k(e){d.push(e)}function S(e){e.finish();var t=d.indexOf(e);d.splice(t,1)}async function C(e){await a.ensureDoc("checkHeader");await a.ensureDoc("parseStartXRef");await a.ensureDoc("parse",[e]);e||await a.ensureDoc("checkFirstPage");const[t,r]=await Promise.all([a.ensureDoc("numPages"),a.ensureDoc("fingerprint")]);return{numPages:t,fingerprint:r}}function x(e,t){var a,i=(0,r.createPromiseCapability)(),s=e.source;if(s.data){try{a=new n.LocalPdfManager(p,s.data,s.password,t,b);i.resolve(a)}catch(e){i.reject(e)}return i.promise}var o,l=[];try{o=new c.PDFWorkerStream(v)}catch(e){i.reject(e);return i.promise}var h=o.getFullReader();h.headersReady.then((function(){if(h.isRangeSupported){var e=s.disableAutoFetch||h.isStreamingSupported;a=new n.NetworkPdfManager(p,o,{msgHandler:v,password:s.password,length:h.contentLength,disableAutoFetch:e,rangeChunkSize:s.rangeChunkSize},t,b);for(let e=0;e<l.length;e++)a.sendProgressiveData(l[e]);l=[];i.resolve(a);u=null}})).catch((function(e){i.reject(e);u=null}));var d=0;new Promise((function(e,o){var c=function(e){try{w();if(e.done){a||function(){var e=(0,r.arraysToBytes)(l);s.length&&e.length!==s.length&&(0,r.warn)("reported HTTP length is different from actual");try{a=new n.LocalPdfManager(p,e,s.password,t,b);i.resolve(a)}catch(e){i.reject(e)}l=[]}();u=null;return}var f=e.value;d+=(0,r.arrayByteLength)(f);h.isStreamingSupported||v.send("DocProgress",{loaded:d,total:Math.max(d,h.contentLength||0)});a?a.sendProgressiveData(f):l.push(f);h.read().then(c,o)}catch(e){o(e)}};h.read().then(c,o)})).catch((function(e){i.reject(e);u=null}));u=function(e){o.cancelAllRequests(e)};return i.promise}v.on("GetPage",(function(e){return a.getPage(e.pageIndex).then((function(e){return Promise.all([a.ensure(e,"rotate"),a.ensure(e,"ref"),a.ensure(e,"userUnit"),a.ensure(e,"view")]).then((function([e,t,a,r]){return{rotate:e,ref:t,userUnit:a,view:r}}))}))}));v.on("GetPageIndex",(function(e){var t=i.Ref.get(e.ref.num,e.ref.gen);return a.pdfDocument.catalog.getPageIndex(t)}));v.on("GetDestinations",(function(e){return a.ensureCatalog("destinations")}));v.on("GetDestination",(function(e){return a.ensureCatalog("getDestination",[e.id])}));v.on("GetPageLabels",(function(e){return a.ensureCatalog("pageLabels")}));v.on("GetPageLayout",(function(e){return a.ensureCatalog("pageLayout")}));v.on("GetPageMode",(function(e){return a.ensureCatalog("pageMode")}));v.on("GetViewerPreferences",(function(e){return a.ensureCatalog("viewerPreferences")}));v.on("GetOpenAction",(function(e){return a.ensureCatalog("openAction")}));v.on("GetAttachments",(function(e){return a.ensureCatalog("attachments")}));v.on("GetJavaScript",(function(e){return a.ensureCatalog("javaScript")}));v.on("GetOutline",(function(e){return a.ensureCatalog("documentOutline")}));v.on("GetPermissions",(function(e){return a.ensureCatalog("permissions")}));v.on("GetMetadata",(function(e){return Promise.all([a.ensureDoc("documentInfo"),a.ensureCatalog("metadata")])}));v.on("GetData",(function(e){a.requestLoadedStream();return a.onLoadedStream().then((function(e){return e.bytes}))}));v.on("GetStats",(function(e){return a.pdfDocument.xref.stats}));v.on("GetAnnotations",(function({pageIndex:e,intent:t}){return a.getPage(e).then((function(e){return e.getAnnotationsData(t)}))}));v.on("GetOperatorList",(function(e,t){var i=e.pageIndex;a.getPage(i).then((function(a){var n=new h(`GetOperatorList: page ${i}`);k(n);const s=f>=r.VerbosityLevel.INFOS?Date.now():0;a.getOperatorList({handler:v,sink:t,task:n,intent:e.intent,renderInteractiveForms:e.renderInteractiveForms}).then((function(e){S(n);s&&(0,r.info)(`page=${i+1} - getOperatorList: time=`+`${Date.now()-s}ms, len=${e.length}`);t.close()}),(function(e){S(n);if(!n.terminated){v.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});t.error(e)}}))}))}),this);v.on("GetTextContent",(function(e,t){var i=e.pageIndex;t.onPull=function(e){};t.onCancel=function(e){};a.getPage(i).then((function(a){var n=new h("GetTextContent: page "+i);k(n);const s=f>=r.VerbosityLevel.INFOS?Date.now():0;a.extractTextContent({handler:v,task:n,sink:t,normalizeWhitespace:e.normalizeWhitespace,combineTextItems:e.combineTextItems}).then((function(){S(n);s&&(0,r.info)(`page=${i+1} - getTextContent: time=`+`${Date.now()-s}ms`);t.close()}),(function(e){S(n);n.terminated||t.error(e)}))}))}));v.on("FontFallback",(function(e){return a.fontFallback(e.id,v)}));v.on("Cleanup",(function(e){return a.cleanup()}));v.on("Terminate",(function(e){s=!0;const t=[];if(a){a.terminate(new r.AbortException("Worker was terminated."));const e=a.cleanup();t.push(e);a=null}else(0,i.clearPrimitiveCaches)();u&&u(new r.AbortException("Worker was terminated."));d.forEach((function(e){t.push(e.finished);e.terminate()}));return Promise.all(t).then((function(){v.destroy();v=null}))}));v.on("Ready",(function(t){!function(e){function t(e){w();v.send("GetDoc",{pdfInfo:e})}function i(e){w();if(e instanceof r.PasswordException){var t=new h(`PasswordException: response ${e.code}`);k(t);v.sendWithPromise("PasswordRequest",e).then((function(e){S(t);a.updatePassword(e.password);n()})).catch((function(){S(t);v.send("DocException",e)}))}else e instanceof r.InvalidPDFException||e instanceof r.MissingPDFException||e instanceof r.UnexpectedResponseException||e instanceof r.UnknownErrorException?v.send("DocException",e):v.send("DocException",new r.UnknownErrorException(e.message,e.toString()))}function n(){w();C(!1).then(t,(function(e){w();if(e instanceof l.XRefParseException){a.requestLoadedStream();a.onLoadedStream().then((function(){w();C(!0).then(t,i)}))}else i(e)}),i)}w();x(e,{forceDataSchema:e.disableCreateObjectURL,maxImageSize:e.maxImageSize,disableFontFace:e.disableFontFace,nativeImageDecoderSupport:e.nativeImageDecoderSupport,ignoreErrors:e.ignoreErrors,isEvalSupported:e.isEvalSupported}).then((function(e){if(s){e.terminate(new r.AbortException("Worker was terminated."));throw new Error("Worker was terminated")}(a=e).onLoadedStream().then((function(e){v.send("DataLoaded",{length:e.bytes.byteLength})}))})).then(n,i)}(e);e=null}));return y},initializeFromPort(e){var t=new o.MessageHandler("worker","main",e);d.setup(t,e);t.send("ready",null)}};t.WorkerMessageHandler=d;"undefined"==typeof window&&!s.isNodeJS&&"undefined"!=typeof self&&("function"==typeof(u=self).postMessage&&"onmessage"in u)&&d.initializeFromPort(self)},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.arrayByteLength=d;t.arraysToBytes=function(e){const t=e.length;if(1===t&&e[0]instanceof Uint8Array)return e[0];let a=0;for(let r=0;r<t;r++)a+=d(e[r]);let r=0;const i=new Uint8Array(a);for(let a=0;a<t;a++){let t=e[a];t instanceof Uint8Array||(t="string"==typeof t?u(t):new Uint8Array(t));const n=t.byteLength;i.set(t,r);r+=n}return i};t.assert=o;t.bytesToString=function(e){o(null!==e&&"object"==typeof e&&void 0!==e.length,"Invalid argument for bytesToString");const t=e.length;if(t<8192)return String.fromCharCode.apply(null,e);const a=[];for(let r=0;r<t;r+=8192){const i=Math.min(r+8192,t),n=e.subarray(r,i);a.push(String.fromCharCode.apply(null,n))}return a.join("")};t.createPromiseCapability=function(){const e=Object.create(null);let t=!1;Object.defineProperty(e,"settled",{get:()=>t});e.promise=new Promise((function(a,r){e.resolve=function(e){t=!0;a(e)};e.reject=function(e){t=!0;r(e)}}));return e};t.getVerbosityLevel=function(){return i};t.info=function(e){i>=r.INFOS&&console.log(`Info: ${e}`)};t.isArrayBuffer=function(e){return"object"==typeof e&&null!==e&&void 0!==e.byteLength};t.isArrayEqual=function(e,t){if(e.length!==t.length)return!1;return e.every((function(e,a){return e===t[a]}))};t.isBool=function(e){return"boolean"==typeof e};t.isEmptyObj=function(e){for(const t in e)return!1;return!0};t.isNum=function(e){return"number"==typeof e};t.isString=function(e){return"string"==typeof e};t.isSameOrigin=function(e,t){let a;try{a=new URL(e);if(!a.origin||"null"===a.origin)return!1}catch(e){return!1}const r=new URL(t,a);return a.origin===r.origin};t.createValidAbsoluteUrl=function(e,t){if(!e)return null;try{const a=t?new URL(e,t):new URL(e);if(function(e){if(!e)return!1;switch(e.protocol){case"http:":case"https:":case"ftp:":case"mailto:":case"tel:":return!0;default:return!1}}(a))return a}catch(e){}return null};t.removeNullCharacters=function(e){if("string"!=typeof e){n("The argument for removeNullCharacters must be a string.");return e}return e.replace(h,"")};t.setVerbosityLevel=function(e){Number.isInteger(e)&&(i=e)};t.shadow=c;t.string32=function(e){return String.fromCharCode(e>>24&255,e>>16&255,e>>8&255,255&e)};t.stringToBytes=u;t.stringToPDFString=function(e){const t=e.length,a=[];if("þ"===e[0]&&"ÿ"===e[1])for(let r=2;r<t;r+=2)a.push(String.fromCharCode(e.charCodeAt(r)<<8|e.charCodeAt(r+1)));else if("ÿ"===e[0]&&"þ"===e[1])for(let r=2;r<t;r+=2)a.push(String.fromCharCode(e.charCodeAt(r+1)<<8|e.charCodeAt(r)));else for(let r=0;r<t;++r){const t=b[e.charCodeAt(r)];a.push(t?String.fromCharCode(t):e.charAt(r))}return a.join("")};t.stringToUTF8String=function(e){return decodeURIComponent(escape(e))};t.utf8StringToString=function(e){return unescape(encodeURIComponent(e))};t.warn=n;t.unreachable=s;t.IsEvalSupportedCached=t.IsLittleEndianCached=t.createObjectURL=t.FormatError=t.Util=t.UnknownErrorException=t.UnexpectedResponseException=t.TextRenderingMode=t.StreamType=t.PermissionFlag=t.PasswordResponses=t.PasswordException=t.NativeImageDecoding=t.MissingPDFException=t.InvalidPDFException=t.AbortException=t.CMapCompressionType=t.ImageKind=t.FontType=t.AnnotationType=t.AnnotationStateModelType=t.AnnotationReviewState=t.AnnotationReplyType=t.AnnotationMarkedState=t.AnnotationFlag=t.AnnotationFieldFlag=t.AnnotationBorderStyleType=t.UNSUPPORTED_FEATURES=t.VerbosityLevel=t.OPS=t.IDENTITY_MATRIX=t.FONT_IDENTITY_MATRIX=t.BaseException=void 0;a(3);t.IDENTITY_MATRIX=[1,0,0,1,0,0];t.FONT_IDENTITY_MATRIX=[.001,0,0,.001,0,0];t.NativeImageDecoding={NONE:"none",DECODE:"decode",DISPLAY:"display"};t.PermissionFlag={PRINT:4,MODIFY_CONTENTS:8,COPY:16,MODIFY_ANNOTATIONS:32,FILL_INTERACTIVE_FORMS:256,COPY_FOR_ACCESSIBILITY:512,ASSEMBLE:1024,PRINT_HIGH_QUALITY:2048};t.TextRenderingMode={FILL:0,STROKE:1,FILL_STROKE:2,INVISIBLE:3,FILL_ADD_TO_PATH:4,STROKE_ADD_TO_PATH:5,FILL_STROKE_ADD_TO_PATH:6,ADD_TO_PATH:7,FILL_STROKE_MASK:3,ADD_TO_PATH_FLAG:4};t.ImageKind={GRAYSCALE_1BPP:1,RGB_24BPP:2,RGBA_32BPP:3};t.AnnotationType={TEXT:1,LINK:2,FREETEXT:3,LINE:4,SQUARE:5,CIRCLE:6,POLYGON:7,POLYLINE:8,HIGHLIGHT:9,UNDERLINE:10,SQUIGGLY:11,STRIKEOUT:12,STAMP:13,CARET:14,INK:15,POPUP:16,FILEATTACHMENT:17,SOUND:18,MOVIE:19,WIDGET:20,SCREEN:21,PRINTERMARK:22,TRAPNET:23,WATERMARK:24,THREED:25,REDACT:26};t.AnnotationStateModelType={MARKED:"Marked",REVIEW:"Review"};t.AnnotationMarkedState={MARKED:"Marked",UNMARKED:"Unmarked"};t.AnnotationReviewState={ACCEPTED:"Accepted",REJECTED:"Rejected",CANCELLED:"Cancelled",COMPLETED:"Completed",NONE:"None"};t.AnnotationReplyType={GROUP:"Group",REPLY:"R"};t.AnnotationFlag={INVISIBLE:1,HIDDEN:2,PRINT:4,NOZOOM:8,NOROTATE:16,NOVIEW:32,READONLY:64,LOCKED:128,TOGGLENOVIEW:256,LOCKEDCONTENTS:512};t.AnnotationFieldFlag={READONLY:1,REQUIRED:2,NOEXPORT:4,MULTILINE:4096,PASSWORD:8192,NOTOGGLETOOFF:16384,RADIO:32768,PUSHBUTTON:65536,COMBO:131072,EDIT:262144,SORT:524288,FILESELECT:1048576,MULTISELECT:2097152,DONOTSPELLCHECK:4194304,DONOTSCROLL:8388608,COMB:16777216,RICHTEXT:33554432,RADIOSINUNISON:33554432,COMMITONSELCHANGE:67108864};t.AnnotationBorderStyleType={SOLID:1,DASHED:2,BEVELED:3,INSET:4,UNDERLINE:5};t.StreamType={UNKNOWN:"UNKNOWN",FLATE:"FLATE",LZW:"LZW",DCT:"DCT",JPX:"JPX",JBIG:"JBIG",A85:"A85",AHX:"AHX",CCF:"CCF",RLX:"RLX"};t.FontType={UNKNOWN:"UNKNOWN",TYPE1:"TYPE1",TYPE1C:"TYPE1C",CIDFONTTYPE0:"CIDFONTTYPE0",CIDFONTTYPE0C:"CIDFONTTYPE0C",TRUETYPE:"TRUETYPE",CIDFONTTYPE2:"CIDFONTTYPE2",TYPE3:"TYPE3",OPENTYPE:"OPENTYPE",TYPE0:"TYPE0",MMTYPE1:"MMTYPE1"};const r={ERRORS:0,WARNINGS:1,INFOS:5};t.VerbosityLevel=r;t.CMapCompressionType={NONE:0,BINARY:1,STREAM:2};t.OPS={dependency:1,setLineWidth:2,setLineCap:3,setLineJoin:4,setMiterLimit:5,setDash:6,setRenderingIntent:7,setFlatness:8,setGState:9,save:10,restore:11,transform:12,moveTo:13,lineTo:14,curveTo:15,curveTo2:16,curveTo3:17,closePath:18,rectangle:19,stroke:20,closeStroke:21,fill:22,eoFill:23,fillStroke:24,eoFillStroke:25,closeFillStroke:26,closeEOFillStroke:27,endPath:28,clip:29,eoClip:30,beginText:31,endText:32,setCharSpacing:33,setWordSpacing:34,setHScale:35,setLeading:36,setFont:37,setTextRenderingMode:38,setTextRise:39,moveText:40,setLeadingMoveText:41,setTextMatrix:42,nextLine:43,showText:44,showSpacedText:45,nextLineShowText:46,nextLineSetSpacingShowText:47,setCharWidth:48,setCharWidthAndBounds:49,setStrokeColorSpace:50,setFillColorSpace:51,setStrokeColor:52,setStrokeColorN:53,setFillColor:54,setFillColorN:55,setStrokeGray:56,setFillGray:57,setStrokeRGBColor:58,setFillRGBColor:59,setStrokeCMYKColor:60,setFillCMYKColor:61,shadingFill:62,beginInlineImage:63,beginImageData:64,endInlineImage:65,paintXObject:66,markPoint:67,markPointProps:68,beginMarkedContent:69,beginMarkedContentProps:70,endMarkedContent:71,beginCompat:72,endCompat:73,paintFormXObjectBegin:74,paintFormXObjectEnd:75,beginGroup:76,endGroup:77,beginAnnotations:78,endAnnotations:79,beginAnnotation:80,endAnnotation:81,paintJpegXObject:82,paintImageMaskXObject:83,paintImageMaskXObjectGroup:84,paintImageXObject:85,paintInlineImageXObject:86,paintInlineImageXObjectGroup:87,paintImageXObjectRepeat:88,paintImageMaskXObjectRepeat:89,paintSolidColorImageMask:90,constructPath:91};t.UNSUPPORTED_FEATURES={unknown:"unknown",forms:"forms",javaScript:"javaScript",smask:"smask",shadingPattern:"shadingPattern",font:"font"};t.PasswordResponses={NEED_PASSWORD:1,INCORRECT_PASSWORD:2};let i=r.WARNINGS;function n(e){i>=r.WARNINGS&&console.log(`Warning: ${e}`)}function s(e){throw new Error(e)}function o(e,t){e||s(t)}function c(e,t,a){Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!1});return a}const l=function(){function e(t){this.constructor===e&&s("Cannot initialize BaseException.");this.message=t;this.name=this.constructor.name}e.prototype=new Error;e.constructor=e;return e}();t.BaseException=l;t.PasswordException=class extends l{constructor(e,t){super(e);this.code=t}};t.UnknownErrorException=class extends l{constructor(e,t){super(e);this.details=t}};t.InvalidPDFException=class extends l{};t.MissingPDFException=class extends l{};t.UnexpectedResponseException=class extends l{constructor(e,t){super(e);this.status=t}};t.FormatError=class extends l{};t.AbortException=class extends l{};const h=/\x00/g;function u(e){o("string"==typeof e,"Invalid argument for stringToBytes");const t=e.length,a=new Uint8Array(t);for(let r=0;r<t;++r)a[r]=255&e.charCodeAt(r);return a}function d(e){if(void 0!==e.length)return e.length;o(void 0!==e.byteLength);return e.byteLength}const f={get value(){return c(this,"value",function(){const e=new Uint8Array(4);e[0]=1;return 1===new Uint32Array(e.buffer,0,1)[0]}())}};t.IsLittleEndianCached=f;const g={get value(){return c(this,"value",function(){try{new Function("");return!0}catch(e){return!1}}())}};t.IsEvalSupportedCached=g;const m=["rgb(",0,",",0,",",0,")"];class p{static makeCssRgb(e,t,a){m[1]=e;m[3]=t;m[5]=a;return m.join("")}static transform(e,t){return[e[0]*t[0]+e[2]*t[1],e[1]*t[0]+e[3]*t[1],e[0]*t[2]+e[2]*t[3],e[1]*t[2]+e[3]*t[3],e[0]*t[4]+e[2]*t[5]+e[4],e[1]*t[4]+e[3]*t[5]+e[5]]}static applyTransform(e,t){return[e[0]*t[0]+e[1]*t[2]+t[4],e[0]*t[1]+e[1]*t[3]+t[5]]}static applyInverseTransform(e,t){const a=t[0]*t[3]-t[1]*t[2];return[(e[0]*t[3]-e[1]*t[2]+t[2]*t[5]-t[4]*t[3])/a,(-e[0]*t[1]+e[1]*t[0]+t[4]*t[1]-t[5]*t[0])/a]}static getAxialAlignedBoundingBox(e,t){const a=p.applyTransform(e,t),r=p.applyTransform(e.slice(2,4),t),i=p.applyTransform([e[0],e[3]],t),n=p.applyTransform([e[2],e[1]],t);return[Math.min(a[0],r[0],i[0],n[0]),Math.min(a[1],r[1],i[1],n[1]),Math.max(a[0],r[0],i[0],n[0]),Math.max(a[1],r[1],i[1],n[1])]}static inverseTransform(e){const t=e[0]*e[3]-e[1]*e[2];return[e[3]/t,-e[1]/t,-e[2]/t,e[0]/t,(e[2]*e[5]-e[4]*e[3])/t,(e[4]*e[1]-e[5]*e[0])/t]}static apply3dTransform(e,t){return[e[0]*t[0]+e[1]*t[1]+e[2]*t[2],e[3]*t[0]+e[4]*t[1]+e[5]*t[2],e[6]*t[0]+e[7]*t[1]+e[8]*t[2]]}static singularValueDecompose2dScale(e){const t=[e[0],e[2],e[1],e[3]],a=e[0]*t[0]+e[1]*t[2],r=e[0]*t[1]+e[1]*t[3],i=e[2]*t[0]+e[3]*t[2],n=e[2]*t[1]+e[3]*t[3],s=(a+n)/2,o=Math.sqrt((a+n)*(a+n)-4*(a*n-i*r))/2,c=s+o||1,l=s-o||1;return[Math.sqrt(c),Math.sqrt(l)]}static normalizeRect(e){const t=e.slice(0);if(e[0]>e[2]){t[0]=e[2];t[2]=e[0]}if(e[1]>e[3]){t[1]=e[3];t[3]=e[1]}return t}static intersect(e,t){function a(e,t){return e-t}const r=[e[0],e[2],t[0],t[2]].sort(a),i=[e[1],e[3],t[1],t[3]].sort(a),n=[];e=p.normalizeRect(e);t=p.normalizeRect(t);if(!(r[0]===e[0]&&r[1]===t[0]||r[0]===t[0]&&r[1]===e[0]))return null;n[0]=r[1];n[2]=r[2];if(!(i[0]===e[1]&&i[1]===t[1]||i[0]===t[1]&&i[1]===e[1]))return null;n[1]=i[1];n[3]=i[2];return n}}t.Util=p;const b=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,728,711,710,729,733,731,730,732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8226,8224,8225,8230,8212,8211,402,8260,8249,8250,8722,8240,8222,8220,8221,8216,8217,8218,8482,64257,64258,321,338,352,376,381,305,322,339,353,382,0,8364];const y=function(){const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return function(t,a,r=!1){if(!r&&URL.createObjectURL){const e=new Blob([t],{type:a});return URL.createObjectURL(e)}let i=`data:${a};base64,`;for(let a=0,r=t.length;a<r;a+=3){const n=255&t[a],s=255&t[a+1],o=255&t[a+2];i+=e[n>>2]+e[(3&n)<<4|s>>4]+e[a+1<r?(15&s)<<2|o>>6:64]+e[a+2<r?63&o:64]}return i}}();t.createObjectURL=y},function(e,t,a){},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.clearPrimitiveCaches=function(){n._clearCache();i._clearCache();o._clearCache()};t.isEOF=function(e){return e===r};t.isCmd=function(e,t){return e instanceof n&&(void 0===t||e.cmd===t)};t.isDict=u;t.isName=h;t.isRef=function(e){return e instanceof o};t.isRefsEqual=function(e,t){return e.num===t.num&&e.gen===t.gen};t.isStream=function(e){return"object"==typeof e&&null!==e&&void 0!==e.getBytes};t.RefSetCache=t.RefSet=t.Ref=t.Name=t.Dict=t.Cmd=t.EOF=void 0;a(2);var r={};t.EOF=r;var i=function(){let e=Object.create(null);function t(e){this.name=e}t.prototype={};t.get=function(a){var r=e[a];return r||(e[a]=new t(a))};t._clearCache=function(){e=Object.create(null)};return t}();t.Name=i;var n=function(){let e=Object.create(null);function t(e){this.cmd=e}t.prototype={};t.get=function(a){var r=e[a];return r||(e[a]=new t(a))};t._clearCache=function(){e=Object.create(null)};return t}();t.Cmd=n;var s=function(){var e=function(){return e};function t(t){this._map=Object.create(null);this.xref=t;this.objId=null;this.suppressEncryption=!1;this.__nonSerializable__=e}t.prototype={assignXref:function(e){this.xref=e},get(e,t,a){let r=this._map[e];if(void 0===r&&void 0!==t){r=this._map[t];void 0===r&&void 0!==a&&(r=this._map[a])}return r instanceof o&&this.xref?this.xref.fetch(r,this.suppressEncryption):r},async getAsync(e,t,a){let r=this._map[e];if(void 0===r&&void 0!==t){r=this._map[t];void 0===r&&void 0!==a&&(r=this._map[a])}return r instanceof o&&this.xref?this.xref.fetchAsync(r,this.suppressEncryption):r},getArray(e,t,a){let r=this.get(e,t,a);if(!Array.isArray(r)||!this.xref)return r;r=r.slice();for(let e=0,t=r.length;e<t;e++)r[e]instanceof o&&(r[e]=this.xref.fetch(r[e],this.suppressEncryption));return r},getRaw:function(e){return this._map[e]},getKeys:function(){return Object.keys(this._map)},set:function(e,t){this._map[e]=t},has:function(e){return void 0!==this._map[e]},forEach:function(e){for(var t in this._map)e(t,this.get(t))}};t.empty=new t(null);t.merge=function(e,a){const r=new t(e);for(let e=0,t=a.length;e<t;e++){const t=a[e];if(u(t))for(const e in t._map)void 0===r._map[e]&&(r._map[e]=t._map[e])}return r};return t}();t.Dict=s;var o=function(){let e=Object.create(null);function t(e,t){this.num=e;this.gen=t}t.prototype={toString:function(){return 0===this.gen?`${this.num}R`:`${this.num}R${this.gen}`}};t.get=function(a,r){const i=0===r?`${a}R`:`${a}R${r}`,n=e[i];return n||(e[i]=new t(a,r))};t._clearCache=function(){e=Object.create(null)};return t}();t.Ref=o;var c=function(){function e(){this.dict=Object.create(null)}e.prototype={has:function(e){return e.toString()in this.dict},put:function(e){this.dict[e.toString()]=!0},remove:function(e){delete this.dict[e.toString()]}};return e}();t.RefSet=c;var l=function(){function e(){this.dict=Object.create(null)}e.prototype={get:function(e){return this.dict[e.toString()]},has:function(e){return e.toString()in this.dict},put:function(e,t){this.dict[e.toString()]=t},putAlias:function(e,t){this.dict[e.toString()]=this.get(t)},forEach:function(e){for(const t in this.dict)e(this.dict[t])},clear:function(){this.dict=Object.create(null)}};return e}();t.RefSetCache=l;function h(e,t){return e instanceof i&&(void 0===t||e.name===t)}function u(e,t){return e instanceof s&&(void 0===t||h(e.get("Type"),t))}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.NetworkPdfManager=t.LocalPdfManager=void 0;var r=a(2),i=a(6),n=a(7),s=a(8),o=a(11);class c{constructor(){this.constructor===c&&(0,r.unreachable)("Cannot initialize BasePdfManager.")}get docId(){return this._docId}get password(){return this._password}get docBaseUrl(){let e=null;if(this._docBaseUrl){const t=(0,r.createValidAbsoluteUrl)(this._docBaseUrl);t?e=t.href:(0,r.warn)(`Invalid absolute docBaseUrl: "${this._docBaseUrl}".`)}return(0,r.shadow)(this,"docBaseUrl",e)}onLoadedStream(){(0,r.unreachable)("Abstract method `onLoadedStream` called")}ensureDoc(e,t){return this.ensure(this.pdfDocument,e,t)}ensureXRef(e,t){return this.ensure(this.pdfDocument.xref,e,t)}ensureCatalog(e,t){return this.ensure(this.pdfDocument.catalog,e,t)}getPage(e){return this.pdfDocument.getPage(e)}fontFallback(e,t){return this.pdfDocument.fontFallback(e,t)}cleanup(){return this.pdfDocument.cleanup()}async ensure(e,t,a){(0,r.unreachable)("Abstract method `ensure` called")}requestRange(e,t){(0,r.unreachable)("Abstract method `requestRange` called")}requestLoadedStream(){(0,r.unreachable)("Abstract method `requestLoadedStream` called")}sendProgressiveData(e){(0,r.unreachable)("Abstract method `sendProgressiveData` called")}updatePassword(e){this._password=e}terminate(e){(0,r.unreachable)("Abstract method `terminate` called")}}t.LocalPdfManager=class extends c{constructor(e,t,a,r,i){super();this._docId=e;this._password=a;this._docBaseUrl=i;this.evaluatorOptions=r;const n=new o.Stream(t);this.pdfDocument=new s.PDFDocument(this,n);this._loadedStreamPromise=Promise.resolve(n)}async ensure(e,t,a){const r=e[t];return"function"==typeof r?r.apply(e,a):r}requestRange(e,t){return Promise.resolve()}requestLoadedStream(){}onLoadedStream(){return this._loadedStreamPromise}terminate(e){}};t.NetworkPdfManager=class extends c{constructor(e,t,a,r,n){super();this._docId=e;this._password=a.password;this._docBaseUrl=n;this.msgHandler=a.msgHandler;this.evaluatorOptions=r;this.streamManager=new i.ChunkedStreamManager(t,{msgHandler:a.msgHandler,length:a.length,disableAutoFetch:a.disableAutoFetch,rangeChunkSize:a.rangeChunkSize});this.pdfDocument=new s.PDFDocument(this,this.streamManager.getStream())}async ensure(e,t,a){try{const r=e[t];return"function"==typeof r?r.apply(e,a):r}catch(r){if(!(r instanceof n.MissingDataException))throw r;await this.requestRange(r.begin,r.end);return this.ensure(e,t,a)}}requestRange(e,t){return this.streamManager.requestRange(e,t)}requestLoadedStream(){this.streamManager.requestAllChunks()}sendProgressiveData(e){this.streamManager.onReceiveData({chunk:e})}onLoadedStream(){return this.streamManager.onLoadedStream()}terminate(e){this.streamManager.abort(e)}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.ChunkedStreamManager=t.ChunkedStream=void 0;var r=a(2),i=a(7);class n{constructor(e,t,a){this.bytes=new Uint8Array(e);this.start=0;this.pos=0;this.end=e;this.chunkSize=t;this.loadedChunks=[];this.numChunksLoaded=0;this.numChunks=Math.ceil(e/t);this.manager=a;this.progressiveDataLength=0;this.lastSuccessfulEnsureByteChunk=-1}getMissingChunks(){const e=[];for(let t=0,a=this.numChunks;t<a;++t)this.loadedChunks[t]||e.push(t);return e}getBaseStreams(){return[this]}allChunksLoaded(){return this.numChunksLoaded===this.numChunks}onReceiveData(e,t){const a=this.chunkSize;if(e%a!=0)throw new Error(`Bad begin offset: ${e}`);const r=e+t.byteLength;if(r%a!=0&&r!==this.bytes.length)throw new Error(`Bad end offset: ${r}`);this.bytes.set(new Uint8Array(t),e);const i=Math.floor(e/a),n=Math.floor((r-1)/a)+1;for(let e=i;e<n;++e)if(!this.loadedChunks[e]){this.loadedChunks[e]=!0;++this.numChunksLoaded}}onReceiveProgressiveData(e){let t=this.progressiveDataLength;const a=Math.floor(t/this.chunkSize);this.bytes.set(new Uint8Array(e),t);t+=e.byteLength;this.progressiveDataLength=t;const r=t>=this.end?this.numChunks:Math.floor(t/this.chunkSize);for(let e=a;e<r;++e)if(!this.loadedChunks[e]){this.loadedChunks[e]=!0;++this.numChunksLoaded}}ensureByte(e){if(e<this.progressiveDataLength)return;const t=Math.floor(e/this.chunkSize);if(t!==this.lastSuccessfulEnsureByteChunk){if(!this.loadedChunks[t])throw new i.MissingDataException(e,e+1);this.lastSuccessfulEnsureByteChunk=t}}ensureRange(e,t){if(e>=t)return;if(t<=this.progressiveDataLength)return;const a=this.chunkSize,r=Math.floor(e/a),n=Math.floor((t-1)/a)+1;for(let a=r;a<n;++a)if(!this.loadedChunks[a])throw new i.MissingDataException(e,t)}nextEmptyChunk(e){const t=this.numChunks;for(let a=0;a<t;++a){const r=(e+a)%t;if(!this.loadedChunks[r])return r}return null}hasChunk(e){return!!this.loadedChunks[e]}get length(){return this.end-this.start}get isEmpty(){return 0===this.length}getByte(){const e=this.pos;if(e>=this.end)return-1;e>=this.progressiveDataLength&&this.ensureByte(e);return this.bytes[this.pos++]}getUint16(){const e=this.getByte(),t=this.getByte();return-1===e||-1===t?-1:(e<<8)+t}getInt32(){return(this.getByte()<<24)+(this.getByte()<<16)+(this.getByte()<<8)+this.getByte()}getBytes(e,t=!1){const a=this.bytes,r=this.pos,i=this.end;if(!e){i>this.progressiveDataLength&&this.ensureRange(r,i);const e=a.subarray(r,i);return t?new Uint8ClampedArray(e):e}let n=r+e;n>i&&(n=i);n>this.progressiveDataLength&&this.ensureRange(r,n);this.pos=n;const s=a.subarray(r,n);return t?new Uint8ClampedArray(s):s}peekByte(){const e=this.getByte();-1!==e&&this.pos--;return e}peekBytes(e,t=!1){const a=this.getBytes(e,t);this.pos-=a.length;return a}getByteRange(e,t){e<0&&(e=0);t>this.end&&(t=this.end);t>this.progressiveDataLength&&this.ensureRange(e,t);return this.bytes.subarray(e,t)}skip(e){e||(e=1);this.pos+=e}reset(){this.pos=this.start}moveStart(){this.start=this.pos}makeSubStream(e,t,a){t?e+t>this.progressiveDataLength&&this.ensureRange(e,e+t):e>=this.progressiveDataLength&&this.ensureByte(e);function r(){}r.prototype=Object.create(this);r.prototype.getMissingChunks=function(){const e=this.chunkSize,t=Math.floor(this.start/e),a=Math.floor((this.end-1)/e)+1,r=[];for(let e=t;e<a;++e)this.loadedChunks[e]||r.push(e);return r};r.prototype.allChunksLoaded=function(){return this.numChunksLoaded===this.numChunks||0===this.getMissingChunks().length};const i=new r;i.pos=i.start=e;i.end=e+t||this.end;i.dict=a;return i}}t.ChunkedStream=n;t.ChunkedStreamManager=class{constructor(e,t){this.length=t.length;this.chunkSize=t.rangeChunkSize;this.stream=new n(this.length,this.chunkSize,this);this.pdfNetworkStream=e;this.disableAutoFetch=t.disableAutoFetch;this.msgHandler=t.msgHandler;this.currRequestId=0;this.chunksNeededByRequest=Object.create(null);this.requestsByChunk=Object.create(null);this.promisesByRequest=Object.create(null);this.progressiveDataLength=0;this.aborted=!1;this._loadedStreamCapability=(0,r.createPromiseCapability)()}onLoadedStream(){return this._loadedStreamCapability.promise}sendRequest(e,t){const a=this.pdfNetworkStream.getRangeReader(e,t);a.isStreamingSupported||(a.onProgress=this.onProgress.bind(this));let i=[],n=0;new Promise((e,t)=>{const s=o=>{try{if(!o.done){const e=o.value;i.push(e);n+=(0,r.arrayByteLength)(e);a.isStreamingSupported&&this.onProgress({loaded:n});a.read().then(s,t);return}const c=(0,r.arraysToBytes)(i);i=null;e(c)}catch(e){t(e)}};a.read().then(s,t)}).then(t=>{this.aborted||this.onReceiveData({chunk:t,begin:e})})}requestAllChunks(){const e=this.stream.getMissingChunks();this._requestChunks(e);return this._loadedStreamCapability.promise}_requestChunks(e){const t=this.currRequestId++,a=Object.create(null);this.chunksNeededByRequest[t]=a;for(const t of e)this.stream.hasChunk(t)||(a[t]=!0);if((0,r.isEmptyObj)(a))return Promise.resolve();const i=(0,r.createPromiseCapability)();this.promisesByRequest[t]=i;const n=[];for(let e in a){e|=0;if(!(e in this.requestsByChunk)){this.requestsByChunk[e]=[];n.push(e)}this.requestsByChunk[e].push(t)}if(!n.length)return i.promise;const s=this.groupChunks(n);for(const e of s){const t=e.beginChunk*this.chunkSize,a=Math.min(e.endChunk*this.chunkSize,this.length);this.sendRequest(t,a)}return i.promise}getStream(){return this.stream}requestRange(e,t){t=Math.min(t,this.length);const a=this.getBeginChunk(e),r=this.getEndChunk(t),i=[];for(let e=a;e<r;++e)i.push(e);return this._requestChunks(i)}requestRanges(e=[]){const t=[];for(const a of e){const e=this.getBeginChunk(a.begin),r=this.getEndChunk(a.end);for(let a=e;a<r;++a)t.includes(a)||t.push(a)}t.sort((function(e,t){return e-t}));return this._requestChunks(t)}groupChunks(e){const t=[];let a=-1,r=-1;for(let i=0,n=e.length;i<n;++i){const n=e[i];a<0&&(a=n);if(r>=0&&r+1!==n){t.push({beginChunk:a,endChunk:r+1});a=n}i+1===e.length&&t.push({beginChunk:a,endChunk:n+1});r=n}return t}onProgress(e){this.msgHandler.send("DocProgress",{loaded:this.stream.numChunksLoaded*this.chunkSize+e.loaded,total:this.length})}onReceiveData(e){const t=e.chunk,a=void 0===e.begin,i=a?this.progressiveDataLength:e.begin,n=i+t.byteLength,s=Math.floor(i/this.chunkSize),o=n<this.length?Math.floor(n/this.chunkSize):Math.ceil(n/this.chunkSize);if(a){this.stream.onReceiveProgressiveData(t);this.progressiveDataLength=n}else this.stream.onReceiveData(i,t);this.stream.allChunksLoaded()&&this._loadedStreamCapability.resolve(this.stream);const c=[];for(let e=s;e<o;++e){const t=this.requestsByChunk[e]||[];delete this.requestsByChunk[e];for(const a of t){const t=this.chunksNeededByRequest[a];e in t&&delete t[e];(0,r.isEmptyObj)(t)&&c.push(a)}}if(!this.disableAutoFetch&&(0,r.isEmptyObj)(this.requestsByChunk)){let e;if(1===this.stream.numChunksLoaded){const t=this.stream.numChunks-1;this.stream.hasChunk(t)||(e=t)}else e=this.stream.nextEmptyChunk(o);Number.isInteger(e)&&this._requestChunks([e])}for(const e of c){const t=this.promisesByRequest[e];delete this.promisesByRequest[e];t.resolve()}this.msgHandler.send("DocProgress",{loaded:this.stream.numChunksLoaded*this.chunkSize,total:this.length})}onError(e){this._loadedStreamCapability.reject(e)}getBeginChunk(e){return Math.floor(e/this.chunkSize)}getEndChunk(e){return Math.floor((e-1)/this.chunkSize)+1}abort(e){this.aborted=!0;this.pdfNetworkStream&&this.pdfNetworkStream.cancelAllRequests(e);for(const t in this.promisesByRequest)this.promisesByRequest[t].reject(e)}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getLookupTableFactory=function(e){let t;return function(){if(e){t=Object.create(null);e(t);e=null}return t}};t.getInheritableProperty=function({dict:e,key:t,getArray:a=!1,stopWhenFound:i=!0}){let n,s=0;for(;e;){const o=a?e.getArray(t):e.get(t);if(void 0!==o){if(i)return o;n||(n=[]);n.push(o)}if(++s>100){(0,r.warn)(`getInheritableProperty: maximum loop count exceeded for "${t}"`);break}e=e.get("Parent")}return n};t.toRomanNumerals=function(e,t=!1){(0,r.assert)(Number.isInteger(e)&&e>0,"The number should be a positive integer.");const a=[];let i;for(;e>=1e3;){e-=1e3;a.push("M")}i=e/100|0;e%=100;a.push(o[i]);i=e/10|0;e%=10;a.push(o[10+i]);a.push(o[20+e]);const n=a.join("");return t?n.toLowerCase():n};t.log2=function(e){if(e<=0)return 0;return Math.ceil(Math.log2(e))};t.readInt8=function(e,t){return e[t]<<24>>24};t.readUint16=function(e,t){return e[t]<<8|e[t+1]};t.readUint32=function(e,t){return(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])>>>0};t.isWhiteSpace=function(e){return 32===e||9===e||13===e||10===e};t.XRefParseException=t.XRefEntryException=t.MissingDataException=void 0;var r=a(2);class i extends r.BaseException{constructor(e,t){super(`Missing data [${e}, ${t})`);this.begin=e;this.end=t}}t.MissingDataException=i;class n extends r.BaseException{}t.XRefEntryException=n;class s extends r.BaseException{}t.XRefParseException=s;const o=["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM","","X","XX","XXX","XL","L","LX","LXX","LXXX","XC","","I","II","III","IV","V","VI","VII","VIII","IX"]},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PDFDocument=t.Page=void 0;var r=a(2),i=a(9),n=a(4),s=a(7),o=a(11),c=a(23),l=a(21),h=a(10),u=a(24),d=a(25),f=a(39);const g=[0,0,612,792];function m(e,t){return"display"===t&&e.viewable||"print"===t&&e.printable}class p{constructor({pdfManager:e,xref:t,pageIndex:a,pageDict:r,ref:i,fontCache:n,builtInCMapCache:s,pdfFunctionFactory:o}){this.pdfManager=e;this.pageIndex=a;this.pageDict=r;this.xref=t;this.ref=i;this.fontCache=n;this.builtInCMapCache=s;this.pdfFunctionFactory=o;this.evaluatorOptions=e.evaluatorOptions;this.resourcesPromise=null;const c={obj:0};this.idFactory={createObjId:()=>`p${a}_${++c.obj}`,getDocId:()=>`g_${e.docId}`}}_getInheritableProperty(e,t=!1){const a=(0,s.getInheritableProperty)({dict:this.pageDict,key:e,getArray:t,stopWhenFound:!1});return Array.isArray(a)?1!==a.length&&(0,n.isDict)(a[0])?n.Dict.merge(this.xref,a):a[0]:a}get content(){return this.pageDict.get("Contents")}get resources(){return(0,r.shadow)(this,"resources",this._getInheritableProperty("Resources")||n.Dict.empty)}_getBoundingBox(e){const t=this._getInheritableProperty(e,!0);if(Array.isArray(t)&&4===t.length){if(t[2]-t[0]!=0&&t[3]-t[1]!=0)return t;(0,r.warn)(`Empty /${e} entry.`)}return null}get mediaBox(){return(0,r.shadow)(this,"mediaBox",this._getBoundingBox("MediaBox")||g)}get cropBox(){return(0,r.shadow)(this,"cropBox",this._getBoundingBox("CropBox")||this.mediaBox)}get userUnit(){let e=this.pageDict.get("UserUnit");(!(0,r.isNum)(e)||e<=0)&&(e=1);return(0,r.shadow)(this,"userUnit",e)}get view(){const{cropBox:e,mediaBox:t}=this;let a;if(e===t||(0,r.isArrayEqual)(e,t))a=t;else{const i=r.Util.intersect(e,t);i&&i[2]-i[0]!=0&&i[3]-i[1]!=0?a=i:(0,r.warn)("Empty /CropBox and /MediaBox intersection.")}return(0,r.shadow)(this,"view",a||t)}get rotate(){let e=this._getInheritableProperty("Rotate")||0;e%90!=0?e=0:e>=360?e%=360:e<0&&(e=(e%360+360)%360);return(0,r.shadow)(this,"rotate",e)}getContentStream(){const e=this.content;let t;if(Array.isArray(e)){const a=this.xref,r=[];for(const t of e)r.push(a.fetchIfRef(t));t=new o.StreamsSequenceStream(r)}else t=(0,n.isStream)(e)?e:new o.NullStream;return t}loadResources(e){this.resourcesPromise||(this.resourcesPromise=this.pdfManager.ensure(this,"resources"));return this.resourcesPromise.then(()=>new i.ObjectLoader(this.resources,e,this.xref).load())}getOperatorList({handler:e,sink:t,task:a,intent:i,renderInteractiveForms:n}){const s=this.pdfManager.ensure(this,"getContentStream"),o=this.loadResources(["ExtGState","ColorSpace","Pattern","Shading","XObject","Font"]),c=new d.PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this.idFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,options:this.evaluatorOptions,pdfFunctionFactory:this.pdfFunctionFactory}),l=Promise.all([s,o]).then(([r])=>{const n=new u.OperatorList(i,t,this.pageIndex);e.send("StartRenderPage",{transparency:c.hasBlendModes(this.resources),pageIndex:this.pageIndex,intent:i});return c.getOperatorList({stream:r,task:a,resources:this.resources,operatorList:n}).then((function(){return n}))});return Promise.all([l,this._parsedAnnotations]).then((function([e,t]){if(0===t.length){e.flush(!0);return{length:e.totalLength}}const s=[];for(const e of t)m(e,i)&&s.push(e.getOperatorList(c,a,n));return Promise.all(s).then((function(t){e.addOp(r.OPS.beginAnnotations,[]);for(const a of t)e.addOpList(a);e.addOp(r.OPS.endAnnotations,[]);e.flush(!0);return{length:e.totalLength}}))}))}extractTextContent({handler:e,task:t,normalizeWhitespace:a,sink:r,combineTextItems:i}){const n=this.pdfManager.ensure(this,"getContentStream"),s=this.loadResources(["ExtGState","XObject","Font"]);return Promise.all([n,s]).then(([n])=>new d.PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this.idFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,options:this.evaluatorOptions,pdfFunctionFactory:this.pdfFunctionFactory}).getTextContent({stream:n,task:t,resources:this.resources,normalizeWhitespace:a,combineTextItems:i,sink:r}))}getAnnotationsData(e){return this._parsedAnnotations.then((function(t){const a=[];for(let r=0,i=t.length;r<i;r++)e&&!m(t[r],e)||a.push(t[r].data);return a}))}get annotations(){return(0,r.shadow)(this,"annotations",this._getInheritableProperty("Annots")||[])}get _parsedAnnotations(){const e=this.pdfManager.ensure(this,"annotations").then(()=>{const e=this.annotations,t=[];for(let a=0,r=e.length;a<r;a++)t.push(c.AnnotationFactory.create(this.xref,e[a],this.pdfManager,this.idFactory));return Promise.all(t).then((function(e){return e.filter((function(e){return!!e}))}),(function(e){(0,r.warn)(`_parsedAnnotations: "${e}".`);return[]}))});return(0,r.shadow)(this,"_parsedAnnotations",e)}}t.Page=p;const b=new Uint8Array([37,80,68,70,45]),y=new Uint8Array([115,116,97,114,116,120,114,101,102]),v=new Uint8Array([101,110,100,111,98,106]),w=/^[1-9]\.[0-9]$/;function k(e,t,a=1024,r=!1){const i=t.length,n=e.peekBytes(a),s=n.length-i;if(s<=0)return!1;if(r){const a=i-1;let r=n.length-1;for(;r>=a;){let s=0;for(;s<i&&n[r-s]===t[a-s];)s++;if(s>=i){e.pos+=r-a;return!0}r--}}else{let a=0;for(;a<=s;){let r=0;for(;r<i&&n[a+r]===t[r];)r++;if(r>=i){e.pos+=a;return!0}a++}}return!1}t.PDFDocument=class{constructor(e,t){let a;if((0,n.isStream)(t))a=t;else{if(!(0,r.isArrayBuffer)(t))throw new Error("PDFDocument: Unknown argument type");a=new o.Stream(t)}if(a.length<=0)throw new r.InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes.");this.pdfManager=e;this.stream=a;this.xref=new i.XRef(a,e);this.pdfFunctionFactory=new f.PDFFunctionFactory({xref:this.xref,isEvalSupported:e.evaluatorOptions.isEvalSupported});this._pagePromises=[]}parse(e){this.setup(e);const t=this.catalog.catDict.get("Version");(0,n.isName)(t)&&(this.pdfFormatVersion=t.name);try{this.acroForm=this.catalog.catDict.get("AcroForm");if(this.acroForm){this.xfa=this.acroForm.get("XFA");const e=this.acroForm.get("Fields");Array.isArray(e)&&0!==e.length||this.xfa||(this.acroForm=null)}}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("Cannot fetch AcroForm entry; assuming no AcroForms are present");this.acroForm=null}try{const e=this.catalog.catDict.get("Collection");(0,n.isDict)(e)&&e.getKeys().length>0&&(this.collection=e)}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("Cannot fetch Collection dictionary.")}}get linearization(){let e=null;try{e=h.Linearization.create(this.stream)}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)(e)}return(0,r.shadow)(this,"linearization",e)}get startXRef(){const e=this.stream;let t=0;if(this.linearization){e.reset();k(e,v)&&(t=e.pos+6-e.start)}else{const a=1024,r=y.length;let i=!1,n=e.end;for(;!i&&n>0;){n-=a-r;n<0&&(n=0);e.pos=n;i=k(e,y,a,!0)}if(i){e.skip(9);let a;do{a=e.getByte()}while((0,s.isWhiteSpace)(a));let r="";for(;a>=32&&a<=57;){r+=String.fromCharCode(a);a=e.getByte()}t=parseInt(r,10);isNaN(t)&&(t=0)}}return(0,r.shadow)(this,"startXRef",t)}checkHeader(){const e=this.stream;e.reset();if(!k(e,b))return;e.moveStart();let t,a="";for(;(t=e.getByte())>32&&!(a.length>=12);)a+=String.fromCharCode(t);this.pdfFormatVersion||(this.pdfFormatVersion=a.substring(5))}parseStartXRef(){this.xref.setStartXRef(this.startXRef)}setup(e){this.xref.parse(e);this.catalog=new i.Catalog(this.pdfManager,this.xref)}get numPages(){const e=this.linearization,t=e?e.numPages:this.catalog.numPages;return(0,r.shadow)(this,"numPages",t)}get documentInfo(){const e={Title:r.isString,Author:r.isString,Subject:r.isString,Keywords:r.isString,Creator:r.isString,Producer:r.isString,CreationDate:r.isString,ModDate:r.isString,Trapped:n.isName};let t=this.pdfFormatVersion;if("string"!=typeof t||!w.test(t)){(0,r.warn)(`Invalid PDF header version number: ${t}`);t=null}const a={PDFFormatVersion:t,IsLinearized:!!this.linearization,IsAcroFormPresent:!!this.acroForm,IsXFAPresent:!!this.xfa,IsCollectionPresent:!!this.collection};let i;try{i=this.xref.trailer.get("Info")}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("The document information dictionary is invalid.")}if((0,n.isDict)(i))for(const t of i.getKeys()){const s=i.get(t);if(e[t])e[t](s)?a[t]="string"!=typeof s?s:(0,r.stringToPDFString)(s):(0,r.info)(`Bad value in document info for "${t}".`);else if("string"==typeof t){let e;if((0,r.isString)(s))e=(0,r.stringToPDFString)(s);else{if(!((0,n.isName)(s)||(0,r.isNum)(s)||(0,r.isBool)(s))){(0,r.info)(`Unsupported value in document info for (custom) "${t}".`);continue}e=s}a.Custom||(a.Custom=Object.create(null));a.Custom[t]=e}}return(0,r.shadow)(this,"documentInfo",a)}get fingerprint(){let e;const t=this.xref.trailer.get("ID");e=Array.isArray(t)&&t[0]&&(0,r.isString)(t[0])&&"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"!==t[0]?(0,r.stringToBytes)(t[0]):(0,l.calculateMD5)(this.stream.getByteRange(0,1024),0,1024);const a=[];for(let t=0,r=e.length;t<r;t++){const r=e[t].toString(16);a.push(r.padStart(2,"0"))}return(0,r.shadow)(this,"fingerprint",a.join(""))}_getLinearizationPage(e){const{catalog:t,linearization:a}=this;(0,r.assert)(a&&a.pageFirst===e);const i=n.Ref.get(a.objectNumberFirst,0);return this.xref.fetchAsync(i).then(e=>{if((0,n.isDict)(e,"Page")||(0,n.isDict)(e)&&!e.has("Type")&&e.has("Contents")){i&&!t.pageKidsCountCache.has(i)&&t.pageKidsCountCache.put(i,1);return[e,i]}throw new r.FormatError("The Linearization dictionary doesn't point to a valid Page dictionary.")}).catch(a=>{(0,r.info)(a);return t.getPageDict(e)})}getPage(e){if(void 0!==this._pagePromises[e])return this._pagePromises[e];const{catalog:t,linearization:a}=this,r=a&&a.pageFirst===e?this._getLinearizationPage(e):t.getPageDict(e);return this._pagePromises[e]=r.then(([a,r])=>new p({pdfManager:this.pdfManager,xref:this.xref,pageIndex:e,pageDict:a,ref:r,fontCache:t.fontCache,builtInCMapCache:t.builtInCMapCache,pdfFunctionFactory:this.pdfFunctionFactory}))}checkFirstPage(){return this.getPage(0).catch(async e=>{if(e instanceof s.XRefEntryException){this._pagePromises.length=0;await this.cleanup();throw new s.XRefParseException}})}fontFallback(e,t){return this.catalog.fontFallback(e,t)}async cleanup(){return this.catalog?this.catalog.cleanup():(0,n.clearPrimitiveCaches)()}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.FileSpec=t.XRef=t.ObjectLoader=t.Catalog=void 0;var r=a(2),i=a(4),n=a(10),s=a(7),o=a(21),c=a(22);function l(e){return(0,i.isDict)(e)?e.get("D"):e}class h{constructor(e,t){this.pdfManager=e;this.xref=t;this.catDict=t.getCatalogObj();if(!(0,i.isDict)(this.catDict))throw new r.FormatError("Catalog object is not a dictionary.");this.fontCache=new i.RefSetCache;this.builtInCMapCache=new Map;this.pageKidsCountCache=new i.RefSetCache}get metadata(){const e=this.catDict.getRaw("Metadata");if(!(0,i.isRef)(e))return(0,r.shadow)(this,"metadata",null);const t=!(this.xref.encrypt&&this.xref.encrypt.encryptMetadata),a=this.xref.fetch(e,t);let n;if(a&&(0,i.isDict)(a.dict)){const e=a.dict.get("Type"),t=a.dict.get("Subtype");if((0,i.isName)(e,"Metadata")&&(0,i.isName)(t,"XML"))try{n=(0,r.stringToUTF8String)((0,r.bytesToString)(a.getBytes()))}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("Skipping invalid metadata.")}}return(0,r.shadow)(this,"metadata",n)}get toplevelPagesDict(){const e=this.catDict.get("Pages");if(!(0,i.isDict)(e))throw new r.FormatError("Invalid top-level pages dictionary.");return(0,r.shadow)(this,"toplevelPagesDict",e)}get documentOutline(){let e=null;try{e=this._readDocumentOutline()}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)("Unable to read document outline.")}return(0,r.shadow)(this,"documentOutline",e)}_readDocumentOutline(){let e=this.catDict.get("Outlines");if(!(0,i.isDict)(e))return null;e=e.getRaw("First");if(!(0,i.isRef)(e))return null;const t={items:[]},a=[{obj:e,parent:t}],n=new i.RefSet;n.put(e);const s=this.xref,o=new Uint8ClampedArray(3);for(;a.length>0;){const t=a.shift(),l=s.fetchIfRef(t.obj);if(null===l)continue;if(!l.has("Title"))throw new r.FormatError("Invalid outline item encountered.");const u={url:null,dest:null};h.parseDestDictionary({destDict:l,resultObj:u,docBaseUrl:this.pdfManager.docBaseUrl});const d=l.get("Title"),f=l.get("F")||0,g=l.getArray("C"),m=l.get("Count");let p=o;!Array.isArray(g)||3!==g.length||0===g[0]&&0===g[1]&&0===g[2]||(p=c.ColorSpace.singletons.rgb.getRgb(g,0));const b={dest:u.dest,url:u.url,unsafeUrl:u.unsafeUrl,newWindow:u.newWindow,title:(0,r.stringToPDFString)(d),color:p,count:Number.isInteger(m)?m:void 0,bold:!!(2&f),italic:!!(1&f),items:[]};t.parent.items.push(b);e=l.getRaw("First");if((0,i.isRef)(e)&&!n.has(e)){a.push({obj:e,parent:b});n.put(e)}e=l.getRaw("Next");if((0,i.isRef)(e)&&!n.has(e)){a.push({obj:e,parent:t.parent});n.put(e)}}return t.items.length>0?t.items:null}get permissions(){let e=null;try{e=this._readPermissions()}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)("Unable to read permissions.")}return(0,r.shadow)(this,"permissions",e)}_readPermissions(){const e=this.xref.trailer.get("Encrypt");if(!(0,i.isDict)(e))return null;let t=e.get("P");if(!(0,r.isNum)(t))return null;t+=2**32;const a=[];for(const e in r.PermissionFlag){const i=r.PermissionFlag[e];t&i&&a.push(i)}return a}get numPages(){const e=this.toplevelPagesDict.get("Count");if(!Number.isInteger(e))throw new r.FormatError("Page count in top-level pages dictionary is not an integer.");return(0,r.shadow)(this,"numPages",e)}get destinations(){const e=this._readDests(),t=Object.create(null);if(e instanceof f){const a=e.getAll();for(const e in a)t[e]=l(a[e])}else e instanceof i.Dict&&e.forEach((function(e,a){a&&(t[e]=l(a))}));return(0,r.shadow)(this,"destinations",t)}getDestination(e){const t=this._readDests();return t instanceof f||t instanceof i.Dict?l(t.get(e)||null):null}_readDests(){const e=this.catDict.get("Names");return e&&e.has("Dests")?new f(e.getRaw("Dests"),this.xref):this.catDict.has("Dests")?this.catDict.get("Dests"):void 0}get pageLabels(){let e=null;try{e=this._readPageLabels()}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)("Unable to read page labels.")}return(0,r.shadow)(this,"pageLabels",e)}_readPageLabels(){const e=this.catDict.getRaw("PageLabels");if(!e)return null;const t=new Array(this.numPages);let a=null,n="";const o=new g(e,this.xref).getAll();let c="",l=1;for(let e=0,h=this.numPages;e<h;e++){if(e in o){const t=o[e];if(!(0,i.isDict)(t))throw new r.FormatError("PageLabel is not a dictionary.");if(t.has("Type")&&!(0,i.isName)(t.get("Type"),"PageLabel"))throw new r.FormatError("Invalid type in PageLabel dictionary.");if(t.has("S")){const e=t.get("S");if(!(0,i.isName)(e))throw new r.FormatError("Invalid style in PageLabel dictionary.");a=e.name}else a=null;if(t.has("P")){const e=t.get("P");if(!(0,r.isString)(e))throw new r.FormatError("Invalid prefix in PageLabel dictionary.");n=(0,r.stringToPDFString)(e)}else n="";if(t.has("St")){const e=t.get("St");if(!(Number.isInteger(e)&&e>=1))throw new r.FormatError("Invalid start in PageLabel dictionary.");l=e}else l=1}switch(a){case"D":c=l;break;case"R":case"r":c=(0,s.toRomanNumerals)(l,"r"===a);break;case"A":case"a":const e=26,t=65,i=97,n="a"===a?i:t,o=l-1,h=String.fromCharCode(n+o%e),u=[];for(let t=0,a=o/e|0;t<=a;t++)u.push(h);c=u.join("");break;default:if(a)throw new r.FormatError(`Invalid style "${a}" in PageLabel dictionary.`);c=""}t[e]=n+c;l++}return t}get pageLayout(){const e=this.catDict.get("PageLayout");let t="";if((0,i.isName)(e))switch(e.name){case"SinglePage":case"OneColumn":case"TwoColumnLeft":case"TwoColumnRight":case"TwoPageLeft":case"TwoPageRight":t=e.name}return(0,r.shadow)(this,"pageLayout",t)}get pageMode(){const e=this.catDict.get("PageMode");let t="UseNone";if((0,i.isName)(e))switch(e.name){case"UseNone":case"UseOutlines":case"UseThumbs":case"FullScreen":case"UseOC":case"UseAttachments":t=e.name}return(0,r.shadow)(this,"pageMode",t)}get viewerPreferences(){const e={HideToolbar:r.isBool,HideMenubar:r.isBool,HideWindowUI:r.isBool,FitWindow:r.isBool,CenterWindow:r.isBool,DisplayDocTitle:r.isBool,NonFullScreenPageMode:i.isName,Direction:i.isName,ViewArea:i.isName,ViewClip:i.isName,PrintArea:i.isName,PrintClip:i.isName,PrintScaling:i.isName,Duplex:i.isName,PickTrayByPDFSize:r.isBool,PrintPageRange:Array.isArray,NumCopies:Number.isInteger},t=this.catDict.get("ViewerPreferences"),a=Object.create(null);if((0,i.isDict)(t))for(const i in e){if(!t.has(i))continue;const n=t.get(i);if(!e[i](n)){(0,r.info)(`Bad value in ViewerPreferences for "${i}".`);continue}let s;switch(i){case"NonFullScreenPageMode":switch(n.name){case"UseNone":case"UseOutlines":case"UseThumbs":case"UseOC":s=n.name;break;default:s="UseNone"}break;case"Direction":switch(n.name){case"L2R":case"R2L":s=n.name;break;default:s="L2R"}break;case"ViewArea":case"ViewClip":case"PrintArea":case"PrintClip":switch(n.name){case"MediaBox":case"CropBox":case"BleedBox":case"TrimBox":case"ArtBox":s=n.name;break;default:s="CropBox"}break;case"PrintScaling":switch(n.name){case"None":case"AppDefault":s=n.name;break;default:s="AppDefault"}break;case"Duplex":switch(n.name){case"Simplex":case"DuplexFlipShortEdge":case"DuplexFlipLongEdge":s=n.name;break;default:s="None"}break;case"PrintPageRange":if(n.length%2!=0)break;n.every((e,t,a)=>Number.isInteger(e)&&e>0&&(0===t||e>=a[t-1])&&e<=this.numPages)&&(s=n);break;case"NumCopies":n>0&&(s=n);break;default:(0,r.assert)("boolean"==typeof n);s=n}void 0!==s?a[i]=s:(0,r.info)(`Bad value in ViewerPreferences for "${i}".`)}return(0,r.shadow)(this,"viewerPreferences",a)}get openAction(){const e=this.catDict.get("OpenAction");let t=null;if((0,i.isDict)(e)){const a=new i.Dict(this.xref);a.set("A",e);const r={url:null,dest:null,action:null};h.parseDestDictionary({destDict:a,resultObj:r});if(Array.isArray(r.dest)){t||(t=Object.create(null));t.dest=r.dest}else if(r.action){t||(t=Object.create(null));t.action=r.action}}else if(Array.isArray(e)){t||(t=Object.create(null));t.dest=e}return(0,r.shadow)(this,"openAction",t)}get attachments(){const e=this.catDict.get("Names");let t=null;if(e&&e.has("EmbeddedFiles")){const a=new f(e.getRaw("EmbeddedFiles"),this.xref).getAll();for(const e in a){const i=new m(a[e],this.xref);t||(t=Object.create(null));t[(0,r.stringToPDFString)(e)]=i.serializable}}return(0,r.shadow)(this,"attachments",t)}get javaScript(){const e=this.catDict.get("Names");let t=null;function a(e){const a=e.get("S");if(!(0,i.isName)(a,"JavaScript"))return;let n=e.get("JS");if((0,i.isStream)(n))n=(0,r.bytesToString)(n.getBytes());else if(!(0,r.isString)(n))return;t||(t=[]);t.push((0,r.stringToPDFString)(n))}if(e&&e.has("JavaScript")){const t=new f(e.getRaw("JavaScript"),this.xref).getAll();for(const e in t){const r=t[e];(0,i.isDict)(r)&&a(r)}}const n=this.catDict.get("OpenAction");(0,i.isDict)(n)&&(0,i.isName)(n.get("S"),"JavaScript")&&a(n);return(0,r.shadow)(this,"javaScript",t)}fontFallback(e,t){const a=[];this.fontCache.forEach((function(e){a.push(e)}));return Promise.all(a).then(a=>{for(const r of a)if(r.loadedName===e){r.fallback(t);return}})}cleanup(){(0,i.clearPrimitiveCaches)();this.pageKidsCountCache.clear();const e=[];this.fontCache.forEach((function(t){e.push(t)}));return Promise.all(e).then(e=>{for(const{dict:t}of e)delete t.translated;this.fontCache.clear();this.builtInCMapCache.clear()})}getPageDict(e){const t=(0,r.createPromiseCapability)(),a=[this.catDict.getRaw("Pages")],n=new i.RefSet,s=this.xref,o=this.pageKidsCountCache;let c,l=0;!function h(){for(;a.length;){const u=a.pop();if((0,i.isRef)(u)){c=o.get(u);if(c>0&&l+c<e){l+=c;continue}if(n.has(u)){t.reject(new r.FormatError("Pages tree contains circular reference."));return}n.put(u);s.fetchAsync(u).then((function(r){if((0,i.isDict)(r,"Page")||(0,i.isDict)(r)&&!r.has("Kids"))if(e===l){u&&!o.has(u)&&o.put(u,1);t.resolve([r,u])}else{l++;h()}else{a.push(r);h()}}),t.reject);return}if(!(0,i.isDict)(u)){t.reject(new r.FormatError("Page dictionary kid reference points to wrong type of object."));return}c=u.get("Count");if(Number.isInteger(c)&&c>=0){const t=u.objId;t&&!o.has(t)&&o.put(t,c);if(l+c<=e){l+=c;continue}}const d=u.get("Kids");if(!Array.isArray(d)){if((0,i.isName)(u.get("Type"),"Page")||!u.has("Type")&&u.has("Contents")){if(l===e){t.resolve([u,null]);return}l++;continue}t.reject(new r.FormatError("Page dictionary kids object is not an array."));return}for(let e=d.length-1;e>=0;e--)a.push(d[e])}t.reject(new Error(`Page index ${e} not found.`))}();return t.promise}getPageIndex(e){const t=this.xref;let a=0;return function n(s){return function(a){let n,s=0;return t.fetchAsync(a).then((function(t){if((0,i.isRefsEqual)(a,e)&&!(0,i.isDict)(t,"Page")&&(!(0,i.isDict)(t)||t.has("Type")||!t.has("Contents")))throw new r.FormatError("The reference does not point to a /Page dictionary.");if(!t)return null;if(!(0,i.isDict)(t))throw new r.FormatError("Node must be a dictionary.");n=t.getRaw("Parent");return t.getAsync("Parent")})).then((function(e){if(!e)return null;if(!(0,i.isDict)(e))throw new r.FormatError("Parent must be a dictionary.");return e.getAsync("Kids")})).then((function(e){if(!e)return null;const o=[];let c=!1;for(let n=0,l=e.length;n<l;n++){const l=e[n];if(!(0,i.isRef)(l))throw new r.FormatError("Kid must be a reference.");if((0,i.isRefsEqual)(l,a)){c=!0;break}o.push(t.fetchAsync(l).then((function(e){if(!(0,i.isDict)(e))throw new r.FormatError("Kid node must be a dictionary.");e.has("Count")?s+=e.get("Count"):s++})))}if(!c)throw new r.FormatError("Kid reference not found in parent's kids.");return Promise.all(o).then((function(){return[s,n]}))}))}(s).then((function(e){if(!e)return a;const[t,r]=e;a+=t;return n(r)}))}(e)}static parseDestDictionary(e){const t=e.destDict;if(!(0,i.isDict)(t)){(0,r.warn)("parseDestDictionary: `destDict` must be a dictionary.");return}const a=e.resultObj;if("object"!=typeof a){(0,r.warn)("parseDestDictionary: `resultObj` must be an object.");return}const n=e.docBaseUrl||null;let s,o,c=t.get("A");!(0,i.isDict)(c)&&t.has("Dest")&&(c=t.get("Dest"));if((0,i.isDict)(c)){const e=c.get("S");if(!(0,i.isName)(e)){(0,r.warn)("parseDestDictionary: Invalid type in Action dictionary.");return}const t=e.name;switch(t){case"URI":s=c.get("URI");(0,i.isName)(s)?s="/"+s.name:(0,r.isString)(s)&&(s=function(e){return e.startsWith("www.")?`http://${e}`:e}(s));break;case"GoTo":o=c.get("D");break;case"Launch":case"GoToR":const e=c.get("F");(0,i.isDict)(e)?s=e.get("F")||null:(0,r.isString)(e)&&(s=e);let n=c.get("D");if(n){(0,i.isName)(n)&&(n=n.name);if((0,r.isString)(s)){const e=s.split("#")[0];(0,r.isString)(n)?s=e+"#"+n:Array.isArray(n)&&(s=e+"#"+JSON.stringify(n))}}const l=c.get("NewWindow");(0,r.isBool)(l)&&(a.newWindow=l);break;case"Named":const h=c.get("N");(0,i.isName)(h)&&(a.action=h.name);break;case"JavaScript":const u=c.get("JS");let d;(0,i.isStream)(u)?d=(0,r.bytesToString)(u.getBytes()):(0,r.isString)(u)&&(d=u);if(d){const e=new RegExp("^\\s*("+["app.launchURL","window.open"].join("|").split(".").join("\\.")+")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))","i").exec((0,r.stringToPDFString)(d));if(e&&e[2]){s=e[2];"true"===e[3]&&"app.launchURL"===e[1]&&(a.newWindow=!0);break}}default:(0,r.warn)(`parseDestDictionary: unsupported action type "${t}".`)}}else t.has("Dest")&&(o=t.get("Dest"));if((0,r.isString)(s)){s=function(e){try{return(0,r.stringToUTF8String)(e)}catch(t){return e}}(s);const e=(0,r.createValidAbsoluteUrl)(s,n);e&&(a.url=e.href);a.unsafeUrl=s}if(o){(0,i.isName)(o)&&(o=o.name);((0,r.isString)(o)||Array.isArray(o))&&(a.dest=o)}}}t.Catalog=h;var u=function(){function e(e,t){this.stream=e;this.pdfManager=t;this.entries=[];this.xrefstms=Object.create(null);this._cacheMap=new Map;this.stats={streamTypes:Object.create(null),fontTypes:Object.create(null)}}e.prototype={setStartXRef:function(e){this.startXRefQueue=[e]},parse:function(e){var t;if(e){(0,r.warn)("Indexing all PDF objects");t=this.indexObjects()}else t=this.readXRef();t.assignXref(this);this.trailer=t;let a,n;try{a=t.get("Encrypt")}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)(`XRef.parse - Invalid "Encrypt" reference: "${e}".`)}if((0,i.isDict)(a)){var c=t.get("ID"),l=c&&c.length?c[0]:"";a.suppressEncryption=!0;this.encrypt=new o.CipherTransformFactory(a,l,this.pdfManager.password)}try{n=t.get("Root")}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)(`XRef.parse - Invalid "Root" reference: "${e}".`)}if(!(0,i.isDict)(n)||!n.has("Pages")){if(!e)throw new s.XRefParseException;throw new r.FormatError("Invalid root reference")}this.root=n},processXRefTable:function(e){"tableState"in this||(this.tableState={entryNum:0,streamPos:e.lexer.stream.pos,parserBuf1:e.buf1,parserBuf2:e.buf2});var t=this.readXRefTable(e);if(!(0,i.isCmd)(t,"trailer"))throw new r.FormatError("Invalid XRef table: could not find trailer dictionary");var a=e.getObj();!(0,i.isDict)(a)&&a.dict&&(a=a.dict);if(!(0,i.isDict)(a))throw new r.FormatError("Invalid XRef table: could not parse trailer dictionary");delete this.tableState;return a},readXRefTable:function(e){var t,a=e.lexer.stream,n=this.tableState;a.pos=n.streamPos;e.buf1=n.parserBuf1;e.buf2=n.parserBuf2;for(;;){if(!("firstEntryNum"in n)||!("entryCount"in n)){if((0,i.isCmd)(t=e.getObj(),"trailer"))break;n.firstEntryNum=t;n.entryCount=e.getObj()}var s=n.firstEntryNum,o=n.entryCount;if(!Number.isInteger(s)||!Number.isInteger(o))throw new r.FormatError("Invalid XRef table: wrong types in subsection header");for(var c=n.entryNum;c<o;c++){n.streamPos=a.pos;n.entryNum=c;n.parserBuf1=e.buf1;n.parserBuf2=e.buf2;var l={};l.offset=e.getObj();l.gen=e.getObj();var h=e.getObj();if(h instanceof i.Cmd)switch(h.cmd){case"f":l.free=!0;break;case"n":l.uncompressed=!0}if(!Number.isInteger(l.offset)||!Number.isInteger(l.gen)||!l.free&&!l.uncompressed)throw new r.FormatError(`Invalid entry in XRef subsection: ${s}, ${o}`);0===c&&l.free&&1===s&&(s=0);this.entries[c+s]||(this.entries[c+s]=l)}n.entryNum=0;n.streamPos=a.pos;n.parserBuf1=e.buf1;n.parserBuf2=e.buf2;delete n.firstEntryNum;delete n.entryCount}if(this.entries[0]&&!this.entries[0].free)throw new r.FormatError("Invalid XRef table: unexpected first object");return t},processXRefStream:function(e){if(!("streamState"in this)){var t=e.dict,a=t.get("W"),r=t.get("Index");r||(r=[0,t.get("Size")]);this.streamState={entryRanges:r,byteWidths:a,entryNum:0,streamPos:e.pos}}this.readXRefStream(e);delete this.streamState;return e.dict},readXRefStream:function(e){var t,a,i=this.streamState;e.pos=i.streamPos;for(var n=i.byteWidths,s=n[0],o=n[1],c=n[2],l=i.entryRanges;l.length>0;){var h=l[0],u=l[1];if(!Number.isInteger(h)||!Number.isInteger(u))throw new r.FormatError(`Invalid XRef range fields: ${h}, ${u}`);if(!Number.isInteger(s)||!Number.isInteger(o)||!Number.isInteger(c))throw new r.FormatError(`Invalid XRef entry fields length: ${h}, ${u}`);for(t=i.entryNum;t<u;++t){i.entryNum=t;i.streamPos=e.pos;var d=0,f=0,g=0;for(a=0;a<s;++a)d=d<<8|e.getByte();0===s&&(d=1);for(a=0;a<o;++a)f=f<<8|e.getByte();for(a=0;a<c;++a)g=g<<8|e.getByte();var m={};m.offset=f;m.gen=g;switch(d){case 0:m.free=!0;break;case 1:m.uncompressed=!0;break;case 2:break;default:throw new r.FormatError(`Invalid XRef entry type: ${d}`)}this.entries[h+t]||(this.entries[h+t]=m)}i.entryNum=0;i.streamPos=e.pos;l.splice(0,2)}},indexObjects:function(){function e(e,t){for(var a="",r=e[t];10!==r&&13!==r&&60!==r&&!(++t>=e.length);){a+=String.fromCharCode(r);r=e[t]}return a}function t(e,t,a){for(var r=a.length,i=e.length,n=0;t<i;){for(var s=0;s<r&&e[t+s]===a[s];)++s;if(s>=r)break;t++;n++}return n}var a=/^(\d+)\s+(\d+)\s+obj\b/;const o=/\bendobj[\b\s]$/,c=/\s+(\d+\s+\d+\s+obj[\b\s<])$/;var l=new Uint8Array([116,114,97,105,108,101,114]),h=new Uint8Array([115,116,97,114,116,120,114,101,102]);const u=new Uint8Array([111,98,106]);var d=new Uint8Array([47,88,82,101,102]);this.entries.length=0;var f=this.stream;f.pos=0;for(var g,m,p=f.getBytes(),b=f.start,y=p.length,v=[],w=[];b<y;){var k=p[b];if(9!==k&&10!==k&&13!==k&&32!==k)if(37!==k){var S,C=e(p,b);if(C.startsWith("xref")&&(4===C.length||/\s/.test(C[4]))){b+=t(p,b,l);v.push(b);b+=t(p,b,h)}else if(S=a.exec(C)){const e=0|S[1],a=0|S[2];this.entries[e]&&this.entries[e].gen!==a||(this.entries[e]={offset:b-f.start,gen:a,uncompressed:!0});let i,n=b+C.length;for(;n<p.length;){const e=n+t(p,n,u)+4;i=e-b;const a=Math.max(e-25,n),s=(0,r.bytesToString)(p.subarray(a,e));if(o.test(s))break;{const e=c.exec(s);if(e&&e[1]){(0,r.warn)('indexObjects: Found new "obj" inside of another "obj", caused by missing "endobj" -- trying to recover.');i-=e[1].length;break}}n=e}const s=p.subarray(b,b+i);var x=t(s,0,d);if(x<i&&s[x+5]<64){w.push(b-f.start);this.xrefstms[b-f.start]=1}b+=i}else if(C.startsWith("trailer")&&(7===C.length||/\s/.test(C[7]))){v.push(b);b+=t(p,b,h)}else b+=C.length+1}else do{if(++b>=y)break;k=p[b]}while(10!==k&&13!==k);else++b}for(g=0,m=w.length;g<m;++g){this.startXRefQueue.push(w[g]);this.readXRef(!0)}let A;for(g=0,m=v.length;g<m;++g){f.pos=v[g];const e=new n.Parser({lexer:new n.Lexer(f),xref:this,allowStreams:!0,recoveryMode:!0});var I=e.getObj();if(!(0,i.isCmd)(I,"trailer"))continue;const t=e.getObj();if(!(0,i.isDict)(t))continue;let a;try{a=t.get("Root")}catch(e){if(e instanceof s.MissingDataException)throw e;continue}if((0,i.isDict)(a)&&a.has("Pages")){if(t.has("ID"))return t;A=t}}if(A)return A;throw new r.InvalidPDFException("Invalid PDF structure.")},readXRef:function(e){var t=this.stream;const a=Object.create(null);try{for(;this.startXRefQueue.length;){var o=this.startXRefQueue[0];if(a[o]){(0,r.warn)("readXRef - skipping XRef table since it was already parsed.");this.startXRefQueue.shift();continue}a[o]=!0;t.pos=o+t.start;const e=new n.Parser({lexer:new n.Lexer(t),xref:this,allowStreams:!0});var c,l=e.getObj();if((0,i.isCmd)(l,"xref")){c=this.processXRefTable(e);this.topDict||(this.topDict=c);l=c.get("XRefStm");if(Number.isInteger(l)){var h=l;if(!(h in this.xrefstms)){this.xrefstms[h]=1;this.startXRefQueue.push(h)}}}else{if(!Number.isInteger(l))throw new r.FormatError("Invalid XRef stream header");if(!Number.isInteger(e.getObj())||!(0,i.isCmd)(e.getObj(),"obj")||!(0,i.isStream)(l=e.getObj()))throw new r.FormatError("Invalid XRef stream");c=this.processXRefStream(l);this.topDict||(this.topDict=c);if(!c)throw new r.FormatError("Failed to read XRef stream")}l=c.get("Prev");Number.isInteger(l)?this.startXRefQueue.push(l):(0,i.isRef)(l)&&this.startXRefQueue.push(l.num);this.startXRefQueue.shift()}return this.topDict}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.info)("(while reading XRef): "+e)}if(!e)throw new s.XRefParseException},getEntry:function(e){var t=this.entries[e];return t&&!t.free&&t.offset?t:null},fetchIfRef:function(e,t){return e instanceof i.Ref?this.fetch(e,t):e},fetch:function(e,t){if(!(e instanceof i.Ref))throw new Error("ref object is not a reference");const a=e.num,r=this._cacheMap.get(a);if(void 0!==r){r instanceof i.Dict&&!r.objId&&(r.objId=e.toString());return r}let n=this.getEntry(a);if(null===n){this._cacheMap.set(a,n);return n}n=n.uncompressed?this.fetchUncompressed(e,n,t):this.fetchCompressed(e,n,t);(0,i.isDict)(n)?n.objId=e.toString():(0,i.isStream)(n)&&(n.dict.objId=e.toString());return n},fetchUncompressed(e,t,a=!1){var r=e.gen,o=e.num;if(t.gen!==r)throw new s.XRefEntryException(`Inconsistent generation in XRef: ${e}`);var c=this.stream.makeSubStream(t.offset+this.stream.start);const l=new n.Parser({lexer:new n.Lexer(c),xref:this,allowStreams:!0});var h=l.getObj(),u=l.getObj(),d=l.getObj();if(h!==o||u!==r||!(d instanceof i.Cmd))throw new s.XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`);if("obj"!==d.cmd){if(d.cmd.startsWith("obj")){o=parseInt(d.cmd.substring(3),10);if(!Number.isNaN(o))return o}throw new s.XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`)}t=this.encrypt&&!a?l.getObj(this.encrypt.createCipherTransform(o,r)):l.getObj();(0,i.isStream)(t)||this._cacheMap.set(o,t);return t},fetchCompressed(e,t,a=!1){const o=t.offset,c=this.fetch(i.Ref.get(o,0));if(!(0,i.isStream)(c))throw new r.FormatError("bad ObjStm stream");const l=c.dict.get("First"),h=c.dict.get("N");if(!Number.isInteger(l)||!Number.isInteger(h))throw new r.FormatError("invalid first and n parameters for ObjStm stream");const u=new n.Parser({lexer:new n.Lexer(c),xref:this,allowStreams:!0}),d=new Array(h);for(let e=0;e<h;++e){const t=u.getObj();if(!Number.isInteger(t))throw new r.FormatError(`invalid object number in the ObjStm stream: ${t}`);const a=u.getObj();if(!Number.isInteger(a))throw new r.FormatError(`invalid object offset in the ObjStm stream: ${a}`);d[e]=t}const f=new Array(h);for(let e=0;e<h;++e){const t=u.getObj();f[e]=t;u.buf1 instanceof i.Cmd&&"endobj"===u.buf1.cmd&&u.shift();if((0,i.isStream)(t))continue;const a=d[e],r=this.entries[a];r&&r.offset===o&&r.gen===e&&this._cacheMap.set(a,t)}if(void 0===(t=f[t.gen]))throw new s.XRefEntryException(`Bad (compressed) XRef entry: ${e}`);return t},async fetchIfRefAsync(e,t){return e instanceof i.Ref?this.fetchAsync(e,t):e},async fetchAsync(e,t){try{return this.fetch(e,t)}catch(a){if(!(a instanceof s.MissingDataException))throw a;await this.pdfManager.requestRange(a.begin,a.end);return this.fetchAsync(e,t)}},getCatalogObj:function(){return this.root}};return e}();t.XRef=u;class d{constructor(e,t,a){this.constructor===d&&(0,r.unreachable)("Cannot initialize NameOrNumberTree.");this.root=e;this.xref=t;this._type=a}getAll(){const e=Object.create(null);if(!this.root)return e;const t=this.xref,a=new i.RefSet;a.put(this.root);const n=[this.root];for(;n.length>0;){const s=t.fetchIfRef(n.shift());if(!(0,i.isDict)(s))continue;if(s.has("Kids")){const e=s.get("Kids");for(let t=0,i=e.length;t<i;t++){const i=e[t];if(a.has(i))throw new r.FormatError(`Duplicate entry in "${this._type}" tree.`);n.push(i);a.put(i)}continue}const o=s.get(this._type);if(Array.isArray(o))for(let a=0,r=o.length;a<r;a+=2)e[t.fetchIfRef(o[a])]=t.fetchIfRef(o[a+1])}return e}get(e){if(!this.root)return null;const t=this.xref;let a=t.fetchIfRef(this.root),i=0;for(;a.has("Kids");){if(++i>10){(0,r.warn)(`Search depth limit reached for "${this._type}" tree.`);return null}const n=a.get("Kids");if(!Array.isArray(n))return null;let s=0,o=n.length-1;for(;s<=o;){const r=s+o>>1,i=t.fetchIfRef(n[r]).get("Limits");if(e<t.fetchIfRef(i[0]))o=r-1;else{if(!(e>t.fetchIfRef(i[1]))){a=t.fetchIfRef(n[r]);break}s=r+1}}if(s>o)return null}const n=a.get(this._type);if(Array.isArray(n)){let a=0,i=n.length-2;for(;a<=i;){const r=a+i>>1,s=r+(1&r),o=t.fetchIfRef(n[s]);if(e<o)i=s-2;else{if(!(e>o))return t.fetchIfRef(n[s+1]);a=s+2}}(0,r.info)(`Falling back to an exhaustive search, for key "${e}", `+`in "${this._type}" tree.`);for(let a=0,i=n.length;a<i;a+=2){if(t.fetchIfRef(n[a])===e){(0,r.warn)(`The "${e}" key was found at an incorrect, `+`i.e. out-of-order, position in "${this._type}" tree.`);return t.fetchIfRef(n[a+1])}}}return null}}class f extends d{constructor(e,t){super(e,t,"Names")}}class g extends d{constructor(e,t){super(e,t,"Nums")}}var m=function(){function e(e,t){if(e&&(0,i.isDict)(e)){this.xref=t;this.root=e;e.has("FS")&&(this.fs=e.get("FS"));this.description=e.has("Desc")?(0,r.stringToPDFString)(e.get("Desc")):"";e.has("RF")&&(0,r.warn)("Related file specifications are not supported");this.contentAvailable=!0;if(!e.has("EF")){this.contentAvailable=!1;(0,r.warn)("Non-embedded file specifications are not supported")}}}function t(e){return e.has("UF")?e.get("UF"):e.has("F")?e.get("F"):e.has("Unix")?e.get("Unix"):e.has("Mac")?e.get("Mac"):e.has("DOS")?e.get("DOS"):null}e.prototype={get filename(){if(!this._filename&&this.root){var e=t(this.root)||"unnamed";this._filename=(0,r.stringToPDFString)(e).replace(/\\\\/g,"\\").replace(/\\\//g,"/").replace(/\\/g,"/")}return this._filename},get content(){if(!this.contentAvailable)return null;!this.contentRef&&this.root&&(this.contentRef=t(this.root.get("EF")));var e=null;if(this.contentRef){var a=this.xref.fetchIfRef(this.contentRef);a&&(0,i.isStream)(a)?e=a.getBytes():(0,r.warn)("Embedded file specification points to non-existing/invalid content")}else(0,r.warn)("Embedded file specification does not have a content");return e},get serializable(){return{filename:this.filename,content:this.content}}};return e}();t.FileSpec=m;const p=function(){function e(e){return e instanceof i.Ref||e instanceof i.Dict||Array.isArray(e)||(0,i.isStream)(e)}function t(t,a){if(t instanceof i.Dict||(0,i.isStream)(t)){const r=t instanceof i.Dict?t:t.dict,n=r.getKeys();for(let t=0,i=n.length;t<i;t++){const i=r.getRaw(n[t]);e(i)&&a.push(i)}}else if(Array.isArray(t))for(let r=0,i=t.length;r<i;r++){const i=t[r];e(i)&&a.push(i)}}function a(e,t,a){this.dict=e;this.keys=t;this.xref=a;this.refSet=null}a.prototype={async load(){if(!this.xref.stream.allChunksLoaded||this.xref.stream.allChunksLoaded())return;const{keys:e,dict:t}=this;this.refSet=new i.RefSet;const a=[];for(let r=0,i=e.length;r<i;r++){const i=t.getRaw(e[r]);void 0!==i&&a.push(i)}return this._walk(a)},async _walk(e){const a=[],r=[];for(;e.length;){let n=e.pop();if(n instanceof i.Ref){if(this.refSet.has(n))continue;try{this.refSet.put(n);n=this.xref.fetch(n)}catch(e){if(!(e instanceof s.MissingDataException))throw e;a.push(n);r.push({begin:e.begin,end:e.end})}}if(n&&n.getBaseStreams){const e=n.getBaseStreams();let t=!1;for(let a=0,i=e.length;a<i;a++){const i=e[a];if(i.allChunksLoaded&&!i.allChunksLoaded()){t=!0;r.push({begin:i.start,end:i.end})}}t&&a.push(n)}t(n,e)}if(r.length){await this.xref.stream.manager.requestRanges(r);for(let e=0,t=a.length;e<t;e++){const t=a[e];t instanceof i.Ref&&this.refSet.remove(t)}return this._walk(a)}this.refSet=null}};return a}();t.ObjectLoader=p},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Parser=t.Linearization=t.Lexer=void 0;var r=a(11),i=a(2),n=a(4),s=a(7),o=a(12),c=a(14),l=a(17),h=a(19);function u(e){const t=e.length;let a=1,r=0;for(let i=0;i<t;++i){a+=255&e[i];r+=a}return r%65521<<16|a%65521}class d{constructor({lexer:e,xref:t,allowStreams:a=!1,recoveryMode:r=!1}){this.lexer=e;this.xref=t;this.allowStreams=a;this.recoveryMode=r;this.imageCache=Object.create(null);this.refill()}refill(){this.buf1=this.lexer.getObj();this.buf2=this.lexer.getObj()}shift(){if(this.buf2 instanceof n.Cmd&&"ID"===this.buf2.cmd){this.buf1=this.buf2;this.buf2=null}else{this.buf1=this.buf2;this.buf2=this.lexer.getObj()}}tryShift(){try{this.shift();return!0}catch(e){if(e instanceof s.MissingDataException)throw e;return!1}}getObj(e=null){const t=this.buf1;this.shift();if(t instanceof n.Cmd)switch(t.cmd){case"BI":return this.makeInlineImage(e);case"[":const a=[];for(;!(0,n.isCmd)(this.buf1,"]")&&!(0,n.isEOF)(this.buf1);)a.push(this.getObj(e));if((0,n.isEOF)(this.buf1)){if(!this.recoveryMode)throw new i.FormatError("End of file inside array");return a}this.shift();return a;case"<<":const r=new n.Dict(this.xref);for(;!(0,n.isCmd)(this.buf1,">>")&&!(0,n.isEOF)(this.buf1);){if(!(0,n.isName)(this.buf1)){(0,i.info)("Malformed dictionary: key must be a name object");this.shift();continue}const t=this.buf1.name;this.shift();if((0,n.isEOF)(this.buf1))break;r.set(t,this.getObj(e))}if((0,n.isEOF)(this.buf1)){if(!this.recoveryMode)throw new i.FormatError("End of file inside dictionary");return r}if((0,n.isCmd)(this.buf2,"stream"))return this.allowStreams?this.makeStream(r,e):r;this.shift();return r;default:return t}if(Number.isInteger(t)){if(Number.isInteger(this.buf1)&&(0,n.isCmd)(this.buf2,"R")){const e=n.Ref.get(t,this.buf1);this.shift();this.shift();return e}return t}return"string"==typeof t&&e?e.decryptString(t):t}findDefaultInlineStreamEnd(e){const t=e.pos;let a,r,n=0;for(;-1!==(a=e.getByte());)if(0===n)n=69===a?1:0;else if(1===n)n=73===a?2:0;else{(0,i.assert)(2===n);if(32===a||10===a||13===a){r=e.pos;const t=e.peekBytes(10);for(let e=0,r=t.length;e<r;e++){a=t[e];if((0!==a||0===t[e+1])&&(10!==a&&13!==a&&(a<32||a>127))){n=0;break}}if(2===n)break}else n=0}if(-1===a){(0,i.warn)("findDefaultInlineStreamEnd: Reached the end of the stream without finding a valid EI marker");if(r){(0,i.warn)('... trying to recover by using the last "EI" occurrence.');e.skip(-(e.pos-r))}}let o=4;e.skip(-o);a=e.peekByte();e.skip(o);(0,s.isWhiteSpace)(a)||o--;return e.pos-o-t}findDCTDecodeInlineStreamEnd(e){const t=e.pos;let a,r,n=!1;for(;-1!==(a=e.getByte());)if(255===a){switch(e.getByte()){case 0:break;case 255:e.skip(-1);break;case 217:n=!0;break;case 192:case 193:case 194:case 195:case 197:case 198:case 199:case 201:case 202:case 203:case 205:case 206:case 207:case 196:case 204:case 218:case 219:case 220:case 221:case 222:case 223:case 224:case 225:case 226:case 227:case 228:case 229:case 230:case 231:case 232:case 233:case 234:case 235:case 236:case 237:case 238:case 239:case 254:r=e.getUint16();r>2?e.skip(r-2):e.skip(-2)}if(n)break}const s=e.pos-t;if(-1===a){(0,i.warn)("Inline DCTDecode image stream: EOI marker not found, searching for /EI/ instead.");e.skip(-s);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return s}findASCII85DecodeInlineStreamEnd(e){const t=e.pos;let a;for(;-1!==(a=e.getByte());)if(126===a){const t=e.pos;a=e.peekByte();for(;(0,s.isWhiteSpace)(a);){e.skip();a=e.peekByte()}if(62===a){e.skip();break}if(e.pos>t){const t=e.peekBytes(2);if(69===t[0]&&73===t[1])break}}const r=e.pos-t;if(-1===a){(0,i.warn)("Inline ASCII85Decode image stream: EOD marker not found, searching for /EI/ instead.");e.skip(-r);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return r}findASCIIHexDecodeInlineStreamEnd(e){const t=e.pos;let a;for(;-1!==(a=e.getByte())&&62!==a;);const r=e.pos-t;if(-1===a){(0,i.warn)("Inline ASCIIHexDecode image stream: EOD marker not found, searching for /EI/ instead.");e.skip(-r);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return r}inlineStreamSkipEI(e){let t,a=0;for(;-1!==(t=e.getByte());)if(0===a)a=69===t?1:0;else if(1===a)a=73===t?2:0;else if(2===a)break}makeInlineImage(e){const t=this.lexer,a=t.stream,r=new n.Dict(this.xref);let s;for(;!(0,n.isCmd)(this.buf1,"ID")&&!(0,n.isEOF)(this.buf1);){if(!(0,n.isName)(this.buf1))throw new i.FormatError("Dictionary key must be a name object");const t=this.buf1.name;this.shift();if((0,n.isEOF)(this.buf1))break;r.set(t,this.getObj(e))}-1!==t.beginInlineImagePos&&(s=a.pos-t.beginInlineImagePos);const o=r.get("Filter","F");let c;if((0,n.isName)(o))c=o.name;else if(Array.isArray(o)){const e=this.xref.fetchIfRef(o[0]);(0,n.isName)(e)&&(c=e.name)}const l=a.pos;let h;h="DCTDecode"===c||"DCT"===c?this.findDCTDecodeInlineStreamEnd(a):"ASCII85Decode"===c||"A85"===c?this.findASCII85DecodeInlineStreamEnd(a):"ASCIIHexDecode"===c||"AHx"===c?this.findASCIIHexDecodeInlineStreamEnd(a):this.findDefaultInlineStreamEnd(a);let d,f=a.makeSubStream(l,h,r);if(h<1e3&&s<5552){const e=f.getBytes();f.reset();const r=a.pos;a.pos=t.beginInlineImagePos;const i=a.getBytes(s);a.pos=r;d=u(e)+"_"+u(i);const o=this.imageCache[d];if(void 0!==o){this.buf2=n.Cmd.get("EI");this.shift();o.reset();return o}}e&&(f=e.createStream(f,h));f=this.filter(f,r,h);f.dict=r;if(void 0!==d){f.cacheKey=`inline_${h}_${d}`;this.imageCache[d]=f}this.buf2=n.Cmd.get("EI");this.shift();return f}_findStreamLength(e,t){const{stream:a}=this.lexer;a.pos=e;const r=t.length;for(;a.pos<a.end;){const i=a.peekBytes(2048),n=i.length-r;if(n<=0)break;let s=0;for(;s<n;){let n=0;for(;n<r&&i[s+n]===t[n];)n++;if(n>=r){a.pos+=s;return a.pos-e}s++}a.pos+=n}return-1}makeStream(e,t){const a=this.lexer;let r=a.stream;a.skipToNextLine();const o=r.pos-1;let c=e.get("Length");if(!Number.isInteger(c)){(0,i.info)(`Bad length "${c}" in stream`);c=0}r.pos=o+c;a.nextChar();if(this.tryShift()&&(0,n.isCmd)(this.buf2,"endstream"))this.shift();else{const e=new Uint8Array([101,110,100,115,116,114,101,97,109]);let t=this._findStreamLength(o,e);if(t<0){const a=1;for(let n=1;n<=a;n++){const a=e.length-n,c=e.slice(0,a),l=this._findStreamLength(o,c);if(l>=0){const e=r.peekBytes(a+1)[a];if(!(0,s.isWhiteSpace)(e))break;(0,i.info)(`Found "${(0,i.bytesToString)(c)}" when `+"searching for endstream command.");t=l;break}}if(t<0)throw new i.FormatError("Missing endstream command.")}c=t;a.nextChar();this.shift();this.shift()}this.shift();r=r.makeSubStream(o,c,e);t&&(r=t.createStream(r,c));r=this.filter(r,e,c);r.dict=e;return r}filter(e,t,a){let r=t.get("Filter","F"),s=t.get("DecodeParms","DP");if((0,n.isName)(r)){Array.isArray(s)&&(0,i.warn)("/DecodeParms should not contain an Array, when /Filter contains a Name.");return this.makeFilter(e,r.name,a,s)}let o=a;if(Array.isArray(r)){const t=r,a=s;for(let c=0,l=t.length;c<l;++c){r=this.xref.fetchIfRef(t[c]);if(!(0,n.isName)(r))throw new i.FormatError(`Bad filter name "${r}"`);s=null;Array.isArray(a)&&c in a&&(s=this.xref.fetchIfRef(a[c]));e=this.makeFilter(e,r.name,o,s);o=null}}return e}makeFilter(e,t,a,n){if(0===a){(0,i.warn)(`Empty "${t}" stream.`);return new r.NullStream}try{const s=this.xref.stats.streamTypes;if("FlateDecode"===t||"Fl"===t){s[i.StreamType.FLATE]=!0;return n?new r.PredictorStream(new r.FlateStream(e,a),a,n):new r.FlateStream(e,a)}if("LZWDecode"===t||"LZW"===t){s[i.StreamType.LZW]=!0;let t=1;if(n){n.has("EarlyChange")&&(t=n.get("EarlyChange"));return new r.PredictorStream(new r.LZWStream(e,a,t),a,n)}return new r.LZWStream(e,a,t)}if("DCTDecode"===t||"DCT"===t){s[i.StreamType.DCT]=!0;return new l.JpegStream(e,a,e.dict,n)}if("JPXDecode"===t||"JPX"===t){s[i.StreamType.JPX]=!0;return new h.JpxStream(e,a,e.dict,n)}if("ASCII85Decode"===t||"A85"===t){s[i.StreamType.A85]=!0;return new r.Ascii85Stream(e,a)}if("ASCIIHexDecode"===t||"AHx"===t){s[i.StreamType.AHX]=!0;return new r.AsciiHexStream(e,a)}if("CCITTFaxDecode"===t||"CCF"===t){s[i.StreamType.CCF]=!0;return new o.CCITTFaxStream(e,a,n)}if("RunLengthDecode"===t||"RL"===t){s[i.StreamType.RLX]=!0;return new r.RunLengthStream(e,a)}if("JBIG2Decode"===t){s[i.StreamType.JBIG]=!0;return new c.Jbig2Stream(e,a,e.dict,n)}(0,i.warn)(`Filter "${t}" is not supported.`);return e}catch(e){if(e instanceof s.MissingDataException)throw e;(0,i.warn)(`Invalid stream: "${e}"`);return new r.NullStream}}}t.Parser=d;const f=[1,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];function g(e){return e>=48&&e<=57?15&e:e>=65&&e<=70||e>=97&&e<=102?9+(15&e):-1}class m{constructor(e,t=null){this.stream=e;this.nextChar();this.strBuf=[];this.knownCommands=t;this._hexStringNumWarn=0;this.beginInlineImagePos=-1}nextChar(){return this.currentChar=this.stream.getByte()}peekChar(){return this.stream.peekByte()}getNumber(){let e=this.currentChar,t=!1,a=0,r=0;if(45===e){r=-1;e=this.nextChar();45===e&&(e=this.nextChar())}else if(43===e){r=1;e=this.nextChar()}if(10===e||13===e)do{e=this.nextChar()}while(10===e||13===e);if(46===e){a=10;e=this.nextChar()}if(e<48||e>57){if(10===a&&0===r&&((0,s.isWhiteSpace)(e)||-1===e)){(0,i.warn)("Lexer.getNumber - treating a single decimal point as zero.");return 0}throw new i.FormatError(`Invalid number: ${String.fromCharCode(e)} (charCode ${e})`)}r=r||1;let n=e-48,o=0,c=1;for(;(e=this.nextChar())>=0;)if(e>=48&&e<=57){const r=e-48;if(t)o=10*o+r;else{0!==a&&(a*=10);n=10*n+r}}else if(46===e){if(0!==a)break;a=1}else if(45===e)(0,i.warn)("Badly formatted number: minus sign in the middle");else{if(69!==e&&101!==e)break;e=this.peekChar();if(43===e||45===e){c=45===e?-1:1;this.nextChar()}else if(e<48||e>57)break;t=!0}0!==a&&(n/=a);t&&(n*=10**(c*o));return r*n}getString(){let e=1,t=!1;const a=this.strBuf;a.length=0;let r=this.nextChar();for(;;){let n=!1;switch(0|r){case-1:(0,i.warn)("Unterminated string");t=!0;break;case 40:++e;a.push("(");break;case 41:if(0==--e){this.nextChar();t=!0}else a.push(")");break;case 92:r=this.nextChar();switch(r){case-1:(0,i.warn)("Unterminated string");t=!0;break;case 110:a.push("\n");break;case 114:a.push("\r");break;case 116:a.push("\t");break;case 98:a.push("\b");break;case 102:a.push("\f");break;case 92:case 40:case 41:a.push(String.fromCharCode(r));break;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:let e=15&r;r=this.nextChar();n=!0;if(r>=48&&r<=55){e=(e<<3)+(15&r);r=this.nextChar();if(r>=48&&r<=55){n=!1;e=(e<<3)+(15&r)}}a.push(String.fromCharCode(e));break;case 13:10===this.peekChar()&&this.nextChar();break;case 10:break;default:a.push(String.fromCharCode(r))}break;default:a.push(String.fromCharCode(r))}if(t)break;n||(r=this.nextChar())}return a.join("")}getName(){let e,t;const a=this.strBuf;a.length=0;for(;(e=this.nextChar())>=0&&!f[e];)if(35===e){e=this.nextChar();if(f[e]){(0,i.warn)("Lexer_getName: NUMBER SIGN (#) should be followed by a hexadecimal number.");a.push("#");break}const r=g(e);if(-1!==r){t=e;e=this.nextChar();const n=g(e);if(-1===n){(0,i.warn)(`Lexer_getName: Illegal digit (${String.fromCharCode(e)}) `+"in hexadecimal number.");a.push("#",String.fromCharCode(t));if(f[e])break;a.push(String.fromCharCode(e));continue}a.push(String.fromCharCode(r<<4|n))}else a.push("#",String.fromCharCode(e))}else a.push(String.fromCharCode(e));a.length>127&&(0,i.warn)(`Name token is longer than allowed by the spec: ${a.length}`);return n.Name.get(a.join(""))}_hexStringWarn(e){5!=this._hexStringNumWarn++?this._hexStringNumWarn>5||(0,i.warn)(`getHexString - ignoring invalid character: ${e}`):(0,i.warn)("getHexString - ignoring additional invalid characters.")}getHexString(){const e=this.strBuf;e.length=0;let t,a,r=this.currentChar,n=!0;this._hexStringNumWarn=0;for(;;){if(r<0){(0,i.warn)("Unterminated hex string");break}if(62===r){this.nextChar();break}if(1!==f[r]){if(n){t=g(r);if(-1===t){this._hexStringWarn(r);r=this.nextChar();continue}}else{a=g(r);if(-1===a){this._hexStringWarn(r);r=this.nextChar();continue}e.push(String.fromCharCode(t<<4|a))}n=!n;r=this.nextChar()}else r=this.nextChar()}return e.join("")}getObj(){let e=!1,t=this.currentChar;for(;;){if(t<0)return n.EOF;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(1!==f[t])break;t=this.nextChar()}switch(0|t){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return this.getNumber();case 40:return this.getString();case 47:return this.getName();case 91:this.nextChar();return n.Cmd.get("[");case 93:this.nextChar();return n.Cmd.get("]");case 60:t=this.nextChar();if(60===t){this.nextChar();return n.Cmd.get("<<")}return this.getHexString();case 62:t=this.nextChar();if(62===t){this.nextChar();return n.Cmd.get(">>")}return n.Cmd.get(">");case 123:this.nextChar();return n.Cmd.get("{");case 125:this.nextChar();return n.Cmd.get("}");case 41:this.nextChar();throw new i.FormatError(`Illegal character: ${t}`)}let a=String.fromCharCode(t);const r=this.knownCommands;let s=r&&void 0!==r[a];for(;(t=this.nextChar())>=0&&!f[t];){const e=a+String.fromCharCode(t);if(s&&void 0===r[e])break;if(128===a.length)throw new i.FormatError(`Command token too long: ${a.length}`);a=e;s=r&&void 0!==r[a]}if("true"===a)return!0;if("false"===a)return!1;if("null"===a)return null;"BI"===a&&(this.beginInlineImagePos=this.stream.pos);return n.Cmd.get(a)}skipToNextLine(){let e=this.currentChar;for(;e>=0;){if(13===e){e=this.nextChar();10===e&&this.nextChar();break}if(10===e){this.nextChar();break}e=this.nextChar()}}}t.Lexer=m;t.Linearization=class{static create(e){function t(e,t,a=!1){const r=e.get(t);if(Number.isInteger(r)&&(a?r>=0:r>0))return r;throw new Error(`The "${t}" parameter in the linearization `+"dictionary is invalid.")}const a=new d({lexer:new m(e),xref:null}),r=a.getObj(),s=a.getObj(),o=a.getObj(),c=a.getObj();let l,h;if(!(Number.isInteger(r)&&Number.isInteger(s)&&(0,n.isCmd)(o,"obj")&&(0,n.isDict)(c)&&(0,i.isNum)(l=c.get("Linearized"))&&l>0))return null;if((h=t(c,"L"))!==e.length)throw new Error('The "L" parameter in the linearization dictionary does not equal the stream length.');return{length:h,hints:function(e){const t=e.get("H");let a;if(Array.isArray(t)&&(2===(a=t.length)||4===a)){for(let e=0;e<a;e++){const a=t[e];if(!(Number.isInteger(a)&&a>0))throw new Error(`Hint (${e}) in the linearization dictionary is invalid.`)}return t}throw new Error("Hint array in the linearization dictionary is invalid.")}(c),objectNumberFirst:t(c,"O"),endFirst:t(c,"E"),numPages:t(c,"N"),mainXRefEntriesOffset:t(c,"T"),pageFirst:c.has("P")?t(c,"P",!0):0}}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.LZWStream=t.StringStream=t.StreamsSequenceStream=t.Stream=t.RunLengthStream=t.PredictorStream=t.NullStream=t.FlateStream=t.DecodeStream=t.DecryptStream=t.AsciiHexStream=t.Ascii85Stream=void 0;var r=a(2),i=a(4),n=a(7),s=function(){function e(e,t,a,r){this.bytes=e instanceof Uint8Array?e:new Uint8Array(e);this.start=t||0;this.pos=this.start;this.end=t+a||this.bytes.length;this.dict=r}e.prototype={get length(){return this.end-this.start},get isEmpty(){return 0===this.length},getByte:function(){return this.pos>=this.end?-1:this.bytes[this.pos++]},getUint16:function(){var e=this.getByte(),t=this.getByte();return-1===e||-1===t?-1:(e<<8)+t},getInt32:function(){return(this.getByte()<<24)+(this.getByte()<<16)+(this.getByte()<<8)+this.getByte()},getBytes(e,t=!1){var a=this.bytes,r=this.pos,i=this.end;if(!e){const e=a.subarray(r,i);return t?new Uint8ClampedArray(e):e}var n=r+e;n>i&&(n=i);this.pos=n;const s=a.subarray(r,n);return t?new Uint8ClampedArray(s):s},peekByte:function(){var e=this.getByte();-1!==e&&this.pos--;return e},peekBytes(e,t=!1){var a=this.getBytes(e,t);this.pos-=a.length;return a},getByteRange(e,t){e<0&&(e=0);t>this.end&&(t=this.end);return this.bytes.subarray(e,t)},skip:function(e){e||(e=1);this.pos+=e},reset:function(){this.pos=this.start},moveStart:function(){this.start=this.pos},makeSubStream:function(t,a,r){return new e(this.bytes.buffer,t,a,r)}};return e}();t.Stream=s;var o=function(){function e(e){const t=(0,r.stringToBytes)(e);s.call(this,t)}e.prototype=s.prototype;return e}();t.StringStream=o;var c=function(){var e=new Uint8Array(0);function t(t){this._rawMinBufferLength=t||0;this.pos=0;this.bufferLength=0;this.eof=!1;this.buffer=e;this.minBufferLength=512;if(t)for(;this.minBufferLength<t;)this.minBufferLength*=2}t.prototype={get isEmpty(){for(;!this.eof&&0===this.bufferLength;)this.readBlock();return 0===this.bufferLength},ensureBuffer:function(e){var t=this.buffer;if(e<=t.byteLength)return t;for(var a=this.minBufferLength;a<e;)a*=2;var r=new Uint8Array(a);r.set(t);return this.buffer=r},getByte:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return-1;this.readBlock()}return this.buffer[this.pos++]},getUint16:function(){var e=this.getByte(),t=this.getByte();return-1===e||-1===t?-1:(e<<8)+t},getInt32:function(){return(this.getByte()<<24)+(this.getByte()<<16)+(this.getByte()<<8)+this.getByte()},getBytes(e,t=!1){var a,r=this.pos;if(e){this.ensureBuffer(r+e);a=r+e;for(;!this.eof&&this.bufferLength<a;)this.readBlock();var i=this.bufferLength;a>i&&(a=i)}else{for(;!this.eof;)this.readBlock();a=this.bufferLength}this.pos=a;const n=this.buffer.subarray(r,a);return!t||n instanceof Uint8ClampedArray?n:new Uint8ClampedArray(n)},peekByte:function(){var e=this.getByte();-1!==e&&this.pos--;return e},peekBytes(e,t=!1){var a=this.getBytes(e,t);this.pos-=a.length;return a},makeSubStream:function(e,t,a){for(var r=e+t;this.bufferLength<=r&&!this.eof;)this.readBlock();return new s(this.buffer,e,t,a)},getByteRange(e,t){(0,r.unreachable)("Should not call DecodeStream.getByteRange")},skip:function(e){e||(e=1);this.pos+=e},reset:function(){this.pos=0},getBaseStreams:function(){return this.str&&this.str.getBaseStreams?this.str.getBaseStreams():[]}};return t}();t.DecodeStream=c;var l=function(){function e(e){this.streams=e;let t=0;for(let a=0,r=e.length;a<r;a++){const r=e[a];t+=r instanceof c?r._rawMinBufferLength:r.length}c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){var e=this.streams;if(0!==e.length){var t=e.shift().getBytes(),a=this.bufferLength,r=a+t.length;this.ensureBuffer(r).set(t,a);this.bufferLength=r}else this.eof=!0};e.prototype.getBaseStreams=function(){for(var e=[],t=0,a=this.streams.length;t<a;t++){var r=this.streams[t];r.getBaseStreams&&e.push(...r.getBaseStreams())}return e};return e}();t.StreamsSequenceStream=l;var h=function(){var e=new Int32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),t=new Int32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),a=new Int32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),i=[new Int32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],n=[new Int32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];function s(e,t){this.str=e;this.dict=e.dict;var a=e.getByte(),i=e.getByte();if(-1===a||-1===i)throw new r.FormatError(`Invalid header in flate stream: ${a}, ${i}`);if(8!=(15&a))throw new r.FormatError(`Unknown compression method in flate stream: ${a}, ${i}`);if(((a<<8)+i)%31!=0)throw new r.FormatError(`Bad FCHECK in flate stream: ${a}, ${i}`);if(32&i)throw new r.FormatError(`FDICT bit set in flate stream: ${a}, ${i}`);this.codeSize=0;this.codeBuf=0;c.call(this,t)}s.prototype=Object.create(c.prototype);s.prototype.getBits=function(e){for(var t,a=this.str,i=this.codeSize,n=this.codeBuf;i<e;){if(-1===(t=a.getByte()))throw new r.FormatError("Bad encoding in flate stream");n|=t<<i;i+=8}t=n&(1<<e)-1;this.codeBuf=n>>e;this.codeSize=i-=e;return t};s.prototype.getCode=function(e){for(var t,a=this.str,i=e[0],n=e[1],s=this.codeSize,o=this.codeBuf;s<n&&-1!==(t=a.getByte());){o|=t<<s;s+=8}var c=i[o&(1<<n)-1],l=c>>16,h=65535&c;if(l<1||s<l)throw new r.FormatError("Bad encoding in flate stream");this.codeBuf=o>>l;this.codeSize=s-l;return h};s.prototype.generateHuffmanTable=function(e){var t,a=e.length,r=0;for(t=0;t<a;++t)e[t]>r&&(r=e[t]);for(var i=1<<r,n=new Int32Array(i),s=1,o=0,c=2;s<=r;++s,o<<=1,c<<=1)for(var l=0;l<a;++l)if(e[l]===s){var h=0,u=o;for(t=0;t<s;++t){h=h<<1|1&u;u>>=1}for(t=h;t<i;t+=c)n[t]=s<<16|l;++o}return[n,r]};s.prototype.readBlock=function(){var s,o,c=this.str,l=this.getBits(3);1&l&&(this.eof=!0);if(0!==(l>>=1)){var h,u;if(1===l){h=i;u=n}else{if(2!==l)throw new r.FormatError("Unknown block type in flate stream");var d,f=this.getBits(5)+257,g=this.getBits(5)+1,m=this.getBits(4)+4,p=new Uint8Array(e.length);for(d=0;d<m;++d)p[e[d]]=this.getBits(3);var b=this.generateHuffmanTable(p);o=0;d=0;for(var y,v,w,k=f+g,S=new Uint8Array(k);d<k;){var C=this.getCode(b);if(16===C){y=2;v=3;w=o}else if(17===C){y=3;v=3;w=o=0}else{if(18!==C){S[d++]=o=C;continue}y=7;v=11;w=o=0}for(var x=this.getBits(y)+v;x-- >0;)S[d++]=w}h=this.generateHuffmanTable(S.subarray(0,f));u=this.generateHuffmanTable(S.subarray(f,k))}for(var A=(s=this.buffer)?s.length:0,I=this.bufferLength;;){var F=this.getCode(h);if(F<256){I+1>=A&&(A=(s=this.ensureBuffer(I+1)).length);s[I++]=F}else{if(256===F){this.bufferLength=I;return}var T=(F=t[F-=257])>>16;T>0&&(T=this.getBits(T));o=(65535&F)+T;F=this.getCode(u);(T=(F=a[F])>>16)>0&&(T=this.getBits(T));var E=(65535&F)+T;I+o>=A&&(A=(s=this.ensureBuffer(I+o)).length);for(var O=0;O<o;++O,++I)s[I]=s[I-E]}}}else{var P;if(-1===(P=c.getByte()))throw new r.FormatError("Bad block header in flate stream");var B=P;if(-1===(P=c.getByte()))throw new r.FormatError("Bad block header in flate stream");B|=P<<8;if(-1===(P=c.getByte()))throw new r.FormatError("Bad block header in flate stream");var D=P;if(-1===(P=c.getByte()))throw new r.FormatError("Bad block header in flate stream");if((D|=P<<8)!==(65535&~B)&&(0!==B||0!==D))throw new r.FormatError("Bad uncompressed block length in flate stream");this.codeBuf=0;this.codeSize=0;const e=this.bufferLength,t=e+B;s=this.ensureBuffer(t);this.bufferLength=t;if(0===B)-1===c.peekByte()&&(this.eof=!0);else{const t=c.getBytes(B);s.set(t,e);t.length<B&&(this.eof=!0)}}};return s}();t.FlateStream=h;var u=function(){function e(e,t,a){if(!(0,i.isDict)(a))return e;var n=this.predictor=a.get("Predictor")||1;if(n<=1)return e;if(2!==n&&(n<10||n>15))throw new r.FormatError(`Unsupported predictor: ${n}`);this.readBlock=2===n?this.readBlockTiff:this.readBlockPng;this.str=e;this.dict=e.dict;var s=this.colors=a.get("Colors")||1,o=this.bits=a.get("BitsPerComponent")||8,l=this.columns=a.get("Columns")||1;this.pixBytes=s*o+7>>3;this.rowBytes=l*s*o+7>>3;c.call(this,t);return this}e.prototype=Object.create(c.prototype);e.prototype.readBlockTiff=function(){var e=this.rowBytes,t=this.bufferLength,a=this.ensureBuffer(t+e),r=this.bits,i=this.colors,n=this.str.getBytes(e);this.eof=!n.length;if(!this.eof){var s,o=0,c=0,l=0,h=0,u=t;if(1===r&&1===i)for(s=0;s<e;++s){var d=n[s]^o;d^=d>>1;d^=d>>2;o=(1&(d^=d>>4))<<7;a[u++]=d}else if(8===r){for(s=0;s<i;++s)a[u++]=n[s];for(;s<e;++s){a[u]=a[u-i]+n[s];u++}}else if(16===r){var f=2*i;for(s=0;s<f;++s)a[u++]=n[s];for(;s<e;s+=2){var g=((255&n[s])<<8)+(255&n[s+1])+((255&a[u-f])<<8)+(255&a[u-f+1]);a[u++]=g>>8&255;a[u++]=255&g}}else{var m=new Uint8Array(i+1),p=(1<<r)-1,b=0,y=t,v=this.columns;for(s=0;s<v;++s)for(var w=0;w<i;++w){if(l<r){o=o<<8|255&n[b++];l+=8}m[w]=m[w]+(o>>l-r)&p;l-=r;c=c<<r|m[w];if((h+=r)>=8){a[y++]=c>>h-8&255;h-=8}}h>0&&(a[y++]=(c<<8-h)+(o&(1<<8-h)-1))}this.bufferLength+=e}};e.prototype.readBlockPng=function(){var e=this.rowBytes,t=this.pixBytes,a=this.str.getByte(),i=this.str.getBytes(e);this.eof=!i.length;if(!this.eof){var n=this.bufferLength,s=this.ensureBuffer(n+e),o=s.subarray(n-e,n);0===o.length&&(o=new Uint8Array(e));var c,l,h,u=n;switch(a){case 0:for(c=0;c<e;++c)s[u++]=i[c];break;case 1:for(c=0;c<t;++c)s[u++]=i[c];for(;c<e;++c){s[u]=s[u-t]+i[c]&255;u++}break;case 2:for(c=0;c<e;++c)s[u++]=o[c]+i[c]&255;break;case 3:for(c=0;c<t;++c)s[u++]=(o[c]>>1)+i[c];for(;c<e;++c){s[u]=(o[c]+s[u-t]>>1)+i[c]&255;u++}break;case 4:for(c=0;c<t;++c){l=o[c];h=i[c];s[u++]=l+h}for(;c<e;++c){l=o[c];var d=o[c-t],f=s[u-t],g=f+l-d,m=g-f;m<0&&(m=-m);var p=g-l;p<0&&(p=-p);var b=g-d;b<0&&(b=-b);h=i[c];s[u++]=m<=p&&m<=b?f+h:p<=b?l+h:d+h}break;default:throw new r.FormatError(`Unsupported predictor: ${a}`)}this.bufferLength+=e}};return e}();t.PredictorStream=u;var d=function(){function e(e,t,a){this.str=e;this.dict=e.dict;this.decrypt=a;this.nextChunk=null;this.initialized=!1;c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){var e;if(this.initialized)e=this.nextChunk;else{e=this.str.getBytes(512);this.initialized=!0}if(e&&0!==e.length){this.nextChunk=this.str.getBytes(512);var t=this.nextChunk&&this.nextChunk.length>0;e=(0,this.decrypt)(e,!t);var a,r=this.bufferLength,i=e.length,n=this.ensureBuffer(r+i);for(a=0;a<i;a++)n[r++]=e[a];this.bufferLength=r}else this.eof=!0};return e}();t.DecryptStream=d;var f=function(){function e(e,t){this.str=e;this.dict=e.dict;this.input=new Uint8Array(5);t&&(t*=.8);c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){for(var e=this.str,t=e.getByte();(0,n.isWhiteSpace)(t);)t=e.getByte();if(-1!==t&&126!==t){var a,r,i=this.bufferLength;if(122===t){a=this.ensureBuffer(i+4);for(r=0;r<4;++r)a[i+r]=0;this.bufferLength+=4}else{var s=this.input;s[0]=t;for(r=1;r<5;++r){t=e.getByte();for(;(0,n.isWhiteSpace)(t);)t=e.getByte();s[r]=t;if(-1===t||126===t)break}a=this.ensureBuffer(i+r-1);this.bufferLength+=r-1;if(r<5){for(;r<5;++r)s[r]=117;this.eof=!0}var o=0;for(r=0;r<5;++r)o=85*o+(s[r]-33);for(r=3;r>=0;--r){a[i+r]=255&o;o>>=8}}}else this.eof=!0};return e}();t.Ascii85Stream=f;var g=function(){function e(e,t){this.str=e;this.dict=e.dict;this.firstDigit=-1;t&&(t*=.5);c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){var e=this.str.getBytes(8e3);if(e.length){for(var t=e.length+1>>1,a=this.ensureBuffer(this.bufferLength+t),r=this.bufferLength,i=this.firstDigit,n=0,s=e.length;n<s;n++){var o,c=e[n];if(c>=48&&c<=57)o=15&c;else{if(!(c>=65&&c<=70||c>=97&&c<=102)){if(62===c){this.eof=!0;break}continue}o=9+(15&c)}if(i<0)i=o;else{a[r++]=i<<4|o;i=-1}}if(i>=0&&this.eof){a[r++]=i<<4;i=-1}this.firstDigit=i;this.bufferLength=r}else this.eof=!0};return e}();t.AsciiHexStream=g;var m=function(){function e(e,t){this.str=e;this.dict=e.dict;c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBlock=function(){var e=this.str.getBytes(2);if(!e||e.length<2||128===e[0])this.eof=!0;else{var t,a=this.bufferLength,r=e[0];if(r<128){(t=this.ensureBuffer(a+r+1))[a++]=e[1];if(r>0){var i=this.str.getBytes(r);t.set(i,a);a+=r}}else{r=257-r;var n=e[1];t=this.ensureBuffer(a+r+1);for(var s=0;s<r;s++)t[a++]=n}this.bufferLength=a}};return e}();t.RunLengthStream=m;var p=function(){function e(e,t,a){this.str=e;this.dict=e.dict;this.cachedData=0;this.bitsCached=0;for(var r={earlyChange:a,codeLength:9,nextCode:258,dictionaryValues:new Uint8Array(4096),dictionaryLengths:new Uint16Array(4096),dictionaryPrevCodes:new Uint16Array(4096),currentSequence:new Uint8Array(4096),currentSequenceLength:0},i=0;i<256;++i){r.dictionaryValues[i]=i;r.dictionaryLengths[i]=1}this.lzwState=r;c.call(this,t)}e.prototype=Object.create(c.prototype);e.prototype.readBits=function(e){for(var t=this.bitsCached,a=this.cachedData;t<e;){var r=this.str.getByte();if(-1===r){this.eof=!0;return null}a=a<<8|r;t+=8}this.bitsCached=t-=e;this.cachedData=a;this.lastCode=null;return a>>>t&(1<<e)-1};e.prototype.readBlock=function(){var e,t,a,r=1024,i=this.lzwState;if(i){var n=i.earlyChange,s=i.nextCode,o=i.dictionaryValues,c=i.dictionaryLengths,l=i.dictionaryPrevCodes,h=i.codeLength,u=i.prevCode,d=i.currentSequence,f=i.currentSequenceLength,g=0,m=this.bufferLength,p=this.ensureBuffer(this.bufferLength+r);for(e=0;e<512;e++){var b=this.readBits(h),y=f>0;if(b<256){d[0]=b;f=1}else{if(!(b>=258)){if(256===b){h=9;s=258;f=0;continue}this.eof=!0;delete this.lzwState;break}if(b<s)for(t=(f=c[b])-1,a=b;t>=0;t--){d[t]=o[a];a=l[a]}else d[f++]=d[0]}if(y){l[s]=u;c[s]=c[u]+1;o[s]=d[0];h=++s+n&s+n-1?h:0|Math.min(Math.log(s+n)/.6931471805599453+1,12)}u=b;if(r<(g+=f)){do{r+=512}while(r<g);p=this.ensureBuffer(this.bufferLength+r)}for(t=0;t<f;t++)p[m++]=d[t]}i.nextCode=s;i.codeLength=h;i.prevCode=u;i.currentSequenceLength=f;this.bufferLength=m}};return e}();t.LZWStream=p;var b=function(){function e(){s.call(this,new Uint8Array(0))}e.prototype=s.prototype;return e}();t.NullStream=b},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.CCITTFaxStream=void 0;var r=a(4),i=a(13),n=a(11),s=function(){function e(e,t,a){this.str=e;this.dict=e.dict;(0,r.isDict)(a)||(a=r.Dict.empty);const s={next:()=>e.getByte()};this.ccittFaxDecoder=new i.CCITTFaxDecoder(s,{K:a.get("K"),EndOfLine:a.get("EndOfLine"),EncodedByteAlign:a.get("EncodedByteAlign"),Columns:a.get("Columns"),Rows:a.get("Rows"),EndOfBlock:a.get("EndOfBlock"),BlackIs1:a.get("BlackIs1")});n.DecodeStream.call(this,t)}e.prototype=Object.create(n.DecodeStream.prototype);e.prototype.readBlock=function(){for(;!this.eof;){const e=this.ccittFaxDecoder.readNextChar();if(-1===e){this.eof=!0;return}this.ensureBuffer(this.bufferLength+1);this.buffer[this.bufferLength++]=e}};return e}();t.CCITTFaxStream=s},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.CCITTFaxDecoder=void 0;var r=a(2);const i=function(){const e=[[-1,-1],[-1,-1],[7,8],[7,7],[6,6],[6,6],[6,5],[6,5],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2]],t=[[-1,-1],[12,-2],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[11,1792],[11,1792],[12,1984],[12,2048],[12,2112],[12,2176],[12,2240],[12,2304],[11,1856],[11,1856],[11,1920],[11,1920],[12,2368],[12,2432],[12,2496],[12,2560]],a=[[-1,-1],[-1,-1],[-1,-1],[-1,-1],[8,29],[8,29],[8,30],[8,30],[8,45],[8,45],[8,46],[8,46],[7,22],[7,22],[7,22],[7,22],[7,23],[7,23],[7,23],[7,23],[8,47],[8,47],[8,48],[8,48],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[7,20],[7,20],[7,20],[7,20],[8,33],[8,33],[8,34],[8,34],[8,35],[8,35],[8,36],[8,36],[8,37],[8,37],[8,38],[8,38],[7,19],[7,19],[7,19],[7,19],[8,31],[8,31],[8,32],[8,32],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[8,53],[8,53],[8,54],[8,54],[7,26],[7,26],[7,26],[7,26],[8,39],[8,39],[8,40],[8,40],[8,41],[8,41],[8,42],[8,42],[8,43],[8,43],[8,44],[8,44],[7,21],[7,21],[7,21],[7,21],[7,28],[7,28],[7,28],[7,28],[8,61],[8,61],[8,62],[8,62],[8,63],[8,63],[8,0],[8,0],[8,320],[8,320],[8,384],[8,384],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[7,27],[7,27],[7,27],[7,27],[8,59],[8,59],[8,60],[8,60],[9,1472],[9,1536],[9,1600],[9,1728],[7,18],[7,18],[7,18],[7,18],[7,24],[7,24],[7,24],[7,24],[8,49],[8,49],[8,50],[8,50],[8,51],[8,51],[8,52],[8,52],[7,25],[7,25],[7,25],[7,25],[8,55],[8,55],[8,56],[8,56],[8,57],[8,57],[8,58],[8,58],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[8,448],[8,448],[8,512],[8,512],[9,704],[9,768],[8,640],[8,640],[8,576],[8,576],[9,832],[9,896],[9,960],[9,1024],[9,1088],[9,1152],[9,1216],[9,1280],[9,1344],[9,1408],[7,256],[7,256],[7,256],[7,256],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7]],i=[[-1,-1],[-1,-1],[12,-2],[12,-2],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[11,1792],[11,1792],[11,1792],[11,1792],[12,1984],[12,1984],[12,2048],[12,2048],[12,2112],[12,2112],[12,2176],[12,2176],[12,2240],[12,2240],[12,2304],[12,2304],[11,1856],[11,1856],[11,1856],[11,1856],[11,1920],[11,1920],[11,1920],[11,1920],[12,2368],[12,2368],[12,2432],[12,2432],[12,2496],[12,2496],[12,2560],[12,2560],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[12,52],[12,52],[13,640],[13,704],[13,768],[13,832],[12,55],[12,55],[12,56],[12,56],[13,1280],[13,1344],[13,1408],[13,1472],[12,59],[12,59],[12,60],[12,60],[13,1536],[13,1600],[11,24],[11,24],[11,24],[11,24],[11,25],[11,25],[11,25],[11,25],[13,1664],[13,1728],[12,320],[12,320],[12,384],[12,384],[12,448],[12,448],[13,512],[13,576],[12,53],[12,53],[12,54],[12,54],[13,896],[13,960],[13,1024],[13,1088],[13,1152],[13,1216],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64]],n=[[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[11,23],[11,23],[12,50],[12,51],[12,44],[12,45],[12,46],[12,47],[12,57],[12,58],[12,61],[12,256],[10,16],[10,16],[10,16],[10,16],[10,17],[10,17],[10,17],[10,17],[12,48],[12,49],[12,62],[12,63],[12,30],[12,31],[12,32],[12,33],[12,40],[12,41],[11,22],[11,22],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[12,128],[12,192],[12,26],[12,27],[12,28],[12,29],[11,19],[11,19],[11,20],[11,20],[12,34],[12,35],[12,36],[12,37],[12,38],[12,39],[11,21],[11,21],[12,42],[12,43],[10,0],[10,0],[10,0],[10,0],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12]],s=[[-1,-1],[-1,-1],[-1,-1],[-1,-1],[6,9],[6,8],[5,7],[5,7],[4,6],[4,6],[4,6],[4,6],[4,5],[4,5],[4,5],[4,5],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2]];function o(e,t={}){if(!e||"function"!=typeof e.next)throw new Error('CCITTFaxDecoder - invalid "source" parameter.');this.source=e;this.eof=!1;this.encoding=t.K||0;this.eoline=t.EndOfLine||!1;this.byteAlign=t.EncodedByteAlign||!1;this.columns=t.Columns||1728;this.rows=t.Rows||0;let a,r=t.EndOfBlock;null==r&&(r=!0);this.eoblock=r;this.black=t.BlackIs1||!1;this.codingLine=new Uint32Array(this.columns+1);this.refLine=new Uint32Array(this.columns+2);this.codingLine[0]=this.columns;this.codingPos=0;this.row=0;this.nextLine2D=this.encoding<0;this.inputBits=0;this.inputBuf=0;this.outputBits=0;this.rowsDone=!1;for(;0===(a=this._lookBits(12));)this._eatBits(1);1===a&&this._eatBits(12);if(this.encoding>0){this.nextLine2D=!this._lookBits(1);this._eatBits(1)}}o.prototype={readNextChar(){if(this.eof)return-1;const e=this.refLine,t=this.codingLine,a=this.columns;let i,n,s,o,c;if(0===this.outputBits){this.rowsDone&&(this.eof=!0);if(this.eof)return-1;this.err=!1;let s,c,l;if(this.nextLine2D){for(o=0;t[o]<a;++o)e[o]=t[o];e[o++]=a;e[o]=a;t[0]=0;this.codingPos=0;i=0;n=0;for(;t[this.codingPos]<a;){s=this._getTwoDimCode();switch(s){case 0:this._addPixels(e[i+1],n);e[i+1]<a&&(i+=2);break;case 1:s=c=0;if(n){do{s+=l=this._getBlackCode()}while(l>=64);do{c+=l=this._getWhiteCode()}while(l>=64)}else{do{s+=l=this._getWhiteCode()}while(l>=64);do{c+=l=this._getBlackCode()}while(l>=64)}this._addPixels(t[this.codingPos]+s,n);t[this.codingPos]<a&&this._addPixels(t[this.codingPos]+c,1^n);for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2;break;case 7:this._addPixels(e[i]+3,n);n^=1;if(t[this.codingPos]<a){++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 5:this._addPixels(e[i]+2,n);n^=1;if(t[this.codingPos]<a){++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 3:this._addPixels(e[i]+1,n);n^=1;if(t[this.codingPos]<a){++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 2:this._addPixels(e[i],n);n^=1;if(t[this.codingPos]<a){++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 8:this._addPixelsNeg(e[i]-3,n);n^=1;if(t[this.codingPos]<a){i>0?--i:++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 6:this._addPixelsNeg(e[i]-2,n);n^=1;if(t[this.codingPos]<a){i>0?--i:++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case 4:this._addPixelsNeg(e[i]-1,n);n^=1;if(t[this.codingPos]<a){i>0?--i:++i;for(;e[i]<=t[this.codingPos]&&e[i]<a;)i+=2}break;case-1:this._addPixels(a,0);this.eof=!0;break;default:(0,r.info)("bad 2d code");this._addPixels(a,0);this.err=!0}}}else{t[0]=0;this.codingPos=0;n=0;for(;t[this.codingPos]<a;){s=0;if(n)do{s+=l=this._getBlackCode()}while(l>=64);else do{s+=l=this._getWhiteCode()}while(l>=64);this._addPixels(t[this.codingPos]+s,n);n^=1}}let h=!1;this.byteAlign&&(this.inputBits&=-8);if(this.eoblock||this.row!==this.rows-1){s=this._lookBits(12);if(this.eoline)for(;-1!==s&&1!==s;){this._eatBits(1);s=this._lookBits(12)}else for(;0===s;){this._eatBits(1);s=this._lookBits(12)}if(1===s){this._eatBits(12);h=!0}else-1===s&&(this.eof=!0)}else this.rowsDone=!0;if(!this.eof&&this.encoding>0&&!this.rowsDone){this.nextLine2D=!this._lookBits(1);this._eatBits(1)}if(this.eoblock&&h&&this.byteAlign){s=this._lookBits(12);if(1===s){this._eatBits(12);if(this.encoding>0){this._lookBits(1);this._eatBits(1)}if(this.encoding>=0)for(o=0;o<4;++o){s=this._lookBits(12);1!==s&&(0,r.info)("bad rtc code: "+s);this._eatBits(12);if(this.encoding>0){this._lookBits(1);this._eatBits(1)}}this.eof=!0}}else if(this.err&&this.eoline){for(;;){s=this._lookBits(13);if(-1===s){this.eof=!0;return-1}if(s>>1==1)break;this._eatBits(1)}this._eatBits(12);if(this.encoding>0){this._eatBits(1);this.nextLine2D=!(1&s)}}t[0]>0?this.outputBits=t[this.codingPos=0]:this.outputBits=t[this.codingPos=1];this.row++}if(this.outputBits>=8){c=1&this.codingPos?0:255;this.outputBits-=8;if(0===this.outputBits&&t[this.codingPos]<a){this.codingPos++;this.outputBits=t[this.codingPos]-t[this.codingPos-1]}}else{s=8;c=0;do{if(this.outputBits>s){c<<=s;1&this.codingPos||(c|=255>>8-s);this.outputBits-=s;s=0}else{c<<=this.outputBits;1&this.codingPos||(c|=255>>8-this.outputBits);s-=this.outputBits;this.outputBits=0;if(t[this.codingPos]<a){this.codingPos++;this.outputBits=t[this.codingPos]-t[this.codingPos-1]}else if(s>0){c<<=s;s=0}}}while(s)}this.black&&(c^=255);return c},_addPixels(e,t){const a=this.codingLine;let i=this.codingPos;if(e>a[i]){if(e>this.columns){(0,r.info)("row is wrong length");this.err=!0;e=this.columns}1&i^t&&++i;a[i]=e}this.codingPos=i},_addPixelsNeg(e,t){const a=this.codingLine;let i=this.codingPos;if(e>a[i]){if(e>this.columns){(0,r.info)("row is wrong length");this.err=!0;e=this.columns}1&i^t&&++i;a[i]=e}else if(e<a[i]){if(e<0){(0,r.info)("invalid code");this.err=!0;e=0}for(;i>0&&e<a[i-1];)--i;a[i]=e}this.codingPos=i},_findTableCode(e,t,a,r){const i=r||0;for(let r=e;r<=t;++r){let e=this._lookBits(r);if(-1===e)return[!0,1,!1];r<t&&(e<<=t-r);if(!i||e>=i){const t=a[e-i];if(t[0]===r){this._eatBits(r);return[!0,t[1],!0]}}}return[!1,0,!1]},_getTwoDimCode(){let t,a=0;if(this.eoblock){a=this._lookBits(7);t=e[a];if(t&&t[0]>0){this._eatBits(t[0]);return t[1]}}else{const t=this._findTableCode(1,7,e);if(t[0]&&t[2])return t[1]}(0,r.info)("Bad two dim code");return-1},_getWhiteCode(){let e,i=0;if(this.eoblock){i=this._lookBits(12);if(-1===i)return 1;e=i>>5==0?t[i]:a[i>>3];if(e[0]>0){this._eatBits(e[0]);return e[1]}}else{let e=this._findTableCode(1,9,a);if(e[0])return e[1];e=this._findTableCode(11,12,t);if(e[0])return e[1]}(0,r.info)("bad white code");this._eatBits(1);return 1},_getBlackCode(){let e,t;if(this.eoblock){e=this._lookBits(13);if(-1===e)return 1;t=e>>7==0?i[e]:e>>9==0&&e>>7!=0?n[(e>>1)-64]:s[e>>7];if(t[0]>0){this._eatBits(t[0]);return t[1]}}else{let e=this._findTableCode(2,6,s);if(e[0])return e[1];e=this._findTableCode(7,12,n,64);if(e[0])return e[1];e=this._findTableCode(10,13,i);if(e[0])return e[1]}(0,r.info)("bad black code");this._eatBits(1);return 1},_lookBits(e){let t;for(;this.inputBits<e;){if(-1===(t=this.source.next()))return 0===this.inputBits?-1:this.inputBuf<<e-this.inputBits&65535>>16-e;this.inputBuf=this.inputBuf<<8|t;this.inputBits+=8}return this.inputBuf>>this.inputBits-e&65535>>16-e},_eatBits(e){(this.inputBits-=e)<0&&(this.inputBits=0)}};return o}();t.CCITTFaxDecoder=i},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Jbig2Stream=void 0;var r=a(4),i=a(11),n=a(15),s=a(2);const o=function(){function e(e,t,a,r){this.stream=e;this.maybeLength=t;this.dict=a;this.params=r;i.DecodeStream.call(this,t)}e.prototype=Object.create(i.DecodeStream.prototype);Object.defineProperty(e.prototype,"bytes",{get(){return(0,s.shadow)(this,"bytes",this.stream.getBytes(this.maybeLength))},configurable:!0});e.prototype.ensureBuffer=function(e){};e.prototype.readBlock=function(){if(this.eof)return;const e=new n.Jbig2Image,t=[];if((0,r.isDict)(this.params)){const e=this.params.get("JBIG2Globals");if((0,r.isStream)(e)){const a=e.getBytes();t.push({data:a,start:0,end:a.length})}}t.push({data:this.bytes,start:0,end:this.bytes.length});const a=e.parseChunks(t),i=a.length;for(let e=0;e<i;e++)a[e]^=255;this.buffer=a;this.bufferLength=i;this.eof=!0};return e}();t.Jbig2Stream=o},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Jbig2Image=void 0;var r=a(2),i=a(7),n=a(16),s=a(13);class o extends r.BaseException{constructor(e){super(`JBIG2 error: ${e}`)}}var c=function(){function e(){}e.prototype={getContexts(e){return e in this?this[e]:this[e]=new Int8Array(65536)}};function t(e,t,a){this.data=e;this.start=t;this.end=a}t.prototype={get decoder(){var e=new n.ArithmeticDecoder(this.data,this.start,this.end);return(0,r.shadow)(this,"decoder",e)},get contextCache(){var t=new e;return(0,r.shadow)(this,"contextCache",t)}};function a(e,t,a){var r=e.getContexts(t),i=1;function n(e){for(var t=0,n=0;n<e;n++){var s=a.readBit(r,i);i=i<256?i<<1|s:511&(i<<1|s)|256;t=t<<1|s}return t>>>0}var s=n(1),o=n(1)?n(1)?n(1)?n(1)?n(1)?n(32)+4436:n(12)+340:n(8)+84:n(6)+20:n(4)+4:n(2);return 0===s?o:o>0?-o:null}function c(e,t,a){for(var r=e.getContexts("IAID"),i=1,n=0;n<a;n++){i=i<<1|t.readBit(r,i)}return a<31?i&(1<<a)-1:2147483647&i}var l=["SymbolDictionary",null,null,null,"IntermediateTextRegion",null,"ImmediateTextRegion","ImmediateLosslessTextRegion",null,null,null,null,null,null,null,null,"PatternDictionary",null,null,null,"IntermediateHalftoneRegion",null,"ImmediateHalftoneRegion","ImmediateLosslessHalftoneRegion",null,null,null,null,null,null,null,null,null,null,null,null,"IntermediateGenericRegion",null,"ImmediateGenericRegion","ImmediateLosslessGenericRegion","IntermediateGenericRefinementRegion",null,"ImmediateGenericRefinementRegion","ImmediateLosslessGenericRefinementRegion",null,null,null,null,"PageInformation","EndOfPage","EndOfStripe","EndOfFile","Profiles","Tables",null,null,null,null,null,null,null,null,"Extension"],h=[[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:2,y:-1},{x:-4,y:0},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}],[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:2,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:2,y:-1},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}],[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-2,y:0},{x:-1,y:0}],[{x:-3,y:-1},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-4,y:0},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}]],u=[{coding:[{x:0,y:-1},{x:1,y:-1},{x:-1,y:0}],reference:[{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:0,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}]},{coding:[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0}],reference:[{x:0,y:-1},{x:-1,y:0},{x:0,y:0},{x:1,y:0},{x:0,y:1},{x:1,y:1}]}],d=[39717,1941,229,405],f=[32,8];function g(e,t,a,r,i,n,s,o){if(e){return B(new E(o.data,o.start,o.end),t,a,!1)}if(0===r&&!n&&!i&&4===s.length&&3===s[0].x&&-1===s[0].y&&-3===s[1].x&&-1===s[1].y&&2===s[2].x&&-2===s[2].y&&-2===s[3].x&&-2===s[3].y)return function(e,t,a){var r,i,n,s,o,c,l,h=a.decoder,u=a.contextCache.getContexts("GB"),d=[];for(i=0;i<t;i++){o=d[i]=new Uint8Array(e);c=i<1?o:d[i-1];r=(l=i<2?o:d[i-2])[0]<<13|l[1]<<12|l[2]<<11|c[0]<<7|c[1]<<6|c[2]<<5|c[3]<<4;for(n=0;n<e;n++){o[n]=s=h.readBit(u,r);r=(31735&r)<<1|(n+3<e?l[n+3]<<11:0)|(n+4<e?c[n+4]<<4:0)|s}}return d}(t,a,o);var c=!!n,l=h[r].concat(s);l.sort((function(e,t){return e.y-t.y||e.x-t.x}));var u,f,g=l.length,m=new Int8Array(g),p=new Int8Array(g),b=[],y=0,v=0,w=0,k=0;for(f=0;f<g;f++){m[f]=l[f].x;p[f]=l[f].y;v=Math.min(v,l[f].x);w=Math.max(w,l[f].x);k=Math.min(k,l[f].y);f<g-1&&l[f].y===l[f+1].y&&l[f].x===l[f+1].x-1?y|=1<<g-1-f:b.push(f)}var S=b.length,C=new Int8Array(S),x=new Int8Array(S),A=new Uint16Array(S);for(u=0;u<S;u++){f=b[u];C[u]=l[f].x;x[u]=l[f].y;A[u]=1<<g-1-f}for(var I,F,T,O,P,D=-v,N=-k,M=t-w,L=d[r],R=new Uint8Array(t),U=[],q=o.decoder,j=o.contextCache.getContexts("GB"),_=0,z=0,H=0;H<a;H++){if(i){if(_^=q.readBit(j,L)){U.push(R);continue}}R=new Uint8Array(R);U.push(R);for(I=0;I<t;I++)if(c&&n[H][I])R[I]=0;else{if(I>=D&&I<M&&H>=N){z=z<<1&y;for(f=0;f<S;f++){F=H+x[f];T=I+C[f];(O=U[F][T])&&(z|=O=A[f])}}else{z=0;P=g-1;for(f=0;f<g;f++,P--)(T=I+m[f])>=0&&T<t&&(F=H+p[f])>=0&&(O=U[F][T])&&(z|=O<<P)}var G=q.readBit(j,z);R[I]=G}}return U}function m(e,t,a,r,i,n,s,c,l){var h=u[a].coding;0===a&&(h=h.concat([c[0]]));var d,g=h.length,m=new Int32Array(g),p=new Int32Array(g);for(d=0;d<g;d++){m[d]=h[d].x;p[d]=h[d].y}var b=u[a].reference;0===a&&(b=b.concat([c[1]]));var y=b.length,v=new Int32Array(y),w=new Int32Array(y);for(d=0;d<y;d++){v[d]=b[d].x;w[d]=b[d].y}for(var k=r[0].length,S=r.length,C=f[a],x=[],A=l.decoder,I=l.contextCache.getContexts("GR"),F=0,T=0;T<t;T++){if(s){if(F^=A.readBit(I,C))throw new o("prediction is not supported")}var E=new Uint8Array(e);x.push(E);for(var O=0;O<e;O++){var P,B,D=0;for(d=0;d<g;d++){P=T+p[d];B=O+m[d];P<0||B<0||B>=e?D<<=1:D=D<<1|x[P][B]}for(d=0;d<y;d++){P=T+w[d]-n;B=O+v[d]-i;P<0||P>=S||B<0||B>=k?D<<=1:D=D<<1|r[P][B]}var N=A.readBit(I,D);E[O]=N}}return x}function p(e,t,r,i,n,s,l,h,u,d,f,g,p,b,y,v,w,k,S){if(e&&t)throw new o("refinement with Huffman is not supported");var C,x,A=[];for(C=0;C<i;C++){x=new Uint8Array(r);if(n)for(var I=0;I<r;I++)x[I]=n;A.push(x)}var F=w.decoder,T=w.contextCache,E=e?-b.tableDeltaT.decode(S):-a(T,"IADT",F),O=0;C=0;for(;C<s;){E+=e?b.tableDeltaT.decode(S):a(T,"IADT",F);for(var P=O+=e?b.tableFirstS.decode(S):a(T,"IAFS",F);;){let i=0;l>1&&(i=e?S.readBits(k):a(T,"IAIT",F));var B=l*E+i,D=e?b.symbolIDTable.decode(S):c(T,F,u),N=t&&(e?S.readBit():a(T,"IARI",F)),M=h[D],L=M[0].length,R=M.length;if(N){var U=a(T,"IARDW",F),q=a(T,"IARDH",F);M=m(L+=U,R+=q,y,M,(U>>1)+a(T,"IARDX",F),(q>>1)+a(T,"IARDY",F),!1,v,w)}var j,_,z,H=B-(1&g?0:R-1),G=P-(2&g?L-1:0);if(d){for(j=0;j<R;j++)if(x=A[G+j]){z=M[j];var W=Math.min(r-H,L);switch(p){case 0:for(_=0;_<W;_++)x[H+_]|=z[_];break;case 2:for(_=0;_<W;_++)x[H+_]^=z[_];break;default:throw new o(`operator ${p} is not supported`)}}P+=R-1}else{for(_=0;_<R;_++)if(x=A[H+_]){z=M[_];switch(p){case 0:for(j=0;j<L;j++)x[G+j]|=z[j];break;case 2:for(j=0;j<L;j++)x[G+j]^=z[j];break;default:throw new o(`operator ${p} is not supported`)}}P+=L-1}C++;var X=e?b.tableDeltaS.decode(S):a(T,"IADS",F);if(null===X)break;P+=X+f}}return A}function b(e,t){var a={};a.number=(0,i.readUint32)(e,t);var r=e[t+4],n=63&r;if(!l[n])throw new o("invalid segment type: "+n);a.type=n;a.typeName=l[n];a.deferredNonRetain=!!(128&r);var s=!!(64&r),c=e[t+5],h=c>>5&7,u=[31&c],d=t+6;if(7===c){h=536870911&(0,i.readUint32)(e,d-1);d+=3;var f=h+7>>3;u[0]=e[d++];for(;--f>0;)u.push(e[d++])}else if(5===c||6===c)throw new o("invalid referred-to flags");a.retainBits=u;let g=4;a.number<=256?g=1:a.number<=65536&&(g=2);var m,p,b=[];for(m=0;m<h;m++){let t;t=1===g?e[d]:2===g?(0,i.readUint16)(e,d):(0,i.readUint32)(e,d);b.push(t);d+=g}a.referredTo=b;if(s){a.pageAssociation=(0,i.readUint32)(e,d);d+=4}else a.pageAssociation=e[d++];a.length=(0,i.readUint32)(e,d);d+=4;if(4294967295===a.length){if(38!==n)throw new o("invalid unknown segment length");var y=v(e,d),k=!!(1&e[d+w]),S=new Uint8Array(6);if(!k){S[0]=255;S[1]=172}S[2]=y.height>>>24&255;S[3]=y.height>>16&255;S[4]=y.height>>8&255;S[5]=255&y.height;for(m=d,p=e.length;m<p;m++){for(var C=0;C<6&&S[C]===e[m+C];)C++;if(6===C){a.length=m+6;break}}if(4294967295===a.length)throw new o("segment end was not found")}a.headerEnd=d;return a}function y(e,t,a,r){for(var i=[],n=a;n<r;){var s=b(t,n);n=s.headerEnd;var o={header:s,data:t};if(!e.randomAccess){o.start=n;n+=s.length;o.end=n}i.push(o);if(51===s.type)break}if(e.randomAccess)for(var c=0,l=i.length;c<l;c++){i[c].start=n;n+=i[c].header.length;i[c].end=n}return i}function v(e,t){return{width:(0,i.readUint32)(e,t),height:(0,i.readUint32)(e,t+4),x:(0,i.readUint32)(e,t+8),y:(0,i.readUint32)(e,t+12),combinationOperator:7&e[t+16]}}var w=17;function k(e,t){var a,r,n,s,c=e.header,l=e.data,h=e.start,u=e.end;switch(c.type){case 0:var d={},f=(0,i.readUint16)(l,h);d.huffman=!!(1&f);d.refinement=!!(2&f);d.huffmanDHSelector=f>>2&3;d.huffmanDWSelector=f>>4&3;d.bitmapSizeSelector=f>>6&1;d.aggregationInstancesSelector=f>>7&1;d.bitmapCodingContextUsed=!!(256&f);d.bitmapCodingContextRetained=!!(512&f);d.template=f>>10&3;d.refinementTemplate=f>>12&1;h+=2;if(!d.huffman){s=0===d.template?4:1;r=[];for(n=0;n<s;n++){r.push({x:(0,i.readInt8)(l,h),y:(0,i.readInt8)(l,h+1)});h+=2}d.at=r}if(d.refinement&&!d.refinementTemplate){r=[];for(n=0;n<2;n++){r.push({x:(0,i.readInt8)(l,h),y:(0,i.readInt8)(l,h+1)});h+=2}d.refinementAt=r}d.numberOfExportedSymbols=(0,i.readUint32)(l,h);h+=4;d.numberOfNewSymbols=(0,i.readUint32)(l,h);h+=4;a=[d,c.number,c.referredTo,l,h,u];break;case 6:case 7:var g={};g.info=v(l,h);h+=w;var m=(0,i.readUint16)(l,h);h+=2;g.huffman=!!(1&m);g.refinement=!!(2&m);g.logStripSize=m>>2&3;g.stripSize=1<<g.logStripSize;g.referenceCorner=m>>4&3;g.transposed=!!(64&m);g.combinationOperator=m>>7&3;g.defaultPixelValue=m>>9&1;g.dsOffset=m<<17>>27;g.refinementTemplate=m>>15&1;if(g.huffman){var p=(0,i.readUint16)(l,h);h+=2;g.huffmanFS=3&p;g.huffmanDS=p>>2&3;g.huffmanDT=p>>4&3;g.huffmanRefinementDW=p>>6&3;g.huffmanRefinementDH=p>>8&3;g.huffmanRefinementDX=p>>10&3;g.huffmanRefinementDY=p>>12&3;g.huffmanRefinementSizeSelector=!!(16384&p)}if(g.refinement&&!g.refinementTemplate){r=[];for(n=0;n<2;n++){r.push({x:(0,i.readInt8)(l,h),y:(0,i.readInt8)(l,h+1)});h+=2}g.refinementAt=r}g.numberOfSymbolInstances=(0,i.readUint32)(l,h);h+=4;a=[g,c.referredTo,l,h,u];break;case 16:const e={},t=l[h++];e.mmr=!!(1&t);e.template=t>>1&3;e.patternWidth=l[h++];e.patternHeight=l[h++];e.maxPatternIndex=(0,i.readUint32)(l,h);h+=4;a=[e,c.number,l,h,u];break;case 22:case 23:const C={};C.info=v(l,h);h+=w;const x=l[h++];C.mmr=!!(1&x);C.template=x>>1&3;C.enableSkip=!!(8&x);C.combinationOperator=x>>4&7;C.defaultPixelValue=x>>7&1;C.gridWidth=(0,i.readUint32)(l,h);h+=4;C.gridHeight=(0,i.readUint32)(l,h);h+=4;C.gridOffsetX=4294967295&(0,i.readUint32)(l,h);h+=4;C.gridOffsetY=4294967295&(0,i.readUint32)(l,h);h+=4;C.gridVectorX=(0,i.readUint16)(l,h);h+=2;C.gridVectorY=(0,i.readUint16)(l,h);h+=2;a=[C,c.referredTo,l,h,u];break;case 38:case 39:var b={};b.info=v(l,h);h+=w;var y=l[h++];b.mmr=!!(1&y);b.template=y>>1&3;b.prediction=!!(8&y);if(!b.mmr){s=0===b.template?4:1;r=[];for(n=0;n<s;n++){r.push({x:(0,i.readInt8)(l,h),y:(0,i.readInt8)(l,h+1)});h+=2}b.at=r}a=[b,l,h,u];break;case 48:var k={width:(0,i.readUint32)(l,h),height:(0,i.readUint32)(l,h+4),resolutionX:(0,i.readUint32)(l,h+8),resolutionY:(0,i.readUint32)(l,h+12)};4294967295===k.height&&delete k.height;var S=l[h+16];(0,i.readUint16)(l,h+17);k.lossless=!!(1&S);k.refinement=!!(2&S);k.defaultPixelValue=S>>2&1;k.combinationOperator=S>>3&3;k.requiresBuffer=!!(32&S);k.combinationOperatorOverride=!!(64&S);a=[k];break;case 49:case 50:case 51:break;case 53:a=[c.number,l,h,u];break;case 62:break;default:throw new o(`segment type ${c.typeName}(${c.type})`+" is not implemented")}var C="on"+c.typeName;C in t&&t[C].apply(t,a)}function S(e,t){for(var a=0,r=e.length;a<r;a++)k(e[a],t)}function C(){}C.prototype={onPageInformation:function(e){this.currentPageInfo=e;var t=e.width+7>>3,a=new Uint8ClampedArray(t*e.height);if(e.defaultPixelValue)for(var r=0,i=a.length;r<i;r++)a[r]=255;this.buffer=a},drawBitmap:function(e,t){var a,r,i,n,s=this.currentPageInfo,c=e.width,l=e.height,h=s.width+7>>3,u=s.combinationOperatorOverride?e.combinationOperator:s.combinationOperator,d=this.buffer,f=128>>(7&e.x),g=e.y*h+(e.x>>3);switch(u){case 0:for(a=0;a<l;a++){i=f;n=g;for(r=0;r<c;r++){t[a][r]&&(d[n]|=i);if(!(i>>=1)){i=128;n++}}g+=h}break;case 2:for(a=0;a<l;a++){i=f;n=g;for(r=0;r<c;r++){t[a][r]&&(d[n]^=i);if(!(i>>=1)){i=128;n++}}g+=h}break;default:throw new o(`operator ${u} is not supported`)}},onImmediateGenericRegion:function(e,a,r,i){var n=e.info,s=new t(a,r,i),o=g(e.mmr,n.width,n.height,e.template,e.prediction,null,e.at,s);this.drawBitmap(n,o)},onImmediateLosslessGenericRegion:function(){this.onImmediateGenericRegion.apply(this,arguments)},onSymbolDictionary:function(e,r,n,s,l,h){let u,d;if(e.huffman){u=function(e,t,a){let r,i,n,s,c=0;switch(e.huffmanDHSelector){case 0:case 1:r=T(e.huffmanDHSelector+4);break;case 3:r=O(c,t,a);c++;break;default:throw new o("invalid Huffman DH selector")}switch(e.huffmanDWSelector){case 0:case 1:i=T(e.huffmanDWSelector+2);break;case 3:i=O(c,t,a);c++;break;default:throw new o("invalid Huffman DW selector")}if(e.bitmapSizeSelector){n=O(c,t,a);c++}else n=T(1);s=e.aggregationInstancesSelector?O(c,t,a):T(1);return{tableDeltaHeight:r,tableDeltaWidth:i,tableBitmapSize:n,tableAggregateInstances:s}}(e,n,this.customTables);d=new E(s,l,h)}var f=this.symbols;f||(this.symbols=f={});for(var b=[],y=0,v=n.length;y<v;y++){const e=f[n[y]];e&&(b=b.concat(e))}var w=new t(s,l,h);f[r]=function(e,t,r,n,s,l,h,u,d,f,b,y){if(e&&t)throw new o("symbol refinement with Huffman is not supported");var v=[],w=0,k=(0,i.log2)(r.length+n),S=b.decoder,C=b.contextCache;let x,A;if(e){x=T(1);A=[];k=Math.max(k,1)}for(;v.length<n;){w+=e?l.tableDeltaHeight.decode(y):a(C,"IADH",S);let i=0,n=0;const s=e?A.length:0;for(;;){var I,F=e?l.tableDeltaWidth.decode(y):a(C,"IADW",S);if(null===F)break;i+=F;n+=i;if(t){var E=a(C,"IAAI",S);if(E>1)I=p(e,t,i,w,0,E,1,r.concat(v),k,0,0,1,0,l,d,f,b,0,y);else{var O=c(C,S,k),D=a(C,"IARDX",S),N=a(C,"IARDY",S);I=m(i,w,d,O<r.length?r[O]:v[O-r.length],D,N,!1,f,b)}v.push(I)}else if(e)A.push(i);else{I=g(!1,i,w,h,!1,null,u,b);v.push(I)}}if(e&&!t){const e=l.tableBitmapSize.decode(y);y.byteAlign();let t;if(0===e)t=P(y,n,w);else{const a=y.end,r=y.position+e;y.end=r;t=B(y,n,w,!1);y.end=a;y.position=r}const a=A.length;if(s===a-1)v.push(t);else{let e,r,i,n,o,c=0;for(e=s;e<a;e++){n=A[e];i=c+n;o=[];for(r=0;r<w;r++)o.push(t[r].subarray(c,i));v.push(o);c=i}}}}for(var M=[],L=[],R=!1,U=r.length+n;L.length<U;){for(var q=e?x.decode(y):a(C,"IAEX",S);q--;)L.push(R);R=!R}for(var j=0,_=r.length;j<_;j++)L[j]&&M.push(r[j]);for(var z=0;z<n;j++,z++)L[j]&&M.push(v[z]);return M}(e.huffman,e.refinement,b,e.numberOfNewSymbols,e.numberOfExportedSymbols,u,e.template,e.at,e.refinementTemplate,e.refinementAt,w,d)},onImmediateTextRegion:function(e,a,r,n,s){var c=e.info;let l,h;for(var u=this.symbols,d=[],f=0,g=a.length;f<g;f++){const e=u[a[f]];e&&(d=d.concat(e))}var m=(0,i.log2)(d.length);if(e.huffman){h=new E(r,n,s);l=function(e,t,a,r,i){const n=[];for(let e=0;e<=34;e++){const t=i.readBits(4);n.push(new x([e,t,0,0]))}const s=new I(n,!1);n.length=0;for(let e=0;e<r;){const t=s.decode(i);if(t>=32){let a,r,s;switch(t){case 32:if(0===e)throw new o("no previous value in symbol ID table");r=i.readBits(2)+3;a=n[e-1].prefixLength;break;case 33:r=i.readBits(3)+3;a=0;break;case 34:r=i.readBits(7)+11;a=0;break;default:throw new o("invalid code length in symbol ID table")}for(s=0;s<r;s++){n.push(new x([e,a,0,0]));e++}}else{n.push(new x([e,t,0,0]));e++}}i.byteAlign();const c=new I(n,!1);let l,h,u,d=0;switch(e.huffmanFS){case 0:case 1:l=T(e.huffmanFS+6);break;case 3:l=O(d,t,a);d++;break;default:throw new o("invalid Huffman FS selector")}switch(e.huffmanDS){case 0:case 1:case 2:h=T(e.huffmanDS+8);break;case 3:h=O(d,t,a);d++;break;default:throw new o("invalid Huffman DS selector")}switch(e.huffmanDT){case 0:case 1:case 2:u=T(e.huffmanDT+11);break;case 3:u=O(d,t,a);d++;break;default:throw new o("invalid Huffman DT selector")}if(e.refinement)throw new o("refinement with Huffman is not supported");return{symbolIDTable:c,tableFirstS:l,tableDeltaS:h,tableDeltaT:u}}(e,a,this.customTables,d.length,h)}var b=new t(r,n,s),y=p(e.huffman,e.refinement,c.width,c.height,e.defaultPixelValue,e.numberOfSymbolInstances,e.stripSize,d,m,e.transposed,e.dsOffset,e.referenceCorner,e.combinationOperator,l,e.refinementTemplate,e.refinementAt,b,e.logStripSize,h);this.drawBitmap(c,y)},onImmediateLosslessTextRegion:function(){this.onImmediateTextRegion.apply(this,arguments)},onPatternDictionary(e,a,r,i,n){let s=this.patterns;s||(this.patterns=s={});const o=new t(r,i,n);s[a]=function(e,t,a,r,i,n){const s=[];if(!e){s.push({x:-t,y:0});if(0===i){s.push({x:-3,y:-1});s.push({x:2,y:-2});s.push({x:-2,y:-2})}}const o=g(e,(r+1)*t,a,i,!1,null,s,n),c=[];for(let e=0;e<=r;e++){const r=[],i=t*e,n=i+t;for(let e=0;e<a;e++)r.push(o[e].subarray(i,n));c.push(r)}return c}(e.mmr,e.patternWidth,e.patternHeight,e.maxPatternIndex,e.template,o)},onImmediateHalftoneRegion(e,a,r,n,s){const c=this.patterns[a[0]],l=e.info,h=new t(r,n,s),u=function(e,t,a,r,n,s,c,l,h,u,d,f,m,p,b){if(c)throw new o("skip is not supported");if(0!==l)throw new o("operator "+l+" is not supported in halftone region");const y=[];let v,w,k;for(v=0;v<n;v++){k=new Uint8Array(r);if(s)for(w=0;w<r;w++)k[w]=s;y.push(k)}const S=t.length,C=t[0],x=C[0].length,A=C.length,I=(0,i.log2)(S),F=[];if(!e){F.push({x:a<=1?3:2,y:-1});if(0===a){F.push({x:-3,y:-1});F.push({x:2,y:-2});F.push({x:-2,y:-2})}}const T=[];let O,P,D,N,M,L,R,U,q,j,_;e&&(O=new E(b.data,b.start,b.end));for(v=I-1;v>=0;v--){P=e?B(O,h,u,!0):g(!1,h,u,a,!1,null,F,b);T[v]=P}for(D=0;D<u;D++)for(N=0;N<h;N++){M=0;L=0;for(w=I-1;w>=0;w--){M=T[w][D][N]^M;L|=M<<w}R=t[L];U=d+D*p+N*m>>8;q=f+D*m-N*p>>8;if(U>=0&&U+x<=r&&q>=0&&q+A<=n)for(v=0;v<A;v++){_=y[q+v];j=R[v];for(w=0;w<x;w++)_[U+w]|=j[w]}else{let e,t;for(v=0;v<A;v++){t=q+v;if(!(t<0||t>=n)){_=y[t];j=R[v];for(w=0;w<x;w++){e=U+w;e>=0&&e<r&&(_[e]|=j[w])}}}}}return y}(e.mmr,c,e.template,l.width,l.height,e.defaultPixelValue,e.enableSkip,e.combinationOperator,e.gridWidth,e.gridHeight,e.gridOffsetX,e.gridOffsetY,e.gridVectorX,e.gridVectorY,h);this.drawBitmap(l,u)},onImmediateLosslessHalftoneRegion(){this.onImmediateHalftoneRegion.apply(this,arguments)},onTables(e,t,a,r){let n=this.customTables;n||(this.customTables=n={});n[e]=function(e,t,a){const r=e[t],n=4294967295&(0,i.readUint32)(e,t+1),s=4294967295&(0,i.readUint32)(e,t+5),o=new E(e,t+9,a),c=1+(r>>1&7),l=1+(r>>4&7),h=[];let u,d,f=n;do{u=o.readBits(c);d=o.readBits(l);h.push(new x([f,u,d,0]));f+=1<<d}while(f<s);u=o.readBits(c);h.push(new x([n-1,u,32,0,"lower"]));u=o.readBits(c);h.push(new x([s,u,32,0]));if(1&r){u=o.readBits(c);h.push(new x([u,0]))}return new I(h,!1)}(t,a,r)}};function x(e){if(2===e.length){this.isOOB=!0;this.rangeLow=0;this.prefixLength=e[0];this.rangeLength=0;this.prefixCode=e[1];this.isLowerRange=!1}else{this.isOOB=!1;this.rangeLow=e[0];this.prefixLength=e[1];this.rangeLength=e[2];this.prefixCode=e[3];this.isLowerRange="lower"===e[4]}}function A(e){this.children=[];if(e){this.isLeaf=!0;this.rangeLength=e.rangeLength;this.rangeLow=e.rangeLow;this.isLowerRange=e.isLowerRange;this.isOOB=e.isOOB}else this.isLeaf=!1}A.prototype={buildTree(e,t){const a=e.prefixCode>>t&1;if(t<=0)this.children[a]=new A(e);else{let r=this.children[a];r||(this.children[a]=r=new A(null));r.buildTree(e,t-1)}},decodeNode(e){if(this.isLeaf){if(this.isOOB)return null;const t=e.readBits(this.rangeLength);return this.rangeLow+(this.isLowerRange?-t:t)}const t=this.children[e.readBit()];if(!t)throw new o("invalid Huffman data");return t.decodeNode(e)}};function I(e,t){t||this.assignPrefixCodes(e);this.rootNode=new A(null);for(let t=0,a=e.length;t<a;t++){const a=e[t];a.prefixLength>0&&this.rootNode.buildTree(a,a.prefixLength-1)}}I.prototype={decode(e){return this.rootNode.decodeNode(e)},assignPrefixCodes(e){const t=e.length;let a=0;for(let r=0;r<t;r++)a=Math.max(a,e[r].prefixLength);const r=new Uint32Array(a+1);for(let a=0;a<t;a++)r[e[a].prefixLength]++;let i,n,s,o=1,c=0;r[0]=0;for(;o<=a;){c=c+r[o-1]<<1;i=c;n=0;for(;n<t;){s=e[n];if(s.prefixLength===o){s.prefixCode=i;i++}n++}o++}}};const F={};function T(e){let t,a=F[e];if(a)return a;switch(e){case 1:t=[[0,1,4,0],[16,2,8,2],[272,3,16,6],[65808,3,32,7]];break;case 2:t=[[0,1,0,0],[1,2,0,2],[2,3,0,6],[3,4,3,14],[11,5,6,30],[75,6,32,62],[6,63]];break;case 3:t=[[-256,8,8,254],[0,1,0,0],[1,2,0,2],[2,3,0,6],[3,4,3,14],[11,5,6,30],[-257,8,32,255,"lower"],[75,7,32,126],[6,62]];break;case 4:t=[[1,1,0,0],[2,2,0,2],[3,3,0,6],[4,4,3,14],[12,5,6,30],[76,5,32,31]];break;case 5:t=[[-255,7,8,126],[1,1,0,0],[2,2,0,2],[3,3,0,6],[4,4,3,14],[12,5,6,30],[-256,7,32,127,"lower"],[76,6,32,62]];break;case 6:t=[[-2048,5,10,28],[-1024,4,9,8],[-512,4,8,9],[-256,4,7,10],[-128,5,6,29],[-64,5,5,30],[-32,4,5,11],[0,2,7,0],[128,3,7,2],[256,3,8,3],[512,4,9,12],[1024,4,10,13],[-2049,6,32,62,"lower"],[2048,6,32,63]];break;case 7:t=[[-1024,4,9,8],[-512,3,8,0],[-256,4,7,9],[-128,5,6,26],[-64,5,5,27],[-32,4,5,10],[0,4,5,11],[32,5,5,28],[64,5,6,29],[128,4,7,12],[256,3,8,1],[512,3,9,2],[1024,3,10,3],[-1025,5,32,30,"lower"],[2048,5,32,31]];break;case 8:t=[[-15,8,3,252],[-7,9,1,508],[-5,8,1,253],[-3,9,0,509],[-2,7,0,124],[-1,4,0,10],[0,2,1,0],[2,5,0,26],[3,6,0,58],[4,3,4,4],[20,6,1,59],[22,4,4,11],[38,4,5,12],[70,5,6,27],[134,5,7,28],[262,6,7,60],[390,7,8,125],[646,6,10,61],[-16,9,32,510,"lower"],[1670,9,32,511],[2,1]];break;case 9:t=[[-31,8,4,252],[-15,9,2,508],[-11,8,2,253],[-7,9,1,509],[-5,7,1,124],[-3,4,1,10],[-1,3,1,2],[1,3,1,3],[3,5,1,26],[5,6,1,58],[7,3,5,4],[39,6,2,59],[43,4,5,11],[75,4,6,12],[139,5,7,27],[267,5,8,28],[523,6,8,60],[779,7,9,125],[1291,6,11,61],[-32,9,32,510,"lower"],[3339,9,32,511],[2,0]];break;case 10:t=[[-21,7,4,122],[-5,8,0,252],[-4,7,0,123],[-3,5,0,24],[-2,2,2,0],[2,5,0,25],[3,6,0,54],[4,7,0,124],[5,8,0,253],[6,2,6,1],[70,5,5,26],[102,6,5,55],[134,6,6,56],[198,6,7,57],[326,6,8,58],[582,6,9,59],[1094,6,10,60],[2118,7,11,125],[-22,8,32,254,"lower"],[4166,8,32,255],[2,2]];break;case 11:t=[[1,1,0,0],[2,2,1,2],[4,4,0,12],[5,4,1,13],[7,5,1,28],[9,5,2,29],[13,6,2,60],[17,7,2,122],[21,7,3,123],[29,7,4,124],[45,7,5,125],[77,7,6,126],[141,7,32,127]];break;case 12:t=[[1,1,0,0],[2,2,0,2],[3,3,1,6],[5,5,0,28],[6,5,1,29],[8,6,1,60],[10,7,0,122],[11,7,1,123],[13,7,2,124],[17,7,3,125],[25,7,4,126],[41,8,5,254],[73,8,32,255]];break;case 13:t=[[1,1,0,0],[2,3,0,4],[3,4,0,12],[4,5,0,28],[5,4,1,13],[7,3,3,5],[15,6,1,58],[17,6,2,59],[21,6,3,60],[29,6,4,61],[45,6,5,62],[77,7,6,126],[141,7,32,127]];break;case 14:t=[[-2,3,0,4],[-1,3,0,5],[0,1,0,0],[1,3,0,6],[2,3,0,7]];break;case 15:t=[[-24,7,4,124],[-8,6,2,60],[-4,5,1,28],[-2,4,0,12],[-1,3,0,4],[0,1,0,0],[1,3,0,5],[2,4,0,13],[3,5,1,29],[5,6,2,61],[9,7,4,125],[-25,7,32,126,"lower"],[25,7,32,127]];break;default:throw new o(`standard table B.${e} does not exist`)}for(let e=0,a=t.length;e<a;e++)t[e]=new x(t[e]);a=new I(t,!0);F[e]=a;return a}function E(e,t,a){this.data=e;this.start=t;this.end=a;this.position=t;this.shift=-1;this.currentByte=0}E.prototype={readBit(){if(this.shift<0){if(this.position>=this.end)throw new o("end of data while reading bit");this.currentByte=this.data[this.position++];this.shift=7}const e=this.currentByte>>this.shift&1;this.shift--;return e},readBits(e){let t,a=0;for(t=e-1;t>=0;t--)a|=this.readBit()<<t;return a},byteAlign(){this.shift=-1},next(){return this.position>=this.end?-1:this.data[this.position++]}};function O(e,t,a){let r=0;for(let i=0,n=t.length;i<n;i++){const n=a[t[i]];if(n){if(e===r)return n;r++}}throw new o("can't find custom Huffman table")}function P(e,t,a){const r=[];for(let i=0;i<a;i++){const a=new Uint8Array(t);r.push(a);for(let r=0;r<t;r++)a[r]=e.readBit();e.byteAlign()}return r}function B(e,t,a,r){const i={K:-1,Columns:t,Rows:a,BlackIs1:!0,EndOfBlock:r},n=new s.CCITTFaxDecoder(e,i),o=[];let c,l=!1;for(let e=0;e<a;e++){const e=new Uint8Array(t);o.push(e);let a=-1;for(let r=0;r<t;r++){if(a<0){c=n.readNextChar();if(-1===c){c=0;l=!0}a=7}e[r]=c>>a&1;a--}}if(r&&!l){const e=5;for(let t=0;t<e&&-1!==n.readNextChar();t++);}return o}function D(){}D.prototype={parseChunks:e=>function(e){for(var t=new C,a=0,r=e.length;a<r;a++){var i=e[a];S(y({},i.data,i.start,i.end),t)}return t.buffer}(e),parse(e){const{imgData:t,width:a,height:r}=function(e){const t=e.length;let a=0;if(151!==e[a]||74!==e[a+1]||66!==e[a+2]||50!==e[a+3]||13!==e[a+4]||10!==e[a+5]||26!==e[a+6]||10!==e[a+7])throw new o("parseJbig2 - invalid header.");const r=Object.create(null);a+=8;const n=e[a++];r.randomAccess=!(1&n);if(!(2&n)){r.numberOfPages=(0,i.readUint32)(e,a);a+=4}const s=y(r,e,a,t),c=new C;S(s,c);const{width:l,height:h}=c.currentPageInfo,u=c.buffer,d=new Uint8ClampedArray(l*h);let f=0,g=0;for(let e=0;e<h;e++){let e,t=0;for(let a=0;a<l;a++){if(!t){t=128;e=u[g++]}d[f++]=e&t?0:255;t>>=1}}return{imgData:d,width:l,height:h}}(e);this.width=a;this.height=r;return t}};return D}();t.Jbig2Image=c},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.ArithmeticDecoder=void 0;const r=[{qe:22017,nmps:1,nlps:1,switchFlag:1},{qe:13313,nmps:2,nlps:6,switchFlag:0},{qe:6145,nmps:3,nlps:9,switchFlag:0},{qe:2753,nmps:4,nlps:12,switchFlag:0},{qe:1313,nmps:5,nlps:29,switchFlag:0},{qe:545,nmps:38,nlps:33,switchFlag:0},{qe:22017,nmps:7,nlps:6,switchFlag:1},{qe:21505,nmps:8,nlps:14,switchFlag:0},{qe:18433,nmps:9,nlps:14,switchFlag:0},{qe:14337,nmps:10,nlps:14,switchFlag:0},{qe:12289,nmps:11,nlps:17,switchFlag:0},{qe:9217,nmps:12,nlps:18,switchFlag:0},{qe:7169,nmps:13,nlps:20,switchFlag:0},{qe:5633,nmps:29,nlps:21,switchFlag:0},{qe:22017,nmps:15,nlps:14,switchFlag:1},{qe:21505,nmps:16,nlps:14,switchFlag:0},{qe:20737,nmps:17,nlps:15,switchFlag:0},{qe:18433,nmps:18,nlps:16,switchFlag:0},{qe:14337,nmps:19,nlps:17,switchFlag:0},{qe:13313,nmps:20,nlps:18,switchFlag:0},{qe:12289,nmps:21,nlps:19,switchFlag:0},{qe:10241,nmps:22,nlps:19,switchFlag:0},{qe:9217,nmps:23,nlps:20,switchFlag:0},{qe:8705,nmps:24,nlps:21,switchFlag:0},{qe:7169,nmps:25,nlps:22,switchFlag:0},{qe:6145,nmps:26,nlps:23,switchFlag:0},{qe:5633,nmps:27,nlps:24,switchFlag:0},{qe:5121,nmps:28,nlps:25,switchFlag:0},{qe:4609,nmps:29,nlps:26,switchFlag:0},{qe:4353,nmps:30,nlps:27,switchFlag:0},{qe:2753,nmps:31,nlps:28,switchFlag:0},{qe:2497,nmps:32,nlps:29,switchFlag:0},{qe:2209,nmps:33,nlps:30,switchFlag:0},{qe:1313,nmps:34,nlps:31,switchFlag:0},{qe:1089,nmps:35,nlps:32,switchFlag:0},{qe:673,nmps:36,nlps:33,switchFlag:0},{qe:545,nmps:37,nlps:34,switchFlag:0},{qe:321,nmps:38,nlps:35,switchFlag:0},{qe:273,nmps:39,nlps:36,switchFlag:0},{qe:133,nmps:40,nlps:37,switchFlag:0},{qe:73,nmps:41,nlps:38,switchFlag:0},{qe:37,nmps:42,nlps:39,switchFlag:0},{qe:21,nmps:43,nlps:40,switchFlag:0},{qe:9,nmps:44,nlps:41,switchFlag:0},{qe:5,nmps:45,nlps:42,switchFlag:0},{qe:1,nmps:45,nlps:43,switchFlag:0},{qe:22017,nmps:46,nlps:46,switchFlag:0}];t.ArithmeticDecoder=class{constructor(e,t,a){this.data=e;this.bp=t;this.dataEnd=a;this.chigh=e[t];this.clow=0;this.byteIn();this.chigh=this.chigh<<7&65535|this.clow>>9&127;this.clow=this.clow<<7&65535;this.ct-=7;this.a=32768}byteIn(){const e=this.data;let t=this.bp;if(255===e[t])if(e[t+1]>143){this.clow+=65280;this.ct=8}else{t++;this.clow+=e[t]<<9;this.ct=7;this.bp=t}else{t++;this.clow+=t<this.dataEnd?e[t]<<8:65280;this.ct=8;this.bp=t}if(this.clow>65535){this.chigh+=this.clow>>16;this.clow&=65535}}readBit(e,t){let a=e[t]>>1,i=1&e[t];const n=r[a],s=n.qe;let o,c=this.a-s;if(this.chigh<s)if(c<s){c=s;o=i;a=n.nmps}else{c=s;o=1^i;1===n.switchFlag&&(i=o);a=n.nlps}else{this.chigh-=s;if(0!=(32768&c)){this.a=c;return i}if(c<s){o=1^i;1===n.switchFlag&&(i=o);a=n.nlps}else{o=i;a=n.nmps}}do{0===this.ct&&this.byteIn();c<<=1;this.chigh=this.chigh<<1&65535|this.clow>>15&1;this.clow=this.clow<<1&65535;this.ct--}while(0==(32768&c));this.a=c;e[t]=a<<1|i;return o}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.JpegStream=void 0;var r=a(2),i=a(11),n=a(4),s=a(18);const o=function(){function e(e,t,a,r){let n;for(;-1!==(n=e.getByte());)if(255===n){e.skip(-1);break}this.stream=e;this.maybeLength=t;this.dict=a;this.params=r;i.DecodeStream.call(this,t)}e.prototype=Object.create(i.DecodeStream.prototype);Object.defineProperty(e.prototype,"bytes",{get:function(){return(0,r.shadow)(this,"bytes",this.stream.getBytes(this.maybeLength))},configurable:!0});e.prototype.ensureBuffer=function(e){};e.prototype.readBlock=function(){if(this.eof)return;const e={decodeTransform:void 0,colorTransform:void 0},t=this.dict.getArray("Decode","D");if(this.forceRGB&&Array.isArray(t)){const a=this.dict.get("BitsPerComponent")||8,r=t.length,i=new Int32Array(r);let n=!1;const s=(1<<a)-1;for(let e=0;e<r;e+=2){i[e]=256*(t[e+1]-t[e])|0;i[e+1]=t[e]*s|0;256===i[e]&&0===i[e+1]||(n=!0)}n&&(e.decodeTransform=i)}if((0,n.isDict)(this.params)){const t=this.params.get("ColorTransform");Number.isInteger(t)&&(e.colorTransform=t)}const a=new s.JpegImage(e);a.parse(this.bytes);const r=a.getData({width:this.drawWidth,height:this.drawHeight,forceRGB:this.forceRGB,isSourcePDF:!0});this.buffer=r;this.bufferLength=r.length;this.eof=!0};Object.defineProperty(e.prototype,"maybeValidDimensions",{get:function(){const{dict:e,stream:t}=this,a=e.get("Height","H"),i=t.pos;let n,s=!0,o=!1;for(;-1!==(n=t.getByte());)if(255===n){switch(t.getByte()){case 192:case 193:case 194:o=!0;t.pos+=2;t.pos+=1;const e=t.getUint16();if(e===a)break;if(0===e){s=!1;break}if(e>10*a){s=!1;break}break;case 195:case 197:case 198:case 199:case 201:case 202:case 203:case 205:case 206:case 207:o=!0;break;case 196:case 204:case 218:case 219:case 220:case 221:case 222:case 223:case 224:case 225:case 226:case 227:case 228:case 229:case 230:case 231:case 232:case 233:case 234:case 235:case 236:case 237:case 238:case 239:case 254:const r=t.getUint16();r>2?t.skip(r-2):t.skip(-2);break;case 255:t.skip(-1);break;case 217:o=!0}if(o)break}t.pos=i;return(0,r.shadow)(this,"maybeValidDimensions",s)},configurable:!0});e.prototype.getIR=function(e=!1){return(0,r.createObjectURL)(this.bytes,"image/jpeg",e)};return e}();t.JpegStream=o},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.JpegImage=void 0;var r=a(2),i=a(7);class n extends r.BaseException{constructor(e){super(`JPEG error: ${e}`)}}class s extends r.BaseException{constructor(e,t){super(e);this.scanLines=t}}class o extends r.BaseException{}var c=function(){var e=new Uint8Array([0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63]);function t({decodeTransform:e=null,colorTransform:t=-1}={}){this._decodeTransform=e;this._colorTransform=t}function a(e,t){for(var a,r,i=0,n=[],s=16;s>0&&!e[s-1];)s--;n.push({children:[],index:0});var o,c=n[0];for(a=0;a<s;a++){for(r=0;r<e[a];r++){(c=n.pop()).children[c.index]=t[i];for(;c.index>0;)c=n.pop();c.index++;n.push(c);for(;n.length<=a;){n.push(o={children:[],index:0});c.children[c.index]=o.children;c=o}i++}if(a+1<s){n.push(o={children:[],index:0});c.children[c.index]=o.children;c=o}}return n[0].children}function c(e,t,a){return 64*((e.blocksPerLine+1)*t+a)}function l(t,a,l,h,u,f,g,m,p,b=!1){var y=l.mcusPerLine,v=l.progressive,w=a,k=0,S=0;function C(){if(S>0){S--;return k>>S&1}if(255===(k=t[a++])){var e=t[a++];if(e){if(220===e&&b){a+=2;const e=(0,i.readUint16)(t,a);a+=2;if(e>0&&e!==l.scanLines)throw new s("Found DNL marker (0xFFDC) while parsing scan data",e)}else if(217===e){if(b){const e=8*O;if(e>0&&e<l.scanLines/10)throw new s("Found EOI marker (0xFFD9) while parsing scan data, possibly caused by incorrect `scanLines` parameter",e)}throw new o("Found EOI marker (0xFFD9) while parsing scan data")}throw new n(`unexpected marker ${(k<<8|e).toString(16)}`)}}S=7;return k>>>7}function x(e){for(var t=e;;){switch(typeof(t=t[C()])){case"number":return t;case"object":continue}throw new n("invalid huffman sequence")}}function A(e){for(var t=0;e>0;){t=t<<1|C();e--}return t}function I(e){if(1===e)return 1===C()?1:-1;var t=A(e);return t>=1<<e-1?t:t+(-1<<e)+1}var F=0;var T,E=0;let O=0;function P(e,t,a,r,i){var n=a%y;O=(a/y|0)*e.v+r;var s=n*e.h+i;t(e,c(e,O,s))}function B(e,t,a){O=a/e.blocksPerLine|0;var r=a%e.blocksPerLine;t(e,c(e,O,r))}var D,N,M,L,R,U,q=h.length;U=v?0===f?0===m?function(e,t){var a=x(e.huffmanTableDC),r=0===a?0:I(a)<<p;e.blockData[t]=e.pred+=r}:function(e,t){e.blockData[t]|=C()<<p}:0===m?function(t,a){if(F>0)F--;else for(var r=f,i=g;r<=i;){var n=x(t.huffmanTableAC),s=15&n,o=n>>4;if(0!==s){var c=e[r+=o];t.blockData[a+c]=I(s)*(1<<p);r++}else{if(o<15){F=A(o)+(1<<o)-1;break}r+=16}}}:function(t,a){for(var r,i,s=f,o=g,c=0;s<=o;){const o=a+e[s],l=t.blockData[o]<0?-1:1;switch(E){case 0:c=(i=x(t.huffmanTableAC))>>4;if(0===(r=15&i))if(c<15){F=A(c)+(1<<c);E=4}else{c=16;E=1}else{if(1!==r)throw new n("invalid ACn encoding");T=I(r);E=c?2:3}continue;case 1:case 2:t.blockData[o]?t.blockData[o]+=l*(C()<<p):0===--c&&(E=2===E?3:0);break;case 3:if(t.blockData[o])t.blockData[o]+=l*(C()<<p);else{t.blockData[o]=T<<p;E=0}break;case 4:t.blockData[o]&&(t.blockData[o]+=l*(C()<<p))}s++}4===E&&0===--F&&(E=0)}:function(t,a){var r=x(t.huffmanTableDC),i=0===r?0:I(r);t.blockData[a]=t.pred+=i;for(var n=1;n<64;){var s=x(t.huffmanTableAC),o=15&s,c=s>>4;if(0!==o){var l=e[n+=c];t.blockData[a+l]=I(o);n++}else{if(c<15)break;n+=16}}};var j,_,z,H,G=0;_=1===q?h[0].blocksPerLine*h[0].blocksPerColumn:y*l.mcusPerColumn;for(;G<_;){var W=u?Math.min(_-G,u):_;for(N=0;N<q;N++)h[N].pred=0;F=0;if(1===q){D=h[0];for(R=0;R<W;R++){B(D,U,G);G++}}else for(R=0;R<W;R++){for(N=0;N<q;N++){z=(D=h[N]).h;H=D.v;for(M=0;M<H;M++)for(L=0;L<z;L++)P(D,U,G,M,L)}G++}S=0;if(!(j=d(t,a)))break;if(j.invalid){(0,r.warn)("decodeScan - unexpected MCU data, current marker is: "+j.invalid);a=j.offset}var X=j&&j.marker;if(!X||X<=65280)throw new n("decodeScan - a valid marker was not found.");if(!(X>=65488&&X<=65495))break;a+=2}if((j=d(t,a))&&j.invalid){(0,r.warn)("decodeScan - unexpected Scan data, current marker is: "+j.invalid);a=j.offset}return a-w}function h(e,t,a){var r,i,s,o,c,l,h,u,d,f,g,m,p,b,y,v,w,k=e.quantizationTable,S=e.blockData;if(!k)throw new n("missing required Quantization Table.");for(var C=0;C<64;C+=8){d=S[t+C];f=S[t+C+1];g=S[t+C+2];m=S[t+C+3];p=S[t+C+4];b=S[t+C+5];y=S[t+C+6];v=S[t+C+7];d*=k[C];if(0!=(f|g|m|p|b|y|v)){f*=k[C+1];g*=k[C+2];m*=k[C+3];p*=k[C+4];b*=k[C+5];i=(r=(r=5793*d+128>>8)+(i=5793*p+128>>8)+1>>1)-i;w=3784*(s=g)+1567*(o=y*=k[C+6])+128>>8;s=1567*s-3784*o+128>>8;h=(c=(c=2896*(f-(v*=k[C+7]))+128>>8)+(h=b<<4)+1>>1)-h;l=(u=(u=2896*(f+v)+128>>8)+(l=m<<4)+1>>1)-l;o=(r=r+(o=w)+1>>1)-o;s=(i=i+s+1>>1)-s;w=2276*c+3406*u+2048>>12;c=3406*c-2276*u+2048>>12;u=w;w=799*l+4017*h+2048>>12;l=4017*l-799*h+2048>>12;h=w;a[C]=r+u;a[C+7]=r-u;a[C+1]=i+h;a[C+6]=i-h;a[C+2]=s+l;a[C+5]=s-l;a[C+3]=o+c;a[C+4]=o-c}else{w=5793*d+512>>10;a[C]=w;a[C+1]=w;a[C+2]=w;a[C+3]=w;a[C+4]=w;a[C+5]=w;a[C+6]=w;a[C+7]=w}}for(var x=0;x<8;++x){d=a[x];if(0!=((f=a[x+8])|(g=a[x+16])|(m=a[x+24])|(p=a[x+32])|(b=a[x+40])|(y=a[x+48])|(v=a[x+56]))){i=(r=4112+((r=5793*d+2048>>12)+(i=5793*p+2048>>12)+1>>1))-i;w=3784*(s=g)+1567*(o=y)+2048>>12;s=1567*s-3784*o+2048>>12;o=w;h=(c=(c=2896*(f-v)+2048>>12)+(h=b)+1>>1)-h;l=(u=(u=2896*(f+v)+2048>>12)+(l=m)+1>>1)-l;w=2276*c+3406*u+2048>>12;c=3406*c-2276*u+2048>>12;u=w;w=799*l+4017*h+2048>>12;l=4017*l-799*h+2048>>12;(d=(r=r+o+1>>1)+u)<16?d=0:d>=4080?d=255:d>>=4;(f=(i=i+s+1>>1)+(h=w))<16?f=0:f>=4080?f=255:f>>=4;(g=(s=i-s)+l)<16?g=0:g>=4080?g=255:g>>=4;(m=(o=r-o)+c)<16?m=0:m>=4080?m=255:m>>=4;(p=o-c)<16?p=0:p>=4080?p=255:p>>=4;(b=s-l)<16?b=0:b>=4080?b=255:b>>=4;(y=i-h)<16?y=0:y>=4080?y=255:y>>=4;(v=r-u)<16?v=0:v>=4080?v=255:v>>=4;S[t+x]=d;S[t+x+8]=f;S[t+x+16]=g;S[t+x+24]=m;S[t+x+32]=p;S[t+x+40]=b;S[t+x+48]=y;S[t+x+56]=v}else{w=(w=5793*d+8192>>14)<-2040?0:w>=2024?255:w+2056>>4;S[t+x]=w;S[t+x+8]=w;S[t+x+16]=w;S[t+x+24]=w;S[t+x+32]=w;S[t+x+40]=w;S[t+x+48]=w;S[t+x+56]=w}}}function u(e,t){for(var a=t.blocksPerLine,r=t.blocksPerColumn,i=new Int16Array(64),n=0;n<r;n++)for(var s=0;s<a;s++){h(t,c(t,n,s),i)}return t.blockData}function d(e,t,a=t){const r=e.length-1;var n=a<t?a:t;if(t>=r)return null;var s=(0,i.readUint16)(e,t);if(s>=65472&&s<=65534)return{invalid:null,marker:s,offset:t};for(var o=(0,i.readUint16)(e,n);!(o>=65472&&o<=65534);){if(++n>=r)return null;o=(0,i.readUint16)(e,n)}return{invalid:s.toString(16),marker:o,offset:n}}t.prototype={parse(t,{dnlScanLines:c=null}={}){function h(){const e=(0,i.readUint16)(t,p);let a=(p+=2)+e-2;var n=d(t,a,p);if(n&&n.invalid){(0,r.warn)("readDataBlock - incorrect length, current marker is: "+n.invalid);a=n.offset}var s=t.subarray(p,a);p+=s.length;return s}function f(e){for(var t=Math.ceil(e.samplesPerLine/8/e.maxH),a=Math.ceil(e.scanLines/8/e.maxV),r=0;r<e.components.length;r++){z=e.components[r];var i=Math.ceil(Math.ceil(e.samplesPerLine/8)*z.h/e.maxH),n=Math.ceil(Math.ceil(e.scanLines/8)*z.v/e.maxV),s=t*z.h,o=64*(a*z.v)*(s+1);z.blockData=new Int16Array(o);z.blocksPerLine=i;z.blocksPerColumn=n}e.mcusPerLine=t;e.mcusPerColumn=a}var g,m,p=0,b=null,y=null;let v=0;var w=[],k=[],S=[];let C=(0,i.readUint16)(t,p);p+=2;if(65496!==C)throw new n("SOI not found");C=(0,i.readUint16)(t,p);p+=2;e:for(;65497!==C;){var x,A,I;switch(C){case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:case 65534:var F=h();65504===C&&74===F[0]&&70===F[1]&&73===F[2]&&70===F[3]&&0===F[4]&&(b={version:{major:F[5],minor:F[6]},densityUnits:F[7],xDensity:F[8]<<8|F[9],yDensity:F[10]<<8|F[11],thumbWidth:F[12],thumbHeight:F[13],thumbData:F.subarray(14,14+3*F[12]*F[13])});65518===C&&65===F[0]&&100===F[1]&&111===F[2]&&98===F[3]&&101===F[4]&&(y={version:F[5]<<8|F[6],flags0:F[7]<<8|F[8],flags1:F[9]<<8|F[10],transformCode:F[11]});break;case 65499:for(var T=(0,i.readUint16)(t,p)+(p+=2)-2;p<T;){var E=t[p++],O=new Uint16Array(64);if(E>>4==0)for(A=0;A<64;A++)O[e[A]]=t[p++];else{if(E>>4!=1)throw new n("DQT - invalid table spec");for(A=0;A<64;A++){O[e[A]]=(0,i.readUint16)(t,p);p+=2}}w[15&E]=O}break;case 65472:case 65473:case 65474:if(g)throw new n("Only single frame JPEGs supported");p+=2;(g={}).extended=65473===C;g.progressive=65474===C;g.precision=t[p++];const u=(0,i.readUint16)(t,p);p+=2;g.scanLines=c||u;g.samplesPerLine=(0,i.readUint16)(t,p);p+=2;g.components=[];g.componentIds={};var P,B=t[p++],D=0,N=0;for(x=0;x<B;x++){P=t[p];var M=t[p+1]>>4,L=15&t[p+1];D<M&&(D=M);N<L&&(N=L);var R=t[p+2];I=g.components.push({h:M,v:L,quantizationId:R,quantizationTable:null});g.componentIds[P]=I-1;p+=3}g.maxH=D;g.maxV=N;f(g);break;case 65476:const J=(0,i.readUint16)(t,p);p+=2;for(x=2;x<J;){var U=t[p++],q=new Uint8Array(16),j=0;for(A=0;A<16;A++,p++)j+=q[A]=t[p];var _=new Uint8Array(j);for(A=0;A<j;A++,p++)_[A]=t[p];x+=17+j;(U>>4==0?S:k)[15&U]=a(q,_)}break;case 65501:p+=2;m=(0,i.readUint16)(t,p);p+=2;break;case 65498:const Z=1==++v&&!c;p+=2;var z,H=t[p++],G=[];for(x=0;x<H;x++){var W=g.componentIds[t[p++]];z=g.components[W];var X=t[p++];z.huffmanTableDC=S[X>>4];z.huffmanTableAC=k[15&X];G.push(z)}var V=t[p++],K=t[p++],Y=t[p++];try{var $=l(t,p,g,G,m,V,K,Y>>4,15&Y,Z);p+=$}catch(e){if(e instanceof s){(0,r.warn)(`${e.message} -- attempting to re-parse the JPEG image.`);return this.parse(t,{dnlScanLines:e.scanLines})}if(e instanceof o){(0,r.warn)(`${e.message} -- ignoring the rest of the image data.`);break e}throw e}break;case 65500:p+=4;break;case 65535:255!==t[p]&&p--;break;default:const Q=d(t,p-2,p-3);if(Q&&Q.invalid){(0,r.warn)("JpegImage.parse - unexpected data, current marker is: "+Q.invalid);p=Q.offset;break}if(p>=t.length-1){(0,r.warn)("JpegImage.parse - reached the end of the image data without finding an EOI marker (0xFFD9).");break e}throw new n("JpegImage.parse - unknown marker: "+C.toString(16))}C=(0,i.readUint16)(t,p);p+=2}this.width=g.samplesPerLine;this.height=g.scanLines;this.jfif=b;this.adobe=y;this.components=[];for(x=0;x<g.components.length;x++){var J=w[(z=g.components[x]).quantizationId];J&&(z.quantizationTable=J);this.components.push({output:u(0,z),scaleX:z.h/g.maxH,scaleY:z.v/g.maxV,blocksPerLine:z.blocksPerLine,blocksPerColumn:z.blocksPerColumn})}this.numComponents=this.components.length},_getLinearizedBlockData(e,t,a=!1){var r,i,n,s,o,c,l,h,u,d,f,g=this.width/e,m=this.height/t,p=0,b=this.components.length,y=e*t*b,v=new Uint8ClampedArray(y),w=new Uint32Array(e);let k;for(l=0;l<b;l++){i=(r=this.components[l]).scaleX*g;n=r.scaleY*m;p=l;f=r.output;s=r.blocksPerLine+1<<3;if(i!==k){for(o=0;o<e;o++){h=0|o*i;w[o]=(4294967288&h)<<3|7&h}k=i}for(c=0;c<t;c++){d=s*(4294967288&(h=0|c*n))|(7&h)<<3;for(o=0;o<e;o++){v[p]=f[d+w[o]];p+=b}}}let S=this._decodeTransform;a||4!==b||S||(S=new Int32Array([-256,255,-256,255,-256,255,-256,255]));if(S)for(l=0;l<y;)for(h=0,u=0;h<b;h++,l++,u+=2)v[l]=(v[l]*S[u]>>8)+S[u+1];return v},get _isColorConversionNeeded(){return this.adobe?!!this.adobe.transformCode:3===this.numComponents?0!==this._colorTransform:1===this._colorTransform},_convertYccToRgb:function(e){for(var t,a,r,i=0,n=e.length;i<n;i+=3){t=e[i];a=e[i+1];r=e[i+2];e[i]=t-179.456+1.402*r;e[i+1]=t+135.459-.344*a-.714*r;e[i+2]=t-226.816+1.772*a}return e},_convertYcckToRgb:function(e){for(var t,a,r,i,n=0,s=0,o=e.length;s<o;s+=4){t=e[s];a=e[s+1];r=e[s+2];i=e[s+3];e[n++]=a*(-660635669420364e-19*a+.000437130475926232*r-54080610064599e-18*t+.00048449797120281*i-.154362151871126)-122.67195406894+r*(-.000957964378445773*r+.000817076911346625*t-.00477271405408747*i+1.53380253221734)+t*(.000961250184130688*t-.00266257332283933*i+.48357088451265)+i*(-.000336197177618394*i+.484791561490776);e[n++]=107.268039397724+a*(219927104525741e-19*a-.000640992018297945*r+.000659397001245577*t+.000426105652938837*i-.176491792462875)+r*(-.000778269941513683*r+.00130872261408275*t+.000770482631801132*i-.151051492775562)+t*(.00126935368114843*t-.00265090189010898*i+.25802910206845)+i*(-.000318913117588328*i-.213742400323665);e[n++]=a*(-.000570115196973677*a-263409051004589e-19*r+.0020741088115012*t-.00288260236853442*i+.814272968359295)-20.810012546947+r*(-153496057440975e-19*r-.000132689043961446*t+.000560833691242812*i-.195152027534049)+t*(.00174418132927582*t-.00255243321439347*i+.116935020465145)+i*(-.000343531996510555*i+.24165260232407)}return e.subarray(0,n)},_convertYcckToCmyk:function(e){for(var t,a,r,i=0,n=e.length;i<n;i+=4){t=e[i];a=e[i+1];r=e[i+2];e[i]=434.456-t-1.402*r;e[i+1]=119.541-t+.344*a+.714*r;e[i+2]=481.816-t-1.772*a}return e},_convertCmykToRgb:function(e){for(var t,a,r,i,n=0,s=0,o=e.length;s<o;s+=4){t=e[s];a=e[s+1];r=e[s+2];i=e[s+3];e[n++]=255+t*(-6747147073602441e-20*t+.0008379262121013727*a+.0002894718188643294*r+.003264231057537806*i-1.1185611867203937)+a*(26374107616089405e-21*a-8626949158638572e-20*r-.0002748769067499491*i-.02155688794978967)+r*(-3878099212869363e-20*r-.0003267808279485286*i+.0686742238595345)-i*(.0003361971776183937*i+.7430659151342254);e[n++]=255+t*(.00013596372813588848*t+.000924537132573585*a+.00010567359618683593*r+.0004791864687436512*i-.3109689587515875)+a*(-.00023545346108370344*a+.0002702845253534714*r+.0020200308977307156*i-.7488052167015494)+r*(6834815998235662e-20*r+.00015168452363460973*i-.09751927774728933)-i*(.0003189131175883281*i+.7364883807733168);e[n++]=255+t*(13598650411385307e-21*t+.00012423956175490851*a+.0004751985097583589*r-36729317476630422e-22*i-.05562186980264034)+a*(.00016141380598724676*a+.0009692239130725186*r+.0007782692450036253*i-.44015232367526463)+r*(5.068882914068769e-7*r+.0017778369011375071*i-.7591454649749609)-i*(.0003435319965105553*i+.7063770186160144)}return e.subarray(0,n)},getData({width:e,height:t,forceRGB:a=!1,isSourcePDF:r=!1}){if(this.numComponents>4)throw new n("Unsupported color mode");var i=this._getLinearizedBlockData(e,t,r);if(1===this.numComponents&&a){for(var s=i.length,o=new Uint8ClampedArray(3*s),c=0,l=0;l<s;l++){var h=i[l];o[c++]=h;o[c++]=h;o[c++]=h}return o}if(3===this.numComponents&&this._isColorConversionNeeded)return this._convertYccToRgb(i);if(4===this.numComponents){if(this._isColorConversionNeeded)return a?this._convertYcckToRgb(i):this._convertYcckToCmyk(i);if(a)return this._convertCmykToRgb(i)}return i}};return t}();t.JpegImage=c},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.JpxStream=void 0;var r=a(11),i=a(20),n=a(2);const s=function(){function e(e,t,a,i){this.stream=e;this.maybeLength=t;this.dict=a;this.params=i;r.DecodeStream.call(this,t)}e.prototype=Object.create(r.DecodeStream.prototype);Object.defineProperty(e.prototype,"bytes",{get:function(){return(0,n.shadow)(this,"bytes",this.stream.getBytes(this.maybeLength))},configurable:!0});e.prototype.ensureBuffer=function(e){};e.prototype.readBlock=function(){if(this.eof)return;const e=new i.JpxImage;e.parse(this.bytes);const t=e.width,a=e.height,r=e.componentsCount,n=e.tiles.length;if(1===n)this.buffer=e.tiles[0].items;else{const i=new Uint8ClampedArray(t*a*r);for(let a=0;a<n;a++){const n=e.tiles[a],s=n.width,o=n.height,c=n.left,l=n.top,h=n.items;let u=0,d=(t*l+c)*r;const f=t*r,g=s*r;for(let e=0;e<o;e++){const e=h.subarray(u,u+g);i.set(e,d);u+=g;d+=f}}this.buffer=i}this.bufferLength=this.buffer.length;this.eof=!0};return e}();t.JpxStream=s},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.JpxImage=void 0;var r=a(2),i=a(7),n=a(16);class s extends r.BaseException{constructor(e){super(`JPX error: ${e}`)}}var o=function(){var e={LL:0,LH:1,HL:1,HH:2};function t(){this.failOnCorruptedImage=!1}t.prototype={parse:function(e){if(65359!==(0,i.readUint16)(e,0))for(var t=0,a=e.length;t<a;){var n=8,o=(0,i.readUint32)(e,t),c=(0,i.readUint32)(e,t+4);t+=n;if(1===o){o=4294967296*(0,i.readUint32)(e,t)+(0,i.readUint32)(e,t+4);t+=8;n+=8}0===o&&(o=a-t+n);if(o<n)throw new s("Invalid box field size");var l=o-n,h=!0;switch(c){case 1785737832:h=!1;break;case 1668246642:var u=e[t];if(1===u){var d=(0,i.readUint32)(e,t+3);switch(d){case 16:case 17:case 18:break;default:(0,r.warn)("Unknown colorspace "+d)}}else 2===u&&(0,r.info)("ICC profile not supported");break;case 1785737827:this.parseCodestream(e,t,t+l);break;case 1783636e3:218793738!==(0,i.readUint32)(e,t)&&(0,r.warn)("Invalid JP2 signature");break;case 1783634458:case 1718909296:case 1920099697:case 1919251232:case 1768449138:break;default:var f=String.fromCharCode(c>>24&255,c>>16&255,c>>8&255,255&c);(0,r.warn)("Unsupported header type "+c+" ("+f+")")}h&&(t+=l)}else this.parseCodestream(e,0,e.length)},parseImageProperties:function(e){for(var t=e.getByte();t>=0;){if(65361===(t<<8|(t=e.getByte()))){e.skip(4);var a=e.getInt32()>>>0,r=e.getInt32()>>>0,i=e.getInt32()>>>0,n=e.getInt32()>>>0;e.skip(16);var o=e.getUint16();this.width=a-i;this.height=r-n;this.componentsCount=o;this.bitsPerComponent=8;return}}throw new s("No size marker found in JPX stream")},parseCodestream:function(e,t,n){var c={},l=!1;try{for(var h=t;h+1<n;){var u=(0,i.readUint16)(e,h);h+=2;var d,f,g,m,p,b,y=0;switch(u){case 65359:c.mainHeader=!0;break;case 65497:break;case 65361:y=(0,i.readUint16)(e,h);var k={};k.Xsiz=(0,i.readUint32)(e,h+4);k.Ysiz=(0,i.readUint32)(e,h+8);k.XOsiz=(0,i.readUint32)(e,h+12);k.YOsiz=(0,i.readUint32)(e,h+16);k.XTsiz=(0,i.readUint32)(e,h+20);k.YTsiz=(0,i.readUint32)(e,h+24);k.XTOsiz=(0,i.readUint32)(e,h+28);k.YTOsiz=(0,i.readUint32)(e,h+32);var x=(0,i.readUint16)(e,h+36);k.Csiz=x;var A=[];d=h+38;for(var I=0;I<x;I++){var F={precision:1+(127&e[d]),isSigned:!!(128&e[d]),XRsiz:e[d+1],YRsiz:e[d+2]};d+=3;a(F,k);A.push(F)}c.SIZ=k;c.components=A;o(c,A);c.QCC=[];c.COC=[];break;case 65372:y=(0,i.readUint16)(e,h);var T={};d=h+2;switch(31&(f=e[d++])){case 0:m=8;p=!0;break;case 1:m=16;p=!1;break;case 2:m=16;p=!0;break;default:throw new Error("Invalid SQcd value "+f)}T.noQuantization=8===m;T.scalarExpounded=p;T.guardBits=f>>5;g=[];for(;d<y+h;){var E={};if(8===m){E.epsilon=e[d++]>>3;E.mu=0}else{E.epsilon=e[d]>>3;E.mu=(7&e[d])<<8|e[d+1];d+=2}g.push(E)}T.SPqcds=g;if(c.mainHeader)c.QCD=T;else{c.currentTile.QCD=T;c.currentTile.QCC=[]}break;case 65373:y=(0,i.readUint16)(e,h);var O,P={};d=h+2;if(c.SIZ.Csiz<257)O=e[d++];else{O=(0,i.readUint16)(e,d);d+=2}switch(31&(f=e[d++])){case 0:m=8;p=!0;break;case 1:m=16;p=!1;break;case 2:m=16;p=!0;break;default:throw new Error("Invalid SQcd value "+f)}P.noQuantization=8===m;P.scalarExpounded=p;P.guardBits=f>>5;g=[];for(;d<y+h;){E={};if(8===m){E.epsilon=e[d++]>>3;E.mu=0}else{E.epsilon=e[d]>>3;E.mu=(7&e[d])<<8|e[d+1];d+=2}g.push(E)}P.SPqcds=g;c.mainHeader?c.QCC[O]=P:c.currentTile.QCC[O]=P;break;case 65362:y=(0,i.readUint16)(e,h);var B={};d=h+2;var D=e[d++];B.entropyCoderWithCustomPrecincts=!!(1&D);B.sopMarkerUsed=!!(2&D);B.ephMarkerUsed=!!(4&D);B.progressionOrder=e[d++];B.layersCount=(0,i.readUint16)(e,d);d+=2;B.multipleComponentTransform=e[d++];B.decompositionLevelsCount=e[d++];B.xcb=2+(15&e[d++]);B.ycb=2+(15&e[d++]);var N=e[d++];B.selectiveArithmeticCodingBypass=!!(1&N);B.resetContextProbabilities=!!(2&N);B.terminationOnEachCodingPass=!!(4&N);B.verticallyStripe=!!(8&N);B.predictableTermination=!!(16&N);B.segmentationSymbolUsed=!!(32&N);B.reversibleTransformation=e[d++];if(B.entropyCoderWithCustomPrecincts){for(var M=[];d<y+h;){var L=e[d++];M.push({PPx:15&L,PPy:L>>4})}B.precinctsSizes=M}var R=[];B.selectiveArithmeticCodingBypass&&R.push("selectiveArithmeticCodingBypass");B.resetContextProbabilities&&R.push("resetContextProbabilities");B.terminationOnEachCodingPass&&R.push("terminationOnEachCodingPass");B.verticallyStripe&&R.push("verticallyStripe");B.predictableTermination&&R.push("predictableTermination");if(R.length>0){l=!0;throw new Error("Unsupported COD options ("+R.join(", ")+")")}if(c.mainHeader)c.COD=B;else{c.currentTile.COD=B;c.currentTile.COC=[]}break;case 65424:y=(0,i.readUint16)(e,h);(b={}).index=(0,i.readUint16)(e,h+2);b.length=(0,i.readUint32)(e,h+4);b.dataEnd=b.length+h-2;b.partIndex=e[h+8];b.partsCount=e[h+9];c.mainHeader=!1;if(0===b.partIndex){b.COD=c.COD;b.COC=c.COC.slice(0);b.QCD=c.QCD;b.QCC=c.QCC.slice(0)}c.currentTile=b;break;case 65427:if(0===(b=c.currentTile).partIndex){C(c,b.index);v(c)}w(c,e,h,y=b.dataEnd-h);break;case 65365:case 65367:case 65368:case 65380:y=(0,i.readUint16)(e,h);break;case 65363:throw new Error("Codestream code 0xFF53 (COC) is not implemented");default:throw new Error("Unknown codestream code: "+u.toString(16))}h+=y}}catch(e){if(l||this.failOnCorruptedImage)throw new s(e.message);(0,r.warn)("JPX: Trying to recover from: "+e.message)}this.tiles=function(e){for(var t=e.SIZ,a=e.components,r=t.Csiz,i=[],n=0,s=e.tiles.length;n<s;n++){var o,c=e.tiles[n],l=[];for(o=0;o<r;o++)l[o]=S(e,c,o);var h,u,d,f,g,m,p,b=l[0],y=new Uint8ClampedArray(b.items.length*r),v={left:b.left,top:b.top,width:b.width,height:b.height,items:y},w=0;if(c.codingStyleDefaultParameters.multipleComponentTransform){var k=4===r,C=l[0].items,x=l[1].items,A=l[2].items,I=k?l[3].items:null;h=a[0].precision-8;u=.5+(128<<h);var F=c.components[0],T=r-3;f=C.length;if(F.codingStyleParameters.reversibleTransformation)for(d=0;d<f;d++,w+=T){g=C[d]+u;m=x[d];p=A[d];const e=g-(p+m>>2);y[w++]=e+p>>h;y[w++]=e>>h;y[w++]=e+m>>h}else for(d=0;d<f;d++,w+=T){g=C[d]+u;m=x[d];p=A[d];y[w++]=g+1.402*p>>h;y[w++]=g-.34413*m-.71414*p>>h;y[w++]=g+1.772*m>>h}if(k)for(d=0,w=3;d<f;d++,w+=4)y[w]=I[d]+u>>h}else for(o=0;o<r;o++){var E=l[o].items;h=a[o].precision-8;u=.5+(128<<h);for(w=o,d=0,f=E.length;d<f;d++){y[w]=E[d]+u>>h;w+=r}}i.push(v)}return i}(c);this.width=c.SIZ.Xsiz-c.SIZ.XOsiz;this.height=c.SIZ.Ysiz-c.SIZ.YOsiz;this.componentsCount=c.SIZ.Csiz}};function a(e,t){e.x0=Math.ceil(t.XOsiz/e.XRsiz);e.x1=Math.ceil(t.Xsiz/e.XRsiz);e.y0=Math.ceil(t.YOsiz/e.YRsiz);e.y1=Math.ceil(t.Ysiz/e.YRsiz);e.width=e.x1-e.x0;e.height=e.y1-e.y0}function o(e,t){for(var a,r=e.SIZ,i=[],n=Math.ceil((r.Xsiz-r.XTOsiz)/r.XTsiz),s=Math.ceil((r.Ysiz-r.YTOsiz)/r.YTsiz),o=0;o<s;o++)for(var c=0;c<n;c++){(a={}).tx0=Math.max(r.XTOsiz+c*r.XTsiz,r.XOsiz);a.ty0=Math.max(r.YTOsiz+o*r.YTsiz,r.YOsiz);a.tx1=Math.min(r.XTOsiz+(c+1)*r.XTsiz,r.Xsiz);a.ty1=Math.min(r.YTOsiz+(o+1)*r.YTsiz,r.Ysiz);a.width=a.tx1-a.tx0;a.height=a.ty1-a.ty0;a.components=[];i.push(a)}e.tiles=i;for(var l=0,h=r.Csiz;l<h;l++)for(var u=t[l],d=0,f=i.length;d<f;d++){var g={};a=i[d];g.tcx0=Math.ceil(a.tx0/u.XRsiz);g.tcy0=Math.ceil(a.ty0/u.YRsiz);g.tcx1=Math.ceil(a.tx1/u.XRsiz);g.tcy1=Math.ceil(a.ty1/u.YRsiz);g.width=g.tcx1-g.tcx0;g.height=g.tcy1-g.tcy0;a.components[l]=g}}function c(e,t,a){var r=t.codingStyleParameters,i={};if(r.entropyCoderWithCustomPrecincts){i.PPx=r.precinctsSizes[a].PPx;i.PPy=r.precinctsSizes[a].PPy}else{i.PPx=15;i.PPy=15}i.xcb_=a>0?Math.min(r.xcb,i.PPx-1):Math.min(r.xcb,i.PPx);i.ycb_=a>0?Math.min(r.ycb,i.PPy-1):Math.min(r.ycb,i.PPy);return i}function l(e,t,a){var r=1<<a.PPx,i=1<<a.PPy,n=0===t.resLevel,s=1<<a.PPx+(n?0:-1),o=1<<a.PPy+(n?0:-1),c=t.trx1>t.trx0?Math.ceil(t.trx1/r)-Math.floor(t.trx0/r):0,l=t.try1>t.try0?Math.ceil(t.try1/i)-Math.floor(t.try0/i):0,h=c*l;t.precinctParameters={precinctWidth:r,precinctHeight:i,numprecinctswide:c,numprecinctshigh:l,numprecincts:h,precinctWidthInSubband:s,precinctHeightInSubband:o}}function h(e,t,a){var r,i,n,s,o=a.xcb_,c=a.ycb_,l=1<<o,h=1<<c,u=t.tbx0>>o,d=t.tby0>>c,f=t.tbx1+l-1>>o,g=t.tby1+h-1>>c,m=t.resolution.precinctParameters,p=[],b=[];for(i=d;i<g;i++)for(r=u;r<f;r++){(n={cbx:r,cby:i,tbx0:l*r,tby0:h*i,tbx1:l*(r+1),tby1:h*(i+1)}).tbx0_=Math.max(t.tbx0,n.tbx0);n.tby0_=Math.max(t.tby0,n.tby0);n.tbx1_=Math.min(t.tbx1,n.tbx1);n.tby1_=Math.min(t.tby1,n.tby1);s=Math.floor((n.tbx0_-t.tbx0)/m.precinctWidthInSubband)+Math.floor((n.tby0_-t.tby0)/m.precinctHeightInSubband)*m.numprecinctswide;n.precinctNumber=s;n.subbandType=t.type;n.Lblock=3;if(!(n.tbx1_<=n.tbx0_||n.tby1_<=n.tby0_)){p.push(n);var y=b[s];if(void 0!==y){r<y.cbxMin?y.cbxMin=r:r>y.cbxMax&&(y.cbxMax=r);i<y.cbyMin?y.cbxMin=i:i>y.cbyMax&&(y.cbyMax=i)}else b[s]=y={cbxMin:r,cbyMin:i,cbxMax:r,cbyMax:i};n.precinct=y}}t.codeblockParameters={codeblockWidth:o,codeblockHeight:c,numcodeblockwide:f-u+1,numcodeblockhigh:g-d+1};t.codeblocks=p;t.precincts=b}function u(e,t,a){for(var r=[],i=e.subbands,n=0,s=i.length;n<s;n++)for(var o=i[n].codeblocks,c=0,l=o.length;c<l;c++){var h=o[c];h.precinctNumber===t&&r.push(h)}return{layerNumber:a,codeblocks:r}}function d(e){for(var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=r.codingStyleDefaultParameters.layersCount,n=t.Csiz,o=0,c=0;c<n;c++)o=Math.max(o,r.components[c].codingStyleParameters.decompositionLevelsCount);var l=0,h=0,d=0,f=0;this.nextPacket=function(){for(;l<i;l++){for(;h<=o;h++){for(;d<n;d++){var e=r.components[d];if(!(h>e.codingStyleParameters.decompositionLevelsCount)){for(var t=e.resolutions[h],a=t.precinctParameters.numprecincts;f<a;){var c=u(t,f,l);f++;return c}f=0}}d=0}h=0}throw new s("Out of packets")}}function f(e){for(var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=r.codingStyleDefaultParameters.layersCount,n=t.Csiz,o=0,c=0;c<n;c++)o=Math.max(o,r.components[c].codingStyleParameters.decompositionLevelsCount);var l=0,h=0,d=0,f=0;this.nextPacket=function(){for(;l<=o;l++){for(;h<i;h++){for(;d<n;d++){var e=r.components[d];if(!(l>e.codingStyleParameters.decompositionLevelsCount)){for(var t=e.resolutions[l],a=t.precinctParameters.numprecincts;f<a;){var c=u(t,f,h);f++;return c}f=0}}d=0}h=0}throw new s("Out of packets")}}function g(e){var t,a,r,i,n=e.SIZ,o=e.currentTile.index,c=e.tiles[o],l=c.codingStyleDefaultParameters.layersCount,h=n.Csiz,d=0;for(r=0;r<h;r++){var f=c.components[r];d=Math.max(d,f.codingStyleParameters.decompositionLevelsCount)}var g=new Int32Array(d+1);for(a=0;a<=d;++a){var m=0;for(r=0;r<h;++r){var p=c.components[r].resolutions;a<p.length&&(m=Math.max(m,p[a].precinctParameters.numprecincts))}g[a]=m}t=0;a=0;r=0;i=0;this.nextPacket=function(){for(;a<=d;a++){for(;i<g[a];i++){for(;r<h;r++){var e=c.components[r];if(!(a>e.codingStyleParameters.decompositionLevelsCount)){var n=e.resolutions[a],o=n.precinctParameters.numprecincts;if(!(i>=o)){for(;t<l;){var f=u(n,i,t);t++;return f}t=0}}}r=0}i=0}throw new s("Out of packets")}}function m(e){var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=r.codingStyleDefaultParameters.layersCount,n=t.Csiz,o=y(r),c=o,l=0,h=0,d=0,f=0,g=0;this.nextPacket=function(){for(;g<c.maxNumHigh;g++){for(;f<c.maxNumWide;f++){for(;d<n;d++){for(var e=r.components[d],t=e.codingStyleParameters.decompositionLevelsCount;h<=t;h++){var a=e.resolutions[h],m=o.components[d].resolutions[h],p=b(f,g,m,c,a);if(null!==p){for(;l<i;){var y=u(a,p,l);l++;return y}l=0}}h=0}d=0}f=0}throw new s("Out of packets")}}function p(e){var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=r.codingStyleDefaultParameters.layersCount,n=t.Csiz,o=y(r),c=0,l=0,h=0,d=0,f=0;this.nextPacket=function(){for(;h<n;++h){for(var e=r.components[h],t=o.components[h],a=e.codingStyleParameters.decompositionLevelsCount;f<t.maxNumHigh;f++){for(;d<t.maxNumWide;d++){for(;l<=a;l++){var g=e.resolutions[l],m=t.resolutions[l],p=b(d,f,m,t,g);if(null!==p){for(;c<i;){var y=u(g,p,c);c++;return y}c=0}}l=0}d=0}f=0}throw new s("Out of packets")}}function b(e,t,a,r,i){var n=e*r.minWidth,s=t*r.minHeight;if(n%a.width!=0||s%a.height!=0)return null;var o=s/a.width*i.precinctParameters.numprecinctswide;return n/a.height+o}function y(e){for(var t=e.components.length,a=Number.MAX_VALUE,r=Number.MAX_VALUE,i=0,n=0,s=new Array(t),o=0;o<t;o++){for(var c=e.components[o],l=c.codingStyleParameters.decompositionLevelsCount,h=new Array(l+1),u=Number.MAX_VALUE,d=Number.MAX_VALUE,f=0,g=0,m=1,p=l;p>=0;--p){var b=c.resolutions[p],y=m*b.precinctParameters.precinctWidth,v=m*b.precinctParameters.precinctHeight;u=Math.min(u,y);d=Math.min(d,v);f=Math.max(f,b.precinctParameters.numprecinctswide);g=Math.max(g,b.precinctParameters.numprecinctshigh);h[p]={width:y,height:v};m<<=1}a=Math.min(a,u);r=Math.min(r,d);i=Math.max(i,f);n=Math.max(n,g);s[o]={resolutions:h,minWidth:u,minHeight:d,maxNumWide:f,maxNumHigh:g}}return{components:s,minWidth:a,minHeight:r,maxNumWide:i,maxNumHigh:n}}function v(e){for(var t=e.SIZ,a=e.currentTile.index,r=e.tiles[a],i=t.Csiz,n=0;n<i;n++){for(var o=r.components[n],u=o.codingStyleParameters.decompositionLevelsCount,b=[],y=[],v=0;v<=u;v++){var w,k=c(0,o,v),S={},C=1<<u-v;S.trx0=Math.ceil(o.tcx0/C);S.try0=Math.ceil(o.tcy0/C);S.trx1=Math.ceil(o.tcx1/C);S.try1=Math.ceil(o.tcy1/C);S.resLevel=v;l(0,S,k);b.push(S);if(0===v){(w={}).type="LL";w.tbx0=Math.ceil(o.tcx0/C);w.tby0=Math.ceil(o.tcy0/C);w.tbx1=Math.ceil(o.tcx1/C);w.tby1=Math.ceil(o.tcy1/C);w.resolution=S;h(0,w,k);y.push(w);S.subbands=[w]}else{var x=1<<u-v+1,A=[];(w={}).type="HL";w.tbx0=Math.ceil(o.tcx0/x-.5);w.tby0=Math.ceil(o.tcy0/x);w.tbx1=Math.ceil(o.tcx1/x-.5);w.tby1=Math.ceil(o.tcy1/x);w.resolution=S;h(0,w,k);y.push(w);A.push(w);(w={}).type="LH";w.tbx0=Math.ceil(o.tcx0/x);w.tby0=Math.ceil(o.tcy0/x-.5);w.tbx1=Math.ceil(o.tcx1/x);w.tby1=Math.ceil(o.tcy1/x-.5);w.resolution=S;h(0,w,k);y.push(w);A.push(w);(w={}).type="HH";w.tbx0=Math.ceil(o.tcx0/x-.5);w.tby0=Math.ceil(o.tcy0/x-.5);w.tbx1=Math.ceil(o.tcx1/x-.5);w.tby1=Math.ceil(o.tcy1/x-.5);w.resolution=S;h(0,w,k);y.push(w);A.push(w);S.subbands=A}}o.resolutions=b;o.subbands=y}var I=r.codingStyleDefaultParameters.progressionOrder;switch(I){case 0:r.packetsIterator=new d(e);break;case 1:r.packetsIterator=new f(e);break;case 2:r.packetsIterator=new g(e);break;case 3:r.packetsIterator=new m(e);break;case 4:r.packetsIterator=new p(e);break;default:throw new s(`Unsupported progression order ${I}`)}}function w(e,t,a,r){var n,s=0,o=0,c=!1;function l(e){for(;o<e;){var r=t[a+s];s++;if(c){n=n<<7|r;o+=7;c=!1}else{n=n<<8|r;o+=8}255===r&&(c=!0)}return n>>>(o-=e)&(1<<e)-1}function h(e){if(255===t[a+s-1]&&t[a+s]===e){u(1);return!0}if(255===t[a+s]&&t[a+s+1]===e){u(2);return!0}return!1}function u(e){s+=e}function d(){o=0;if(c){s++;c=!1}}function f(){if(0===l(1))return 1;if(0===l(1))return 2;var e=l(2);return e<3?e+3:(e=l(5))<31?e+6:(e=l(7))+37}for(var g=e.currentTile.index,m=e.tiles[g],p=e.COD.sopMarkerUsed,b=e.COD.ephMarkerUsed,y=m.packetsIterator;s<r;){d();p&&h(145)&&u(4);var v=y.nextPacket();if(l(1)){for(var w,k=v.layerNumber,S=[],C=0,I=v.codeblocks.length;C<I;C++){var F=(w=v.codeblocks[C]).precinct,T=w.cbx-F.cbxMin,E=w.cby-F.cbyMin,O=!1,P=!1;if(void 0!==w.included)O=!!l(1);else{var B,D;if(void 0!==(F=w.precinct).inclusionTree)B=F.inclusionTree;else{var N=F.cbxMax-F.cbxMin+1,M=F.cbyMax-F.cbyMin+1;B=new A(N,M,k);D=new x(N,M);F.inclusionTree=B;F.zeroBitPlanesTree=D}if(B.reset(T,E,k))for(;;){if(!l(1)){B.incrementValue(k);break}if(!B.nextLevel()){w.included=!0;O=P=!0;break}}}if(O){if(P){(D=F.zeroBitPlanesTree).reset(T,E);for(;;)if(l(1)){if(!D.nextLevel())break}else D.incrementValue();w.zeroBitPlanes=D.value}for(var L=f();l(1);)w.Lblock++;var R=(0,i.log2)(L),U=l((L<1<<R?R-1:R)+w.Lblock);S.push({codeblock:w,codingpasses:L,dataLength:U})}}d();b&&h(146);for(;S.length>0;){var q=S.shift();void 0===(w=q.codeblock).data&&(w.data=[]);w.data.push({data:t,start:a+s,end:a+s+q.dataLength,codingpasses:q.codingpasses});s+=q.dataLength}}}return s}function k(e,t,a,r,i,s,o,c){for(var l=r.tbx0,h=r.tby0,u=r.tbx1-r.tbx0,d=r.codeblocks,f="H"===r.type.charAt(0)?1:0,g="H"===r.type.charAt(1)?t:0,m=0,p=d.length;m<p;++m){var b=d[m],y=b.tbx1_-b.tbx0_,v=b.tby1_-b.tby0_;if(0!==y&&0!==v&&void 0!==b.data){var w,k;w=new I(y,v,b.subbandType,b.zeroBitPlanes,s);k=2;var S,C,x,A=b.data,F=0,T=0;for(S=0,C=A.length;S<C;S++){F+=(x=A[S]).end-x.start;T+=x.codingpasses}var E=new Uint8Array(F),O=0;for(S=0,C=A.length;S<C;S++){var P=(x=A[S]).data.subarray(x.start,x.end);E.set(P,O);O+=P.length}var B=new n.ArithmeticDecoder(E,0,F);w.setDecoder(B);for(S=0;S<T;S++){switch(k){case 0:w.runSignificancePropagationPass();break;case 1:w.runMagnitudeRefinementPass();break;case 2:w.runCleanupPass();c&&w.checkSegmentationSymbol()}k=(k+1)%3}var D,N,M,L=b.tbx0_-l+(b.tby0_-h)*u,R=w.coefficentsSign,U=w.coefficentsMagnitude,q=w.bitsDecoded,j=o?0:.5;O=0;var _="LL"!==r.type;for(S=0;S<v;S++){var z=2*(L/u|0)*(t-u)+f+g;for(D=0;D<y;D++){if(0!==(N=U[O])){N=(N+j)*i;0!==R[O]&&(N=-N);M=q[O];var H=_?z+(L<<1):L;e[H]=o&&M>=s?N:N*(1<<s-M)}L++;O++}L+=u-y}}}}function S(t,a,r){for(var i=a.components[r],n=i.codingStyleParameters,s=i.quantizationParameters,o=n.decompositionLevelsCount,c=s.SPqcds,l=s.scalarExpounded,h=s.guardBits,u=n.segmentationSymbolUsed,d=t.components[r].precision,f=n.reversibleTransformation,g=f?new E:new T,m=[],p=0,b=0;b<=o;b++){for(var y=i.resolutions[b],v=y.trx1-y.trx0,w=y.try1-y.try0,S=new Float32Array(v*w),C=0,x=y.subbands.length;C<x;C++){var A,I;if(l){A=c[p].mu;I=c[p].epsilon;p++}else{A=c[0].mu;I=c[0].epsilon+(b>0?1-b:0)}var F=y.subbands[C],O=e[F.type];k(S,v,0,F,f?1:2**(d+O-I)*(1+A/2048),h+I-1,f,u)}m.push({width:v,height:w,items:S})}var P=g.calculate(m,i.tcx0,i.tcy0);return{left:i.tcx0,top:i.tcy0,width:P.width,height:P.height,items:P.items}}function C(e,t){for(var a=e.SIZ.Csiz,r=e.tiles[t],i=0;i<a;i++){var n=r.components[i],s=void 0!==e.currentTile.QCC[i]?e.currentTile.QCC[i]:e.currentTile.QCD;n.quantizationParameters=s;var o=void 0!==e.currentTile.COC[i]?e.currentTile.COC[i]:e.currentTile.COD;n.codingStyleParameters=o}r.codingStyleDefaultParameters=e.currentTile.COD}var x=function(){function e(e,t){var a=(0,i.log2)(Math.max(e,t))+1;this.levels=[];for(var r=0;r<a;r++){var n={width:e,height:t,items:[]};this.levels.push(n);e=Math.ceil(e/2);t=Math.ceil(t/2)}}e.prototype={reset:function(e,t){for(var a,r=0,i=0;r<this.levels.length;){var n=e+t*(a=this.levels[r]).width;if(void 0!==a.items[n]){i=a.items[n];break}a.index=n;e>>=1;t>>=1;r++}r--;(a=this.levels[r]).items[a.index]=i;this.currentLevel=r;delete this.value},incrementValue:function(){var e=this.levels[this.currentLevel];e.items[e.index]++},nextLevel:function(){var e=this.currentLevel,t=this.levels[e],a=t.items[t.index];if(--e<0){this.value=a;return!1}this.currentLevel=e;(t=this.levels[e]).items[t.index]=a;return!0}};return e}(),A=function(){function e(e,t,a){var r=(0,i.log2)(Math.max(e,t))+1;this.levels=[];for(var n=0;n<r;n++){for(var s=new Uint8Array(e*t),o=0,c=s.length;o<c;o++)s[o]=a;var l={width:e,height:t,items:s};this.levels.push(l);e=Math.ceil(e/2);t=Math.ceil(t/2)}}e.prototype={reset:function(e,t,a){for(var r=0;r<this.levels.length;){var i=this.levels[r],n=e+t*i.width;i.index=n;var s=i.items[n];if(255===s)break;if(s>a){this.currentLevel=r;this.propagateValues();return!1}e>>=1;t>>=1;r++}this.currentLevel=r-1;return!0},incrementValue:function(e){var t=this.levels[this.currentLevel];t.items[t.index]=e+1;this.propagateValues()},propagateValues:function(){for(var e=this.currentLevel,t=this.levels[e],a=t.items[t.index];--e>=0;)(t=this.levels[e]).items[t.index]=a},nextLevel:function(){var e=this.currentLevel,t=this.levels[e],a=t.items[t.index];t.items[t.index]=255;if(--e<0)return!1;this.currentLevel=e;(t=this.levels[e]).items[t.index]=a;return!0}};return e}(),I=function(){var e=new Uint8Array([0,5,8,0,3,7,8,0,4,7,8,0,0,0,0,0,1,6,8,0,3,7,8,0,4,7,8,0,0,0,0,0,2,6,8,0,3,7,8,0,4,7,8,0,0,0,0,0,2,6,8,0,3,7,8,0,4,7,8,0,0,0,0,0,2,6,8,0,3,7,8,0,4,7,8]),t=new Uint8Array([0,3,4,0,5,7,7,0,8,8,8,0,0,0,0,0,1,3,4,0,6,7,7,0,8,8,8,0,0,0,0,0,2,3,4,0,6,7,7,0,8,8,8,0,0,0,0,0,2,3,4,0,6,7,7,0,8,8,8,0,0,0,0,0,2,3,4,0,6,7,7,0,8,8,8]),a=new Uint8Array([0,1,2,0,1,2,2,0,2,2,2,0,0,0,0,0,3,4,5,0,4,5,5,0,5,5,5,0,0,0,0,0,6,7,7,0,7,7,7,0,7,7,7,0,0,0,0,0,8,8,8,0,8,8,8,0,8,8,8,0,0,0,0,0,8,8,8,0,8,8,8,0,8,8,8]);function r(r,i,n,s,o){this.width=r;this.height=i;let c;c="HH"===n?a:"HL"===n?t:e;this.contextLabelTable=c;var l=r*i;this.neighborsSignificance=new Uint8Array(l);this.coefficentsSign=new Uint8Array(l);let h;h=o>14?new Uint32Array(l):o>6?new Uint16Array(l):new Uint8Array(l);this.coefficentsMagnitude=h;this.processingFlags=new Uint8Array(l);var u=new Uint8Array(l);if(0!==s)for(var d=0;d<l;d++)u[d]=s;this.bitsDecoded=u;this.reset()}r.prototype={setDecoder:function(e){this.decoder=e},reset:function(){this.contexts=new Int8Array(19);this.contexts[0]=8;this.contexts[17]=92;this.contexts[18]=6},setNeighborsSignificance:function(e,t,a){var r,i=this.neighborsSignificance,n=this.width,s=this.height,o=t>0,c=t+1<n;if(e>0){r=a-n;o&&(i[r-1]+=16);c&&(i[r+1]+=16);i[r]+=4}if(e+1<s){r=a+n;o&&(i[r-1]+=16);c&&(i[r+1]+=16);i[r]+=4}o&&(i[a-1]+=1);c&&(i[a+1]+=1);i[a]|=128},runSignificancePropagationPass:function(){for(var e=this.decoder,t=this.width,a=this.height,r=this.coefficentsMagnitude,i=this.coefficentsSign,n=this.neighborsSignificance,s=this.processingFlags,o=this.contexts,c=this.contextLabelTable,l=this.bitsDecoded,h=0;h<a;h+=4)for(var u=0;u<t;u++)for(var d=h*t+u,f=0;f<4;f++,d+=t){var g=h+f;if(g>=a)break;s[d]&=-2;if(!r[d]&&n[d]){var m=c[n[d]];if(e.readBit(o,m)){var p=this.decodeSignBit(g,u,d);i[d]=p;r[d]=1;this.setNeighborsSignificance(g,u,d);s[d]|=2}l[d]++;s[d]|=1}}},decodeSignBit:function(e,t,a){var r,i,n,s,o,c,l=this.width,h=this.height,u=this.coefficentsMagnitude,d=this.coefficentsSign;s=t>0&&0!==u[a-1];if(t+1<l&&0!==u[a+1]){n=d[a+1];r=s?1-n-(i=d[a-1]):1-n-n}else r=s?1-(i=d[a-1])-i:0;var f=3*r;s=e>0&&0!==u[a-l];if(e+1<h&&0!==u[a+l]){n=d[a+l];r=s?1-n-(i=d[a-l])+f:1-n-n+f}else r=s?1-(i=d[a-l])-i+f:f;if(r>=0){o=9+r;c=this.decoder.readBit(this.contexts,o)}else{o=9-r;c=1^this.decoder.readBit(this.contexts,o)}return c},runMagnitudeRefinementPass:function(){for(var e,t=this.decoder,a=this.width,r=this.height,i=this.coefficentsMagnitude,n=this.neighborsSignificance,s=this.contexts,o=this.bitsDecoded,c=this.processingFlags,l=a*r,h=4*a,u=0;u<l;u=e){e=Math.min(l,u+h);for(var d=0;d<a;d++)for(var f=u+d;f<e;f+=a)if(i[f]&&0==(1&c[f])){var g=16;if(0!=(2&c[f])){c[f]^=2;g=0===(127&n[f])?15:14}var m=t.readBit(s,g);i[f]=i[f]<<1|m;o[f]++;c[f]|=1}}},runCleanupPass:function(){for(var e,t=this.decoder,a=this.width,r=this.height,i=this.neighborsSignificance,n=this.coefficentsMagnitude,s=this.coefficentsSign,o=this.contexts,c=this.contextLabelTable,l=this.bitsDecoded,h=this.processingFlags,u=a,d=2*a,f=3*a,g=0;g<r;g=e){e=Math.min(g+4,r);for(var m=g*a,p=g+3<r,b=0;b<a;b++){var y,v=m+b,w=0,k=v,S=g;if(p&&0===h[v]&&0===h[v+u]&&0===h[v+d]&&0===h[v+f]&&0===i[v]&&0===i[v+u]&&0===i[v+d]&&0===i[v+f]){if(!t.readBit(o,18)){l[v]++;l[v+u]++;l[v+d]++;l[v+f]++;continue}if(0!==(w=t.readBit(o,17)<<1|t.readBit(o,17))){S=g+w;k+=w*a}y=this.decodeSignBit(S,b,k);s[k]=y;n[k]=1;this.setNeighborsSignificance(S,b,k);h[k]|=2;k=v;for(var C=g;C<=S;C++,k+=a)l[k]++;w++}for(S=g+w;S<e;S++,k+=a)if(!n[k]&&0==(1&h[k])){var x=c[i[k]];if(1===t.readBit(o,x)){y=this.decodeSignBit(S,b,k);s[k]=y;n[k]=1;this.setNeighborsSignificance(S,b,k);h[k]|=2}l[k]++}}}},checkSegmentationSymbol:function(){var e=this.decoder,t=this.contexts;if(10!==(e.readBit(t,17)<<3|e.readBit(t,17)<<2|e.readBit(t,17)<<1|e.readBit(t,17)))throw new s("Invalid segmentation symbol")}};return r}(),F=function(){function e(){}e.prototype.calculate=function(e,t,a){for(var r=e[0],i=1,n=e.length;i<n;i++)r=this.iterate(r,e[i],t,a);return r};e.prototype.extend=function(e,t,a){var r=t-1,i=t+1,n=t+a-2,s=t+a;e[r--]=e[i++];e[s++]=e[n--];e[r--]=e[i++];e[s++]=e[n--];e[r--]=e[i++];e[s++]=e[n--];e[r]=e[i];e[s]=e[n]};e.prototype.iterate=function(e,t,a,r){var i,n,s,o,c,l,h=e.width,u=e.height,d=e.items,f=t.width,g=t.height,m=t.items;for(s=0,i=0;i<u;i++){o=2*i*f;for(n=0;n<h;n++,s++,o+=2)m[o]=d[s]}d=e.items=null;var p=new Float32Array(f+8);if(1===f){if(0!=(1&a))for(l=0,s=0;l<g;l++,s+=f)m[s]*=.5}else for(l=0,s=0;l<g;l++,s+=f){p.set(m.subarray(s,s+f),4);this.extend(p,4,f);this.filter(p,4,f);m.set(p.subarray(4,4+f),s)}var b=16,y=[];for(i=0;i<b;i++)y.push(new Float32Array(g+8));var v,w=0;e=4+g;if(1===g){if(0!=(1&r))for(c=0;c<f;c++)m[c]*=.5}else for(c=0;c<f;c++){if(0===w){b=Math.min(f-c,b);for(s=c,o=4;o<e;s+=f,o++)for(v=0;v<b;v++)y[v][o]=m[s+v];w=b}var k=y[--w];this.extend(k,4,g);this.filter(k,4,g);if(0===w){s=c-b+1;for(o=4;o<e;s+=f,o++)for(v=0;v<b;v++)m[s+v]=y[v][o]}}return{width:f,height:g,items:m}};return e}(),T=function(){function e(){F.call(this)}e.prototype=Object.create(F.prototype);e.prototype.filter=function(e,t,a){var r,i,n,s,o=a>>1,c=-1.586134342059924,l=-.052980118572961,h=.882911075530934,u=.443506852043971,d=1.230174104914001;r=(t|=0)-3;for(i=o+4;i--;r+=2)e[r]*=.8128930661159609;n=u*e[(r=t-2)-1];for(i=o+3;i--;r+=2){s=u*e[r+1];e[r]=d*e[r]-n-s;if(!i--)break;n=u*e[(r+=2)+1];e[r]=d*e[r]-n-s}n=h*e[(r=t-1)-1];for(i=o+2;i--;r+=2){s=h*e[r+1];e[r]-=n+s;if(!i--)break;n=h*e[(r+=2)+1];e[r]-=n+s}n=l*e[(r=t)-1];for(i=o+1;i--;r+=2){s=l*e[r+1];e[r]-=n+s;if(!i--)break;n=l*e[(r+=2)+1];e[r]-=n+s}if(0!==o){n=c*e[(r=t+1)-1];for(i=o;i--;r+=2){s=c*e[r+1];e[r]-=n+s;if(!i--)break;n=c*e[(r+=2)+1];e[r]-=n+s}}};return e}(),E=function(){function e(){F.call(this)}e.prototype=Object.create(F.prototype);e.prototype.filter=function(e,t,a){var r,i,n=a>>1;for(r=t|=0,i=n+1;i--;r+=2)e[r]-=e[r-1]+e[r+1]+2>>2;for(r=t+1,i=n;i--;r+=2)e[r]+=e[r-1]+e[r+1]>>1};return e}();return t}();t.JpxImage=o},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.calculateSHA512=t.calculateSHA384=t.calculateSHA256=t.calculateMD5=t.PDF20=t.PDF17=t.CipherTransformFactory=t.ARCFourCipher=t.AES256Cipher=t.AES128Cipher=void 0;var r=a(2),i=a(4),n=a(11),s=function(){function e(e){this.a=0;this.b=0;var t,a,r=new Uint8Array(256),i=0,n=e.length;for(t=0;t<256;++t)r[t]=t;for(t=0;t<256;++t){i=i+(a=r[t])+e[t%n]&255;r[t]=r[i];r[i]=a}this.s=r}e.prototype={encryptBlock:function(e){var t,a,r,i=e.length,n=this.a,s=this.b,o=this.s,c=new Uint8Array(i);for(t=0;t<i;++t){r=o[s=s+(a=o[n=n+1&255])&255];o[n]=r;o[s]=a;c[t]=e[t]^o[a+r&255]}this.a=n;this.b=s;return c}};e.prototype.decryptBlock=e.prototype.encryptBlock;return e}();t.ARCFourCipher=s;var o,c,l=(o=new Uint8Array([7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21]),c=new Int32Array([-680876936,-389564586,606105819,-1044525330,-176418897,1200080426,-1473231341,-45705983,1770035416,-1958414417,-42063,-1990404162,1804603682,-40341101,-1502002290,1236535329,-165796510,-1069501632,643717713,-373897302,-701558691,38016083,-660478335,-405537848,568446438,-1019803690,-187363961,1163531501,-1444681467,-51403784,1735328473,-1926607734,-378558,-2022574463,1839030562,-35309556,-1530992060,1272893353,-155497632,-1094730640,681279174,-358537222,-722521979,76029189,-640364487,-421815835,530742520,-995338651,-198630844,1126891415,-1416354905,-57434055,1700485571,-1894986606,-1051523,-2054922799,1873313359,-30611744,-1560198380,1309151649,-145523070,-1120210379,718787259,-343485551]),function(e,t,a){var r,i,n,s=1732584193,l=-271733879,h=-1732584194,u=271733878,d=a+72&-64,f=new Uint8Array(d);for(r=0;r<a;++r)f[r]=e[t++];f[r++]=128;n=d-8;for(;r<n;)f[r++]=0;f[r++]=a<<3&255;f[r++]=a>>5&255;f[r++]=a>>13&255;f[r++]=a>>21&255;f[r++]=a>>>29&255;f[r++]=0;f[r++]=0;f[r++]=0;var g=new Int32Array(16);for(r=0;r<d;){for(i=0;i<16;++i,r+=4)g[i]=f[r]|f[r+1]<<8|f[r+2]<<16|f[r+3]<<24;var m,p,b=s,y=l,v=h,w=u;for(i=0;i<64;++i){if(i<16){m=y&v|~y&w;p=i}else if(i<32){m=w&y|~w&v;p=5*i+1&15}else if(i<48){m=y^v^w;p=3*i+5&15}else{m=v^(y|~w);p=7*i&15}var k=w,S=b+m+c[i]+g[p]|0,C=o[i];w=v;v=y;y=y+(S<<C|S>>>32-C)|0;b=k}s=s+b|0;l=l+y|0;h=h+v|0;u=u+w|0}return new Uint8Array([255&s,s>>8&255,s>>16&255,s>>>24&255,255&l,l>>8&255,l>>16&255,l>>>24&255,255&h,h>>8&255,h>>16&255,h>>>24&255,255&u,u>>8&255,u>>16&255,u>>>24&255])});t.calculateMD5=l;var h=function(){function e(e,t){this.high=0|e;this.low=0|t}e.prototype={and:function(e){this.high&=e.high;this.low&=e.low},xor:function(e){this.high^=e.high;this.low^=e.low},or:function(e){this.high|=e.high;this.low|=e.low},shiftRight:function(e){if(e>=32){this.low=this.high>>>e-32|0;this.high=0}else{this.low=this.low>>>e|this.high<<32-e;this.high=this.high>>>e|0}},shiftLeft:function(e){if(e>=32){this.high=this.low<<e-32;this.low=0}else{this.high=this.high<<e|this.low>>>32-e;this.low=this.low<<e}},rotateRight:function(e){var t,a;if(32&e){a=this.low;t=this.high}else{t=this.low;a=this.high}e&=31;this.low=t>>>e|a<<32-e;this.high=a>>>e|t<<32-e},not:function(){this.high=~this.high;this.low=~this.low},add:function(e){var t=(this.low>>>0)+(e.low>>>0),a=(this.high>>>0)+(e.high>>>0);t>4294967295&&(a+=1);this.low=0|t;this.high=0|a},copyTo:function(e,t){e[t]=this.high>>>24&255;e[t+1]=this.high>>16&255;e[t+2]=this.high>>8&255;e[t+3]=255&this.high;e[t+4]=this.low>>>24&255;e[t+5]=this.low>>16&255;e[t+6]=this.low>>8&255;e[t+7]=255&this.low},assign:function(e){this.high=e.high;this.low=e.low}};return e}(),u=function(){function e(e,t){return e>>>t|e<<32-t}function t(e,t,a){return e&t^~e&a}function a(e,t,a){return e&t^e&a^t&a}function r(t){return e(t,2)^e(t,13)^e(t,22)}function i(t){return e(t,6)^e(t,11)^e(t,25)}function n(t){return e(t,7)^e(t,18)^t>>>3}var s=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];return function(o,c,l){var h,u,d,f=1779033703,g=3144134277,m=1013904242,p=2773480762,b=1359893119,y=2600822924,v=528734635,w=1541459225,k=64*Math.ceil((l+9)/64),S=new Uint8Array(k);for(h=0;h<l;++h)S[h]=o[c++];S[h++]=128;d=k-8;for(;h<d;)S[h++]=0;S[h++]=0;S[h++]=0;S[h++]=0;S[h++]=l>>>29&255;S[h++]=l>>21&255;S[h++]=l>>13&255;S[h++]=l>>5&255;S[h++]=l<<3&255;var C,x=new Uint32Array(64);for(h=0;h<k;){for(u=0;u<16;++u){x[u]=S[h]<<24|S[h+1]<<16|S[h+2]<<8|S[h+3];h+=4}for(u=16;u<64;++u)x[u]=(e(C=x[u-2],17)^e(C,19)^C>>>10)+x[u-7]+n(x[u-15])+x[u-16]|0;var A,I,F=f,T=g,E=m,O=p,P=b,B=y,D=v,N=w;for(u=0;u<64;++u){A=N+i(P)+t(P,B,D)+s[u]+x[u];I=r(F)+a(F,T,E);N=D;D=B;B=P;P=O+A|0;O=E;E=T;T=F;F=A+I|0}f=f+F|0;g=g+T|0;m=m+E|0;p=p+O|0;b=b+P|0;y=y+B|0;v=v+D|0;w=w+N|0}return new Uint8Array([f>>24&255,f>>16&255,f>>8&255,255&f,g>>24&255,g>>16&255,g>>8&255,255&g,m>>24&255,m>>16&255,m>>8&255,255&m,p>>24&255,p>>16&255,p>>8&255,255&p,b>>24&255,b>>16&255,b>>8&255,255&b,y>>24&255,y>>16&255,y>>8&255,255&y,v>>24&255,v>>16&255,v>>8&255,255&v,w>>24&255,w>>16&255,w>>8&255,255&w])}}();t.calculateSHA256=u;var d=function(){function e(e,t,a,r,i){e.assign(t);e.and(a);i.assign(t);i.not();i.and(r);e.xor(i)}function t(e,t,a,r,i){e.assign(t);e.and(a);i.assign(t);i.and(r);e.xor(i);i.assign(a);i.and(r);e.xor(i)}function a(e,t,a){e.assign(t);e.rotateRight(28);a.assign(t);a.rotateRight(34);e.xor(a);a.assign(t);a.rotateRight(39);e.xor(a)}function r(e,t,a){e.assign(t);e.rotateRight(14);a.assign(t);a.rotateRight(18);e.xor(a);a.assign(t);a.rotateRight(41);e.xor(a)}function i(e,t,a){e.assign(t);e.rotateRight(1);a.assign(t);a.rotateRight(8);e.xor(a);a.assign(t);a.shiftRight(7);e.xor(a)}function n(e,t,a){e.assign(t);e.rotateRight(19);a.assign(t);a.rotateRight(61);e.xor(a);a.assign(t);a.shiftRight(6);e.xor(a)}var s=[new h(1116352408,3609767458),new h(1899447441,602891725),new h(3049323471,3964484399),new h(3921009573,2173295548),new h(961987163,4081628472),new h(1508970993,3053834265),new h(2453635748,2937671579),new h(2870763221,3664609560),new h(3624381080,2734883394),new h(310598401,1164996542),new h(607225278,1323610764),new h(1426881987,3590304994),new h(1925078388,4068182383),new h(2162078206,991336113),new h(2614888103,633803317),new h(3248222580,3479774868),new h(3835390401,2666613458),new h(4022224774,944711139),new h(264347078,2341262773),new h(604807628,2007800933),new h(770255983,1495990901),new h(1249150122,1856431235),new h(1555081692,3175218132),new h(1996064986,2198950837),new h(2554220882,3999719339),new h(2821834349,766784016),new h(2952996808,2566594879),new h(3210313671,3203337956),new h(3336571891,1034457026),new h(3584528711,2466948901),new h(113926993,3758326383),new h(338241895,168717936),new h(666307205,1188179964),new h(773529912,1546045734),new h(1294757372,1522805485),new h(1396182291,2643833823),new h(1695183700,2343527390),new h(1986661051,1014477480),new h(2177026350,1206759142),new h(2456956037,344077627),new h(2730485921,1290863460),new h(2820302411,3158454273),new h(3259730800,3505952657),new h(3345764771,106217008),new h(3516065817,3606008344),new h(3600352804,1432725776),new h(4094571909,1467031594),new h(275423344,851169720),new h(430227734,3100823752),new h(506948616,1363258195),new h(659060556,3750685593),new h(883997877,3785050280),new h(958139571,3318307427),new h(1322822218,3812723403),new h(1537002063,2003034995),new h(1747873779,3602036899),new h(1955562222,1575990012),new h(2024104815,1125592928),new h(2227730452,2716904306),new h(2361852424,442776044),new h(2428436474,593698344),new h(2756734187,3733110249),new h(3204031479,2999351573),new h(3329325298,3815920427),new h(3391569614,3928383900),new h(3515267271,566280711),new h(3940187606,3454069534),new h(4118630271,4000239992),new h(116418474,1914138554),new h(174292421,2731055270),new h(289380356,3203993006),new h(460393269,320620315),new h(685471733,587496836),new h(852142971,1086792851),new h(1017036298,365543100),new h(1126000580,2618297676),new h(1288033470,3409855158),new h(1501505948,4234509866),new h(1607167915,987167468),new h(1816402316,1246189591)];return function(o,c,l,u){var d,f,g,m,p,b,y,v;if(u=!!u){d=new h(3418070365,3238371032);f=new h(1654270250,914150663);g=new h(2438529370,812702999);m=new h(355462360,4144912697);p=new h(1731405415,4290775857);b=new h(2394180231,1750603025);y=new h(3675008525,1694076839);v=new h(1203062813,3204075428)}else{d=new h(1779033703,4089235720);f=new h(3144134277,2227873595);g=new h(1013904242,4271175723);m=new h(2773480762,1595750129);p=new h(1359893119,2917565137);b=new h(2600822924,725511199);y=new h(528734635,4215389547);v=new h(1541459225,327033209)}var w,k,S,C=128*Math.ceil((l+17)/128),x=new Uint8Array(C);for(w=0;w<l;++w)x[w]=o[c++];x[w++]=128;S=C-16;for(;w<S;)x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=0;x[w++]=l>>>29&255;x[w++]=l>>21&255;x[w++]=l>>13&255;x[w++]=l>>5&255;x[w++]=l<<3&255;var A=new Array(80);for(w=0;w<80;w++)A[w]=new h(0,0);var I,F,T=new h(0,0),E=new h(0,0),O=new h(0,0),P=new h(0,0),B=new h(0,0),D=new h(0,0),N=new h(0,0),M=new h(0,0),L=new h(0,0),R=new h(0,0),U=new h(0,0),q=new h(0,0);for(w=0;w<C;){for(k=0;k<16;++k){A[k].high=x[w]<<24|x[w+1]<<16|x[w+2]<<8|x[w+3];A[k].low=x[w+4]<<24|x[w+5]<<16|x[w+6]<<8|x[w+7];w+=8}for(k=16;k<80;++k){n(I=A[k],A[k-2],q);I.add(A[k-7]);i(U,A[k-15],q);I.add(U);I.add(A[k-16])}T.assign(d);E.assign(f);O.assign(g);P.assign(m);B.assign(p);D.assign(b);N.assign(y);M.assign(v);for(k=0;k<80;++k){L.assign(M);r(U,B,q);L.add(U);e(U,B,D,N,q);L.add(U);L.add(s[k]);L.add(A[k]);a(R,T,q);t(U,T,E,O,q);R.add(U);I=M;M=N;N=D;D=B;P.add(L);B=P;P=O;O=E;E=T;I.assign(L);I.add(R);T=I}d.add(T);f.add(E);g.add(O);m.add(P);p.add(B);b.add(D);y.add(N);v.add(M)}if(u){F=new Uint8Array(48);d.copyTo(F,0);f.copyTo(F,8);g.copyTo(F,16);m.copyTo(F,24);p.copyTo(F,32);b.copyTo(F,40)}else{F=new Uint8Array(64);d.copyTo(F,0);f.copyTo(F,8);g.copyTo(F,16);m.copyTo(F,24);p.copyTo(F,32);b.copyTo(F,40);y.copyTo(F,48);v.copyTo(F,56)}return F}}();t.calculateSHA512=d;var f=function(e,t,a){return d(e,t,a,!0)};t.calculateSHA384=f;var g=function(){function e(){}e.prototype={decryptBlock:function(e){return e}};return e}();class m{constructor(){this.constructor===m&&(0,r.unreachable)("Cannot initialize AESBaseCipher.");this._s=new Uint8Array([99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22]);this._inv_s=new Uint8Array([82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,124,227,57,130,155,47,255,135,52,142,67,68,196,222,233,203,84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,46,161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,248,246,100,134,104,152,22,212,164,92,204,93,101,182,146,108,112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,216,171,0,140,188,211,10,247,228,88,5,184,179,69,6,208,44,30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,79,103,220,234,151,242,207,206,240,180,230,115,150,172,116,34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,113,29,41,197,137,111,183,98,14,170,24,190,27,252,86,62,75,198,210,121,32,154,219,192,254,120,205,90,244,31,221,168,51,136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181,74,13,45,229,122,159,147,201,156,239,160,224,59,77,174,42,245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,214,38,225,105,20,99,85,33,12,125]);this._mix=new Uint32Array([0,235474187,470948374,303765277,941896748,908933415,607530554,708780849,1883793496,2118214995,1817866830,1649639237,1215061108,1181045119,1417561698,1517767529,3767586992,4003061179,4236429990,4069246893,3635733660,3602770327,3299278474,3400528769,2430122216,2664543715,2362090238,2193862645,2835123396,2801107407,3035535058,3135740889,3678124923,3576870512,3341394285,3374361702,3810496343,3977675356,4279080257,4043610186,2876494627,2776292904,3076639029,3110650942,2472011535,2640243204,2403728665,2169303058,1001089995,899835584,666464733,699432150,59727847,226906860,530400753,294930682,1273168787,1172967064,1475418501,1509430414,1942435775,2110667444,1876241833,1641816226,2910219766,2743034109,2976151520,3211623147,2505202138,2606453969,2302690252,2269728455,3711829422,3543599269,3240894392,3475313331,3843699074,3943906441,4178062228,4144047775,1306967366,1139781709,1374988112,1610459739,1975683434,2076935265,1775276924,1742315127,1034867998,866637845,566021896,800440835,92987698,193195065,429456164,395441711,1984812685,2017778566,1784663195,1683407248,1315562145,1080094634,1383856311,1551037884,101039829,135050206,437757123,337553864,1042385657,807962610,573804783,742039012,2531067453,2564033334,2328828971,2227573024,2935566865,2700099354,3001755655,3168937228,3868552805,3902563182,4203181171,4102977912,3736164937,3501741890,3265478751,3433712980,1106041591,1340463100,1576976609,1408749034,2043211483,2009195472,1708848333,1809054150,832877231,1068351396,766945465,599762354,159417987,126454664,361929877,463180190,2709260871,2943682380,3178106961,3009879386,2572697195,2538681184,2236228733,2336434550,3509871135,3745345300,3441850377,3274667266,3910161971,3877198648,4110568485,4211818798,2597806476,2497604743,2261089178,2295101073,2733856160,2902087851,3202437046,2968011453,3936291284,3835036895,4136440770,4169408201,3535486456,3702665459,3467192302,3231722213,2051518780,1951317047,1716890410,1750902305,1113818384,1282050075,1584504582,1350078989,168810852,67556463,371049330,404016761,841739592,1008918595,775550814,540080725,3969562369,3801332234,4035489047,4269907996,3569255213,3669462566,3366754619,3332740144,2631065433,2463879762,2160117071,2395588676,2767645557,2868897406,3102011747,3069049960,202008497,33778362,270040487,504459436,875451293,975658646,675039627,641025152,2084704233,1917518562,1615861247,1851332852,1147550661,1248802510,1484005843,1451044056,933301370,967311729,733156972,632953703,260388950,25965917,328671808,496906059,1206477858,1239443753,1543208500,1441952575,2144161806,1908694277,1675577880,1842759443,3610369226,3644379585,3408119516,3307916247,4011190502,3776767469,4077384432,4245618683,2809771154,2842737049,3144396420,3043140495,2673705150,2438237621,2203032232,2370213795]);this._mixCol=new Uint8Array(256);for(let e=0;e<256;e++)this._mixCol[e]=e<128?e<<1:e<<1^27;this.buffer=new Uint8Array(16);this.bufferPosition=0}_expandKey(e){(0,r.unreachable)("Cannot call `_expandKey` on the base class")}_decrypt(e,t){let a,r,i;const n=new Uint8Array(16);n.set(e);for(let e=0,a=this._keySize;e<16;++e,++a)n[e]^=t[a];for(let e=this._cyclesOfRepetition-1;e>=1;--e){a=n[13];n[13]=n[9];n[9]=n[5];n[5]=n[1];n[1]=a;a=n[14];r=n[10];n[14]=n[6];n[10]=n[2];n[6]=a;n[2]=r;a=n[15];r=n[11];i=n[7];n[15]=n[3];n[11]=a;n[7]=r;n[3]=i;for(let e=0;e<16;++e)n[e]=this._inv_s[n[e]];for(let a=0,r=16*e;a<16;++a,++r)n[a]^=t[r];for(let e=0;e<16;e+=4){const t=this._mix[n[e]],r=this._mix[n[e+1]],i=this._mix[n[e+2]],s=this._mix[n[e+3]];a=t^r>>>8^r<<24^i>>>16^i<<16^s>>>24^s<<8;n[e]=a>>>24&255;n[e+1]=a>>16&255;n[e+2]=a>>8&255;n[e+3]=255&a}}a=n[13];n[13]=n[9];n[9]=n[5];n[5]=n[1];n[1]=a;a=n[14];r=n[10];n[14]=n[6];n[10]=n[2];n[6]=a;n[2]=r;a=n[15];r=n[11];i=n[7];n[15]=n[3];n[11]=a;n[7]=r;n[3]=i;for(let e=0;e<16;++e){n[e]=this._inv_s[n[e]];n[e]^=t[e]}return n}_encrypt(e,t){const a=this._s;let r,i,n;const s=new Uint8Array(16);s.set(e);for(let e=0;e<16;++e)s[e]^=t[e];for(let e=1;e<this._cyclesOfRepetition;e++){for(let e=0;e<16;++e)s[e]=a[s[e]];n=s[1];s[1]=s[5];s[5]=s[9];s[9]=s[13];s[13]=n;n=s[2];i=s[6];s[2]=s[10];s[6]=s[14];s[10]=n;s[14]=i;n=s[3];i=s[7];r=s[11];s[3]=s[15];s[7]=n;s[11]=i;s[15]=r;for(let e=0;e<16;e+=4){const t=s[e+0],a=s[e+1],i=s[e+2],n=s[e+3];r=t^a^i^n;s[e+0]^=r^this._mixCol[t^a];s[e+1]^=r^this._mixCol[a^i];s[e+2]^=r^this._mixCol[i^n];s[e+3]^=r^this._mixCol[n^t]}for(let a=0,r=16*e;a<16;++a,++r)s[a]^=t[r]}for(let e=0;e<16;++e)s[e]=a[s[e]];n=s[1];s[1]=s[5];s[5]=s[9];s[9]=s[13];s[13]=n;n=s[2];i=s[6];s[2]=s[10];s[6]=s[14];s[10]=n;s[14]=i;n=s[3];i=s[7];r=s[11];s[3]=s[15];s[7]=n;s[11]=i;s[15]=r;for(let e=0,a=this._keySize;e<16;++e,++a)s[e]^=t[a];return s}_decryptBlock2(e,t){const a=e.length;let r=this.buffer,i=this.bufferPosition;const n=[];let s=this.iv;for(let t=0;t<a;++t){r[i]=e[t];++i;if(i<16)continue;const a=this._decrypt(r,this._key);for(let e=0;e<16;++e)a[e]^=s[e];s=r;n.push(a);r=new Uint8Array(16);i=0}this.buffer=r;this.bufferLength=i;this.iv=s;if(0===n.length)return new Uint8Array(0);let o=16*n.length;if(t){const e=n[n.length-1];let t=e[15];if(t<=16){for(let a=15,r=16-t;a>=r;--a)if(e[a]!==t){t=0;break}o-=t;n[n.length-1]=e.subarray(0,16-t)}}const c=new Uint8Array(o);for(let e=0,t=0,a=n.length;e<a;++e,t+=16)c.set(n[e],t);return c}decryptBlock(e,t,a=null){const r=e.length,i=this.buffer;let n=this.bufferPosition;if(a)this.iv=a;else{for(let t=0;n<16&&t<r;++t,++n)i[n]=e[t];if(n<16){this.bufferLength=n;return new Uint8Array(0)}this.iv=i;e=e.subarray(16)}this.buffer=new Uint8Array(16);this.bufferLength=0;this.decryptBlock=this._decryptBlock2;return this.decryptBlock(e,t)}encrypt(e,t){const a=e.length;let r=this.buffer,i=this.bufferPosition;const n=[];t||(t=new Uint8Array(16));for(let s=0;s<a;++s){r[i]=e[s];++i;if(i<16)continue;for(let e=0;e<16;++e)r[e]^=t[e];const a=this._encrypt(r,this._key);t=a;n.push(a);r=new Uint8Array(16);i=0}this.buffer=r;this.bufferLength=i;this.iv=t;if(0===n.length)return new Uint8Array(0);const s=16*n.length,o=new Uint8Array(s);for(let e=0,t=0,a=n.length;e<a;++e,t+=16)o.set(n[e],t);return o}}class p extends m{constructor(e){super();this._cyclesOfRepetition=10;this._keySize=160;this._rcon=new Uint8Array([141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141]);this._key=this._expandKey(e)}_expandKey(e){const t=this._s,a=this._rcon,r=new Uint8Array(176);r.set(e);for(let e=16,i=1;e<176;++i){let n=r[e-3],s=r[e-2],o=r[e-1],c=r[e-4];n=t[n];s=t[s];o=t[o];c=t[c];n^=a[i];for(let t=0;t<4;++t){r[e]=n^=r[e-16];e++;r[e]=s^=r[e-16];e++;r[e]=o^=r[e-16];e++;r[e]=c^=r[e-16];e++}}return r}}t.AES128Cipher=p;class b extends m{constructor(e){super();this._cyclesOfRepetition=14;this._keySize=224;this._key=this._expandKey(e)}_expandKey(e){const t=this._s,a=new Uint8Array(240);a.set(e);let r,i,n,s,o=1;for(let e=32,c=1;e<240;++c){if(e%32==16){r=t[r];i=t[i];n=t[n];s=t[s]}else if(e%32==0){r=a[e-3];i=a[e-2];n=a[e-1];s=a[e-4];r=t[r];i=t[i];n=t[n];s=t[s];r^=o;(o<<=1)>=256&&(o=255&(27^o))}for(let t=0;t<4;++t){a[e]=r^=a[e-32];e++;a[e]=i^=a[e-32];e++;a[e]=n^=a[e-32];e++;a[e]=s^=a[e-32];e++}}return a}}t.AES256Cipher=b;var y=function(){function e(e,t){if(e.length!==t.length)return!1;for(var a=0;a<e.length;a++)if(e[a]!==t[a])return!1;return!0}function t(){}t.prototype={checkOwnerPassword:function(t,a,r,i){var n=new Uint8Array(t.length+56);n.set(t,0);n.set(a,t.length);n.set(r,t.length+a.length);return e(u(n,0,n.length),i)},checkUserPassword:function(t,a,r){var i=new Uint8Array(t.length+8);i.set(t,0);i.set(a,t.length);return e(u(i,0,i.length),r)},getOwnerKey:function(e,t,a,r){var i=new Uint8Array(e.length+56);i.set(e,0);i.set(t,e.length);i.set(a,e.length+t.length);var n=u(i,0,i.length);return new b(n).decryptBlock(r,!1,new Uint8Array(16))},getUserKey:function(e,t,a){var r=new Uint8Array(e.length+8);r.set(e,0);r.set(t,e.length);var i=u(r,0,r.length);return new b(i).decryptBlock(a,!1,new Uint8Array(16))}};return t}();t.PDF17=y;var v=function(){function e(e,t){var a=new Uint8Array(e.length+t.length);a.set(e,0);a.set(t,e.length);return a}function t(t,a,r){for(var i=u(a,0,a.length).subarray(0,32),n=[0],s=0;s<64||n[n.length-1]>s-32;){var o=t.length+i.length+r.length,c=new Uint8Array(64*o),l=e(t,i);l=e(l,r);for(var h=0,g=0;h<64;h++,g+=o)c.set(l,g);n=new p(i.subarray(0,16)).encrypt(c,i.subarray(16,32));for(var m=0,b=0;b<16;b++){m*=1;m%=3;m+=(n[b]>>>0)%3;m%=3}0===m?i=u(n,0,n.length):1===m?i=f(n,0,n.length):2===m&&(i=d(n,0,n.length));s++}return i.subarray(0,32)}function a(){}function r(e,t){if(e.length!==t.length)return!1;for(var a=0;a<e.length;a++)if(e[a]!==t[a])return!1;return!0}a.prototype={hash:function(e,a,r){return t(e,a,r)},checkOwnerPassword:function(e,a,i,n){var s=new Uint8Array(e.length+56);s.set(e,0);s.set(a,e.length);s.set(i,e.length+a.length);return r(t(e,s,i),n)},checkUserPassword:function(e,a,i){var n=new Uint8Array(e.length+8);n.set(e,0);n.set(a,e.length);return r(t(e,n,[]),i)},getOwnerKey:function(e,a,r,i){var n=new Uint8Array(e.length+56);n.set(e,0);n.set(a,e.length);n.set(r,e.length+a.length);var s=t(e,n,r);return new b(s).decryptBlock(i,!1,new Uint8Array(16))},getUserKey:function(e,a,r){var i=new Uint8Array(e.length+8);i.set(e,0);i.set(a,e.length);var n=t(e,i,[]);return new b(n).decryptBlock(r,!1,new Uint8Array(16))}};return a}();t.PDF20=v;var w=function(){function e(e,t){this.StringCipherConstructor=e;this.StreamCipherConstructor=t}e.prototype={createStream:function(e,t){var a=new this.StreamCipherConstructor;return new n.DecryptStream(e,t,(function(e,t){return a.decryptBlock(e,t)}))},decryptString:function(e){var t=new this.StringCipherConstructor,a=(0,r.stringToBytes)(e);a=t.decryptBlock(a,!0);return(0,r.bytesToString)(a)}};return e}(),k=function(){var e=new Uint8Array([40,191,78,94,78,117,138,65,100,0,78,86,255,250,1,8,46,46,0,182,208,104,62,128,47,12,169,254,100,83,105,122]);function t(t,a,r,i,n,o,c,h){var u,d,f=40+r.length+t.length,g=new Uint8Array(f),m=0;if(a){d=Math.min(32,a.length);for(;m<d;++m)g[m]=a[m]}u=0;for(;m<32;)g[m++]=e[u++];for(u=0,d=r.length;u<d;++u)g[m++]=r[u];g[m++]=255&n;g[m++]=n>>8&255;g[m++]=n>>16&255;g[m++]=n>>>24&255;for(u=0,d=t.length;u<d;++u)g[m++]=t[u];if(o>=4&&!h){g[m++]=255;g[m++]=255;g[m++]=255;g[m++]=255}var p=l(g,0,m),b=c>>3;if(o>=3)for(u=0;u<50;++u)p=l(p,0,b);var y,v=p.subarray(0,b);if(o>=3){for(m=0;m<32;++m)g[m]=e[m];for(u=0,d=t.length;u<d;++u)g[m++]=t[u];y=new s(v).encryptBlock(l(g,0,m));d=v.length;var w,k=new Uint8Array(d);for(u=1;u<=19;++u){for(w=0;w<d;++w)k[w]=v[w]^u;y=new s(k).encryptBlock(y)}for(u=0,d=y.length;u<d;++u)if(i[u]!==y[u])return null}else for(u=0,d=(y=new s(v).encryptBlock(e)).length;u<d;++u)if(i[u]!==y[u])return null;return v}var a=i.Name.get("Identity");function n(n,o,c){var h=n.get("Filter");if(!(0,i.isName)(h,"Standard"))throw new r.FormatError("unknown encryption method");this.dict=n;var u=n.get("V");if(!Number.isInteger(u)||1!==u&&2!==u&&4!==u&&5!==u)throw new r.FormatError("unsupported encryption algorithm");this.algorithm=u;var d=n.get("Length");if(!d)if(u<=3)d=40;else{var f=n.get("CF"),g=n.get("StmF");if((0,i.isDict)(f)&&(0,i.isName)(g)){f.suppressEncryption=!0;var m=f.get(g.name);(d=m&&m.get("Length")||128)<40&&(d<<=3)}}if(!Number.isInteger(d)||d<40||d%8!=0)throw new r.FormatError("invalid key length");var p=(0,r.stringToBytes)(n.get("O")).subarray(0,32),b=(0,r.stringToBytes)(n.get("U")).subarray(0,32),w=n.get("P"),k=n.get("R"),S=(4===u||5===u)&&!1!==n.get("EncryptMetadata");this.encryptMetadata=S;var C,x,A=(0,r.stringToBytes)(o);if(c){if(6===k)try{c=(0,r.utf8StringToString)(c)}catch(e){(0,r.warn)("CipherTransformFactory: Unable to convert UTF8 encoded password.")}C=(0,r.stringToBytes)(c)}if(5!==u)x=t(A,C,p,b,w,k,d,S);else{var I=(0,r.stringToBytes)(n.get("O")).subarray(32,40),F=(0,r.stringToBytes)(n.get("O")).subarray(40,48),T=(0,r.stringToBytes)(n.get("U")).subarray(0,48),E=(0,r.stringToBytes)(n.get("U")).subarray(32,40),O=(0,r.stringToBytes)(n.get("U")).subarray(40,48),P=(0,r.stringToBytes)(n.get("OE")),B=(0,r.stringToBytes)(n.get("UE"));(0,r.stringToBytes)(n.get("Perms"));x=function(e,t,a,r,i,n,s,o,c,l,h,u){if(t){var d=Math.min(127,t.length);t=t.subarray(0,d)}else t=[];var f;return(f=6===e?new v:new y).checkUserPassword(t,o,s)?f.getUserKey(t,c,h):t.length&&f.checkOwnerPassword(t,r,n,a)?f.getOwnerKey(t,i,n,l):null}(k,C,p,I,F,T,b,E,O,P,B)}if(!x&&!c)throw new r.PasswordException("No password given",r.PasswordResponses.NEED_PASSWORD);if(!x&&c){x=t(A,function(t,a,r,i){var n,o,c=new Uint8Array(32),h=0;o=Math.min(32,t.length);for(;h<o;++h)c[h]=t[h];n=0;for(;h<32;)c[h++]=e[n++];var u,d=l(c,0,h),f=i>>3;if(r>=3)for(n=0;n<50;++n)d=l(d,0,d.length);if(r>=3){u=a;var g,m=new Uint8Array(f);for(n=19;n>=0;n--){for(g=0;g<f;++g)m[g]=d[g]^n;u=new s(m).encryptBlock(u)}}else u=new s(d.subarray(0,f)).encryptBlock(a);return u}(C,p,k,d),p,b,w,k,d,S)}if(!x)throw new r.PasswordException("Incorrect Password",r.PasswordResponses.INCORRECT_PASSWORD);this.encryptionKey=x;if(u>=4){var D=n.get("CF");(0,i.isDict)(D)&&(D.suppressEncryption=!0);this.cf=D;this.stmf=n.get("StmF")||a;this.strf=n.get("StrF")||a;this.eff=n.get("EFF")||this.stmf}}function o(e,t,a,r){var i,n,s=new Uint8Array(a.length+9);for(i=0,n=a.length;i<n;++i)s[i]=a[i];s[i++]=255&e;s[i++]=e>>8&255;s[i++]=e>>16&255;s[i++]=255&t;s[i++]=t>>8&255;if(r){s[i++]=115;s[i++]=65;s[i++]=108;s[i++]=84}return l(s,0,i).subarray(0,Math.min(a.length+5,16))}function c(e,t,a,n,c){if(!(0,i.isName)(t))throw new r.FormatError("Invalid crypt filter name.");var l,h=e.get(t.name);null!=h&&(l=h.get("CFM"));if(!l||"None"===l.name)return function(){return new g};if("V2"===l.name)return function(){return new s(o(a,n,c,!1))};if("AESV2"===l.name)return function(){return new p(o(a,n,c,!0))};if("AESV3"===l.name)return function(){return new b(c)};throw new r.FormatError("Unknown crypto method")}n.prototype={createCipherTransform:function(e,t){if(4===this.algorithm||5===this.algorithm)return new w(c(this.cf,this.stmf,e,t,this.encryptionKey),c(this.cf,this.strf,e,t,this.encryptionKey));var a=o(e,t,this.encryptionKey,!1),r=function(){return new s(a)};return new w(r,r)}};return n}();t.CipherTransformFactory=k},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.ColorSpace=void 0;var r=a(2),i=a(4);class n{constructor(e,t){this.constructor===n&&(0,r.unreachable)("Cannot initialize ColorSpace.");this.name=e;this.numComps=t}getRgb(e,t){const a=new Uint8ClampedArray(3);this.getRgbItem(e,t,a,0);return a}getRgbItem(e,t,a,i){(0,r.unreachable)("Should not call ColorSpace.getRgbItem")}getRgbBuffer(e,t,a,i,n,s,o){(0,r.unreachable)("Should not call ColorSpace.getRgbBuffer")}getOutputLength(e,t){(0,r.unreachable)("Should not call ColorSpace.getOutputLength")}isPassthrough(e){return!1}isDefaultDecode(e,t){return n.isDefaultDecode(e,this.numComps)}fillRgb(e,t,a,r,i,n,s,o,c){const l=t*a;let h=null;const u=1<<s,d=a!==i||t!==r;if(this.isPassthrough(s))h=o;else if(1===this.numComps&&l>u&&"DeviceGray"!==this.name&&"DeviceRGB"!==this.name){const t=s<=8?new Uint8Array(u):new Uint16Array(u);for(let e=0;e<u;e++)t[e]=e;const a=new Uint8ClampedArray(3*u);this.getRgbBuffer(t,0,u,a,0,s,0);if(d){h=new Uint8Array(3*l);let e=0;for(let t=0;t<l;++t){const r=3*o[t];h[e++]=a[r];h[e++]=a[r+1];h[e++]=a[r+2]}}else{let t=0;for(let r=0;r<l;++r){const i=3*o[r];e[t++]=a[i];e[t++]=a[i+1];e[t++]=a[i+2];t+=c}}}else if(d){h=new Uint8ClampedArray(3*l);this.getRgbBuffer(o,0,l,h,0,s,0)}else this.getRgbBuffer(o,0,r*n,e,0,s,c);if(h)if(d)!function(e,t,a,r,i,n,s){s=1!==s?0:s;const o=a/i,c=r/n;let l,h=0;const u=new Uint16Array(i),d=3*a;for(let e=0;e<i;e++)u[e]=3*Math.floor(e*o);for(let a=0;a<n;a++){const r=Math.floor(a*c)*d;for(let a=0;a<i;a++){l=r+u[a];t[h++]=e[l++];t[h++]=e[l++];t[h++]=e[l++];h+=s}}}(h,e,t,a,r,i,c);else{let t=0,a=0;for(let i=0,s=r*n;i<s;i++){e[t++]=h[a++];e[t++]=h[a++];e[t++]=h[a++];t+=c}}}get usesZeroToOneRange(){return(0,r.shadow)(this,"usesZeroToOneRange",!0)}static parse(e,t,a,r){const i=this.parseToIR(e,t,a,r);return this.fromIR(i)}static fromIR(e){const t=Array.isArray(e)?e[0]:e;let a,i,n;switch(t){case"DeviceGrayCS":return this.singletons.gray;case"DeviceRgbCS":return this.singletons.rgb;case"DeviceCmykCS":return this.singletons.cmyk;case"CalGrayCS":a=e[1];i=e[2];n=e[3];return new d(a,i,n);case"CalRGBCS":a=e[1];i=e[2];n=e[3];const l=e[4];return new f(a,i,n,l);case"PatternCS":let h=e[1];h&&(h=this.fromIR(h));return new o(h);case"IndexedCS":const u=e[1],m=e[2],p=e[3];return new c(this.fromIR(u),m,p);case"AlternateCS":const b=e[1],y=e[2],v=e[3];return new s(b,this.fromIR(y),v);case"LabCS":a=e[1];i=e[2];const w=e[3];return new g(a,i,w);default:throw new r.FormatError(`Unknown colorspace name: ${t}`)}}static parseToIR(e,t,a=null,n){e=t.fetchIfRef(e);if((0,i.isName)(e))switch(e.name){case"DeviceGray":case"G":return"DeviceGrayCS";case"DeviceRGB":case"RGB":return"DeviceRgbCS";case"DeviceCMYK":case"CMYK":return"DeviceCmykCS";case"Pattern":return["PatternCS",null];default:if((0,i.isDict)(a)){const r=a.get("ColorSpace");if((0,i.isDict)(r)){const s=r.get(e.name);if(s){if((0,i.isName)(s))return this.parseToIR(s,t,a,n);e=s;break}}}throw new r.FormatError(`unrecognized colorspace ${e.name}`)}if(Array.isArray(e)){const s=t.fetchIfRef(e[0]).name;let o,c,l,h,u,d;switch(s){case"DeviceGray":case"G":return"DeviceGrayCS";case"DeviceRGB":case"RGB":return"DeviceRgbCS";case"DeviceCMYK":case"CMYK":return"DeviceCmykCS";case"CalGray":c=t.fetchIfRef(e[1]);h=c.getArray("WhitePoint");u=c.getArray("BlackPoint");d=c.get("Gamma");return["CalGrayCS",h,u,d];case"CalRGB":c=t.fetchIfRef(e[1]);h=c.getArray("WhitePoint");u=c.getArray("BlackPoint");d=c.getArray("Gamma");return["CalRGBCS",h,u,d,c.getArray("Matrix")];case"ICCBased":const f=t.fetchIfRef(e[1]).dict;o=f.get("N");l=f.get("Alternate");if(l){const e=this.parseToIR(l,t,a,n);if(this.fromIR(e,n).numComps===o)return e;(0,r.warn)("ICCBased color space: Ignoring incorrect /Alternate entry.")}if(1===o)return"DeviceGrayCS";if(3===o)return"DeviceRgbCS";if(4===o)return"DeviceCmykCS";break;case"Pattern":let g=e[1]||null;g&&(g=this.parseToIR(g,t,a,n));return["PatternCS",g];case"Indexed":case"I":const m=this.parseToIR(e[1],t,a,n),p=t.fetchIfRef(e[2])+1;let b=t.fetchIfRef(e[3]);(0,i.isStream)(b)&&(b=b.getBytes());return["IndexedCS",m,p,b];case"Separation":case"DeviceN":const y=t.fetchIfRef(e[1]);o=Array.isArray(y)?y.length:1;l=this.parseToIR(e[2],t,a,n);return["AlternateCS",o,l,n.create(t.fetchIfRef(e[3]))];case"Lab":c=t.fetchIfRef(e[1]);h=c.getArray("WhitePoint");u=c.getArray("BlackPoint");return["LabCS",h,u,c.getArray("Range")];default:throw new r.FormatError(`unimplemented color space object "${s}"`)}}throw new r.FormatError(`unrecognized color space object: "${e}"`)}static isDefaultDecode(e,t){if(!Array.isArray(e))return!0;if(2*t!==e.length){(0,r.warn)("The decode map is not the correct length");return!0}for(let t=0,a=e.length;t<a;t+=2)if(0!==e[t]||1!==e[t+1])return!1;return!0}static get singletons(){return(0,r.shadow)(this,"singletons",{get gray(){return(0,r.shadow)(this,"gray",new l)},get rgb(){return(0,r.shadow)(this,"rgb",new h)},get cmyk(){return(0,r.shadow)(this,"cmyk",new u)}})}}t.ColorSpace=n;class s extends n{constructor(e,t,a){super("Alternate",e);this.base=t;this.tintFn=a;this.tmpBuf=new Float32Array(t.numComps)}getRgbItem(e,t,a,r){const i=this.tmpBuf;this.tintFn(e,t,i,0);this.base.getRgbItem(i,0,a,r)}getRgbBuffer(e,t,a,r,i,n,s){const o=this.tintFn,c=this.base,l=1/((1<<n)-1),h=c.numComps,u=c.usesZeroToOneRange,d=(c.isPassthrough(8)||!u)&&0===s;let f=d?i:0;const g=d?r:new Uint8ClampedArray(h*a),m=this.numComps,p=new Float32Array(m),b=new Float32Array(h);let y,v;for(y=0;y<a;y++){for(v=0;v<m;v++)p[v]=e[t++]*l;o(p,0,b,0);if(u)for(v=0;v<h;v++)g[f++]=255*b[v];else{c.getRgbItem(b,0,g,f);f+=h}}d||c.getRgbBuffer(g,0,a,r,i,8,s)}getOutputLength(e,t){return this.base.getOutputLength(e*this.base.numComps/this.numComps,t)}}class o extends n{constructor(e){super("Pattern",null);this.base=e}isDefaultDecode(e,t){(0,r.unreachable)("Should not call PatternCS.isDefaultDecode")}}class c extends n{constructor(e,t,a){super("Indexed",1);this.base=e;this.highVal=t;const n=e.numComps*t;if((0,i.isStream)(a)){this.lookup=new Uint8Array(n);const e=a.getBytes(n);this.lookup.set(e)}else if((0,r.isString)(a)){this.lookup=new Uint8Array(n);for(let e=0;e<n;++e)this.lookup[e]=a.charCodeAt(e)}else{if(!(a instanceof Uint8Array))throw new r.FormatError(`Unrecognized lookup table: ${a}`);this.lookup=a}}getRgbItem(e,t,a,r){const i=this.base.numComps,n=e[t]*i;this.base.getRgbBuffer(this.lookup,n,1,a,r,8,0)}getRgbBuffer(e,t,a,r,i,n,s){const o=this.base,c=o.numComps,l=o.getOutputLength(c,s),h=this.lookup;for(let n=0;n<a;++n){const a=e[t++]*c;o.getRgbBuffer(h,a,1,r,i,8,s);i+=l}}getOutputLength(e,t){return this.base.getOutputLength(e*this.base.numComps,t)}isDefaultDecode(e,t){if(!Array.isArray(e))return!0;if(2!==e.length){(0,r.warn)("Decode map length is not correct");return!0}if(!Number.isInteger(t)||t<1){(0,r.warn)("Bits per component is not correct");return!0}return 0===e[0]&&e[1]===(1<<t)-1}}class l extends n{constructor(){super("DeviceGray",1)}getRgbItem(e,t,a,r){const i=255*e[t];a[r]=a[r+1]=a[r+2]=i}getRgbBuffer(e,t,a,r,i,n,s){const o=255/((1<<n)-1);let c=t,l=i;for(let t=0;t<a;++t){const t=o*e[c++];r[l++]=t;r[l++]=t;r[l++]=t;l+=s}}getOutputLength(e,t){return e*(3+t)}}class h extends n{constructor(){super("DeviceRGB",3)}getRgbItem(e,t,a,r){a[r]=255*e[t];a[r+1]=255*e[t+1];a[r+2]=255*e[t+2]}getRgbBuffer(e,t,a,r,i,n,s){if(8===n&&0===s){r.set(e.subarray(t,t+3*a),i);return}const o=255/((1<<n)-1);let c=t,l=i;for(let t=0;t<a;++t){r[l++]=o*e[c++];r[l++]=o*e[c++];r[l++]=o*e[c++];l+=s}}getOutputLength(e,t){return e*(3+t)/3|0}isPassthrough(e){return 8===e}}const u=function(){function e(e,t,a,r,i){const n=e[t]*a,s=e[t+1]*a,o=e[t+2]*a,c=e[t+3]*a;r[i]=255+n*(-4.387332384609988*n+54.48615194189176*s+18.82290502165302*o+212.25662451639585*c-285.2331026137004)+s*(1.7149763477362134*s-5.6096736904047315*o+-17.873870861415444*c-5.497006427196366)+o*(-2.5217340131683033*o-21.248923337353073*c+17.5119270841813)+c*(-21.86122147463605*c-189.48180835922747);r[i+1]=255+n*(8.841041422036149*n+60.118027045597366*s+6.871425592049007*o+31.159100130055922*c-79.2970844816548)+s*(-15.310361306967817*s+17.575251261109482*o+131.35250912493976*c-190.9453302588951)+o*(4.444339102852739*o+9.8632861493405*c-24.86741582555878)+c*(-20.737325471181034*c-187.80453709719578);r[i+2]=255+n*(.8842522430003296*n+8.078677503112928*s+30.89978309703729*o-.23883238689178934*c-14.183576799673286)+s*(10.49593273432072*s+63.02378494754052*o+50.606957656360734*c-112.23884253719248)+o*(.03296041114873217*o+115.60384449646641*c-193.58209356861505)+c*(-22.33816807309886*c-180.12613974708367)}return class extends n{constructor(){super("DeviceCMYK",4)}getRgbItem(t,a,r,i){e(t,a,1,r,i)}getRgbBuffer(t,a,r,i,n,s,o){const c=1/((1<<s)-1);for(let s=0;s<r;s++){e(t,a,c,i,n);a+=4;n+=3+o}}getOutputLength(e,t){return e/4*(3+t)|0}}}(),d=function(){function e(e,t,a,r,i,n){const s=(t[a]*n)**e.G,o=e.YW*s,c=Math.max(295.8*o**.3333333333333333-40.8,0);r[i]=c;r[i+1]=c;r[i+2]=c}return class extends n{constructor(e,t,a){super("CalGray",1);if(!e)throw new r.FormatError("WhitePoint missing - required for color space CalGray");t=t||[0,0,0];a=a||1;this.XW=e[0];this.YW=e[1];this.ZW=e[2];this.XB=t[0];this.YB=t[1];this.ZB=t[2];this.G=a;if(this.XW<0||this.ZW<0||1!==this.YW)throw new r.FormatError(`Invalid WhitePoint components for ${this.name}`+", no fallback available");if(this.XB<0||this.YB<0||this.ZB<0){(0,r.info)(`Invalid BlackPoint for ${this.name}, falling back to default.`);this.XB=this.YB=this.ZB=0}0===this.XB&&0===this.YB&&0===this.ZB||(0,r.warn)(`${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, `+`ZB: ${this.ZB}, only default values are supported.`);if(this.G<1){(0,r.info)(`Invalid Gamma: ${this.G} for ${this.name}, `+"falling back to default.");this.G=1}}getRgbItem(t,a,r,i){e(this,t,a,r,i,1)}getRgbBuffer(t,a,r,i,n,s,o){const c=1/((1<<s)-1);for(let s=0;s<r;++s){e(this,t,a,i,n,c);a+=1;n+=3+o}}getOutputLength(e,t){return e*(3+t)}}}(),f=function(){const e=new Float32Array([.8951,.2664,-.1614,-.7502,1.7135,.0367,.0389,-.0685,1.0296]),t=new Float32Array([.9869929,-.1470543,.1599627,.4323053,.5183603,.0492912,-.0085287,.0400428,.9684867]),a=new Float32Array([3.2404542,-1.5371385,-.4985314,-.969266,1.8760108,.041556,.0556434,-.2040259,1.0572252]),i=new Float32Array([1,1,1]),s=new Float32Array(3),o=new Float32Array(3),c=new Float32Array(3);function l(e,t,a){a[0]=e[0]*t[0]+e[1]*t[1]+e[2]*t[2];a[1]=e[3]*t[0]+e[4]*t[1]+e[5]*t[2];a[2]=e[6]*t[0]+e[7]*t[1]+e[8]*t[2]}function h(e){return u(0,1,e<=.0031308?12.92*e:1.055*e**(1/2.4)-.055)}function u(e,t,a){return Math.max(e,Math.min(t,a))}function d(e){return e<0?-d(-e):e>8?((e+16)/116)**3:e*((24/116)**3/8)}function f(r,n,f,g,m,p){const b=u(0,1,n[f]*p),y=u(0,1,n[f+1]*p),v=u(0,1,n[f+2]*p),w=b**r.GR,k=y**r.GG,S=v**r.GB,C=r.MXA*w+r.MXB*k+r.MXC*S,x=r.MYA*w+r.MYB*k+r.MYC*S,A=r.MZA*w+r.MZB*k+r.MZC*S,I=o;I[0]=C;I[1]=x;I[2]=A;const F=c;!function(a,r,i){if(1===a[0]&&1===a[2]){i[0]=r[0];i[1]=r[1];i[2]=r[2];return}const n=i;l(e,r,n);const o=s;!function(e,t,a){a[0]=1*t[0]/e[0];a[1]=1*t[1]/e[1];a[2]=1*t[2]/e[2]}(a,n,o);l(t,o,i)}(r.whitePoint,I,F);const T=o;!function(e,t,a){if(0===e[0]&&0===e[1]&&0===e[2]){a[0]=t[0];a[1]=t[1];a[2]=t[2];return}const r=d(0),i=(1-r)/(1-d(e[0])),n=1-i,s=(1-r)/(1-d(e[1])),o=1-s,c=(1-r)/(1-d(e[2])),l=1-c;a[0]=t[0]*i+n;a[1]=t[1]*s+o;a[2]=t[2]*c+l}(r.blackPoint,F,T);const E=c;!function(a,r,i){const n=i;l(e,r,n);const o=s;!function(e,t,a){a[0]=.95047*t[0]/e[0];a[1]=1*t[1]/e[1];a[2]=1.08883*t[2]/e[2]}(a,n,o);l(t,o,i)}(i,T,E);const O=o;l(a,E,O);g[m]=255*h(O[0]);g[m+1]=255*h(O[1]);g[m+2]=255*h(O[2])}return class extends n{constructor(e,t,a,i){super("CalRGB",3);if(!e)throw new r.FormatError("WhitePoint missing - required for color space CalRGB");t=t||new Float32Array(3);a=a||new Float32Array([1,1,1]);i=i||new Float32Array([1,0,0,0,1,0,0,0,1]);const n=e[0],s=e[1],o=e[2];this.whitePoint=e;const c=t[0],l=t[1],h=t[2];this.blackPoint=t;this.GR=a[0];this.GG=a[1];this.GB=a[2];this.MXA=i[0];this.MYA=i[1];this.MZA=i[2];this.MXB=i[3];this.MYB=i[4];this.MZB=i[5];this.MXC=i[6];this.MYC=i[7];this.MZC=i[8];if(n<0||o<0||1!==s)throw new r.FormatError(`Invalid WhitePoint components for ${this.name}`+", no fallback available");if(c<0||l<0||h<0){(0,r.info)(`Invalid BlackPoint for ${this.name} [${c}, ${l}, ${h}], `+"falling back to default.");this.blackPoint=new Float32Array(3)}if(this.GR<0||this.GG<0||this.GB<0){(0,r.info)(`Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for `+`${this.name}, falling back to default.`);this.GR=this.GG=this.GB=1}}getRgbItem(e,t,a,r){f(this,e,t,a,r,1)}getRgbBuffer(e,t,a,r,i,n,s){const o=1/((1<<n)-1);for(let n=0;n<a;++n){f(this,e,t,r,i,o);t+=3;i+=3+s}}getOutputLength(e,t){return e*(3+t)/3|0}}}(),g=function(){function e(e){let t;t=e>=6/29?e*e*e:108/841*(e-4/29);return t}function t(e,t,a,r){return a+e*(r-a)/t}function a(a,r,i,n,s,o){let c=r[i],l=r[i+1],h=r[i+2];if(!1!==n){c=t(c,n,0,100);l=t(l,n,a.amin,a.amax);h=t(h,n,a.bmin,a.bmax)}l>a.amax?l=a.amax:l<a.amin&&(l=a.amin);h>a.bmax?h=a.bmax:h<a.bmin&&(h=a.bmin);const u=(c+16)/116,d=u+l/500,f=u-h/200,g=a.XW*e(d),m=a.YW*e(u),p=a.ZW*e(f);let b,y,v;if(a.ZW<1){b=3.1339*g+-1.617*m+-.4906*p;y=-.9785*g+1.916*m+.0333*p;v=.072*g+-.229*m+1.4057*p}else{b=3.2406*g+-1.5372*m+-.4986*p;y=-.9689*g+1.8758*m+.0415*p;v=.0557*g+-.204*m+1.057*p}s[o]=255*Math.sqrt(b);s[o+1]=255*Math.sqrt(y);s[o+2]=255*Math.sqrt(v)}return class extends n{constructor(e,t,a){super("Lab",3);if(!e)throw new r.FormatError("WhitePoint missing - required for color space Lab");t=t||[0,0,0];a=a||[-100,100,-100,100];this.XW=e[0];this.YW=e[1];this.ZW=e[2];this.amin=a[0];this.amax=a[1];this.bmin=a[2];this.bmax=a[3];this.XB=t[0];this.YB=t[1];this.ZB=t[2];if(this.XW<0||this.ZW<0||1!==this.YW)throw new r.FormatError("Invalid WhitePoint components, no fallback available");if(this.XB<0||this.YB<0||this.ZB<0){(0,r.info)("Invalid BlackPoint, falling back to default");this.XB=this.YB=this.ZB=0}if(this.amin>this.amax||this.bmin>this.bmax){(0,r.info)("Invalid Range, falling back to defaults");this.amin=-100;this.amax=100;this.bmin=-100;this.bmax=100}}getRgbItem(e,t,r,i){a(this,e,t,!1,r,i)}getRgbBuffer(e,t,r,i,n,s,o){const c=(1<<s)-1;for(let s=0;s<r;s++){a(this,e,t,c,i,n);t+=3;n+=3+o}}getOutputLength(e,t){return e*(3+t)/3|0}isDefaultDecode(e,t){return!0}get usesZeroToOneRange(){return(0,r.shadow)(this,"usesZeroToOneRange",!1)}}}()},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getQuadPoints=h;t.MarkupAnnotation=t.AnnotationFactory=t.AnnotationBorderStyle=t.Annotation=void 0;var r=a(2),i=a(9),n=a(4),s=a(22),o=a(7),c=a(24),l=a(11);t.AnnotationFactory=class{static create(e,t,a,r){return a.ensure(this,"_create",[e,t,a,r])}static _create(e,t,a,i){const s=e.fetchIfRef(t);if(!(0,n.isDict)(s))return;const c=(0,n.isRef)(t)?t.toString():`annot_${i.createObjId()}`;let l=s.get("Subtype");l=(0,n.isName)(l)?l.name:null;const h={xref:e,dict:s,subtype:l,id:c,pdfManager:a};switch(l){case"Link":return new v(h);case"Text":return new y(h);case"Widget":let e=(0,o.getInheritableProperty)({dict:s,key:"FT"});e=(0,n.isName)(e)?e.name:null;switch(e){case"Tx":return new m(h);case"Btn":return new p(h);case"Ch":return new b(h)}(0,r.warn)('Unimplemented widget field type "'+e+'", falling back to base field type.');return new g(h);case"Popup":return new w(h);case"FreeText":return new k(h);case"Line":return new S(h);case"Square":return new C(h);case"Circle":return new x(h);case"PolyLine":return new A(h);case"Polygon":return new I(h);case"Caret":return new F(h);case"Ink":return new T(h);case"Highlight":return new E(h);case"Underline":return new O(h);case"Squiggly":return new P(h);case"StrikeOut":return new B(h);case"Stamp":return new D(h);case"FileAttachment":return new N(h);default:l?(0,r.warn)('Unimplemented annotation type "'+l+'", falling back to base annotation.'):(0,r.warn)("Annotation is missing the required /Subtype.");return new u(h)}}};function h(e,t){if(!e.has("QuadPoints"))return null;const a=e.getArray("QuadPoints");if(!Array.isArray(a)||a.length%8>0)return null;const r=[];for(let e=0,i=a.length/8;e<i;e++){r.push([]);for(let i=8*e,n=8*e+8;i<n;i+=2){const n=a[i],s=a[i+1];if(n<t[0]||n>t[2]||s<t[1]||s>t[3])return null;r[e].push({x:n,y:s})}}return r}class u{constructor(e){const t=e.dict;this.setContents(t.get("Contents"));this.setModificationDate(t.get("M"));this.setFlags(t.get("F"));this.setRectangle(t.getArray("Rect"));this.setColor(t.getArray("C"));this.setBorderStyle(t);this.setAppearance(t);this.data={annotationFlags:this.flags,borderStyle:this.borderStyle,color:this.color,contents:this.contents,hasAppearance:!!this.appearance,id:e.id,modificationDate:this.modificationDate,rect:this.rectangle,subtype:e.subtype}}_hasFlag(e,t){return!!(e&t)}_isViewable(e){return!this._hasFlag(e,r.AnnotationFlag.INVISIBLE)&&!this._hasFlag(e,r.AnnotationFlag.HIDDEN)&&!this._hasFlag(e,r.AnnotationFlag.NOVIEW)}_isPrintable(e){return this._hasFlag(e,r.AnnotationFlag.PRINT)&&!this._hasFlag(e,r.AnnotationFlag.INVISIBLE)&&!this._hasFlag(e,r.AnnotationFlag.HIDDEN)}get viewable(){return 0===this.flags||this._isViewable(this.flags)}get printable(){return 0!==this.flags&&this._isPrintable(this.flags)}setContents(e){this.contents=(0,r.stringToPDFString)(e||"")}setModificationDate(e){this.modificationDate=(0,r.isString)(e)?e:null}setFlags(e){this.flags=Number.isInteger(e)&&e>0?e:0}hasFlag(e){return this._hasFlag(this.flags,e)}setRectangle(e){Array.isArray(e)&&4===e.length?this.rectangle=r.Util.normalizeRect(e):this.rectangle=[0,0,0,0]}setColor(e){const t=new Uint8ClampedArray(3);if(Array.isArray(e))switch(e.length){case 0:this.color=null;break;case 1:s.ColorSpace.singletons.gray.getRgbItem(e,0,t,0);this.color=t;break;case 3:s.ColorSpace.singletons.rgb.getRgbItem(e,0,t,0);this.color=t;break;case 4:s.ColorSpace.singletons.cmyk.getRgbItem(e,0,t,0);this.color=t;break;default:this.color=t}else this.color=t}setBorderStyle(e){this.borderStyle=new d;if((0,n.isDict)(e))if(e.has("BS")){const t=e.get("BS"),a=t.get("Type");if(!a||(0,n.isName)(a,"Border")){this.borderStyle.setWidth(t.get("W"),this.rectangle);this.borderStyle.setStyle(t.get("S"));this.borderStyle.setDashArray(t.getArray("D"))}}else if(e.has("Border")){const t=e.getArray("Border");if(Array.isArray(t)&&t.length>=3){this.borderStyle.setHorizontalCornerRadius(t[0]);this.borderStyle.setVerticalCornerRadius(t[1]);this.borderStyle.setWidth(t[2],this.rectangle);4===t.length&&this.borderStyle.setDashArray(t[3])}}else this.borderStyle.setWidth(0)}setAppearance(e){this.appearance=null;const t=e.get("AP");if(!(0,n.isDict)(t))return;const a=t.get("N");if((0,n.isStream)(a)){this.appearance=a;return}if(!(0,n.isDict)(a))return;const r=e.get("AS");(0,n.isName)(r)&&a.has(r.name)&&(this.appearance=a.get(r.name))}loadResources(e){return this.appearance.dict.getAsync("Resources").then(t=>{if(!t)return;return new i.ObjectLoader(t,e,t.xref).load().then((function(){return t}))})}getOperatorList(e,t,a){if(!this.appearance)return Promise.resolve(new c.OperatorList);const i=this.data,n=this.appearance.dict,s=this.loadResources(["ExtGState","ColorSpace","Pattern","Shading","XObject","Font"]),o=n.getArray("BBox")||[0,0,1,1],l=n.getArray("Matrix")||[1,0,0,1,0,0],h=function(e,t,a){const[i,n,s,o]=r.Util.getAxialAlignedBoundingBox(t,a);if(i===s||n===o)return[1,0,0,1,e[0],e[1]];const c=(e[2]-e[0])/(s-i),l=(e[3]-e[1])/(o-n);return[c,0,0,l,e[0]-i*c,e[1]-n*l]}(i.rect,o,l);return s.then(a=>{const n=new c.OperatorList;n.addOp(r.OPS.beginAnnotation,[i.rect,h,l]);return e.getOperatorList({stream:this.appearance,task:t,resources:a,operatorList:n}).then(()=>{n.addOp(r.OPS.endAnnotation,[]);this.appearance.reset();return n})})}}t.Annotation=u;class d{constructor(){this.width=1;this.style=r.AnnotationBorderStyleType.SOLID;this.dashArray=[3];this.horizontalCornerRadius=0;this.verticalCornerRadius=0}setWidth(e,t=[0,0,0,0]){if((0,n.isName)(e))this.width=0;else if(Number.isInteger(e)){if(e>0){const a=(t[2]-t[0])/2,i=(t[3]-t[1])/2;if(a>0&&i>0&&(e>a||e>i)){(0,r.warn)(`AnnotationBorderStyle.setWidth - ignoring width: ${e}`);e=1}}this.width=e}}setStyle(e){if((0,n.isName)(e))switch(e.name){case"S":this.style=r.AnnotationBorderStyleType.SOLID;break;case"D":this.style=r.AnnotationBorderStyleType.DASHED;break;case"B":this.style=r.AnnotationBorderStyleType.BEVELED;break;case"I":this.style=r.AnnotationBorderStyleType.INSET;break;case"U":this.style=r.AnnotationBorderStyleType.UNDERLINE}}setDashArray(e){if(Array.isArray(e)&&e.length>0){let t=!0,a=!0;for(const r of e){if(!(+r>=0)){t=!1;break}r>0&&(a=!1)}t&&!a?this.dashArray=e:this.width=0}else e&&(this.width=0)}setHorizontalCornerRadius(e){Number.isInteger(e)&&(this.horizontalCornerRadius=e)}setVerticalCornerRadius(e){Number.isInteger(e)&&(this.verticalCornerRadius=e)}}t.AnnotationBorderStyle=d;class f extends u{constructor(e){super(e);const t=e.dict;if(t.has("IRT")){const e=t.getRaw("IRT");this.data.inReplyTo=(0,n.isRef)(e)?e.toString():null;const a=t.get("RT");this.data.replyType=(0,n.isName)(a)?a.name:r.AnnotationReplyType.REPLY}if(this.data.replyType===r.AnnotationReplyType.GROUP){const e=t.get("IRT");this.data.title=(0,r.stringToPDFString)(e.get("T")||"");this.setContents(e.get("Contents"));this.data.contents=this.contents;if(e.has("CreationDate")){this.setCreationDate(e.get("CreationDate"));this.data.creationDate=this.creationDate}else this.data.creationDate=null;if(e.has("M")){this.setModificationDate(e.get("M"));this.data.modificationDate=this.modificationDate}else this.data.modificationDate=null;this.data.hasPopup=e.has("Popup");if(e.has("C")){this.setColor(e.getArray("C"));this.data.color=this.color}else this.data.color=null}else{this.data.title=(0,r.stringToPDFString)(t.get("T")||"");this.setCreationDate(t.get("CreationDate"));this.data.creationDate=this.creationDate;this.data.hasPopup=t.has("Popup");t.has("C")||(this.data.color=null)}}setCreationDate(e){this.creationDate=(0,r.isString)(e)?e:null}}t.MarkupAnnotation=f;class g extends u{constructor(e){super(e);const t=e.dict,a=this.data;a.annotationType=r.AnnotationType.WIDGET;a.fieldName=this._constructFieldName(t);a.fieldValue=(0,o.getInheritableProperty)({dict:t,key:"V",getArray:!0});a.alternativeText=(0,r.stringToPDFString)(t.get("TU")||"");a.defaultAppearance=(0,o.getInheritableProperty)({dict:t,key:"DA"})||"";const i=(0,o.getInheritableProperty)({dict:t,key:"FT"});a.fieldType=(0,n.isName)(i)?i.name:null;this.fieldResources=(0,o.getInheritableProperty)({dict:t,key:"DR"})||n.Dict.empty;a.fieldFlags=(0,o.getInheritableProperty)({dict:t,key:"Ff"});(!Number.isInteger(a.fieldFlags)||a.fieldFlags<0)&&(a.fieldFlags=0);a.readOnly=this.hasFieldFlag(r.AnnotationFieldFlag.READONLY);if("Sig"===a.fieldType){a.fieldValue=null;this.setFlags(r.AnnotationFlag.HIDDEN)}}_constructFieldName(e){if(!e.has("T")&&!e.has("Parent")){(0,r.warn)("Unknown field name, falling back to empty field name.");return""}if(!e.has("Parent"))return(0,r.stringToPDFString)(e.get("T"));const t=[];e.has("T")&&t.unshift((0,r.stringToPDFString)(e.get("T")));let a=e;for(;a.has("Parent");){a=a.get("Parent");if(!(0,n.isDict)(a))break;a.has("T")&&t.unshift((0,r.stringToPDFString)(a.get("T")))}return t.join(".")}hasFieldFlag(e){return!!(this.data.fieldFlags&e)}getOperatorList(e,t,a){return a?Promise.resolve(new c.OperatorList):super.getOperatorList(e,t,a)}}class m extends g{constructor(e){super(e);const t=e.dict;this.data.fieldValue=(0,r.stringToPDFString)(this.data.fieldValue||"");let a=(0,o.getInheritableProperty)({dict:t,key:"Q"});(!Number.isInteger(a)||a<0||a>2)&&(a=null);this.data.textAlignment=a;let i=(0,o.getInheritableProperty)({dict:t,key:"MaxLen"});(!Number.isInteger(i)||i<0)&&(i=null);this.data.maxLen=i;this.data.multiLine=this.hasFieldFlag(r.AnnotationFieldFlag.MULTILINE);this.data.comb=this.hasFieldFlag(r.AnnotationFieldFlag.COMB)&&!this.hasFieldFlag(r.AnnotationFieldFlag.MULTILINE)&&!this.hasFieldFlag(r.AnnotationFieldFlag.PASSWORD)&&!this.hasFieldFlag(r.AnnotationFieldFlag.FILESELECT)&&null!==this.data.maxLen}getOperatorList(e,t,a){if(a||this.appearance)return super.getOperatorList(e,t,a);const i=new c.OperatorList;if(!this.data.defaultAppearance)return Promise.resolve(i);const n=new l.Stream((0,r.stringToBytes)(this.data.defaultAppearance));return e.getOperatorList({stream:n,task:t,resources:this.fieldResources,operatorList:i}).then((function(){return i}))}}class p extends g{constructor(e){super(e);this.data.checkBox=!this.hasFieldFlag(r.AnnotationFieldFlag.RADIO)&&!this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON);this.data.radioButton=this.hasFieldFlag(r.AnnotationFieldFlag.RADIO)&&!this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON);this.data.pushButton=this.hasFieldFlag(r.AnnotationFieldFlag.PUSHBUTTON);this.data.checkBox?this._processCheckBox(e):this.data.radioButton?this._processRadioButton(e):this.data.pushButton?this._processPushButton(e):(0,r.warn)("Invalid field flags for button widget annotation")}_processCheckBox(e){(0,n.isName)(this.data.fieldValue)&&(this.data.fieldValue=this.data.fieldValue.name);const t=e.dict.get("AP");if(!(0,n.isDict)(t))return;const a=t.get("D");if(!(0,n.isDict)(a))return;const r=a.getKeys();2===r.length&&(this.data.exportValue="Off"===r[0]?r[1]:r[0])}_processRadioButton(e){this.data.fieldValue=this.data.buttonValue=null;const t=e.dict.get("Parent");if((0,n.isDict)(t)&&t.has("V")){const e=t.get("V");(0,n.isName)(e)&&(this.data.fieldValue=e.name)}const a=e.dict.get("AP");if(!(0,n.isDict)(a))return;const r=a.get("N");if((0,n.isDict)(r))for(const e of r.getKeys())if("Off"!==e){this.data.buttonValue=e;break}}_processPushButton(e){e.dict.has("A")?i.Catalog.parseDestDictionary({destDict:e.dict,resultObj:this.data,docBaseUrl:e.pdfManager.docBaseUrl}):(0,r.warn)("Push buttons without action dictionaries are not supported")}}class b extends g{constructor(e){super(e);this.data.options=[];const t=(0,o.getInheritableProperty)({dict:e.dict,key:"Opt"});if(Array.isArray(t)){const a=e.xref;for(let e=0,i=t.length;e<i;e++){const i=a.fetchIfRef(t[e]),n=Array.isArray(i);this.data.options[e]={exportValue:n?a.fetchIfRef(i[0]):i,displayValue:(0,r.stringToPDFString)(n?a.fetchIfRef(i[1]):i)}}}Array.isArray(this.data.fieldValue)||(this.data.fieldValue=[this.data.fieldValue]);this.data.combo=this.hasFieldFlag(r.AnnotationFieldFlag.COMBO);this.data.multiSelect=this.hasFieldFlag(r.AnnotationFieldFlag.MULTISELECT)}}class y extends f{constructor(e){super(e);const t=e.dict;this.data.annotationType=r.AnnotationType.TEXT;if(this.data.hasAppearance)this.data.name="NoIcon";else{this.data.rect[1]=this.data.rect[3]-22;this.data.rect[2]=this.data.rect[0]+22;this.data.name=t.has("Name")?t.get("Name").name:"Note"}if(t.has("State")){this.data.state=t.get("State")||null;this.data.stateModel=t.get("StateModel")||null}else{this.data.state=null;this.data.stateModel=null}}}class v extends u{constructor(e){super(e);this.data.annotationType=r.AnnotationType.LINK;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t);i.Catalog.parseDestDictionary({destDict:e.dict,resultObj:this.data,docBaseUrl:e.pdfManager.docBaseUrl})}}class w extends u{constructor(e){super(e);this.data.annotationType=r.AnnotationType.POPUP;let t=e.dict.get("Parent");if(!t){(0,r.warn)("Popup annotation has a missing or invalid parent annotation.");return}const a=t.get("Subtype");this.data.parentType=(0,n.isName)(a)?a.name:null;const i=e.dict.getRaw("Parent");this.data.parentId=(0,n.isRef)(i)?i.toString():null;const s=t.get("RT");(0,n.isName)(s,r.AnnotationReplyType.GROUP)&&(t=t.get("IRT"));if(t.has("M")){this.setModificationDate(t.get("M"));this.data.modificationDate=this.modificationDate}else this.data.modificationDate=null;if(t.has("C")){this.setColor(t.getArray("C"));this.data.color=this.color}else this.data.color=null;if(!this.viewable){const e=t.get("F");this._isViewable(e)&&this.setFlags(e)}this.data.title=(0,r.stringToPDFString)(t.get("T")||"");this.data.contents=(0,r.stringToPDFString)(t.get("Contents")||"")}}class k extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.FREETEXT}}class S extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.LINE;this.data.lineCoordinates=r.Util.normalizeRect(e.dict.getArray("L"))}}class C extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.SQUARE}}class x extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.CIRCLE}}class A extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.POLYLINE;const t=e.dict.getArray("Vertices");this.data.vertices=[];for(let e=0,a=t.length;e<a;e+=2)this.data.vertices.push({x:t[e],y:t[e+1]})}}class I extends A{constructor(e){super(e);this.data.annotationType=r.AnnotationType.POLYGON}}class F extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.CARET}}class T extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.INK;const t=e.xref,a=e.dict.getArray("InkList");this.data.inkLists=[];for(let e=0,r=a.length;e<r;++e){this.data.inkLists.push([]);for(let r=0,i=a[e].length;r<i;r+=2)this.data.inkLists[e].push({x:t.fetchIfRef(a[e][r]),y:t.fetchIfRef(a[e][r+1])})}}}class E extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.HIGHLIGHT;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t)}}class O extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.UNDERLINE;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t)}}class P extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.SQUIGGLY;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t)}}class B extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.STRIKEOUT;const t=h(e.dict,this.rectangle);t&&(this.data.quadPoints=t)}}class D extends f{constructor(e){super(e);this.data.annotationType=r.AnnotationType.STAMP}}class N extends f{constructor(e){super(e);const t=new i.FileSpec(e.dict.get("FS"),e.xref);this.data.annotationType=r.AnnotationType.FILEATTACHMENT;this.data.file=t.serializable}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.OperatorList=void 0;var r=a(2),i=function(){function e(e,t,a,r,i){for(var n=e,s=0,o=t.length-1;s<o;s++){var c=t[s];n=n[c]||(n[c]=[])}n[t[t.length-1]]={checkFn:a,iterateFn:r,processFn:i}}var t=[];e(t,[r.OPS.save,r.OPS.transform,r.OPS.paintInlineImageXObject,r.OPS.restore],null,(function(e,t){var a=e.fnArray,i=(t-(e.iCurr-3))%4;switch(i){case 0:return a[t]===r.OPS.save;case 1:return a[t]===r.OPS.transform;case 2:return a[t]===r.OPS.paintInlineImageXObject;case 3:return a[t]===r.OPS.restore}throw new Error(`iterateInlineImageGroup - invalid pos: ${i}`)}),(function(e,t){var a=e.fnArray,i=e.argsArray,n=e.iCurr,s=n-3,o=n-2,c=n-1,l=Math.min(Math.floor((t-s)/4),200);if(l<10)return t-(t-s)%4;var h,u=0,d=[],f=0,g=1,m=1;for(h=0;h<l;h++){var p=i[o+(h<<2)],b=i[c+(h<<2)][0];if(g+b.width>1e3){u=Math.max(u,g);m+=f+2;g=0;f=0}d.push({transform:p,x:g,y:m,w:b.width,h:b.height});g+=b.width+2;f=Math.max(f,b.height)}var y=Math.max(u,g)+1,v=m+f+1,w=new Uint8ClampedArray(y*v*4),k=y<<2;for(h=0;h<l;h++){var S=i[c+(h<<2)][0].data,C=d[h].w<<2,x=0,A=d[h].x+d[h].y*y<<2;w.set(S.subarray(0,C),A-k);for(var I=0,F=d[h].h;I<F;I++){w.set(S.subarray(x,x+C),A);x+=C;A+=k}w.set(S.subarray(x-C,x),A);for(;A>=0;){S[A-4]=S[A];S[A-3]=S[A+1];S[A-2]=S[A+2];S[A-1]=S[A+3];S[A+C]=S[A+C-4];S[A+C+1]=S[A+C-3];S[A+C+2]=S[A+C-2];S[A+C+3]=S[A+C-1];A-=k}}a.splice(s,4*l,r.OPS.paintInlineImageXObjectGroup);i.splice(s,4*l,[{width:y,height:v,kind:r.ImageKind.RGBA_32BPP,data:w},d]);return s+1}));e(t,[r.OPS.save,r.OPS.transform,r.OPS.paintImageMaskXObject,r.OPS.restore],null,(function(e,t){var a=e.fnArray,i=(t-(e.iCurr-3))%4;switch(i){case 0:return a[t]===r.OPS.save;case 1:return a[t]===r.OPS.transform;case 2:return a[t]===r.OPS.paintImageMaskXObject;case 3:return a[t]===r.OPS.restore}throw new Error(`iterateImageMaskGroup - invalid pos: ${i}`)}),(function(e,t){var a,i=e.fnArray,n=e.argsArray,s=e.iCurr,o=s-3,c=s-2,l=s-1,h=Math.floor((t-o)/4);if((h=function(e,t,a,i){for(var n=e+2,s=0;s<t;s++){var o=i[n+4*s],c=1===o.length&&o[0];if(!c||1!==c.width||1!==c.height||c.data.length&&(1!==c.data.length||0!==c.data[0]))break;a[n+4*s]=r.OPS.paintSolidColorImageMask}return t-s}(o,h,i,n))<10)return t-(t-o)%4;var u,d,f=!1,g=n[l][0];if(0===n[c][1]&&0===n[c][2]){f=!0;var m=n[c][0],p=n[c][3];u=c+4;var b=l+4;for(a=1;a<h;a++,u+=4,b+=4){d=n[u];if(n[b][0]!==g||d[0]!==m||0!==d[1]||0!==d[2]||d[3]!==p){a<10?f=!1:h=a;break}}}if(f){h=Math.min(h,1e3);var y=new Float32Array(2*h);u=c;for(a=0;a<h;a++,u+=4){d=n[u];y[a<<1]=d[4];y[1+(a<<1)]=d[5]}i.splice(o,4*h,r.OPS.paintImageMaskXObjectRepeat);n.splice(o,4*h,[g,m,p,y])}else{h=Math.min(h,100);var v=[];for(a=0;a<h;a++){d=n[c+(a<<2)];var w=n[l+(a<<2)][0];v.push({data:w.data,width:w.width,height:w.height,transform:d})}i.splice(o,4*h,r.OPS.paintImageMaskXObjectGroup);n.splice(o,4*h,[v])}return o+1}));e(t,[r.OPS.save,r.OPS.transform,r.OPS.paintImageXObject,r.OPS.restore],(function(e){var t=e.argsArray,a=e.iCurr-2;return 0===t[a][1]&&0===t[a][2]}),(function(e,t){var a=e.fnArray,i=e.argsArray,n=(t-(e.iCurr-3))%4;switch(n){case 0:return a[t]===r.OPS.save;case 1:if(a[t]!==r.OPS.transform)return!1;var s=e.iCurr-2,o=i[s][0],c=i[s][3];return i[t][0]===o&&0===i[t][1]&&0===i[t][2]&&i[t][3]===c;case 2:if(a[t]!==r.OPS.paintImageXObject)return!1;var l=i[e.iCurr-1][0];return i[t][0]===l;case 3:return a[t]===r.OPS.restore}throw new Error(`iterateImageGroup - invalid pos: ${n}`)}),(function(e,t){var a=e.fnArray,i=e.argsArray,n=e.iCurr,s=n-3,o=n-2,c=i[n-1][0],l=i[o][0],h=i[o][3],u=Math.min(Math.floor((t-s)/4),1e3);if(u<3)return t-(t-s)%4;for(var d=new Float32Array(2*u),f=o,g=0;g<u;g++,f+=4){var m=i[f];d[g<<1]=m[4];d[1+(g<<1)]=m[5]}var p=[c,l,h,d];a.splice(s,4*u,r.OPS.paintImageXObjectRepeat);i.splice(s,4*u,p);return s+1}));e(t,[r.OPS.beginText,r.OPS.setFont,r.OPS.setTextMatrix,r.OPS.showText,r.OPS.endText],null,(function(e,t){var a=e.fnArray,i=e.argsArray,n=(t-(e.iCurr-4))%5;switch(n){case 0:return a[t]===r.OPS.beginText;case 1:return a[t]===r.OPS.setFont;case 2:return a[t]===r.OPS.setTextMatrix;case 3:if(a[t]!==r.OPS.showText)return!1;var s=e.iCurr-3,o=i[s][0],c=i[s][1];return i[t][0]===o&&i[t][1]===c;case 4:return a[t]===r.OPS.endText}throw new Error(`iterateShowTextGroup - invalid pos: ${n}`)}),(function(e,t){var a=e.fnArray,r=e.argsArray,i=e.iCurr,n=i-4,s=i-3,o=i-2,c=i-1,l=i,h=r[s][0],u=r[s][1],d=Math.min(Math.floor((t-n)/5),1e3);if(d<3)return t-(t-n)%5;var f=n;if(n>=4&&a[n-4]===a[s]&&a[n-3]===a[o]&&a[n-2]===a[c]&&a[n-1]===a[l]&&r[n-4][0]===h&&r[n-4][1]===u){d++;f-=5}for(var g=f+4,m=1;m<d;m++){a.splice(g,3);r.splice(g,3);g+=2}return g+1}));function a(e){this.queue=e;this.state=null;this.context={iCurr:0,fnArray:e.fnArray,argsArray:e.argsArray};this.match=null;this.lastProcessed=0}a.prototype={_optimize(){const e=this.queue.fnArray;let a=this.lastProcessed,r=e.length,i=this.state,n=this.match;if(!i&&!n&&a+1===r&&!t[e[a]]){this.lastProcessed=r;return}const s=this.context;for(;a<r;){if(n){if((0,n.iterateFn)(s,a)){a++;continue}a=(0,n.processFn)(s,a+1);r=e.length;n=null;i=null;if(a>=r)break}i=(i||t)[e[a]];if(i&&!Array.isArray(i)){s.iCurr=a;a++;if(!i.checkFn||(0,i.checkFn)(s)){n=i;i=null}else i=null}else a++}this.state=i;this.match=n;this.lastProcessed=a},push(e,t){this.queue.fnArray.push(e);this.queue.argsArray.push(t);this._optimize()},flush(){for(;this.match;){const e=this.queue.fnArray.length;this.lastProcessed=(0,this.match.processFn)(this.context,e);this.match=null;this.state=null;this._optimize()}},reset(){this.state=null;this.match=null;this.lastProcessed=0}};return a}(),n=function(){function e(e){this.queue=e}e.prototype={push(e,t){this.queue.fnArray.push(e);this.queue.argsArray.push(t)},flush(){},reset(){}};return e}(),s=function(){function e(e,t,a){this._streamSink=t;this.fnArray=[];this.argsArray=[];this.optimizer=t&&"oplist"!==e?new i(this):new n(this);this.dependencies=Object.create(null);this._totalLength=0;this.pageIndex=a;this.intent=e;this.weight=0;this._resolved=t?null:Promise.resolve()}e.prototype={get length(){return this.argsArray.length},get ready(){return this._resolved||this._streamSink.ready},get totalLength(){return this._totalLength+this.length},addOp(e,t){this.optimizer.push(e,t);this.weight++;this._streamSink&&(this.weight>=1e3||this.weight>=995&&(e===r.OPS.restore||e===r.OPS.endText))&&this.flush()},addDependency(e){if(!(e in this.dependencies)){this.dependencies[e]=!0;this.addOp(r.OPS.dependency,[e])}},addDependencies(e){for(var t in e)this.addDependency(t)},addOpList(e){Object.assign(this.dependencies,e.dependencies);for(var t=0,a=e.length;t<a;t++)this.addOp(e.fnArray[t],e.argsArray[t])},getIR(){return{fnArray:this.fnArray,argsArray:this.argsArray,length:this.length}},get _transfers(){const e=[],{fnArray:t,argsArray:a,length:i}=this;for(let n=0;n<i;n++)switch(t[n]){case r.OPS.paintInlineImageXObject:case r.OPS.paintInlineImageXObjectGroup:case r.OPS.paintImageMaskXObject:const t=a[n][0];t.cached||e.push(t.data.buffer)}return e},flush(e=!1){this.optimizer.flush();const t=this.length;this._totalLength+=t;this._streamSink.enqueue({fnArray:this.fnArray,argsArray:this.argsArray,lastChunk:e,length:t},1,this._transfers);this.dependencies=Object.create(null);this.fnArray.length=0;this.argsArray.length=0;this.weight=0;this.optimizer.reset()}};return e}();t.OperatorList=s},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PartialEvaluator=void 0;var r=a(2),i=a(26),n=a(4),s=a(27),o=a(30),c=a(7),l=a(33),h=a(32),u=a(36),d=a(10),f=a(37),g=a(22),m=a(11),p=a(31),b=a(38),y=a(39),v=a(17),w=a(41),k=a(42),S=a(24),C=a(43),x=function(){const e={forceDataSchema:!1,maxImageSize:-1,disableFontFace:!1,nativeImageDecoderSupport:r.NativeImageDecoding.DECODE,ignoreErrors:!1,isEvalSupported:!0};function t({xref:t,handler:a,pageIndex:i,idFactory:n,fontCache:s,builtInCMapCache:o,options:c=null,pdfFunctionFactory:l}){this.xref=t;this.handler=a;this.pageIndex=i;this.idFactory=n;this.fontCache=s;this.builtInCMapCache=o;this.options=c||e;this.pdfFunctionFactory=l;this.parsingType3Font=!1;this.fetchBuiltInCMap=async e=>{if(this.builtInCMapCache.has(e))return this.builtInCMapCache.get(e);const t=this.handler.sendWithStream("FetchBuiltInCMap",{name:e}).getReader(),a=await new Promise((function(e,a){!function r(){t.read().then((function({value:t,done:a}){if(!a){e(t);r()}}),a)}()}));a.compressionType!==r.CMapCompressionType.NONE&&this.builtInCMapCache.set(e,a);return a}}function a(){this.reset()}a.prototype={check:function(){if(++this.checked<100)return!1;this.checked=0;return this.endTime<=Date.now()},reset:function(){this.endTime=Date.now()+20;this.checked=0}};function d(e,t=!1){if(Array.isArray(e)){for(let t=0,a=e.length;t<a;t++){const a=d(e[t],!0);if(a)return a}(0,r.warn)(`Unsupported blend mode Array: ${e}`);return"source-over"}if(!(0,n.isName)(e))return t?null:"source-over";switch(e.name){case"Normal":case"Compatible":return"source-over";case"Multiply":return"multiply";case"Screen":return"screen";case"Overlay":return"overlay";case"Darken":return"darken";case"Lighten":return"lighten";case"ColorDodge":return"color-dodge";case"ColorBurn":return"color-burn";case"HardLight":return"hard-light";case"SoftLight":return"soft-light";case"Difference":return"difference";case"Exclusion":return"exclusion";case"Hue":return"hue";case"Saturation":return"saturation";case"Color":return"color";case"Luminosity":return"luminosity"}if(t)return null;(0,r.warn)(`Unsupported blend mode: ${e.name}`);return"source-over"}var x=Promise.resolve();t.prototype={clone(t=e){var a=Object.create(this);a.options=t;return a},hasBlendModes:function(e){if(!(e instanceof n.Dict))return!1;var t=Object.create(null);e.objId&&(t[e.objId]=!0);for(var a=[e],i=this.xref;a.length;){var s=a.shift(),o=s.get("ExtGState");if(o instanceof n.Dict){var l=o.getKeys();for(let e=0,a=l.length;e<a;e++){const a=l[e];let s=o.getRaw(a);if(s instanceof n.Ref){if(t[s.toString()])continue;try{s=i.fetch(s)}catch(e){if(e instanceof c.MissingDataException)throw e;if(this.options.ignoreErrors){s instanceof n.Ref&&(t[s.toString()]=!0);this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`hasBlendModes - ignoring ExtGState: "${e}".`);continue}throw e}}if(!(s instanceof n.Dict))continue;s.objId&&(t[s.objId]=!0);const h=s.get("BM");if(h instanceof n.Name){if("Normal"!==h.name)return!0}else if(void 0!==h&&Array.isArray(h))for(let e=0,t=h.length;e<t;e++)if(h[e]instanceof n.Name&&"Normal"!==h[e].name)return!0}}var h=s.get("XObject");if(h instanceof n.Dict){var u=h.getKeys();for(let e=0,s=u.length;e<s;e++){const s=u[e];var d=h.getRaw(s);if(d instanceof n.Ref){if(t[d.toString()])continue;try{d=i.fetch(d)}catch(e){if(e instanceof c.MissingDataException)throw e;if(this.options.ignoreErrors){d instanceof n.Ref&&(t[d.toString()]=!0);this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`hasBlendModes - ignoring XObject: "${e}".`);continue}throw e}}if((0,n.isStream)(d)){if(d.dict.objId){if(t[d.dict.objId])continue;t[d.dict.objId]=!0}var f=d.dict.get("Resources");if(f instanceof n.Dict&&(!f.objId||!t[f.objId])){a.push(f);f.objId&&(t[f.objId]=!0)}}}}}return!1},async buildFormXObject(e,t,a,i,s,o){var c=t.dict,l=c.getArray("Matrix"),h=c.getArray("BBox");h=Array.isArray(h)&&4===h.length?r.Util.normalizeRect(h):null;var u=c.get("Group");if(u){var d={matrix:l,bbox:h,smask:a,isolated:!1,knockout:!1},f=u.get("S"),m=null;if((0,n.isName)(f,"Transparency")){d.isolated=u.get("I")||!1;d.knockout=u.get("K")||!1;u.has("CS")&&(m=await this.parseColorSpace({cs:u.get("CS"),resources:e}))}if(a&&a.backdrop){m=m||g.ColorSpace.singletons.rgb;a.backdrop=m.getRgb(a.backdrop,0)}i.addOp(r.OPS.beginGroup,[d])}i.addOp(r.OPS.paintFormXObjectBegin,[l,h]);return this.getOperatorList({stream:t,task:s,resources:c.get("Resources")||e,operatorList:i,initialState:o}).then((function(){i.addOp(r.OPS.paintFormXObjectEnd,[]);u&&i.addOp(r.OPS.endGroup,[d])}))},async buildPaintImageXObject({resources:e,image:t,isInline:a=!1,operatorList:i,cacheKey:n,imageCache:s,forceDisableNativeImageDecoder:o=!1}){var c=t.dict,l=c.get("Width","W"),h=c.get("Height","H");if(!(l&&(0,r.isNum)(l)&&h&&(0,r.isNum)(h))){(0,r.warn)("Image dimensions are missing, or not numbers.");return}var u,d,f=this.options.maxImageSize;if(-1!==f&&l*h>f){(0,r.warn)("Image exceeded maximum allowed size and was removed.");return}if(c.get("ImageMask","IM")||!1){var g=c.get("Width","W"),p=c.get("Height","H"),b=g+7>>3,y=t.getBytes(b*p,!0),w=c.getArray("Decode","D");(u=C.PDFImage.createMask({imgArray:y,width:g,height:p,imageIsFromDecodeStream:t instanceof m.DecodeStream,inverseDecode:!!w&&w[0]>0})).cached=!!n;d=[u];i.addOp(r.OPS.paintImageMaskXObject,d);n&&(s[n]={fn:r.OPS.paintImageMaskXObject,args:d});return}var S=c.get("SMask","SM")||!1,x=c.get("Mask")||!1;if(a&&!S&&!x&&!(t instanceof v.JpegStream)&&l+h<200){u=new C.PDFImage({xref:this.xref,res:e,image:t,isInline:a,pdfFunctionFactory:this.pdfFunctionFactory}).createImageData(!0);i.addOp(r.OPS.paintInlineImageXObject,[u]);return}const A=o?r.NativeImageDecoding.NONE:this.options.nativeImageDecoderSupport;let I=`img_${this.idFactory.createObjId()}`;if(this.parsingType3Font){(0,r.assert)(A===r.NativeImageDecoding.NONE,"Type3 image resources should be completely decoded in the worker.");I=`${this.idFactory.getDocId()}_type3res_${I}`}if(A!==r.NativeImageDecoding.NONE&&!S&&!x&&t instanceof v.JpegStream&&k.NativeImageDecoder.isSupported(t,this.xref,e,this.pdfFunctionFactory)&&t.maybeValidDimensions)return this.handler.sendWithPromise("obj",[I,this.pageIndex,"JpegStream",t.getIR(this.options.forceDataSchema)]).then((function(){i.addDependency(I);d=[I,l,h];i.addOp(r.OPS.paintJpegXObject,d);n&&(s[n]={fn:r.OPS.paintJpegXObject,args:d})}),o=>{(0,r.warn)("Native JPEG decoding failed -- trying to recover: "+(o&&o.message));return this.buildPaintImageXObject({resources:e,image:t,isInline:a,operatorList:i,cacheKey:n,imageCache:s,forceDisableNativeImageDecoder:!0})});var F=null;A===r.NativeImageDecoding.DECODE&&(t instanceof v.JpegStream||x instanceof v.JpegStream||S instanceof v.JpegStream)&&(F=new k.NativeImageDecoder({xref:this.xref,resources:e,handler:this.handler,forceDataSchema:this.options.forceDataSchema,pdfFunctionFactory:this.pdfFunctionFactory}));i.addDependency(I);d=[I,l,h];const T=C.PDFImage.buildImage({handler:this.handler,xref:this.xref,res:e,image:t,isInline:a,nativeDecoder:F,pdfFunctionFactory:this.pdfFunctionFactory}).then(e=>{var t=e.createImageData(!1);if(this.parsingType3Font)return this.handler.sendWithPromise("commonobj",[I,"FontType3Res",t],[t.data.buffer]);this.handler.send("obj",[I,this.pageIndex,"Image",t],[t.data.buffer])}).catch(e=>{(0,r.warn)("Unable to decode image: "+e);if(this.parsingType3Font)return this.handler.sendWithPromise("commonobj",[I,"FontType3Res",null]);this.handler.send("obj",[I,this.pageIndex,"Image",null])});this.parsingType3Font&&await T;i.addOp(r.OPS.paintImageXObject,d);n&&(s[n]={fn:r.OPS.paintImageXObject,args:d})},handleSMask:function(e,t,a,r,i){var n=e.get("G"),s={subtype:e.get("S").name,backdrop:e.get("BC")},o=e.get("TR");if((0,y.isPDFFunction)(o)){const e=this.pdfFunctionFactory.create(o);for(var c=new Uint8Array(256),l=new Float32Array(1),h=0;h<256;h++){l[0]=h/255;e(l,0,l,0);c[h]=255*l[0]|0}s.transferMap=c}return this.buildFormXObject(t,n,s,a,r,i.state.clone())},handleTilingType(e,t,a,i,s,o,c){const l=new S.OperatorList,h=[s.get("Resources"),a],d=n.Dict.merge(this.xref,h);return this.getOperatorList({stream:i,task:c,resources:d,operatorList:l}).then((function(){return(0,u.getTilingPatternIR)({fnArray:l.fnArray,argsArray:l.argsArray},s,t)})).then((function(t){o.addDependencies(l.dependencies);o.addOp(e,t)}),e=>{if(!(e instanceof r.AbortException)){if(!this.options.ignoreErrors)throw e;this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`handleTilingType - ignoring pattern: "${e}".`)}})},handleSetFont:function(e,t,a,i,n,o){var c;t&&(c=(t=t.slice())[0].name);return this.loadFont(c,a,e).then(t=>t.font.isType3Font?t.loadType3Data(this,e,i,n).then((function(){return t})).catch(e=>{this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});return new A("g_font_error",new s.ErrorFont("Type3 font load error: "+e),t.font)}):t).then(e=>{o.font=e.font;e.send(this.handler);return e.loadedName})},handleText(e,a){const i=a.font,n=i.charsToGlyphs(e);if(i.data){(!!(a.textRenderingMode&r.TextRenderingMode.ADD_TO_PATH_FLAG)||"Pattern"===a.fillColorSpace.name||i.disableFontFace||this.options.disableFontFace)&&t.buildFontPaths(i,n,this.handler)}return n},ensureStateFont(e){if(e.font)return;const t=new r.FormatError("Missing setFont (Tf) operator before text rendering operator.");if(!this.options.ignoreErrors)throw t;this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});(0,r.warn)(`ensureStateFont: "${t}".`)},setGState:function(e,t,a,i,s){for(var o=[],c=t.getKeys(),l=Promise.resolve(),h=0,u=c.length;h<u;h++){const u=c[h],f=t.get(u);switch(u){case"Type":break;case"LW":case"LC":case"LJ":case"ML":case"D":case"RI":case"FL":case"CA":case"ca":o.push([u,f]);break;case"Font":l=l.then(()=>this.handleSetFont(e,null,f[0],a,i,s.state).then((function(e){a.addDependency(e);o.push([u,[e,f[1]]])})));break;case"BM":o.push([u,d(f)]);break;case"SMask":if((0,n.isName)(f,"None")){o.push([u,!1]);break}if((0,n.isDict)(f)){l=l.then(()=>this.handleSMask(f,e,a,i,s));o.push([u,!0])}else(0,r.warn)("Unsupported SMask type");break;case"OP":case"op":case"OPM":case"BG":case"BG2":case"UCR":case"UCR2":case"TR":case"TR2":case"HT":case"SM":case"SA":case"AIS":case"TK":(0,r.info)("graphic state operator "+u);break;default:(0,r.info)("Unknown graphic state operator "+u)}}return l.then((function(){o.length>0&&a.addOp(r.OPS.setGState,[o])}))},loadFont:function(e,a,i){function o(){return Promise.resolve(new A("g_font_error",new s.ErrorFont("Font "+e+" is not available"),a))}var c,l=this.xref;if(a){if(!(0,n.isRef)(a))throw new r.FormatError('The "font" object should be a reference.');c=a}else{var h=i.get("Font");h&&(c=h.getRaw(e))}if(!c){const i=`Font "${e||a&&a.toString()}" is not available`;if(!this.options.ignoreErrors&&!this.parsingType3Font){(0,r.warn)(`${i}.`);return o()}this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});(0,r.warn)(`${i} -- attempting to fallback to a default font.`);c=t.getFallbackFontDict()}if(this.fontCache.has(c))return this.fontCache.get(c);a=l.fetchIfRef(c);if(!(0,n.isDict)(a))return o();if(a.translated)return a.translated;var u=(0,r.createPromiseCapability)(),d=this.preEvaluateFont(a);const{descriptor:f,hash:g}=d;var m,p,b=(0,n.isRef)(c);b&&(m=c.toString());if(g&&(0,n.isDict)(f)){f.fontAliases||(f.fontAliases=Object.create(null));var y=f.fontAliases;if(y[g]){var v=y[g].aliasRef;if(b&&v&&this.fontCache.has(v)){this.fontCache.putAlias(c,v);return this.fontCache.get(c)}}else y[g]={fontID:s.Font.getFontID()};b&&(y[g].aliasRef=c);m=y[g].fontID}if(b)this.fontCache.put(c,u.promise);else{m||(m=this.idFactory.createObjId());this.fontCache.put(`id_${m}`,u.promise)}(0,r.assert)(m,'The "fontID" must be defined.');a.loadedName=`${this.idFactory.getDocId()}_f${m}`;a.translated=u.promise;try{p=this.translateFont(d)}catch(e){p=Promise.reject(e)}p.then((function(e){if(void 0!==e.fontType){l.stats.fontTypes[e.fontType]=!0}u.resolve(new A(a.loadedName,e,a))})).catch(e=>{this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});try{var t=f&&f.get("FontFile3"),i=t&&t.get("Subtype"),n=(0,s.getFontType)(d.type,i&&i.name);l.stats.fontTypes[n]=!0}catch(e){}u.resolve(new A(a.loadedName,new s.ErrorFont(e instanceof Error?e.message:e),a))});return u.promise},buildPath(e,t,a,i=!1){var n=e.length-1;a||(a=[]);if(n<0||e.fnArray[n]!==r.OPS.constructPath){if(i){(0,r.warn)(`Encountered path operator "${t}" inside of a text object.`);e.addOp(r.OPS.save,null)}e.addOp(r.OPS.constructPath,[[t],a]);i&&e.addOp(r.OPS.restore,null)}else{var s=e.argsArray[n];s[0].push(t);Array.prototype.push.apply(s[1],a)}},parseColorSpace({cs:e,resources:t}){return new Promise(a=>{a(g.ColorSpace.parse(e,this.xref,t,this.pdfFunctionFactory))}).catch(e=>{if(e instanceof r.AbortException)return null;if(this.options.ignoreErrors){this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`parseColorSpace - ignoring ColorSpace: "${e}".`);return null}throw e})},async handleColorN(e,t,a,i,s,o,c){var l,h=a[a.length-1];if((0,n.isName)(h)&&(l=s.get(h.name))){var d=(0,n.isStream)(l)?l.dict:l,f=d.get("PatternType");if(1===f){var g=i.base?i.base.getRgb(a,0):null;return this.handleTilingType(t,g,o,l,d,e,c)}if(2===f){var m=d.get("Shading"),p=d.getArray("Matrix");l=u.Pattern.parseShading(m,p,this.xref,o,this.handler,this.pdfFunctionFactory);e.addOp(t,l.getIR());return}throw new r.FormatError(`Unknown PatternType: ${f}`)}throw new r.FormatError(`Unknown PatternName: ${h}`)},getOperatorList({stream:e,task:t,resources:i,operatorList:s,initialState:o=null}){i=i||n.Dict.empty;o=o||new T;if(!s)throw new Error('getOperatorList: missing "operatorList" parameter');var c=this,l=this.xref;let h=!1;var d=Object.create(null),f=i.get("XObject")||n.Dict.empty,m=i.get("Pattern")||n.Dict.empty,p=new I(o),b=new E(e,l,p),y=new a;function v(e){for(var t=0,a=b.savedStatesDepth;t<a;t++)s.addOp(r.OPS.restore,[])}return new Promise((function e(a,o){const w=function(t){Promise.all([t,s.ready]).then((function(){try{e(a,o)}catch(e){o(e)}}),o)};t.ensureNotTerminated();y.reset();for(var k,S,C,A,I={};!(k=y.check());){I.args=null;if(!b.read(I))break;var F=I.args,T=I.fn;switch(0|T){case r.OPS.paintXObject:var E=F[0].name;if(E&&void 0!==d[E]){s.addOp(d[E].fn,d[E].args);F=null;continue}w(new Promise((function(e,a){if(!E)throw new r.FormatError("XObject must be referred to by name.");const o=f.get(E);if(!o){s.addOp(T,F);e();return}if(!(0,n.isStream)(o))throw new r.FormatError("XObject should be a stream");const l=o.dict.get("Subtype");if(!(0,n.isName)(l))throw new r.FormatError("XObject should have a Name subtype");if("Form"!==l.name)if("Image"!==l.name){if("PS"!==l.name)throw new r.FormatError(`Unhandled XObject subtype ${l.name}`);(0,r.info)("Ignored XObject subtype PS");e()}else c.buildPaintImageXObject({resources:i,image:o,operatorList:s,cacheKey:E,imageCache:d}).then(e,a);else{p.save();c.buildFormXObject(i,o,null,s,t,p.state.clone()).then((function(){p.restore();e()}),a)}})).catch((function(e){if(!(e instanceof r.AbortException)){if(!c.options.ignoreErrors)throw e;c.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`getOperatorList - ignoring XObject: "${e}".`)}})));return;case r.OPS.setFont:var O=F[1];w(c.handleSetFont(i,F,null,s,t,p.state).then((function(e){s.addDependency(e);s.addOp(r.OPS.setFont,[e,O])})));return;case r.OPS.beginText:h=!0;break;case r.OPS.endText:h=!1;break;case r.OPS.endInlineImage:var P=F[0].cacheKey;if(P){var B=d[P];if(void 0!==B){s.addOp(B.fn,B.args);F=null;continue}}w(c.buildPaintImageXObject({resources:i,image:F[0],isInline:!0,operatorList:s,cacheKey:P,imageCache:d}));return;case r.OPS.showText:if(!p.state.font){c.ensureStateFont(p.state);continue}F[0]=c.handleText(F[0],p.state);break;case r.OPS.showSpacedText:if(!p.state.font){c.ensureStateFont(p.state);continue}var D=F[0],N=[],M=D.length,L=p.state;for(S=0;S<M;++S){var R=D[S];(0,r.isString)(R)?Array.prototype.push.apply(N,c.handleText(R,L)):(0,r.isNum)(R)&&N.push(R)}F[0]=N;T=r.OPS.showText;break;case r.OPS.nextLineShowText:if(!p.state.font){c.ensureStateFont(p.state);continue}s.addOp(r.OPS.nextLine);F[0]=c.handleText(F[0],p.state);T=r.OPS.showText;break;case r.OPS.nextLineSetSpacingShowText:if(!p.state.font){c.ensureStateFont(p.state);continue}s.addOp(r.OPS.nextLine);s.addOp(r.OPS.setWordSpacing,[F.shift()]);s.addOp(r.OPS.setCharSpacing,[F.shift()]);F[0]=c.handleText(F[0],p.state);T=r.OPS.showText;break;case r.OPS.setTextRenderingMode:p.state.textRenderingMode=F[0];break;case r.OPS.setFillColorSpace:w(c.parseColorSpace({cs:F[0],resources:i}).then((function(e){e&&(p.state.fillColorSpace=e)})));return;case r.OPS.setStrokeColorSpace:w(c.parseColorSpace({cs:F[0],resources:i}).then((function(e){e&&(p.state.strokeColorSpace=e)})));return;case r.OPS.setFillColor:A=p.state.fillColorSpace;F=A.getRgb(F,0);T=r.OPS.setFillRGBColor;break;case r.OPS.setStrokeColor:A=p.state.strokeColorSpace;F=A.getRgb(F,0);T=r.OPS.setStrokeRGBColor;break;case r.OPS.setFillGray:p.state.fillColorSpace=g.ColorSpace.singletons.gray;F=g.ColorSpace.singletons.gray.getRgb(F,0);T=r.OPS.setFillRGBColor;break;case r.OPS.setStrokeGray:p.state.strokeColorSpace=g.ColorSpace.singletons.gray;F=g.ColorSpace.singletons.gray.getRgb(F,0);T=r.OPS.setStrokeRGBColor;break;case r.OPS.setFillCMYKColor:p.state.fillColorSpace=g.ColorSpace.singletons.cmyk;F=g.ColorSpace.singletons.cmyk.getRgb(F,0);T=r.OPS.setFillRGBColor;break;case r.OPS.setStrokeCMYKColor:p.state.strokeColorSpace=g.ColorSpace.singletons.cmyk;F=g.ColorSpace.singletons.cmyk.getRgb(F,0);T=r.OPS.setStrokeRGBColor;break;case r.OPS.setFillRGBColor:p.state.fillColorSpace=g.ColorSpace.singletons.rgb;F=g.ColorSpace.singletons.rgb.getRgb(F,0);break;case r.OPS.setStrokeRGBColor:p.state.strokeColorSpace=g.ColorSpace.singletons.rgb;F=g.ColorSpace.singletons.rgb.getRgb(F,0);break;case r.OPS.setFillColorN:if("Pattern"===(A=p.state.fillColorSpace).name){w(c.handleColorN(s,r.OPS.setFillColorN,F,A,m,i,t));return}F=A.getRgb(F,0);T=r.OPS.setFillRGBColor;break;case r.OPS.setStrokeColorN:if("Pattern"===(A=p.state.strokeColorSpace).name){w(c.handleColorN(s,r.OPS.setStrokeColorN,F,A,m,i,t));return}F=A.getRgb(F,0);T=r.OPS.setStrokeRGBColor;break;case r.OPS.shadingFill:var U=i.get("Shading");if(!U)throw new r.FormatError("No shading resource found");var q=U.get(F[0].name);if(!q)throw new r.FormatError("No shading object found");var j=u.Pattern.parseShading(q,null,l,i,c.handler,c.pdfFunctionFactory).getIR();F=[j];T=r.OPS.shadingFill;break;case r.OPS.setGState:var _=F[0],z=i.get("ExtGState");if(!(0,n.isDict)(z)||!z.has(_.name))break;var H=z.get(_.name);w(c.setGState(i,H,s,t,p));return;case r.OPS.moveTo:case r.OPS.lineTo:case r.OPS.curveTo:case r.OPS.curveTo2:case r.OPS.curveTo3:case r.OPS.closePath:case r.OPS.rectangle:c.buildPath(s,T,F,h);continue;case r.OPS.markPoint:case r.OPS.markPointProps:case r.OPS.beginMarkedContent:case r.OPS.beginMarkedContentProps:case r.OPS.endMarkedContent:case r.OPS.beginCompat:case r.OPS.endCompat:continue;default:if(null!==F){for(S=0,C=F.length;S<C&&!(F[S]instanceof n.Dict);S++);if(S<C){(0,r.warn)("getOperatorList - ignoring operator: "+T);continue}}}s.addOp(T,F)}if(k)w(x);else{v();a()}})).catch(e=>{if(!(e instanceof r.AbortException)){if(!this.options.ignoreErrors)throw e;this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.unknown});(0,r.warn)(`getOperatorList - ignoring errors during "${t.name}" `+`task: "${e}".`);v()}})},getTextContent({stream:e,task:t,resources:i,stateManager:s=null,normalizeWhitespace:o=!1,combineTextItems:c=!1,sink:h,seenStyles:u=Object.create(null)}){i=i||n.Dict.empty;s=s||new I(new F);var d,g=/\s/g,m={items:[],styles:Object.create(null)},p={initialized:!1,str:[],width:0,height:0,vertical:!1,lastAdvanceWidth:0,lastAdvanceHeight:0,textAdvanceScale:0,spaceWidth:0,fakeSpaceMin:1/0,fakeMultiSpaceMin:1/0,fakeMultiSpaceMax:-0,textRunBreakAllowed:!1,transform:null,fontName:null},b=this,y=this.xref,v=null,w=Object.create(null),k=new E(e,y,s);function S(){if(p.initialized)return p;var e=d.font;if(!(e.loadedName in u)){u[e.loadedName]=!0;m.styles[e.loadedName]={fontFamily:e.fallbackName,ascent:e.ascent,descent:e.descent,vertical:!!e.vertical}}p.fontName=e.loadedName;var t=[d.fontSize*d.textHScale,0,0,d.fontSize,0,d.textRise];if(e.isType3Font&&d.fontSize<=1&&!(0,r.isArrayEqual)(d.fontMatrix,r.FONT_IDENTITY_MATRIX)){const a=e.bbox[3]-e.bbox[1];a>0&&(t[3]*=a*d.fontMatrix[3])}var a=r.Util.transform(d.ctm,r.Util.transform(d.textMatrix,t));p.transform=a;if(e.vertical){p.width=Math.sqrt(a[0]*a[0]+a[1]*a[1]);p.height=0;p.vertical=!0}else{p.width=0;p.height=Math.sqrt(a[2]*a[2]+a[3]*a[3]);p.vertical=!1}var i=d.textLineMatrix[0],n=d.textLineMatrix[1],s=Math.sqrt(i*i+n*n);i=d.ctm[0];n=d.ctm[1];var o=Math.sqrt(i*i+n*n);p.textAdvanceScale=o*s;p.lastAdvanceWidth=0;p.lastAdvanceHeight=0;var c=e.spaceWidth/1e3*d.fontSize;if(c){p.spaceWidth=c;p.fakeSpaceMin=.3*c;p.fakeMultiSpaceMin=1.5*c;p.fakeMultiSpaceMax=4*c;p.textRunBreakAllowed=!e.isMonospace}else{p.spaceWidth=0;p.fakeSpaceMin=1/0;p.fakeMultiSpaceMin=1/0;p.fakeMultiSpaceMax=0;p.textRunBreakAllowed=!1}p.initialized=!0;return p}function C(e){for(var t,a=0,r=e.length;a<r&&(t=e.charCodeAt(a))>=32&&t<=127;)a++;return a<r?e.replace(g," "):e}function A(e,t){return b.loadFont(e,t,i).then((function(e){d.font=e.font;d.fontMatrix=e.font.fontMatrix||r.FONT_IDENTITY_MATRIX}))}function T(e){for(var t=d.font,a=S(),r=0,i=0,n=t.charsToGlyphs(e),s=0;s<n.length;s++){var o=n[s],c=null;c=t.vertical&&o.vmetric?o.vmetric[0]:o.width;var h=o.unicode,u=(0,l.getNormalizedUnicodes)();void 0!==u[h]&&(h=u[h]);h=(0,l.reverseIfRtl)(h);var f=d.charSpacing;if(o.isSpace){var g=d.wordSpacing;f+=g;g>0&&O(g,a.str)}var m=0,p=0;if(t.vertical){i+=p=c*d.fontMatrix[0]*d.fontSize+f}else{r+=m=(c*d.fontMatrix[0]*d.fontSize+f)*d.textHScale}d.translateTextMatrix(m,p);a.str.push(h)}if(t.vertical){a.lastAdvanceHeight=i;a.height+=Math.abs(i)}else{a.lastAdvanceWidth=r;a.width+=r}return a}function O(e,t){if(!(e<p.fakeSpaceMin))if(e<p.fakeMultiSpaceMin)t.push(" ");else for(var a=Math.round(e/p.spaceWidth);a-- >0;)t.push(" ")}function P(){if(p.initialized){p.vertical?p.height*=p.textAdvanceScale:p.width*=p.textAdvanceScale;m.items.push((t=(e=p).str.join(""),a=(0,f.bidi)(t,-1,e.vertical),{str:o?C(a.str):a.str,dir:a.dir,width:e.width,height:e.height,transform:e.transform,fontName:e.fontName}));var e,t,a;p.initialized=!1;p.str.length=0}}function B(){const e=m.items.length;if(e>0){h.enqueue(m,e);m.items=[];m.styles=Object.create(null)}}var D=new a;return new Promise((function e(a,l){const f=function(t){B();Promise.all([t,h.ready]).then((function(){try{e(a,l)}catch(e){l(e)}}),l)};t.ensureNotTerminated();D.reset();for(var g,y={},C=[];!(g=D.check());){C.length=0;y.args=C;if(!k.read(y))break;d=s.state;var F,E=y.fn;C=y.args;switch(0|E){case r.OPS.setFont:var N=C[0].name,M=C[1];if(d.font&&N===d.fontName&&M===d.fontSize)break;P();d.fontName=N;d.fontSize=M;f(A(N,null));return;case r.OPS.setTextRise:P();d.textRise=C[0];break;case r.OPS.setHScale:P();d.textHScale=C[0]/100;break;case r.OPS.setLeading:P();d.leading=C[0];break;case r.OPS.moveText:var L=!!d.font&&0===(d.font.vertical?C[0]:C[1]);F=C[0]-C[1];if(c&&L&&p.initialized&&F>0&&F<=p.fakeMultiSpaceMax){d.translateTextLineMatrix(C[0],C[1]);p.width+=C[0]-p.lastAdvanceWidth;p.height+=C[1]-p.lastAdvanceHeight;O(C[0]-p.lastAdvanceWidth-(C[1]-p.lastAdvanceHeight),p.str);break}P();d.translateTextLineMatrix(C[0],C[1]);d.textMatrix=d.textLineMatrix.slice();break;case r.OPS.setLeadingMoveText:P();d.leading=-C[1];d.translateTextLineMatrix(C[0],C[1]);d.textMatrix=d.textLineMatrix.slice();break;case r.OPS.nextLine:P();d.carriageReturn();break;case r.OPS.setTextMatrix:F=d.calcTextLineMatrixAdvance(C[0],C[1],C[2],C[3],C[4],C[5]);if(c&&null!==F&&p.initialized&&F.value>0&&F.value<=p.fakeMultiSpaceMax){d.translateTextLineMatrix(F.width,F.height);p.width+=F.width-p.lastAdvanceWidth;p.height+=F.height-p.lastAdvanceHeight;O(F.width-p.lastAdvanceWidth-(F.height-p.lastAdvanceHeight),p.str);break}P();d.setTextMatrix(C[0],C[1],C[2],C[3],C[4],C[5]);d.setTextLineMatrix(C[0],C[1],C[2],C[3],C[4],C[5]);break;case r.OPS.setCharSpacing:d.charSpacing=C[0];break;case r.OPS.setWordSpacing:d.wordSpacing=C[0];break;case r.OPS.beginText:P();d.textMatrix=r.IDENTITY_MATRIX.slice();d.textLineMatrix=r.IDENTITY_MATRIX.slice();break;case r.OPS.showSpacedText:if(!s.state.font){b.ensureStateFont(s.state);continue}for(var R,U=C[0],q=0,j=U.length;q<j;q++)if("string"==typeof U[q])T(U[q]);else if((0,r.isNum)(U[q])){S();F=U[q]*d.fontSize/1e3;var _=!1;if(d.font.vertical){R=F;d.translateTextMatrix(0,R);(_=p.textRunBreakAllowed&&F>p.fakeMultiSpaceMax)||(p.height+=R)}else{R=(F=-F)*d.textHScale;d.translateTextMatrix(R,0);(_=p.textRunBreakAllowed&&F>p.fakeMultiSpaceMax)||(p.width+=R)}_?P():F>0&&O(F,p.str)}break;case r.OPS.showText:if(!s.state.font){b.ensureStateFont(s.state);continue}T(C[0]);break;case r.OPS.nextLineShowText:if(!s.state.font){b.ensureStateFont(s.state);continue}P();d.carriageReturn();T(C[0]);break;case r.OPS.nextLineSetSpacingShowText:if(!s.state.font){b.ensureStateFont(s.state);continue}P();d.wordSpacing=C[0];d.charSpacing=C[1];d.carriageReturn();T(C[2]);break;case r.OPS.paintXObject:P();v||(v=i.get("XObject")||n.Dict.empty);var z=C[0].name;if(z&&void 0!==w[z])break;f(new Promise((function(e,a){if(!z)throw new r.FormatError("XObject must be referred to by name.");const l=v.get(z);if(!l){e();return}if(!(0,n.isStream)(l))throw new r.FormatError("XObject should be a stream");const d=l.dict.get("Subtype");if(!(0,n.isName)(d))throw new r.FormatError("XObject should have a Name subtype");if("Form"!==d.name){w[z]=!0;e();return}const f=s.state.clone(),g=new I(f),m=l.dict.getArray("Matrix");Array.isArray(m)&&6===m.length&&g.transform(m);B();const p={enqueueInvoked:!1,enqueue(e,t){this.enqueueInvoked=!0;h.enqueue(e,t)},get desiredSize(){return h.desiredSize},get ready(){return h.ready}};b.getTextContent({stream:l,task:t,resources:l.dict.get("Resources")||i,stateManager:g,normalizeWhitespace:o,combineTextItems:c,sink:p,seenStyles:u}).then((function(){p.enqueueInvoked||(w[z]=!0);e()}),a)})).catch((function(e){if(!(e instanceof r.AbortException)){if(!b.options.ignoreErrors)throw e;(0,r.warn)(`getTextContent - ignoring XObject: "${e}".`)}})));return;case r.OPS.setGState:P();var H=C[0],G=i.get("ExtGState");if(!(0,n.isDict)(G)||!(0,n.isName)(H))break;var W=G.get(H.name);if(!(0,n.isDict)(W))break;var X=W.get("Font");if(X){d.fontName=null;d.fontSize=X[1];f(A(null,X[0]));return}}if(m.items.length>=h.desiredSize){g=!0;break}}if(g)f(x);else{P();B();a()}})).catch(e=>{if(!(e instanceof r.AbortException)){if(!this.options.ignoreErrors)throw e;(0,r.warn)(`getTextContent - ignoring errors during "${t.name}" `+`task: "${e}".`);P();B()}})},extractDataStructures:function(e,t,a){const i=this.xref;let c;var l=e.get("ToUnicode")||t.get("ToUnicode"),h=l?this.readToUnicode(l):Promise.resolve(void 0);if(a.composite){var u=e.get("CIDSystemInfo");(0,n.isDict)(u)&&(a.cidSystemInfo={registry:(0,r.stringToPDFString)(u.get("Registry")),ordering:(0,r.stringToPDFString)(u.get("Ordering")),supplement:u.get("Supplement")});var d=e.get("CIDToGIDMap");(0,n.isStream)(d)&&(c=d.getBytes())}var f,g=[],m=null;if(e.has("Encoding")){f=e.get("Encoding");if((0,n.isDict)(f)){m=f.get("BaseEncoding");m=(0,n.isName)(m)?m.name:null;if(f.has("Differences"))for(var p=f.get("Differences"),b=0,y=0,v=p.length;y<v;y++){var w=i.fetchIfRef(p[y]);if((0,r.isNum)(w))b=w;else{if(!(0,n.isName)(w))throw new r.FormatError(`Invalid entry in 'Differences' array: ${w}`);g[b++]=w.name}}}else{if(!(0,n.isName)(f))throw new r.FormatError("Encoding is not a Name nor a Dict");m=f.name}"MacRomanEncoding"!==m&&"MacExpertEncoding"!==m&&"WinAnsiEncoding"!==m&&(m=null)}if(m)a.defaultEncoding=(0,o.getEncoding)(m).slice();else{var k=!!(a.flags&s.FontFlags.Symbolic),S=!!(a.flags&s.FontFlags.Nonsymbolic);f=o.StandardEncoding;"TrueType"!==a.type||S||(f=o.WinAnsiEncoding);if(k){f=o.MacRomanEncoding;a.file||(/Symbol/i.test(a.name)?f=o.SymbolSetEncoding:/Dingbats|Wingdings/i.test(a.name)&&(f=o.ZapfDingbatsEncoding))}a.defaultEncoding=f}a.differences=g;a.baseEncodingName=m;a.hasEncoding=!!m||g.length>0;a.dict=e;return h.then(e=>{a.toUnicode=e;return this.buildToUnicode(a)}).then(e=>{a.toUnicode=e;c&&(a.cidToGidMap=this.readCidToGidMap(c,e));return a})},_buildSimpleFontToUnicode(e,t=!1){(0,r.assert)(!e.composite,"Must be a simple font.");const a=[],i=e.defaultEncoding.slice(),n=e.baseEncodingName,c=e.differences;for(const e in c){const t=c[e];".notdef"!==t&&(i[e]=t)}const h=(0,p.getGlyphsUnicode)();for(const r in i){let s=i[r];if(""!==s)if(void 0!==h[s])a[r]=String.fromCharCode(h[s]);else{let i=0;switch(s[0]){case"G":3===s.length&&(i=parseInt(s.substring(1),16));break;case"g":5===s.length&&(i=parseInt(s.substring(1),16));break;case"C":case"c":if(s.length>=3&&s.length<=4){const a=s.substring(1);if(t){i=parseInt(a,16);break}i=+a;if(Number.isNaN(i)&&Number.isInteger(parseInt(a,16)))return this._buildSimpleFontToUnicode(e,!0)}break;default:const a=(0,l.getUnicodeForGlyph)(s,h);-1!==a&&(i=a)}if(i>0&&Number.isInteger(i)){if(n&&i===+r){const e=(0,o.getEncoding)(n);if(e&&(s=e[r])){a[r]=String.fromCharCode(h[s]);continue}}a[r]=String.fromCodePoint(i)}}}return new s.ToUnicodeMap(a)},buildToUnicode(e){e.hasIncludedToUnicodeMap=!!e.toUnicode&&e.toUnicode.length>0;if(e.hasIncludedToUnicodeMap){!e.composite&&e.hasEncoding&&(e.fallbackToUnicode=this._buildSimpleFontToUnicode(e));return Promise.resolve(e.toUnicode)}if(!e.composite)return Promise.resolve(this._buildSimpleFontToUnicode(e));if(e.composite&&(e.cMap.builtInCMap&&!(e.cMap instanceof i.IdentityCMap)||"Adobe"===e.cidSystemInfo.registry&&("GB1"===e.cidSystemInfo.ordering||"CNS1"===e.cidSystemInfo.ordering||"Japan1"===e.cidSystemInfo.ordering||"Korea1"===e.cidSystemInfo.ordering))){const t=e.cidSystemInfo.registry,a=e.cidSystemInfo.ordering,o=n.Name.get(t+"-"+a+"-UCS2");return i.CMapFactory.create({encoding:o,fetchBuiltInCMap:this.fetchBuiltInCMap,useCMap:null}).then((function(t){const a=e.cMap,i=[];a.forEach((function(e,a){if(a>65535)throw new r.FormatError("Max size of CID is 65,535");const n=t.lookup(a);n&&(i[e]=String.fromCharCode((n.charCodeAt(0)<<8)+n.charCodeAt(1)))}));return new s.ToUnicodeMap(i)}))}return Promise.resolve(new s.IdentityToUnicodeMap(e.firstChar,e.lastChar))},readToUnicode:function(e){var t=e;return(0,n.isName)(t)?i.CMapFactory.create({encoding:t,fetchBuiltInCMap:this.fetchBuiltInCMap,useCMap:null}).then((function(e){return e instanceof i.IdentityCMap?new s.IdentityToUnicodeMap(0,65535):new s.ToUnicodeMap(e.getMap())})):(0,n.isStream)(t)?i.CMapFactory.create({encoding:t,fetchBuiltInCMap:this.fetchBuiltInCMap,useCMap:null}).then((function(e){if(e instanceof i.IdentityCMap)return new s.IdentityToUnicodeMap(0,65535);var t=new Array(e.length);e.forEach((function(e,a){for(var r=[],i=0;i<a.length;i+=2){var n=a.charCodeAt(i)<<8|a.charCodeAt(i+1);if(55296==(63488&n)){i+=2;var s=a.charCodeAt(i)<<8|a.charCodeAt(i+1);r.push(((1023&n)<<10)+(1023&s)+65536)}else r.push(n)}t[e]=String.fromCodePoint.apply(String,r)}));return new s.ToUnicodeMap(t)}),e=>{if(e instanceof r.AbortException)return null;if(this.options.ignoreErrors){this.handler.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.font});(0,r.warn)(`readToUnicode - ignoring ToUnicode data: "${e}".`);return null}throw e}):Promise.resolve(null)},readCidToGidMap(e,t){for(var a=[],r=0,i=e.length;r<i;r++){var n=e[r++]<<8|e[r];const i=r>>1;(0!==n||t.has(i))&&(a[i]=n)}return a},extractWidths:function(e,t,a){var r,i,o,c,l,h,u,d,f=this.xref,g=[],m=0,p=[];if(a.composite){m=e.has("DW")?e.get("DW"):1e3;if(d=e.get("W"))for(i=0,o=d.length;i<o;i++){h=f.fetchIfRef(d[i++]);u=f.fetchIfRef(d[i]);if(Array.isArray(u))for(c=0,l=u.length;c<l;c++)g[h++]=f.fetchIfRef(u[c]);else{var b=f.fetchIfRef(d[++i]);for(c=h;c<=u;c++)g[c]=b}}if(a.vertical){var y=e.getArray("DW2")||[880,-1e3];r=[y[1],.5*m,y[0]];if(y=e.get("W2"))for(i=0,o=y.length;i<o;i++){h=f.fetchIfRef(y[i++]);u=f.fetchIfRef(y[i]);if(Array.isArray(u))for(c=0,l=u.length;c<l;c++)p[h++]=[f.fetchIfRef(u[c++]),f.fetchIfRef(u[c++]),f.fetchIfRef(u[c])];else{var v=[f.fetchIfRef(y[++i]),f.fetchIfRef(y[++i]),f.fetchIfRef(y[++i])];for(c=h;c<=u;c++)p[c]=v}}}}else{var w=a.firstChar;if(d=e.get("Widths")){c=w;for(i=0,o=d.length;i<o;i++)g[c++]=f.fetchIfRef(d[i]);m=parseFloat(t.get("MissingWidth"))||0}else{var k=e.get("BaseFont");if((0,n.isName)(k)){var S=this.getBaseFontMetrics(k.name);g=this.buildCharCodeToWidth(S.widths,a);m=S.defaultWidth}}}var C=!0,x=m;for(var A in g){var I=g[A];if(I)if(x){if(x!==I){C=!1;break}}else x=I}C&&(a.flags|=s.FontFlags.FixedPitch);a.defaultWidth=m;a.widths=g;a.defaultVMetrics=r;a.vmetrics=p},isSerifFont:function(e){var t=e.split("-")[0];return t in(0,h.getSerifFonts)()||-1!==t.search(/serif/gi)},getBaseFontMetrics:function(e){var t=0,a=[],i=!1,n=(0,h.getStdFontMap)()[e]||e,s=(0,b.getMetrics)();n in s||(n=this.isSerifFont(e)?"Times-Roman":"Helvetica");var o=s[n];if((0,r.isNum)(o)){t=o;i=!0}else a=o();return{defaultWidth:t,monospace:i,widths:a}},buildCharCodeToWidth:function(e,t){for(var a=Object.create(null),r=t.differences,i=t.defaultEncoding,n=0;n<256;n++)n in r&&e[r[n]]?a[n]=e[r[n]]:n in i&&e[i[n]]&&(a[n]=e[i[n]]);return a},preEvaluateFont:function(e){var t=e,a=e.get("Subtype");if(!(0,n.isName)(a))throw new r.FormatError("invalid font Subtype");var i,s=!1;if("Type0"===a.name){var o=e.get("DescendantFonts");if(!o)throw new r.FormatError("Descendant fonts are not specified");a=(e=Array.isArray(o)?this.xref.fetchIfRef(o[0]):o).get("Subtype");if(!(0,n.isName)(a))throw new r.FormatError("invalid font Subtype");s=!0}var c=e.get("FontDescriptor");if(c){var l=new w.MurmurHash3_64,h=t.getRaw("Encoding");if((0,n.isName)(h))l.update(h.name);else if((0,n.isRef)(h))l.update(h.toString());else if((0,n.isDict)(h))for(var u=h.getKeys(),d=0,f=u.length;d<f;d++){var g=h.getRaw(u[d]);if((0,n.isName)(g))l.update(g.name);else if((0,n.isRef)(g))l.update(g.toString());else if(Array.isArray(g)){for(var m=g.length,p=new Array(m),b=0;b<m;b++){var y=g[b];(0,n.isName)(y)?p[b]=y.name:((0,r.isNum)(y)||(0,n.isRef)(y))&&(p[b]=y.toString())}l.update(p.join())}}const a=e.get("FirstChar")||0,o=e.get("LastChar")||(s?65535:255);l.update(`${a}-${o}`);var v=e.get("ToUnicode")||t.get("ToUnicode");if((0,n.isStream)(v)){var k=v.str||v;i=k.buffer?new Uint8Array(k.buffer.buffer,0,k.bufferLength):new Uint8Array(k.bytes.buffer,k.start,k.end-k.start);l.update(i)}else(0,n.isName)(v)&&l.update(v.name);var S=e.get("Widths")||t.get("Widths");if(S){i=new Uint8Array(new Uint32Array(S).buffer);l.update(i)}}return{descriptor:c,dict:e,baseDict:t,composite:s,type:a.name,hash:l?l.hexdigest():""}},translateFont:function(e){var t,a=e.baseDict,o=e.dict,c=e.composite,l=e.descriptor,u=e.type,d=c?65535:255;const f=o.get("FirstChar")||0,g=o.get("LastChar")||d;if(!l){if("Type3"!==u){var m=o.get("BaseFont");if(!(0,n.isName)(m))throw new r.FormatError("Base font is not specified");m=m.name.replace(/[,_]/g,"-");var p=this.getBaseFontMetrics(m),b=m.split("-")[0],y=(this.isSerifFont(b)?s.FontFlags.Serif:0)|(p.monospace?s.FontFlags.FixedPitch:0)|((0,h.getSymbolsFonts)()[b]?s.FontFlags.Symbolic:s.FontFlags.Nonsymbolic);t={type:u,name:m,widths:p.widths,defaultWidth:p.defaultWidth,flags:y,firstChar:f,lastChar:g};const e=o.get("Widths");return this.extractDataStructures(o,o,t).then(t=>{if(e){const a=[];let r=f;for(let t=0,i=e.length;t<i;t++)a[r++]=this.xref.fetchIfRef(e[t]);t.widths=a}else t.widths=this.buildCharCodeToWidth(p.widths,t);return new s.Font(m,null,t)})}(l=new n.Dict(null)).set("FontName",n.Name.get(u));l.set("FontBBox",o.getArray("FontBBox")||[0,0,0,0])}var v=l.get("FontName"),w=o.get("BaseFont");(0,r.isString)(v)&&(v=n.Name.get(v));(0,r.isString)(w)&&(w=n.Name.get(w));if("Type3"!==u){var k=v&&v.name,S=w&&w.name;if(k!==S){(0,r.info)(`The FontDescriptor's FontName is "${k}" but `+`should be the same as the Font's BaseFont "${S}".`);k&&S&&S.startsWith(k)&&(v=w)}}v=v||w;if(!(0,n.isName)(v))throw new r.FormatError("invalid font name");var C,x=l.get("FontFile","FontFile2","FontFile3");if(x&&x.dict){var A=x.dict.get("Subtype");A&&(A=A.name);var I=x.dict.get("Length1"),F=x.dict.get("Length2"),T=x.dict.get("Length3")}t={type:u,name:v.name,subtype:A,file:x,length1:I,length2:F,length3:T,loadedName:a.loadedName,composite:c,wideChars:c,fixedPitch:!1,fontMatrix:o.getArray("FontMatrix")||r.FONT_IDENTITY_MATRIX,firstChar:f||0,lastChar:g||d,bbox:l.getArray("FontBBox"),ascent:l.get("Ascent"),descent:l.get("Descent"),xHeight:l.get("XHeight"),capHeight:l.get("CapHeight"),flags:l.get("Flags"),italicAngle:l.get("ItalicAngle"),isType3Font:!1};if(c){var E=a.get("Encoding");(0,n.isName)(E)&&(t.cidEncoding=E.name);C=i.CMapFactory.create({encoding:E,fetchBuiltInCMap:this.fetchBuiltInCMap,useCMap:null}).then((function(e){t.cMap=e;t.vertical=t.cMap.vertical}))}else C=Promise.resolve(void 0);return C.then(()=>this.extractDataStructures(o,a,t)).then(e=>{this.extractWidths(o,l,e);"Type3"===u&&(e.isType3Font=!0);return new s.Font(v.name,x,e)})}};t.buildFontPaths=function(e,t,a){function r(t){e.renderer.hasBuiltPath(t)||a.send("commonobj",[`${e.loadedName}_path_${t}`,"FontPath",e.renderer.getPathJs(t)])}for(const e of t){r(e.fontChar);const t=e.accent;t&&t.fontChar&&r(t.fontChar)}};t.getFallbackFontDict=function(){if(this._fallbackFontDict)return this._fallbackFontDict;const e=new n.Dict;e.set("BaseFont",n.Name.get("PDFJS-FallbackFont"));e.set("Type",n.Name.get("FallbackType"));e.set("Subtype",n.Name.get("FallbackType"));e.set("Encoding",n.Name.get("WinAnsiEncoding"));return this._fallbackFontDict=e};return t}();t.PartialEvaluator=x;var A=function(){function e(e,t,a){this.loadedName=e;this.font=t;this.dict=a;this.type3Loaded=null;this.sent=!1}e.prototype={send(e){if(!this.sent){this.sent=!0;e.send("commonobj",[this.loadedName,"Font",this.font.exportData()])}},fallback(e){if(!this.font.data)return;this.font.disableFontFace=!0;const t=this.font.glyphCacheValues;x.buildFontPaths(this.font,t,e)},loadType3Data(e,t,a,i){if(!this.font.isType3Font)throw new Error("Must be a Type3 font.");if(this.type3Loaded)return this.type3Loaded;var n=Object.create(e.options);n.ignoreErrors=!1;n.nativeImageDecoderSupport=r.NativeImageDecoding.NONE;var s=e.clone(n);s.parsingType3Font=!0;for(var o=this.font,c=Promise.resolve(),l=this.dict.get("CharProcs"),h=this.dict.get("Resources")||t,u=l.getKeys(),d=Object.create(null),f=0,g=u.length;f<g;++f){const e=u[f];c=c.then((function(){var t=l.get(e),n=new S.OperatorList;return s.getOperatorList({stream:t,task:i,resources:h,operatorList:n}).then((function(){d[e]=n.getIR();a.addDependencies(n.dependencies)})).catch((function(t){(0,r.warn)(`Type3 font resource "${e}" is not available.`);var a=new S.OperatorList;d[e]=a.getIR()}))}))}this.type3Loaded=c.then((function(){o.charProcOperatorList=d}));return this.type3Loaded}};return e}(),I=function(){function e(e){this.state=e;this.stateStack=[]}e.prototype={save(){var e=this.state;this.stateStack.push(this.state);this.state=e.clone()},restore(){var e=this.stateStack.pop();e&&(this.state=e)},transform(e){this.state.ctm=r.Util.transform(this.state.ctm,e)}};return e}(),F=function(){function e(){this.ctm=new Float32Array(r.IDENTITY_MATRIX);this.fontName=null;this.fontSize=0;this.font=null;this.fontMatrix=r.FONT_IDENTITY_MATRIX;this.textMatrix=r.IDENTITY_MATRIX.slice();this.textLineMatrix=r.IDENTITY_MATRIX.slice();this.charSpacing=0;this.wordSpacing=0;this.leading=0;this.textHScale=1;this.textRise=0}e.prototype={setTextMatrix:function(e,t,a,r,i,n){var s=this.textMatrix;s[0]=e;s[1]=t;s[2]=a;s[3]=r;s[4]=i;s[5]=n},setTextLineMatrix:function(e,t,a,r,i,n){var s=this.textLineMatrix;s[0]=e;s[1]=t;s[2]=a;s[3]=r;s[4]=i;s[5]=n},translateTextMatrix:function(e,t){var a=this.textMatrix;a[4]=a[0]*e+a[2]*t+a[4];a[5]=a[1]*e+a[3]*t+a[5]},translateTextLineMatrix:function(e,t){var a=this.textLineMatrix;a[4]=a[0]*e+a[2]*t+a[4];a[5]=a[1]*e+a[3]*t+a[5]},calcTextLineMatrixAdvance:function(e,t,a,r,i,n){var s=this.font;if(!s)return null;var o=this.textLineMatrix;if(e!==o[0]||t!==o[1]||a!==o[2]||r!==o[3])return null;var c=i-o[4],l=n-o[5];if(s.vertical&&0!==c||!s.vertical&&0!==l)return null;var h,u,d=e*r-t*a;if(s.vertical){h=-l*a/d;u=l*e/d}else{h=c*r/d;u=-c*t/d}return{width:h,height:u,value:s.vertical?u:h}},calcRenderMatrix:function(e){var t=[this.fontSize*this.textHScale,0,0,this.fontSize,0,this.textRise];return r.Util.transform(e,r.Util.transform(this.textMatrix,t))},carriageReturn:function(){this.translateTextLineMatrix(0,-this.leading);this.textMatrix=this.textLineMatrix.slice()},clone:function(){var e=Object.create(this);e.textMatrix=this.textMatrix.slice();e.textLineMatrix=this.textLineMatrix.slice();e.fontMatrix=this.fontMatrix.slice();return e}};return e}(),T=function(){function e(){this.ctm=new Float32Array(r.IDENTITY_MATRIX);this.font=null;this.textRenderingMode=r.TextRenderingMode.FILL;this.fillColorSpace=g.ColorSpace.singletons.gray;this.strokeColorSpace=g.ColorSpace.singletons.gray}e.prototype={clone:function(){return Object.create(this)}};return e}(),E=function(){var e=(0,c.getLookupTableFactory)((function(e){e.w={id:r.OPS.setLineWidth,numArgs:1,variableArgs:!1};e.J={id:r.OPS.setLineCap,numArgs:1,variableArgs:!1};e.j={id:r.OPS.setLineJoin,numArgs:1,variableArgs:!1};e.M={id:r.OPS.setMiterLimit,numArgs:1,variableArgs:!1};e.d={id:r.OPS.setDash,numArgs:2,variableArgs:!1};e.ri={id:r.OPS.setRenderingIntent,numArgs:1,variableArgs:!1};e.i={id:r.OPS.setFlatness,numArgs:1,variableArgs:!1};e.gs={id:r.OPS.setGState,numArgs:1,variableArgs:!1};e.q={id:r.OPS.save,numArgs:0,variableArgs:!1};e.Q={id:r.OPS.restore,numArgs:0,variableArgs:!1};e.cm={id:r.OPS.transform,numArgs:6,variableArgs:!1};e.m={id:r.OPS.moveTo,numArgs:2,variableArgs:!1};e.l={id:r.OPS.lineTo,numArgs:2,variableArgs:!1};e.c={id:r.OPS.curveTo,numArgs:6,variableArgs:!1};e.v={id:r.OPS.curveTo2,numArgs:4,variableArgs:!1};e.y={id:r.OPS.curveTo3,numArgs:4,variableArgs:!1};e.h={id:r.OPS.closePath,numArgs:0,variableArgs:!1};e.re={id:r.OPS.rectangle,numArgs:4,variableArgs:!1};e.S={id:r.OPS.stroke,numArgs:0,variableArgs:!1};e.s={id:r.OPS.closeStroke,numArgs:0,variableArgs:!1};e.f={id:r.OPS.fill,numArgs:0,variableArgs:!1};e.F={id:r.OPS.fill,numArgs:0,variableArgs:!1};e["f*"]={id:r.OPS.eoFill,numArgs:0,variableArgs:!1};e.B={id:r.OPS.fillStroke,numArgs:0,variableArgs:!1};e["B*"]={id:r.OPS.eoFillStroke,numArgs:0,variableArgs:!1};e.b={id:r.OPS.closeFillStroke,numArgs:0,variableArgs:!1};e["b*"]={id:r.OPS.closeEOFillStroke,numArgs:0,variableArgs:!1};e.n={id:r.OPS.endPath,numArgs:0,variableArgs:!1};e.W={id:r.OPS.clip,numArgs:0,variableArgs:!1};e["W*"]={id:r.OPS.eoClip,numArgs:0,variableArgs:!1};e.BT={id:r.OPS.beginText,numArgs:0,variableArgs:!1};e.ET={id:r.OPS.endText,numArgs:0,variableArgs:!1};e.Tc={id:r.OPS.setCharSpacing,numArgs:1,variableArgs:!1};e.Tw={id:r.OPS.setWordSpacing,numArgs:1,variableArgs:!1};e.Tz={id:r.OPS.setHScale,numArgs:1,variableArgs:!1};e.TL={id:r.OPS.setLeading,numArgs:1,variableArgs:!1};e.Tf={id:r.OPS.setFont,numArgs:2,variableArgs:!1};e.Tr={id:r.OPS.setTextRenderingMode,numArgs:1,variableArgs:!1};e.Ts={id:r.OPS.setTextRise,numArgs:1,variableArgs:!1};e.Td={id:r.OPS.moveText,numArgs:2,variableArgs:!1};e.TD={id:r.OPS.setLeadingMoveText,numArgs:2,variableArgs:!1};e.Tm={id:r.OPS.setTextMatrix,numArgs:6,variableArgs:!1};e["T*"]={id:r.OPS.nextLine,numArgs:0,variableArgs:!1};e.Tj={id:r.OPS.showText,numArgs:1,variableArgs:!1};e.TJ={id:r.OPS.showSpacedText,numArgs:1,variableArgs:!1};e["'"]={id:r.OPS.nextLineShowText,numArgs:1,variableArgs:!1};e['"']={id:r.OPS.nextLineSetSpacingShowText,numArgs:3,variableArgs:!1};e.d0={id:r.OPS.setCharWidth,numArgs:2,variableArgs:!1};e.d1={id:r.OPS.setCharWidthAndBounds,numArgs:6,variableArgs:!1};e.CS={id:r.OPS.setStrokeColorSpace,numArgs:1,variableArgs:!1};e.cs={id:r.OPS.setFillColorSpace,numArgs:1,variableArgs:!1};e.SC={id:r.OPS.setStrokeColor,numArgs:4,variableArgs:!0};e.SCN={id:r.OPS.setStrokeColorN,numArgs:33,variableArgs:!0};e.sc={id:r.OPS.setFillColor,numArgs:4,variableArgs:!0};e.scn={id:r.OPS.setFillColorN,numArgs:33,variableArgs:!0};e.G={id:r.OPS.setStrokeGray,numArgs:1,variableArgs:!1};e.g={id:r.OPS.setFillGray,numArgs:1,variableArgs:!1};e.RG={id:r.OPS.setStrokeRGBColor,numArgs:3,variableArgs:!1};e.rg={id:r.OPS.setFillRGBColor,numArgs:3,variableArgs:!1};e.K={id:r.OPS.setStrokeCMYKColor,numArgs:4,variableArgs:!1};e.k={id:r.OPS.setFillCMYKColor,numArgs:4,variableArgs:!1};e.sh={id:r.OPS.shadingFill,numArgs:1,variableArgs:!1};e.BI={id:r.OPS.beginInlineImage,numArgs:0,variableArgs:!1};e.ID={id:r.OPS.beginImageData,numArgs:0,variableArgs:!1};e.EI={id:r.OPS.endInlineImage,numArgs:1,variableArgs:!1};e.Do={id:r.OPS.paintXObject,numArgs:1,variableArgs:!1};e.MP={id:r.OPS.markPoint,numArgs:1,variableArgs:!1};e.DP={id:r.OPS.markPointProps,numArgs:2,variableArgs:!1};e.BMC={id:r.OPS.beginMarkedContent,numArgs:1,variableArgs:!1};e.BDC={id:r.OPS.beginMarkedContentProps,numArgs:2,variableArgs:!1};e.EMC={id:r.OPS.endMarkedContent,numArgs:0,variableArgs:!1};e.BX={id:r.OPS.beginCompat,numArgs:0,variableArgs:!1};e.EX={id:r.OPS.endCompat,numArgs:0,variableArgs:!1};e.BM=null;e.BD=null;e.true=null;e.fa=null;e.fal=null;e.fals=null;e.false=null;e.nu=null;e.nul=null;e.null=null}));function t(t,a,r){this.opMap=e();this.parser=new d.Parser({lexer:new d.Lexer(t,this.opMap),xref:a});this.stateManager=r;this.nonProcessedArgs=[];this._numInvalidPathOPS=0}t.prototype={get savedStatesDepth(){return this.stateManager.stateStack.length},read:function(e){for(var t=e.args;;){var a=this.parser.getObj();if(a instanceof n.Cmd){var i=a.cmd,s=this.opMap[i];if(!s){(0,r.warn)(`Unknown command "${i}".`);continue}var o=s.id,c=s.numArgs,l=null!==t?t.length:0;if(s.variableArgs)l>c&&(0,r.info)(`Command ${i}: expected [0, ${c}] args, `+`but received ${l} args.`);else{if(l!==c){for(var h=this.nonProcessedArgs;l>c;){h.push(t.shift());l--}for(;l<c&&0!==h.length;){null===t&&(t=[]);t.unshift(h.pop());l++}}if(l<c){const e=`command ${i}: expected ${c} args, `+`but received ${l} args.`;if(o>=r.OPS.moveTo&&o<=r.OPS.endPath&&++this._numInvalidPathOPS>20)throw new r.FormatError(`Invalid ${e}`);(0,r.warn)(`Skipping ${e}`);null!==t&&(t.length=0);continue}}this.preprocessCommand(o,t);e.fn=o;e.args=t;return!0}if(a===n.EOF)return!1;if(null!==a){null===t&&(t=[]);t.push(a);if(t.length>33)throw new r.FormatError("Too many arguments")}}},preprocessCommand:function(e,t){switch(0|e){case r.OPS.save:this.stateManager.save();break;case r.OPS.restore:this.stateManager.restore();break;case r.OPS.transform:this.stateManager.transform(t)}}};return t}()},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.CMapFactory=t.IdentityCMap=t.CMap=void 0;var r=a(2),i=a(4),n=a(10),s=a(7),o=a(11),c=["Adobe-GB1-UCS2","Adobe-CNS1-UCS2","Adobe-Japan1-UCS2","Adobe-Korea1-UCS2","78-EUC-H","78-EUC-V","78-H","78-RKSJ-H","78-RKSJ-V","78-V","78ms-RKSJ-H","78ms-RKSJ-V","83pv-RKSJ-H","90ms-RKSJ-H","90ms-RKSJ-V","90msp-RKSJ-H","90msp-RKSJ-V","90pv-RKSJ-H","90pv-RKSJ-V","Add-H","Add-RKSJ-H","Add-RKSJ-V","Add-V","Adobe-CNS1-0","Adobe-CNS1-1","Adobe-CNS1-2","Adobe-CNS1-3","Adobe-CNS1-4","Adobe-CNS1-5","Adobe-CNS1-6","Adobe-GB1-0","Adobe-GB1-1","Adobe-GB1-2","Adobe-GB1-3","Adobe-GB1-4","Adobe-GB1-5","Adobe-Japan1-0","Adobe-Japan1-1","Adobe-Japan1-2","Adobe-Japan1-3","Adobe-Japan1-4","Adobe-Japan1-5","Adobe-Japan1-6","Adobe-Korea1-0","Adobe-Korea1-1","Adobe-Korea1-2","B5-H","B5-V","B5pc-H","B5pc-V","CNS-EUC-H","CNS-EUC-V","CNS1-H","CNS1-V","CNS2-H","CNS2-V","ETHK-B5-H","ETHK-B5-V","ETen-B5-H","ETen-B5-V","ETenms-B5-H","ETenms-B5-V","EUC-H","EUC-V","Ext-H","Ext-RKSJ-H","Ext-RKSJ-V","Ext-V","GB-EUC-H","GB-EUC-V","GB-H","GB-V","GBK-EUC-H","GBK-EUC-V","GBK2K-H","GBK2K-V","GBKp-EUC-H","GBKp-EUC-V","GBT-EUC-H","GBT-EUC-V","GBT-H","GBT-V","GBTpc-EUC-H","GBTpc-EUC-V","GBpc-EUC-H","GBpc-EUC-V","H","HKdla-B5-H","HKdla-B5-V","HKdlb-B5-H","HKdlb-B5-V","HKgccs-B5-H","HKgccs-B5-V","HKm314-B5-H","HKm314-B5-V","HKm471-B5-H","HKm471-B5-V","HKscs-B5-H","HKscs-B5-V","Hankaku","Hiragana","KSC-EUC-H","KSC-EUC-V","KSC-H","KSC-Johab-H","KSC-Johab-V","KSC-V","KSCms-UHC-H","KSCms-UHC-HW-H","KSCms-UHC-HW-V","KSCms-UHC-V","KSCpc-EUC-H","KSCpc-EUC-V","Katakana","NWP-H","NWP-V","RKSJ-H","RKSJ-V","Roman","UniCNS-UCS2-H","UniCNS-UCS2-V","UniCNS-UTF16-H","UniCNS-UTF16-V","UniCNS-UTF32-H","UniCNS-UTF32-V","UniCNS-UTF8-H","UniCNS-UTF8-V","UniGB-UCS2-H","UniGB-UCS2-V","UniGB-UTF16-H","UniGB-UTF16-V","UniGB-UTF32-H","UniGB-UTF32-V","UniGB-UTF8-H","UniGB-UTF8-V","UniJIS-UCS2-H","UniJIS-UCS2-HW-H","UniJIS-UCS2-HW-V","UniJIS-UCS2-V","UniJIS-UTF16-H","UniJIS-UTF16-V","UniJIS-UTF32-H","UniJIS-UTF32-V","UniJIS-UTF8-H","UniJIS-UTF8-V","UniJIS2004-UTF16-H","UniJIS2004-UTF16-V","UniJIS2004-UTF32-H","UniJIS2004-UTF32-V","UniJIS2004-UTF8-H","UniJIS2004-UTF8-V","UniJISPro-UCS2-HW-V","UniJISPro-UCS2-V","UniJISPro-UTF8-V","UniJISX0213-UTF32-H","UniJISX0213-UTF32-V","UniJISX02132004-UTF32-H","UniJISX02132004-UTF32-V","UniKS-UCS2-H","UniKS-UCS2-V","UniKS-UTF16-H","UniKS-UTF16-V","UniKS-UTF32-H","UniKS-UTF32-V","UniKS-UTF8-H","UniKS-UTF8-V","V","WP-Symbol"];class l{constructor(e=!1){this.codespaceRanges=[[],[],[],[]];this.numCodespaceRanges=0;this._map=[];this.name="";this.vertical=!1;this.useCMap=null;this.builtInCMap=e}addCodespaceRange(e,t,a){this.codespaceRanges[e-1].push(t,a);this.numCodespaceRanges++}mapCidRange(e,t,a){for(;e<=t;)this._map[e++]=a++}mapBfRange(e,t,a){for(var r=a.length-1;e<=t;){this._map[e++]=a;a=a.substring(0,r)+String.fromCharCode(a.charCodeAt(r)+1)}}mapBfRangeToArray(e,t,a){const r=a.length;let i=0;for(;e<=t&&i<r;){this._map[e]=a[i++];++e}}mapOne(e,t){this._map[e]=t}lookup(e){return this._map[e]}contains(e){return void 0!==this._map[e]}forEach(e){const t=this._map,a=t.length;if(a<=65536)for(let r=0;r<a;r++)void 0!==t[r]&&e(r,t[r]);else for(const a in t)e(a,t[a])}charCodeOf(e){const t=this._map;if(t.length<=65536)return t.indexOf(e);for(const a in t)if(t[a]===e)return 0|a;return-1}getMap(){return this._map}readCharCode(e,t,a){let r=0;const i=this.codespaceRanges;for(let n=0,s=i.length;n<s;n++){r=(r<<8|e.charCodeAt(t+n))>>>0;const s=i[n];for(let e=0,t=s.length;e<t;){const t=s[e++],i=s[e++];if(r>=t&&r<=i){a.charcode=r;a.length=n+1;return}}}a.charcode=0;a.length=1}get length(){return this._map.length}get isIdentityCMap(){if("Identity-H"!==this.name&&"Identity-V"!==this.name)return!1;if(65536!==this._map.length)return!1;for(let e=0;e<65536;e++)if(this._map[e]!==e)return!1;return!0}}t.CMap=l;class h extends l{constructor(e,t){super();this.vertical=e;this.addCodespaceRange(t,0,65535)}mapCidRange(e,t,a){(0,r.unreachable)("should not call mapCidRange")}mapBfRange(e,t,a){(0,r.unreachable)("should not call mapBfRange")}mapBfRangeToArray(e,t,a){(0,r.unreachable)("should not call mapBfRangeToArray")}mapOne(e,t){(0,r.unreachable)("should not call mapCidOne")}lookup(e){return Number.isInteger(e)&&e<=65535?e:void 0}contains(e){return Number.isInteger(e)&&e<=65535}forEach(e){for(let t=0;t<=65535;t++)e(t,t)}charCodeOf(e){return Number.isInteger(e)&&e<=65535?e:-1}getMap(){const e=new Array(65536);for(let t=0;t<=65535;t++)e[t]=t;return e}get length(){return 65536}get isIdentityCMap(){(0,r.unreachable)("should not access .isIdentityCMap")}}t.IdentityCMap=h;var u=function(){function e(e,t){for(var a=0,r=0;r<=t;r++)a=a<<8|e[r];return a>>>0}function t(e,t){return 1===t?String.fromCharCode(e[0],e[1]):3===t?String.fromCharCode(e[0],e[1],e[2],e[3]):String.fromCharCode.apply(null,e.subarray(0,t+1))}function a(e,t,a){for(var r=0,i=a;i>=0;i--){r+=e[i]+t[i];e[i]=255&r;r>>=8}}function i(e,t){for(var a=1,r=t;r>=0&&a>0;r--){a+=e[r];e[r]=255&a;a>>=8}}function n(e){this.buffer=e;this.pos=0;this.end=e.length;this.tmpBuf=new Uint8Array(19)}n.prototype={readByte(){return this.pos>=this.end?-1:this.buffer[this.pos++]},readNumber(){var e,t=0;do{var a=this.readByte();if(a<0)throw new r.FormatError("unexpected EOF in bcmap");e=!(128&a);t=t<<7|127&a}while(!e);return t},readSigned(){var e=this.readNumber();return 1&e?~(e>>>1):e>>>1},readHex(e,t){e.set(this.buffer.subarray(this.pos,this.pos+t+1));this.pos+=t+1},readHexNumber(e,t){var a,i=this.tmpBuf,n=0;do{var s=this.readByte();if(s<0)throw new r.FormatError("unexpected EOF in bcmap");a=!(128&s);i[n++]=127&s}while(!a);for(var o=t,c=0,l=0;o>=0;){for(;l<8&&i.length>0;){c=i[--n]<<l|c;l+=7}e[o]=255&c;o--;c>>=8;l-=8}},readHexSigned(e,t){this.readHexNumber(e,t);for(var a=1&e[t]?255:0,r=0,i=0;i<=t;i++){r=(1&r)<<8|e[i];e[i]=r>>1^a}},readString(){for(var e=this.readNumber(),t="",a=0;a<e;a++)t+=String.fromCharCode(this.readNumber());return t}};function s(){}s.prototype={process:function(r,s,o){return new Promise((function(c,l){var h=new n(r),u=h.readByte();s.vertical=!!(1&u);for(var d,f,g=null,m=new Uint8Array(16),p=new Uint8Array(16),b=new Uint8Array(16),y=new Uint8Array(16),v=new Uint8Array(16);(f=h.readByte())>=0;){var w=f>>5;if(7!==w){var k=!!(16&f),S=15&f;if(S+1>16)throw new Error("processBinaryCMap: Invalid dataSize.");var C,x=h.readNumber();switch(w){case 0:h.readHex(m,S);h.readHexNumber(p,S);a(p,m,S);s.addCodespaceRange(S+1,e(m,S),e(p,S));for(C=1;C<x;C++){i(p,S);h.readHexNumber(m,S);a(m,p,S);h.readHexNumber(p,S);a(p,m,S);s.addCodespaceRange(S+1,e(m,S),e(p,S))}break;case 1:h.readHex(m,S);h.readHexNumber(p,S);a(p,m,S);h.readNumber();for(C=1;C<x;C++){i(p,S);h.readHexNumber(m,S);a(m,p,S);h.readHexNumber(p,S);a(p,m,S);h.readNumber()}break;case 2:h.readHex(b,S);d=h.readNumber();s.mapOne(e(b,S),d);for(C=1;C<x;C++){i(b,S);if(!k){h.readHexNumber(v,S);a(b,v,S)}d=h.readSigned()+(d+1);s.mapOne(e(b,S),d)}break;case 3:h.readHex(m,S);h.readHexNumber(p,S);a(p,m,S);d=h.readNumber();s.mapCidRange(e(m,S),e(p,S),d);for(C=1;C<x;C++){i(p,S);if(k)m.set(p);else{h.readHexNumber(m,S);a(m,p,S)}h.readHexNumber(p,S);a(p,m,S);d=h.readNumber();s.mapCidRange(e(m,S),e(p,S),d)}break;case 4:h.readHex(b,1);h.readHex(y,S);s.mapOne(e(b,1),t(y,S));for(C=1;C<x;C++){i(b,1);if(!k){h.readHexNumber(v,1);a(b,v,1)}i(y,S);h.readHexSigned(v,S);a(y,v,S);s.mapOne(e(b,1),t(y,S))}break;case 5:h.readHex(m,1);h.readHexNumber(p,1);a(p,m,1);h.readHex(y,S);s.mapBfRange(e(m,1),e(p,1),t(y,S));for(C=1;C<x;C++){i(p,1);if(k)m.set(p);else{h.readHexNumber(m,1);a(m,p,1)}h.readHexNumber(p,1);a(p,m,1);h.readHex(y,S);s.mapBfRange(e(m,1),e(p,1),t(y,S))}break;default:l(new Error("processBinaryCMap: Unknown type: "+w));return}}else switch(31&f){case 0:h.readString();break;case 1:g=h.readString()}}c(g?o(g):s)}))}};return s}(),d=function(){function e(e){for(var t=0,a=0;a<e.length;a++)t=t<<8|e.charCodeAt(a);return t>>>0}function t(e){if(!(0,r.isString)(e))throw new r.FormatError("Malformed CMap: expected string.")}function a(e){if(!Number.isInteger(e))throw new r.FormatError("Malformed CMap: expected int.")}function d(a,r){for(;;){var n=r.getObj();if((0,i.isEOF)(n))break;if((0,i.isCmd)(n,"endbfchar"))return;t(n);var s=e(n);t(n=r.getObj());var o=n;a.mapOne(s,o)}}function f(a,n){for(;;){var s=n.getObj();if((0,i.isEOF)(s))break;if((0,i.isCmd)(s,"endbfrange"))return;t(s);var o=e(s);t(s=n.getObj());var c=e(s);s=n.getObj();if(Number.isInteger(s)||(0,r.isString)(s)){var l=Number.isInteger(s)?String.fromCharCode(s):s;a.mapBfRange(o,c,l)}else{if(!(0,i.isCmd)(s,"["))break;s=n.getObj();for(var h=[];!(0,i.isCmd)(s,"]")&&!(0,i.isEOF)(s);){h.push(s);s=n.getObj()}a.mapBfRangeToArray(o,c,h)}}throw new r.FormatError("Invalid bf range.")}function g(r,n){for(;;){var s=n.getObj();if((0,i.isEOF)(s))break;if((0,i.isCmd)(s,"endcidchar"))return;t(s);var o=e(s);a(s=n.getObj());var c=s;r.mapOne(o,c)}}function m(r,n){for(;;){var s=n.getObj();if((0,i.isEOF)(s))break;if((0,i.isCmd)(s,"endcidrange"))return;t(s);var o=e(s);t(s=n.getObj());var c=e(s);a(s=n.getObj());var l=s;r.mapCidRange(o,c,l)}}function p(t,a){for(;;){var n=a.getObj();if((0,i.isEOF)(n))break;if((0,i.isCmd)(n,"endcodespacerange"))return;if(!(0,r.isString)(n))break;var s=e(n);n=a.getObj();if(!(0,r.isString)(n))break;var o=e(n);t.addCodespaceRange(n.length,s,o)}throw new r.FormatError("Invalid codespace range.")}function b(e,t){var a=t.getObj();Number.isInteger(a)&&(e.vertical=!!a)}function y(e,t){var a=t.getObj();(0,i.isName)(a)&&(0,r.isString)(a.name)&&(e.name=a.name)}function v(e,t,a,n){var o,c;e:for(;;)try{var l=t.getObj();if((0,i.isEOF)(l))break;if((0,i.isName)(l)){"WMode"===l.name?b(e,t):"CMapName"===l.name&&y(e,t);o=l}else if((0,i.isCmd)(l))switch(l.cmd){case"endcmap":break e;case"usecmap":(0,i.isName)(o)&&(c=o.name);break;case"begincodespacerange":p(e,t);break;case"beginbfchar":d(e,t);break;case"begincidchar":g(e,t);break;case"beginbfrange":f(e,t);break;case"begincidrange":m(e,t)}}catch(e){if(e instanceof s.MissingDataException)throw e;(0,r.warn)("Invalid cMap data: "+e);continue}!n&&c&&(n=c);return n?w(e,a,n):Promise.resolve(e)}function w(e,t,a){return k(a,t).then((function(t){e.useCMap=t;if(0===e.numCodespaceRanges){for(var a=e.useCMap.codespaceRanges,r=0;r<a.length;r++)e.codespaceRanges[r]=a[r].slice();e.numCodespaceRanges=e.useCMap.numCodespaceRanges}e.useCMap.forEach((function(t,a){e.contains(t)||e.mapOne(t,e.useCMap.lookup(t))}));return e}))}function k(e,t){return"Identity-H"===e?Promise.resolve(new h(!1,2)):"Identity-V"===e?Promise.resolve(new h(!0,2)):c.includes(e)?t?t(e).then((function(e){var a=e.cMapData,i=e.compressionType,s=new l(!0);if(i===r.CMapCompressionType.BINARY)return(new u).process(a,s,(function(e){return w(s,t,e)}));if(i===r.CMapCompressionType.NONE){var c=new n.Lexer(new o.Stream(a));return v(s,c,t,null)}return Promise.reject(new Error("TODO: Only BINARY/NONE CMap compression is currently supported."))})):Promise.reject(new Error("Built-in CMap parameters are not provided.")):Promise.reject(new Error("Unknown CMap name: "+e))}return{async create(e){var t=e.encoding,a=e.fetchBuiltInCMap,r=e.useCMap;if((0,i.isName)(t))return k(t.name,a);if((0,i.isStream)(t)){return v(new l,new n.Lexer(t),a,r).then((function(e){return e.isIdentityCMap?k(e.name,a):e}))}throw new Error("Encoding required.")}}}();t.CMapFactory=d},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getFontType=y;t.IdentityToUnicodeMap=t.ToUnicodeMap=t.FontFlags=t.Font=t.ErrorFont=t.SEAC_ANALYSIS_ENABLED=void 0;var r=a(2),i=a(28),n=a(31),s=a(30),o=a(32),c=a(33),l=a(7),h=a(34),u=a(26),d=a(11),f=a(35);const g=[[57344,63743],[1048576,1114109]];t.SEAC_ANALYSIS_ENABLED=!0;var m={FixedPitch:1,Serif:2,Symbolic:4,Script:8,Nonsymbolic:32,Italic:64,AllCap:65536,SmallCap:131072,ForceBold:262144};t.FontFlags=m;var p=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"];function b(e){if(e.fontMatrix&&e.fontMatrix[0]!==r.FONT_IDENTITY_MATRIX[0]){var t=.001/e.fontMatrix[0],a=e.widths;for(var i in a)a[i]*=t;e.defaultWidth*=t}}function y(e,t){switch(e){case"Type1":return"Type1C"===t?r.FontType.TYPE1C:r.FontType.TYPE1;case"CIDFontType0":return"CIDFontType0C"===t?r.FontType.CIDFONTTYPE0C:r.FontType.CIDFONTTYPE0;case"OpenType":return r.FontType.OPENTYPE;case"TrueType":return r.FontType.TRUETYPE;case"CIDFontType2":return r.FontType.CIDFONTTYPE2;case"MMType1":return r.FontType.MMTYPE1;case"Type0":return r.FontType.TYPE0;default:return r.FontType.UNKNOWN}}function v(e,t){if(void 0!==t[e])return e;var a=(0,c.getUnicodeForGlyph)(e,t);if(-1!==a)for(var i in t)if(t[i]===a)return i;(0,r.info)("Unable to recover a standard glyph name for: "+e);return e}var w=function(){function e(e,t,a,r,i,n,s,o){this.fontChar=e;this.unicode=t;this.accent=a;this.width=r;this.vmetric=i;this.operatorListId=n;this.isSpace=s;this.isInFont=o}e.prototype.matchesForCache=function(e,t,a,r,i,n,s,o){return this.fontChar===e&&this.unicode===t&&this.accent===a&&this.width===r&&this.vmetric===i&&this.operatorListId===n&&this.isSpace===s&&this.isInFont===o};return e}(),k=function(){function e(e=[]){this._map=e}e.prototype={get length(){return this._map.length},forEach(e){for(var t in this._map)e(t,this._map[t].charCodeAt(0))},has(e){return void 0!==this._map[e]},get(e){return this._map[e]},charCodeOf(e){const t=this._map;if(t.length<=65536)return t.indexOf(e);for(const a in t)if(t[a]===e)return 0|a;return-1},amend(e){for(var t in e)this._map[t]=e[t]}};return e}();t.ToUnicodeMap=k;var S=function(){function e(e,t){this.firstChar=e;this.lastChar=t}e.prototype={get length(){return this.lastChar+1-this.firstChar},forEach(e){for(var t=this.firstChar,a=this.lastChar;t<=a;t++)e(t,t)},has(e){return this.firstChar<=e&&e<=this.lastChar},get(e){if(this.firstChar<=e&&e<=this.lastChar)return String.fromCharCode(e)},charCodeOf(e){return Number.isInteger(e)&&e>=this.firstChar&&e<=this.lastChar?e:-1},amend(e){(0,r.unreachable)("Should not call amend()")}};return e}();t.IdentityToUnicodeMap=S;var C=function(){function e(e,t,a){e[t]=a>>8&255;e[t+1]=255&a}function t(e,t,a){e[t]=a>>24&255;e[t+1]=a>>16&255;e[t+2]=a>>8&255;e[t+3]=255&a}function a(e,t,a){var r,i;if(a instanceof Uint8Array)e.set(a,t);else if("string"==typeof a)for(r=0,i=a.length;r<i;r++)e[t++]=255&a.charCodeAt(r);else for(r=0,i=a.length;r<i;r++)e[t++]=255&a[r]}function i(e){this.sfnt=e;this.tables=Object.create(null)}i.getSearchParams=function(e,t){for(var a=1,r=0;(a^e)>a;){a<<=1;r++}var i=a*t;return{range:i,entry:r,rangeShift:t*e-i}};i.prototype={toArray:function(){var n=this.sfnt,s=this.tables,o=Object.keys(s);o.sort();var c,h,u,d,f,g=o.length,m=12+16*g,p=[m];for(c=0;c<g;c++){m+=((d=s[o[c]]).length+3&-4)>>>0;p.push(m)}var b=new Uint8Array(m);for(c=0;c<g;c++){d=s[o[c]];a(b,p[c],d)}"true"===n&&(n=(0,r.string32)(65536));b[0]=255&n.charCodeAt(0);b[1]=255&n.charCodeAt(1);b[2]=255&n.charCodeAt(2);b[3]=255&n.charCodeAt(3);e(b,4,g);var y=i.getSearchParams(g,16);e(b,6,y.range);e(b,8,y.entry);e(b,10,y.rangeShift);m=12;for(c=0;c<g;c++){f=o[c];b[m]=255&f.charCodeAt(0);b[m+1]=255&f.charCodeAt(1);b[m+2]=255&f.charCodeAt(2);b[m+3]=255&f.charCodeAt(3);var v=0;for(h=p[c],u=p[c+1];h<u;h+=4){v=v+(0,l.readUint32)(b,h)>>>0}t(b,m+4,v);t(b,m+8,p[c]);t(b,m+12,s[f].length);m+=16}return b},addTable:function(e,t){if(e in this.tables)throw new Error("Table "+e+" already exists");this.tables[e]=t}};return i}(),x=function(){function e(e,t,a){var i;this.name=e;this.loadedName=a.loadedName;this.isType3Font=a.isType3Font;this.sizes=[];this.missingFile=!1;this.glyphCache=Object.create(null);this.isSerifFont=!!(a.flags&m.Serif);this.isSymbolicFont=!!(a.flags&m.Symbolic);this.isMonospace=!!(a.flags&m.FixedPitch);var n=a.type,s=a.subtype;this.type=n;this.subtype=s;let o="sans-serif";this.isMonospace?o="monospace":this.isSerifFont&&(o="serif");this.fallbackName=o;this.differences=a.differences;this.widths=a.widths;this.defaultWidth=a.defaultWidth;this.composite=a.composite;this.wideChars=a.wideChars;this.cMap=a.cMap;this.ascent=a.ascent/1e3;this.descent=a.descent/1e3;this.fontMatrix=a.fontMatrix;this.bbox=a.bbox;this.defaultEncoding=a.defaultEncoding;this.toUnicode=a.toUnicode;this.fallbackToUnicode=a.fallbackToUnicode||new k;this.toFontChar=[];if("Type3"!==a.type){this.cidEncoding=a.cidEncoding;this.vertical=a.vertical;if(this.vertical){this.vmetrics=a.vmetrics;this.defaultVMetrics=a.defaultVMetrics}if(t&&!t.isEmpty){[n,s]=function(e,{type:t,subtype:a,composite:i}){let n,s;if(function(e){var t=e.peekBytes(4);return 65536===(0,l.readUint32)(t,0)||"true"===(0,r.bytesToString)(t)}(e)||I(e))n=i?"CIDFontType2":"TrueType";else if(function(e){var t=e.peekBytes(4);return"OTTO"===(0,r.bytesToString)(t)}(e))n=i?"CIDFontType2":"OpenType";else if(function(e){var t=e.peekBytes(2);if(37===t[0]&&33===t[1])return!0;if(128===t[0]&&1===t[1])return!0;return!1}(e))n=i?"CIDFontType0":"MMType1"===t?"MMType1":"Type1";else if(function(e){const t=e.peekBytes(4);if(t[0]>=1&&t[3]>=1&&t[3]<=4)return!0;return!1}(e))if(i){n="CIDFontType0";s="CIDFontType0C"}else{n="MMType1"===t?"MMType1":"Type1";s="Type1C"}else{(0,r.warn)("getFontFileType: Unable to detect correct font file Type/Subtype.");n=t;s=a}return[n,s]}(t,a);n===this.type&&s===this.subtype||(0,r.info)("Inconsistent font file Type/SubType, expected: "+`${this.type}/${this.subtype} but found: ${n}/${s}.`);try{var c;switch(n){case"MMType1":(0,r.info)("MMType1 font ("+e+"), falling back to Type1.");case"Type1":case"CIDFontType0":this.mimetype="font/opentype";var h="Type1C"===s||"CIDFontType0C"===s?new T(t,a):new F(e,t,a);b(a);c=this.convert(e,h,a);break;case"OpenType":case"TrueType":case"CIDFontType2":this.mimetype="font/opentype";c=this.checkAndRepair(e,t,a);if(this.isOpenType){b(a);n="OpenType"}break;default:throw new r.FormatError(`Font ${n} is not supported`)}}catch(e){(0,r.warn)(e);this.fallbackToSystemFont();return}this.data=c;this.fontType=y(n,s);this.fontMatrix=a.fontMatrix;this.widths=a.widths;this.defaultWidth=a.defaultWidth;this.toUnicode=a.toUnicode;this.encoding=a.baseEncoding;this.seacMap=a.seacMap}else{t&&(0,r.warn)('Font file is empty in "'+e+'" ('+this.loadedName+")");this.fallbackToSystemFont()}}else{for(i=0;i<256;i++)this.toFontChar[i]=this.differences[i]||a.defaultEncoding[i];this.fontType=r.FontType.TYPE3}}e.getFontID=(t=1,function(){return String(t++)});var t;function a(e,t){return(e<<8)+t}function f(e,t){var a=(e<<8)+t;return 32768&a?a-65536:a}function x(e){return String.fromCharCode(e>>8&255,255&e)}function A(e){e>32767?e=32767:e<-32768&&(e=-32768);return String.fromCharCode(e>>8&255,255&e)}function I(e){const t=e.peekBytes(4);return"ttcf"===(0,r.bytesToString)(t)}function E(e,t,a){for(var r,i=[],n=0,s=e.length;n<s;n++)-1!==(r=(0,c.getUnicodeForGlyph)(e[n],t))&&(i[n]=r);for(var o in a)-1!==(r=(0,c.getUnicodeForGlyph)(a[o],t))&&(i[+o]=r);return i}function O(e,t,a){var i=Object.create(null),n=[],s=0,o=g[s][0],c=g[s][1];for(var l in e){var h=e[l|=0];if(t(h)){if(o>c){if(++s>=g.length){(0,r.warn)("Ran out of space in font private use area.");break}o=g[s][0];c=g[s][1]}var u=o++;0===h&&(h=a);i[u]=h;n[l]=u}}return{toFontChar:n,charCodeToGlyphId:i,nextAvailableFontCharCode:o}}function P(e,t){var a,i,n,s,o=function(e,t){var a=[];for(var r in e)e[r]>=t||a.push({fontCharCode:0|r,glyphId:e[r]});0===a.length&&a.push({fontCharCode:0,glyphId:0});a.sort((function(e,t){return e.fontCharCode-t.fontCharCode}));for(var i=[],n=a.length,s=0;s<n;){var o=a[s].fontCharCode,c=[a[s].glyphId];++s;for(var l=o;s<n&&l+1===a[s].fontCharCode;){c.push(a[s].glyphId);++s;if(65535===++l)break}i.push([o,l,c])}return i}(e,t),c=o[o.length-1][1]>65535?2:1,l="\0\0"+x(c)+"\0\0"+(0,r.string32)(4+8*c);for(a=o.length-1;a>=0&&!(o[a][0]<=65535);--a);var h=a+1;o[a][0]<65535&&65535===o[a][1]&&(o[a][1]=65534);var u,d,f,g,m=o[a][1]<65535?1:0,p=h+m,b=C.getSearchParams(p,2),y="",v="",w="",k="",S="",A=0;for(a=0,i=h;a<i;a++){d=(u=o[a])[0];f=u[1];y+=x(d);v+=x(f);var I=!0;for(n=1,s=(g=u[2]).length;n<s;++n)if(g[n]!==g[n-1]+1){I=!1;break}if(I){w+=x(g[0]-d&65535);k+=x(0)}else{var F=2*(p-a)+2*A;A+=f-d+1;w+=x(0);k+=x(F);for(n=0,s=g.length;n<s;++n)S+=x(g[n])}}if(m>0){v+="ÿÿ";y+="ÿÿ";w+="\0";k+="\0\0"}var T="\0\0"+x(2*p)+x(b.range)+x(b.entry)+x(b.rangeShift)+v+"\0\0"+y+w+k+S,E="",O="";if(c>1){l+="\0\0\n"+(0,r.string32)(4+8*c+4+T.length);E="";for(a=0,i=o.length;a<i;a++){d=(u=o[a])[0];var P=(g=u[2])[0];for(n=1,s=g.length;n<s;++n)if(g[n]!==g[n-1]+1){f=u[0]+n-1;E+=(0,r.string32)(d)+(0,r.string32)(f)+(0,r.string32)(P);d=f+1;P=g[n]}E+=(0,r.string32)(d)+(0,r.string32)(u[1])+(0,r.string32)(P)}O="\0\f\0\0"+(0,r.string32)(E.length+16)+"\0\0\0\0"+(0,r.string32)(E.length/12)}return l+"\0"+x(T.length+4)+T+O+E}function B(e,t,a){a=a||{unitsPerEm:0,yMax:0,yMin:0,ascent:0,descent:0};var i=0,n=0,s=0,o=0,l=null,h=0;if(t){for(var u in t){(l>(u|=0)||!l)&&(l=u);h<u&&(h=u);var d=(0,c.getUnicodeRangeFor)(u);if(d<32)i|=1<<d;else if(d<64)n|=1<<d-32;else if(d<96)s|=1<<d-64;else{if(!(d<123))throw new r.FormatError("Unicode ranges Bits > 123 are reserved for internal usage");o|=1<<d-96}}h>65535&&(h=65535)}else{l=0;h=255}var f=e.bbox||[0,0,0,0],g=a.unitsPerEm||1/(e.fontMatrix||r.FONT_IDENTITY_MATRIX)[0],m=e.ascentScaled?1:g/1e3,p=a.ascent||Math.round(m*(e.ascent||f[3])),b=a.descent||Math.round(m*(e.descent||f[1]));b>0&&e.descent>0&&f[1]<0&&(b=-b);var y=a.yMax||p,v=-a.yMin||-b;return"\0$ô\0\0\0Š»\0\0\0ŒŠ»\0\0ß\x001\0\0\0\0"+String.fromCharCode(e.fixedPitch?9:0)+"\0\0\0\0\0\0"+(0,r.string32)(i)+(0,r.string32)(n)+(0,r.string32)(s)+(0,r.string32)(o)+"*21*"+x(e.italicAngle?1:0)+x(l||e.firstChar)+x(h||e.lastChar)+x(p)+x(b)+"\0d"+x(y)+x(v)+"\0\0\0\0\0\0\0\0"+x(e.xHeight)+x(e.capHeight)+x(0)+x(l||e.firstChar)+"\0"}function D(e){var t=Math.floor(65536*e.italicAngle);return"\0\0\0"+(0,r.string32)(t)+"\0\0\0\0"+(0,r.string32)(e.fixedPitch)+"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}function N(e,t){t||(t=[[],[]]);var a,r,i,n,s,o=[t[0][0]||"Original licence",t[0][1]||e,t[0][2]||"Unknown",t[0][3]||"uniqueID",t[0][4]||e,t[0][5]||"Version 0.11",t[0][6]||"",t[0][7]||"Unknown",t[0][8]||"Unknown",t[0][9]||"Unknown"],c=[];for(a=0,r=o.length;a<r;a++){var l=[];for(i=0,n=(s=t[1][a]||o[a]).length;i<n;i++)l.push(x(s.charCodeAt(i)));c.push(l.join(""))}var h=[o,c],u=["\0","\0"],d=["\0\0","\0"],f=["\0\0","\t"],g=o.length*u.length,m="\0\0"+x(g)+x(12*g+6),p=0;for(a=0,r=u.length;a<r;a++){var b=h[a];for(i=0,n=b.length;i<n;i++){s=b[i];m+=u[a]+d[a]+f[a]+x(i)+x(s.length)+x(p);p+=s.length}}return m+=o.join("")+c.join("")}e.prototype={name:null,font:null,mimetype:null,encoding:null,disableFontFace:!1,get renderer(){var e=h.FontRendererFactory.create(this,!0);return(0,r.shadow)(this,"renderer",e)},exportData:function(){var e={};for(var t in this)this.hasOwnProperty(t)&&(e[t]=this[t]);return e},fallbackToSystemFont:function(){this.missingFile=!0;var e,t,a=this.name,i=this.type,l=this.subtype;let h=a.replace(/[,_]/g,"-").replace(/\s/g,"");var u=(0,o.getStdFontMap)(),d=(0,o.getNonStdFontMap)(),f=!!u[h]||!(!d[h]||!u[d[h]]);h=u[h]||d[h]||h;this.bold=-1!==h.search(/bold/gi);this.italic=-1!==h.search(/oblique/gi)||-1!==h.search(/italic/gi);this.black=-1!==a.search(/Black/g);this.remeasure=Object.keys(this.widths).length>0;if(f&&"CIDFontType2"===i&&this.cidEncoding.startsWith("Identity-")){const t=(0,o.getGlyphMapForStandardFonts)(),r=[];for(e in t)r[+e]=t[e];if(/Arial-?Black/i.test(a)){var g=(0,o.getSupplementalGlyphMapForArialBlack)();for(e in g)r[+e]=g[e]}else if(/Calibri/i.test(a)){const t=(0,o.getSupplementalGlyphMapForCalibri)();for(e in t)r[+e]=t[e]}this.toUnicode instanceof S||this.toUnicode.forEach((function(e,t){r[+e]=t}));this.toFontChar=r;this.toUnicode=new k(r)}else if(/Symbol/i.test(h))this.toFontChar=E(s.SymbolSetEncoding,(0,n.getGlyphsUnicode)(),this.differences);else if(/Dingbats/i.test(h)){/Wingdings/i.test(a)&&(0,r.warn)("Non-embedded Wingdings font, falling back to ZapfDingbats.");this.toFontChar=E(s.ZapfDingbatsEncoding,(0,n.getDingbatsGlyphsUnicode)(),this.differences)}else if(f)this.toFontChar=E(this.defaultEncoding,(0,n.getGlyphsUnicode)(),this.differences);else{const r=(0,n.getGlyphsUnicode)(),i=[];this.toUnicode.forEach((e,a)=>{if(!this.composite){var n=this.differences[e]||this.defaultEncoding[e];-1!==(t=(0,c.getUnicodeForGlyph)(n,r))&&(a=t)}i[+e]=a});if(this.composite&&this.toUnicode instanceof S&&/Verdana/i.test(a)){const t=(0,o.getGlyphMapForStandardFonts)();for(e in t)i[+e]=t[e]}this.toFontChar=i}this.loadedName=h.split("-")[0];this.fontType=y(i,l)},checkAndRepair:function(e,t,o){const c=["OS/2","cmap","head","hhea","hmtx","maxp","name","post","loca","glyf","fpgm","prep","cvt ","CFF "];function l(e,a){const r=Object.create(null);r["OS/2"]=null;r.cmap=null;r.head=null;r.hhea=null;r.hmtx=null;r.maxp=null;r.name=null;r.post=null;for(let e=0;e<a;e++){const e=h(t);c.includes(e.tag)&&(0!==e.length&&(r[e.tag]=e))}return r}function h(e){var t=(0,r.bytesToString)(e.getBytes(4)),a=e.getInt32()>>>0,i=e.getInt32()>>>0,n=e.getInt32()>>>0,s=e.pos;e.pos=e.start?e.start:0;e.skip(i);var o=e.getBytes(n);e.pos=s;if("head"===t){o[8]=o[9]=o[10]=o[11]=0;o[17]|=32}return{tag:t,checksum:a,length:n,offset:i,data:o}}function g(e){return{version:(0,r.bytesToString)(e.getBytes(4)),numTables:e.getUint16(),searchRange:e.getUint16(),entrySelector:e.getUint16(),rangeShift:e.getUint16()}}function m(e,t,a,r,i,n){var s={length:0,sizeOfInstructions:0};if(a-t<=12)return s;var o=e.subarray(t,a),c=f(o[0],o[1]);if(c<0){!function(e,t,a){e[t+1]=a;e[t]=a>>>8}(o,0,c=-1);r.set(o,i);s.length=o.length;return s}var l,h=10,u=0;for(l=0;l<c;l++){u=(o[h]<<8|o[h+1])+1;h+=2}var d=h,g=o[h]<<8|o[h+1];s.sizeOfInstructions=g;var m=h+=2+g,p=0;for(l=0;l<u;l++){var b=o[h++];192&b&&(o[h-1]=63&b);let e=2;2&b?e=1:16&b&&(e=0);let t=2;4&b?t=1:32&b&&(t=0);const a=e+t;p+=a;if(8&b){var y=o[h++];l+=y;p+=y*a}}if(0===p)return s;var v=h+p;if(v>o.length)return s;if(!n&&g>0){r.set(o.subarray(0,d),i);r.set([0,0],i+d);r.set(o.subarray(m,v),i+d+2);v-=g;o.length-v>3&&(v=v+3&-4);s.length=v;return s}if(o.length-v>3){v=v+3&-4;r.set(o.subarray(0,v),i);s.length=v;return s}r.set(o,i);s.length=o.length;return s}function y(e){var a=(t.start?t.start:0)+e.offset;t.pos=a;var i=[[],[]],n=e.length,s=a+n;if(0!==t.getUint16()||n<6)return i;var o,c,l=t.getUint16(),h=t.getUint16(),u=[];for(o=0;o<l&&t.pos+12<=s;o++){var d={platform:t.getUint16(),encoding:t.getUint16(),language:t.getUint16(),name:t.getUint16(),length:t.getUint16(),offset:t.getUint16()};(1===d.platform&&0===d.encoding&&0===d.language||3===d.platform&&1===d.encoding&&1033===d.language)&&u.push(d)}for(o=0,c=u.length;o<c;o++){var f=u[o];if(!(f.length<=0)){var g=a+h+f.offset;if(!(g+f.length>s)){t.pos=g;var m=f.name;if(f.encoding){for(var p="",b=0,y=f.length;b<y;b+=2)p+=String.fromCharCode(t.getUint16());i[1][m]=p}else i[0][m]=(0,r.bytesToString)(t.getBytes(f.length))}}}return i}var w=[0,0,0,0,0,0,0,0,-2,-2,-2,-2,0,0,-2,-5,-1,-1,-1,-1,-1,-1,-1,-1,0,0,-1,0,-1,-1,-1,-1,1,-1,-999,0,1,0,-1,-2,0,-1,-2,-1,-1,0,-1,-1,0,0,-999,-999,-1,-1,-1,-1,-2,-999,-2,-2,-999,0,-2,-2,0,0,-2,0,-2,0,0,0,-2,-1,-1,1,1,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,-1,0,-1,-1,0,-999,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,-2,-999,-999,-999,-999,-999,-1,-1,-2,-2,0,0,0,0,-1,-1,-999,-2,-2,0,0,-1,-2,-2,0,0,0,-1,-1,-1,-2];function k(e,t){for(var a,i,n,s,o,c=e.data,l=0,h=0,u=0,d=[],f=[],g=[],m=t.tooComplexToFollowFunctions,p=!1,b=0,y=0,v=c.length;l<v;){var k=c[l++];if(64===k){i=c[l++];if(p||y)l+=i;else for(a=0;a<i;a++)d.push(c[l++])}else if(65===k){i=c[l++];if(p||y)l+=2*i;else for(a=0;a<i;a++){n=c[l++];d.push(n<<8|c[l++])}}else if(176==(248&k)){i=k-176+1;if(p||y)l+=i;else for(a=0;a<i;a++)d.push(c[l++])}else if(184==(248&k)){i=k-184+1;if(p||y)l+=2*i;else for(a=0;a<i;a++){n=c[l++];d.push(n<<8|c[l++])}}else if(43!==k||m)if(44!==k||m){if(45===k)if(p){p=!1;h=l}else{if(!(o=f.pop())){(0,r.warn)("TT: ENDF bad stack");t.hintsValid=!1;return}s=g.pop();c=o.data;l=o.i;t.functionsStackDeltas[s]=d.length-o.stackTop}else if(137===k){if(p||y){(0,r.warn)("TT: nested IDEFs not allowed");m=!0}p=!0;u=l}else if(88===k)++b;else if(27===k)y=b;else if(89===k){y===b&&(y=0);--b}else if(28===k&&!p&&!y){var S=d[d.length-1];S>0&&(l+=S-1)}}else{if(p||y){(0,r.warn)("TT: nested FDEFs not allowed");m=!0}p=!0;u=l;s=d.pop();t.functionsDefined[s]={data:c,i:l}}else if(!p&&!y){s=d[d.length-1];if(isNaN(s))(0,r.info)("TT: CALL empty stack (or invalid entry).");else{t.functionsUsed[s]=!0;if(s in t.functionsStackDeltas){const e=d.length+t.functionsStackDeltas[s];if(e<0){(0,r.warn)("TT: CALL invalid functions stack delta.");t.hintsValid=!1;return}d.length=e}else if(s in t.functionsDefined&&!g.includes(s)){f.push({data:c,i:l,stackTop:d.length-1});g.push(s);if(!(o=t.functionsDefined[s])){(0,r.warn)("TT: CALL non-existent function");t.hintsValid=!1;return}c=o.data;l=o.i}}}if(!p&&!y){let e=0;k<=142?e=w[k]:k>=192&&k<=223?e=-1:k>=224&&(e=-2);if(k>=113&&k<=117){i=d.pop();isNaN(i)||(e=2*-i)}for(;e<0&&d.length>0;){d.pop();e++}for(;e>0;){d.push(NaN);e--}}}t.tooComplexToFollowFunctions=m;var C=[c];l>c.length&&C.push(new Uint8Array(l-c.length));if(u>h){(0,r.warn)("TT: complementing a missing function tail");C.push(new Uint8Array([34,45]))}!function(e,t){if(t.length>1){var a,r,i=0;for(a=0,r=t.length;a<r;a++)i+=t[a].length;i=i+3&-4;var n=new Uint8Array(i),s=0;for(a=0,r=t.length;a<r;a++){n.set(t[a],s);s+=t[a].length}e.data=n;e.length=i}}(e,C)}let S,x,A,F;if(I(t=new d.Stream(new Uint8Array(t.getBytes())))){const e=function(e,t){const{numFonts:a,offsetTable:i}=function(e){const t=(0,r.bytesToString)(e.getBytes(4));(0,r.assert)("ttcf"===t,"Must be a TrueType Collection font.");const a=e.getUint16(),i=e.getUint16(),n=e.getInt32()>>>0,s=[];for(let t=0;t<n;t++)s.push(e.getInt32()>>>0);const o={ttcTag:t,majorVersion:a,minorVersion:i,numFonts:n,offsetTable:s};switch(a){case 1:return o;case 2:o.dsigTag=e.getInt32()>>>0;o.dsigLength=e.getInt32()>>>0;o.dsigOffset=e.getInt32()>>>0;return o}throw new r.FormatError(`Invalid TrueType Collection majorVersion: ${a}.`)}(e);for(let n=0;n<a;n++){e.pos=(e.start||0)+i[n];const a=g(e),s=l(0,a.numTables);if(!s.name)throw new r.FormatError('TrueType Collection font must contain a "name" table.');const o=y(s.name);for(let e=0,r=o.length;e<r;e++)for(let r=0,i=o[e].length;r<i;r++){const i=o[e][r];if(i&&i.replace(/\s/g,"")===t)return{header:a,tables:s}}}throw new r.FormatError(`TrueType Collection does not contain "${t}" font.`)}(t,this.name);S=e.header;x=e.tables}else{S=g(t);x=l(0,S.numTables)}var E=!x["CFF "];if(E){if(!x.loca)throw new r.FormatError('Required "loca" table is not found');if(!x.glyf){(0,r.warn)('Required "glyf" table is not found -- trying to recover.');x.glyf={tag:"glyf",data:new Uint8Array(0)}}this.isOpenType=!1}else{const t=o.composite&&((o.cidToGidMap||[]).length>0||!(o.cMap instanceof u.IdentityCMap));if("OTTO"===S.version&&!t||!x.head||!x.hhea||!x.maxp||!x.post){F=new d.Stream(x["CFF "].data);A=new T(F,o);b(o);return this.convert(e,A,o)}delete x.glyf;delete x.loca;delete x.fpgm;delete x.prep;delete x["cvt "];this.isOpenType=!0}if(!x.maxp)throw new r.FormatError('Required "maxp" table is not found');t.pos=(t.start||0)+x.maxp.offset;var M=t.getInt32();const L=t.getUint16();let R=L+1,U=!0;if(R>65535){U=!1;R=L;(0,r.warn)("Not enough space in glyfs to duplicate first glyph.")}var q=0,j=0;if(M>=65536&&x.maxp.length>=22){t.pos+=8;if(t.getUint16()>2){x.maxp.data[14]=0;x.maxp.data[15]=2}t.pos+=4;q=t.getUint16();t.pos+=4;j=t.getUint16()}x.maxp.data[4]=R>>8;x.maxp.data[5]=255&R;var _=function(e,t,a,i){var n={functionsDefined:[],functionsUsed:[],functionsStackDeltas:[],tooComplexToFollowFunctions:!1,hintsValid:!0};e&&k(e,n);t&&k(t,n);e&&function(e,t){if(!e.tooComplexToFollowFunctions)if(e.functionsDefined.length>t){(0,r.warn)("TT: more functions defined than expected");e.hintsValid=!1}else for(var a=0,i=e.functionsUsed.length;a<i;a++){if(a>t){(0,r.warn)("TT: invalid function id: "+a);e.hintsValid=!1;return}if(e.functionsUsed[a]&&!e.functionsDefined[a]){(0,r.warn)("TT: undefined function: "+a);e.hintsValid=!1;return}}}(n,i);if(a&&1&a.length){var s=new Uint8Array(a.length+1);s.set(a.data);a.data=s}return n.hintsValid}(x.fpgm,x.prep,x["cvt "],q);if(!_){delete x.fpgm;delete x.prep;delete x["cvt "]}!function(e,t,a,i,n){if(t){e.pos=(e.start?e.start:0)+t.offset;e.pos+=4;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=8;e.pos+=2;var s=e.getUint16();if(s>i){(0,r.info)("The numOfMetrics ("+s+") should not be greater than the numGlyphs ("+i+")");s=i;t.data[34]=(65280&s)>>8;t.data[35]=255&s}var o=i-s-(a.length-4*s>>1);if(o>0){var c=new Uint8Array(a.length+2*o);c.set(a.data);if(n){c[a.length]=a.data[2];c[a.length+1]=a.data[3]}a.data=c}}else a&&(a.data=null)}(t,x.hhea,x.hmtx,R,U);if(!x.head)throw new r.FormatError('Required "head" table is not found');!function(e,t,i){var n,s,o,c,l=e.data,h=(n=l[0],s=l[1],o=l[2],c=l[3],(n<<24)+(s<<16)+(o<<8)+c);if(h>>16!=1){(0,r.info)("Attempting to fix invalid version in head table: "+h);l[0]=0;l[1]=1;l[2]=0;l[3]=0}var u=a(l[50],l[51]);if(u<0||u>1){(0,r.info)("Attempting to fix invalid indexToLocFormat in head table: "+u);var d=t+1;if(i===d<<1){l[50]=0;l[51]=0}else{if(i!==d<<2)throw new r.FormatError("Could not fix indexToLocFormat: "+u);l[50]=0;l[51]=1}}}(x.head,L,E?x.loca.length:0);var z=Object.create(null);if(E){var H=a(x.head.data[50],x.head.data[51]),G=function(e,t,a,r,i,n,s){var o,c,l;if(r){o=4;c=function(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]};l=function(e,t,a){e[t]=a>>>24&255;e[t+1]=a>>16&255;e[t+2]=a>>8&255;e[t+3]=255&a}}else{o=2;c=function(e,t){return e[t]<<9|e[t+1]<<1};l=function(e,t,a){e[t]=a>>9&255;e[t+1]=a>>1&255}}var h=n?a+1:a,u=o*(1+h),d=new Uint8Array(u);d.set(e.data.subarray(0,u));e.data=d;var f,g,p=t.data,b=p.length,y=new Uint8Array(b),v=c(d,0),w=0,k=Object.create(null);l(d,0,w);for(f=0,g=o;f<a;f++,g+=o){var S=c(d,g);0===S&&(S=v);S>b&&(b+3&-4)===S&&(S=b);S>b&&(v=S);var C=m(p,v,S,y,w,i),x=C.length;0===x&&(k[f]=!0);C.sizeOfInstructions>s&&(s=C.sizeOfInstructions);l(d,g,w+=x);v=S}if(0===w){var A=new Uint8Array([0,1,0,0,0,0,0,0,0,0,0,0,0,0,49,0]);for(f=0,g=o;f<h;f++,g+=o)l(d,g,A.length);t.data=A}else if(n){var I=c(d,o);if(y.length>I+w)t.data=y.subarray(0,I+w);else{t.data=new Uint8Array(I+w);t.data.set(y.subarray(0,w))}t.data.set(y.subarray(0,I),w);l(e.data,d.length-o,w+I)}else t.data=y.subarray(0,w);return{missingGlyphs:k,maxSizeOfInstructions:s}}(x.loca,x.glyf,L,H,_,U,j);z=G.missingGlyphs;if(M>=65536&&x.maxp.length>=22){x.maxp.data[26]=G.maxSizeOfInstructions>>8;x.maxp.data[27]=255&G.maxSizeOfInstructions}}if(!x.hhea)throw new r.FormatError('Required "hhea" table is not found');if(0===x.hhea.data[10]&&0===x.hhea.data[11]){x.hhea.data[10]=255;x.hhea.data[11]=255}var W={unitsPerEm:a(x.head.data[18],x.head.data[19]),yMax:a(x.head.data[42],x.head.data[43]),yMin:f(x.head.data[38],x.head.data[39]),ascent:a(x.hhea.data[4],x.hhea.data[5]),descent:f(x.hhea.data[6],x.hhea.data[7])};this.ascent=W.ascent/W.unitsPerEm;this.descent=W.descent/W.unitsPerEm;x.post&&function(e,a,i){var n=(t.start?t.start:0)+e.offset;t.pos=n;var s,o=n+e.length,c=t.getInt32();t.getBytes(28);var l,h=!0;switch(c){case 65536:s=p;break;case 131072:var u=t.getUint16();if(u!==i){h=!1;break}var d=[];for(l=0;l<u;++l){var f=t.getUint16();if(f>=32768){h=!1;break}d.push(f)}if(!h)break;for(var g=[],m=[];t.pos<o;){var b=t.getByte();m.length=b;for(l=0;l<b;++l)m[l]=String.fromCharCode(t.getByte());g.push(m.join(""))}s=[];for(l=0;l<u;++l){var y=d[l];y<258?s.push(p[y]):s.push(g[y-258])}break;case 196608:break;default:(0,r.warn)("Unknown/unsupported post table version "+c);h=!1;a.defaultEncoding&&(s=a.defaultEncoding)}a.glyphNames=s}(x.post,o,L);x.post={tag:"post",data:D(o)};var X,V=[];function K(e){return!z[e]}if(o.composite){var Y=o.cidToGidMap||[],$=0===Y.length;o.cMap.forEach((function(e,t){if(t>65535)throw new r.FormatError("Max size of CID is 65,535");var a=-1;$?a=t:void 0!==Y[t]&&(a=Y[t]);a>=0&&a<L&&K(a)&&(V[e]=a)}))}else{var J=function(e,t,a,i){if(!e){(0,r.warn)("No cmap table available.");return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}var n,s=(t.start?t.start:0)+e.offset;t.pos=s;t.getUint16();for(var o,c=t.getUint16(),l=!1,h=0;h<c;h++){var u=t.getUint16(),d=t.getUint16(),f=t.getInt32()>>>0,g=!1;if(!o||o.platformId!==u||o.encodingId!==d){if(0===u&&0===d)g=!0;else if(1===u&&0===d)g=!0;else if(3!==u||1!==d||!i&&o){if(a&&3===u&&0===d){g=!0;l=!0}}else{g=!0;a||(l=!0)}g&&(o={platformId:u,encodingId:d,offset:f});if(l)break}}o&&(t.pos=s+o.offset);if(!o||-1===t.peekByte()){(0,r.warn)("Could not find a preferred cmap table.");return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}var m=t.getUint16();t.getUint16();t.getUint16();var p,b,y=!1,v=[];if(0===m){for(p=0;p<256;p++){var w=t.getByte();w&&v.push({charCode:p,glyphId:w})}y=!0}else if(4===m){var k=t.getUint16()>>1;t.getBytes(6);var S,C=[];for(S=0;S<k;S++)C.push({end:t.getUint16()});t.getUint16();for(S=0;S<k;S++)C[S].start=t.getUint16();for(S=0;S<k;S++)C[S].delta=t.getUint16();var x=0;for(S=0;S<k;S++){n=C[S];var A=t.getUint16();if(A){var I=(A>>1)-(k-S);n.offsetIndex=I;x=Math.max(x,I+n.end-n.start+1)}else n.offsetIndex=-1}var F=[];for(p=0;p<x;p++)F.push(t.getUint16());for(S=0;S<k;S++){s=(n=C[S]).start;var T=n.end,E=n.delta;I=n.offsetIndex;for(p=s;p<=T;p++)if(65535!==p){b=(b=I<0?p:F[I+p-s])+E&65535;v.push({charCode:p,glyphId:b})}}}else{if(6!==m){(0,r.warn)("cmap table has unsupported format: "+m);return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}var O=t.getUint16(),P=t.getUint16();for(p=0;p<P;p++){b=t.getUint16();var B=O+p;v.push({charCode:B,glyphId:b})}}v.sort((function(e,t){return e.charCode-t.charCode}));for(h=1;h<v.length;h++)if(v[h-1].charCode===v[h].charCode){v.splice(h,1);h--}return{platformId:o.platformId,encodingId:o.encodingId,mappings:v,hasShortCmap:y}}(x.cmap,t,this.isSymbolicFont,o.hasEncoding),Z=J.platformId,Q=J.encodingId,ee=J.mappings,te=ee.length;if(o.hasEncoding&&(3===Z&&1===Q||1===Z&&0===Q)||-1===Z&&-1===Q&&(0,s.getEncoding)(o.baseEncodingName)){var ae=[];"MacRomanEncoding"!==o.baseEncodingName&&"WinAnsiEncoding"!==o.baseEncodingName||(ae=(0,s.getEncoding)(o.baseEncodingName));var re=(0,n.getGlyphsUnicode)();for(X=0;X<256;X++){var ie,ne;if(ie=this.differences&&X in this.differences?this.differences[X]:X in ae&&""!==ae[X]?ae[X]:s.StandardEncoding[X]){ne=v(ie,re);var se;3===Z&&1===Q?se=re[ne]:1===Z&&0===Q&&(se=s.MacRomanEncoding.indexOf(ne));var oe=!1;for(let e=0;e<te;++e)if(ee[e].charCode===se){V[X]=ee[e].glyphId;oe=!0;break}if(!oe&&o.glyphNames){var ce=o.glyphNames.indexOf(ie);-1===ce&&ne!==ie&&(ce=o.glyphNames.indexOf(ne));ce>0&&K(ce)&&(V[X]=ce)}}}}else if(0===Z&&0===Q)for(let e=0;e<te;++e)V[ee[e].charCode]=ee[e].glyphId;else for(let e=0;e<te;++e){X=ee[e].charCode;3===Z&&X>=61440&&X<=61695&&(X&=255);V[X]=ee[e].glyphId}}0===V.length&&(V[0]=0);let le=R-1;U||(le=0);var he=O(V,K,le);this.toFontChar=he.toFontChar;x.cmap={tag:"cmap",data:P(he.charCodeToGlyphId,R)};x["OS/2"]&&function(e){var t=new d.Stream(e.data),a=t.getUint16();t.getBytes(60);var r=t.getUint16();if(a<4&&768&r)return!1;if(t.getUint16()>t.getUint16())return!1;t.getBytes(6);if(0===t.getUint16())return!1;e.data[8]=e.data[9]=0;return!0}(x["OS/2"])||(x["OS/2"]={tag:"OS/2",data:B(o,he.charCodeToGlyphId,W)});if(!E)try{F=new d.Stream(x["CFF "].data);A=new i.CFFParser(F,o,!0).parse();A.duplicateFirstGlyph();var ue=new i.CFFCompiler(A);x["CFF "].data=ue.compile()}catch(e){(0,r.warn)("Failed to compile font "+o.loadedName)}if(x.name){var de=y(x.name);x.name.data=N(e,de)}else x.name={tag:"name",data:N(this.name)};var fe=new C(S.version);for(var ge in x)fe.addTable(ge,x[ge].data);return fe.toArray()},convert:function(e,t,a){a.fixedPitch=!1;a.builtInEncoding&&function(e,t){if(!e.hasIncludedToUnicodeMap&&!(e.hasEncoding||t===e.defaultEncoding||e.toUnicode instanceof S)){var a=[],r=(0,n.getGlyphsUnicode)();for(var i in t){var s=t[i],o=(0,c.getUnicodeForGlyph)(s,r);-1!==o&&(a[i]=String.fromCharCode(o))}e.toUnicode.amend(a)}}(a,a.builtInEncoding);let i=1;t instanceof T&&(i=t.numGlyphs-1);var o=t.getGlyphMapping(a),l=O(o,t.hasGlyphId.bind(t),i);this.toFontChar=l.toFontChar;var h=t.numGlyphs;function u(e,t){var a=null;for(var r in e)if(t===e[r]){a||(a=[]);a.push(0|r)}return a}function d(e,t){for(var a in e)if(t===e[a])return 0|a;l.charCodeToGlyphId[l.nextAvailableFontCharCode]=t;return l.nextAvailableFontCharCode++}var f=t.seacs;if(f&&f.length){var g=a.fontMatrix||r.FONT_IDENTITY_MATRIX,m=t.getCharset(),p=Object.create(null);for(var b in f){var y=f[b|=0],v=s.StandardEncoding[y[2]],w=s.StandardEncoding[y[3]],k=m.indexOf(v),I=m.indexOf(w);if(!(k<0||I<0)){var F={x:y[0]*g[0]+y[1]*g[2]+g[4],y:y[0]*g[1]+y[1]*g[3]+g[5]},E=u(o,b);if(E)for(var M=0,L=E.length;M<L;M++){var R=E[M],U=l.charCodeToGlyphId,q=d(U,k),j=d(U,I);p[R]={baseFontCharCode:q,accentFontCharCode:j,accentOffset:F}}}}a.seacMap=p}var _=1/(a.fontMatrix||r.FONT_IDENTITY_MATRIX)[0],z=new C("OTTO");z.addTable("CFF ",t.data);z.addTable("OS/2",B(a,l.charCodeToGlyphId));z.addTable("cmap",P(l.charCodeToGlyphId,h));z.addTable("head","\0\0\0\0\0\0\0\0\0\0_<õ\0\0"+A(_)+"\0\0\0\0ž\v~'\0\0\0\0ž\v~'\0\0"+A(a.descent)+"ÿ"+A(a.ascent)+x(a.italicAngle?2:0)+"\0\0\0\0\0\0\0");z.addTable("hhea","\0\0\0"+A(a.ascent)+A(a.descent)+"\0\0ÿÿ\0\0\0\0\0\0"+A(a.capHeight)+A(Math.tan(a.italicAngle)*a.xHeight)+"\0\0\0\0\0\0\0\0\0\0\0\0"+x(h));z.addTable("hmtx",function(){for(var e=t.charstrings,a=t.cff?t.cff.widths:null,r="\0\0\0\0",i=1,n=h;i<n;i++){var s=0;if(e){var o=e[i-1];s="width"in o?o.width:0}else a&&(s=Math.ceil(a[i]||0));r+=x(s)+x(0)}return r}());z.addTable("maxp","\0\0P\0"+x(h));z.addTable("name",N(e));z.addTable("post",D(a));return z.toArray()},get spaceWidth(){if("_shadowWidth"in this)return this._shadowWidth;for(var e,t=["space","minus","one","i","I"],a=0,r=t.length;a<r;a++){var i=t[a];if(i in this.widths){e=this.widths[i];break}var s=(0,n.getGlyphsUnicode)()[i],o=0;this.composite&&this.cMap.contains(s)&&(o=this.cMap.lookup(s));!o&&this.toUnicode&&(o=this.toUnicode.charCodeOf(s));o<=0&&(o=s);if(e=this.widths[o])break}e=e||this.defaultWidth;this._shadowWidth=e;return e},charToGlyph:function(e,t){var a,i,n,s=e;this.cMap&&this.cMap.contains(e)&&(s=this.cMap.lookup(e));i=this.widths[s];i=(0,r.isNum)(i)?i:this.defaultWidth;var o=this.vmetrics&&this.vmetrics[s];let l=this.toUnicode.get(e)||this.fallbackToUnicode.get(e)||e;"number"==typeof l&&(l=String.fromCharCode(l));var h=e in this.toFontChar;a=this.toFontChar[e]||e;if(this.missingFile){const t=this.differences[e]||this.defaultEncoding[e];".notdef"!==t&&""!==t||"Type1"!==this.type||(a=32);a=(0,c.mapSpecialUnicodeValues)(a)}this.isType3Font&&(n=a);var u=null;if(this.seacMap&&this.seacMap[e]){h=!0;var d=this.seacMap[e];a=d.baseFontCharCode;u={fontChar:String.fromCodePoint(d.accentFontCharCode),offset:d.accentOffset}}var f="number"==typeof a?String.fromCodePoint(a):"",g=this.glyphCache[e];if(!g||!g.matchesForCache(f,l,u,i,o,n,t,h)){g=new w(f,l,u,i,o,n,t,h);this.glyphCache[e]=g}return g},charsToGlyphs:function(e){var t,a,r,i=this.charsCache;if(i&&(t=i[e]))return t;i||(i=this.charsCache=Object.create(null));t=[];var n,s=e,o=0;if(this.cMap)for(var c=Object.create(null);o<e.length;){this.cMap.readCharCode(e,o,c);r=c.charcode;var l=c.length;o+=l;var h=1===l&&32===e.charCodeAt(o-1);a=this.charToGlyph(r,h);t.push(a)}else for(o=0,n=e.length;o<n;++o){r=e.charCodeAt(o);a=this.charToGlyph(r,32===r);t.push(a)}return i[s]=t},get glyphCacheValues(){return Object.values(this.glyphCache)}};return e}();t.Font=x;var A=function(){function e(e){this.error=e;this.loadedName="g_font_error";this.missingFile=!0}e.prototype={charsToGlyphs:function(){return[]},exportData:function(){return{error:this.error}}};return e}();t.ErrorFont=A;function I(e,t,a){var r,i,o,c=Object.create(null),l=!!(e.flags&m.Symbolic);if(e.baseEncodingName){o=(0,s.getEncoding)(e.baseEncodingName);for(i=0;i<o.length;i++){r=a.indexOf(o[i]);c[i]=r>=0?r:0}}else if(l)for(i in t)c[i]=t[i];else{o=s.StandardEncoding;for(i=0;i<o.length;i++){r=a.indexOf(o[i]);c[i]=r>=0?r:0}}var h,u=e.differences;if(u)for(i in u){var d=u[i];if(-1===(r=a.indexOf(d))){h||(h=(0,n.getGlyphsUnicode)());var f=v(d,h);f!==d&&(r=a.indexOf(f))}c[i]=r>=0?r:0}return c}var F=function(){function e(e,t,a){for(var r,i=e.length,n=t.length,s=i-n,o=a,c=!1;o<s;){r=0;for(;r<n&&e[o+r]===t[r];)r++;if(r>=n){o+=r;for(;o<i&&(0,l.isWhiteSpace)(e[o]);)o++;c=!0;break}o++}return{found:c,length:o}}function t(t,a,i){var n=i.length1,s=(i.length2,a.peekBytes(6)),o=128===s[0]&&1===s[1];if(o){a.skip(6);n=s[5]<<24|s[4]<<16|s[3]<<8|s[2]}var c=function(t,a){var i,n,s,o,c=[101,101,120,101,99],h=t.pos;try{n=(i=t.getBytes(a)).length}catch(e){if(e instanceof l.MissingDataException)throw e}if(n===a&&(s=e(i,c,a-2*c.length)).found&&s.length===a)return{stream:new d.Stream(i),length:a};(0,r.warn)('Invalid "Length1" property in Type1 font -- trying to recover.');t.pos=h;for(;;){if(0===(s=e(t.peekBytes(2048),c,0)).length)break;t.pos+=s.length;if(s.found){o=t.pos-h;break}}t.pos=h;if(o)return{stream:new d.Stream(t.getBytes(o)),length:o};(0,r.warn)('Unable to recover "Length1" property in Type1 font -- using as is.');return{stream:new d.Stream(t.getBytes(a)),length:a}}(a,n);new f.Type1Parser(c.stream,!1,!0).extractFontHeader(i);o&&(s=a.getBytes(6))[5]<<24|s[4]<<16|s[3]<<8|s[2];var h,u=(h=a.getBytes(),{stream:new d.Stream(h),length:h.length}),g=new f.Type1Parser(u.stream,!0,!0).extractFontProgram(i);for(var m in g.properties)i[m]=g.properties[m];var p=g.charstrings,b=this.getType2Charstrings(p),y=this.getType2Subrs(g.subrs);this.charstrings=p;this.data=this.wrap(t,b,this.charstrings,y,i);this.seacs=this.getSeacs(g.charstrings)}t.prototype={get numGlyphs(){return this.charstrings.length+1},getCharset:function(){for(var e=[".notdef"],t=this.charstrings,a=0;a<t.length;a++)e.push(t[a].glyphName);return e},getGlyphMapping:function(e){var t,a=this.charstrings,r=[".notdef"];for(t=0;t<a.length;t++)r.push(a[t].glyphName);var i=e.builtInEncoding;if(i){var n=Object.create(null);for(var s in i)(t=r.indexOf(i[s]))>=0&&(n[s]=t)}return I(e,n,r)},hasGlyphId:function(e){return!(e<0||e>=this.numGlyphs)&&(0===e||this.charstrings[e-1].charstring.length>0)},getSeacs:function(e){var t,a,r=[];for(t=0,a=e.length;t<a;t++){var i=e[t];i.seac&&(r[t+1]=i.seac)}return r},getType2Charstrings:function(e){for(var t=[],a=0,r=e.length;a<r;a++)t.push(e[a].charstring);return t},getType2Subrs:function(e){var t=0,a=e.length;t=a<1133?107:a<33769?1131:32768;var r,i=[];for(r=0;r<t;r++)i.push([11]);for(r=0;r<a;r++)i.push(e[r]);return i},wrap:function(e,t,a,r,n){var s=new i.CFF;s.header=new i.CFFHeader(1,0,4,4);s.names=[e];var o=new i.CFFTopDict;o.setByName("version",391);o.setByName("Notice",392);o.setByName("FullName",393);o.setByName("FamilyName",394);o.setByName("Weight",395);o.setByName("Encoding",null);o.setByName("FontMatrix",n.fontMatrix);o.setByName("FontBBox",n.bbox);o.setByName("charset",null);o.setByName("CharStrings",null);o.setByName("Private",null);s.topDict=o;var c=new i.CFFStrings;c.add("Version 0.11");c.add("See original notice");c.add(e);c.add(e);c.add("Medium");s.strings=c;s.globalSubrIndex=new i.CFFIndex;var l,h,u=t.length,d=[".notdef"];for(l=0;l<u;l++){const e=a[l].glyphName;-1===i.CFFStandardStrings.indexOf(e)&&c.add(e);d.push(e)}s.charset=new i.CFFCharset(!1,0,d);var f=new i.CFFIndex;f.add([139,14]);for(l=0;l<u;l++)f.add(t[l]);s.charStrings=f;var g=new i.CFFPrivateDict;g.setByName("Subrs",null);var m=["BlueValues","OtherBlues","FamilyBlues","FamilyOtherBlues","StemSnapH","StemSnapV","BlueShift","BlueFuzz","BlueScale","LanguageGroup","ExpansionFactor","ForceBold","StdHW","StdVW"];for(l=0,h=m.length;l<h;l++){var p=m[l];if(p in n.privateData){var b=n.privateData[p];if(Array.isArray(b))for(var y=b.length-1;y>0;y--)b[y]-=b[y-1];g.setByName(p,b)}}s.topDict.privateDict=g;var v=new i.CFFIndex;for(l=0,h=r.length;l<h;l++)v.add(r[l]);g.subrsIndex=v;return new i.CFFCompiler(s).compile()}};return t}(),T=function(){function e(e,t){this.properties=t;var a=new i.CFFParser(e,t,!0);this.cff=a.parse();this.cff.duplicateFirstGlyph();var n=new i.CFFCompiler(this.cff);this.seacs=this.cff.seacs;try{this.data=n.compile()}catch(a){(0,r.warn)("Failed to compile font "+t.loadedName);this.data=e}}e.prototype={get numGlyphs(){return this.cff.charStrings.count},getCharset:function(){return this.cff.charset.charset},getGlyphMapping:function(){var e,t,a=this.cff,r=this.properties,i=a.charset.charset;if(r.composite){e=Object.create(null);let s;if(a.isCIDFont)for(t=0;t<i.length;t++){var n=i[t];s=r.cMap.charCodeOf(n);e[s]=t}else for(t=0;t<a.charStrings.count;t++){s=r.cMap.charCodeOf(t);e[s]=t}return e}return e=I(r,a.encoding?a.encoding.encoding:null,i)},hasGlyphId:function(e){return this.cff.hasGlyphId(e)}};return e}()},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.CFFFDSelect=t.CFFCompiler=t.CFFPrivateDict=t.CFFTopDict=t.CFFCharset=t.CFFIndex=t.CFFStrings=t.CFFHeader=t.CFF=t.CFFParser=t.CFFStandardStrings=void 0;var r=a(2),i=a(29),n=a(30),s=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003","Black","Bold","Book","Light","Medium","Regular","Roman","Semibold"];t.CFFStandardStrings=s;var o=function(){var e=[null,{id:"hstem",min:2,stackClearing:!0,stem:!0},null,{id:"vstem",min:2,stackClearing:!0,stem:!0},{id:"vmoveto",min:1,stackClearing:!0},{id:"rlineto",min:2,resetStack:!0},{id:"hlineto",min:1,resetStack:!0},{id:"vlineto",min:1,resetStack:!0},{id:"rrcurveto",min:6,resetStack:!0},null,{id:"callsubr",min:1,undefStack:!0},{id:"return",min:0,undefStack:!0},null,null,{id:"endchar",min:0,stackClearing:!0},null,null,null,{id:"hstemhm",min:2,stackClearing:!0,stem:!0},{id:"hintmask",min:0,stackClearing:!0},{id:"cntrmask",min:0,stackClearing:!0},{id:"rmoveto",min:2,stackClearing:!0},{id:"hmoveto",min:1,stackClearing:!0},{id:"vstemhm",min:2,stackClearing:!0,stem:!0},{id:"rcurveline",min:8,resetStack:!0},{id:"rlinecurve",min:8,resetStack:!0},{id:"vvcurveto",min:4,resetStack:!0},{id:"hhcurveto",min:4,resetStack:!0},null,{id:"callgsubr",min:1,undefStack:!0},{id:"vhcurveto",min:4,resetStack:!0},{id:"hvcurveto",min:4,resetStack:!0}],t=[null,null,null,{id:"and",min:2,stackDelta:-1},{id:"or",min:2,stackDelta:-1},{id:"not",min:1,stackDelta:0},null,null,null,{id:"abs",min:1,stackDelta:0},{id:"add",min:2,stackDelta:-1,stackFn:function(e,t){e[t-2]=e[t-2]+e[t-1]}},{id:"sub",min:2,stackDelta:-1,stackFn:function(e,t){e[t-2]=e[t-2]-e[t-1]}},{id:"div",min:2,stackDelta:-1,stackFn:function(e,t){e[t-2]=e[t-2]/e[t-1]}},null,{id:"neg",min:1,stackDelta:0,stackFn:function(e,t){e[t-1]=-e[t-1]}},{id:"eq",min:2,stackDelta:-1},null,null,{id:"drop",min:1,stackDelta:-1},null,{id:"put",min:2,stackDelta:-2},{id:"get",min:1,stackDelta:0},{id:"ifelse",min:4,stackDelta:-3},{id:"random",min:0,stackDelta:1},{id:"mul",min:2,stackDelta:-1,stackFn:function(e,t){e[t-2]=e[t-2]*e[t-1]}},null,{id:"sqrt",min:1,stackDelta:0},{id:"dup",min:1,stackDelta:1},{id:"exch",min:2,stackDelta:0},{id:"index",min:2,stackDelta:0},{id:"roll",min:3,stackDelta:-2},null,null,null,{id:"hflex",min:7,resetStack:!0},{id:"flex",min:13,resetStack:!0},{id:"hflex1",min:9,resetStack:!0},{id:"flex1",min:11,resetStack:!0}];function a(e,t,a){this.bytes=e.getBytes();this.properties=t;this.seacAnalysisEnabled=!!a}a.prototype={parse:function(){var e=this.properties,t=new c;this.cff=t;var a=this.parseHeader(),r=this.parseIndex(a.endPos),i=this.parseIndex(r.endPos),n=this.parseIndex(i.endPos),s=this.parseIndex(n.endPos),o=this.parseDict(i.obj.get(0)),l=this.createDict(f,o,t.strings);t.header=a.obj;t.names=this.parseNameIndex(r.obj);t.strings=this.parseStringIndex(n.obj);t.topDict=l;t.globalSubrIndex=s.obj;this.parsePrivateDict(t.topDict);t.isCIDFont=l.hasName("ROS");var h=l.getByName("CharStrings"),u=this.parseIndex(h).obj,d=l.getByName("FontMatrix");d&&(e.fontMatrix=d);var g,m,p=l.getByName("FontBBox");if(p){e.ascent=Math.max(p[3],p[1]);e.descent=Math.min(p[1],p[3]);e.ascentScaled=!0}if(t.isCIDFont){for(var b=this.parseIndex(l.getByName("FDArray")).obj,y=0,v=b.count;y<v;++y){var w=b.get(y),k=this.createDict(f,this.parseDict(w),t.strings);this.parsePrivateDict(k);t.fdArray.push(k)}m=null;g=this.parseCharsets(l.getByName("charset"),u.count,t.strings,!0);t.fdSelect=this.parseFDSelect(l.getByName("FDSelect"),u.count)}else{g=this.parseCharsets(l.getByName("charset"),u.count,t.strings,!1);m=this.parseEncoding(l.getByName("Encoding"),e,t.strings,g.charset)}t.charset=g;t.encoding=m;var S=this.parseCharStrings({charStrings:u,localSubrIndex:l.privateDict.subrsIndex,globalSubrIndex:s.obj,fdSelect:t.fdSelect,fdArray:t.fdArray,privateDict:l.privateDict});t.charStrings=S.charStrings;t.seacs=S.seacs;t.widths=S.widths;return t},parseHeader:function(){for(var e=this.bytes,t=e.length,a=0;a<t&&1!==e[a];)++a;if(a>=t)throw new r.FormatError("Invalid CFF header");if(0!==a){(0,r.info)("cff data is shifted");e=e.subarray(a);this.bytes=e}var i=e[0],n=e[1],s=e[2],o=e[3];return{obj:new l(i,n,s,o),endPos:s}},parseDict:function(e){var t=0;function a(){var a=e[t++];if(30===a)return function(){var a="";const r=["0","1","2","3","4","5","6","7","8","9",".","E","E-",null,"-"];var i=e.length;for(;t<i;){var n=e[t++],s=n>>4,o=15&n;if(15===s)break;a+=r[s];if(15===o)break;a+=r[o]}return parseFloat(a)}();if(28===a)return a=((a=e[t++])<<24|e[t++]<<16)>>16;if(29===a)return a=(a=(a=(a=e[t++])<<8|e[t++])<<8|e[t++])<<8|e[t++];if(a>=32&&a<=246)return a-139;if(a>=247&&a<=250)return 256*(a-247)+e[t++]+108;if(a>=251&&a<=254)return-256*(a-251)-e[t++]-108;(0,r.warn)('CFFParser_parseDict: "'+a+'" is a reserved command.');return NaN}var i=[],n=[];t=0;for(var s=e.length;t<s;){var o=e[t];if(o<=21){12===o&&(o=o<<8|e[++t]);n.push([o,i]);i=[];++t}else i.push(a())}return n},parseIndex:function(e){var t,a,r=new u,i=this.bytes,n=i[e++]<<8|i[e++],s=[],o=e;if(0!==n){var c=i[e++],l=e+(n+1)*c-1;for(t=0,a=n+1;t<a;++t){for(var h=0,d=0;d<c;++d){h<<=8;h+=i[e++]}s.push(l+h)}o=s[n]}for(t=0,a=s.length-1;t<a;++t){var f=s[t],g=s[t+1];r.add(i.subarray(f,g))}return{obj:r,endPos:o}},parseNameIndex:function(e){for(var t=[],a=0,i=e.count;a<i;++a){var n=e.get(a);t.push((0,r.bytesToString)(n))}return t},parseStringIndex:function(e){for(var t=new h,a=0,i=e.count;a<i;++a){var n=e.get(a);t.add((0,r.bytesToString)(n))}return t},createDict:function(e,t,a){for(var r=new e(a),i=0,n=t.length;i<n;++i){var s=t[i],o=s[0],c=s[1];r.setByKey(o,c)}return r},parseCharString:function(a,i,n,s){if(!i||a.callDepth>10)return!1;for(var o=a.stackSize,c=a.stack,l=i.length,h=0;h<l;){var u=i[h++],d=null;if(12===u){var f=i[h++];if(0===f){i[h-2]=139;i[h-1]=22;o=0}else d=t[f]}else if(28===u){c[o]=(i[h]<<24|i[h+1]<<16)>>16;h+=2;o++}else if(14===u){if(o>=4){o-=4;if(this.seacAnalysisEnabled){a.seac=c.slice(o,o+4);return!1}}d=e[u]}else if(u>=32&&u<=246){c[o]=u-139;o++}else if(u>=247&&u<=254){c[o]=u<251?(u-247<<8)+i[h]+108:-(u-251<<8)-i[h]-108;h++;o++}else if(255===u){c[o]=(i[h]<<24|i[h+1]<<16|i[h+2]<<8|i[h+3])/65536;h+=4;o++}else if(19===u||20===u){a.hints+=o>>1;h+=a.hints+7>>3;o%=2;d=e[u]}else{if(10===u||29===u){var g;if(!(g=10===u?n:s)){d=e[u];(0,r.warn)("Missing subrsIndex for "+d.id);return!1}var m=32768;g.count<1240?m=107:g.count<33900&&(m=1131);var p=c[--o]+m;if(p<0||p>=g.count||isNaN(p)){d=e[u];(0,r.warn)("Out of bounds subrIndex for "+d.id);return!1}a.stackSize=o;a.callDepth++;if(!this.parseCharString(a,g.get(p),n,s))return!1;a.callDepth--;o=a.stackSize;continue}if(11===u){a.stackSize=o;return!0}d=e[u]}if(d){if(d.stem){a.hints+=o>>1;if(3===u||23===u)a.hasVStems=!0;else if(a.hasVStems&&(1===u||18===u)){(0,r.warn)("CFF stem hints are in wrong order");i[h-1]=1===u?3:23}}if("min"in d&&!a.undefStack&&o<d.min){(0,r.warn)("Not enough parameters for "+d.id+"; actual: "+o+", expected: "+d.min);return!1}if(a.firstStackClearing&&d.stackClearing){a.firstStackClearing=!1;(o-=d.min)>=2&&d.stem?o%=2:o>1&&(0,r.warn)("Found too many parameters for stack-clearing command");o>0&&c[o-1]>=0&&(a.width=c[o-1])}if("stackDelta"in d){"stackFn"in d&&d.stackFn(c,o);o+=d.stackDelta}else if(d.stackClearing)o=0;else if(d.resetStack){o=0;a.undefStack=!1}else if(d.undefStack){o=0;a.undefStack=!0;a.firstStackClearing=!1}}}a.stackSize=o;return!0},parseCharStrings({charStrings:e,localSubrIndex:t,globalSubrIndex:a,fdSelect:i,fdArray:n,privateDict:s}){for(var o=[],c=[],l=e.count,h=0;h<l;h++){var u=e.get(h),d={callDepth:0,stackSize:0,stack:[],undefStack:!0,hints:0,firstStackClearing:!0,seac:null,width:null,hasVStems:!1},f=!0,g=null,m=s;if(i&&n.length){var p=i.getFDIndex(h);if(-1===p){(0,r.warn)("Glyph index is not in fd select.");f=!1}if(p>=n.length){(0,r.warn)("Invalid fd index for glyph index.");f=!1}f&&(g=(m=n[p].privateDict).subrsIndex)}else t&&(g=t);f&&(f=this.parseCharString(d,u,g,a));if(null!==d.width){const e=m.getByName("nominalWidthX");c[h]=e+d.width}else{const e=m.getByName("defaultWidthX");c[h]=e}null!==d.seac&&(o[h]=d.seac);f||e.set(h,new Uint8Array([14]))}return{charStrings:e,seacs:o,widths:c}},emptyPrivateDictionary:function(e){var t=this.createDict(g,[],e.strings);e.setByKey(18,[0,0]);e.privateDict=t},parsePrivateDict:function(e){if(e.hasName("Private")){var t=e.getByName("Private");if(Array.isArray(t)&&2===t.length){var a=t[0],r=t[1];if(0===a||r>=this.bytes.length)this.emptyPrivateDictionary(e);else{var i=r+a,n=this.bytes.subarray(r,i),s=this.parseDict(n),o=this.createDict(g,s,e.strings);e.privateDict=o;if(o.getByName("Subrs")){var c=o.getByName("Subrs"),l=r+c;if(0===c||l>=this.bytes.length)this.emptyPrivateDictionary(e);else{var h=this.parseIndex(l);o.subrsIndex=h.obj}}}}else e.removeByName("Private")}else this.emptyPrivateDictionary(e)},parseCharsets:function(e,t,a,n){if(0===e)return new p(!0,m.ISO_ADOBE,i.ISOAdobeCharset);if(1===e)return new p(!0,m.EXPERT,i.ExpertCharset);if(2===e)return new p(!0,m.EXPERT_SUBSET,i.ExpertSubsetCharset);var s,o,c,l=this.bytes,h=e,u=l[e++],d=[".notdef"];t-=1;switch(u){case 0:for(c=0;c<t;c++){s=l[e++]<<8|l[e++];d.push(n?s:a.get(s))}break;case 1:for(;d.length<=t;){s=l[e++]<<8|l[e++];o=l[e++];for(c=0;c<=o;c++)d.push(n?s++:a.get(s++))}break;case 2:for(;d.length<=t;){s=l[e++]<<8|l[e++];o=l[e++]<<8|l[e++];for(c=0;c<=o;c++)d.push(n?s++:a.get(s++))}break;default:throw new r.FormatError("Unknown charset format")}var f=e,g=l.subarray(h,f);return new p(!1,u,d,g)},parseEncoding:function(e,t,a,i){var s,o,c,l=Object.create(null),h=this.bytes,u=!1,d=null;if(0===e||1===e){u=!0;s=e;var f=e?n.ExpertEncoding:n.StandardEncoding;for(o=0,c=i.length;o<c;o++){var g=f.indexOf(i[o]);-1!==g&&(l[g]=o)}}else{var m=e;switch(127&(s=h[e++])){case 0:var p=h[e++];for(o=1;o<=p;o++)l[h[e++]]=o;break;case 1:var y=h[e++],v=1;for(o=0;o<y;o++)for(var w=h[e++],k=h[e++],S=w;S<=w+k;S++)l[S]=v++;break;default:throw new r.FormatError(`Unknown encoding format: ${s} in CFF`)}var C=e;if(128&s){h[m]&=127;!function(){var t=h[e++];for(o=0;o<t;o++){var r=h[e++],n=(h[e++]<<8)+(255&h[e++]);l[r]=i.indexOf(a.get(n))}}()}d=h.subarray(m,C)}return new b(u,s&=127,l,d)},parseFDSelect:function(e,t){var a,i=this.bytes,n=i[e++],s=[];switch(n){case 0:for(a=0;a<t;++a){var o=i[e++];s.push(o)}break;case 3:var c=i[e++]<<8|i[e++];for(a=0;a<c;++a){var l=i[e++]<<8|i[e++];if(0===a&&0!==l){(0,r.warn)("parseFDSelect: The first range must have a first GID of 0 -- trying to recover.");l=0}for(var h=i[e++],u=i[e]<<8|i[e+1],d=l;d<u;++d)s.push(h)}e+=2;break;default:throw new r.FormatError(`parseFDSelect: Unknown format "${n}".`)}if(s.length!==t)throw new r.FormatError("parseFDSelect: Invalid font data.");return new y(n,s)}};return a}();t.CFFParser=o;var c=function(){function e(){this.header=null;this.names=[];this.topDict=null;this.strings=new h;this.globalSubrIndex=null;this.encoding=null;this.charset=null;this.charStrings=null;this.fdArray=[];this.fdSelect=null;this.isCIDFont=!1}e.prototype={duplicateFirstGlyph:function(){if(this.charStrings.count>=65535)(0,r.warn)("Not enough space in charstrings to duplicate first glyph.");else{var e=this.charStrings.get(0);this.charStrings.add(e);this.isCIDFont&&this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0])}},hasGlyphId:function(e){return!(e<0||e>=this.charStrings.count)&&this.charStrings.get(e).length>0}};return e}();t.CFF=c;var l=function(e,t,a,r){this.major=e;this.minor=t;this.hdrSize=a;this.offSize=r};t.CFFHeader=l;var h=function(){function e(){this.strings=[]}e.prototype={get:function(e){return e>=0&&e<=390?s[e]:e-391<=this.strings.length?this.strings[e-391]:s[0]},getSID:function(e){let t=s.indexOf(e);if(-1!==t)return t;t=this.strings.indexOf(e);return-1!==t?t+391:-1},add:function(e){this.strings.push(e)},get count(){return this.strings.length}};return e}();t.CFFStrings=h;var u=function(){function e(){this.objects=[];this.length=0}e.prototype={add:function(e){this.length+=e.length;this.objects.push(e)},set:function(e,t){this.length+=t.length-this.objects[e].length;this.objects[e]=t},get:function(e){return this.objects[e]},get count(){return this.objects.length}};return e}();t.CFFIndex=u;var d=function(){function e(e,t){this.keyToNameMap=e.keyToNameMap;this.nameToKeyMap=e.nameToKeyMap;this.defaults=e.defaults;this.types=e.types;this.opcodes=e.opcodes;this.order=e.order;this.strings=t;this.values=Object.create(null)}e.prototype={setByKey:function(e,t){if(!(e in this.keyToNameMap))return!1;var a=t.length;if(0===a)return!0;for(var i=0;i<a;i++)if(isNaN(t[i])){(0,r.warn)('Invalid CFFDict value: "'+t+'" for key "'+e+'".');return!0}var n=this.types[e];"num"!==n&&"sid"!==n&&"offset"!==n||(t=t[0]);this.values[e]=t;return!0},setByName:function(e,t){if(!(e in this.nameToKeyMap))throw new r.FormatError(`Invalid dictionary name "${e}"`);this.values[this.nameToKeyMap[e]]=t},hasName:function(e){return this.nameToKeyMap[e]in this.values},getByName:function(e){if(!(e in this.nameToKeyMap))throw new r.FormatError(`Invalid dictionary name ${e}"`);var t=this.nameToKeyMap[e];return t in this.values?this.values[t]:this.defaults[t]},removeByName:function(e){delete this.values[this.nameToKeyMap[e]]}};e.createTables=function(e){for(var t={keyToNameMap:{},nameToKeyMap:{},defaults:{},types:{},opcodes:{},order:[]},a=0,r=e.length;a<r;++a){var i=e[a],n=Array.isArray(i[0])?(i[0][0]<<8)+i[0][1]:i[0];t.keyToNameMap[n]=i[1];t.nameToKeyMap[i[1]]=n;t.types[n]=i[2];t.defaults[n]=i[3];t.opcodes[n]=Array.isArray(i[0])?i[0]:[i[0]];t.order.push(n)}return t};return e}(),f=function(){var e=[[[12,30],"ROS",["sid","sid","num"],null],[[12,20],"SyntheticBase","num",null],[0,"version","sid",null],[1,"Notice","sid",null],[[12,0],"Copyright","sid",null],[2,"FullName","sid",null],[3,"FamilyName","sid",null],[4,"Weight","sid",null],[[12,1],"isFixedPitch","num",0],[[12,2],"ItalicAngle","num",0],[[12,3],"UnderlinePosition","num",-100],[[12,4],"UnderlineThickness","num",50],[[12,5],"PaintType","num",0],[[12,6],"CharstringType","num",2],[[12,7],"FontMatrix",["num","num","num","num","num","num"],[.001,0,0,.001,0,0]],[13,"UniqueID","num",null],[5,"FontBBox",["num","num","num","num"],[0,0,0,0]],[[12,8],"StrokeWidth","num",0],[14,"XUID","array",null],[15,"charset","offset",0],[16,"Encoding","offset",0],[17,"CharStrings","offset",0],[18,"Private",["offset","offset"],null],[[12,21],"PostScript","sid",null],[[12,22],"BaseFontName","sid",null],[[12,23],"BaseFontBlend","delta",null],[[12,31],"CIDFontVersion","num",0],[[12,32],"CIDFontRevision","num",0],[[12,33],"CIDFontType","num",0],[[12,34],"CIDCount","num",8720],[[12,35],"UIDBase","num",null],[[12,37],"FDSelect","offset",null],[[12,36],"FDArray","offset",null],[[12,38],"FontName","sid",null]],t=null;function a(a){null===t&&(t=d.createTables(e));d.call(this,t,a);this.privateDict=null}a.prototype=Object.create(d.prototype);return a}();t.CFFTopDict=f;var g=function(){var e=[[6,"BlueValues","delta",null],[7,"OtherBlues","delta",null],[8,"FamilyBlues","delta",null],[9,"FamilyOtherBlues","delta",null],[[12,9],"BlueScale","num",.039625],[[12,10],"BlueShift","num",7],[[12,11],"BlueFuzz","num",1],[10,"StdHW","num",null],[11,"StdVW","num",null],[[12,12],"StemSnapH","delta",null],[[12,13],"StemSnapV","delta",null],[[12,14],"ForceBold","num",0],[[12,17],"LanguageGroup","num",0],[[12,18],"ExpansionFactor","num",.06],[[12,19],"initialRandomSeed","num",0],[20,"defaultWidthX","num",0],[21,"nominalWidthX","num",0],[19,"Subrs","offset",null]],t=null;function a(a){null===t&&(t=d.createTables(e));d.call(this,t,a);this.subrsIndex=null}a.prototype=Object.create(d.prototype);return a}();t.CFFPrivateDict=g;var m={ISO_ADOBE:0,EXPERT:1,EXPERT_SUBSET:2},p=function(e,t,a,r){this.predefined=e;this.format=t;this.charset=a;this.raw=r};t.CFFCharset=p;var b=function(e,t,a,r){this.predefined=e;this.format=t;this.encoding=a;this.raw=r},y=function(){function e(e,t){this.format=e;this.fdSelect=t}e.prototype={getFDIndex:function(e){return e<0||e>=this.fdSelect.length?-1:this.fdSelect[e]}};return e}();t.CFFFDSelect=y;var v=function(){function e(){this.offsets=Object.create(null)}e.prototype={isTracking:function(e){return e in this.offsets},track:function(e,t){if(e in this.offsets)throw new r.FormatError(`Already tracking location of ${e}`);this.offsets[e]=t},offset:function(e){for(var t in this.offsets)this.offsets[t]+=e},setEntryLocation:function(e,t,a){if(!(e in this.offsets))throw new r.FormatError(`Not tracking location of ${e}`);for(var i=a.data,n=this.offsets[e],s=0,o=t.length;s<o;++s){var c=5*s+n,l=c+1,h=c+2,u=c+3,d=c+4;if(29!==i[c]||0!==i[l]||0!==i[h]||0!==i[u]||0!==i[d])throw new r.FormatError("writing to an offset that is not empty");var f=t[s];i[c]=29;i[l]=f>>24&255;i[h]=f>>16&255;i[u]=f>>8&255;i[d]=255&f}}};return e}(),w=function(){function e(e){this.cff=e}e.prototype={compile:function(){var e=this.cff,t={data:[],length:0,add:function(e){this.data=this.data.concat(e);this.length=this.data.length}},a=this.compileHeader(e.header);t.add(a);var i=this.compileNameIndex(e.names);t.add(i);if(e.isCIDFont&&e.topDict.hasName("FontMatrix")){var n=e.topDict.getByName("FontMatrix");e.topDict.removeByName("FontMatrix");for(var s=0,o=e.fdArray.length;s<o;s++){var c=e.fdArray[s],l=n.slice(0);c.hasName("FontMatrix")&&(l=r.Util.transform(l,c.getByName("FontMatrix")));c.setByName("FontMatrix",l)}}e.topDict.setByName("charset",0);var h=this.compileTopDicts([e.topDict],t.length,e.isCIDFont);t.add(h.output);var u=h.trackers[0],d=this.compileStringIndex(e.strings.strings);t.add(d);var f=this.compileIndex(e.globalSubrIndex);t.add(f);if(e.encoding&&e.topDict.hasName("Encoding"))if(e.encoding.predefined)u.setEntryLocation("Encoding",[e.encoding.format],t);else{var g=this.compileEncoding(e.encoding);u.setEntryLocation("Encoding",[t.length],t);t.add(g)}var m=this.compileCharset(e.charset,e.charStrings.count,e.strings,e.isCIDFont);u.setEntryLocation("charset",[t.length],t);t.add(m);var p=this.compileCharStrings(e.charStrings);u.setEntryLocation("CharStrings",[t.length],t);t.add(p);if(e.isCIDFont){u.setEntryLocation("FDSelect",[t.length],t);var b=this.compileFDSelect(e.fdSelect);t.add(b);h=this.compileTopDicts(e.fdArray,t.length,!0);u.setEntryLocation("FDArray",[t.length],t);t.add(h.output);var y=h.trackers;this.compilePrivateDicts(e.fdArray,y,t)}this.compilePrivateDicts([e.topDict],[u],t);t.add([0]);return t.data},encodeNumber:function(e){return parseFloat(e)!==parseInt(e,10)||isNaN(e)?this.encodeFloat(e):this.encodeInteger(e)},encodeFloat:function(e){var t=e.toString(),a=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(t);if(a){var r=parseFloat("1e"+((a[2]?+a[2]:0)+a[1].length));t=(Math.round(e*r)/r).toString()}var i,n,s="";for(i=0,n=t.length;i<n;++i){var o=t[i];s+="e"===o?"-"===t[++i]?"c":"b":"."===o?"a":"-"===o?"e":o}var c=[30];for(i=0,n=(s+=1&s.length?"f":"ff").length;i<n;i+=2)c.push(parseInt(s.substring(i,i+2),16));return c},encodeInteger:function(e){return e>=-107&&e<=107?[e+139]:e>=108&&e<=1131?[247+((e-=108)>>8),255&e]:e>=-1131&&e<=-108?[251+((e=-e-108)>>8),255&e]:e>=-32768&&e<=32767?[28,e>>8&255,255&e]:[29,e>>24&255,e>>16&255,e>>8&255,255&e]},compileHeader:function(e){return[e.major,e.minor,e.hdrSize,e.offSize]},compileNameIndex:function(e){for(var t=new u,a=0,i=e.length;a<i;++a){for(var n=e[a],s=Math.min(n.length,127),o=new Array(s),c=0;c<s;c++){var l=n[c];(l<"!"||l>"~"||"["===l||"]"===l||"("===l||")"===l||"{"===l||"}"===l||"<"===l||">"===l||"/"===l||"%"===l)&&(l="_");o[c]=l}""===(o=o.join(""))&&(o="Bad_Font_Name");t.add((0,r.stringToBytes)(o))}return this.compileIndex(t)},compileTopDicts:function(e,t,a){for(var r=[],i=new u,n=0,s=e.length;n<s;++n){var o=e[n];if(a){o.removeByName("CIDFontVersion");o.removeByName("CIDFontRevision");o.removeByName("CIDFontType");o.removeByName("CIDCount");o.removeByName("UIDBase")}var c=new v,l=this.compileDict(o,c);r.push(c);i.add(l);c.offset(t)}return{trackers:r,output:i=this.compileIndex(i,r)}},compilePrivateDicts:function(e,t,a){for(var i=0,n=e.length;i<n;++i){var s=e[i],o=s.privateDict;if(!o||!s.hasName("Private"))throw new r.FormatError("There must be a private dictionary.");var c=new v,l=this.compileDict(o,c),h=a.length;c.offset(h);l.length||(h=0);t[i].setEntryLocation("Private",[l.length,h],a);a.add(l);if(o.subrsIndex&&o.hasName("Subrs")){var u=this.compileIndex(o.subrsIndex);c.setEntryLocation("Subrs",[l.length],a);a.add(u)}}},compileDict:function(e,t){for(var a=[],i=e.order,n=0;n<i.length;++n){var s=i[n];if(s in e.values){var o=e.values[s],c=e.types[s];Array.isArray(c)||(c=[c]);Array.isArray(o)||(o=[o]);if(0!==o.length){for(var l=0,h=c.length;l<h;++l){var u=c[l],d=o[l];switch(u){case"num":case"sid":a=a.concat(this.encodeNumber(d));break;case"offset":var f=e.keyToNameMap[s];t.isTracking(f)||t.track(f,a.length);a=a.concat([29,0,0,0,0]);break;case"array":case"delta":a=a.concat(this.encodeNumber(d));for(var g=1,m=o.length;g<m;++g)a=a.concat(this.encodeNumber(o[g]));break;default:throw new r.FormatError(`Unknown data type of ${u}`)}}a=a.concat(e.opcodes[s])}}}return a},compileStringIndex:function(e){for(var t=new u,a=0,i=e.length;a<i;++a)t.add((0,r.stringToBytes)(e[a]));return this.compileIndex(t)},compileGlobalSubrIndex:function(){var e=this.cff.globalSubrIndex;this.out.writeByteArray(this.compileIndex(e))},compileCharStrings:function(e){for(var t=new u,a=0;a<e.count;a++){var r=e.get(a);0!==r.length?t.add(r):t.add(new Uint8Array([139,14]))}return this.compileIndex(t)},compileCharset:function(e,t,a,i){let n;const s=t-1;if(i)n=new Uint8Array([2,0,0,s>>8&255,255&s]);else{n=new Uint8Array(1+2*s);n[0]=0;let t=0;const i=e.charset.length;let o=!1;for(let s=1;s<n.length;s+=2){let c=0;if(t<i){const i=e.charset[t++];c=a.getSID(i);if(-1===c){c=0;if(!o){o=!0;(0,r.warn)(`Couldn't find ${i} in CFF strings`)}}}n[s]=c>>8&255;n[s+1]=255&c}}return this.compileTypedArray(n)},compileEncoding:function(e){return this.compileTypedArray(e.raw)},compileFDSelect:function(e){const t=e.format;let a,r;switch(t){case 0:a=new Uint8Array(1+e.fdSelect.length);a[0]=t;for(r=0;r<e.fdSelect.length;r++)a[r+1]=e.fdSelect[r];break;case 3:const i=0;let n=e.fdSelect[0];const s=[t,0,0,i>>8&255,255&i,n];for(r=1;r<e.fdSelect.length;r++){const t=e.fdSelect[r];if(t!==n){s.push(r>>8&255,255&r,t);n=t}}const o=(s.length-3)/3;s[1]=o>>8&255;s[2]=255&o;s.push(r>>8&255,255&r);a=new Uint8Array(s)}return this.compileTypedArray(a)},compileTypedArray:function(e){for(var t=[],a=0,r=e.length;a<r;++a)t[a]=e[a];return t},compileIndex:function(e,t){t=t||[];var a=e.objects,r=a.length;if(0===r)return[0,0,0];var i,n,s=[r>>8&255,255&r],o=1;for(i=0;i<r;++i)o+=a[i].length;n=o<256?1:o<65536?2:o<16777216?3:4;s.push(n);var c=1;for(i=0;i<r+1;i++){1===n?s.push(255&c):2===n?s.push(c>>8&255,255&c):3===n?s.push(c>>16&255,c>>8&255,255&c):s.push(c>>>24&255,c>>16&255,c>>8&255,255&c);a[i]&&(c+=a[i].length)}for(i=0;i<r;i++){t[i]&&t[i].offset(s.length);for(var l=0,h=a[i].length;l<h;l++)s.push(a[i][l])}return s}};return e}();t.CFFCompiler=w},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.ExpertSubsetCharset=t.ExpertCharset=t.ISOAdobeCharset=void 0;t.ISOAdobeCharset=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron"];t.ExpertCharset=[".notdef","space","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","fi","fl","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"];t.ExpertSubsetCharset=[".notdef","space","dollaroldstyle","dollarsuperior","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","fi","fl","ffi","ffl","parenleftinferior","parenrightinferior","hyphensuperior","colonmonetary","onefitted","rupiah","centoldstyle","figuredash","hypheninferior","onequarter","onehalf","threequarters","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior"]},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getEncoding=function(e){switch(e){case"WinAnsiEncoding":return o;case"StandardEncoding":return s;case"MacRomanEncoding":return n;case"SymbolSetEncoding":return c;case"ZapfDingbatsEncoding":return l;case"ExpertEncoding":return r;case"MacExpertEncoding":return i;default:return null}};t.ExpertEncoding=t.ZapfDingbatsEncoding=t.SymbolSetEncoding=t.MacRomanEncoding=t.StandardEncoding=t.WinAnsiEncoding=void 0;const r=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclamsmall","Hungarumlautsmall","","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","","asuperior","bsuperior","centsuperior","dsuperior","esuperior","","","","isuperior","","","lsuperior","msuperior","nsuperior","osuperior","","","rsuperior","ssuperior","tsuperior","","ff","fi","fl","ffi","ffl","parenleftinferior","","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdownsmall","centoldstyle","Lslashsmall","","","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","","Dotaccentsmall","","","Macronsmall","","","figuredash","hypheninferior","","","Ogoneksmall","Ringsmall","Cedillasmall","","","","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","","","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"];t.ExpertEncoding=r;const i=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclamsmall","Hungarumlautsmall","centoldstyle","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","","threequartersemdash","","questionsmall","","","","","Ethsmall","","","onequarter","onehalf","threequarters","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","","","","","","","ff","fi","fl","ffi","ffl","parenleftinferior","","parenrightinferior","Circumflexsmall","hypheninferior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","","","asuperior","centsuperior","","","","","Aacutesmall","Agravesmall","Acircumflexsmall","Adieresissmall","Atildesmall","Aringsmall","Ccedillasmall","Eacutesmall","Egravesmall","Ecircumflexsmall","Edieresissmall","Iacutesmall","Igravesmall","Icircumflexsmall","Idieresissmall","Ntildesmall","Oacutesmall","Ogravesmall","Ocircumflexsmall","Odieresissmall","Otildesmall","Uacutesmall","Ugravesmall","Ucircumflexsmall","Udieresissmall","","eightsuperior","fourinferior","threeinferior","sixinferior","eightinferior","seveninferior","Scaronsmall","","centinferior","twoinferior","","Dieresissmall","","Caronsmall","osuperior","fiveinferior","","commainferior","periodinferior","Yacutesmall","","dollarinferior","","","Thornsmall","","nineinferior","zeroinferior","Zcaronsmall","AEsmall","Oslashsmall","questiondownsmall","oneinferior","Lslashsmall","","","","","","","Cedillasmall","","","","","","OEsmall","figuredash","hyphensuperior","","","","","exclamdownsmall","","Ydieresissmall","","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","ninesuperior","zerosuperior","","esuperior","rsuperior","tsuperior","","","isuperior","ssuperior","dsuperior","","","","","","lsuperior","Ogoneksmall","Brevesmall","Macronsmall","bsuperior","nsuperior","msuperior","commasuperior","periodsuperior","Dotaccentsmall","Ringsmall","","","",""],n=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","space","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron"];t.MacRomanEncoding=n;const s=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","","endash","dagger","daggerdbl","periodcentered","","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","","questiondown","","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","","ring","cedilla","","hungarumlaut","ogonek","caron","emdash","","","","","","","","","","","","","","","","","AE","","ordfeminine","","","","","Lslash","Oslash","OE","ordmasculine","","","","","","ae","","","","dotlessi","","","lslash","oslash","oe","germandbls","","","",""];t.StandardEncoding=s;const o=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","bullet","Euro","bullet","quotesinglbase","florin","quotedblbase","ellipsis","dagger","daggerdbl","circumflex","perthousand","Scaron","guilsinglleft","OE","bullet","Zcaron","bullet","bullet","quoteleft","quoteright","quotedblleft","quotedblright","bullet","endash","emdash","tilde","trademark","scaron","guilsinglright","oe","bullet","zcaron","Ydieresis","space","exclamdown","cent","sterling","currency","yen","brokenbar","section","dieresis","copyright","ordfeminine","guillemotleft","logicalnot","hyphen","registered","macron","degree","plusminus","twosuperior","threesuperior","acute","mu","paragraph","periodcentered","cedilla","onesuperior","ordmasculine","guillemotright","onequarter","onehalf","threequarters","questiondown","Agrave","Aacute","Acircumflex","Atilde","Adieresis","Aring","AE","Ccedilla","Egrave","Eacute","Ecircumflex","Edieresis","Igrave","Iacute","Icircumflex","Idieresis","Eth","Ntilde","Ograve","Oacute","Ocircumflex","Otilde","Odieresis","multiply","Oslash","Ugrave","Uacute","Ucircumflex","Udieresis","Yacute","Thorn","germandbls","agrave","aacute","acircumflex","atilde","adieresis","aring","ae","ccedilla","egrave","eacute","ecircumflex","edieresis","igrave","iacute","icircumflex","idieresis","eth","ntilde","ograve","oacute","ocircumflex","otilde","odieresis","divide","oslash","ugrave","uacute","ucircumflex","udieresis","yacute","thorn","ydieresis"];t.WinAnsiEncoding=o;const c=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","universal","numbersign","existential","percent","ampersand","suchthat","parenleft","parenright","asteriskmath","plus","comma","minus","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","congruent","Alpha","Beta","Chi","Delta","Epsilon","Phi","Gamma","Eta","Iota","theta1","Kappa","Lambda","Mu","Nu","Omicron","Pi","Theta","Rho","Sigma","Tau","Upsilon","sigma1","Omega","Xi","Psi","Zeta","bracketleft","therefore","bracketright","perpendicular","underscore","radicalex","alpha","beta","chi","delta","epsilon","phi","gamma","eta","iota","phi1","kappa","lambda","mu","nu","omicron","pi","theta","rho","sigma","tau","upsilon","omega1","omega","xi","psi","zeta","braceleft","bar","braceright","similar","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Euro","Upsilon1","minute","lessequal","fraction","infinity","florin","club","diamond","heart","spade","arrowboth","arrowleft","arrowup","arrowright","arrowdown","degree","plusminus","second","greaterequal","multiply","proportional","partialdiff","bullet","divide","notequal","equivalence","approxequal","ellipsis","arrowvertex","arrowhorizex","carriagereturn","aleph","Ifraktur","Rfraktur","weierstrass","circlemultiply","circleplus","emptyset","intersection","union","propersuperset","reflexsuperset","notsubset","propersubset","reflexsubset","element","notelement","angle","gradient","registerserif","copyrightserif","trademarkserif","product","radical","dotmath","logicalnot","logicaland","logicalor","arrowdblboth","arrowdblleft","arrowdblup","arrowdblright","arrowdbldown","lozenge","angleleft","registersans","copyrightsans","trademarksans","summation","parenlefttp","parenleftex","parenleftbt","bracketlefttp","bracketleftex","bracketleftbt","bracelefttp","braceleftmid","braceleftbt","braceex","","angleright","integral","integraltp","integralex","integralbt","parenrighttp","parenrightex","parenrightbt","bracketrighttp","bracketrightex","bracketrightbt","bracerighttp","bracerightmid","bracerightbt",""];t.SymbolSetEncoding=c;const l=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","a1","a2","a202","a3","a4","a5","a119","a118","a117","a11","a12","a13","a14","a15","a16","a105","a17","a18","a19","a20","a21","a22","a23","a24","a25","a26","a27","a28","a6","a7","a8","a9","a10","a29","a30","a31","a32","a33","a34","a35","a36","a37","a38","a39","a40","a41","a42","a43","a44","a45","a46","a47","a48","a49","a50","a51","a52","a53","a54","a55","a56","a57","a58","a59","a60","a61","a62","a63","a64","a65","a66","a67","a68","a69","a70","a71","a72","a73","a74","a203","a75","a204","a76","a77","a78","a79","a81","a82","a83","a84","a97","a98","a99","a100","","a89","a90","a93","a94","a91","a92","a205","a85","a206","a86","a87","a88","a95","a96","","","","","","","","","","","","","","","","","","","","a101","a102","a103","a104","a106","a107","a108","a112","a111","a110","a109","a120","a121","a122","a123","a124","a125","a126","a127","a128","a129","a130","a131","a132","a133","a134","a135","a136","a137","a138","a139","a140","a141","a142","a143","a144","a145","a146","a147","a148","a149","a150","a151","a152","a153","a154","a155","a156","a157","a158","a159","a160","a161","a163","a164","a196","a165","a192","a166","a167","a168","a169","a170","a171","a172","a173","a162","a174","a175","a176","a177","a178","a179","a193","a180","a199","a181","a200","a182","","a201","a183","a184","a197","a185","a194","a198","a186","a195","a187","a188","a189","a190","a191",""];t.ZapfDingbatsEncoding=l},function(e,t,a){var r=a(7).getLookupTableFactory,i=r((function(e){e.A=65;e.AE=198;e.AEacute=508;e.AEmacron=482;e.AEsmall=63462;e.Aacute=193;e.Aacutesmall=63457;e.Abreve=258;e.Abreveacute=7854;e.Abrevecyrillic=1232;e.Abrevedotbelow=7862;e.Abrevegrave=7856;e.Abrevehookabove=7858;e.Abrevetilde=7860;e.Acaron=461;e.Acircle=9398;e.Acircumflex=194;e.Acircumflexacute=7844;e.Acircumflexdotbelow=7852;e.Acircumflexgrave=7846;e.Acircumflexhookabove=7848;e.Acircumflexsmall=63458;e.Acircumflextilde=7850;e.Acute=63177;e.Acutesmall=63412;e.Acyrillic=1040;e.Adblgrave=512;e.Adieresis=196;e.Adieresiscyrillic=1234;e.Adieresismacron=478;e.Adieresissmall=63460;e.Adotbelow=7840;e.Adotmacron=480;e.Agrave=192;e.Agravesmall=63456;e.Ahookabove=7842;e.Aiecyrillic=1236;e.Ainvertedbreve=514;e.Alpha=913;e.Alphatonos=902;e.Amacron=256;e.Amonospace=65313;e.Aogonek=260;e.Aring=197;e.Aringacute=506;e.Aringbelow=7680;e.Aringsmall=63461;e.Asmall=63329;e.Atilde=195;e.Atildesmall=63459;e.Aybarmenian=1329;e.B=66;e.Bcircle=9399;e.Bdotaccent=7682;e.Bdotbelow=7684;e.Becyrillic=1041;e.Benarmenian=1330;e.Beta=914;e.Bhook=385;e.Blinebelow=7686;e.Bmonospace=65314;e.Brevesmall=63220;e.Bsmall=63330;e.Btopbar=386;e.C=67;e.Caarmenian=1342;e.Cacute=262;e.Caron=63178;e.Caronsmall=63221;e.Ccaron=268;e.Ccedilla=199;e.Ccedillaacute=7688;e.Ccedillasmall=63463;e.Ccircle=9400;e.Ccircumflex=264;e.Cdot=266;e.Cdotaccent=266;e.Cedillasmall=63416;e.Chaarmenian=1353;e.Cheabkhasiancyrillic=1212;e.Checyrillic=1063;e.Chedescenderabkhasiancyrillic=1214;e.Chedescendercyrillic=1206;e.Chedieresiscyrillic=1268;e.Cheharmenian=1347;e.Chekhakassiancyrillic=1227;e.Cheverticalstrokecyrillic=1208;e.Chi=935;e.Chook=391;e.Circumflexsmall=63222;e.Cmonospace=65315;e.Coarmenian=1361;e.Csmall=63331;e.D=68;e.DZ=497;e.DZcaron=452;e.Daarmenian=1332;e.Dafrican=393;e.Dcaron=270;e.Dcedilla=7696;e.Dcircle=9401;e.Dcircumflexbelow=7698;e.Dcroat=272;e.Ddotaccent=7690;e.Ddotbelow=7692;e.Decyrillic=1044;e.Deicoptic=1006;e.Delta=8710;e.Deltagreek=916;e.Dhook=394;e.Dieresis=63179;e.DieresisAcute=63180;e.DieresisGrave=63181;e.Dieresissmall=63400;e.Digammagreek=988;e.Djecyrillic=1026;e.Dlinebelow=7694;e.Dmonospace=65316;e.Dotaccentsmall=63223;e.Dslash=272;e.Dsmall=63332;e.Dtopbar=395;e.Dz=498;e.Dzcaron=453;e.Dzeabkhasiancyrillic=1248;e.Dzecyrillic=1029;e.Dzhecyrillic=1039;e.E=69;e.Eacute=201;e.Eacutesmall=63465;e.Ebreve=276;e.Ecaron=282;e.Ecedillabreve=7708;e.Echarmenian=1333;e.Ecircle=9402;e.Ecircumflex=202;e.Ecircumflexacute=7870;e.Ecircumflexbelow=7704;e.Ecircumflexdotbelow=7878;e.Ecircumflexgrave=7872;e.Ecircumflexhookabove=7874;e.Ecircumflexsmall=63466;e.Ecircumflextilde=7876;e.Ecyrillic=1028;e.Edblgrave=516;e.Edieresis=203;e.Edieresissmall=63467;e.Edot=278;e.Edotaccent=278;e.Edotbelow=7864;e.Efcyrillic=1060;e.Egrave=200;e.Egravesmall=63464;e.Eharmenian=1335;e.Ehookabove=7866;e.Eightroman=8551;e.Einvertedbreve=518;e.Eiotifiedcyrillic=1124;e.Elcyrillic=1051;e.Elevenroman=8554;e.Emacron=274;e.Emacronacute=7702;e.Emacrongrave=7700;e.Emcyrillic=1052;e.Emonospace=65317;e.Encyrillic=1053;e.Endescendercyrillic=1186;e.Eng=330;e.Enghecyrillic=1188;e.Enhookcyrillic=1223;e.Eogonek=280;e.Eopen=400;e.Epsilon=917;e.Epsilontonos=904;e.Ercyrillic=1056;e.Ereversed=398;e.Ereversedcyrillic=1069;e.Escyrillic=1057;e.Esdescendercyrillic=1194;e.Esh=425;e.Esmall=63333;e.Eta=919;e.Etarmenian=1336;e.Etatonos=905;e.Eth=208;e.Ethsmall=63472;e.Etilde=7868;e.Etildebelow=7706;e.Euro=8364;e.Ezh=439;e.Ezhcaron=494;e.Ezhreversed=440;e.F=70;e.Fcircle=9403;e.Fdotaccent=7710;e.Feharmenian=1366;e.Feicoptic=996;e.Fhook=401;e.Fitacyrillic=1138;e.Fiveroman=8548;e.Fmonospace=65318;e.Fourroman=8547;e.Fsmall=63334;e.G=71;e.GBsquare=13191;e.Gacute=500;e.Gamma=915;e.Gammaafrican=404;e.Gangiacoptic=1002;e.Gbreve=286;e.Gcaron=486;e.Gcedilla=290;e.Gcircle=9404;e.Gcircumflex=284;e.Gcommaaccent=290;e.Gdot=288;e.Gdotaccent=288;e.Gecyrillic=1043;e.Ghadarmenian=1346;e.Ghemiddlehookcyrillic=1172;e.Ghestrokecyrillic=1170;e.Gheupturncyrillic=1168;e.Ghook=403;e.Gimarmenian=1331;e.Gjecyrillic=1027;e.Gmacron=7712;e.Gmonospace=65319;e.Grave=63182;e.Gravesmall=63328;e.Gsmall=63335;e.Gsmallhook=667;e.Gstroke=484;e.H=72;e.H18533=9679;e.H18543=9642;e.H18551=9643;e.H22073=9633;e.HPsquare=13259;e.Haabkhasiancyrillic=1192;e.Hadescendercyrillic=1202;e.Hardsigncyrillic=1066;e.Hbar=294;e.Hbrevebelow=7722;e.Hcedilla=7720;e.Hcircle=9405;e.Hcircumflex=292;e.Hdieresis=7718;e.Hdotaccent=7714;e.Hdotbelow=7716;e.Hmonospace=65320;e.Hoarmenian=1344;e.Horicoptic=1e3;e.Hsmall=63336;e.Hungarumlaut=63183;e.Hungarumlautsmall=63224;e.Hzsquare=13200;e.I=73;e.IAcyrillic=1071;e.IJ=306;e.IUcyrillic=1070;e.Iacute=205;e.Iacutesmall=63469;e.Ibreve=300;e.Icaron=463;e.Icircle=9406;e.Icircumflex=206;e.Icircumflexsmall=63470;e.Icyrillic=1030;e.Idblgrave=520;e.Idieresis=207;e.Idieresisacute=7726;e.Idieresiscyrillic=1252;e.Idieresissmall=63471;e.Idot=304;e.Idotaccent=304;e.Idotbelow=7882;e.Iebrevecyrillic=1238;e.Iecyrillic=1045;e.Ifraktur=8465;e.Igrave=204;e.Igravesmall=63468;e.Ihookabove=7880;e.Iicyrillic=1048;e.Iinvertedbreve=522;e.Iishortcyrillic=1049;e.Imacron=298;e.Imacroncyrillic=1250;e.Imonospace=65321;e.Iniarmenian=1339;e.Iocyrillic=1025;e.Iogonek=302;e.Iota=921;e.Iotaafrican=406;e.Iotadieresis=938;e.Iotatonos=906;e.Ismall=63337;e.Istroke=407;e.Itilde=296;e.Itildebelow=7724;e.Izhitsacyrillic=1140;e.Izhitsadblgravecyrillic=1142;e.J=74;e.Jaarmenian=1345;e.Jcircle=9407;e.Jcircumflex=308;e.Jecyrillic=1032;e.Jheharmenian=1355;e.Jmonospace=65322;e.Jsmall=63338;e.K=75;e.KBsquare=13189;e.KKsquare=13261;e.Kabashkircyrillic=1184;e.Kacute=7728;e.Kacyrillic=1050;e.Kadescendercyrillic=1178;e.Kahookcyrillic=1219;e.Kappa=922;e.Kastrokecyrillic=1182;e.Kaverticalstrokecyrillic=1180;e.Kcaron=488;e.Kcedilla=310;e.Kcircle=9408;e.Kcommaaccent=310;e.Kdotbelow=7730;e.Keharmenian=1364;e.Kenarmenian=1343;e.Khacyrillic=1061;e.Kheicoptic=998;e.Khook=408;e.Kjecyrillic=1036;e.Klinebelow=7732;e.Kmonospace=65323;e.Koppacyrillic=1152;e.Koppagreek=990;e.Ksicyrillic=1134;e.Ksmall=63339;e.L=76;e.LJ=455;e.LL=63167;e.Lacute=313;e.Lambda=923;e.Lcaron=317;e.Lcedilla=315;e.Lcircle=9409;e.Lcircumflexbelow=7740;e.Lcommaaccent=315;e.Ldot=319;e.Ldotaccent=319;e.Ldotbelow=7734;e.Ldotbelowmacron=7736;e.Liwnarmenian=1340;e.Lj=456;e.Ljecyrillic=1033;e.Llinebelow=7738;e.Lmonospace=65324;e.Lslash=321;e.Lslashsmall=63225;e.Lsmall=63340;e.M=77;e.MBsquare=13190;e.Macron=63184;e.Macronsmall=63407;e.Macute=7742;e.Mcircle=9410;e.Mdotaccent=7744;e.Mdotbelow=7746;e.Menarmenian=1348;e.Mmonospace=65325;e.Msmall=63341;e.Mturned=412;e.Mu=924;e.N=78;e.NJ=458;e.Nacute=323;e.Ncaron=327;e.Ncedilla=325;e.Ncircle=9411;e.Ncircumflexbelow=7754;e.Ncommaaccent=325;e.Ndotaccent=7748;e.Ndotbelow=7750;e.Nhookleft=413;e.Nineroman=8552;e.Nj=459;e.Njecyrillic=1034;e.Nlinebelow=7752;e.Nmonospace=65326;e.Nowarmenian=1350;e.Nsmall=63342;e.Ntilde=209;e.Ntildesmall=63473;e.Nu=925;e.O=79;e.OE=338;e.OEsmall=63226;e.Oacute=211;e.Oacutesmall=63475;e.Obarredcyrillic=1256;e.Obarreddieresiscyrillic=1258;e.Obreve=334;e.Ocaron=465;e.Ocenteredtilde=415;e.Ocircle=9412;e.Ocircumflex=212;e.Ocircumflexacute=7888;e.Ocircumflexdotbelow=7896;e.Ocircumflexgrave=7890;e.Ocircumflexhookabove=7892;e.Ocircumflexsmall=63476;e.Ocircumflextilde=7894;e.Ocyrillic=1054;e.Odblacute=336;e.Odblgrave=524;e.Odieresis=214;e.Odieresiscyrillic=1254;e.Odieresissmall=63478;e.Odotbelow=7884;e.Ogoneksmall=63227;e.Ograve=210;e.Ogravesmall=63474;e.Oharmenian=1365;e.Ohm=8486;e.Ohookabove=7886;e.Ohorn=416;e.Ohornacute=7898;e.Ohorndotbelow=7906;e.Ohorngrave=7900;e.Ohornhookabove=7902;e.Ohorntilde=7904;e.Ohungarumlaut=336;e.Oi=418;e.Oinvertedbreve=526;e.Omacron=332;e.Omacronacute=7762;e.Omacrongrave=7760;e.Omega=8486;e.Omegacyrillic=1120;e.Omegagreek=937;e.Omegaroundcyrillic=1146;e.Omegatitlocyrillic=1148;e.Omegatonos=911;e.Omicron=927;e.Omicrontonos=908;e.Omonospace=65327;e.Oneroman=8544;e.Oogonek=490;e.Oogonekmacron=492;e.Oopen=390;e.Oslash=216;e.Oslashacute=510;e.Oslashsmall=63480;e.Osmall=63343;e.Ostrokeacute=510;e.Otcyrillic=1150;e.Otilde=213;e.Otildeacute=7756;e.Otildedieresis=7758;e.Otildesmall=63477;e.P=80;e.Pacute=7764;e.Pcircle=9413;e.Pdotaccent=7766;e.Pecyrillic=1055;e.Peharmenian=1354;e.Pemiddlehookcyrillic=1190;e.Phi=934;e.Phook=420;e.Pi=928;e.Piwrarmenian=1363;e.Pmonospace=65328;e.Psi=936;e.Psicyrillic=1136;e.Psmall=63344;e.Q=81;e.Qcircle=9414;e.Qmonospace=65329;e.Qsmall=63345;e.R=82;e.Raarmenian=1356;e.Racute=340;e.Rcaron=344;e.Rcedilla=342;e.Rcircle=9415;e.Rcommaaccent=342;e.Rdblgrave=528;e.Rdotaccent=7768;e.Rdotbelow=7770;e.Rdotbelowmacron=7772;e.Reharmenian=1360;e.Rfraktur=8476;e.Rho=929;e.Ringsmall=63228;e.Rinvertedbreve=530;e.Rlinebelow=7774;e.Rmonospace=65330;e.Rsmall=63346;e.Rsmallinverted=641;e.Rsmallinvertedsuperior=694;e.S=83;e.SF010000=9484;e.SF020000=9492;e.SF030000=9488;e.SF040000=9496;e.SF050000=9532;e.SF060000=9516;e.SF070000=9524;e.SF080000=9500;e.SF090000=9508;e.SF100000=9472;e.SF110000=9474;e.SF190000=9569;e.SF200000=9570;e.SF210000=9558;e.SF220000=9557;e.SF230000=9571;e.SF240000=9553;e.SF250000=9559;e.SF260000=9565;e.SF270000=9564;e.SF280000=9563;e.SF360000=9566;e.SF370000=9567;e.SF380000=9562;e.SF390000=9556;e.SF400000=9577;e.SF410000=9574;e.SF420000=9568;e.SF430000=9552;e.SF440000=9580;e.SF450000=9575;e.SF460000=9576;e.SF470000=9572;e.SF480000=9573;e.SF490000=9561;e.SF500000=9560;e.SF510000=9554;e.SF520000=9555;e.SF530000=9579;e.SF540000=9578;e.Sacute=346;e.Sacutedotaccent=7780;e.Sampigreek=992;e.Scaron=352;e.Scarondotaccent=7782;e.Scaronsmall=63229;e.Scedilla=350;e.Schwa=399;e.Schwacyrillic=1240;e.Schwadieresiscyrillic=1242;e.Scircle=9416;e.Scircumflex=348;e.Scommaaccent=536;e.Sdotaccent=7776;e.Sdotbelow=7778;e.Sdotbelowdotaccent=7784;e.Seharmenian=1357;e.Sevenroman=8550;e.Shaarmenian=1351;e.Shacyrillic=1064;e.Shchacyrillic=1065;e.Sheicoptic=994;e.Shhacyrillic=1210;e.Shimacoptic=1004;e.Sigma=931;e.Sixroman=8549;e.Smonospace=65331;e.Softsigncyrillic=1068;e.Ssmall=63347;e.Stigmagreek=986;e.T=84;e.Tau=932;e.Tbar=358;e.Tcaron=356;e.Tcedilla=354;e.Tcircle=9417;e.Tcircumflexbelow=7792;e.Tcommaaccent=354;e.Tdotaccent=7786;e.Tdotbelow=7788;e.Tecyrillic=1058;e.Tedescendercyrillic=1196;e.Tenroman=8553;e.Tetsecyrillic=1204;e.Theta=920;e.Thook=428;e.Thorn=222;e.Thornsmall=63486;e.Threeroman=8546;e.Tildesmall=63230;e.Tiwnarmenian=1359;e.Tlinebelow=7790;e.Tmonospace=65332;e.Toarmenian=1337;e.Tonefive=444;e.Tonesix=388;e.Tonetwo=423;e.Tretroflexhook=430;e.Tsecyrillic=1062;e.Tshecyrillic=1035;e.Tsmall=63348;e.Twelveroman=8555;e.Tworoman=8545;e.U=85;e.Uacute=218;e.Uacutesmall=63482;e.Ubreve=364;e.Ucaron=467;e.Ucircle=9418;e.Ucircumflex=219;e.Ucircumflexbelow=7798;e.Ucircumflexsmall=63483;e.Ucyrillic=1059;e.Udblacute=368;e.Udblgrave=532;e.Udieresis=220;e.Udieresisacute=471;e.Udieresisbelow=7794;e.Udieresiscaron=473;e.Udieresiscyrillic=1264;e.Udieresisgrave=475;e.Udieresismacron=469;e.Udieresissmall=63484;e.Udotbelow=7908;e.Ugrave=217;e.Ugravesmall=63481;e.Uhookabove=7910;e.Uhorn=431;e.Uhornacute=7912;e.Uhorndotbelow=7920;e.Uhorngrave=7914;e.Uhornhookabove=7916;e.Uhorntilde=7918;e.Uhungarumlaut=368;e.Uhungarumlautcyrillic=1266;e.Uinvertedbreve=534;e.Ukcyrillic=1144;e.Umacron=362;e.Umacroncyrillic=1262;e.Umacrondieresis=7802;e.Umonospace=65333;e.Uogonek=370;e.Upsilon=933;e.Upsilon1=978;e.Upsilonacutehooksymbolgreek=979;e.Upsilonafrican=433;e.Upsilondieresis=939;e.Upsilondieresishooksymbolgreek=980;e.Upsilonhooksymbol=978;e.Upsilontonos=910;e.Uring=366;e.Ushortcyrillic=1038;e.Usmall=63349;e.Ustraightcyrillic=1198;e.Ustraightstrokecyrillic=1200;e.Utilde=360;e.Utildeacute=7800;e.Utildebelow=7796;e.V=86;e.Vcircle=9419;e.Vdotbelow=7806;e.Vecyrillic=1042;e.Vewarmenian=1358;e.Vhook=434;e.Vmonospace=65334;e.Voarmenian=1352;e.Vsmall=63350;e.Vtilde=7804;e.W=87;e.Wacute=7810;e.Wcircle=9420;e.Wcircumflex=372;e.Wdieresis=7812;e.Wdotaccent=7814;e.Wdotbelow=7816;e.Wgrave=7808;e.Wmonospace=65335;e.Wsmall=63351;e.X=88;e.Xcircle=9421;e.Xdieresis=7820;e.Xdotaccent=7818;e.Xeharmenian=1341;e.Xi=926;e.Xmonospace=65336;e.Xsmall=63352;e.Y=89;e.Yacute=221;e.Yacutesmall=63485;e.Yatcyrillic=1122;e.Ycircle=9422;e.Ycircumflex=374;e.Ydieresis=376;e.Ydieresissmall=63487;e.Ydotaccent=7822;e.Ydotbelow=7924;e.Yericyrillic=1067;e.Yerudieresiscyrillic=1272;e.Ygrave=7922;e.Yhook=435;e.Yhookabove=7926;e.Yiarmenian=1349;e.Yicyrillic=1031;e.Yiwnarmenian=1362;e.Ymonospace=65337;e.Ysmall=63353;e.Ytilde=7928;e.Yusbigcyrillic=1130;e.Yusbigiotifiedcyrillic=1132;e.Yuslittlecyrillic=1126;e.Yuslittleiotifiedcyrillic=1128;e.Z=90;e.Zaarmenian=1334;e.Zacute=377;e.Zcaron=381;e.Zcaronsmall=63231;e.Zcircle=9423;e.Zcircumflex=7824;e.Zdot=379;e.Zdotaccent=379;e.Zdotbelow=7826;e.Zecyrillic=1047;e.Zedescendercyrillic=1176;e.Zedieresiscyrillic=1246;e.Zeta=918;e.Zhearmenian=1338;e.Zhebrevecyrillic=1217;e.Zhecyrillic=1046;e.Zhedescendercyrillic=1174;e.Zhedieresiscyrillic=1244;e.Zlinebelow=7828;e.Zmonospace=65338;e.Zsmall=63354;e.Zstroke=437;e.a=97;e.aabengali=2438;e.aacute=225;e.aadeva=2310;e.aagujarati=2694;e.aagurmukhi=2566;e.aamatragurmukhi=2622;e.aarusquare=13059;e.aavowelsignbengali=2494;e.aavowelsigndeva=2366;e.aavowelsigngujarati=2750;e.abbreviationmarkarmenian=1375;e.abbreviationsigndeva=2416;e.abengali=2437;e.abopomofo=12570;e.abreve=259;e.abreveacute=7855;e.abrevecyrillic=1233;e.abrevedotbelow=7863;e.abrevegrave=7857;e.abrevehookabove=7859;e.abrevetilde=7861;e.acaron=462;e.acircle=9424;e.acircumflex=226;e.acircumflexacute=7845;e.acircumflexdotbelow=7853;e.acircumflexgrave=7847;e.acircumflexhookabove=7849;e.acircumflextilde=7851;e.acute=180;e.acutebelowcmb=791;e.acutecmb=769;e.acutecomb=769;e.acutedeva=2388;e.acutelowmod=719;e.acutetonecmb=833;e.acyrillic=1072;e.adblgrave=513;e.addakgurmukhi=2673;e.adeva=2309;e.adieresis=228;e.adieresiscyrillic=1235;e.adieresismacron=479;e.adotbelow=7841;e.adotmacron=481;e.ae=230;e.aeacute=509;e.aekorean=12624;e.aemacron=483;e.afii00208=8213;e.afii08941=8356;e.afii10017=1040;e.afii10018=1041;e.afii10019=1042;e.afii10020=1043;e.afii10021=1044;e.afii10022=1045;e.afii10023=1025;e.afii10024=1046;e.afii10025=1047;e.afii10026=1048;e.afii10027=1049;e.afii10028=1050;e.afii10029=1051;e.afii10030=1052;e.afii10031=1053;e.afii10032=1054;e.afii10033=1055;e.afii10034=1056;e.afii10035=1057;e.afii10036=1058;e.afii10037=1059;e.afii10038=1060;e.afii10039=1061;e.afii10040=1062;e.afii10041=1063;e.afii10042=1064;e.afii10043=1065;e.afii10044=1066;e.afii10045=1067;e.afii10046=1068;e.afii10047=1069;e.afii10048=1070;e.afii10049=1071;e.afii10050=1168;e.afii10051=1026;e.afii10052=1027;e.afii10053=1028;e.afii10054=1029;e.afii10055=1030;e.afii10056=1031;e.afii10057=1032;e.afii10058=1033;e.afii10059=1034;e.afii10060=1035;e.afii10061=1036;e.afii10062=1038;e.afii10063=63172;e.afii10064=63173;e.afii10065=1072;e.afii10066=1073;e.afii10067=1074;e.afii10068=1075;e.afii10069=1076;e.afii10070=1077;e.afii10071=1105;e.afii10072=1078;e.afii10073=1079;e.afii10074=1080;e.afii10075=1081;e.afii10076=1082;e.afii10077=1083;e.afii10078=1084;e.afii10079=1085;e.afii10080=1086;e.afii10081=1087;e.afii10082=1088;e.afii10083=1089;e.afii10084=1090;e.afii10085=1091;e.afii10086=1092;e.afii10087=1093;e.afii10088=1094;e.afii10089=1095;e.afii10090=1096;e.afii10091=1097;e.afii10092=1098;e.afii10093=1099;e.afii10094=1100;e.afii10095=1101;e.afii10096=1102;e.afii10097=1103;e.afii10098=1169;e.afii10099=1106;e.afii10100=1107;e.afii10101=1108;e.afii10102=1109;e.afii10103=1110;e.afii10104=1111;e.afii10105=1112;e.afii10106=1113;e.afii10107=1114;e.afii10108=1115;e.afii10109=1116;e.afii10110=1118;e.afii10145=1039;e.afii10146=1122;e.afii10147=1138;e.afii10148=1140;e.afii10192=63174;e.afii10193=1119;e.afii10194=1123;e.afii10195=1139;e.afii10196=1141;e.afii10831=63175;e.afii10832=63176;e.afii10846=1241;e.afii299=8206;e.afii300=8207;e.afii301=8205;e.afii57381=1642;e.afii57388=1548;e.afii57392=1632;e.afii57393=1633;e.afii57394=1634;e.afii57395=1635;e.afii57396=1636;e.afii57397=1637;e.afii57398=1638;e.afii57399=1639;e.afii57400=1640;e.afii57401=1641;e.afii57403=1563;e.afii57407=1567;e.afii57409=1569;e.afii57410=1570;e.afii57411=1571;e.afii57412=1572;e.afii57413=1573;e.afii57414=1574;e.afii57415=1575;e.afii57416=1576;e.afii57417=1577;e.afii57418=1578;e.afii57419=1579;e.afii57420=1580;e.afii57421=1581;e.afii57422=1582;e.afii57423=1583;e.afii57424=1584;e.afii57425=1585;e.afii57426=1586;e.afii57427=1587;e.afii57428=1588;e.afii57429=1589;e.afii57430=1590;e.afii57431=1591;e.afii57432=1592;e.afii57433=1593;e.afii57434=1594;e.afii57440=1600;e.afii57441=1601;e.afii57442=1602;e.afii57443=1603;e.afii57444=1604;e.afii57445=1605;e.afii57446=1606;e.afii57448=1608;e.afii57449=1609;e.afii57450=1610;e.afii57451=1611;e.afii57452=1612;e.afii57453=1613;e.afii57454=1614;e.afii57455=1615;e.afii57456=1616;e.afii57457=1617;e.afii57458=1618;e.afii57470=1607;e.afii57505=1700;e.afii57506=1662;e.afii57507=1670;e.afii57508=1688;e.afii57509=1711;e.afii57511=1657;e.afii57512=1672;e.afii57513=1681;e.afii57514=1722;e.afii57519=1746;e.afii57534=1749;e.afii57636=8362;e.afii57645=1470;e.afii57658=1475;e.afii57664=1488;e.afii57665=1489;e.afii57666=1490;e.afii57667=1491;e.afii57668=1492;e.afii57669=1493;e.afii57670=1494;e.afii57671=1495;e.afii57672=1496;e.afii57673=1497;e.afii57674=1498;e.afii57675=1499;e.afii57676=1500;e.afii57677=1501;e.afii57678=1502;e.afii57679=1503;e.afii57680=1504;e.afii57681=1505;e.afii57682=1506;e.afii57683=1507;e.afii57684=1508;e.afii57685=1509;e.afii57686=1510;e.afii57687=1511;e.afii57688=1512;e.afii57689=1513;e.afii57690=1514;e.afii57694=64298;e.afii57695=64299;e.afii57700=64331;e.afii57705=64287;e.afii57716=1520;e.afii57717=1521;e.afii57718=1522;e.afii57723=64309;e.afii57793=1460;e.afii57794=1461;e.afii57795=1462;e.afii57796=1467;e.afii57797=1464;e.afii57798=1463;e.afii57799=1456;e.afii57800=1458;e.afii57801=1457;e.afii57802=1459;e.afii57803=1474;e.afii57804=1473;e.afii57806=1465;e.afii57807=1468;e.afii57839=1469;e.afii57841=1471;e.afii57842=1472;e.afii57929=700;e.afii61248=8453;e.afii61289=8467;e.afii61352=8470;e.afii61573=8236;e.afii61574=8237;e.afii61575=8238;e.afii61664=8204;e.afii63167=1645;e.afii64937=701;e.agrave=224;e.agujarati=2693;e.agurmukhi=2565;e.ahiragana=12354;e.ahookabove=7843;e.aibengali=2448;e.aibopomofo=12574;e.aideva=2320;e.aiecyrillic=1237;e.aigujarati=2704;e.aigurmukhi=2576;e.aimatragurmukhi=2632;e.ainarabic=1593;e.ainfinalarabic=65226;e.aininitialarabic=65227;e.ainmedialarabic=65228;e.ainvertedbreve=515;e.aivowelsignbengali=2504;e.aivowelsigndeva=2376;e.aivowelsigngujarati=2760;e.akatakana=12450;e.akatakanahalfwidth=65393;e.akorean=12623;e.alef=1488;e.alefarabic=1575;e.alefdageshhebrew=64304;e.aleffinalarabic=65166;e.alefhamzaabovearabic=1571;e.alefhamzaabovefinalarabic=65156;e.alefhamzabelowarabic=1573;e.alefhamzabelowfinalarabic=65160;e.alefhebrew=1488;e.aleflamedhebrew=64335;e.alefmaddaabovearabic=1570;e.alefmaddaabovefinalarabic=65154;e.alefmaksuraarabic=1609;e.alefmaksurafinalarabic=65264;e.alefmaksurainitialarabic=65267;e.alefmaksuramedialarabic=65268;e.alefpatahhebrew=64302;e.alefqamatshebrew=64303;e.aleph=8501;e.allequal=8780;e.alpha=945;e.alphatonos=940;e.amacron=257;e.amonospace=65345;e.ampersand=38;e.ampersandmonospace=65286;e.ampersandsmall=63270;e.amsquare=13250;e.anbopomofo=12578;e.angbopomofo=12580;e.angbracketleft=12296;e.angbracketright=12297;e.angkhankhuthai=3674;e.angle=8736;e.anglebracketleft=12296;e.anglebracketleftvertical=65087;e.anglebracketright=12297;e.anglebracketrightvertical=65088;e.angleleft=9001;e.angleright=9002;e.angstrom=8491;e.anoteleia=903;e.anudattadeva=2386;e.anusvarabengali=2434;e.anusvaradeva=2306;e.anusvaragujarati=2690;e.aogonek=261;e.apaatosquare=13056;e.aparen=9372;e.apostrophearmenian=1370;e.apostrophemod=700;e.apple=63743;e.approaches=8784;e.approxequal=8776;e.approxequalorimage=8786;e.approximatelyequal=8773;e.araeaekorean=12686;e.araeakorean=12685;e.arc=8978;e.arighthalfring=7834;e.aring=229;e.aringacute=507;e.aringbelow=7681;e.arrowboth=8596;e.arrowdashdown=8675;e.arrowdashleft=8672;e.arrowdashright=8674;e.arrowdashup=8673;e.arrowdblboth=8660;e.arrowdbldown=8659;e.arrowdblleft=8656;e.arrowdblright=8658;e.arrowdblup=8657;e.arrowdown=8595;e.arrowdownleft=8601;e.arrowdownright=8600;e.arrowdownwhite=8681;e.arrowheaddownmod=709;e.arrowheadleftmod=706;e.arrowheadrightmod=707;e.arrowheadupmod=708;e.arrowhorizex=63719;e.arrowleft=8592;e.arrowleftdbl=8656;e.arrowleftdblstroke=8653;e.arrowleftoverright=8646;e.arrowleftwhite=8678;e.arrowright=8594;e.arrowrightdblstroke=8655;e.arrowrightheavy=10142;e.arrowrightoverleft=8644;e.arrowrightwhite=8680;e.arrowtableft=8676;e.arrowtabright=8677;e.arrowup=8593;e.arrowupdn=8597;e.arrowupdnbse=8616;e.arrowupdownbase=8616;e.arrowupleft=8598;e.arrowupleftofdown=8645;e.arrowupright=8599;e.arrowupwhite=8679;e.arrowvertex=63718;e.asciicircum=94;e.asciicircummonospace=65342;e.asciitilde=126;e.asciitildemonospace=65374;e.ascript=593;e.ascriptturned=594;e.asmallhiragana=12353;e.asmallkatakana=12449;e.asmallkatakanahalfwidth=65383;e.asterisk=42;e.asteriskaltonearabic=1645;e.asteriskarabic=1645;e.asteriskmath=8727;e.asteriskmonospace=65290;e.asterisksmall=65121;e.asterism=8258;e.asuperior=63209;e.asymptoticallyequal=8771;e.at=64;e.atilde=227;e.atmonospace=65312;e.atsmall=65131;e.aturned=592;e.aubengali=2452;e.aubopomofo=12576;e.audeva=2324;e.augujarati=2708;e.augurmukhi=2580;e.aulengthmarkbengali=2519;e.aumatragurmukhi=2636;e.auvowelsignbengali=2508;e.auvowelsigndeva=2380;e.auvowelsigngujarati=2764;e.avagrahadeva=2365;e.aybarmenian=1377;e.ayin=1506;e.ayinaltonehebrew=64288;e.ayinhebrew=1506;e.b=98;e.babengali=2476;e.backslash=92;e.backslashmonospace=65340;e.badeva=2348;e.bagujarati=2732;e.bagurmukhi=2604;e.bahiragana=12400;e.bahtthai=3647;e.bakatakana=12496;e.bar=124;e.barmonospace=65372;e.bbopomofo=12549;e.bcircle=9425;e.bdotaccent=7683;e.bdotbelow=7685;e.beamedsixteenthnotes=9836;e.because=8757;e.becyrillic=1073;e.beharabic=1576;e.behfinalarabic=65168;e.behinitialarabic=65169;e.behiragana=12409;e.behmedialarabic=65170;e.behmeeminitialarabic=64671;e.behmeemisolatedarabic=64520;e.behnoonfinalarabic=64621;e.bekatakana=12505;e.benarmenian=1378;e.bet=1489;e.beta=946;e.betasymbolgreek=976;e.betdagesh=64305;e.betdageshhebrew=64305;e.bethebrew=1489;e.betrafehebrew=64332;e.bhabengali=2477;e.bhadeva=2349;e.bhagujarati=2733;e.bhagurmukhi=2605;e.bhook=595;e.bihiragana=12403;e.bikatakana=12499;e.bilabialclick=664;e.bindigurmukhi=2562;e.birusquare=13105;e.blackcircle=9679;e.blackdiamond=9670;e.blackdownpointingtriangle=9660;e.blackleftpointingpointer=9668;e.blackleftpointingtriangle=9664;e.blacklenticularbracketleft=12304;e.blacklenticularbracketleftvertical=65083;e.blacklenticularbracketright=12305;e.blacklenticularbracketrightvertical=65084;e.blacklowerlefttriangle=9699;e.blacklowerrighttriangle=9698;e.blackrectangle=9644;e.blackrightpointingpointer=9658;e.blackrightpointingtriangle=9654;e.blacksmallsquare=9642;e.blacksmilingface=9787;e.blacksquare=9632;e.blackstar=9733;e.blackupperlefttriangle=9700;e.blackupperrighttriangle=9701;e.blackuppointingsmalltriangle=9652;e.blackuppointingtriangle=9650;e.blank=9251;e.blinebelow=7687;e.block=9608;e.bmonospace=65346;e.bobaimaithai=3610;e.bohiragana=12412;e.bokatakana=12508;e.bparen=9373;e.bqsquare=13251;e.braceex=63732;e.braceleft=123;e.braceleftbt=63731;e.braceleftmid=63730;e.braceleftmonospace=65371;e.braceleftsmall=65115;e.bracelefttp=63729;e.braceleftvertical=65079;e.braceright=125;e.bracerightbt=63742;e.bracerightmid=63741;e.bracerightmonospace=65373;e.bracerightsmall=65116;e.bracerighttp=63740;e.bracerightvertical=65080;e.bracketleft=91;e.bracketleftbt=63728;e.bracketleftex=63727;e.bracketleftmonospace=65339;e.bracketlefttp=63726;e.bracketright=93;e.bracketrightbt=63739;e.bracketrightex=63738;e.bracketrightmonospace=65341;e.bracketrighttp=63737;e.breve=728;e.brevebelowcmb=814;e.brevecmb=774;e.breveinvertedbelowcmb=815;e.breveinvertedcmb=785;e.breveinverteddoublecmb=865;e.bridgebelowcmb=810;e.bridgeinvertedbelowcmb=826;e.brokenbar=166;e.bstroke=384;e.bsuperior=63210;e.btopbar=387;e.buhiragana=12406;e.bukatakana=12502;e.bullet=8226;e.bulletinverse=9688;e.bulletoperator=8729;e.bullseye=9678;e.c=99;e.caarmenian=1390;e.cabengali=2458;e.cacute=263;e.cadeva=2330;e.cagujarati=2714;e.cagurmukhi=2586;e.calsquare=13192;e.candrabindubengali=2433;e.candrabinducmb=784;e.candrabindudeva=2305;e.candrabindugujarati=2689;e.capslock=8682;e.careof=8453;e.caron=711;e.caronbelowcmb=812;e.caroncmb=780;e.carriagereturn=8629;e.cbopomofo=12568;e.ccaron=269;e.ccedilla=231;e.ccedillaacute=7689;e.ccircle=9426;e.ccircumflex=265;e.ccurl=597;e.cdot=267;e.cdotaccent=267;e.cdsquare=13253;e.cedilla=184;e.cedillacmb=807;e.cent=162;e.centigrade=8451;e.centinferior=63199;e.centmonospace=65504;e.centoldstyle=63394;e.centsuperior=63200;e.chaarmenian=1401;e.chabengali=2459;e.chadeva=2331;e.chagujarati=2715;e.chagurmukhi=2587;e.chbopomofo=12564;e.cheabkhasiancyrillic=1213;e.checkmark=10003;e.checyrillic=1095;e.chedescenderabkhasiancyrillic=1215;e.chedescendercyrillic=1207;e.chedieresiscyrillic=1269;e.cheharmenian=1395;e.chekhakassiancyrillic=1228;e.cheverticalstrokecyrillic=1209;e.chi=967;e.chieuchacirclekorean=12919;e.chieuchaparenkorean=12823;e.chieuchcirclekorean=12905;e.chieuchkorean=12618;e.chieuchparenkorean=12809;e.chochangthai=3594;e.chochanthai=3592;e.chochingthai=3593;e.chochoethai=3596;e.chook=392;e.cieucacirclekorean=12918;e.cieucaparenkorean=12822;e.cieuccirclekorean=12904;e.cieuckorean=12616;e.cieucparenkorean=12808;e.cieucuparenkorean=12828;e.circle=9675;e.circlecopyrt=169;e.circlemultiply=8855;e.circleot=8857;e.circleplus=8853;e.circlepostalmark=12342;e.circlewithlefthalfblack=9680;e.circlewithrighthalfblack=9681;e.circumflex=710;e.circumflexbelowcmb=813;e.circumflexcmb=770;e.clear=8999;e.clickalveolar=450;e.clickdental=448;e.clicklateral=449;e.clickretroflex=451;e.club=9827;e.clubsuitblack=9827;e.clubsuitwhite=9831;e.cmcubedsquare=13220;e.cmonospace=65347;e.cmsquaredsquare=13216;e.coarmenian=1409;e.colon=58;e.colonmonetary=8353;e.colonmonospace=65306;e.colonsign=8353;e.colonsmall=65109;e.colontriangularhalfmod=721;e.colontriangularmod=720;e.comma=44;e.commaabovecmb=787;e.commaaboverightcmb=789;e.commaaccent=63171;e.commaarabic=1548;e.commaarmenian=1373;e.commainferior=63201;e.commamonospace=65292;e.commareversedabovecmb=788;e.commareversedmod=701;e.commasmall=65104;e.commasuperior=63202;e.commaturnedabovecmb=786;e.commaturnedmod=699;e.compass=9788;e.congruent=8773;e.contourintegral=8750;e.control=8963;e.controlACK=6;e.controlBEL=7;e.controlBS=8;e.controlCAN=24;e.controlCR=13;e.controlDC1=17;e.controlDC2=18;e.controlDC3=19;e.controlDC4=20;e.controlDEL=127;e.controlDLE=16;e.controlEM=25;e.controlENQ=5;e.controlEOT=4;e.controlESC=27;e.controlETB=23;e.controlETX=3;e.controlFF=12;e.controlFS=28;e.controlGS=29;e.controlHT=9;e.controlLF=10;e.controlNAK=21;e.controlNULL=0;e.controlRS=30;e.controlSI=15;e.controlSO=14;e.controlSOT=2;e.controlSTX=1;e.controlSUB=26;e.controlSYN=22;e.controlUS=31;e.controlVT=11;e.copyright=169;e.copyrightsans=63721;e.copyrightserif=63193;e.cornerbracketleft=12300;e.cornerbracketlefthalfwidth=65378;e.cornerbracketleftvertical=65089;e.cornerbracketright=12301;e.cornerbracketrighthalfwidth=65379;e.cornerbracketrightvertical=65090;e.corporationsquare=13183;e.cosquare=13255;e.coverkgsquare=13254;e.cparen=9374;e.cruzeiro=8354;e.cstretched=663;e.curlyand=8911;e.curlyor=8910;e.currency=164;e.cyrBreve=63185;e.cyrFlex=63186;e.cyrbreve=63188;e.cyrflex=63189;e.d=100;e.daarmenian=1380;e.dabengali=2470;e.dadarabic=1590;e.dadeva=2342;e.dadfinalarabic=65214;e.dadinitialarabic=65215;e.dadmedialarabic=65216;e.dagesh=1468;e.dageshhebrew=1468;e.dagger=8224;e.daggerdbl=8225;e.dagujarati=2726;e.dagurmukhi=2598;e.dahiragana=12384;e.dakatakana=12480;e.dalarabic=1583;e.dalet=1491;e.daletdagesh=64307;e.daletdageshhebrew=64307;e.dalethebrew=1491;e.dalfinalarabic=65194;e.dammaarabic=1615;e.dammalowarabic=1615;e.dammatanaltonearabic=1612;e.dammatanarabic=1612;e.danda=2404;e.dargahebrew=1447;e.dargalefthebrew=1447;e.dasiapneumatacyrilliccmb=1157;e.dblGrave=63187;e.dblanglebracketleft=12298;e.dblanglebracketleftvertical=65085;e.dblanglebracketright=12299;e.dblanglebracketrightvertical=65086;e.dblarchinvertedbelowcmb=811;e.dblarrowleft=8660;e.dblarrowright=8658;e.dbldanda=2405;e.dblgrave=63190;e.dblgravecmb=783;e.dblintegral=8748;e.dbllowline=8215;e.dbllowlinecmb=819;e.dbloverlinecmb=831;e.dblprimemod=698;e.dblverticalbar=8214;e.dblverticallineabovecmb=782;e.dbopomofo=12553;e.dbsquare=13256;e.dcaron=271;e.dcedilla=7697;e.dcircle=9427;e.dcircumflexbelow=7699;e.dcroat=273;e.ddabengali=2465;e.ddadeva=2337;e.ddagujarati=2721;e.ddagurmukhi=2593;e.ddalarabic=1672;e.ddalfinalarabic=64393;e.dddhadeva=2396;e.ddhabengali=2466;e.ddhadeva=2338;e.ddhagujarati=2722;e.ddhagurmukhi=2594;e.ddotaccent=7691;e.ddotbelow=7693;e.decimalseparatorarabic=1643;e.decimalseparatorpersian=1643;e.decyrillic=1076;e.degree=176;e.dehihebrew=1453;e.dehiragana=12391;e.deicoptic=1007;e.dekatakana=12487;e.deleteleft=9003;e.deleteright=8998;e.delta=948;e.deltaturned=397;e.denominatorminusonenumeratorbengali=2552;e.dezh=676;e.dhabengali=2471;e.dhadeva=2343;e.dhagujarati=2727;e.dhagurmukhi=2599;e.dhook=599;e.dialytikatonos=901;e.dialytikatonoscmb=836;e.diamond=9830;e.diamondsuitwhite=9826;e.dieresis=168;e.dieresisacute=63191;e.dieresisbelowcmb=804;e.dieresiscmb=776;e.dieresisgrave=63192;e.dieresistonos=901;e.dihiragana=12386;e.dikatakana=12482;e.dittomark=12291;e.divide=247;e.divides=8739;e.divisionslash=8725;e.djecyrillic=1106;e.dkshade=9619;e.dlinebelow=7695;e.dlsquare=13207;e.dmacron=273;e.dmonospace=65348;e.dnblock=9604;e.dochadathai=3598;e.dodekthai=3604;e.dohiragana=12393;e.dokatakana=12489;e.dollar=36;e.dollarinferior=63203;e.dollarmonospace=65284;e.dollaroldstyle=63268;e.dollarsmall=65129;e.dollarsuperior=63204;e.dong=8363;e.dorusquare=13094;e.dotaccent=729;e.dotaccentcmb=775;e.dotbelowcmb=803;e.dotbelowcomb=803;e.dotkatakana=12539;e.dotlessi=305;e.dotlessj=63166;e.dotlessjstrokehook=644;e.dotmath=8901;e.dottedcircle=9676;e.doubleyodpatah=64287;e.doubleyodpatahhebrew=64287;e.downtackbelowcmb=798;e.downtackmod=725;e.dparen=9375;e.dsuperior=63211;e.dtail=598;e.dtopbar=396;e.duhiragana=12389;e.dukatakana=12485;e.dz=499;e.dzaltone=675;e.dzcaron=454;e.dzcurl=677;e.dzeabkhasiancyrillic=1249;e.dzecyrillic=1109;e.dzhecyrillic=1119;e.e=101;e.eacute=233;e.earth=9793;e.ebengali=2447;e.ebopomofo=12572;e.ebreve=277;e.ecandradeva=2317;e.ecandragujarati=2701;e.ecandravowelsigndeva=2373;e.ecandravowelsigngujarati=2757;e.ecaron=283;e.ecedillabreve=7709;e.echarmenian=1381;e.echyiwnarmenian=1415;e.ecircle=9428;e.ecircumflex=234;e.ecircumflexacute=7871;e.ecircumflexbelow=7705;e.ecircumflexdotbelow=7879;e.ecircumflexgrave=7873;e.ecircumflexhookabove=7875;e.ecircumflextilde=7877;e.ecyrillic=1108;e.edblgrave=517;e.edeva=2319;e.edieresis=235;e.edot=279;e.edotaccent=279;e.edotbelow=7865;e.eegurmukhi=2575;e.eematragurmukhi=2631;e.efcyrillic=1092;e.egrave=232;e.egujarati=2703;e.eharmenian=1383;e.ehbopomofo=12573;e.ehiragana=12360;e.ehookabove=7867;e.eibopomofo=12575;e.eight=56;e.eightarabic=1640;e.eightbengali=2542;e.eightcircle=9319;e.eightcircleinversesansserif=10129;e.eightdeva=2414;e.eighteencircle=9329;e.eighteenparen=9349;e.eighteenperiod=9369;e.eightgujarati=2798;e.eightgurmukhi=2670;e.eighthackarabic=1640;e.eighthangzhou=12328;e.eighthnotebeamed=9835;e.eightideographicparen=12839;e.eightinferior=8328;e.eightmonospace=65304;e.eightoldstyle=63288;e.eightparen=9339;e.eightperiod=9359;e.eightpersian=1784;e.eightroman=8567;e.eightsuperior=8312;e.eightthai=3672;e.einvertedbreve=519;e.eiotifiedcyrillic=1125;e.ekatakana=12456;e.ekatakanahalfwidth=65396;e.ekonkargurmukhi=2676;e.ekorean=12628;e.elcyrillic=1083;e.element=8712;e.elevencircle=9322;e.elevenparen=9342;e.elevenperiod=9362;e.elevenroman=8570;e.ellipsis=8230;e.ellipsisvertical=8942;e.emacron=275;e.emacronacute=7703;e.emacrongrave=7701;e.emcyrillic=1084;e.emdash=8212;e.emdashvertical=65073;e.emonospace=65349;e.emphasismarkarmenian=1371;e.emptyset=8709;e.enbopomofo=12579;e.encyrillic=1085;e.endash=8211;e.endashvertical=65074;e.endescendercyrillic=1187;e.eng=331;e.engbopomofo=12581;e.enghecyrillic=1189;e.enhookcyrillic=1224;e.enspace=8194;e.eogonek=281;e.eokorean=12627;e.eopen=603;e.eopenclosed=666;e.eopenreversed=604;e.eopenreversedclosed=606;e.eopenreversedhook=605;e.eparen=9376;e.epsilon=949;e.epsilontonos=941;e.equal=61;e.equalmonospace=65309;e.equalsmall=65126;e.equalsuperior=8316;e.equivalence=8801;e.erbopomofo=12582;e.ercyrillic=1088;e.ereversed=600;e.ereversedcyrillic=1101;e.escyrillic=1089;e.esdescendercyrillic=1195;e.esh=643;e.eshcurl=646;e.eshortdeva=2318;e.eshortvowelsigndeva=2374;e.eshreversedloop=426;e.eshsquatreversed=645;e.esmallhiragana=12359;e.esmallkatakana=12455;e.esmallkatakanahalfwidth=65386;e.estimated=8494;e.esuperior=63212;e.eta=951;e.etarmenian=1384;e.etatonos=942;e.eth=240;e.etilde=7869;e.etildebelow=7707;e.etnahtafoukhhebrew=1425;e.etnahtafoukhlefthebrew=1425;e.etnahtahebrew=1425;e.etnahtalefthebrew=1425;e.eturned=477;e.eukorean=12641;e.euro=8364;e.evowelsignbengali=2503;e.evowelsigndeva=2375;e.evowelsigngujarati=2759;e.exclam=33;e.exclamarmenian=1372;e.exclamdbl=8252;e.exclamdown=161;e.exclamdownsmall=63393;e.exclammonospace=65281;e.exclamsmall=63265;e.existential=8707;e.ezh=658;e.ezhcaron=495;e.ezhcurl=659;e.ezhreversed=441;e.ezhtail=442;e.f=102;e.fadeva=2398;e.fagurmukhi=2654;e.fahrenheit=8457;e.fathaarabic=1614;e.fathalowarabic=1614;e.fathatanarabic=1611;e.fbopomofo=12552;e.fcircle=9429;e.fdotaccent=7711;e.feharabic=1601;e.feharmenian=1414;e.fehfinalarabic=65234;e.fehinitialarabic=65235;e.fehmedialarabic=65236;e.feicoptic=997;e.female=9792;e.ff=64256;e.f_f=64256;e.ffi=64259;e.ffl=64260;e.fi=64257;e.fifteencircle=9326;e.fifteenparen=9346;e.fifteenperiod=9366;e.figuredash=8210;e.filledbox=9632;e.filledrect=9644;e.finalkaf=1498;e.finalkafdagesh=64314;e.finalkafdageshhebrew=64314;e.finalkafhebrew=1498;e.finalmem=1501;e.finalmemhebrew=1501;e.finalnun=1503;e.finalnunhebrew=1503;e.finalpe=1507;e.finalpehebrew=1507;e.finaltsadi=1509;e.finaltsadihebrew=1509;e.firsttonechinese=713;e.fisheye=9673;e.fitacyrillic=1139;e.five=53;e.fivearabic=1637;e.fivebengali=2539;e.fivecircle=9316;e.fivecircleinversesansserif=10126;e.fivedeva=2411;e.fiveeighths=8541;e.fivegujarati=2795;e.fivegurmukhi=2667;e.fivehackarabic=1637;e.fivehangzhou=12325;e.fiveideographicparen=12836;e.fiveinferior=8325;e.fivemonospace=65301;e.fiveoldstyle=63285;e.fiveparen=9336;e.fiveperiod=9356;e.fivepersian=1781;e.fiveroman=8564;e.fivesuperior=8309;e.fivethai=3669;e.fl=64258;e.florin=402;e.fmonospace=65350;e.fmsquare=13209;e.fofanthai=3615;e.fofathai=3613;e.fongmanthai=3663;e.forall=8704;e.four=52;e.fourarabic=1636;e.fourbengali=2538;e.fourcircle=9315;e.fourcircleinversesansserif=10125;e.fourdeva=2410;e.fourgujarati=2794;e.fourgurmukhi=2666;e.fourhackarabic=1636;e.fourhangzhou=12324;e.fourideographicparen=12835;e.fourinferior=8324;e.fourmonospace=65300;e.fournumeratorbengali=2551;e.fouroldstyle=63284;e.fourparen=9335;e.fourperiod=9355;e.fourpersian=1780;e.fourroman=8563;e.foursuperior=8308;e.fourteencircle=9325;e.fourteenparen=9345;e.fourteenperiod=9365;e.fourthai=3668;e.fourthtonechinese=715;e.fparen=9377;e.fraction=8260;e.franc=8355;e.g=103;e.gabengali=2455;e.gacute=501;e.gadeva=2327;e.gafarabic=1711;e.gaffinalarabic=64403;e.gafinitialarabic=64404;e.gafmedialarabic=64405;e.gagujarati=2711;e.gagurmukhi=2583;e.gahiragana=12364;e.gakatakana=12460;e.gamma=947;e.gammalatinsmall=611;e.gammasuperior=736;e.gangiacoptic=1003;e.gbopomofo=12557;e.gbreve=287;e.gcaron=487;e.gcedilla=291;e.gcircle=9430;e.gcircumflex=285;e.gcommaaccent=291;e.gdot=289;e.gdotaccent=289;e.gecyrillic=1075;e.gehiragana=12370;e.gekatakana=12466;e.geometricallyequal=8785;e.gereshaccenthebrew=1436;e.gereshhebrew=1523;e.gereshmuqdamhebrew=1437;e.germandbls=223;e.gershayimaccenthebrew=1438;e.gershayimhebrew=1524;e.getamark=12307;e.ghabengali=2456;e.ghadarmenian=1394;e.ghadeva=2328;e.ghagujarati=2712;e.ghagurmukhi=2584;e.ghainarabic=1594;e.ghainfinalarabic=65230;e.ghaininitialarabic=65231;e.ghainmedialarabic=65232;e.ghemiddlehookcyrillic=1173;e.ghestrokecyrillic=1171;e.gheupturncyrillic=1169;e.ghhadeva=2394;e.ghhagurmukhi=2650;e.ghook=608;e.ghzsquare=13203;e.gihiragana=12366;e.gikatakana=12462;e.gimarmenian=1379;e.gimel=1490;e.gimeldagesh=64306;e.gimeldageshhebrew=64306;e.gimelhebrew=1490;e.gjecyrillic=1107;e.glottalinvertedstroke=446;e.glottalstop=660;e.glottalstopinverted=662;e.glottalstopmod=704;e.glottalstopreversed=661;e.glottalstopreversedmod=705;e.glottalstopreversedsuperior=740;e.glottalstopstroke=673;e.glottalstopstrokereversed=674;e.gmacron=7713;e.gmonospace=65351;e.gohiragana=12372;e.gokatakana=12468;e.gparen=9378;e.gpasquare=13228;e.gradient=8711;e.grave=96;e.gravebelowcmb=790;e.gravecmb=768;e.gravecomb=768;e.gravedeva=2387;e.gravelowmod=718;e.gravemonospace=65344;e.gravetonecmb=832;e.greater=62;e.greaterequal=8805;e.greaterequalorless=8923;e.greatermonospace=65310;e.greaterorequivalent=8819;e.greaterorless=8823;e.greateroverequal=8807;e.greatersmall=65125;e.gscript=609;e.gstroke=485;e.guhiragana=12368;e.guillemotleft=171;e.guillemotright=187;e.guilsinglleft=8249;e.guilsinglright=8250;e.gukatakana=12464;e.guramusquare=13080;e.gysquare=13257;e.h=104;e.haabkhasiancyrillic=1193;e.haaltonearabic=1729;e.habengali=2489;e.hadescendercyrillic=1203;e.hadeva=2361;e.hagujarati=2745;e.hagurmukhi=2617;e.haharabic=1581;e.hahfinalarabic=65186;e.hahinitialarabic=65187;e.hahiragana=12399;e.hahmedialarabic=65188;e.haitusquare=13098;e.hakatakana=12495;e.hakatakanahalfwidth=65418;e.halantgurmukhi=2637;e.hamzaarabic=1569;e.hamzalowarabic=1569;e.hangulfiller=12644;e.hardsigncyrillic=1098;e.harpoonleftbarbup=8636;e.harpoonrightbarbup=8640;e.hasquare=13258;e.hatafpatah=1458;e.hatafpatah16=1458;e.hatafpatah23=1458;e.hatafpatah2f=1458;e.hatafpatahhebrew=1458;e.hatafpatahnarrowhebrew=1458;e.hatafpatahquarterhebrew=1458;e.hatafpatahwidehebrew=1458;e.hatafqamats=1459;e.hatafqamats1b=1459;e.hatafqamats28=1459;e.hatafqamats34=1459;e.hatafqamatshebrew=1459;e.hatafqamatsnarrowhebrew=1459;e.hatafqamatsquarterhebrew=1459;e.hatafqamatswidehebrew=1459;e.hatafsegol=1457;e.hatafsegol17=1457;e.hatafsegol24=1457;e.hatafsegol30=1457;e.hatafsegolhebrew=1457;e.hatafsegolnarrowhebrew=1457;e.hatafsegolquarterhebrew=1457;e.hatafsegolwidehebrew=1457;e.hbar=295;e.hbopomofo=12559;e.hbrevebelow=7723;e.hcedilla=7721;e.hcircle=9431;e.hcircumflex=293;e.hdieresis=7719;e.hdotaccent=7715;e.hdotbelow=7717;e.he=1492;e.heart=9829;e.heartsuitblack=9829;e.heartsuitwhite=9825;e.hedagesh=64308;e.hedageshhebrew=64308;e.hehaltonearabic=1729;e.heharabic=1607;e.hehebrew=1492;e.hehfinalaltonearabic=64423;e.hehfinalalttwoarabic=65258;e.hehfinalarabic=65258;e.hehhamzaabovefinalarabic=64421;e.hehhamzaaboveisolatedarabic=64420;e.hehinitialaltonearabic=64424;e.hehinitialarabic=65259;e.hehiragana=12408;e.hehmedialaltonearabic=64425;e.hehmedialarabic=65260;e.heiseierasquare=13179;e.hekatakana=12504;e.hekatakanahalfwidth=65421;e.hekutaarusquare=13110;e.henghook=615;e.herutusquare=13113;e.het=1495;e.hethebrew=1495;e.hhook=614;e.hhooksuperior=689;e.hieuhacirclekorean=12923;e.hieuhaparenkorean=12827;e.hieuhcirclekorean=12909;e.hieuhkorean=12622;e.hieuhparenkorean=12813;e.hihiragana=12402;e.hikatakana=12498;e.hikatakanahalfwidth=65419;e.hiriq=1460;e.hiriq14=1460;e.hiriq21=1460;e.hiriq2d=1460;e.hiriqhebrew=1460;e.hiriqnarrowhebrew=1460;e.hiriqquarterhebrew=1460;e.hiriqwidehebrew=1460;e.hlinebelow=7830;e.hmonospace=65352;e.hoarmenian=1392;e.hohipthai=3627;e.hohiragana=12411;e.hokatakana=12507;e.hokatakanahalfwidth=65422;e.holam=1465;e.holam19=1465;e.holam26=1465;e.holam32=1465;e.holamhebrew=1465;e.holamnarrowhebrew=1465;e.holamquarterhebrew=1465;e.holamwidehebrew=1465;e.honokhukthai=3630;e.hookabovecomb=777;e.hookcmb=777;e.hookpalatalizedbelowcmb=801;e.hookretroflexbelowcmb=802;e.hoonsquare=13122;e.horicoptic=1001;e.horizontalbar=8213;e.horncmb=795;e.hotsprings=9832;e.house=8962;e.hparen=9379;e.hsuperior=688;e.hturned=613;e.huhiragana=12405;e.huiitosquare=13107;e.hukatakana=12501;e.hukatakanahalfwidth=65420;e.hungarumlaut=733;e.hungarumlautcmb=779;e.hv=405;e.hyphen=45;e.hypheninferior=63205;e.hyphenmonospace=65293;e.hyphensmall=65123;e.hyphensuperior=63206;e.hyphentwo=8208;e.i=105;e.iacute=237;e.iacyrillic=1103;e.ibengali=2439;e.ibopomofo=12583;e.ibreve=301;e.icaron=464;e.icircle=9432;e.icircumflex=238;e.icyrillic=1110;e.idblgrave=521;e.ideographearthcircle=12943;e.ideographfirecircle=12939;e.ideographicallianceparen=12863;e.ideographiccallparen=12858;e.ideographiccentrecircle=12965;e.ideographicclose=12294;e.ideographiccomma=12289;e.ideographiccommaleft=65380;e.ideographiccongratulationparen=12855;e.ideographiccorrectcircle=12963;e.ideographicearthparen=12847;e.ideographicenterpriseparen=12861;e.ideographicexcellentcircle=12957;e.ideographicfestivalparen=12864;e.ideographicfinancialcircle=12950;e.ideographicfinancialparen=12854;e.ideographicfireparen=12843;e.ideographichaveparen=12850;e.ideographichighcircle=12964;e.ideographiciterationmark=12293;e.ideographiclaborcircle=12952;e.ideographiclaborparen=12856;e.ideographicleftcircle=12967;e.ideographiclowcircle=12966;e.ideographicmedicinecircle=12969;e.ideographicmetalparen=12846;e.ideographicmoonparen=12842;e.ideographicnameparen=12852;e.ideographicperiod=12290;e.ideographicprintcircle=12958;e.ideographicreachparen=12867;e.ideographicrepresentparen=12857;e.ideographicresourceparen=12862;e.ideographicrightcircle=12968;e.ideographicsecretcircle=12953;e.ideographicselfparen=12866;e.ideographicsocietyparen=12851;e.ideographicspace=12288;e.ideographicspecialparen=12853;e.ideographicstockparen=12849;e.ideographicstudyparen=12859;e.ideographicsunparen=12848;e.ideographicsuperviseparen=12860;e.ideographicwaterparen=12844;e.ideographicwoodparen=12845;e.ideographiczero=12295;e.ideographmetalcircle=12942;e.ideographmooncircle=12938;e.ideographnamecircle=12948;e.ideographsuncircle=12944;e.ideographwatercircle=12940;e.ideographwoodcircle=12941;e.ideva=2311;e.idieresis=239;e.idieresisacute=7727;e.idieresiscyrillic=1253;e.idotbelow=7883;e.iebrevecyrillic=1239;e.iecyrillic=1077;e.ieungacirclekorean=12917;e.ieungaparenkorean=12821;e.ieungcirclekorean=12903;e.ieungkorean=12615;e.ieungparenkorean=12807;e.igrave=236;e.igujarati=2695;e.igurmukhi=2567;e.ihiragana=12356;e.ihookabove=7881;e.iibengali=2440;e.iicyrillic=1080;e.iideva=2312;e.iigujarati=2696;e.iigurmukhi=2568;e.iimatragurmukhi=2624;e.iinvertedbreve=523;e.iishortcyrillic=1081;e.iivowelsignbengali=2496;e.iivowelsigndeva=2368;e.iivowelsigngujarati=2752;e.ij=307;e.ikatakana=12452;e.ikatakanahalfwidth=65394;e.ikorean=12643;e.ilde=732;e.iluyhebrew=1452;e.imacron=299;e.imacroncyrillic=1251;e.imageorapproximatelyequal=8787;e.imatragurmukhi=2623;e.imonospace=65353;e.increment=8710;e.infinity=8734;e.iniarmenian=1387;e.integral=8747;e.integralbottom=8993;e.integralbt=8993;e.integralex=63733;e.integraltop=8992;e.integraltp=8992;e.intersection=8745;e.intisquare=13061;e.invbullet=9688;e.invcircle=9689;e.invsmileface=9787;e.iocyrillic=1105;e.iogonek=303;e.iota=953;e.iotadieresis=970;e.iotadieresistonos=912;e.iotalatin=617;e.iotatonos=943;e.iparen=9380;e.irigurmukhi=2674;e.ismallhiragana=12355;e.ismallkatakana=12451;e.ismallkatakanahalfwidth=65384;e.issharbengali=2554;e.istroke=616;e.isuperior=63213;e.iterationhiragana=12445;e.iterationkatakana=12541;e.itilde=297;e.itildebelow=7725;e.iubopomofo=12585;e.iucyrillic=1102;e.ivowelsignbengali=2495;e.ivowelsigndeva=2367;e.ivowelsigngujarati=2751;e.izhitsacyrillic=1141;e.izhitsadblgravecyrillic=1143;e.j=106;e.jaarmenian=1393;e.jabengali=2460;e.jadeva=2332;e.jagujarati=2716;e.jagurmukhi=2588;e.jbopomofo=12560;e.jcaron=496;e.jcircle=9433;e.jcircumflex=309;e.jcrossedtail=669;e.jdotlessstroke=607;e.jecyrillic=1112;e.jeemarabic=1580;e.jeemfinalarabic=65182;e.jeeminitialarabic=65183;e.jeemmedialarabic=65184;e.jeharabic=1688;e.jehfinalarabic=64395;e.jhabengali=2461;e.jhadeva=2333;e.jhagujarati=2717;e.jhagurmukhi=2589;e.jheharmenian=1403;e.jis=12292;e.jmonospace=65354;e.jparen=9381;e.jsuperior=690;e.k=107;e.kabashkircyrillic=1185;e.kabengali=2453;e.kacute=7729;e.kacyrillic=1082;e.kadescendercyrillic=1179;e.kadeva=2325;e.kaf=1499;e.kafarabic=1603;e.kafdagesh=64315;e.kafdageshhebrew=64315;e.kaffinalarabic=65242;e.kafhebrew=1499;e.kafinitialarabic=65243;e.kafmedialarabic=65244;e.kafrafehebrew=64333;e.kagujarati=2709;e.kagurmukhi=2581;e.kahiragana=12363;e.kahookcyrillic=1220;e.kakatakana=12459;e.kakatakanahalfwidth=65398;e.kappa=954;e.kappasymbolgreek=1008;e.kapyeounmieumkorean=12657;e.kapyeounphieuphkorean=12676;e.kapyeounpieupkorean=12664;e.kapyeounssangpieupkorean=12665;e.karoriisquare=13069;e.kashidaautoarabic=1600;e.kashidaautonosidebearingarabic=1600;e.kasmallkatakana=12533;e.kasquare=13188;e.kasraarabic=1616;e.kasratanarabic=1613;e.kastrokecyrillic=1183;e.katahiraprolongmarkhalfwidth=65392;e.kaverticalstrokecyrillic=1181;e.kbopomofo=12558;e.kcalsquare=13193;e.kcaron=489;e.kcedilla=311;e.kcircle=9434;e.kcommaaccent=311;e.kdotbelow=7731;e.keharmenian=1412;e.kehiragana=12369;e.kekatakana=12465;e.kekatakanahalfwidth=65401;e.kenarmenian=1391;e.kesmallkatakana=12534;e.kgreenlandic=312;e.khabengali=2454;e.khacyrillic=1093;e.khadeva=2326;e.khagujarati=2710;e.khagurmukhi=2582;e.khaharabic=1582;e.khahfinalarabic=65190;e.khahinitialarabic=65191;e.khahmedialarabic=65192;e.kheicoptic=999;e.khhadeva=2393;e.khhagurmukhi=2649;e.khieukhacirclekorean=12920;e.khieukhaparenkorean=12824;e.khieukhcirclekorean=12906;e.khieukhkorean=12619;e.khieukhparenkorean=12810;e.khokhaithai=3586;e.khokhonthai=3589;e.khokhuatthai=3587;e.khokhwaithai=3588;e.khomutthai=3675;e.khook=409;e.khorakhangthai=3590;e.khzsquare=13201;e.kihiragana=12365;e.kikatakana=12461;e.kikatakanahalfwidth=65399;e.kiroguramusquare=13077;e.kiromeetorusquare=13078;e.kirosquare=13076;e.kiyeokacirclekorean=12910;e.kiyeokaparenkorean=12814;e.kiyeokcirclekorean=12896;e.kiyeokkorean=12593;e.kiyeokparenkorean=12800;e.kiyeoksioskorean=12595;e.kjecyrillic=1116;e.klinebelow=7733;e.klsquare=13208;e.kmcubedsquare=13222;e.kmonospace=65355;e.kmsquaredsquare=13218;e.kohiragana=12371;e.kohmsquare=13248;e.kokaithai=3585;e.kokatakana=12467;e.kokatakanahalfwidth=65402;e.kooposquare=13086;e.koppacyrillic=1153;e.koreanstandardsymbol=12927;e.koroniscmb=835;e.kparen=9382;e.kpasquare=13226;e.ksicyrillic=1135;e.ktsquare=13263;e.kturned=670;e.kuhiragana=12367;e.kukatakana=12463;e.kukatakanahalfwidth=65400;e.kvsquare=13240;e.kwsquare=13246;e.l=108;e.labengali=2482;e.lacute=314;e.ladeva=2354;e.lagujarati=2738;e.lagurmukhi=2610;e.lakkhangyaothai=3653;e.lamaleffinalarabic=65276;e.lamalefhamzaabovefinalarabic=65272;e.lamalefhamzaaboveisolatedarabic=65271;e.lamalefhamzabelowfinalarabic=65274;e.lamalefhamzabelowisolatedarabic=65273;e.lamalefisolatedarabic=65275;e.lamalefmaddaabovefinalarabic=65270;e.lamalefmaddaaboveisolatedarabic=65269;e.lamarabic=1604;e.lambda=955;e.lambdastroke=411;e.lamed=1500;e.lameddagesh=64316;e.lameddageshhebrew=64316;e.lamedhebrew=1500;e.lamfinalarabic=65246;e.lamhahinitialarabic=64714;e.laminitialarabic=65247;e.lamjeeminitialarabic=64713;e.lamkhahinitialarabic=64715;e.lamlamhehisolatedarabic=65010;e.lammedialarabic=65248;e.lammeemhahinitialarabic=64904;e.lammeeminitialarabic=64716;e.largecircle=9711;e.lbar=410;e.lbelt=620;e.lbopomofo=12556;e.lcaron=318;e.lcedilla=316;e.lcircle=9435;e.lcircumflexbelow=7741;e.lcommaaccent=316;e.ldot=320;e.ldotaccent=320;e.ldotbelow=7735;e.ldotbelowmacron=7737;e.leftangleabovecmb=794;e.lefttackbelowcmb=792;e.less=60;e.lessequal=8804;e.lessequalorgreater=8922;e.lessmonospace=65308;e.lessorequivalent=8818;e.lessorgreater=8822;e.lessoverequal=8806;e.lesssmall=65124;e.lezh=622;e.lfblock=9612;e.lhookretroflex=621;e.lira=8356;e.liwnarmenian=1388;e.lj=457;e.ljecyrillic=1113;e.ll=63168;e.lladeva=2355;e.llagujarati=2739;e.llinebelow=7739;e.llladeva=2356;e.llvocalicbengali=2529;e.llvocalicdeva=2401;e.llvocalicvowelsignbengali=2531;e.llvocalicvowelsigndeva=2403;e.lmiddletilde=619;e.lmonospace=65356;e.lmsquare=13264;e.lochulathai=3628;e.logicaland=8743;e.logicalnot=172;e.logicalnotreversed=8976;e.logicalor=8744;e.lolingthai=3621;e.longs=383;e.lowlinecenterline=65102;e.lowlinecmb=818;e.lowlinedashed=65101;e.lozenge=9674;e.lparen=9383;e.lslash=322;e.lsquare=8467;e.lsuperior=63214;e.ltshade=9617;e.luthai=3622;e.lvocalicbengali=2444;e.lvocalicdeva=2316;e.lvocalicvowelsignbengali=2530;e.lvocalicvowelsigndeva=2402;e.lxsquare=13267;e.m=109;e.mabengali=2478;e.macron=175;e.macronbelowcmb=817;e.macroncmb=772;e.macronlowmod=717;e.macronmonospace=65507;e.macute=7743;e.madeva=2350;e.magujarati=2734;e.magurmukhi=2606;e.mahapakhhebrew=1444;e.mahapakhlefthebrew=1444;e.mahiragana=12414;e.maichattawalowleftthai=63637;e.maichattawalowrightthai=63636;e.maichattawathai=3659;e.maichattawaupperleftthai=63635;e.maieklowleftthai=63628;e.maieklowrightthai=63627;e.maiekthai=3656;e.maiekupperleftthai=63626;e.maihanakatleftthai=63620;e.maihanakatthai=3633;e.maitaikhuleftthai=63625;e.maitaikhuthai=3655;e.maitholowleftthai=63631;e.maitholowrightthai=63630;e.maithothai=3657;e.maithoupperleftthai=63629;e.maitrilowleftthai=63634;e.maitrilowrightthai=63633;e.maitrithai=3658;e.maitriupperleftthai=63632;e.maiyamokthai=3654;e.makatakana=12510;e.makatakanahalfwidth=65423;e.male=9794;e.mansyonsquare=13127;e.maqafhebrew=1470;e.mars=9794;e.masoracirclehebrew=1455;e.masquare=13187;e.mbopomofo=12551;e.mbsquare=13268;e.mcircle=9436;e.mcubedsquare=13221;e.mdotaccent=7745;e.mdotbelow=7747;e.meemarabic=1605;e.meemfinalarabic=65250;e.meeminitialarabic=65251;e.meemmedialarabic=65252;e.meemmeeminitialarabic=64721;e.meemmeemisolatedarabic=64584;e.meetorusquare=13133;e.mehiragana=12417;e.meizierasquare=13182;e.mekatakana=12513;e.mekatakanahalfwidth=65426;e.mem=1502;e.memdagesh=64318;e.memdageshhebrew=64318;e.memhebrew=1502;e.menarmenian=1396;e.merkhahebrew=1445;e.merkhakefulahebrew=1446;e.merkhakefulalefthebrew=1446;e.merkhalefthebrew=1445;e.mhook=625;e.mhzsquare=13202;e.middledotkatakanahalfwidth=65381;e.middot=183;e.mieumacirclekorean=12914;e.mieumaparenkorean=12818;e.mieumcirclekorean=12900;e.mieumkorean=12609;e.mieumpansioskorean=12656;e.mieumparenkorean=12804;e.mieumpieupkorean=12654;e.mieumsioskorean=12655;e.mihiragana=12415;e.mikatakana=12511;e.mikatakanahalfwidth=65424;e.minus=8722;e.minusbelowcmb=800;e.minuscircle=8854;e.minusmod=727;e.minusplus=8723;e.minute=8242;e.miribaarusquare=13130;e.mirisquare=13129;e.mlonglegturned=624;e.mlsquare=13206;e.mmcubedsquare=13219;e.mmonospace=65357;e.mmsquaredsquare=13215;e.mohiragana=12418;e.mohmsquare=13249;e.mokatakana=12514;e.mokatakanahalfwidth=65427;e.molsquare=13270;e.momathai=3617;e.moverssquare=13223;e.moverssquaredsquare=13224;e.mparen=9384;e.mpasquare=13227;e.mssquare=13235;e.msuperior=63215;e.mturned=623;e.mu=181;e.mu1=181;e.muasquare=13186;e.muchgreater=8811;e.muchless=8810;e.mufsquare=13196;e.mugreek=956;e.mugsquare=13197;e.muhiragana=12416;e.mukatakana=12512;e.mukatakanahalfwidth=65425;e.mulsquare=13205;e.multiply=215;e.mumsquare=13211;e.munahhebrew=1443;e.munahlefthebrew=1443;e.musicalnote=9834;e.musicalnotedbl=9835;e.musicflatsign=9837;e.musicsharpsign=9839;e.mussquare=13234;e.muvsquare=13238;e.muwsquare=13244;e.mvmegasquare=13241;e.mvsquare=13239;e.mwmegasquare=13247;e.mwsquare=13245;e.n=110;e.nabengali=2472;e.nabla=8711;e.nacute=324;e.nadeva=2344;e.nagujarati=2728;e.nagurmukhi=2600;e.nahiragana=12394;e.nakatakana=12490;e.nakatakanahalfwidth=65413;e.napostrophe=329;e.nasquare=13185;e.nbopomofo=12555;e.nbspace=160;e.ncaron=328;e.ncedilla=326;e.ncircle=9437;e.ncircumflexbelow=7755;e.ncommaaccent=326;e.ndotaccent=7749;e.ndotbelow=7751;e.nehiragana=12397;e.nekatakana=12493;e.nekatakanahalfwidth=65416;e.newsheqelsign=8362;e.nfsquare=13195;e.ngabengali=2457;e.ngadeva=2329;e.ngagujarati=2713;e.ngagurmukhi=2585;e.ngonguthai=3591;e.nhiragana=12435;e.nhookleft=626;e.nhookretroflex=627;e.nieunacirclekorean=12911;e.nieunaparenkorean=12815;e.nieuncieuckorean=12597;e.nieuncirclekorean=12897;e.nieunhieuhkorean=12598;e.nieunkorean=12596;e.nieunpansioskorean=12648;e.nieunparenkorean=12801;e.nieunsioskorean=12647;e.nieuntikeutkorean=12646;e.nihiragana=12395;e.nikatakana=12491;e.nikatakanahalfwidth=65414;e.nikhahitleftthai=63641;e.nikhahitthai=3661;e.nine=57;e.ninearabic=1641;e.ninebengali=2543;e.ninecircle=9320;e.ninecircleinversesansserif=10130;e.ninedeva=2415;e.ninegujarati=2799;e.ninegurmukhi=2671;e.ninehackarabic=1641;e.ninehangzhou=12329;e.nineideographicparen=12840;e.nineinferior=8329;e.ninemonospace=65305;e.nineoldstyle=63289;e.nineparen=9340;e.nineperiod=9360;e.ninepersian=1785;e.nineroman=8568;e.ninesuperior=8313;e.nineteencircle=9330;e.nineteenparen=9350;e.nineteenperiod=9370;e.ninethai=3673;e.nj=460;e.njecyrillic=1114;e.nkatakana=12531;e.nkatakanahalfwidth=65437;e.nlegrightlong=414;e.nlinebelow=7753;e.nmonospace=65358;e.nmsquare=13210;e.nnabengali=2467;e.nnadeva=2339;e.nnagujarati=2723;e.nnagurmukhi=2595;e.nnnadeva=2345;e.nohiragana=12398;e.nokatakana=12494;e.nokatakanahalfwidth=65417;e.nonbreakingspace=160;e.nonenthai=3603;e.nonuthai=3609;e.noonarabic=1606;e.noonfinalarabic=65254;e.noonghunnaarabic=1722;e.noonghunnafinalarabic=64415;e.nooninitialarabic=65255;e.noonjeeminitialarabic=64722;e.noonjeemisolatedarabic=64587;e.noonmedialarabic=65256;e.noonmeeminitialarabic=64725;e.noonmeemisolatedarabic=64590;e.noonnoonfinalarabic=64653;e.notcontains=8716;e.notelement=8713;e.notelementof=8713;e.notequal=8800;e.notgreater=8815;e.notgreaternorequal=8817;e.notgreaternorless=8825;e.notidentical=8802;e.notless=8814;e.notlessnorequal=8816;e.notparallel=8742;e.notprecedes=8832;e.notsubset=8836;e.notsucceeds=8833;e.notsuperset=8837;e.nowarmenian=1398;e.nparen=9385;e.nssquare=13233;e.nsuperior=8319;e.ntilde=241;e.nu=957;e.nuhiragana=12396;e.nukatakana=12492;e.nukatakanahalfwidth=65415;e.nuktabengali=2492;e.nuktadeva=2364;e.nuktagujarati=2748;e.nuktagurmukhi=2620;e.numbersign=35;e.numbersignmonospace=65283;e.numbersignsmall=65119;e.numeralsigngreek=884;e.numeralsignlowergreek=885;e.numero=8470;e.nun=1504;e.nundagesh=64320;e.nundageshhebrew=64320;e.nunhebrew=1504;e.nvsquare=13237;e.nwsquare=13243;e.nyabengali=2462;e.nyadeva=2334;e.nyagujarati=2718;e.nyagurmukhi=2590;e.o=111;e.oacute=243;e.oangthai=3629;e.obarred=629;e.obarredcyrillic=1257;e.obarreddieresiscyrillic=1259;e.obengali=2451;e.obopomofo=12571;e.obreve=335;e.ocandradeva=2321;e.ocandragujarati=2705;e.ocandravowelsigndeva=2377;e.ocandravowelsigngujarati=2761;e.ocaron=466;e.ocircle=9438;e.ocircumflex=244;e.ocircumflexacute=7889;e.ocircumflexdotbelow=7897;e.ocircumflexgrave=7891;e.ocircumflexhookabove=7893;e.ocircumflextilde=7895;e.ocyrillic=1086;e.odblacute=337;e.odblgrave=525;e.odeva=2323;e.odieresis=246;e.odieresiscyrillic=1255;e.odotbelow=7885;e.oe=339;e.oekorean=12634;e.ogonek=731;e.ogonekcmb=808;e.ograve=242;e.ogujarati=2707;e.oharmenian=1413;e.ohiragana=12362;e.ohookabove=7887;e.ohorn=417;e.ohornacute=7899;e.ohorndotbelow=7907;e.ohorngrave=7901;e.ohornhookabove=7903;e.ohorntilde=7905;e.ohungarumlaut=337;e.oi=419;e.oinvertedbreve=527;e.okatakana=12458;e.okatakanahalfwidth=65397;e.okorean=12631;e.olehebrew=1451;e.omacron=333;e.omacronacute=7763;e.omacrongrave=7761;e.omdeva=2384;e.omega=969;e.omega1=982;e.omegacyrillic=1121;e.omegalatinclosed=631;e.omegaroundcyrillic=1147;e.omegatitlocyrillic=1149;e.omegatonos=974;e.omgujarati=2768;e.omicron=959;e.omicrontonos=972;e.omonospace=65359;e.one=49;e.onearabic=1633;e.onebengali=2535;e.onecircle=9312;e.onecircleinversesansserif=10122;e.onedeva=2407;e.onedotenleader=8228;e.oneeighth=8539;e.onefitted=63196;e.onegujarati=2791;e.onegurmukhi=2663;e.onehackarabic=1633;e.onehalf=189;e.onehangzhou=12321;e.oneideographicparen=12832;e.oneinferior=8321;e.onemonospace=65297;e.onenumeratorbengali=2548;e.oneoldstyle=63281;e.oneparen=9332;e.oneperiod=9352;e.onepersian=1777;e.onequarter=188;e.oneroman=8560;e.onesuperior=185;e.onethai=3665;e.onethird=8531;e.oogonek=491;e.oogonekmacron=493;e.oogurmukhi=2579;e.oomatragurmukhi=2635;e.oopen=596;e.oparen=9386;e.openbullet=9702;e.option=8997;e.ordfeminine=170;e.ordmasculine=186;e.orthogonal=8735;e.oshortdeva=2322;e.oshortvowelsigndeva=2378;e.oslash=248;e.oslashacute=511;e.osmallhiragana=12361;e.osmallkatakana=12457;e.osmallkatakanahalfwidth=65387;e.ostrokeacute=511;e.osuperior=63216;e.otcyrillic=1151;e.otilde=245;e.otildeacute=7757;e.otildedieresis=7759;e.oubopomofo=12577;e.overline=8254;e.overlinecenterline=65098;e.overlinecmb=773;e.overlinedashed=65097;e.overlinedblwavy=65100;e.overlinewavy=65099;e.overscore=175;e.ovowelsignbengali=2507;e.ovowelsigndeva=2379;e.ovowelsigngujarati=2763;e.p=112;e.paampssquare=13184;e.paasentosquare=13099;e.pabengali=2474;e.pacute=7765;e.padeva=2346;e.pagedown=8671;e.pageup=8670;e.pagujarati=2730;e.pagurmukhi=2602;e.pahiragana=12401;e.paiyannoithai=3631;e.pakatakana=12497;e.palatalizationcyrilliccmb=1156;e.palochkacyrillic=1216;e.pansioskorean=12671;e.paragraph=182;e.parallel=8741;e.parenleft=40;e.parenleftaltonearabic=64830;e.parenleftbt=63725;e.parenleftex=63724;e.parenleftinferior=8333;e.parenleftmonospace=65288;e.parenleftsmall=65113;e.parenleftsuperior=8317;e.parenlefttp=63723;e.parenleftvertical=65077;e.parenright=41;e.parenrightaltonearabic=64831;e.parenrightbt=63736;e.parenrightex=63735;e.parenrightinferior=8334;e.parenrightmonospace=65289;e.parenrightsmall=65114;e.parenrightsuperior=8318;e.parenrighttp=63734;e.parenrightvertical=65078;e.partialdiff=8706;e.paseqhebrew=1472;e.pashtahebrew=1433;e.pasquare=13225;e.patah=1463;e.patah11=1463;e.patah1d=1463;e.patah2a=1463;e.patahhebrew=1463;e.patahnarrowhebrew=1463;e.patahquarterhebrew=1463;e.patahwidehebrew=1463;e.pazerhebrew=1441;e.pbopomofo=12550;e.pcircle=9439;e.pdotaccent=7767;e.pe=1508;e.pecyrillic=1087;e.pedagesh=64324;e.pedageshhebrew=64324;e.peezisquare=13115;e.pefinaldageshhebrew=64323;e.peharabic=1662;e.peharmenian=1402;e.pehebrew=1508;e.pehfinalarabic=64343;e.pehinitialarabic=64344;e.pehiragana=12410;e.pehmedialarabic=64345;e.pekatakana=12506;e.pemiddlehookcyrillic=1191;e.perafehebrew=64334;e.percent=37;e.percentarabic=1642;e.percentmonospace=65285;e.percentsmall=65130;e.period=46;e.periodarmenian=1417;e.periodcentered=183;e.periodhalfwidth=65377;e.periodinferior=63207;e.periodmonospace=65294;e.periodsmall=65106;e.periodsuperior=63208;e.perispomenigreekcmb=834;e.perpendicular=8869;e.perthousand=8240;e.peseta=8359;e.pfsquare=13194;e.phabengali=2475;e.phadeva=2347;e.phagujarati=2731;e.phagurmukhi=2603;e.phi=966;e.phi1=981;e.phieuphacirclekorean=12922;e.phieuphaparenkorean=12826;e.phieuphcirclekorean=12908;e.phieuphkorean=12621;e.phieuphparenkorean=12812;e.philatin=632;e.phinthuthai=3642;e.phisymbolgreek=981;e.phook=421;e.phophanthai=3614;e.phophungthai=3612;e.phosamphaothai=3616;e.pi=960;e.pieupacirclekorean=12915;e.pieupaparenkorean=12819;e.pieupcieuckorean=12662;e.pieupcirclekorean=12901;e.pieupkiyeokkorean=12658;e.pieupkorean=12610;e.pieupparenkorean=12805;e.pieupsioskiyeokkorean=12660;e.pieupsioskorean=12612;e.pieupsiostikeutkorean=12661;e.pieupthieuthkorean=12663;e.pieuptikeutkorean=12659;e.pihiragana=12404;e.pikatakana=12500;e.pisymbolgreek=982;e.piwrarmenian=1411;e.plus=43;e.plusbelowcmb=799;e.pluscircle=8853;e.plusminus=177;e.plusmod=726;e.plusmonospace=65291;e.plussmall=65122;e.plussuperior=8314;e.pmonospace=65360;e.pmsquare=13272;e.pohiragana=12413;e.pointingindexdownwhite=9759;e.pointingindexleftwhite=9756;e.pointingindexrightwhite=9758;e.pointingindexupwhite=9757;e.pokatakana=12509;e.poplathai=3611;e.postalmark=12306;e.postalmarkface=12320;e.pparen=9387;e.precedes=8826;e.prescription=8478;e.primemod=697;e.primereversed=8245;e.product=8719;e.projective=8965;e.prolongedkana=12540;e.propellor=8984;e.propersubset=8834;e.propersuperset=8835;e.proportion=8759;e.proportional=8733;e.psi=968;e.psicyrillic=1137;e.psilipneumatacyrilliccmb=1158;e.pssquare=13232;e.puhiragana=12407;e.pukatakana=12503;e.pvsquare=13236;e.pwsquare=13242;e.q=113;e.qadeva=2392;e.qadmahebrew=1448;e.qafarabic=1602;e.qaffinalarabic=65238;e.qafinitialarabic=65239;e.qafmedialarabic=65240;e.qamats=1464;e.qamats10=1464;e.qamats1a=1464;e.qamats1c=1464;e.qamats27=1464;e.qamats29=1464;e.qamats33=1464;e.qamatsde=1464;e.qamatshebrew=1464;e.qamatsnarrowhebrew=1464;e.qamatsqatanhebrew=1464;e.qamatsqatannarrowhebrew=1464;e.qamatsqatanquarterhebrew=1464;e.qamatsqatanwidehebrew=1464;e.qamatsquarterhebrew=1464;e.qamatswidehebrew=1464;e.qarneyparahebrew=1439;e.qbopomofo=12561;e.qcircle=9440;e.qhook=672;e.qmonospace=65361;e.qof=1511;e.qofdagesh=64327;e.qofdageshhebrew=64327;e.qofhebrew=1511;e.qparen=9388;e.quarternote=9833;e.qubuts=1467;e.qubuts18=1467;e.qubuts25=1467;e.qubuts31=1467;e.qubutshebrew=1467;e.qubutsnarrowhebrew=1467;e.qubutsquarterhebrew=1467;e.qubutswidehebrew=1467;e.question=63;e.questionarabic=1567;e.questionarmenian=1374;e.questiondown=191;e.questiondownsmall=63423;e.questiongreek=894;e.questionmonospace=65311;e.questionsmall=63295;e.quotedbl=34;e.quotedblbase=8222;e.quotedblleft=8220;e.quotedblmonospace=65282;e.quotedblprime=12318;e.quotedblprimereversed=12317;e.quotedblright=8221;e.quoteleft=8216;e.quoteleftreversed=8219;e.quotereversed=8219;e.quoteright=8217;e.quoterightn=329;e.quotesinglbase=8218;e.quotesingle=39;e.quotesinglemonospace=65287;e.r=114;e.raarmenian=1404;e.rabengali=2480;e.racute=341;e.radeva=2352;e.radical=8730;e.radicalex=63717;e.radoverssquare=13230;e.radoverssquaredsquare=13231;e.radsquare=13229;e.rafe=1471;e.rafehebrew=1471;e.ragujarati=2736;e.ragurmukhi=2608;e.rahiragana=12425;e.rakatakana=12521;e.rakatakanahalfwidth=65431;e.ralowerdiagonalbengali=2545;e.ramiddlediagonalbengali=2544;e.ramshorn=612;e.ratio=8758;e.rbopomofo=12566;e.rcaron=345;e.rcedilla=343;e.rcircle=9441;e.rcommaaccent=343;e.rdblgrave=529;e.rdotaccent=7769;e.rdotbelow=7771;e.rdotbelowmacron=7773;e.referencemark=8251;e.reflexsubset=8838;e.reflexsuperset=8839;e.registered=174;e.registersans=63720;e.registerserif=63194;e.reharabic=1585;e.reharmenian=1408;e.rehfinalarabic=65198;e.rehiragana=12428;e.rekatakana=12524;e.rekatakanahalfwidth=65434;e.resh=1512;e.reshdageshhebrew=64328;e.reshhebrew=1512;e.reversedtilde=8765;e.reviahebrew=1431;e.reviamugrashhebrew=1431;e.revlogicalnot=8976;e.rfishhook=638;e.rfishhookreversed=639;e.rhabengali=2525;e.rhadeva=2397;e.rho=961;e.rhook=637;e.rhookturned=635;e.rhookturnedsuperior=693;e.rhosymbolgreek=1009;e.rhotichookmod=734;e.rieulacirclekorean=12913;e.rieulaparenkorean=12817;e.rieulcirclekorean=12899;e.rieulhieuhkorean=12608;e.rieulkiyeokkorean=12602;e.rieulkiyeoksioskorean=12649;e.rieulkorean=12601;e.rieulmieumkorean=12603;e.rieulpansioskorean=12652;e.rieulparenkorean=12803;e.rieulphieuphkorean=12607;e.rieulpieupkorean=12604;e.rieulpieupsioskorean=12651;e.rieulsioskorean=12605;e.rieulthieuthkorean=12606;e.rieultikeutkorean=12650;e.rieulyeorinhieuhkorean=12653;e.rightangle=8735;e.righttackbelowcmb=793;e.righttriangle=8895;e.rihiragana=12426;e.rikatakana=12522;e.rikatakanahalfwidth=65432;e.ring=730;e.ringbelowcmb=805;e.ringcmb=778;e.ringhalfleft=703;e.ringhalfleftarmenian=1369;e.ringhalfleftbelowcmb=796;e.ringhalfleftcentered=723;e.ringhalfright=702;e.ringhalfrightbelowcmb=825;e.ringhalfrightcentered=722;e.rinvertedbreve=531;e.rittorusquare=13137;e.rlinebelow=7775;e.rlongleg=636;e.rlonglegturned=634;e.rmonospace=65362;e.rohiragana=12429;e.rokatakana=12525;e.rokatakanahalfwidth=65435;e.roruathai=3619;e.rparen=9389;e.rrabengali=2524;e.rradeva=2353;e.rragurmukhi=2652;e.rreharabic=1681;e.rrehfinalarabic=64397;e.rrvocalicbengali=2528;e.rrvocalicdeva=2400;e.rrvocalicgujarati=2784;e.rrvocalicvowelsignbengali=2500;e.rrvocalicvowelsigndeva=2372;e.rrvocalicvowelsigngujarati=2756;e.rsuperior=63217;e.rtblock=9616;e.rturned=633;e.rturnedsuperior=692;e.ruhiragana=12427;e.rukatakana=12523;e.rukatakanahalfwidth=65433;e.rupeemarkbengali=2546;e.rupeesignbengali=2547;e.rupiah=63197;e.ruthai=3620;e.rvocalicbengali=2443;e.rvocalicdeva=2315;e.rvocalicgujarati=2699;e.rvocalicvowelsignbengali=2499;e.rvocalicvowelsigndeva=2371;e.rvocalicvowelsigngujarati=2755;e.s=115;e.sabengali=2488;e.sacute=347;e.sacutedotaccent=7781;e.sadarabic=1589;e.sadeva=2360;e.sadfinalarabic=65210;e.sadinitialarabic=65211;e.sadmedialarabic=65212;e.sagujarati=2744;e.sagurmukhi=2616;e.sahiragana=12373;e.sakatakana=12469;e.sakatakanahalfwidth=65403;e.sallallahoualayhewasallamarabic=65018;e.samekh=1505;e.samekhdagesh=64321;e.samekhdageshhebrew=64321;e.samekhhebrew=1505;e.saraaathai=3634;e.saraaethai=3649;e.saraaimaimalaithai=3652;e.saraaimaimuanthai=3651;e.saraamthai=3635;e.saraathai=3632;e.saraethai=3648;e.saraiileftthai=63622;e.saraiithai=3637;e.saraileftthai=63621;e.saraithai=3636;e.saraothai=3650;e.saraueeleftthai=63624;e.saraueethai=3639;e.saraueleftthai=63623;e.sarauethai=3638;e.sarauthai=3640;e.sarauuthai=3641;e.sbopomofo=12569;e.scaron=353;e.scarondotaccent=7783;e.scedilla=351;e.schwa=601;e.schwacyrillic=1241;e.schwadieresiscyrillic=1243;e.schwahook=602;e.scircle=9442;e.scircumflex=349;e.scommaaccent=537;e.sdotaccent=7777;e.sdotbelow=7779;e.sdotbelowdotaccent=7785;e.seagullbelowcmb=828;e.second=8243;e.secondtonechinese=714;e.section=167;e.seenarabic=1587;e.seenfinalarabic=65202;e.seeninitialarabic=65203;e.seenmedialarabic=65204;e.segol=1462;e.segol13=1462;e.segol1f=1462;e.segol2c=1462;e.segolhebrew=1462;e.segolnarrowhebrew=1462;e.segolquarterhebrew=1462;e.segoltahebrew=1426;e.segolwidehebrew=1462;e.seharmenian=1405;e.sehiragana=12379;e.sekatakana=12475;e.sekatakanahalfwidth=65406;e.semicolon=59;e.semicolonarabic=1563;e.semicolonmonospace=65307;e.semicolonsmall=65108;e.semivoicedmarkkana=12444;e.semivoicedmarkkanahalfwidth=65439;e.sentisquare=13090;e.sentosquare=13091;e.seven=55;e.sevenarabic=1639;e.sevenbengali=2541;e.sevencircle=9318;e.sevencircleinversesansserif=10128;e.sevendeva=2413;e.seveneighths=8542;e.sevengujarati=2797;e.sevengurmukhi=2669;e.sevenhackarabic=1639;e.sevenhangzhou=12327;e.sevenideographicparen=12838;e.seveninferior=8327;e.sevenmonospace=65303;e.sevenoldstyle=63287;e.sevenparen=9338;e.sevenperiod=9358;e.sevenpersian=1783;e.sevenroman=8566;e.sevensuperior=8311;e.seventeencircle=9328;e.seventeenparen=9348;e.seventeenperiod=9368;e.seventhai=3671;e.sfthyphen=173;e.shaarmenian=1399;e.shabengali=2486;e.shacyrillic=1096;e.shaddaarabic=1617;e.shaddadammaarabic=64609;e.shaddadammatanarabic=64606;e.shaddafathaarabic=64608;e.shaddakasraarabic=64610;e.shaddakasratanarabic=64607;e.shade=9618;e.shadedark=9619;e.shadelight=9617;e.shademedium=9618;e.shadeva=2358;e.shagujarati=2742;e.shagurmukhi=2614;e.shalshelethebrew=1427;e.shbopomofo=12565;e.shchacyrillic=1097;e.sheenarabic=1588;e.sheenfinalarabic=65206;e.sheeninitialarabic=65207;e.sheenmedialarabic=65208;e.sheicoptic=995;e.sheqel=8362;e.sheqelhebrew=8362;e.sheva=1456;e.sheva115=1456;e.sheva15=1456;e.sheva22=1456;e.sheva2e=1456;e.shevahebrew=1456;e.shevanarrowhebrew=1456;e.shevaquarterhebrew=1456;e.shevawidehebrew=1456;e.shhacyrillic=1211;e.shimacoptic=1005;e.shin=1513;e.shindagesh=64329;e.shindageshhebrew=64329;e.shindageshshindot=64300;e.shindageshshindothebrew=64300;e.shindageshsindot=64301;e.shindageshsindothebrew=64301;e.shindothebrew=1473;e.shinhebrew=1513;e.shinshindot=64298;e.shinshindothebrew=64298;e.shinsindot=64299;e.shinsindothebrew=64299;e.shook=642;e.sigma=963;e.sigma1=962;e.sigmafinal=962;e.sigmalunatesymbolgreek=1010;e.sihiragana=12375;e.sikatakana=12471;e.sikatakanahalfwidth=65404;e.siluqhebrew=1469;e.siluqlefthebrew=1469;e.similar=8764;e.sindothebrew=1474;e.siosacirclekorean=12916;e.siosaparenkorean=12820;e.sioscieuckorean=12670;e.sioscirclekorean=12902;e.sioskiyeokkorean=12666;e.sioskorean=12613;e.siosnieunkorean=12667;e.siosparenkorean=12806;e.siospieupkorean=12669;e.siostikeutkorean=12668;e.six=54;e.sixarabic=1638;e.sixbengali=2540;e.sixcircle=9317;e.sixcircleinversesansserif=10127;e.sixdeva=2412;e.sixgujarati=2796;e.sixgurmukhi=2668;e.sixhackarabic=1638;e.sixhangzhou=12326;e.sixideographicparen=12837;e.sixinferior=8326;e.sixmonospace=65302;e.sixoldstyle=63286;e.sixparen=9337;e.sixperiod=9357;e.sixpersian=1782;e.sixroman=8565;e.sixsuperior=8310;e.sixteencircle=9327;e.sixteencurrencydenominatorbengali=2553;e.sixteenparen=9347;e.sixteenperiod=9367;e.sixthai=3670;e.slash=47;e.slashmonospace=65295;e.slong=383;e.slongdotaccent=7835;e.smileface=9786;e.smonospace=65363;e.sofpasuqhebrew=1475;e.softhyphen=173;e.softsigncyrillic=1100;e.sohiragana=12381;e.sokatakana=12477;e.sokatakanahalfwidth=65407;e.soliduslongoverlaycmb=824;e.solidusshortoverlaycmb=823;e.sorusithai=3625;e.sosalathai=3624;e.sosothai=3595;e.sosuathai=3626;e.space=32;e.spacehackarabic=32;e.spade=9824;e.spadesuitblack=9824;e.spadesuitwhite=9828;e.sparen=9390;e.squarebelowcmb=827;e.squarecc=13252;e.squarecm=13213;e.squarediagonalcrosshatchfill=9641;e.squarehorizontalfill=9636;e.squarekg=13199;e.squarekm=13214;e.squarekmcapital=13262;e.squareln=13265;e.squarelog=13266;e.squaremg=13198;e.squaremil=13269;e.squaremm=13212;e.squaremsquared=13217;e.squareorthogonalcrosshatchfill=9638;e.squareupperlefttolowerrightfill=9639;e.squareupperrighttolowerleftfill=9640;e.squareverticalfill=9637;e.squarewhitewithsmallblack=9635;e.srsquare=13275;e.ssabengali=2487;e.ssadeva=2359;e.ssagujarati=2743;e.ssangcieuckorean=12617;e.ssanghieuhkorean=12677;e.ssangieungkorean=12672;e.ssangkiyeokkorean=12594;e.ssangnieunkorean=12645;e.ssangpieupkorean=12611;e.ssangsioskorean=12614;e.ssangtikeutkorean=12600;e.ssuperior=63218;e.sterling=163;e.sterlingmonospace=65505;e.strokelongoverlaycmb=822;e.strokeshortoverlaycmb=821;e.subset=8834;e.subsetnotequal=8842;e.subsetorequal=8838;e.succeeds=8827;e.suchthat=8715;e.suhiragana=12377;e.sukatakana=12473;e.sukatakanahalfwidth=65405;e.sukunarabic=1618;e.summation=8721;e.sun=9788;e.superset=8835;e.supersetnotequal=8843;e.supersetorequal=8839;e.svsquare=13276;e.syouwaerasquare=13180;e.t=116;e.tabengali=2468;e.tackdown=8868;e.tackleft=8867;e.tadeva=2340;e.tagujarati=2724;e.tagurmukhi=2596;e.taharabic=1591;e.tahfinalarabic=65218;e.tahinitialarabic=65219;e.tahiragana=12383;e.tahmedialarabic=65220;e.taisyouerasquare=13181;e.takatakana=12479;e.takatakanahalfwidth=65408;e.tatweelarabic=1600;e.tau=964;e.tav=1514;e.tavdages=64330;e.tavdagesh=64330;e.tavdageshhebrew=64330;e.tavhebrew=1514;e.tbar=359;e.tbopomofo=12554;e.tcaron=357;e.tccurl=680;e.tcedilla=355;e.tcheharabic=1670;e.tchehfinalarabic=64379;e.tchehinitialarabic=64380;e.tchehmedialarabic=64381;e.tcircle=9443;e.tcircumflexbelow=7793;e.tcommaaccent=355;e.tdieresis=7831;e.tdotaccent=7787;e.tdotbelow=7789;e.tecyrillic=1090;e.tedescendercyrillic=1197;e.teharabic=1578;e.tehfinalarabic=65174;e.tehhahinitialarabic=64674;e.tehhahisolatedarabic=64524;e.tehinitialarabic=65175;e.tehiragana=12390;e.tehjeeminitialarabic=64673;e.tehjeemisolatedarabic=64523;e.tehmarbutaarabic=1577;e.tehmarbutafinalarabic=65172;e.tehmedialarabic=65176;e.tehmeeminitialarabic=64676;e.tehmeemisolatedarabic=64526;e.tehnoonfinalarabic=64627;e.tekatakana=12486;e.tekatakanahalfwidth=65411;e.telephone=8481;e.telephoneblack=9742;e.telishagedolahebrew=1440;e.telishaqetanahebrew=1449;e.tencircle=9321;e.tenideographicparen=12841;e.tenparen=9341;e.tenperiod=9361;e.tenroman=8569;e.tesh=679;e.tet=1496;e.tetdagesh=64312;e.tetdageshhebrew=64312;e.tethebrew=1496;e.tetsecyrillic=1205;e.tevirhebrew=1435;e.tevirlefthebrew=1435;e.thabengali=2469;e.thadeva=2341;e.thagujarati=2725;e.thagurmukhi=2597;e.thalarabic=1584;e.thalfinalarabic=65196;e.thanthakhatlowleftthai=63640;e.thanthakhatlowrightthai=63639;e.thanthakhatthai=3660;e.thanthakhatupperleftthai=63638;e.theharabic=1579;e.thehfinalarabic=65178;e.thehinitialarabic=65179;e.thehmedialarabic=65180;e.thereexists=8707;e.therefore=8756;e.theta=952;e.theta1=977;e.thetasymbolgreek=977;e.thieuthacirclekorean=12921;e.thieuthaparenkorean=12825;e.thieuthcirclekorean=12907;e.thieuthkorean=12620;e.thieuthparenkorean=12811;e.thirteencircle=9324;e.thirteenparen=9344;e.thirteenperiod=9364;e.thonangmonthothai=3601;e.thook=429;e.thophuthaothai=3602;e.thorn=254;e.thothahanthai=3607;e.thothanthai=3600;e.thothongthai=3608;e.thothungthai=3606;e.thousandcyrillic=1154;e.thousandsseparatorarabic=1644;e.thousandsseparatorpersian=1644;e.three=51;e.threearabic=1635;e.threebengali=2537;e.threecircle=9314;e.threecircleinversesansserif=10124;e.threedeva=2409;e.threeeighths=8540;e.threegujarati=2793;e.threegurmukhi=2665;e.threehackarabic=1635;e.threehangzhou=12323;e.threeideographicparen=12834;e.threeinferior=8323;e.threemonospace=65299;e.threenumeratorbengali=2550;e.threeoldstyle=63283;e.threeparen=9334;e.threeperiod=9354;e.threepersian=1779;e.threequarters=190;e.threequartersemdash=63198;e.threeroman=8562;e.threesuperior=179;e.threethai=3667;e.thzsquare=13204;e.tihiragana=12385;e.tikatakana=12481;e.tikatakanahalfwidth=65409;e.tikeutacirclekorean=12912;e.tikeutaparenkorean=12816;e.tikeutcirclekorean=12898;e.tikeutkorean=12599;e.tikeutparenkorean=12802;e.tilde=732;e.tildebelowcmb=816;e.tildecmb=771;e.tildecomb=771;e.tildedoublecmb=864;e.tildeoperator=8764;e.tildeoverlaycmb=820;e.tildeverticalcmb=830;e.timescircle=8855;e.tipehahebrew=1430;e.tipehalefthebrew=1430;e.tippigurmukhi=2672;e.titlocyrilliccmb=1155;e.tiwnarmenian=1407;e.tlinebelow=7791;e.tmonospace=65364;e.toarmenian=1385;e.tohiragana=12392;e.tokatakana=12488;e.tokatakanahalfwidth=65412;e.tonebarextrahighmod=741;e.tonebarextralowmod=745;e.tonebarhighmod=742;e.tonebarlowmod=744;e.tonebarmidmod=743;e.tonefive=445;e.tonesix=389;e.tonetwo=424;e.tonos=900;e.tonsquare=13095;e.topatakthai=3599;e.tortoiseshellbracketleft=12308;e.tortoiseshellbracketleftsmall=65117;e.tortoiseshellbracketleftvertical=65081;e.tortoiseshellbracketright=12309;e.tortoiseshellbracketrightsmall=65118;e.tortoiseshellbracketrightvertical=65082;e.totaothai=3605;e.tpalatalhook=427;e.tparen=9391;e.trademark=8482;e.trademarksans=63722;e.trademarkserif=63195;e.tretroflexhook=648;e.triagdn=9660;e.triaglf=9668;e.triagrt=9658;e.triagup=9650;e.ts=678;e.tsadi=1510;e.tsadidagesh=64326;e.tsadidageshhebrew=64326;e.tsadihebrew=1510;e.tsecyrillic=1094;e.tsere=1461;e.tsere12=1461;e.tsere1e=1461;e.tsere2b=1461;e.tserehebrew=1461;e.tserenarrowhebrew=1461;e.tserequarterhebrew=1461;e.tserewidehebrew=1461;e.tshecyrillic=1115;e.tsuperior=63219;e.ttabengali=2463;e.ttadeva=2335;e.ttagujarati=2719;e.ttagurmukhi=2591;e.tteharabic=1657;e.ttehfinalarabic=64359;e.ttehinitialarabic=64360;e.ttehmedialarabic=64361;e.tthabengali=2464;e.tthadeva=2336;e.tthagujarati=2720;e.tthagurmukhi=2592;e.tturned=647;e.tuhiragana=12388;e.tukatakana=12484;e.tukatakanahalfwidth=65410;e.tusmallhiragana=12387;e.tusmallkatakana=12483;e.tusmallkatakanahalfwidth=65391;e.twelvecircle=9323;e.twelveparen=9343;e.twelveperiod=9363;e.twelveroman=8571;e.twentycircle=9331;e.twentyhangzhou=21316;e.twentyparen=9351;e.twentyperiod=9371;e.two=50;e.twoarabic=1634;e.twobengali=2536;e.twocircle=9313;e.twocircleinversesansserif=10123;e.twodeva=2408;e.twodotenleader=8229;e.twodotleader=8229;e.twodotleadervertical=65072;e.twogujarati=2792;e.twogurmukhi=2664;e.twohackarabic=1634;e.twohangzhou=12322;e.twoideographicparen=12833;e.twoinferior=8322;e.twomonospace=65298;e.twonumeratorbengali=2549;e.twooldstyle=63282;e.twoparen=9333;e.twoperiod=9353;e.twopersian=1778;e.tworoman=8561;e.twostroke=443;e.twosuperior=178;e.twothai=3666;e.twothirds=8532;e.u=117;e.uacute=250;e.ubar=649;e.ubengali=2441;e.ubopomofo=12584;e.ubreve=365;e.ucaron=468;e.ucircle=9444;e.ucircumflex=251;e.ucircumflexbelow=7799;e.ucyrillic=1091;e.udattadeva=2385;e.udblacute=369;e.udblgrave=533;e.udeva=2313;e.udieresis=252;e.udieresisacute=472;e.udieresisbelow=7795;e.udieresiscaron=474;e.udieresiscyrillic=1265;e.udieresisgrave=476;e.udieresismacron=470;e.udotbelow=7909;e.ugrave=249;e.ugujarati=2697;e.ugurmukhi=2569;e.uhiragana=12358;e.uhookabove=7911;e.uhorn=432;e.uhornacute=7913;e.uhorndotbelow=7921;e.uhorngrave=7915;e.uhornhookabove=7917;e.uhorntilde=7919;e.uhungarumlaut=369;e.uhungarumlautcyrillic=1267;e.uinvertedbreve=535;e.ukatakana=12454;e.ukatakanahalfwidth=65395;e.ukcyrillic=1145;e.ukorean=12636;e.umacron=363;e.umacroncyrillic=1263;e.umacrondieresis=7803;e.umatragurmukhi=2625;e.umonospace=65365;e.underscore=95;e.underscoredbl=8215;e.underscoremonospace=65343;e.underscorevertical=65075;e.underscorewavy=65103;e.union=8746;e.universal=8704;e.uogonek=371;e.uparen=9392;e.upblock=9600;e.upperdothebrew=1476;e.upsilon=965;e.upsilondieresis=971;e.upsilondieresistonos=944;e.upsilonlatin=650;e.upsilontonos=973;e.uptackbelowcmb=797;e.uptackmod=724;e.uragurmukhi=2675;e.uring=367;e.ushortcyrillic=1118;e.usmallhiragana=12357;e.usmallkatakana=12453;e.usmallkatakanahalfwidth=65385;e.ustraightcyrillic=1199;e.ustraightstrokecyrillic=1201;e.utilde=361;e.utildeacute=7801;e.utildebelow=7797;e.uubengali=2442;e.uudeva=2314;e.uugujarati=2698;e.uugurmukhi=2570;e.uumatragurmukhi=2626;e.uuvowelsignbengali=2498;e.uuvowelsigndeva=2370;e.uuvowelsigngujarati=2754;e.uvowelsignbengali=2497;e.uvowelsigndeva=2369;e.uvowelsigngujarati=2753;e.v=118;e.vadeva=2357;e.vagujarati=2741;e.vagurmukhi=2613;e.vakatakana=12535;e.vav=1493;e.vavdagesh=64309;e.vavdagesh65=64309;e.vavdageshhebrew=64309;e.vavhebrew=1493;e.vavholam=64331;e.vavholamhebrew=64331;e.vavvavhebrew=1520;e.vavyodhebrew=1521;e.vcircle=9445;e.vdotbelow=7807;e.vecyrillic=1074;e.veharabic=1700;e.vehfinalarabic=64363;e.vehinitialarabic=64364;e.vehmedialarabic=64365;e.vekatakana=12537;e.venus=9792;e.verticalbar=124;e.verticallineabovecmb=781;e.verticallinebelowcmb=809;e.verticallinelowmod=716;e.verticallinemod=712;e.vewarmenian=1406;e.vhook=651;e.vikatakana=12536;e.viramabengali=2509;e.viramadeva=2381;e.viramagujarati=2765;e.visargabengali=2435;e.visargadeva=2307;e.visargagujarati=2691;e.vmonospace=65366;e.voarmenian=1400;e.voicediterationhiragana=12446;e.voicediterationkatakana=12542;e.voicedmarkkana=12443;e.voicedmarkkanahalfwidth=65438;e.vokatakana=12538;e.vparen=9393;e.vtilde=7805;e.vturned=652;e.vuhiragana=12436;e.vukatakana=12532;e.w=119;e.wacute=7811;e.waekorean=12633;e.wahiragana=12431;e.wakatakana=12527;e.wakatakanahalfwidth=65436;e.wakorean=12632;e.wasmallhiragana=12430;e.wasmallkatakana=12526;e.wattosquare=13143;e.wavedash=12316;e.wavyunderscorevertical=65076;e.wawarabic=1608;e.wawfinalarabic=65262;e.wawhamzaabovearabic=1572;e.wawhamzaabovefinalarabic=65158;e.wbsquare=13277;e.wcircle=9446;e.wcircumflex=373;e.wdieresis=7813;e.wdotaccent=7815;e.wdotbelow=7817;e.wehiragana=12433;e.weierstrass=8472;e.wekatakana=12529;e.wekorean=12638;e.weokorean=12637;e.wgrave=7809;e.whitebullet=9702;e.whitecircle=9675;e.whitecircleinverse=9689;e.whitecornerbracketleft=12302;e.whitecornerbracketleftvertical=65091;e.whitecornerbracketright=12303;e.whitecornerbracketrightvertical=65092;e.whitediamond=9671;e.whitediamondcontainingblacksmalldiamond=9672;e.whitedownpointingsmalltriangle=9663;e.whitedownpointingtriangle=9661;e.whiteleftpointingsmalltriangle=9667;e.whiteleftpointingtriangle=9665;e.whitelenticularbracketleft=12310;e.whitelenticularbracketright=12311;e.whiterightpointingsmalltriangle=9657;e.whiterightpointingtriangle=9655;e.whitesmallsquare=9643;e.whitesmilingface=9786;e.whitesquare=9633;e.whitestar=9734;e.whitetelephone=9743;e.whitetortoiseshellbracketleft=12312;e.whitetortoiseshellbracketright=12313;e.whiteuppointingsmalltriangle=9653;e.whiteuppointingtriangle=9651;e.wihiragana=12432;e.wikatakana=12528;e.wikorean=12639;e.wmonospace=65367;e.wohiragana=12434;e.wokatakana=12530;e.wokatakanahalfwidth=65382;e.won=8361;e.wonmonospace=65510;e.wowaenthai=3623;e.wparen=9394;e.wring=7832;e.wsuperior=695;e.wturned=653;e.wynn=447;e.x=120;e.xabovecmb=829;e.xbopomofo=12562;e.xcircle=9447;e.xdieresis=7821;e.xdotaccent=7819;e.xeharmenian=1389;e.xi=958;e.xmonospace=65368;e.xparen=9395;e.xsuperior=739;e.y=121;e.yaadosquare=13134;e.yabengali=2479;e.yacute=253;e.yadeva=2351;e.yaekorean=12626;e.yagujarati=2735;e.yagurmukhi=2607;e.yahiragana=12420;e.yakatakana=12516;e.yakatakanahalfwidth=65428;e.yakorean=12625;e.yamakkanthai=3662;e.yasmallhiragana=12419;e.yasmallkatakana=12515;e.yasmallkatakanahalfwidth=65388;e.yatcyrillic=1123;e.ycircle=9448;e.ycircumflex=375;e.ydieresis=255;e.ydotaccent=7823;e.ydotbelow=7925;e.yeharabic=1610;e.yehbarreearabic=1746;e.yehbarreefinalarabic=64431;e.yehfinalarabic=65266;e.yehhamzaabovearabic=1574;e.yehhamzaabovefinalarabic=65162;e.yehhamzaaboveinitialarabic=65163;e.yehhamzaabovemedialarabic=65164;e.yehinitialarabic=65267;e.yehmedialarabic=65268;e.yehmeeminitialarabic=64733;e.yehmeemisolatedarabic=64600;e.yehnoonfinalarabic=64660;e.yehthreedotsbelowarabic=1745;e.yekorean=12630;e.yen=165;e.yenmonospace=65509;e.yeokorean=12629;e.yeorinhieuhkorean=12678;e.yerahbenyomohebrew=1450;e.yerahbenyomolefthebrew=1450;e.yericyrillic=1099;e.yerudieresiscyrillic=1273;e.yesieungkorean=12673;e.yesieungpansioskorean=12675;e.yesieungsioskorean=12674;e.yetivhebrew=1434;e.ygrave=7923;e.yhook=436;e.yhookabove=7927;e.yiarmenian=1397;e.yicyrillic=1111;e.yikorean=12642;e.yinyang=9775;e.yiwnarmenian=1410;e.ymonospace=65369;e.yod=1497;e.yoddagesh=64313;e.yoddageshhebrew=64313;e.yodhebrew=1497;e.yodyodhebrew=1522;e.yodyodpatahhebrew=64287;e.yohiragana=12424;e.yoikorean=12681;e.yokatakana=12520;e.yokatakanahalfwidth=65430;e.yokorean=12635;e.yosmallhiragana=12423;e.yosmallkatakana=12519;e.yosmallkatakanahalfwidth=65390;e.yotgreek=1011;e.yoyaekorean=12680;e.yoyakorean=12679;e.yoyakthai=3618;e.yoyingthai=3597;e.yparen=9396;e.ypogegrammeni=890;e.ypogegrammenigreekcmb=837;e.yr=422;e.yring=7833;e.ysuperior=696;e.ytilde=7929;e.yturned=654;e.yuhiragana=12422;e.yuikorean=12684;e.yukatakana=12518;e.yukatakanahalfwidth=65429;e.yukorean=12640;e.yusbigcyrillic=1131;e.yusbigiotifiedcyrillic=1133;e.yuslittlecyrillic=1127;e.yuslittleiotifiedcyrillic=1129;e.yusmallhiragana=12421;e.yusmallkatakana=12517;e.yusmallkatakanahalfwidth=65389;e.yuyekorean=12683;e.yuyeokorean=12682;e.yyabengali=2527;e.yyadeva=2399;e.z=122;e.zaarmenian=1382;e.zacute=378;e.zadeva=2395;e.zagurmukhi=2651;e.zaharabic=1592;e.zahfinalarabic=65222;e.zahinitialarabic=65223;e.zahiragana=12374;e.zahmedialarabic=65224;e.zainarabic=1586;e.zainfinalarabic=65200;e.zakatakana=12470;e.zaqefgadolhebrew=1429;e.zaqefqatanhebrew=1428;e.zarqahebrew=1432;e.zayin=1494;e.zayindagesh=64310;e.zayindageshhebrew=64310;e.zayinhebrew=1494;e.zbopomofo=12567;e.zcaron=382;e.zcircle=9449;e.zcircumflex=7825;e.zcurl=657;e.zdot=380;e.zdotaccent=380;e.zdotbelow=7827;e.zecyrillic=1079;e.zedescendercyrillic=1177;e.zedieresiscyrillic=1247;e.zehiragana=12380;e.zekatakana=12476;e.zero=48;e.zeroarabic=1632;e.zerobengali=2534;e.zerodeva=2406;e.zerogujarati=2790;e.zerogurmukhi=2662;e.zerohackarabic=1632;e.zeroinferior=8320;e.zeromonospace=65296;e.zerooldstyle=63280;e.zeropersian=1776;e.zerosuperior=8304;e.zerothai=3664;e.zerowidthjoiner=65279;e.zerowidthnonjoiner=8204;e.zerowidthspace=8203;e.zeta=950;e.zhbopomofo=12563;e.zhearmenian=1386;e.zhebrevecyrillic=1218;e.zhecyrillic=1078;e.zhedescendercyrillic=1175;e.zhedieresiscyrillic=1245;e.zihiragana=12376;e.zikatakana=12472;e.zinorhebrew=1454;e.zlinebelow=7829;e.zmonospace=65370;e.zohiragana=12382;e.zokatakana=12478;e.zparen=9397;e.zretroflexhook=656;e.zstroke=438;e.zuhiragana=12378;e.zukatakana=12474;e[".notdef"]=0;e.angbracketleftbig=9001;e.angbracketleftBig=9001;e.angbracketleftbigg=9001;e.angbracketleftBigg=9001;e.angbracketrightBig=9002;e.angbracketrightbig=9002;e.angbracketrightBigg=9002;e.angbracketrightbigg=9002;e.arrowhookleft=8618;e.arrowhookright=8617;e.arrowlefttophalf=8636;e.arrowleftbothalf=8637;e.arrownortheast=8599;e.arrownorthwest=8598;e.arrowrighttophalf=8640;e.arrowrightbothalf=8641;e.arrowsoutheast=8600;e.arrowsouthwest=8601;e.backslashbig=8726;e.backslashBig=8726;e.backslashBigg=8726;e.backslashbigg=8726;e.bardbl=8214;e.bracehtipdownleft=65079;e.bracehtipdownright=65079;e.bracehtipupleft=65080;e.bracehtipupright=65080;e.braceleftBig=123;e.braceleftbig=123;e.braceleftbigg=123;e.braceleftBigg=123;e.bracerightBig=125;e.bracerightbig=125;e.bracerightbigg=125;e.bracerightBigg=125;e.bracketleftbig=91;e.bracketleftBig=91;e.bracketleftbigg=91;e.bracketleftBigg=91;e.bracketrightBig=93;e.bracketrightbig=93;e.bracketrightbigg=93;e.bracketrightBigg=93;e.ceilingleftbig=8968;e.ceilingleftBig=8968;e.ceilingleftBigg=8968;e.ceilingleftbigg=8968;e.ceilingrightbig=8969;e.ceilingrightBig=8969;e.ceilingrightbigg=8969;e.ceilingrightBigg=8969;e.circledotdisplay=8857;e.circledottext=8857;e.circlemultiplydisplay=8855;e.circlemultiplytext=8855;e.circleplusdisplay=8853;e.circleplustext=8853;e.contintegraldisplay=8750;e.contintegraltext=8750;e.coproductdisplay=8720;e.coproducttext=8720;e.floorleftBig=8970;e.floorleftbig=8970;e.floorleftbigg=8970;e.floorleftBigg=8970;e.floorrightbig=8971;e.floorrightBig=8971;e.floorrightBigg=8971;e.floorrightbigg=8971;e.hatwide=770;e.hatwider=770;e.hatwidest=770;e.intercal=7488;e.integraldisplay=8747;e.integraltext=8747;e.intersectiondisplay=8898;e.intersectiontext=8898;e.logicalanddisplay=8743;e.logicalandtext=8743;e.logicalordisplay=8744;e.logicalortext=8744;e.parenleftBig=40;e.parenleftbig=40;e.parenleftBigg=40;e.parenleftbigg=40;e.parenrightBig=41;e.parenrightbig=41;e.parenrightBigg=41;e.parenrightbigg=41;e.prime=8242;e.productdisplay=8719;e.producttext=8719;e.radicalbig=8730;e.radicalBig=8730;e.radicalBigg=8730;e.radicalbigg=8730;e.radicalbt=8730;e.radicaltp=8730;e.radicalvertex=8730;e.slashbig=47;e.slashBig=47;e.slashBigg=47;e.slashbigg=47;e.summationdisplay=8721;e.summationtext=8721;e.tildewide=732;e.tildewider=732;e.tildewidest=732;e.uniondisplay=8899;e.unionmultidisplay=8846;e.unionmultitext=8846;e.unionsqdisplay=8852;e.unionsqtext=8852;e.uniontext=8899;e.vextenddouble=8741;e.vextendsingle=8739})),n=r((function(e){e.space=32;e.a1=9985;e.a2=9986;e.a202=9987;e.a3=9988;e.a4=9742;e.a5=9990;e.a119=9991;e.a118=9992;e.a117=9993;e.a11=9755;e.a12=9758;e.a13=9996;e.a14=9997;e.a15=9998;e.a16=9999;e.a105=1e4;e.a17=10001;e.a18=10002;e.a19=10003;e.a20=10004;e.a21=10005;e.a22=10006;e.a23=10007;e.a24=10008;e.a25=10009;e.a26=10010;e.a27=10011;e.a28=10012;e.a6=10013;e.a7=10014;e.a8=10015;e.a9=10016;e.a10=10017;e.a29=10018;e.a30=10019;e.a31=10020;e.a32=10021;e.a33=10022;e.a34=10023;e.a35=9733;e.a36=10025;e.a37=10026;e.a38=10027;e.a39=10028;e.a40=10029;e.a41=10030;e.a42=10031;e.a43=10032;e.a44=10033;e.a45=10034;e.a46=10035;e.a47=10036;e.a48=10037;e.a49=10038;e.a50=10039;e.a51=10040;e.a52=10041;e.a53=10042;e.a54=10043;e.a55=10044;e.a56=10045;e.a57=10046;e.a58=10047;e.a59=10048;e.a60=10049;e.a61=10050;e.a62=10051;e.a63=10052;e.a64=10053;e.a65=10054;e.a66=10055;e.a67=10056;e.a68=10057;e.a69=10058;e.a70=10059;e.a71=9679;e.a72=10061;e.a73=9632;e.a74=10063;e.a203=10064;e.a75=10065;e.a204=10066;e.a76=9650;e.a77=9660;e.a78=9670;e.a79=10070;e.a81=9687;e.a82=10072;e.a83=10073;e.a84=10074;e.a97=10075;e.a98=10076;e.a99=10077;e.a100=10078;e.a101=10081;e.a102=10082;e.a103=10083;e.a104=10084;e.a106=10085;e.a107=10086;e.a108=10087;e.a112=9827;e.a111=9830;e.a110=9829;e.a109=9824;e.a120=9312;e.a121=9313;e.a122=9314;e.a123=9315;e.a124=9316;e.a125=9317;e.a126=9318;e.a127=9319;e.a128=9320;e.a129=9321;e.a130=10102;e.a131=10103;e.a132=10104;e.a133=10105;e.a134=10106;e.a135=10107;e.a136=10108;e.a137=10109;e.a138=10110;e.a139=10111;e.a140=10112;e.a141=10113;e.a142=10114;e.a143=10115;e.a144=10116;e.a145=10117;e.a146=10118;e.a147=10119;e.a148=10120;e.a149=10121;e.a150=10122;e.a151=10123;e.a152=10124;e.a153=10125;e.a154=10126;e.a155=10127;e.a156=10128;e.a157=10129;e.a158=10130;e.a159=10131;e.a160=10132;e.a161=8594;e.a163=8596;e.a164=8597;e.a196=10136;e.a165=10137;e.a192=10138;e.a166=10139;e.a167=10140;e.a168=10141;e.a169=10142;e.a170=10143;e.a171=10144;e.a172=10145;e.a173=10146;e.a162=10147;e.a174=10148;e.a175=10149;e.a176=10150;e.a177=10151;e.a178=10152;e.a179=10153;e.a193=10154;e.a180=10155;e.a199=10156;e.a181=10157;e.a200=10158;e.a182=10159;e.a201=10161;e.a183=10162;e.a184=10163;e.a197=10164;e.a185=10165;e.a194=10166;e.a198=10167;e.a186=10168;e.a195=10169;e.a187=10170;e.a188=10171;e.a189=10172;e.a190=10173;e.a191=10174;e.a89=10088;e.a90=10089;e.a93=10090;e.a94=10091;e.a91=10092;e.a92=10093;e.a205=10094;e.a85=10095;e.a206=10096;e.a86=10097;e.a87=10098;e.a88=10099;e.a95=10100;e.a96=10101;e[".notdef"]=0}));t.getGlyphsUnicode=i;t.getDingbatsGlyphsUnicode=n},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getSupplementalGlyphMapForCalibri=t.getSupplementalGlyphMapForArialBlack=t.getGlyphMapForStandardFonts=t.getSymbolsFonts=t.getSerifFonts=t.getNonStdFontMap=t.getStdFontMap=void 0;var r=a(7);const i=(0,r.getLookupTableFactory)((function(e){e.ArialNarrow="Helvetica";e["ArialNarrow-Bold"]="Helvetica-Bold";e["ArialNarrow-BoldItalic"]="Helvetica-BoldOblique";e["ArialNarrow-Italic"]="Helvetica-Oblique";e.ArialBlack="Helvetica";e["ArialBlack-Bold"]="Helvetica-Bold";e["ArialBlack-BoldItalic"]="Helvetica-BoldOblique";e["ArialBlack-Italic"]="Helvetica-Oblique";e["Arial-Black"]="Helvetica";e["Arial-Black-Bold"]="Helvetica-Bold";e["Arial-Black-BoldItalic"]="Helvetica-BoldOblique";e["Arial-Black-Italic"]="Helvetica-Oblique";e.Arial="Helvetica";e["Arial-Bold"]="Helvetica-Bold";e["Arial-BoldItalic"]="Helvetica-BoldOblique";e["Arial-Italic"]="Helvetica-Oblique";e["Arial-BoldItalicMT"]="Helvetica-BoldOblique";e["Arial-BoldMT"]="Helvetica-Bold";e["Arial-ItalicMT"]="Helvetica-Oblique";e.ArialMT="Helvetica";e["Courier-Bold"]="Courier-Bold";e["Courier-BoldItalic"]="Courier-BoldOblique";e["Courier-Italic"]="Courier-Oblique";e.CourierNew="Courier";e["CourierNew-Bold"]="Courier-Bold";e["CourierNew-BoldItalic"]="Courier-BoldOblique";e["CourierNew-Italic"]="Courier-Oblique";e["CourierNewPS-BoldItalicMT"]="Courier-BoldOblique";e["CourierNewPS-BoldMT"]="Courier-Bold";e["CourierNewPS-ItalicMT"]="Courier-Oblique";e.CourierNewPSMT="Courier";e.Helvetica="Helvetica";e["Helvetica-Bold"]="Helvetica-Bold";e["Helvetica-BoldItalic"]="Helvetica-BoldOblique";e["Helvetica-BoldOblique"]="Helvetica-BoldOblique";e["Helvetica-Italic"]="Helvetica-Oblique";e["Helvetica-Oblique"]="Helvetica-Oblique";e["Symbol-Bold"]="Symbol";e["Symbol-BoldItalic"]="Symbol";e["Symbol-Italic"]="Symbol";e.TimesNewRoman="Times-Roman";e["TimesNewRoman-Bold"]="Times-Bold";e["TimesNewRoman-BoldItalic"]="Times-BoldItalic";e["TimesNewRoman-Italic"]="Times-Italic";e.TimesNewRomanPS="Times-Roman";e["TimesNewRomanPS-Bold"]="Times-Bold";e["TimesNewRomanPS-BoldItalic"]="Times-BoldItalic";e["TimesNewRomanPS-BoldItalicMT"]="Times-BoldItalic";e["TimesNewRomanPS-BoldMT"]="Times-Bold";e["TimesNewRomanPS-Italic"]="Times-Italic";e["TimesNewRomanPS-ItalicMT"]="Times-Italic";e.TimesNewRomanPSMT="Times-Roman";e["TimesNewRomanPSMT-Bold"]="Times-Bold";e["TimesNewRomanPSMT-BoldItalic"]="Times-BoldItalic";e["TimesNewRomanPSMT-Italic"]="Times-Italic"}));t.getStdFontMap=i;const n=(0,r.getLookupTableFactory)((function(e){e.Calibri="Helvetica";e["Calibri-Bold"]="Helvetica-Bold";e["Calibri-BoldItalic"]="Helvetica-BoldOblique";e["Calibri-Italic"]="Helvetica-Oblique";e.CenturyGothic="Helvetica";e["CenturyGothic-Bold"]="Helvetica-Bold";e["CenturyGothic-BoldItalic"]="Helvetica-BoldOblique";e["CenturyGothic-Italic"]="Helvetica-Oblique";e.ComicSansMS="Comic Sans MS";e["ComicSansMS-Bold"]="Comic Sans MS-Bold";e["ComicSansMS-BoldItalic"]="Comic Sans MS-BoldItalic";e["ComicSansMS-Italic"]="Comic Sans MS-Italic";e.LucidaConsole="Courier";e["LucidaConsole-Bold"]="Courier-Bold";e["LucidaConsole-BoldItalic"]="Courier-BoldOblique";e["LucidaConsole-Italic"]="Courier-Oblique";e["LucidaSans-Demi"]="Helvetica-Bold";e["MS-Gothic"]="MS Gothic";e["MS-Gothic-Bold"]="MS Gothic-Bold";e["MS-Gothic-BoldItalic"]="MS Gothic-BoldItalic";e["MS-Gothic-Italic"]="MS Gothic-Italic";e["MS-Mincho"]="MS Mincho";e["MS-Mincho-Bold"]="MS Mincho-Bold";e["MS-Mincho-BoldItalic"]="MS Mincho-BoldItalic";e["MS-Mincho-Italic"]="MS Mincho-Italic";e["MS-PGothic"]="MS PGothic";e["MS-PGothic-Bold"]="MS PGothic-Bold";e["MS-PGothic-BoldItalic"]="MS PGothic-BoldItalic";e["MS-PGothic-Italic"]="MS PGothic-Italic";e["MS-PMincho"]="MS PMincho";e["MS-PMincho-Bold"]="MS PMincho-Bold";e["MS-PMincho-BoldItalic"]="MS PMincho-BoldItalic";e["MS-PMincho-Italic"]="MS PMincho-Italic";e.NuptialScript="Times-Italic";e.SegoeUISymbol="Helvetica";e.Wingdings="ZapfDingbats";e["Wingdings-Regular"]="ZapfDingbats"}));t.getNonStdFontMap=n;const s=(0,r.getLookupTableFactory)((function(e){e["Adobe Jenson"]=!0;e["Adobe Text"]=!0;e.Albertus=!0;e.Aldus=!0;e.Alexandria=!0;e.Algerian=!0;e["American Typewriter"]=!0;e.Antiqua=!0;e.Apex=!0;e.Arno=!0;e.Aster=!0;e.Aurora=!0;e.Baskerville=!0;e.Bell=!0;e.Bembo=!0;e["Bembo Schoolbook"]=!0;e.Benguiat=!0;e["Berkeley Old Style"]=!0;e["Bernhard Modern"]=!0;e["Berthold City"]=!0;e.Bodoni=!0;e["Bauer Bodoni"]=!0;e["Book Antiqua"]=!0;e.Bookman=!0;e["Bordeaux Roman"]=!0;e["Californian FB"]=!0;e.Calisto=!0;e.Calvert=!0;e.Capitals=!0;e.Cambria=!0;e.Cartier=!0;e.Caslon=!0;e.Catull=!0;e.Centaur=!0;e["Century Old Style"]=!0;e["Century Schoolbook"]=!0;e.Chaparral=!0;e["Charis SIL"]=!0;e.Cheltenham=!0;e["Cholla Slab"]=!0;e.Clarendon=!0;e.Clearface=!0;e.Cochin=!0;e.Colonna=!0;e["Computer Modern"]=!0;e["Concrete Roman"]=!0;e.Constantia=!0;e["Cooper Black"]=!0;e.Corona=!0;e.Ecotype=!0;e.Egyptienne=!0;e.Elephant=!0;e.Excelsior=!0;e.Fairfield=!0;e["FF Scala"]=!0;e.Folkard=!0;e.Footlight=!0;e.FreeSerif=!0;e["Friz Quadrata"]=!0;e.Garamond=!0;e.Gentium=!0;e.Georgia=!0;e.Gloucester=!0;e["Goudy Old Style"]=!0;e["Goudy Schoolbook"]=!0;e["Goudy Pro Font"]=!0;e.Granjon=!0;e["Guardian Egyptian"]=!0;e.Heather=!0;e.Hercules=!0;e["High Tower Text"]=!0;e.Hiroshige=!0;e["Hoefler Text"]=!0;e["Humana Serif"]=!0;e.Imprint=!0;e["Ionic No. 5"]=!0;e.Janson=!0;e.Joanna=!0;e.Korinna=!0;e.Lexicon=!0;e["Liberation Serif"]=!0;e["Linux Libertine"]=!0;e.Literaturnaya=!0;e.Lucida=!0;e["Lucida Bright"]=!0;e.Melior=!0;e.Memphis=!0;e.Miller=!0;e.Minion=!0;e.Modern=!0;e["Mona Lisa"]=!0;e["Mrs Eaves"]=!0;e["MS Serif"]=!0;e["Museo Slab"]=!0;e["New York"]=!0;e["Nimbus Roman"]=!0;e["NPS Rawlinson Roadway"]=!0;e.NuptialScript=!0;e.Palatino=!0;e.Perpetua=!0;e.Plantin=!0;e["Plantin Schoolbook"]=!0;e.Playbill=!0;e["Poor Richard"]=!0;e["Rawlinson Roadway"]=!0;e.Renault=!0;e.Requiem=!0;e.Rockwell=!0;e.Roman=!0;e["Rotis Serif"]=!0;e.Sabon=!0;e.Scala=!0;e.Seagull=!0;e.Sistina=!0;e.Souvenir=!0;e.STIX=!0;e["Stone Informal"]=!0;e["Stone Serif"]=!0;e.Sylfaen=!0;e.Times=!0;e.Trajan=!0;e["Trinité"]=!0;e["Trump Mediaeval"]=!0;e.Utopia=!0;e["Vale Type"]=!0;e["Bitstream Vera"]=!0;e["Vera Serif"]=!0;e.Versailles=!0;e.Wanted=!0;e.Weiss=!0;e["Wide Latin"]=!0;e.Windsor=!0;e.XITS=!0}));t.getSerifFonts=s;const o=(0,r.getLookupTableFactory)((function(e){e.Dingbats=!0;e.Symbol=!0;e.ZapfDingbats=!0}));t.getSymbolsFonts=o;const c=(0,r.getLookupTableFactory)((function(e){e[2]=10;e[3]=32;e[4]=33;e[5]=34;e[6]=35;e[7]=36;e[8]=37;e[9]=38;e[10]=39;e[11]=40;e[12]=41;e[13]=42;e[14]=43;e[15]=44;e[16]=45;e[17]=46;e[18]=47;e[19]=48;e[20]=49;e[21]=50;e[22]=51;e[23]=52;e[24]=53;e[25]=54;e[26]=55;e[27]=56;e[28]=57;e[29]=58;e[30]=894;e[31]=60;e[32]=61;e[33]=62;e[34]=63;e[35]=64;e[36]=65;e[37]=66;e[38]=67;e[39]=68;e[40]=69;e[41]=70;e[42]=71;e[43]=72;e[44]=73;e[45]=74;e[46]=75;e[47]=76;e[48]=77;e[49]=78;e[50]=79;e[51]=80;e[52]=81;e[53]=82;e[54]=83;e[55]=84;e[56]=85;e[57]=86;e[58]=87;e[59]=88;e[60]=89;e[61]=90;e[62]=91;e[63]=92;e[64]=93;e[65]=94;e[66]=95;e[67]=96;e[68]=97;e[69]=98;e[70]=99;e[71]=100;e[72]=101;e[73]=102;e[74]=103;e[75]=104;e[76]=105;e[77]=106;e[78]=107;e[79]=108;e[80]=109;e[81]=110;e[82]=111;e[83]=112;e[84]=113;e[85]=114;e[86]=115;e[87]=116;e[88]=117;e[89]=118;e[90]=119;e[91]=120;e[92]=121;e[93]=122;e[94]=123;e[95]=124;e[96]=125;e[97]=126;e[98]=196;e[99]=197;e[100]=199;e[101]=201;e[102]=209;e[103]=214;e[104]=220;e[105]=225;e[106]=224;e[107]=226;e[108]=228;e[109]=227;e[110]=229;e[111]=231;e[112]=233;e[113]=232;e[114]=234;e[115]=235;e[116]=237;e[117]=236;e[118]=238;e[119]=239;e[120]=241;e[121]=243;e[122]=242;e[123]=244;e[124]=246;e[125]=245;e[126]=250;e[127]=249;e[128]=251;e[129]=252;e[130]=8224;e[131]=176;e[132]=162;e[133]=163;e[134]=167;e[135]=8226;e[136]=182;e[137]=223;e[138]=174;e[139]=169;e[140]=8482;e[141]=180;e[142]=168;e[143]=8800;e[144]=198;e[145]=216;e[146]=8734;e[147]=177;e[148]=8804;e[149]=8805;e[150]=165;e[151]=181;e[152]=8706;e[153]=8721;e[154]=8719;e[156]=8747;e[157]=170;e[158]=186;e[159]=8486;e[160]=230;e[161]=248;e[162]=191;e[163]=161;e[164]=172;e[165]=8730;e[166]=402;e[167]=8776;e[168]=8710;e[169]=171;e[170]=187;e[171]=8230;e[210]=218;e[223]=711;e[224]=321;e[225]=322;e[227]=353;e[229]=382;e[234]=253;e[252]=263;e[253]=268;e[254]=269;e[258]=258;e[260]=260;e[261]=261;e[265]=280;e[266]=281;e[268]=283;e[269]=313;e[275]=323;e[276]=324;e[278]=328;e[284]=345;e[285]=346;e[286]=347;e[292]=367;e[295]=377;e[296]=378;e[298]=380;e[305]=963;e[306]=964;e[307]=966;e[308]=8215;e[309]=8252;e[310]=8319;e[311]=8359;e[312]=8592;e[313]=8593;e[337]=9552;e[493]=1039;e[494]=1040;e[705]=1524;e[706]=8362;e[710]=64288;e[711]=64298;e[759]=1617;e[761]=1776;e[763]=1778;e[775]=1652;e[777]=1764;e[778]=1780;e[779]=1781;e[780]=1782;e[782]=771;e[783]=64726;e[786]=8363;e[788]=8532;e[790]=768;e[791]=769;e[792]=768;e[795]=803;e[797]=64336;e[798]=64337;e[799]=64342;e[800]=64343;e[801]=64344;e[802]=64345;e[803]=64362;e[804]=64363;e[805]=64364;e[2424]=7821;e[2425]=7822;e[2426]=7823;e[2427]=7824;e[2428]=7825;e[2429]=7826;e[2430]=7827;e[2433]=7682;e[2678]=8045;e[2679]=8046;e[2830]=1552;e[2838]=686;e[2840]=751;e[2842]=753;e[2843]=754;e[2844]=755;e[2846]=757;e[2856]=767;e[2857]=848;e[2858]=849;e[2862]=853;e[2863]=854;e[2864]=855;e[2865]=861;e[2866]=862;e[2906]=7460;e[2908]=7462;e[2909]=7463;e[2910]=7464;e[2912]=7466;e[2913]=7467;e[2914]=7468;e[2916]=7470;e[2917]=7471;e[2918]=7472;e[2920]=7474;e[2921]=7475;e[2922]=7476;e[2924]=7478;e[2925]=7479;e[2926]=7480;e[2928]=7482;e[2929]=7483;e[2930]=7484;e[2932]=7486;e[2933]=7487;e[2934]=7488;e[2936]=7490;e[2937]=7491;e[2938]=7492;e[2940]=7494;e[2941]=7495;e[2942]=7496;e[2944]=7498;e[2946]=7500;e[2948]=7502;e[2950]=7504;e[2951]=7505;e[2952]=7506;e[2954]=7508;e[2955]=7509;e[2956]=7510;e[2958]=7512;e[2959]=7513;e[2960]=7514;e[2962]=7516;e[2963]=7517;e[2964]=7518;e[2966]=7520;e[2967]=7521;e[2968]=7522;e[2970]=7524;e[2971]=7525;e[2972]=7526;e[2974]=7528;e[2975]=7529;e[2976]=7530;e[2978]=1537;e[2979]=1538;e[2980]=1539;e[2982]=1549;e[2983]=1551;e[2984]=1552;e[2986]=1554;e[2987]=1555;e[2988]=1556;e[2990]=1623;e[2991]=1624;e[2995]=1775;e[2999]=1791;e[3002]=64290;e[3003]=64291;e[3004]=64292;e[3006]=64294;e[3007]=64295;e[3008]=64296;e[3011]=1900;e[3014]=8223;e[3015]=8244;e[3017]=7532;e[3018]=7533;e[3019]=7534;e[3075]=7590;e[3076]=7591;e[3079]=7594;e[3080]=7595;e[3083]=7598;e[3084]=7599;e[3087]=7602;e[3088]=7603;e[3091]=7606;e[3092]=7607;e[3095]=7610;e[3096]=7611;e[3099]=7614;e[3100]=7615;e[3103]=7618;e[3104]=7619;e[3107]=8337;e[3108]=8338;e[3116]=1884;e[3119]=1885;e[3120]=1885;e[3123]=1886;e[3124]=1886;e[3127]=1887;e[3128]=1887;e[3131]=1888;e[3132]=1888;e[3135]=1889;e[3136]=1889;e[3139]=1890;e[3140]=1890;e[3143]=1891;e[3144]=1891;e[3147]=1892;e[3148]=1892;e[3153]=580;e[3154]=581;e[3157]=584;e[3158]=585;e[3161]=588;e[3162]=589;e[3165]=891;e[3166]=892;e[3169]=1274;e[3170]=1275;e[3173]=1278;e[3174]=1279;e[3181]=7622;e[3182]=7623;e[3282]=11799;e[3316]=578;e[3379]=42785;e[3393]=1159;e[3416]=8377}));t.getGlyphMapForStandardFonts=c;const l=(0,r.getLookupTableFactory)((function(e){e[227]=322;e[264]=261;e[291]=346}));t.getSupplementalGlyphMapForArialBlack=l;const h=(0,r.getLookupTableFactory)((function(e){e[1]=32;e[4]=65;e[17]=66;e[18]=67;e[24]=68;e[28]=69;e[38]=70;e[39]=71;e[44]=72;e[47]=73;e[58]=74;e[60]=75;e[62]=76;e[68]=77;e[69]=78;e[75]=79;e[87]=80;e[89]=81;e[90]=82;e[94]=83;e[100]=84;e[104]=85;e[115]=86;e[116]=87;e[121]=88;e[122]=89;e[127]=90;e[258]=97;e[268]=261;e[271]=98;e[272]=99;e[273]=263;e[282]=100;e[286]=101;e[295]=281;e[296]=102;e[336]=103;e[346]=104;e[349]=105;e[361]=106;e[364]=107;e[367]=108;e[371]=322;e[373]=109;e[374]=110;e[381]=111;e[383]=243;e[393]=112;e[395]=113;e[396]=114;e[400]=115;e[401]=347;e[410]=116;e[437]=117;e[448]=118;e[449]=119;e[454]=120;e[455]=121;e[460]=122;e[463]=380;e[853]=44;e[855]=58;e[856]=46;e[876]=47;e[878]=45;e[882]=45;e[894]=40;e[895]=41;e[896]=91;e[897]=93;e[923]=64;e[1004]=48;e[1005]=49;e[1006]=50;e[1007]=51;e[1008]=52;e[1009]=53;e[1010]=54;e[1011]=55;e[1012]=56;e[1013]=57;e[1081]=37;e[1085]=43;e[1086]=45}));t.getSupplementalGlyphMapForCalibri=h},function(e,t,a){var r=a(7).getLookupTableFactory,i=r((function(e){e[63721]=169;e[63193]=169;e[63720]=174;e[63194]=174;e[63722]=8482;e[63195]=8482;e[63729]=9127;e[63730]=9128;e[63731]=9129;e[63740]=9131;e[63741]=9132;e[63742]=9133;e[63726]=9121;e[63727]=9122;e[63728]=9123;e[63737]=9124;e[63738]=9125;e[63739]=9126;e[63723]=9115;e[63724]=9116;e[63725]=9117;e[63734]=9118;e[63735]=9119;e[63736]=9120}));var n=[{begin:0,end:127},{begin:128,end:255},{begin:256,end:383},{begin:384,end:591},{begin:592,end:687},{begin:688,end:767},{begin:768,end:879},{begin:880,end:1023},{begin:11392,end:11519},{begin:1024,end:1279},{begin:1328,end:1423},{begin:1424,end:1535},{begin:42240,end:42559},{begin:1536,end:1791},{begin:1984,end:2047},{begin:2304,end:2431},{begin:2432,end:2559},{begin:2560,end:2687},{begin:2688,end:2815},{begin:2816,end:2943},{begin:2944,end:3071},{begin:3072,end:3199},{begin:3200,end:3327},{begin:3328,end:3455},{begin:3584,end:3711},{begin:3712,end:3839},{begin:4256,end:4351},{begin:6912,end:7039},{begin:4352,end:4607},{begin:7680,end:7935},{begin:7936,end:8191},{begin:8192,end:8303},{begin:8304,end:8351},{begin:8352,end:8399},{begin:8400,end:8447},{begin:8448,end:8527},{begin:8528,end:8591},{begin:8592,end:8703},{begin:8704,end:8959},{begin:8960,end:9215},{begin:9216,end:9279},{begin:9280,end:9311},{begin:9312,end:9471},{begin:9472,end:9599},{begin:9600,end:9631},{begin:9632,end:9727},{begin:9728,end:9983},{begin:9984,end:10175},{begin:12288,end:12351},{begin:12352,end:12447},{begin:12448,end:12543},{begin:12544,end:12591},{begin:12592,end:12687},{begin:43072,end:43135},{begin:12800,end:13055},{begin:13056,end:13311},{begin:44032,end:55215},{begin:55296,end:57343},{begin:67840,end:67871},{begin:19968,end:40959},{begin:57344,end:63743},{begin:12736,end:12783},{begin:64256,end:64335},{begin:64336,end:65023},{begin:65056,end:65071},{begin:65040,end:65055},{begin:65104,end:65135},{begin:65136,end:65279},{begin:65280,end:65519},{begin:65520,end:65535},{begin:3840,end:4095},{begin:1792,end:1871},{begin:1920,end:1983},{begin:3456,end:3583},{begin:4096,end:4255},{begin:4608,end:4991},{begin:5024,end:5119},{begin:5120,end:5759},{begin:5760,end:5791},{begin:5792,end:5887},{begin:6016,end:6143},{begin:6144,end:6319},{begin:10240,end:10495},{begin:40960,end:42127},{begin:5888,end:5919},{begin:66304,end:66351},{begin:66352,end:66383},{begin:66560,end:66639},{begin:118784,end:119039},{begin:119808,end:120831},{begin:1044480,end:1048573},{begin:65024,end:65039},{begin:917504,end:917631},{begin:6400,end:6479},{begin:6480,end:6527},{begin:6528,end:6623},{begin:6656,end:6687},{begin:11264,end:11359},{begin:11568,end:11647},{begin:19904,end:19967},{begin:43008,end:43055},{begin:65536,end:65663},{begin:65856,end:65935},{begin:66432,end:66463},{begin:66464,end:66527},{begin:66640,end:66687},{begin:66688,end:66735},{begin:67584,end:67647},{begin:68096,end:68191},{begin:119552,end:119647},{begin:73728,end:74751},{begin:119648,end:119679},{begin:7040,end:7103},{begin:7168,end:7247},{begin:7248,end:7295},{begin:43136,end:43231},{begin:43264,end:43311},{begin:43312,end:43359},{begin:43520,end:43615},{begin:65936,end:65999},{begin:66e3,end:66047},{begin:66208,end:66271},{begin:127024,end:127135}];var s=r((function(e){e["¨"]=" ̈";e["¯"]=" ̄";e["´"]=" ́";e["µ"]="μ";e["¸"]=" ̧";e["IJ"]="IJ";e["ij"]="ij";e["Ŀ"]="L·";e["ŀ"]="l·";e["ʼn"]="ʼn";e["ſ"]="s";e["DŽ"]="DŽ";e["Dž"]="Dž";e["dž"]="dž";e["LJ"]="LJ";e["Lj"]="Lj";e["lj"]="lj";e["NJ"]="NJ";e["Nj"]="Nj";e["nj"]="nj";e["DZ"]="DZ";e["Dz"]="Dz";e["dz"]="dz";e["˘"]=" ̆";e["˙"]=" ̇";e["˚"]=" ̊";e["˛"]=" ̨";e["˜"]=" ̃";e["˝"]=" ̋";e["ͺ"]=" ͅ";e["΄"]=" ́";e["ϐ"]="β";e["ϑ"]="θ";e["ϒ"]="Υ";e["ϕ"]="φ";e["ϖ"]="π";e["ϰ"]="κ";e["ϱ"]="ρ";e["ϲ"]="ς";e["ϴ"]="Θ";e["ϵ"]="ε";e["Ϲ"]="Σ";e["և"]="եւ";e["ٵ"]="اٴ";e["ٶ"]="وٴ";e["ٷ"]="ۇٴ";e["ٸ"]="يٴ";e["ำ"]="ํา";e["ຳ"]="ໍາ";e["ໜ"]="ຫນ";e["ໝ"]="ຫມ";e["ཷ"]="ྲཱྀ";e["ཹ"]="ླཱྀ";e["ẚ"]="aʾ";e["᾽"]=" ̓";e["᾿"]=" ̓";e["῀"]=" ͂";e["῾"]=" ̔";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e[" "]=" ";e["‗"]=" ̳";e["․"]=".";e["‥"]="..";e["…"]="...";e["″"]="′′";e["‴"]="′′′";e["‶"]="‵‵";e["‷"]="‵‵‵";e["‼"]="!!";e["‾"]=" ̅";e["⁇"]="??";e["⁈"]="?!";e["⁉"]="!?";e["⁗"]="′′′′";e[" "]=" ";e["₨"]="Rs";e["℀"]="a/c";e["℁"]="a/s";e["℃"]="°C";e["℅"]="c/o";e["℆"]="c/u";e["ℇ"]="Ɛ";e["℉"]="°F";e["№"]="No";e["℡"]="TEL";e["ℵ"]="א";e["ℶ"]="ב";e["ℷ"]="ג";e["ℸ"]="ד";e["℻"]="FAX";e["Ⅰ"]="I";e["Ⅱ"]="II";e["Ⅲ"]="III";e["Ⅳ"]="IV";e["Ⅴ"]="V";e["Ⅵ"]="VI";e["Ⅶ"]="VII";e["Ⅷ"]="VIII";e["Ⅸ"]="IX";e["Ⅹ"]="X";e["Ⅺ"]="XI";e["Ⅻ"]="XII";e["Ⅼ"]="L";e["Ⅽ"]="C";e["Ⅾ"]="D";e["Ⅿ"]="M";e["ⅰ"]="i";e["ⅱ"]="ii";e["ⅲ"]="iii";e["ⅳ"]="iv";e["ⅴ"]="v";e["ⅵ"]="vi";e["ⅶ"]="vii";e["ⅷ"]="viii";e["ⅸ"]="ix";e["ⅹ"]="x";e["ⅺ"]="xi";e["ⅻ"]="xii";e["ⅼ"]="l";e["ⅽ"]="c";e["ⅾ"]="d";e["ⅿ"]="m";e["∬"]="∫∫";e["∭"]="∫∫∫";e["∯"]="∮∮";e["∰"]="∮∮∮";e["⑴"]="(1)";e["⑵"]="(2)";e["⑶"]="(3)";e["⑷"]="(4)";e["⑸"]="(5)";e["⑹"]="(6)";e["⑺"]="(7)";e["⑻"]="(8)";e["⑼"]="(9)";e["⑽"]="(10)";e["⑾"]="(11)";e["⑿"]="(12)";e["⒀"]="(13)";e["⒁"]="(14)";e["⒂"]="(15)";e["⒃"]="(16)";e["⒄"]="(17)";e["⒅"]="(18)";e["⒆"]="(19)";e["⒇"]="(20)";e["⒈"]="1.";e["⒉"]="2.";e["⒊"]="3.";e["⒋"]="4.";e["⒌"]="5.";e["⒍"]="6.";e["⒎"]="7.";e["⒏"]="8.";e["⒐"]="9.";e["⒑"]="10.";e["⒒"]="11.";e["⒓"]="12.";e["⒔"]="13.";e["⒕"]="14.";e["⒖"]="15.";e["⒗"]="16.";e["⒘"]="17.";e["⒙"]="18.";e["⒚"]="19.";e["⒛"]="20.";e["⒜"]="(a)";e["⒝"]="(b)";e["⒞"]="(c)";e["⒟"]="(d)";e["⒠"]="(e)";e["⒡"]="(f)";e["⒢"]="(g)";e["⒣"]="(h)";e["⒤"]="(i)";e["⒥"]="(j)";e["⒦"]="(k)";e["⒧"]="(l)";e["⒨"]="(m)";e["⒩"]="(n)";e["⒪"]="(o)";e["⒫"]="(p)";e["⒬"]="(q)";e["⒭"]="(r)";e["⒮"]="(s)";e["⒯"]="(t)";e["⒰"]="(u)";e["⒱"]="(v)";e["⒲"]="(w)";e["⒳"]="(x)";e["⒴"]="(y)";e["⒵"]="(z)";e["⨌"]="∫∫∫∫";e["⩴"]="::=";e["⩵"]="==";e["⩶"]="===";e["⺟"]="母";e["⻳"]="龟";e["⼀"]="一";e["⼁"]="丨";e["⼂"]="丶";e["⼃"]="丿";e["⼄"]="乙";e["⼅"]="亅";e["⼆"]="二";e["⼇"]="亠";e["⼈"]="人";e["⼉"]="儿";e["⼊"]="入";e["⼋"]="八";e["⼌"]="冂";e["⼍"]="冖";e["⼎"]="冫";e["⼏"]="几";e["⼐"]="凵";e["⼑"]="刀";e["⼒"]="力";e["⼓"]="勹";e["⼔"]="匕";e["⼕"]="匚";e["⼖"]="匸";e["⼗"]="十";e["⼘"]="卜";e["⼙"]="卩";e["⼚"]="厂";e["⼛"]="厶";e["⼜"]="又";e["⼝"]="口";e["⼞"]="囗";e["⼟"]="土";e["⼠"]="士";e["⼡"]="夂";e["⼢"]="夊";e["⼣"]="夕";e["⼤"]="大";e["⼥"]="女";e["⼦"]="子";e["⼧"]="宀";e["⼨"]="寸";e["⼩"]="小";e["⼪"]="尢";e["⼫"]="尸";e["⼬"]="屮";e["⼭"]="山";e["⼮"]="巛";e["⼯"]="工";e["⼰"]="己";e["⼱"]="巾";e["⼲"]="干";e["⼳"]="幺";e["⼴"]="广";e["⼵"]="廴";e["⼶"]="廾";e["⼷"]="弋";e["⼸"]="弓";e["⼹"]="彐";e["⼺"]="彡";e["⼻"]="彳";e["⼼"]="心";e["⼽"]="戈";e["⼾"]="戶";e["⼿"]="手";e["⽀"]="支";e["⽁"]="攴";e["⽂"]="文";e["⽃"]="斗";e["⽄"]="斤";e["⽅"]="方";e["⽆"]="无";e["⽇"]="日";e["⽈"]="曰";e["⽉"]="月";e["⽊"]="木";e["⽋"]="欠";e["⽌"]="止";e["⽍"]="歹";e["⽎"]="殳";e["⽏"]="毋";e["⽐"]="比";e["⽑"]="毛";e["⽒"]="氏";e["⽓"]="气";e["⽔"]="水";e["⽕"]="火";e["⽖"]="爪";e["⽗"]="父";e["⽘"]="爻";e["⽙"]="爿";e["⽚"]="片";e["⽛"]="牙";e["⽜"]="牛";e["⽝"]="犬";e["⽞"]="玄";e["⽟"]="玉";e["⽠"]="瓜";e["⽡"]="瓦";e["⽢"]="甘";e["⽣"]="生";e["⽤"]="用";e["⽥"]="田";e["⽦"]="疋";e["⽧"]="疒";e["⽨"]="癶";e["⽩"]="白";e["⽪"]="皮";e["⽫"]="皿";e["⽬"]="目";e["⽭"]="矛";e["⽮"]="矢";e["⽯"]="石";e["⽰"]="示";e["⽱"]="禸";e["⽲"]="禾";e["⽳"]="穴";e["⽴"]="立";e["⽵"]="竹";e["⽶"]="米";e["⽷"]="糸";e["⽸"]="缶";e["⽹"]="网";e["⽺"]="羊";e["⽻"]="羽";e["⽼"]="老";e["⽽"]="而";e["⽾"]="耒";e["⽿"]="耳";e["⾀"]="聿";e["⾁"]="肉";e["⾂"]="臣";e["⾃"]="自";e["⾄"]="至";e["⾅"]="臼";e["⾆"]="舌";e["⾇"]="舛";e["⾈"]="舟";e["⾉"]="艮";e["⾊"]="色";e["⾋"]="艸";e["⾌"]="虍";e["⾍"]="虫";e["⾎"]="血";e["⾏"]="行";e["⾐"]="衣";e["⾑"]="襾";e["⾒"]="見";e["⾓"]="角";e["⾔"]="言";e["⾕"]="谷";e["⾖"]="豆";e["⾗"]="豕";e["⾘"]="豸";e["⾙"]="貝";e["⾚"]="赤";e["⾛"]="走";e["⾜"]="足";e["⾝"]="身";e["⾞"]="車";e["⾟"]="辛";e["⾠"]="辰";e["⾡"]="辵";e["⾢"]="邑";e["⾣"]="酉";e["⾤"]="釆";e["⾥"]="里";e["⾦"]="金";e["⾧"]="長";e["⾨"]="門";e["⾩"]="阜";e["⾪"]="隶";e["⾫"]="隹";e["⾬"]="雨";e["⾭"]="靑";e["⾮"]="非";e["⾯"]="面";e["⾰"]="革";e["⾱"]="韋";e["⾲"]="韭";e["⾳"]="音";e["⾴"]="頁";e["⾵"]="風";e["⾶"]="飛";e["⾷"]="食";e["⾸"]="首";e["⾹"]="香";e["⾺"]="馬";e["⾻"]="骨";e["⾼"]="高";e["⾽"]="髟";e["⾾"]="鬥";e["⾿"]="鬯";e["⿀"]="鬲";e["⿁"]="鬼";e["⿂"]="魚";e["⿃"]="鳥";e["⿄"]="鹵";e["⿅"]="鹿";e["⿆"]="麥";e["⿇"]="麻";e["⿈"]="黃";e["⿉"]="黍";e["⿊"]="黑";e["⿋"]="黹";e["⿌"]="黽";e["⿍"]="鼎";e["⿎"]="鼓";e["⿏"]="鼠";e["⿐"]="鼻";e["⿑"]="齊";e["⿒"]="齒";e["⿓"]="龍";e["⿔"]="龜";e["⿕"]="龠";e["〶"]="〒";e["〸"]="十";e["〹"]="卄";e["〺"]="卅";e["゛"]=" ゙";e["゜"]=" ゚";e["ㄱ"]="ᄀ";e["ㄲ"]="ᄁ";e["ㄳ"]="ᆪ";e["ㄴ"]="ᄂ";e["ㄵ"]="ᆬ";e["ㄶ"]="ᆭ";e["ㄷ"]="ᄃ";e["ㄸ"]="ᄄ";e["ㄹ"]="ᄅ";e["ㄺ"]="ᆰ";e["ㄻ"]="ᆱ";e["ㄼ"]="ᆲ";e["ㄽ"]="ᆳ";e["ㄾ"]="ᆴ";e["ㄿ"]="ᆵ";e["ㅀ"]="ᄚ";e["ㅁ"]="ᄆ";e["ㅂ"]="ᄇ";e["ㅃ"]="ᄈ";e["ㅄ"]="ᄡ";e["ㅅ"]="ᄉ";e["ㅆ"]="ᄊ";e["ㅇ"]="ᄋ";e["ㅈ"]="ᄌ";e["ㅉ"]="ᄍ";e["ㅊ"]="ᄎ";e["ㅋ"]="ᄏ";e["ㅌ"]="ᄐ";e["ㅍ"]="ᄑ";e["ㅎ"]="ᄒ";e["ㅏ"]="ᅡ";e["ㅐ"]="ᅢ";e["ㅑ"]="ᅣ";e["ㅒ"]="ᅤ";e["ㅓ"]="ᅥ";e["ㅔ"]="ᅦ";e["ㅕ"]="ᅧ";e["ㅖ"]="ᅨ";e["ㅗ"]="ᅩ";e["ㅘ"]="ᅪ";e["ㅙ"]="ᅫ";e["ㅚ"]="ᅬ";e["ㅛ"]="ᅭ";e["ㅜ"]="ᅮ";e["ㅝ"]="ᅯ";e["ㅞ"]="ᅰ";e["ㅟ"]="ᅱ";e["ㅠ"]="ᅲ";e["ㅡ"]="ᅳ";e["ㅢ"]="ᅴ";e["ㅣ"]="ᅵ";e["ㅤ"]="ᅠ";e["ㅥ"]="ᄔ";e["ㅦ"]="ᄕ";e["ㅧ"]="ᇇ";e["ㅨ"]="ᇈ";e["ㅩ"]="ᇌ";e["ㅪ"]="ᇎ";e["ㅫ"]="ᇓ";e["ㅬ"]="ᇗ";e["ㅭ"]="ᇙ";e["ㅮ"]="ᄜ";e["ㅯ"]="ᇝ";e["ㅰ"]="ᇟ";e["ㅱ"]="ᄝ";e["ㅲ"]="ᄞ";e["ㅳ"]="ᄠ";e["ㅴ"]="ᄢ";e["ㅵ"]="ᄣ";e["ㅶ"]="ᄧ";e["ㅷ"]="ᄩ";e["ㅸ"]="ᄫ";e["ㅹ"]="ᄬ";e["ㅺ"]="ᄭ";e["ㅻ"]="ᄮ";e["ㅼ"]="ᄯ";e["ㅽ"]="ᄲ";e["ㅾ"]="ᄶ";e["ㅿ"]="ᅀ";e["ㆀ"]="ᅇ";e["ㆁ"]="ᅌ";e["ㆂ"]="ᇱ";e["ㆃ"]="ᇲ";e["ㆄ"]="ᅗ";e["ㆅ"]="ᅘ";e["ㆆ"]="ᅙ";e["ㆇ"]="ᆄ";e["ㆈ"]="ᆅ";e["ㆉ"]="ᆈ";e["ㆊ"]="ᆑ";e["ㆋ"]="ᆒ";e["ㆌ"]="ᆔ";e["ㆍ"]="ᆞ";e["ㆎ"]="ᆡ";e["㈀"]="(ᄀ)";e["㈁"]="(ᄂ)";e["㈂"]="(ᄃ)";e["㈃"]="(ᄅ)";e["㈄"]="(ᄆ)";e["㈅"]="(ᄇ)";e["㈆"]="(ᄉ)";e["㈇"]="(ᄋ)";e["㈈"]="(ᄌ)";e["㈉"]="(ᄎ)";e["㈊"]="(ᄏ)";e["㈋"]="(ᄐ)";e["㈌"]="(ᄑ)";e["㈍"]="(ᄒ)";e["㈎"]="(가)";e["㈏"]="(나)";e["㈐"]="(다)";e["㈑"]="(라)";e["㈒"]="(마)";e["㈓"]="(바)";e["㈔"]="(사)";e["㈕"]="(아)";e["㈖"]="(자)";e["㈗"]="(차)";e["㈘"]="(카)";e["㈙"]="(타)";e["㈚"]="(파)";e["㈛"]="(하)";e["㈜"]="(주)";e["㈝"]="(오전)";e["㈞"]="(오후)";e["㈠"]="(一)";e["㈡"]="(二)";e["㈢"]="(三)";e["㈣"]="(四)";e["㈤"]="(五)";e["㈥"]="(六)";e["㈦"]="(七)";e["㈧"]="(八)";e["㈨"]="(九)";e["㈩"]="(十)";e["㈪"]="(月)";e["㈫"]="(火)";e["㈬"]="(水)";e["㈭"]="(木)";e["㈮"]="(金)";e["㈯"]="(土)";e["㈰"]="(日)";e["㈱"]="(株)";e["㈲"]="(有)";e["㈳"]="(社)";e["㈴"]="(名)";e["㈵"]="(特)";e["㈶"]="(財)";e["㈷"]="(祝)";e["㈸"]="(労)";e["㈹"]="(代)";e["㈺"]="(呼)";e["㈻"]="(学)";e["㈼"]="(監)";e["㈽"]="(企)";e["㈾"]="(資)";e["㈿"]="(協)";e["㉀"]="(祭)";e["㉁"]="(休)";e["㉂"]="(自)";e["㉃"]="(至)";e["㋀"]="1月";e["㋁"]="2月";e["㋂"]="3月";e["㋃"]="4月";e["㋄"]="5月";e["㋅"]="6月";e["㋆"]="7月";e["㋇"]="8月";e["㋈"]="9月";e["㋉"]="10月";e["㋊"]="11月";e["㋋"]="12月";e["㍘"]="0点";e["㍙"]="1点";e["㍚"]="2点";e["㍛"]="3点";e["㍜"]="4点";e["㍝"]="5点";e["㍞"]="6点";e["㍟"]="7点";e["㍠"]="8点";e["㍡"]="9点";e["㍢"]="10点";e["㍣"]="11点";e["㍤"]="12点";e["㍥"]="13点";e["㍦"]="14点";e["㍧"]="15点";e["㍨"]="16点";e["㍩"]="17点";e["㍪"]="18点";e["㍫"]="19点";e["㍬"]="20点";e["㍭"]="21点";e["㍮"]="22点";e["㍯"]="23点";e["㍰"]="24点";e["㏠"]="1日";e["㏡"]="2日";e["㏢"]="3日";e["㏣"]="4日";e["㏤"]="5日";e["㏥"]="6日";e["㏦"]="7日";e["㏧"]="8日";e["㏨"]="9日";e["㏩"]="10日";e["㏪"]="11日";e["㏫"]="12日";e["㏬"]="13日";e["㏭"]="14日";e["㏮"]="15日";e["㏯"]="16日";e["㏰"]="17日";e["㏱"]="18日";e["㏲"]="19日";e["㏳"]="20日";e["㏴"]="21日";e["㏵"]="22日";e["㏶"]="23日";e["㏷"]="24日";e["㏸"]="25日";e["㏹"]="26日";e["㏺"]="27日";e["㏻"]="28日";e["㏼"]="29日";e["㏽"]="30日";e["㏾"]="31日";e["ff"]="ff";e["fi"]="fi";e["fl"]="fl";e["ffi"]="ffi";e["ffl"]="ffl";e["ſt"]="ſt";e["st"]="st";e["ﬓ"]="մն";e["ﬔ"]="մե";e["ﬕ"]="մի";e["ﬖ"]="վն";e["ﬗ"]="մխ";e["ﭏ"]="אל";e["ﭐ"]="ٱ";e["ﭑ"]="ٱ";e["ﭒ"]="ٻ";e["ﭓ"]="ٻ";e["ﭔ"]="ٻ";e["ﭕ"]="ٻ";e["ﭖ"]="پ";e["ﭗ"]="پ";e["ﭘ"]="پ";e["ﭙ"]="پ";e["ﭚ"]="ڀ";e["ﭛ"]="ڀ";e["ﭜ"]="ڀ";e["ﭝ"]="ڀ";e["ﭞ"]="ٺ";e["ﭟ"]="ٺ";e["ﭠ"]="ٺ";e["ﭡ"]="ٺ";e["ﭢ"]="ٿ";e["ﭣ"]="ٿ";e["ﭤ"]="ٿ";e["ﭥ"]="ٿ";e["ﭦ"]="ٹ";e["ﭧ"]="ٹ";e["ﭨ"]="ٹ";e["ﭩ"]="ٹ";e["ﭪ"]="ڤ";e["ﭫ"]="ڤ";e["ﭬ"]="ڤ";e["ﭭ"]="ڤ";e["ﭮ"]="ڦ";e["ﭯ"]="ڦ";e["ﭰ"]="ڦ";e["ﭱ"]="ڦ";e["ﭲ"]="ڄ";e["ﭳ"]="ڄ";e["ﭴ"]="ڄ";e["ﭵ"]="ڄ";e["ﭶ"]="ڃ";e["ﭷ"]="ڃ";e["ﭸ"]="ڃ";e["ﭹ"]="ڃ";e["ﭺ"]="چ";e["ﭻ"]="چ";e["ﭼ"]="چ";e["ﭽ"]="چ";e["ﭾ"]="ڇ";e["ﭿ"]="ڇ";e["ﮀ"]="ڇ";e["ﮁ"]="ڇ";e["ﮂ"]="ڍ";e["ﮃ"]="ڍ";e["ﮄ"]="ڌ";e["ﮅ"]="ڌ";e["ﮆ"]="ڎ";e["ﮇ"]="ڎ";e["ﮈ"]="ڈ";e["ﮉ"]="ڈ";e["ﮊ"]="ژ";e["ﮋ"]="ژ";e["ﮌ"]="ڑ";e["ﮍ"]="ڑ";e["ﮎ"]="ک";e["ﮏ"]="ک";e["ﮐ"]="ک";e["ﮑ"]="ک";e["ﮒ"]="گ";e["ﮓ"]="گ";e["ﮔ"]="گ";e["ﮕ"]="گ";e["ﮖ"]="ڳ";e["ﮗ"]="ڳ";e["ﮘ"]="ڳ";e["ﮙ"]="ڳ";e["ﮚ"]="ڱ";e["ﮛ"]="ڱ";e["ﮜ"]="ڱ";e["ﮝ"]="ڱ";e["ﮞ"]="ں";e["ﮟ"]="ں";e["ﮠ"]="ڻ";e["ﮡ"]="ڻ";e["ﮢ"]="ڻ";e["ﮣ"]="ڻ";e["ﮤ"]="ۀ";e["ﮥ"]="ۀ";e["ﮦ"]="ہ";e["ﮧ"]="ہ";e["ﮨ"]="ہ";e["ﮩ"]="ہ";e["ﮪ"]="ھ";e["ﮫ"]="ھ";e["ﮬ"]="ھ";e["ﮭ"]="ھ";e["ﮮ"]="ے";e["ﮯ"]="ے";e["ﮰ"]="ۓ";e["ﮱ"]="ۓ";e["ﯓ"]="ڭ";e["ﯔ"]="ڭ";e["ﯕ"]="ڭ";e["ﯖ"]="ڭ";e["ﯗ"]="ۇ";e["ﯘ"]="ۇ";e["ﯙ"]="ۆ";e["ﯚ"]="ۆ";e["ﯛ"]="ۈ";e["ﯜ"]="ۈ";e["ﯝ"]="ٷ";e["ﯞ"]="ۋ";e["ﯟ"]="ۋ";e["ﯠ"]="ۅ";e["ﯡ"]="ۅ";e["ﯢ"]="ۉ";e["ﯣ"]="ۉ";e["ﯤ"]="ې";e["ﯥ"]="ې";e["ﯦ"]="ې";e["ﯧ"]="ې";e["ﯨ"]="ى";e["ﯩ"]="ى";e["ﯪ"]="ئا";e["ﯫ"]="ئا";e["ﯬ"]="ئە";e["ﯭ"]="ئە";e["ﯮ"]="ئو";e["ﯯ"]="ئو";e["ﯰ"]="ئۇ";e["ﯱ"]="ئۇ";e["ﯲ"]="ئۆ";e["ﯳ"]="ئۆ";e["ﯴ"]="ئۈ";e["ﯵ"]="ئۈ";e["ﯶ"]="ئې";e["ﯷ"]="ئې";e["ﯸ"]="ئې";e["ﯹ"]="ئى";e["ﯺ"]="ئى";e["ﯻ"]="ئى";e["ﯼ"]="ی";e["ﯽ"]="ی";e["ﯾ"]="ی";e["ﯿ"]="ی";e["ﰀ"]="ئج";e["ﰁ"]="ئح";e["ﰂ"]="ئم";e["ﰃ"]="ئى";e["ﰄ"]="ئي";e["ﰅ"]="بج";e["ﰆ"]="بح";e["ﰇ"]="بخ";e["ﰈ"]="بم";e["ﰉ"]="بى";e["ﰊ"]="بي";e["ﰋ"]="تج";e["ﰌ"]="تح";e["ﰍ"]="تخ";e["ﰎ"]="تم";e["ﰏ"]="تى";e["ﰐ"]="تي";e["ﰑ"]="ثج";e["ﰒ"]="ثم";e["ﰓ"]="ثى";e["ﰔ"]="ثي";e["ﰕ"]="جح";e["ﰖ"]="جم";e["ﰗ"]="حج";e["ﰘ"]="حم";e["ﰙ"]="خج";e["ﰚ"]="خح";e["ﰛ"]="خم";e["ﰜ"]="سج";e["ﰝ"]="سح";e["ﰞ"]="سخ";e["ﰟ"]="سم";e["ﰠ"]="صح";e["ﰡ"]="صم";e["ﰢ"]="ضج";e["ﰣ"]="ضح";e["ﰤ"]="ضخ";e["ﰥ"]="ضم";e["ﰦ"]="طح";e["ﰧ"]="طم";e["ﰨ"]="ظم";e["ﰩ"]="عج";e["ﰪ"]="عم";e["ﰫ"]="غج";e["ﰬ"]="غم";e["ﰭ"]="فج";e["ﰮ"]="فح";e["ﰯ"]="فخ";e["ﰰ"]="فم";e["ﰱ"]="فى";e["ﰲ"]="في";e["ﰳ"]="قح";e["ﰴ"]="قم";e["ﰵ"]="قى";e["ﰶ"]="قي";e["ﰷ"]="كا";e["ﰸ"]="كج";e["ﰹ"]="كح";e["ﰺ"]="كخ";e["ﰻ"]="كل";e["ﰼ"]="كم";e["ﰽ"]="كى";e["ﰾ"]="كي";e["ﰿ"]="لج";e["ﱀ"]="لح";e["ﱁ"]="لخ";e["ﱂ"]="لم";e["ﱃ"]="لى";e["ﱄ"]="لي";e["ﱅ"]="مج";e["ﱆ"]="مح";e["ﱇ"]="مخ";e["ﱈ"]="مم";e["ﱉ"]="مى";e["ﱊ"]="مي";e["ﱋ"]="نج";e["ﱌ"]="نح";e["ﱍ"]="نخ";e["ﱎ"]="نم";e["ﱏ"]="نى";e["ﱐ"]="ني";e["ﱑ"]="هج";e["ﱒ"]="هم";e["ﱓ"]="هى";e["ﱔ"]="هي";e["ﱕ"]="يج";e["ﱖ"]="يح";e["ﱗ"]="يخ";e["ﱘ"]="يم";e["ﱙ"]="يى";e["ﱚ"]="يي";e["ﱛ"]="ذٰ";e["ﱜ"]="رٰ";e["ﱝ"]="ىٰ";e["ﱞ"]=" ٌّ";e["ﱟ"]=" ٍّ";e["ﱠ"]=" َّ";e["ﱡ"]=" ُّ";e["ﱢ"]=" ِّ";e["ﱣ"]=" ّٰ";e["ﱤ"]="ئر";e["ﱥ"]="ئز";e["ﱦ"]="ئم";e["ﱧ"]="ئن";e["ﱨ"]="ئى";e["ﱩ"]="ئي";e["ﱪ"]="بر";e["ﱫ"]="بز";e["ﱬ"]="بم";e["ﱭ"]="بن";e["ﱮ"]="بى";e["ﱯ"]="بي";e["ﱰ"]="تر";e["ﱱ"]="تز";e["ﱲ"]="تم";e["ﱳ"]="تن";e["ﱴ"]="تى";e["ﱵ"]="تي";e["ﱶ"]="ثر";e["ﱷ"]="ثز";e["ﱸ"]="ثم";e["ﱹ"]="ثن";e["ﱺ"]="ثى";e["ﱻ"]="ثي";e["ﱼ"]="فى";e["ﱽ"]="في";e["ﱾ"]="قى";e["ﱿ"]="قي";e["ﲀ"]="كا";e["ﲁ"]="كل";e["ﲂ"]="كم";e["ﲃ"]="كى";e["ﲄ"]="كي";e["ﲅ"]="لم";e["ﲆ"]="لى";e["ﲇ"]="لي";e["ﲈ"]="ما";e["ﲉ"]="مم";e["ﲊ"]="نر";e["ﲋ"]="نز";e["ﲌ"]="نم";e["ﲍ"]="نن";e["ﲎ"]="نى";e["ﲏ"]="ني";e["ﲐ"]="ىٰ";e["ﲑ"]="ير";e["ﲒ"]="يز";e["ﲓ"]="يم";e["ﲔ"]="ين";e["ﲕ"]="يى";e["ﲖ"]="يي";e["ﲗ"]="ئج";e["ﲘ"]="ئح";e["ﲙ"]="ئخ";e["ﲚ"]="ئم";e["ﲛ"]="ئه";e["ﲜ"]="بج";e["ﲝ"]="بح";e["ﲞ"]="بخ";e["ﲟ"]="بم";e["ﲠ"]="به";e["ﲡ"]="تج";e["ﲢ"]="تح";e["ﲣ"]="تخ";e["ﲤ"]="تم";e["ﲥ"]="ته";e["ﲦ"]="ثم";e["ﲧ"]="جح";e["ﲨ"]="جم";e["ﲩ"]="حج";e["ﲪ"]="حم";e["ﲫ"]="خج";e["ﲬ"]="خم";e["ﲭ"]="سج";e["ﲮ"]="سح";e["ﲯ"]="سخ";e["ﲰ"]="سم";e["ﲱ"]="صح";e["ﲲ"]="صخ";e["ﲳ"]="صم";e["ﲴ"]="ضج";e["ﲵ"]="ضح";e["ﲶ"]="ضخ";e["ﲷ"]="ضم";e["ﲸ"]="طح";e["ﲹ"]="ظم";e["ﲺ"]="عج";e["ﲻ"]="عم";e["ﲼ"]="غج";e["ﲽ"]="غم";e["ﲾ"]="فج";e["ﲿ"]="فح";e["ﳀ"]="فخ";e["ﳁ"]="فم";e["ﳂ"]="قح";e["ﳃ"]="قم";e["ﳄ"]="كج";e["ﳅ"]="كح";e["ﳆ"]="كخ";e["ﳇ"]="كل";e["ﳈ"]="كم";e["ﳉ"]="لج";e["ﳊ"]="لح";e["ﳋ"]="لخ";e["ﳌ"]="لم";e["ﳍ"]="له";e["ﳎ"]="مج";e["ﳏ"]="مح";e["ﳐ"]="مخ";e["ﳑ"]="مم";e["ﳒ"]="نج";e["ﳓ"]="نح";e["ﳔ"]="نخ";e["ﳕ"]="نم";e["ﳖ"]="نه";e["ﳗ"]="هج";e["ﳘ"]="هم";e["ﳙ"]="هٰ";e["ﳚ"]="يج";e["ﳛ"]="يح";e["ﳜ"]="يخ";e["ﳝ"]="يم";e["ﳞ"]="يه";e["ﳟ"]="ئم";e["ﳠ"]="ئه";e["ﳡ"]="بم";e["ﳢ"]="به";e["ﳣ"]="تم";e["ﳤ"]="ته";e["ﳥ"]="ثم";e["ﳦ"]="ثه";e["ﳧ"]="سم";e["ﳨ"]="سه";e["ﳩ"]="شم";e["ﳪ"]="شه";e["ﳫ"]="كل";e["ﳬ"]="كم";e["ﳭ"]="لم";e["ﳮ"]="نم";e["ﳯ"]="نه";e["ﳰ"]="يم";e["ﳱ"]="يه";e["ﳲ"]="ـَّ";e["ﳳ"]="ـُّ";e["ﳴ"]="ـِّ";e["ﳵ"]="طى";e["ﳶ"]="طي";e["ﳷ"]="عى";e["ﳸ"]="عي";e["ﳹ"]="غى";e["ﳺ"]="غي";e["ﳻ"]="سى";e["ﳼ"]="سي";e["ﳽ"]="شى";e["ﳾ"]="شي";e["ﳿ"]="حى";e["ﴀ"]="حي";e["ﴁ"]="جى";e["ﴂ"]="جي";e["ﴃ"]="خى";e["ﴄ"]="خي";e["ﴅ"]="صى";e["ﴆ"]="صي";e["ﴇ"]="ضى";e["ﴈ"]="ضي";e["ﴉ"]="شج";e["ﴊ"]="شح";e["ﴋ"]="شخ";e["ﴌ"]="شم";e["ﴍ"]="شر";e["ﴎ"]="سر";e["ﴏ"]="صر";e["ﴐ"]="ضر";e["ﴑ"]="طى";e["ﴒ"]="طي";e["ﴓ"]="عى";e["ﴔ"]="عي";e["ﴕ"]="غى";e["ﴖ"]="غي";e["ﴗ"]="سى";e["ﴘ"]="سي";e["ﴙ"]="شى";e["ﴚ"]="شي";e["ﴛ"]="حى";e["ﴜ"]="حي";e["ﴝ"]="جى";e["ﴞ"]="جي";e["ﴟ"]="خى";e["ﴠ"]="خي";e["ﴡ"]="صى";e["ﴢ"]="صي";e["ﴣ"]="ضى";e["ﴤ"]="ضي";e["ﴥ"]="شج";e["ﴦ"]="شح";e["ﴧ"]="شخ";e["ﴨ"]="شم";e["ﴩ"]="شر";e["ﴪ"]="سر";e["ﴫ"]="صر";e["ﴬ"]="ضر";e["ﴭ"]="شج";e["ﴮ"]="شح";e["ﴯ"]="شخ";e["ﴰ"]="شم";e["ﴱ"]="سه";e["ﴲ"]="شه";e["ﴳ"]="طم";e["ﴴ"]="سج";e["ﴵ"]="سح";e["ﴶ"]="سخ";e["ﴷ"]="شج";e["ﴸ"]="شح";e["ﴹ"]="شخ";e["ﴺ"]="طم";e["ﴻ"]="ظم";e["ﴼ"]="اً";e["ﴽ"]="اً";e["ﵐ"]="تجم";e["ﵑ"]="تحج";e["ﵒ"]="تحج";e["ﵓ"]="تحم";e["ﵔ"]="تخم";e["ﵕ"]="تمج";e["ﵖ"]="تمح";e["ﵗ"]="تمخ";e["ﵘ"]="جمح";e["ﵙ"]="جمح";e["ﵚ"]="حمي";e["ﵛ"]="حمى";e["ﵜ"]="سحج";e["ﵝ"]="سجح";e["ﵞ"]="سجى";e["ﵟ"]="سمح";e["ﵠ"]="سمح";e["ﵡ"]="سمج";e["ﵢ"]="سمم";e["ﵣ"]="سمم";e["ﵤ"]="صحح";e["ﵥ"]="صحح";e["ﵦ"]="صمم";e["ﵧ"]="شحم";e["ﵨ"]="شحم";e["ﵩ"]="شجي";e["ﵪ"]="شمخ";e["ﵫ"]="شمخ";e["ﵬ"]="شمم";e["ﵭ"]="شمم";e["ﵮ"]="ضحى";e["ﵯ"]="ضخم";e["ﵰ"]="ضخم";e["ﵱ"]="طمح";e["ﵲ"]="طمح";e["ﵳ"]="طمم";e["ﵴ"]="طمي";e["ﵵ"]="عجم";e["ﵶ"]="عمم";e["ﵷ"]="عمم";e["ﵸ"]="عمى";e["ﵹ"]="غمم";e["ﵺ"]="غمي";e["ﵻ"]="غمى";e["ﵼ"]="فخم";e["ﵽ"]="فخم";e["ﵾ"]="قمح";e["ﵿ"]="قمم";e["ﶀ"]="لحم";e["ﶁ"]="لحي";e["ﶂ"]="لحى";e["ﶃ"]="لجج";e["ﶄ"]="لجج";e["ﶅ"]="لخم";e["ﶆ"]="لخم";e["ﶇ"]="لمح";e["ﶈ"]="لمح";e["ﶉ"]="محج";e["ﶊ"]="محم";e["ﶋ"]="محي";e["ﶌ"]="مجح";e["ﶍ"]="مجم";e["ﶎ"]="مخج";e["ﶏ"]="مخم";e["ﶒ"]="مجخ";e["ﶓ"]="همج";e["ﶔ"]="همم";e["ﶕ"]="نحم";e["ﶖ"]="نحى";e["ﶗ"]="نجم";e["ﶘ"]="نجم";e["ﶙ"]="نجى";e["ﶚ"]="نمي";e["ﶛ"]="نمى";e["ﶜ"]="يمم";e["ﶝ"]="يمم";e["ﶞ"]="بخي";e["ﶟ"]="تجي";e["ﶠ"]="تجى";e["ﶡ"]="تخي";e["ﶢ"]="تخى";e["ﶣ"]="تمي";e["ﶤ"]="تمى";e["ﶥ"]="جمي";e["ﶦ"]="جحى";e["ﶧ"]="جمى";e["ﶨ"]="سخى";e["ﶩ"]="صحي";e["ﶪ"]="شحي";e["ﶫ"]="ضحي";e["ﶬ"]="لجي";e["ﶭ"]="لمي";e["ﶮ"]="يحي";e["ﶯ"]="يجي";e["ﶰ"]="يمي";e["ﶱ"]="ممي";e["ﶲ"]="قمي";e["ﶳ"]="نحي";e["ﶴ"]="قمح";e["ﶵ"]="لحم";e["ﶶ"]="عمي";e["ﶷ"]="كمي";e["ﶸ"]="نجح";e["ﶹ"]="مخي";e["ﶺ"]="لجم";e["ﶻ"]="كمم";e["ﶼ"]="لجم";e["ﶽ"]="نجح";e["ﶾ"]="جحي";e["ﶿ"]="حجي";e["ﷀ"]="مجي";e["ﷁ"]="فمي";e["ﷂ"]="بحي";e["ﷃ"]="كمم";e["ﷄ"]="عجم";e["ﷅ"]="صمم";e["ﷆ"]="سخي";e["ﷇ"]="نجي";e["﹉"]="‾";e["﹊"]="‾";e["﹋"]="‾";e["﹌"]="‾";e["﹍"]="_";e["﹎"]="_";e["﹏"]="_";e["ﺀ"]="ء";e["ﺁ"]="آ";e["ﺂ"]="آ";e["ﺃ"]="أ";e["ﺄ"]="أ";e["ﺅ"]="ؤ";e["ﺆ"]="ؤ";e["ﺇ"]="إ";e["ﺈ"]="إ";e["ﺉ"]="ئ";e["ﺊ"]="ئ";e["ﺋ"]="ئ";e["ﺌ"]="ئ";e["ﺍ"]="ا";e["ﺎ"]="ا";e["ﺏ"]="ب";e["ﺐ"]="ب";e["ﺑ"]="ب";e["ﺒ"]="ب";e["ﺓ"]="ة";e["ﺔ"]="ة";e["ﺕ"]="ت";e["ﺖ"]="ت";e["ﺗ"]="ت";e["ﺘ"]="ت";e["ﺙ"]="ث";e["ﺚ"]="ث";e["ﺛ"]="ث";e["ﺜ"]="ث";e["ﺝ"]="ج";e["ﺞ"]="ج";e["ﺟ"]="ج";e["ﺠ"]="ج";e["ﺡ"]="ح";e["ﺢ"]="ح";e["ﺣ"]="ح";e["ﺤ"]="ح";e["ﺥ"]="خ";e["ﺦ"]="خ";e["ﺧ"]="خ";e["ﺨ"]="خ";e["ﺩ"]="د";e["ﺪ"]="د";e["ﺫ"]="ذ";e["ﺬ"]="ذ";e["ﺭ"]="ر";e["ﺮ"]="ر";e["ﺯ"]="ز";e["ﺰ"]="ز";e["ﺱ"]="س";e["ﺲ"]="س";e["ﺳ"]="س";e["ﺴ"]="س";e["ﺵ"]="ش";e["ﺶ"]="ش";e["ﺷ"]="ش";e["ﺸ"]="ش";e["ﺹ"]="ص";e["ﺺ"]="ص";e["ﺻ"]="ص";e["ﺼ"]="ص";e["ﺽ"]="ض";e["ﺾ"]="ض";e["ﺿ"]="ض";e["ﻀ"]="ض";e["ﻁ"]="ط";e["ﻂ"]="ط";e["ﻃ"]="ط";e["ﻄ"]="ط";e["ﻅ"]="ظ";e["ﻆ"]="ظ";e["ﻇ"]="ظ";e["ﻈ"]="ظ";e["ﻉ"]="ع";e["ﻊ"]="ع";e["ﻋ"]="ع";e["ﻌ"]="ع";e["ﻍ"]="غ";e["ﻎ"]="غ";e["ﻏ"]="غ";e["ﻐ"]="غ";e["ﻑ"]="ف";e["ﻒ"]="ف";e["ﻓ"]="ف";e["ﻔ"]="ف";e["ﻕ"]="ق";e["ﻖ"]="ق";e["ﻗ"]="ق";e["ﻘ"]="ق";e["ﻙ"]="ك";e["ﻚ"]="ك";e["ﻛ"]="ك";e["ﻜ"]="ك";e["ﻝ"]="ل";e["ﻞ"]="ل";e["ﻟ"]="ل";e["ﻠ"]="ل";e["ﻡ"]="م";e["ﻢ"]="م";e["ﻣ"]="م";e["ﻤ"]="م";e["ﻥ"]="ن";e["ﻦ"]="ن";e["ﻧ"]="ن";e["ﻨ"]="ن";e["ﻩ"]="ه";e["ﻪ"]="ه";e["ﻫ"]="ه";e["ﻬ"]="ه";e["ﻭ"]="و";e["ﻮ"]="و";e["ﻯ"]="ى";e["ﻰ"]="ى";e["ﻱ"]="ي";e["ﻲ"]="ي";e["ﻳ"]="ي";e["ﻴ"]="ي";e["ﻵ"]="لآ";e["ﻶ"]="لآ";e["ﻷ"]="لأ";e["ﻸ"]="لأ";e["ﻹ"]="لإ";e["ﻺ"]="لإ";e["ﻻ"]="لا";e["ﻼ"]="لا"}));t.mapSpecialUnicodeValues=function(e){return e>=65520&&e<=65535?0:e>=62976&&e<=63743?i()[e]||e:173===e?45:e};t.reverseIfRtl=function(e){var t,a,r=e.length;if(r<=1||!(t=e.charCodeAt(0),a=n[13],t>=a.begin&&t<a.end||t>=(a=n[11]).begin&&t<a.end))return e;for(var i="",s=r-1;s>=0;s--)i+=e[s];return i};t.getUnicodeRangeFor=function(e){for(var t=0,a=n.length;t<a;t++){var r=n[t];if(e>=r.begin&&e<r.end)return t}return-1};t.getNormalizedUnicodes=s;t.getUnicodeForGlyph=function(e,t){var a=t[e];if(void 0!==a)return a;if(!e)return-1;if("u"===e[0]){var r,i=e.length;if(7===i&&"n"===e[1]&&"i"===e[2])r=e.substring(3);else{if(!(i>=5&&i<=7))return-1;r=e.substring(1)}if(r===r.toUpperCase()&&(a=parseInt(r,16))>=0)return a}return-1}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.FontRendererFactory=void 0;var r=a(2),i=a(28),n=a(31),s=a(30),o=a(11),c=function(){function e(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]}function t(e,t){return e[t]<<8|e[t+1]}function a(e){const t=e.length;let a=32768;t<1240?a=107:t<33900&&(a=1131);return a}function c(a,i,n){var s,o,c,l=1===t(a,i+2)?e(a,i+8):e(a,i+16),h=t(a,i+l);if(4===h){t(a,i+l+2);var u=t(a,i+l+6)>>1;o=i+l+14;s=[];for(c=0;c<u;c++,o+=2)s[c]={end:t(a,o)};o+=2;for(c=0;c<u;c++,o+=2)s[c].start=t(a,o);for(c=0;c<u;c++,o+=2)s[c].idDelta=t(a,o);for(c=0;c<u;c++,o+=2){var d=t(a,o);if(0!==d){s[c].ids=[];for(var f=0,g=s[c].end-s[c].start+1;f<g;f++){s[c].ids[f]=t(a,o+d);d+=2}}}return s}if(12===h){e(a,i+l+4);var m=e(a,i+l+12);o=i+l+16;s=[];for(c=0;c<m;c++){s.push({start:e(a,o),end:e(a,o+4),idDelta:e(a,o+8)-e(a,o)});o+=12}return s}throw new r.FormatError(`unsupported cmap: ${h}`)}function l(e,t,a,r){var n=new i.CFFParser(new o.Stream(e,t,a-t),{},r).parse();return{glyphs:n.charStrings.objects,subrs:n.topDict.privateDict&&n.topDict.privateDict.subrsIndex&&n.topDict.privateDict.subrsIndex.objects,gsubrs:n.globalSubrIndex&&n.globalSubrIndex.objects,isCFFCIDFont:n.isCIDFont,fdSelect:n.fdSelect,fdArray:n.fdArray}}function h(e,t){for(var a=t.codePointAt(0),r=0,i=0,n=e.length-1;i<n;){var s=i+n+1>>1;a<e[s].start?n=s-1:i=s}e[i].start<=a&&a<=e[i].end&&(r=e[i].idDelta+(e[i].ids?e[i].ids[a-e[i].start]:a)&65535);return{charCode:a,glyphId:r}}const u=[];class d{constructor(e){this.constructor===d&&(0,r.unreachable)("Cannot initialize CompiledFont.");this.fontMatrix=e;this.compiledGlyphs=Object.create(null);this.compiledCharCodeToGlyphId=Object.create(null)}getPathJs(e){const t=h(this.cmap,e);let a=this.compiledGlyphs[t.glyphId];if(!a){a=this.compileGlyph(this.glyphs[t.glyphId],t.glyphId);this.compiledGlyphs[t.glyphId]=a}void 0===this.compiledCharCodeToGlyphId[t.charCode]&&(this.compiledCharCodeToGlyphId[t.charCode]=t.glyphId);return a}compileGlyph(e,t){if(!e||0===e.length||14===e[0])return u;let a=this.fontMatrix;if(this.isCFFCIDFont){const e=this.fdSelect.getFDIndex(t);if(e>=0&&e<this.fdArray.length){a=this.fdArray[e].getByName("FontMatrix")||r.FONT_IDENTITY_MATRIX}else(0,r.warn)("Invalid fd index for glyph index.")}const i=[];i.push({cmd:"save"});i.push({cmd:"transform",args:a.slice()});i.push({cmd:"scale",args:["size","-size"]});this.compileGlyphImpl(e,i,t);i.push({cmd:"restore"});return i}compileGlyphImpl(){(0,r.unreachable)("Children classes should implement this.")}hasBuiltPath(e){const t=h(this.cmap,e);return void 0!==this.compiledGlyphs[t.glyphId]&&void 0!==this.compiledCharCodeToGlyphId[t.charCode]}}class f extends d{constructor(e,t,a){super(a||[488e-6,0,0,488e-6,0,0]);this.glyphs=e;this.cmap=t}compileGlyphImpl(e,t){!function e(t,a,r){function i(e,t){a.push({cmd:"moveTo",args:[e,t]})}function n(e,t){a.push({cmd:"lineTo",args:[e,t]})}function s(e,t,r,i){a.push({cmd:"quadraticCurveTo",args:[e,t,r,i]})}var o,c=0,l=(t[c]<<24|t[c+1]<<16)>>16,h=0,u=0;c+=10;if(l<0)do{o=t[c]<<8|t[c+1];var d,f,g=t[c+2]<<8|t[c+3];c+=4;if(1&o){d=(t[c]<<24|t[c+1]<<16)>>16;f=(t[c+2]<<24|t[c+3]<<16)>>16;c+=4}else{d=t[c++];f=t[c++]}if(2&o){h=d;u=f}else{h=0;u=0}var m=1,p=1,b=0,y=0;if(8&o){m=p=(t[c]<<24|t[c+1]<<16)/1073741824;c+=2}else if(64&o){m=(t[c]<<24|t[c+1]<<16)/1073741824;p=(t[c+2]<<24|t[c+3]<<16)/1073741824;c+=4}else if(128&o){m=(t[c]<<24|t[c+1]<<16)/1073741824;b=(t[c+2]<<24|t[c+3]<<16)/1073741824;y=(t[c+4]<<24|t[c+5]<<16)/1073741824;p=(t[c+6]<<24|t[c+7]<<16)/1073741824;c+=8}var v=r.glyphs[g];if(v){a.push({cmd:"save"});a.push({cmd:"transform",args:[m,b,y,p,h,u]});e(v,a,r);a.push({cmd:"restore"})}}while(32&o);else{var w,k,S=[];for(w=0;w<l;w++){S.push(t[c]<<8|t[c+1]);c+=2}c+=2+(t[c]<<8|t[c+1]);for(var C=S[S.length-1]+1,x=[];x.length<C;){var A=1;8&(o=t[c++])&&(A+=t[c++]);for(;A-- >0;)x.push({flags:o})}for(w=0;w<C;w++){switch(18&x[w].flags){case 0:h+=(t[c]<<24|t[c+1]<<16)>>16;c+=2;break;case 2:h-=t[c++];break;case 18:h+=t[c++]}x[w].x=h}for(w=0;w<C;w++){switch(36&x[w].flags){case 0:u+=(t[c]<<24|t[c+1]<<16)>>16;c+=2;break;case 4:u-=t[c++];break;case 36:u+=t[c++]}x[w].y=u}var I=0;for(c=0;c<l;c++){var F=S[c],T=x.slice(I,F+1);if(1&T[0].flags)T.push(T[0]);else if(1&T[T.length-1].flags)T.unshift(T[T.length-1]);else{var E={flags:1,x:(T[0].x+T[T.length-1].x)/2,y:(T[0].y+T[T.length-1].y)/2};T.unshift(E);T.push(E)}i(T[0].x,T[0].y);for(w=1,k=T.length;w<k;w++)if(1&T[w].flags)n(T[w].x,T[w].y);else if(1&T[w+1].flags){s(T[w].x,T[w].y,T[w+1].x,T[w+1].y);w++}else s(T[w].x,T[w].y,(T[w].x+T[w+1].x)/2,(T[w].y+T[w+1].y)/2);I=F+1}}}(e,t,this)}}class g extends d{constructor(e,t,r,i){super(r||[.001,0,0,.001,0,0]);this.glyphs=e.glyphs;this.gsubrs=e.gsubrs||[];this.subrs=e.subrs||[];this.cmap=t;this.glyphNameMap=i||(0,n.getGlyphsUnicode)();this.gsubrsBias=a(this.gsubrs);this.subrsBias=a(this.subrs);this.isCFFCIDFont=e.isCFFCIDFont;this.fdSelect=e.fdSelect;this.fdArray=e.fdArray}compileGlyphImpl(e,t,i){!function e(t,i,n,o){var c=[],l=0,u=0,d=0;function f(e,t){i.push({cmd:"moveTo",args:[e,t]})}function g(e,t){i.push({cmd:"lineTo",args:[e,t]})}function m(e,t,a,r,n,s){i.push({cmd:"bezierCurveTo",args:[e,t,a,r,n,s]})}!function t(p){for(var b=0;b<p.length;){var y,v,w,k,S,C,x,A,I=!1,F=p[b++];switch(F){case 1:case 3:d+=c.length>>1;I=!0;break;case 4:u+=c.pop();f(l,u);I=!0;break;case 5:for(;c.length>0;){l+=c.shift();u+=c.shift();g(l,u)}break;case 6:for(;c.length>0;){g(l+=c.shift(),u);if(0===c.length)break;u+=c.shift();g(l,u)}break;case 7:for(;c.length>0;){u+=c.shift();g(l,u);if(0===c.length)break;g(l+=c.shift(),u)}break;case 8:for(;c.length>0;){y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u)}break;case 10:x=c.pop();A=null;if(n.isCFFCIDFont){const e=n.fdSelect.getFDIndex(o);if(e>=0&&e<n.fdArray.length){const t=n.fdArray[e];let r;t.privateDict&&t.privateDict.subrsIndex&&(r=t.privateDict.subrsIndex.objects);r&&(A=r[x+=a(r)])}else(0,r.warn)("Invalid fd index for glyph index.")}else A=n.subrs[x+n.subrsBias];A&&t(A);break;case 11:return;case 12:switch(F=p[b++]){case 34:v=(y=l+c.shift())+c.shift();S=u+c.shift();l=v+c.shift();m(y,u,v,S,l,S);v=(y=l+c.shift())+c.shift();l=v+c.shift();m(y,S,v,u,l,u);break;case 35:y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u);y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u);c.pop();break;case 36:m(y=l+c.shift(),S=u+c.shift(),v=y+c.shift(),C=S+c.shift(),l=v+c.shift(),C);m(y=l+c.shift(),C,v=y+c.shift(),C+c.shift(),l=v+c.shift(),u);break;case 37:var T=l,E=u;y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u);y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v;u=k;Math.abs(l-T)>Math.abs(u-E)?l+=c.shift():u+=c.shift();m(y,w,v,k,l,u);break;default:throw new r.FormatError(`unknown operator: 12 ${F}`)}break;case 14:if(c.length>=4){var O=c.pop(),P=c.pop();u=c.pop();l=c.pop();i.push({cmd:"save"});i.push({cmd:"translate",args:[l,u]});var B=h(n.cmap,String.fromCharCode(n.glyphNameMap[s.StandardEncoding[O]]));e(n.glyphs[B.glyphId],i,n,B.glyphId);i.push({cmd:"restore"});B=h(n.cmap,String.fromCharCode(n.glyphNameMap[s.StandardEncoding[P]]));e(n.glyphs[B.glyphId],i,n,B.glyphId)}return;case 18:d+=c.length>>1;I=!0;break;case 19:case 20:b+=(d+=c.length>>1)+7>>3;I=!0;break;case 21:u+=c.pop();f(l+=c.pop(),u);I=!0;break;case 22:f(l+=c.pop(),u);I=!0;break;case 23:d+=c.length>>1;I=!0;break;case 24:for(;c.length>2;){y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u)}l+=c.shift();u+=c.shift();g(l,u);break;case 25:for(;c.length>6;){l+=c.shift();u+=c.shift();g(l,u)}y=l+c.shift();w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+c.shift();m(y,w,v,k,l,u);break;case 26:c.length%2&&(l+=c.shift());for(;c.length>0;){y=l;w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v;u=k+c.shift();m(y,w,v,k,l,u)}break;case 27:c.length%2&&(u+=c.shift());for(;c.length>0;)m(y=l+c.shift(),w=u,v=y+c.shift(),k=w+c.shift(),l=v+c.shift(),u=k);break;case 28:c.push((p[b]<<24|p[b+1]<<16)>>16);b+=2;break;case 29:x=c.pop()+n.gsubrsBias;(A=n.gsubrs[x])&&t(A);break;case 30:for(;c.length>0;){y=l;w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+(1===c.length?c.shift():0);m(y,w,v,k,l,u);if(0===c.length)break;y=l+c.shift();w=u;v=y+c.shift();k=w+c.shift();u=k+c.shift();m(y,w,v,k,l=v+(1===c.length?c.shift():0),u)}break;case 31:for(;c.length>0;){y=l+c.shift();w=u;v=y+c.shift();k=w+c.shift();u=k+c.shift();m(y,w,v,k,l=v+(1===c.length?c.shift():0),u);if(0===c.length)break;y=l;w=u+c.shift();v=y+c.shift();k=w+c.shift();l=v+c.shift();u=k+(1===c.length?c.shift():0);m(y,w,v,k,l,u)}break;default:if(F<32)throw new r.FormatError(`unknown operator: ${F}`);if(F<247)c.push(F-139);else if(F<251)c.push(256*(F-247)+p[b++]+108);else if(F<255)c.push(256*-(F-251)-p[b++]-108);else{c.push((p[b]<<24|p[b+1]<<16|p[b+2]<<8|p[b+3])/65536);b+=4}}I&&(c.length=0)}}(t)}(e,t,this,i)}}return{create:function(a,i){for(var n,s,o,h,u,d,m=new Uint8Array(a.data),p=t(m,4),b=0,y=12;b<p;b++,y+=16){var v=(0,r.bytesToString)(m.subarray(y,y+4)),w=e(m,y+8),k=e(m,y+12);switch(v){case"cmap":n=c(m,w);break;case"glyf":s=m.subarray(w,w+k);break;case"loca":o=m.subarray(w,w+k);break;case"head":d=t(m,w+18);u=t(m,w+50);break;case"CFF ":h=l(m,w,w+k,i)}}if(s){var S=d?[1/d,0,0,1/d,0,0]:a.fontMatrix;return new f(function(e,t,a){var r,i;if(a){r=4;i=function(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]}}else{r=2;i=function(e,t){return e[t]<<9|e[t+1]<<1}}for(var n=[],s=i(t,0),o=r;o<t.length;o+=r){var c=i(t,o);n.push(e.subarray(s,c));s=c}return n}(s,o,u),n,S)}return new g(h,n,a.fontMatrix,a.glyphNameMap)}}}();t.FontRendererFactory=c},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Type1Parser=void 0;var r=a(30),i=a(7),n=a(11),s=a(2),o=function(){var e=[4],t=[5],a=[6],r=[7],i=[8],n=[12,35],o=[14],c=[21],l=[22],h=[30],u=[31];function d(){this.width=0;this.lsb=0;this.flexing=!1;this.output=[];this.stack=[]}d.prototype={convert:function(d,f,g){for(var m,p,b,y=d.length,v=!1,w=0;w<y;w++){var k=d[w];if(k<32){12===k&&(k=(k<<8)+d[++w]);switch(k){case 1:case 3:this.stack=[];break;case 4:if(this.flexing){if(this.stack.length<1){v=!0;break}var S=this.stack.pop();this.stack.push(0,S);break}v=this.executeCommand(1,e);break;case 5:v=this.executeCommand(2,t);break;case 6:v=this.executeCommand(1,a);break;case 7:v=this.executeCommand(1,r);break;case 8:v=this.executeCommand(6,i);break;case 9:this.stack=[];break;case 10:if(this.stack.length<1){v=!0;break}if(!f[b=this.stack.pop()]){v=!0;break}v=this.convert(f[b],f,g);break;case 11:return v;case 13:if(this.stack.length<2){v=!0;break}m=this.stack.pop();p=this.stack.pop();this.lsb=p;this.width=m;this.stack.push(m,p);v=this.executeCommand(2,l);break;case 14:this.output.push(o[0]);break;case 21:if(this.flexing)break;v=this.executeCommand(2,c);break;case 22:if(this.flexing){this.stack.push(0);break}v=this.executeCommand(1,l);break;case 30:v=this.executeCommand(4,h);break;case 31:v=this.executeCommand(4,u);break;case 3072:case 3073:case 3074:this.stack=[];break;case 3078:if(g){this.seac=this.stack.splice(-4,4);v=this.executeCommand(0,o)}else v=this.executeCommand(4,o);break;case 3079:if(this.stack.length<4){v=!0;break}this.stack.pop();m=this.stack.pop();var C=this.stack.pop();p=this.stack.pop();this.lsb=p;this.width=m;this.stack.push(m,p,C);v=this.executeCommand(3,c);break;case 3084:if(this.stack.length<2){v=!0;break}var x=this.stack.pop(),A=this.stack.pop();this.stack.push(A/x);break;case 3088:if(this.stack.length<2){v=!0;break}b=this.stack.pop();var I=this.stack.pop();if(0===b&&3===I){var F=this.stack.splice(this.stack.length-17,17);this.stack.push(F[2]+F[0],F[3]+F[1],F[4],F[5],F[6],F[7],F[8],F[9],F[10],F[11],F[12],F[13],F[14]);v=this.executeCommand(13,n,!0);this.flexing=!1;this.stack.push(F[15],F[16])}else 1===b&&0===I&&(this.flexing=!0);break;case 3089:break;case 3105:this.stack=[];break;default:(0,s.warn)('Unknown type 1 charstring command of "'+k+'"')}if(v)break}else{k<=246?k-=139:k=k<=250?256*(k-247)+d[++w]+108:k<=254?-256*(k-251)-d[++w]-108:(255&d[++w])<<24|(255&d[++w])<<16|(255&d[++w])<<8|(255&d[++w])<<0;this.stack.push(k)}}return v},executeCommand(e,t,a){var r=this.stack.length;if(e>r)return!0;for(var i=r-e,n=i;n<r;n++){var s=this.stack[n];if(Number.isInteger(s))this.output.push(28,s>>8&255,255&s);else{s=65536*s|0;this.output.push(255,s>>24&255,s>>16&255,s>>8&255,255&s)}}this.output.push.apply(this.output,t);a?this.stack.splice(i,e):this.stack.length=0;return!1}};return d}(),c=function(){function e(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function t(e,t,a){if(a>=e.length)return new Uint8Array(0);var r,i,n=0|t;for(r=0;r<a;r++)n=52845*(e[r]+n)+22719&65535;var s=e.length-a,o=new Uint8Array(s);for(r=a,i=0;i<s;r++,i++){var c=e[r];o[i]=c^n>>8;n=52845*(c+n)+22719&65535}return o}function a(e){return 47===e||91===e||93===e||123===e||125===e||40===e||41===e}function s(a,r,i){if(r){var s=a.getBytes(),o=!(e(s[0])&&e(s[1])&&e(s[2])&&e(s[3]));a=new n.Stream(o?t(s,55665,4):function(t,a,r){var i,n,s=0|a,o=t.length,c=new Uint8Array(o>>>1);for(i=0,n=0;i<o;i++){var l=t[i];if(e(l)){i++;for(var h;i<o&&!e(h=t[i]);)i++;if(i<o){var u=parseInt(String.fromCharCode(l,h),16);c[n++]=u^s>>8;s=52845*(u+s)+22719&65535}}}return Array.prototype.slice.call(c,r,n)}(s,55665,4))}this.seacAnalysisEnabled=!!i;this.stream=a;this.nextChar()}s.prototype={readNumberArray:function(){this.getToken();for(var e=[];;){var t=this.getToken();if(null===t||"]"===t||"}"===t)break;e.push(parseFloat(t||0))}return e},readNumber:function(){var e=this.getToken();return parseFloat(e||0)},readInt:function(){var e=this.getToken();return 0|parseInt(e||0,10)},readBoolean:function(){return"true"===this.getToken()?1:0},nextChar:function(){return this.currentChar=this.stream.getByte()},getToken:function(){for(var e=!1,t=this.currentChar;;){if(-1===t)return null;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(!(0,i.isWhiteSpace)(t))break;t=this.nextChar()}if(a(t)){this.nextChar();return String.fromCharCode(t)}var r="";do{r+=String.fromCharCode(t);t=this.nextChar()}while(t>=0&&!(0,i.isWhiteSpace)(t)&&!a(t));return r},readCharStrings:function(e,a){return-1===a?e:t(e,4330,a)},extractFontProgram:function(e){var t=this.stream,a=[],r=[],i=Object.create(null);i.lenIV=4;for(var n,s,c,l,h,u={subrs:[],charstrings:[],properties:{privateData:i}};null!==(n=this.getToken());)if("/"===n)switch(n=this.getToken()){case"CharStrings":this.getToken();this.getToken();this.getToken();this.getToken();for(;null!==(n=this.getToken())&&"end"!==n;)if("/"===n){var d=this.getToken();s=this.readInt();this.getToken();c=s>0?t.getBytes(s):new Uint8Array(0);l=u.properties.privateData.lenIV;h=this.readCharStrings(c,l);this.nextChar();"noaccess"===(n=this.getToken())&&this.getToken();r.push({glyph:d,encoded:h})}break;case"Subrs":this.readInt();this.getToken();for(;"dup"===this.getToken();){var f=this.readInt();s=this.readInt();this.getToken();c=s>0?t.getBytes(s):new Uint8Array(0);l=u.properties.privateData.lenIV;h=this.readCharStrings(c,l);this.nextChar();"noaccess"===(n=this.getToken())&&this.getToken();a[f]=h}break;case"BlueValues":case"OtherBlues":case"FamilyBlues":case"FamilyOtherBlues":var g=this.readNumberArray();g.length>0&&g.length,0;break;case"StemSnapH":case"StemSnapV":u.properties.privateData[n]=this.readNumberArray();break;case"StdHW":case"StdVW":u.properties.privateData[n]=this.readNumberArray()[0];break;case"BlueShift":case"lenIV":case"BlueFuzz":case"BlueScale":case"LanguageGroup":case"ExpansionFactor":u.properties.privateData[n]=this.readNumber();break;case"ForceBold":u.properties.privateData[n]=this.readBoolean()}for(var m=0;m<r.length;m++){d=r[m].glyph;h=r[m].encoded;var p=new o,b=p.convert(h,a,this.seacAnalysisEnabled),y=p.output;b&&(y=[14]);const t={glyphName:d,charstring:y,width:p.width,lsb:p.lsb,seac:p.seac};".notdef"===d?u.charstrings.unshift(t):u.charstrings.push(t);if(e.builtInEncoding){const t=e.builtInEncoding.indexOf(d);t>-1&&void 0===e.widths[t]&&t>=e.firstChar&&t<=e.lastChar&&(e.widths[t]=p.width)}}return u},extractFontHeader:function(e){for(var t;null!==(t=this.getToken());)if("/"===t)switch(t=this.getToken()){case"FontMatrix":var a=this.readNumberArray();e.fontMatrix=a;break;case"Encoding":var i,n=this.getToken();if(/^\d+$/.test(n)){i=[];var s=0|parseInt(n,10);this.getToken();for(var o=0;o<s;o++){t=this.getToken();for(;"dup"!==t&&"def"!==t;)if(null===(t=this.getToken()))return;if("def"===t)break;var c=this.readInt();this.getToken();var l=this.getToken();i[c]=l;this.getToken()}}else i=(0,r.getEncoding)(n);e.builtInEncoding=i;break;case"FontBBox":var h=this.readNumberArray();e.ascent=Math.max(h[3],h[1]);e.descent=Math.min(h[1],h[3]);e.ascentScaled=!0}}};return s}();t.Type1Parser=c},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getTilingPatternIR=function(e,t,a){const i=t.getArray("Matrix"),n=r.Util.normalizeRect(t.getArray("BBox")),s=t.get("XStep"),o=t.get("YStep"),c=t.get("PaintType"),l=t.get("TilingType");if(n[2]-n[0]==0||n[3]-n[1]==0)throw new r.FormatError(`Invalid getTilingPatternIR /BBox array: [${n}].`);return["TilingPattern",a,e,i,n,s,o,c,l]};t.Pattern=void 0;var r=a(2),i=a(22),n=a(4),s=a(7),o=2,c=3,l=4,h=5,u=6,d=7,f=function(){function e(){(0,r.unreachable)("should not call Pattern constructor")}e.prototype={getPattern:function(e){(0,r.unreachable)(`Should not call Pattern.getStyle: ${e}`)}};e.parseShading=function(e,t,a,i,f,m){var p=(0,n.isStream)(e)?e.dict:e,b=p.get("ShadingType");try{switch(b){case o:case c:return new g.RadialAxial(p,t,a,i,m);case l:case h:case u:case d:return new g.Mesh(e,t,a,i,m);default:throw new r.FormatError("Unsupported ShadingType: "+b)}}catch(e){if(e instanceof s.MissingDataException)throw e;f.send("UnsupportedFeature",{featureId:r.UNSUPPORTED_FEATURES.shadingPattern});(0,r.warn)(e);return new g.Dummy}};return e}();t.Pattern=f;var g={SMALL_NUMBER:1e-6};g.RadialAxial=function(){function e(e,t,a,n,s){this.matrix=t;this.coordsArr=e.getArray("Coords");this.shadingType=e.get("ShadingType");this.type="Pattern";var o=e.get("ColorSpace","CS");o=i.ColorSpace.parse(o,a,n,s);this.cs=o;const l=e.getArray("BBox");Array.isArray(l)&&4===l.length?this.bbox=r.Util.normalizeRect(l):this.bbox=null;var h=0,u=1;if(e.has("Domain")){var d=e.getArray("Domain");h=d[0];u=d[1]}var f=!1,m=!1;if(e.has("Extend")){var p=e.getArray("Extend");f=p[0];m=p[1]}if(!(this.shadingType!==c||f&&m)){var b=this.coordsArr[0],y=this.coordsArr[1],v=this.coordsArr[2],w=this.coordsArr[3],k=this.coordsArr[4],S=this.coordsArr[5],C=Math.sqrt((b-w)*(b-w)+(y-k)*(y-k));v<=S+C&&S<=v+C&&(0,r.warn)("Unsupported radial gradient.")}this.extendStart=f;this.extendEnd=m;var x=e.get("Function"),A=s.createFromArray(x);const I=(u-h)/10;var F=this.colorStops=[];if(h>=u||I<=0)(0,r.info)("Bad shading domain.");else{var T,E=new Float32Array(o.numComps),O=new Float32Array(1);for(let e=0;e<=10;e++){O[0]=h+e*I;A(O,0,E,0);T=o.getRgb(E,0);var P=r.Util.makeCssRgb(T[0],T[1],T[2]);F.push([e/10,P])}var B="transparent";if(e.has("Background")){T=o.getRgb(e.get("Background"),0);B=r.Util.makeCssRgb(T[0],T[1],T[2])}if(!f){F.unshift([0,B]);F[1][0]+=g.SMALL_NUMBER}if(!m){F[F.length-1][0]-=g.SMALL_NUMBER;F.push([1,B])}this.colorStops=F}}e.prototype={getIR:function(){var e,t,a,i,n,s=this.coordsArr,l=this.shadingType;if(l===o){t=[s[0],s[1]];a=[s[2],s[3]];i=null;n=null;e="axial"}else if(l===c){t=[s[0],s[1]];a=[s[3],s[4]];i=s[2];n=s[5];e="radial"}else(0,r.unreachable)(`getPattern type unknown: ${l}`);var h=this.matrix;if(h){t=r.Util.applyTransform(t,h);a=r.Util.applyTransform(a,h);if(l===c){var u=r.Util.singularValueDecompose2dScale(h);i*=u[0];n*=u[1]}}return["RadialAxial",e,this.bbox,this.colorStops,t,a,i,n]}};return e}();g.Mesh=function(){function e(e,t){this.stream=e;this.context=t;this.buffer=0;this.bufferLength=0;var a=t.numComps;this.tmpCompsBuf=new Float32Array(a);var r=t.colorSpace.numComps;this.tmpCsCompsBuf=t.colorFn?new Float32Array(r):this.tmpCompsBuf}e.prototype={get hasData(){if(this.stream.end)return this.stream.pos<this.stream.end;if(this.bufferLength>0)return!0;var e=this.stream.getByte();if(e<0)return!1;this.buffer=e;this.bufferLength=8;return!0},readBits:function(e){var t=this.buffer,a=this.bufferLength;if(32===e){if(0===a)return(this.stream.getByte()<<24|this.stream.getByte()<<16|this.stream.getByte()<<8|this.stream.getByte())>>>0;t=t<<24|this.stream.getByte()<<16|this.stream.getByte()<<8|this.stream.getByte();var r=this.stream.getByte();this.buffer=r&(1<<a)-1;return(t<<8-a|(255&r)>>a)>>>0}if(8===e&&0===a)return this.stream.getByte();for(;a<e;){t=t<<8|this.stream.getByte();a+=8}a-=e;this.bufferLength=a;this.buffer=t&(1<<a)-1;return t>>a},align:function(){this.buffer=0;this.bufferLength=0},readFlag:function(){return this.readBits(this.context.bitsPerFlag)},readCoordinate:function(){var e=this.context.bitsPerCoordinate,t=this.readBits(e),a=this.readBits(e),r=this.context.decode,i=e<32?1/((1<<e)-1):2.3283064365386963e-10;return[t*i*(r[1]-r[0])+r[0],a*i*(r[3]-r[2])+r[2]]},readComponents:function(){for(var e=this.context.numComps,t=this.context.bitsPerComponent,a=t<32?1/((1<<t)-1):2.3283064365386963e-10,r=this.context.decode,i=this.tmpCompsBuf,n=0,s=4;n<e;n++,s+=2){var o=this.readBits(t);i[n]=o*a*(r[s+1]-r[s])+r[s]}var c=this.tmpCsCompsBuf;this.context.colorFn&&this.context.colorFn(i,0,c,0);return this.context.colorSpace.getRgb(c,0)}};var t,a=(t=[],function(e){t[e]||(t[e]=function(e){for(var t=[],a=0;a<=e;a++){var r=a/e,i=1-r;t.push(new Float32Array([i*i*i,3*r*i*i,3*r*r*i,r*r*r]))}return t}(e));return t[e]});function s(e,t){var i=e.figures[t];(0,r.assert)("patch"===i.type,"Unexpected patch mesh figure");var n=e.coords,s=e.colors,o=i.coords,c=i.colors,l=Math.min(n[o[0]][0],n[o[3]][0],n[o[12]][0],n[o[15]][0]),h=Math.min(n[o[0]][1],n[o[3]][1],n[o[12]][1],n[o[15]][1]),u=Math.max(n[o[0]][0],n[o[3]][0],n[o[12]][0],n[o[15]][0]),d=Math.max(n[o[0]][1],n[o[3]][1],n[o[12]][1],n[o[15]][1]),f=Math.ceil(20*(u-l)/(e.bounds[2]-e.bounds[0]));f=Math.max(3,Math.min(20,f));var g=Math.ceil(20*(d-h)/(e.bounds[3]-e.bounds[1]));g=Math.max(3,Math.min(20,g));for(var m=f+1,p=new Int32Array((g+1)*m),b=new Int32Array((g+1)*m),y=0,v=new Uint8Array(3),w=new Uint8Array(3),k=s[c[0]],S=s[c[1]],C=s[c[2]],x=s[c[3]],A=a(g),I=a(f),F=0;F<=g;F++){v[0]=(k[0]*(g-F)+C[0]*F)/g|0;v[1]=(k[1]*(g-F)+C[1]*F)/g|0;v[2]=(k[2]*(g-F)+C[2]*F)/g|0;w[0]=(S[0]*(g-F)+x[0]*F)/g|0;w[1]=(S[1]*(g-F)+x[1]*F)/g|0;w[2]=(S[2]*(g-F)+x[2]*F)/g|0;for(var T=0;T<=f;T++,y++)if(0!==F&&F!==g||0!==T&&T!==f){for(var E=0,O=0,P=0,B=0;B<=3;B++)for(var D=0;D<=3;D++,P++){var N=A[F][B]*I[T][D];E+=n[o[P]][0]*N;O+=n[o[P]][1]*N}p[y]=n.length;n.push([E,O]);b[y]=s.length;var M=new Uint8Array(3);M[0]=(v[0]*(f-T)+w[0]*T)/f|0;M[1]=(v[1]*(f-T)+w[1]*T)/f|0;M[2]=(v[2]*(f-T)+w[2]*T)/f|0;s.push(M)}}p[0]=o[0];b[0]=c[0];p[f]=o[3];b[f]=c[1];p[m*g]=o[12];b[m*g]=c[2];p[m*g+f]=o[15];b[m*g+f]=c[3];e.figures[t]={type:"lattice",coords:p,colors:b,verticesPerRow:m}}function o(e){for(var t=e.coords[0][0],a=e.coords[0][1],r=t,i=a,n=1,s=e.coords.length;n<s;n++){var o=e.coords[n][0],c=e.coords[n][1];t=t>o?o:t;a=a>c?c:a;r=r<o?o:r;i=i<c?c:i}e.bounds=[t,a,r,i]}function c(t,a,c,f,g){if(!(0,n.isStream)(t))throw new r.FormatError("Mesh data is not a stream");var m=t.dict;this.matrix=a;this.shadingType=m.get("ShadingType");this.type="Pattern";const p=m.getArray("BBox");Array.isArray(p)&&4===p.length?this.bbox=r.Util.normalizeRect(p):this.bbox=null;var b=m.get("ColorSpace","CS");b=i.ColorSpace.parse(b,c,f,g);this.cs=b;this.background=m.has("Background")?b.getRgb(m.get("Background"),0):null;var y=m.get("Function"),v=y?g.createFromArray(y):null;this.coords=[];this.colors=[];this.figures=[];var w=new e(t,{bitsPerCoordinate:m.get("BitsPerCoordinate"),bitsPerComponent:m.get("BitsPerComponent"),bitsPerFlag:m.get("BitsPerFlag"),decode:m.getArray("Decode"),colorFn:v,colorSpace:b,numComps:v?1:b.numComps}),k=!1;switch(this.shadingType){case l:!function(e,t){for(var a=e.coords,i=e.colors,n=[],s=[],o=0;t.hasData;){var c=t.readFlag(),l=t.readCoordinate(),h=t.readComponents();if(0===o){if(!(0<=c&&c<=2))throw new r.FormatError("Unknown type4 flag");switch(c){case 0:o=3;break;case 1:s.push(s[s.length-2],s[s.length-1]);o=1;break;case 2:s.push(s[s.length-3],s[s.length-1]);o=1}n.push(c)}s.push(a.length);a.push(l);i.push(h);o--;t.align()}e.figures.push({type:"triangles",coords:new Int32Array(s),colors:new Int32Array(s)})}(this,w);break;case h:var S=0|m.get("VerticesPerRow");if(S<2)throw new r.FormatError("Invalid VerticesPerRow");!function(e,t,a){for(var r=e.coords,i=e.colors,n=[];t.hasData;){var s=t.readCoordinate(),o=t.readComponents();n.push(r.length);r.push(s);i.push(o)}e.figures.push({type:"lattice",coords:new Int32Array(n),colors:new Int32Array(n),verticesPerRow:a})}(this,w,S);break;case u:!function(e,t){for(var a=e.coords,i=e.colors,n=new Int32Array(16),s=new Int32Array(4);t.hasData;){var o,c,l=t.readFlag();if(!(0<=l&&l<=3))throw new r.FormatError("Unknown type6 flag");var h=a.length;for(o=0,c=0!==l?8:12;o<c;o++)a.push(t.readCoordinate());var u,d,f,g,m=i.length;for(o=0,c=0!==l?2:4;o<c;o++)i.push(t.readComponents());switch(l){case 0:n[12]=h+3;n[13]=h+4;n[14]=h+5;n[15]=h+6;n[8]=h+2;n[11]=h+7;n[4]=h+1;n[7]=h+8;n[0]=h;n[1]=h+11;n[2]=h+10;n[3]=h+9;s[2]=m+1;s[3]=m+2;s[0]=m;s[1]=m+3;break;case 1:u=n[12];d=n[13];f=n[14];g=n[15];n[12]=g;n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=f;n[11]=h+3;n[4]=d;n[7]=h+4;n[0]=u;n[1]=h+7;n[2]=h+6;n[3]=h+5;u=s[2];d=s[3];s[2]=d;s[3]=m;s[0]=u;s[1]=m+1;break;case 2:u=n[15];d=n[11];n[12]=n[3];n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=n[7];n[11]=h+3;n[4]=d;n[7]=h+4;n[0]=u;n[1]=h+7;n[2]=h+6;n[3]=h+5;u=s[3];s[2]=s[1];s[3]=m;s[0]=u;s[1]=m+1;break;case 3:n[12]=n[0];n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=n[1];n[11]=h+3;n[4]=n[2];n[7]=h+4;n[0]=n[3];n[1]=h+7;n[2]=h+6;n[3]=h+5;s[2]=s[0];s[3]=m;s[0]=s[1];s[1]=m+1}n[5]=a.length;a.push([(-4*a[n[0]][0]-a[n[15]][0]+6*(a[n[4]][0]+a[n[1]][0])-2*(a[n[12]][0]+a[n[3]][0])+3*(a[n[13]][0]+a[n[7]][0]))/9,(-4*a[n[0]][1]-a[n[15]][1]+6*(a[n[4]][1]+a[n[1]][1])-2*(a[n[12]][1]+a[n[3]][1])+3*(a[n[13]][1]+a[n[7]][1]))/9]);n[6]=a.length;a.push([(-4*a[n[3]][0]-a[n[12]][0]+6*(a[n[2]][0]+a[n[7]][0])-2*(a[n[0]][0]+a[n[15]][0])+3*(a[n[4]][0]+a[n[14]][0]))/9,(-4*a[n[3]][1]-a[n[12]][1]+6*(a[n[2]][1]+a[n[7]][1])-2*(a[n[0]][1]+a[n[15]][1])+3*(a[n[4]][1]+a[n[14]][1]))/9]);n[9]=a.length;a.push([(-4*a[n[12]][0]-a[n[3]][0]+6*(a[n[8]][0]+a[n[13]][0])-2*(a[n[0]][0]+a[n[15]][0])+3*(a[n[11]][0]+a[n[1]][0]))/9,(-4*a[n[12]][1]-a[n[3]][1]+6*(a[n[8]][1]+a[n[13]][1])-2*(a[n[0]][1]+a[n[15]][1])+3*(a[n[11]][1]+a[n[1]][1]))/9]);n[10]=a.length;a.push([(-4*a[n[15]][0]-a[n[0]][0]+6*(a[n[11]][0]+a[n[14]][0])-2*(a[n[12]][0]+a[n[3]][0])+3*(a[n[2]][0]+a[n[8]][0]))/9,(-4*a[n[15]][1]-a[n[0]][1]+6*(a[n[11]][1]+a[n[14]][1])-2*(a[n[12]][1]+a[n[3]][1])+3*(a[n[2]][1]+a[n[8]][1]))/9]);e.figures.push({type:"patch",coords:new Int32Array(n),colors:new Int32Array(s)})}}(this,w);k=!0;break;case d:!function(e,t){for(var a=e.coords,i=e.colors,n=new Int32Array(16),s=new Int32Array(4);t.hasData;){var o,c,l=t.readFlag();if(!(0<=l&&l<=3))throw new r.FormatError("Unknown type7 flag");var h=a.length;for(o=0,c=0!==l?12:16;o<c;o++)a.push(t.readCoordinate());var u,d,f,g,m=i.length;for(o=0,c=0!==l?2:4;o<c;o++)i.push(t.readComponents());switch(l){case 0:n[12]=h+3;n[13]=h+4;n[14]=h+5;n[15]=h+6;n[8]=h+2;n[9]=h+13;n[10]=h+14;n[11]=h+7;n[4]=h+1;n[5]=h+12;n[6]=h+15;n[7]=h+8;n[0]=h;n[1]=h+11;n[2]=h+10;n[3]=h+9;s[2]=m+1;s[3]=m+2;s[0]=m;s[1]=m+3;break;case 1:u=n[12];d=n[13];f=n[14];g=n[15];n[12]=g;n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=f;n[9]=h+9;n[10]=h+10;n[11]=h+3;n[4]=d;n[5]=h+8;n[6]=h+11;n[7]=h+4;n[0]=u;n[1]=h+7;n[2]=h+6;n[3]=h+5;u=s[2];d=s[3];s[2]=d;s[3]=m;s[0]=u;s[1]=m+1;break;case 2:u=n[15];d=n[11];n[12]=n[3];n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=n[7];n[9]=h+9;n[10]=h+10;n[11]=h+3;n[4]=d;n[5]=h+8;n[6]=h+11;n[7]=h+4;n[0]=u;n[1]=h+7;n[2]=h+6;n[3]=h+5;u=s[3];s[2]=s[1];s[3]=m;s[0]=u;s[1]=m+1;break;case 3:n[12]=n[0];n[13]=h+0;n[14]=h+1;n[15]=h+2;n[8]=n[1];n[9]=h+9;n[10]=h+10;n[11]=h+3;n[4]=n[2];n[5]=h+8;n[6]=h+11;n[7]=h+4;n[0]=n[3];n[1]=h+7;n[2]=h+6;n[3]=h+5;s[2]=s[0];s[3]=m;s[0]=s[1];s[1]=m+1}e.figures.push({type:"patch",coords:new Int32Array(n),colors:new Int32Array(s)})}}(this,w);k=!0;break;default:(0,r.unreachable)("Unsupported mesh type.")}if(k){o(this);for(var C=0,x=this.figures.length;C<x;C++)s(this,C)}o(this);!function(e){var t,a,r,i,n=e.coords,s=new Float32Array(2*n.length);for(t=0,r=0,a=n.length;t<a;t++){var o=n[t];s[r++]=o[0];s[r++]=o[1]}e.coords=s;var c=e.colors,l=new Uint8Array(3*c.length);for(t=0,r=0,a=c.length;t<a;t++){var h=c[t];l[r++]=h[0];l[r++]=h[1];l[r++]=h[2]}e.colors=l;var u=e.figures;for(t=0,a=u.length;t<a;t++){var d=u[t],f=d.coords,g=d.colors;for(r=0,i=f.length;r<i;r++){f[r]*=2;g[r]*=3}}}(this)}c.prototype={getIR:function(){return["Mesh",this.shadingType,this.coords,this.colors,this.figures,this.bounds,this.matrix,this.bbox,this.background]}};return c}();g.Dummy=function(){function e(){this.type="Pattern"}e.prototype={getIR:function(){return["Dummy"]}};return e}()},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.bidi=function(e,t,a){var g=!0,m=e.length;if(0===m||a)return u(e,g,a);d.length=m;f.length=m;var p,b,y=0;for(p=0;p<m;++p){d[p]=e.charAt(p);var v=e.charCodeAt(p),w="L";v<=255?w=i[v]:1424<=v&&v<=1524?w="R":1536<=v&&v<=1791?(w=n[255&v])||(0,r.warn)("Bidi: invalid Unicode character "+v.toString(16)):1792<=v&&v<=2220&&(w="AL");"R"!==w&&"AL"!==w&&"AN"!==w||y++;f[p]=w}if(0===y)return u(e,g=!0);if(-1===t)if(y/m<.3){g=!0;t=0}else{g=!1;t=1}var k=[];for(p=0;p<m;++p)k[p]=t;var S,C=s(t)?"R":"L",x=C,A=x,I=x;for(p=0;p<m;++p)"NSM"===f[p]?f[p]=I:I=f[p];I=x;for(p=0;p<m;++p)"EN"===(S=f[p])?f[p]="AL"===I?"AN":"EN":"R"!==S&&"L"!==S&&"AL"!==S||(I=S);for(p=0;p<m;++p)"AL"===(S=f[p])&&(f[p]="R");for(p=1;p<m-1;++p){"ES"===f[p]&&"EN"===f[p-1]&&"EN"===f[p+1]&&(f[p]="EN");"CS"!==f[p]||"EN"!==f[p-1]&&"AN"!==f[p-1]||f[p+1]!==f[p-1]||(f[p]=f[p-1])}for(p=0;p<m;++p)if("EN"===f[p]){var F;for(F=p-1;F>=0&&"ET"===f[F];--F)f[F]="EN";for(F=p+1;F<m&&"ET"===f[F];++F)f[F]="EN"}for(p=0;p<m;++p)"WS"!==(S=f[p])&&"ES"!==S&&"ET"!==S&&"CS"!==S||(f[p]="ON");I=x;for(p=0;p<m;++p)"EN"===(S=f[p])?f[p]="L"===I?"L":"EN":"R"!==S&&"L"!==S||(I=S);for(p=0;p<m;++p)if("ON"===f[p]){var T=c(f,p+1,"ON"),E=x;p>0&&(E=f[p-1]);var O=A;T+1<m&&(O=f[T+1]);"L"!==E&&(E="R");"L"!==O&&(O="R");E===O&&l(f,p,T,E);p=T-1}for(p=0;p<m;++p)"ON"===f[p]&&(f[p]=C);for(p=0;p<m;++p){S=f[p];o(k[p])?"R"===S?k[p]+=1:"AN"!==S&&"EN"!==S||(k[p]+=2):"L"!==S&&"AN"!==S&&"EN"!==S||(k[p]+=1)}var P,B=-1,D=99;for(p=0,b=k.length;p<b;++p){P=k[p];B<P&&(B=P);D>P&&s(P)&&(D=P)}for(P=B;P>=D;--P){var N=-1;for(p=0,b=k.length;p<b;++p)if(k[p]<P){if(N>=0){h(d,N,p);N=-1}}else N<0&&(N=p);N>=0&&h(d,N,k.length)}for(p=0,b=d.length;p<b;++p){var M=d[p];"<"!==M&&">"!==M||(d[p]="")}return u(d.join(""),g)};var r=a(2),i=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],n=["AN","AN","AN","AN","AN","AN","ON","ON","AL","ET","ET","AL","CS","AL","ON","ON","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","AN","AN","AN","AN","AN","AN","AN","AN","AN","ET","AN","AN","AL","AL","AL","NSM","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","ON","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","NSM","NSM","ON","NSM","NSM","NSM","NSM","AL","AL","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","AL","AL","AL","AL","AL","AL"];function s(e){return 0!=(1&e)}function o(e){return 0==(1&e)}function c(e,t,a){for(var r=t,i=e.length;r<i;++r)if(e[r]!==a)return r;return r}function l(e,t,a,r){for(var i=t;i<a;++i)e[i]=r}function h(e,t,a){for(var r=t,i=a-1;r<i;++r,--i){var n=e[r];e[r]=e[i];e[i]=n}}function u(e,t,a=!1){let r="ltr";a?r="ttb":t||(r="rtl");return{str:e,dir:r}}var d=[],f=[]},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.getMetrics=void 0;var r=a(7),i=(0,r.getLookupTableFactory)((function(e){e.Courier=600;e["Courier-Bold"]=600;e["Courier-BoldOblique"]=600;e["Courier-Oblique"]=600;e.Helvetica=(0,r.getLookupTableFactory)((function(e){e.space=278;e.exclam=278;e.quotedbl=355;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=667;e.quoteright=222;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=278;e.semicolon=278;e.less=584;e.equal=584;e.greater=584;e.question=556;e.at=1015;e.A=667;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=500;e.K=667;e.L=556;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=278;e.backslash=278;e.bracketright=278;e.asciicircum=469;e.underscore=556;e.quoteleft=222;e.a=556;e.b=556;e.c=500;e.d=556;e.e=556;e.f=278;e.g=556;e.h=556;e.i=222;e.j=222;e.k=500;e.l=222;e.m=833;e.n=556;e.o=556;e.p=556;e.q=556;e.r=333;e.s=500;e.t=278;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=500;e.braceleft=334;e.bar=260;e.braceright=334;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=191;e.quotedblleft=333;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=537;e.bullet=350;e.quotesinglbase=222;e.quotedblbase=333;e.quotedblright=333;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=556;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=222;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=556;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=667;e.aacute=556;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=500;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=500;e.aring=556;e.Ncommaaccent=722;e.lacute=222;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=500;e.scedilla=500;e.iacute=278;e.lozenge=471;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=556;e.Amacron=667;e.rcaron=333;e.ccedilla=500;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=643;e.Umacron=722;e.uring=556;e.threesuperior=333;e.Ograve=778;e.Agrave=667;e.Abreve=667;e.multiply=584;e.uacute=556;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=500;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=260;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=333;e.omacron=556;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=222;e.tcaron=317;e.eogonek=556;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=556;e.zacute=500;e.iogonek=222;e.Oacute=778;e.oacute=556;e.amacron=556;e.sacute=500;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=333;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=556;e.Eogonek=667;e.dcroat=556;e.threequarters=834;e.Scedilla=667;e.lcaron=299;e.Kcommaaccent=667;e.Lacute=556;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=556;e.onehalf=834;e.lessequal=549;e.ocircumflex=556;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=556;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=556;e.Ccaron=722;e.ugrave=556;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=556;e.Rcommaaccent=722;e.Lcommaaccent=556;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=500;e.minus=584;e.Icircumflex=278;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=584;e.odieresis=556;e.udieresis=556;e.notequal=549;e.gcommaaccent=556;e.eth=556;e.zcaron=500;e.ncommaaccent=556;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-Bold"]=(0,r.getLookupTableFactory)((function(e){e.space=278;e.exclam=333;e.quotedbl=474;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=722;e.quoteright=278;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=333;e.semicolon=333;e.less=584;e.equal=584;e.greater=584;e.question=611;e.at=975;e.A=722;e.B=722;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=556;e.K=722;e.L=611;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=584;e.underscore=556;e.quoteleft=278;e.a=556;e.b=611;e.c=556;e.d=611;e.e=556;e.f=333;e.g=611;e.h=611;e.i=278;e.j=278;e.k=556;e.l=278;e.m=889;e.n=611;e.o=611;e.p=611;e.q=611;e.r=389;e.s=556;e.t=333;e.u=611;e.v=556;e.w=778;e.x=556;e.y=556;e.z=500;e.braceleft=389;e.bar=280;e.braceright=389;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=238;e.quotedblleft=500;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=611;e.fl=611;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=556;e.bullet=350;e.quotesinglbase=278;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=611;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=278;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=611;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=722;e.aacute=556;e.Ucircumflex=722;e.yacute=556;e.scommaaccent=556;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=611;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=556;e.aring=556;e.Ncommaaccent=722;e.lacute=278;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=556;e.scedilla=556;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=611;e.acircumflex=556;e.Amacron=722;e.rcaron=389;e.ccedilla=556;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=743;e.Umacron=722;e.uring=611;e.threesuperior=333;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=584;e.uacute=611;e.Tcaron=611;e.partialdiff=494;e.ydieresis=556;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=556;e.nacute=611;e.umacron=611;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=280;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=611;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=389;e.eogonek=556;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=556;e.zacute=500;e.iogonek=278;e.Oacute=778;e.oacute=611;e.amacron=556;e.sacute=556;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=611;e.twosuperior=333;e.Odieresis=778;e.mu=611;e.igrave=278;e.ohungarumlaut=611;e.Eogonek=667;e.dcroat=611;e.threequarters=834;e.Scedilla=667;e.lcaron=400;e.Kcommaaccent=722;e.Lacute=611;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=611;e.onehalf=834;e.lessequal=549;e.ocircumflex=611;e.ntilde=611;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=611;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=611;e.Ccaron=722;e.ugrave=611;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=611;e.Rcommaaccent=722;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=556;e.minus=584;e.Icircumflex=278;e.ncaron=611;e.tcommaaccent=333;e.logicalnot=584;e.odieresis=611;e.udieresis=611;e.notequal=549;e.gcommaaccent=611;e.eth=611;e.zcaron=500;e.ncommaaccent=611;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-BoldOblique"]=(0,r.getLookupTableFactory)((function(e){e.space=278;e.exclam=333;e.quotedbl=474;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=722;e.quoteright=278;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=333;e.semicolon=333;e.less=584;e.equal=584;e.greater=584;e.question=611;e.at=975;e.A=722;e.B=722;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=556;e.K=722;e.L=611;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=584;e.underscore=556;e.quoteleft=278;e.a=556;e.b=611;e.c=556;e.d=611;e.e=556;e.f=333;e.g=611;e.h=611;e.i=278;e.j=278;e.k=556;e.l=278;e.m=889;e.n=611;e.o=611;e.p=611;e.q=611;e.r=389;e.s=556;e.t=333;e.u=611;e.v=556;e.w=778;e.x=556;e.y=556;e.z=500;e.braceleft=389;e.bar=280;e.braceright=389;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=238;e.quotedblleft=500;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=611;e.fl=611;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=556;e.bullet=350;e.quotesinglbase=278;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=611;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=278;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=611;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=722;e.aacute=556;e.Ucircumflex=722;e.yacute=556;e.scommaaccent=556;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=611;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=556;e.aring=556;e.Ncommaaccent=722;e.lacute=278;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=556;e.scedilla=556;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=611;e.acircumflex=556;e.Amacron=722;e.rcaron=389;e.ccedilla=556;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=743;e.Umacron=722;e.uring=611;e.threesuperior=333;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=584;e.uacute=611;e.Tcaron=611;e.partialdiff=494;e.ydieresis=556;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=556;e.nacute=611;e.umacron=611;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=280;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=611;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=389;e.eogonek=556;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=556;e.zacute=500;e.iogonek=278;e.Oacute=778;e.oacute=611;e.amacron=556;e.sacute=556;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=611;e.twosuperior=333;e.Odieresis=778;e.mu=611;e.igrave=278;e.ohungarumlaut=611;e.Eogonek=667;e.dcroat=611;e.threequarters=834;e.Scedilla=667;e.lcaron=400;e.Kcommaaccent=722;e.Lacute=611;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=611;e.onehalf=834;e.lessequal=549;e.ocircumflex=611;e.ntilde=611;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=611;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=611;e.Ccaron=722;e.ugrave=611;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=611;e.Rcommaaccent=722;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=556;e.minus=584;e.Icircumflex=278;e.ncaron=611;e.tcommaaccent=333;e.logicalnot=584;e.odieresis=611;e.udieresis=611;e.notequal=549;e.gcommaaccent=611;e.eth=611;e.zcaron=500;e.ncommaaccent=611;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-Oblique"]=(0,r.getLookupTableFactory)((function(e){e.space=278;e.exclam=278;e.quotedbl=355;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=667;e.quoteright=222;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=278;e.semicolon=278;e.less=584;e.equal=584;e.greater=584;e.question=556;e.at=1015;e.A=667;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=500;e.K=667;e.L=556;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=278;e.backslash=278;e.bracketright=278;e.asciicircum=469;e.underscore=556;e.quoteleft=222;e.a=556;e.b=556;e.c=500;e.d=556;e.e=556;e.f=278;e.g=556;e.h=556;e.i=222;e.j=222;e.k=500;e.l=222;e.m=833;e.n=556;e.o=556;e.p=556;e.q=556;e.r=333;e.s=500;e.t=278;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=500;e.braceleft=334;e.bar=260;e.braceright=334;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=191;e.quotedblleft=333;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=537;e.bullet=350;e.quotesinglbase=222;e.quotedblbase=333;e.quotedblright=333;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=556;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=222;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=556;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=667;e.aacute=556;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=500;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=500;e.aring=556;e.Ncommaaccent=722;e.lacute=222;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=500;e.scedilla=500;e.iacute=278;e.lozenge=471;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=556;e.Amacron=667;e.rcaron=333;e.ccedilla=500;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=643;e.Umacron=722;e.uring=556;e.threesuperior=333;e.Ograve=778;e.Agrave=667;e.Abreve=667;e.multiply=584;e.uacute=556;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=500;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=260;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=333;e.omacron=556;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=222;e.tcaron=317;e.eogonek=556;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=556;e.zacute=500;e.iogonek=222;e.Oacute=778;e.oacute=556;e.amacron=556;e.sacute=500;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=333;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=556;e.Eogonek=667;e.dcroat=556;e.threequarters=834;e.Scedilla=667;e.lcaron=299;e.Kcommaaccent=667;e.Lacute=556;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=556;e.onehalf=834;e.lessequal=549;e.ocircumflex=556;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=556;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=556;e.Ccaron=722;e.ugrave=556;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=556;e.Rcommaaccent=722;e.Lcommaaccent=556;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=500;e.minus=584;e.Icircumflex=278;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=584;e.odieresis=556;e.udieresis=556;e.notequal=549;e.gcommaaccent=556;e.eth=556;e.zcaron=500;e.ncommaaccent=556;e.onesuperior=333;e.imacron=278;e.Euro=556}));e.Symbol=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=333;e.universal=713;e.numbersign=500;e.existential=549;e.percent=833;e.ampersand=778;e.suchthat=439;e.parenleft=333;e.parenright=333;e.asteriskmath=500;e.plus=549;e.comma=250;e.minus=549;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=278;e.semicolon=278;e.less=549;e.equal=549;e.greater=549;e.question=444;e.congruent=549;e.Alpha=722;e.Beta=667;e.Chi=722;e.Delta=612;e.Epsilon=611;e.Phi=763;e.Gamma=603;e.Eta=722;e.Iota=333;e.theta1=631;e.Kappa=722;e.Lambda=686;e.Mu=889;e.Nu=722;e.Omicron=722;e.Pi=768;e.Theta=741;e.Rho=556;e.Sigma=592;e.Tau=611;e.Upsilon=690;e.sigma1=439;e.Omega=768;e.Xi=645;e.Psi=795;e.Zeta=611;e.bracketleft=333;e.therefore=863;e.bracketright=333;e.perpendicular=658;e.underscore=500;e.radicalex=500;e.alpha=631;e.beta=549;e.chi=549;e.delta=494;e.epsilon=439;e.phi=521;e.gamma=411;e.eta=603;e.iota=329;e.phi1=603;e.kappa=549;e.lambda=549;e.mu=576;e.nu=521;e.omicron=549;e.pi=549;e.theta=521;e.rho=549;e.sigma=603;e.tau=439;e.upsilon=576;e.omega1=713;e.omega=686;e.xi=493;e.psi=686;e.zeta=494;e.braceleft=480;e.bar=200;e.braceright=480;e.similar=549;e.Euro=750;e.Upsilon1=620;e.minute=247;e.lessequal=549;e.fraction=167;e.infinity=713;e.florin=500;e.club=753;e.diamond=753;e.heart=753;e.spade=753;e.arrowboth=1042;e.arrowleft=987;e.arrowup=603;e.arrowright=987;e.arrowdown=603;e.degree=400;e.plusminus=549;e.second=411;e.greaterequal=549;e.multiply=549;e.proportional=713;e.partialdiff=494;e.bullet=460;e.divide=549;e.notequal=549;e.equivalence=549;e.approxequal=549;e.ellipsis=1e3;e.arrowvertex=603;e.arrowhorizex=1e3;e.carriagereturn=658;e.aleph=823;e.Ifraktur=686;e.Rfraktur=795;e.weierstrass=987;e.circlemultiply=768;e.circleplus=768;e.emptyset=823;e.intersection=768;e.union=768;e.propersuperset=713;e.reflexsuperset=713;e.notsubset=713;e.propersubset=713;e.reflexsubset=713;e.element=713;e.notelement=713;e.angle=768;e.gradient=713;e.registerserif=790;e.copyrightserif=790;e.trademarkserif=890;e.product=823;e.radical=549;e.dotmath=250;e.logicalnot=713;e.logicaland=603;e.logicalor=603;e.arrowdblboth=1042;e.arrowdblleft=987;e.arrowdblup=603;e.arrowdblright=987;e.arrowdbldown=603;e.lozenge=494;e.angleleft=329;e.registersans=790;e.copyrightsans=790;e.trademarksans=786;e.summation=713;e.parenlefttp=384;e.parenleftex=384;e.parenleftbt=384;e.bracketlefttp=384;e.bracketleftex=384;e.bracketleftbt=384;e.bracelefttp=494;e.braceleftmid=494;e.braceleftbt=494;e.braceex=494;e.angleright=329;e.integral=274;e.integraltp=686;e.integralex=686;e.integralbt=686;e.parenrighttp=384;e.parenrightex=384;e.parenrightbt=384;e.bracketrighttp=384;e.bracketrightex=384;e.bracketrightbt=384;e.bracerighttp=494;e.bracerightmid=494;e.bracerightbt=494;e.apple=790}));e["Times-Roman"]=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=333;e.quotedbl=408;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=564;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=278;e.semicolon=278;e.less=564;e.equal=564;e.greater=564;e.question=444;e.at=921;e.A=722;e.B=667;e.C=667;e.D=722;e.E=611;e.F=556;e.G=722;e.H=722;e.I=333;e.J=389;e.K=722;e.L=611;e.M=889;e.N=722;e.O=722;e.P=556;e.Q=722;e.R=667;e.S=556;e.T=611;e.U=722;e.V=722;e.W=944;e.X=722;e.Y=722;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=469;e.underscore=500;e.quoteleft=333;e.a=444;e.b=500;e.c=444;e.d=500;e.e=444;e.f=333;e.g=500;e.h=500;e.i=278;e.j=278;e.k=500;e.l=278;e.m=778;e.n=500;e.o=500;e.p=500;e.q=500;e.r=333;e.s=389;e.t=278;e.u=500;e.v=500;e.w=722;e.x=500;e.y=500;e.z=444;e.braceleft=480;e.bar=200;e.braceright=480;e.asciitilde=541;e.exclamdown=333;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=180;e.quotedblleft=444;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=453;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=444;e.quotedblright=444;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=444;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=889;e.ordfeminine=276;e.Lslash=611;e.Oslash=722;e.OE=889;e.ordmasculine=310;e.ae=667;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=500;e.Idieresis=333;e.eacute=444;e.abreve=444;e.uhungarumlaut=500;e.ecaron=444;e.Ydieresis=722;e.divide=564;e.Yacute=722;e.Acircumflex=722;e.aacute=444;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=444;e.Uacute=722;e.uogonek=500;e.Edieresis=611;e.Dcroat=722;e.commaaccent=250;e.copyright=760;e.Emacron=611;e.ccaron=444;e.aring=444;e.Ncommaaccent=722;e.lacute=278;e.agrave=444;e.Tcommaaccent=611;e.Cacute=667;e.atilde=444;e.Edotaccent=611;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=471;e.Rcaron=667;e.Gcommaaccent=722;e.ucircumflex=500;e.acircumflex=444;e.Amacron=722;e.rcaron=333;e.ccedilla=444;e.Zdotaccent=611;e.Thorn=556;e.Omacron=722;e.Racute=667;e.Sacute=556;e.dcaron=588;e.Umacron=722;e.uring=500;e.threesuperior=300;e.Ograve=722;e.Agrave=722;e.Abreve=722;e.multiply=564;e.uacute=500;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=611;e.adieresis=444;e.edieresis=444;e.cacute=444;e.nacute=500;e.umacron=500;e.Ncaron=722;e.Iacute=333;e.plusminus=564;e.brokenbar=200;e.registered=760;e.Gbreve=722;e.Idotaccent=333;e.summation=600;e.Egrave=611;e.racute=333;e.omacron=500;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=326;e.eogonek=444;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=444;e.zacute=444;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=444;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=500;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=611;e.dcroat=500;e.threequarters=750;e.Scedilla=556;e.lcaron=344;e.Kcommaaccent=722;e.Lacute=611;e.trademark=980;e.edotaccent=444;e.Igrave=333;e.Imacron=333;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=500;e.Uhungarumlaut=722;e.Eacute=611;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=500;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=667;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=722;e.zdotaccent=444;e.Ecaron=611;e.Iogonek=333;e.kcommaaccent=500;e.minus=564;e.Icircumflex=333;e.ncaron=500;e.tcommaaccent=278;e.logicalnot=564;e.odieresis=500;e.udieresis=500;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=444;e.ncommaaccent=500;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-Bold"]=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=333;e.quotedbl=555;e.numbersign=500;e.dollar=500;e.percent=1e3;e.ampersand=833;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=570;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=570;e.equal=570;e.greater=570;e.question=500;e.at=930;e.A=722;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=778;e.I=389;e.J=500;e.K=778;e.L=667;e.M=944;e.N=722;e.O=778;e.P=611;e.Q=778;e.R=722;e.S=556;e.T=667;e.U=722;e.V=722;e.W=1e3;e.X=722;e.Y=722;e.Z=667;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=581;e.underscore=500;e.quoteleft=333;e.a=500;e.b=556;e.c=444;e.d=556;e.e=444;e.f=333;e.g=500;e.h=556;e.i=278;e.j=333;e.k=556;e.l=278;e.m=833;e.n=556;e.o=500;e.p=556;e.q=556;e.r=444;e.s=389;e.t=333;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=444;e.braceleft=394;e.bar=220;e.braceright=394;e.asciitilde=520;e.exclamdown=333;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=278;e.quotedblleft=500;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=540;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=300;e.Lslash=667;e.Oslash=778;e.OE=1e3;e.ordmasculine=330;e.ae=722;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=556;e.Idieresis=389;e.eacute=444;e.abreve=500;e.uhungarumlaut=556;e.ecaron=444;e.Ydieresis=722;e.divide=570;e.Yacute=722;e.Acircumflex=722;e.aacute=500;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=747;e.Emacron=667;e.ccaron=444;e.aring=500;e.Ncommaaccent=722;e.lacute=278;e.agrave=500;e.Tcommaaccent=667;e.Cacute=722;e.atilde=500;e.Edotaccent=667;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=500;e.Amacron=722;e.rcaron=444;e.ccedilla=444;e.Zdotaccent=667;e.Thorn=611;e.Omacron=778;e.Racute=722;e.Sacute=556;e.dcaron=672;e.Umacron=722;e.uring=556;e.threesuperior=300;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=570;e.uacute=556;e.Tcaron=667;e.partialdiff=494;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=389;e.plusminus=570;e.brokenbar=220;e.registered=747;e.Gbreve=778;e.Idotaccent=389;e.summation=600;e.Egrave=667;e.racute=444;e.omacron=500;e.Zacute=667;e.Zcaron=667;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=416;e.eogonek=444;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=444;e.zacute=444;e.iogonek=278;e.Oacute=778;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=300;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=667;e.dcroat=556;e.threequarters=750;e.Scedilla=556;e.lcaron=394;e.Kcommaaccent=778;e.Lacute=667;e.trademark=1e3;e.edotaccent=444;e.Igrave=389;e.Imacron=389;e.Lcaron=667;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=778;e.degree=400;e.ograve=500;e.Ccaron=722;e.ugrave=556;e.radical=549;e.Dcaron=722;e.rcommaaccent=444;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=722;e.Lcommaaccent=667;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=444;e.Ecaron=667;e.Iogonek=389;e.kcommaaccent=556;e.minus=570;e.Icircumflex=389;e.ncaron=556;e.tcommaaccent=333;e.logicalnot=570;e.odieresis=500;e.udieresis=556;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=444;e.ncommaaccent=556;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-BoldItalic"]=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=389;e.quotedbl=555;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=570;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=570;e.equal=570;e.greater=570;e.question=500;e.at=832;e.A=667;e.B=667;e.C=667;e.D=722;e.E=667;e.F=667;e.G=722;e.H=778;e.I=389;e.J=500;e.K=667;e.L=611;e.M=889;e.N=722;e.O=722;e.P=611;e.Q=722;e.R=667;e.S=556;e.T=611;e.U=722;e.V=667;e.W=889;e.X=667;e.Y=611;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=570;e.underscore=500;e.quoteleft=333;e.a=500;e.b=500;e.c=444;e.d=500;e.e=444;e.f=333;e.g=500;e.h=556;e.i=278;e.j=278;e.k=500;e.l=278;e.m=778;e.n=556;e.o=500;e.p=500;e.q=500;e.r=389;e.s=389;e.t=278;e.u=556;e.v=444;e.w=667;e.x=500;e.y=444;e.z=389;e.braceleft=348;e.bar=220;e.braceright=348;e.asciitilde=570;e.exclamdown=389;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=278;e.quotedblleft=500;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=500;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=944;e.ordfeminine=266;e.Lslash=611;e.Oslash=722;e.OE=944;e.ordmasculine=300;e.ae=722;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=500;e.Idieresis=389;e.eacute=444;e.abreve=500;e.uhungarumlaut=556;e.ecaron=444;e.Ydieresis=611;e.divide=570;e.Yacute=611;e.Acircumflex=667;e.aacute=500;e.Ucircumflex=722;e.yacute=444;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=747;e.Emacron=667;e.ccaron=444;e.aring=500;e.Ncommaaccent=722;e.lacute=278;e.agrave=500;e.Tcommaaccent=611;e.Cacute=667;e.atilde=500;e.Edotaccent=667;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=494;e.Rcaron=667;e.Gcommaaccent=722;e.ucircumflex=556;e.acircumflex=500;e.Amacron=667;e.rcaron=389;e.ccedilla=444;e.Zdotaccent=611;e.Thorn=611;e.Omacron=722;e.Racute=667;e.Sacute=556;e.dcaron=608;e.Umacron=722;e.uring=556;e.threesuperior=300;e.Ograve=722;e.Agrave=667;e.Abreve=667;e.multiply=570;e.uacute=556;e.Tcaron=611;e.partialdiff=494;e.ydieresis=444;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=389;e.plusminus=570;e.brokenbar=220;e.registered=747;e.Gbreve=722;e.Idotaccent=389;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=500;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=366;e.eogonek=444;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=444;e.zacute=389;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=576;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=667;e.dcroat=500;e.threequarters=750;e.Scedilla=556;e.lcaron=382;e.Kcommaaccent=667;e.Lacute=611;e.trademark=1e3;e.edotaccent=444;e.Igrave=389;e.Imacron=389;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=556;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=667;e.Lcommaaccent=611;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=722;e.zdotaccent=389;e.Ecaron=667;e.Iogonek=389;e.kcommaaccent=500;e.minus=606;e.Icircumflex=389;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=606;e.odieresis=500;e.udieresis=556;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=389;e.ncommaaccent=556;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-Italic"]=(0,r.getLookupTableFactory)((function(e){e.space=250;e.exclam=333;e.quotedbl=420;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=675;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=675;e.equal=675;e.greater=675;e.question=500;e.at=920;e.A=611;e.B=611;e.C=667;e.D=722;e.E=611;e.F=611;e.G=722;e.H=722;e.I=333;e.J=444;e.K=667;e.L=556;e.M=833;e.N=667;e.O=722;e.P=611;e.Q=722;e.R=611;e.S=500;e.T=556;e.U=722;e.V=611;e.W=833;e.X=611;e.Y=556;e.Z=556;e.bracketleft=389;e.backslash=278;e.bracketright=389;e.asciicircum=422;e.underscore=500;e.quoteleft=333;e.a=500;e.b=500;e.c=444;e.d=500;e.e=444;e.f=278;e.g=500;e.h=500;e.i=278;e.j=278;e.k=444;e.l=278;e.m=722;e.n=500;e.o=500;e.p=500;e.q=500;e.r=389;e.s=389;e.t=278;e.u=500;e.v=444;e.w=667;e.x=444;e.y=444;e.z=389;e.braceleft=400;e.bar=275;e.braceright=400;e.asciitilde=541;e.exclamdown=389;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=214;e.quotedblleft=556;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=523;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=556;e.quotedblright=556;e.guillemotright=500;e.ellipsis=889;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=889;e.AE=889;e.ordfeminine=276;e.Lslash=556;e.Oslash=722;e.OE=944;e.ordmasculine=310;e.ae=667;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=667;e.germandbls=500;e.Idieresis=333;e.eacute=444;e.abreve=500;e.uhungarumlaut=500;e.ecaron=444;e.Ydieresis=556;e.divide=675;e.Yacute=556;e.Acircumflex=611;e.aacute=500;e.Ucircumflex=722;e.yacute=444;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=500;e.Edieresis=611;e.Dcroat=722;e.commaaccent=250;e.copyright=760;e.Emacron=611;e.ccaron=444;e.aring=500;e.Ncommaaccent=667;e.lacute=278;e.agrave=500;e.Tcommaaccent=556;e.Cacute=667;e.atilde=500;e.Edotaccent=611;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=471;e.Rcaron=611;e.Gcommaaccent=722;e.ucircumflex=500;e.acircumflex=500;e.Amacron=611;e.rcaron=389;e.ccedilla=444;e.Zdotaccent=556;e.Thorn=611;e.Omacron=722;e.Racute=611;e.Sacute=500;e.dcaron=544;e.Umacron=722;e.uring=500;e.threesuperior=300;e.Ograve=722;e.Agrave=611;e.Abreve=611;e.multiply=675;e.uacute=500;e.Tcaron=556;e.partialdiff=476;e.ydieresis=444;e.Nacute=667;e.icircumflex=278;e.Ecircumflex=611;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=500;e.umacron=500;e.Ncaron=667;e.Iacute=333;e.plusminus=675;e.brokenbar=275;e.registered=760;e.Gbreve=722;e.Idotaccent=333;e.summation=600;e.Egrave=611;e.racute=389;e.omacron=500;e.Zacute=556;e.Zcaron=556;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=300;e.eogonek=444;e.Uogonek=722;e.Aacute=611;e.Adieresis=611;e.egrave=444;e.zacute=389;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=500;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=611;e.dcroat=500;e.threequarters=750;e.Scedilla=500;e.lcaron=300;e.Kcommaaccent=667;e.Lacute=556;e.trademark=980;e.edotaccent=444;e.Igrave=333;e.Imacron=333;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=500;e.Uhungarumlaut=722;e.Eacute=611;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=500;e.Scommaaccent=500;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=500;e.radical=453;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=667;e.otilde=500;e.Rcommaaccent=611;e.Lcommaaccent=556;e.Atilde=611;e.Aogonek=611;e.Aring=611;e.Otilde=722;e.zdotaccent=389;e.Ecaron=611;e.Iogonek=333;e.kcommaaccent=444;e.minus=675;e.Icircumflex=333;e.ncaron=500;e.tcommaaccent=278;e.logicalnot=675;e.odieresis=500;e.udieresis=500;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=389;e.ncommaaccent=500;e.onesuperior=300;e.imacron=278;e.Euro=500}));e.ZapfDingbats=(0,r.getLookupTableFactory)((function(e){e.space=278;e.a1=974;e.a2=961;e.a202=974;e.a3=980;e.a4=719;e.a5=789;e.a119=790;e.a118=791;e.a117=690;e.a11=960;e.a12=939;e.a13=549;e.a14=855;e.a15=911;e.a16=933;e.a105=911;e.a17=945;e.a18=974;e.a19=755;e.a20=846;e.a21=762;e.a22=761;e.a23=571;e.a24=677;e.a25=763;e.a26=760;e.a27=759;e.a28=754;e.a6=494;e.a7=552;e.a8=537;e.a9=577;e.a10=692;e.a29=786;e.a30=788;e.a31=788;e.a32=790;e.a33=793;e.a34=794;e.a35=816;e.a36=823;e.a37=789;e.a38=841;e.a39=823;e.a40=833;e.a41=816;e.a42=831;e.a43=923;e.a44=744;e.a45=723;e.a46=749;e.a47=790;e.a48=792;e.a49=695;e.a50=776;e.a51=768;e.a52=792;e.a53=759;e.a54=707;e.a55=708;e.a56=682;e.a57=701;e.a58=826;e.a59=815;e.a60=789;e.a61=789;e.a62=707;e.a63=687;e.a64=696;e.a65=689;e.a66=786;e.a67=787;e.a68=713;e.a69=791;e.a70=785;e.a71=791;e.a72=873;e.a73=761;e.a74=762;e.a203=762;e.a75=759;e.a204=759;e.a76=892;e.a77=892;e.a78=788;e.a79=784;e.a81=438;e.a82=138;e.a83=277;e.a84=415;e.a97=392;e.a98=392;e.a99=668;e.a100=668;e.a89=390;e.a90=390;e.a93=317;e.a94=317;e.a91=276;e.a92=276;e.a205=509;e.a85=509;e.a206=410;e.a86=410;e.a87=234;e.a88=234;e.a95=334;e.a96=334;e.a101=732;e.a102=544;e.a103=544;e.a104=910;e.a106=667;e.a107=760;e.a108=760;e.a112=776;e.a111=595;e.a110=694;e.a109=626;e.a120=788;e.a121=788;e.a122=788;e.a123=788;e.a124=788;e.a125=788;e.a126=788;e.a127=788;e.a128=788;e.a129=788;e.a130=788;e.a131=788;e.a132=788;e.a133=788;e.a134=788;e.a135=788;e.a136=788;e.a137=788;e.a138=788;e.a139=788;e.a140=788;e.a141=788;e.a142=788;e.a143=788;e.a144=788;e.a145=788;e.a146=788;e.a147=788;e.a148=788;e.a149=788;e.a150=788;e.a151=788;e.a152=788;e.a153=788;e.a154=788;e.a155=788;e.a156=788;e.a157=788;e.a158=788;e.a159=788;e.a160=894;e.a161=838;e.a163=1016;e.a164=458;e.a196=748;e.a165=924;e.a192=748;e.a166=918;e.a167=927;e.a168=928;e.a169=928;e.a170=834;e.a171=873;e.a172=828;e.a173=924;e.a162=924;e.a174=917;e.a175=930;e.a176=931;e.a177=463;e.a178=883;e.a179=836;e.a193=836;e.a180=867;e.a199=867;e.a181=696;e.a200=696;e.a182=874;e.a201=874;e.a183=760;e.a184=946;e.a197=771;e.a185=865;e.a194=771;e.a198=888;e.a186=967;e.a195=888;e.a187=831;e.a188=873;e.a189=927;e.a190=970;e.a191=918}))}));t.getMetrics=i},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.isPDFFunction=function(e){var t;if("object"!=typeof e)return!1;if((0,i.isDict)(e))t=e;else{if(!(0,i.isStream)(e))return!1;t=e.dict}return t.has("FunctionType")};t.PostScriptCompiler=t.PostScriptEvaluator=t.PDFFunctionFactory=void 0;var r=a(2),i=a(4),n=a(40);t.PDFFunctionFactory=class{constructor({xref:e,isEvalSupported:t=!0}){this.xref=e;this.isEvalSupported=!1!==t}create(e){return o.parse({xref:this.xref,isEvalSupported:this.isEvalSupported,fn:e})}createFromArray(e){return o.parseArray({xref:this.xref,isEvalSupported:this.isEvalSupported,fnObj:e})}};function s(e){if(!Array.isArray(e))return null;const t=e.length;for(let a=0;a<t;a++)if("number"!=typeof e[a]){const a=new Array(t);for(let r=0;r<t;r++)a[r]=+e[r];return a}return e}var o={getSampleArray(e,t,a,r){var i,n,s=1;for(i=0,n=e.length;i<n;i++)s*=e[i];s*=t;var o=new Array(s),c=0,l=0,h=1/(2**a-1),u=r.getBytes((s*a+7)/8),d=0;for(i=0;i<s;i++){for(;c<a;){l<<=8;l|=u[d++];c+=8}c-=a;o[i]=(l>>c)*h;l&=(1<<c)-1}return o},getIR({xref:e,isEvalSupported:t,fn:a}){var i=a.dict;i||(i=a);var n=[this.constructSampled,null,this.constructInterpolated,this.constructStiched,this.constructPostScript][i.get("FunctionType")];if(!n)throw new r.FormatError("Unknown type of function");return n.call(this,{xref:e,isEvalSupported:t,fn:a,dict:i})},fromIR({xref:e,isEvalSupported:t,IR:a}){switch(a[0]){case 0:return this.constructSampledFromIR({xref:e,isEvalSupported:t,IR:a});case 2:return this.constructInterpolatedFromIR({xref:e,isEvalSupported:t,IR:a});case 3:return this.constructStichedFromIR({xref:e,isEvalSupported:t,IR:a});default:return this.constructPostScriptFromIR({xref:e,isEvalSupported:t,IR:a})}},parse({xref:e,isEvalSupported:t,fn:a}){const r=this.getIR({xref:e,isEvalSupported:t,fn:a});return this.fromIR({xref:e,isEvalSupported:t,IR:r})},parseArray({xref:e,isEvalSupported:t,fnObj:a}){if(!Array.isArray(a))return this.parse({xref:e,isEvalSupported:t,fn:a});for(var r=[],i=0,n=a.length;i<n;i++)r.push(this.parse({xref:e,isEvalSupported:t,fn:e.fetchIfRef(a[i])}));return function(e,t,a,i){for(var n=0,s=r.length;n<s;n++)r[n](e,t,a,i+n)}},constructSampled({xref:e,isEvalSupported:t,fn:a,dict:i}){function n(e){for(var t=e.length,a=[],r=0,i=0;i<t;i+=2){a[r]=[e[i],e[i+1]];++r}return a}var o=s(i.getArray("Domain")),c=s(i.getArray("Range"));if(!o||!c)throw new r.FormatError("No domain or range");var l=o.length/2,h=c.length/2;o=n(o);c=n(c);var u=s(i.getArray("Size")),d=i.get("BitsPerSample"),f=i.get("Order")||1;1!==f&&(0,r.info)("No support for cubic spline interpolation: "+f);var g=s(i.getArray("Encode"));if(g)g=n(g);else{g=[];for(var m=0;m<l;++m)g.push([0,u[m]-1])}var p=s(i.getArray("Decode"));return[0,l,o,g,p=p?n(p):c,this.getSampleArray(u,h,d,a),u,h,2**d-1,c]},constructSampledFromIR({xref:e,isEvalSupported:t,IR:a}){function r(e,t,a,r,i){return r+(i-r)/(a-t)*(e-t)}return function(e,t,i,n){var s,o,c=a[1],l=a[2],h=a[3],u=a[4],d=a[5],f=a[6],g=a[7],m=a[9],p=1<<c,b=new Float64Array(p),y=new Uint32Array(p);for(o=0;o<p;o++)b[o]=1;var v=g,w=1;for(s=0;s<c;++s){var k=l[s][0],S=l[s][1],C=r(Math.min(Math.max(e[t+s],k),S),k,S,h[s][0],h[s][1]),x=f[s],A=(C=Math.min(Math.max(C,0),x-1))<x-1?Math.floor(C):C-1,I=A+1-C,F=C-A,T=A*v,E=T+v;for(o=0;o<p;o++)if(o&w){b[o]*=F;y[o]+=E}else{b[o]*=I;y[o]+=T}v*=x;w<<=1}for(o=0;o<g;++o){var O=0;for(s=0;s<p;s++)O+=d[y[s]+o]*b[s];O=r(O,0,1,u[o][0],u[o][1]);i[n+o]=Math.min(Math.max(O,m[o][0]),m[o][1])}}},constructInterpolated({xref:e,isEvalSupported:t,fn:a,dict:r}){for(var i=s(r.getArray("C0"))||[0],n=s(r.getArray("C1"))||[1],o=r.get("N"),c=i.length,l=[],h=0;h<c;++h)l.push(n[h]-i[h]);return[2,i,l,o]},constructInterpolatedFromIR({xref:e,isEvalSupported:t,IR:a}){var r=a[1],i=a[2],n=a[3],s=i.length;return function(e,t,a,o){for(var c=1===n?e[t]:e[t]**n,l=0;l<s;++l)a[o+l]=r[l]+c*i[l]}},constructStiched({xref:e,isEvalSupported:t,fn:a,dict:i}){var n=s(i.getArray("Domain"));if(!n)throw new r.FormatError("No domain");if(1!=n.length/2)throw new r.FormatError("Bad domain for stiched function");for(var o=i.get("Functions"),c=[],l=0,h=o.length;l<h;++l)c.push(this.parse({xref:e,isEvalSupported:t,fn:e.fetchIfRef(o[l])}));return[3,n,s(i.getArray("Bounds")),s(i.getArray("Encode")),c]},constructStichedFromIR({xref:e,isEvalSupported:t,IR:a}){var r=a[1],i=a[2],n=a[3],s=a[4],o=new Float32Array(1);return function(e,t,a,c){for(var l=function(e,t,a){e>a?e=a:e<t&&(e=t);return e}(e[t],r[0],r[1]),h=0,u=i.length;h<u&&!(l<i[h]);++h);var d=r[0];h>0&&(d=i[h-1]);var f=r[1];h<i.length&&(f=i[h]);var g=n[2*h],m=n[2*h+1];o[0]=d===f?g:g+(l-d)*(m-g)/(f-d);s[h](o,0,a,c)}},constructPostScript({xref:e,isEvalSupported:t,fn:a,dict:i}){var o=s(i.getArray("Domain")),c=s(i.getArray("Range"));if(!o)throw new r.FormatError("No domain.");if(!c)throw new r.FormatError("No range.");var l=new n.PostScriptLexer(a);return[4,o,c,new n.PostScriptParser(l).parse()]},constructPostScriptFromIR({xref:e,isEvalSupported:t,IR:a}){var i=a[1],n=a[2],s=a[3];if(t&&r.IsEvalSupportedCached.value){const e=(new h).compile(s,i,n);if(e)return new Function("src","srcOffset","dest","destOffset",e)}(0,r.info)("Unable to compile PS function");var o=n.length>>1,c=i.length>>1,u=new l(s),d=Object.create(null),f=8192,g=new Float32Array(c);return function(e,t,a,r){var i,s,l="",h=g;for(i=0;i<c;i++){s=e[t+i];h[i]=s;l+=s+"_"}var m=d[l];if(void 0===m){var p=new Float32Array(o),b=u.execute(h),y=b.length-o;for(i=0;i<o;i++){s=b[y+i];var v=n[2*i];(s<v||s>(v=n[2*i+1]))&&(s=v);p[i]=s}if(f>0){f--;d[l]=p}a.set(p,r)}else a.set(m,r)}}};var c=function(){function e(e){this.stack=e?Array.prototype.slice.call(e,0):[]}e.prototype={push:function(e){if(this.stack.length>=100)throw new Error("PostScript function stack overflow.");this.stack.push(e)},pop:function(){if(this.stack.length<=0)throw new Error("PostScript function stack underflow.");return this.stack.pop()},copy:function(e){if(this.stack.length+e>=100)throw new Error("PostScript function stack overflow.");for(var t=this.stack,a=t.length-e,r=e-1;r>=0;r--,a++)t.push(t[a])},index:function(e){this.push(this.stack[this.stack.length-e-1])},roll:function(e,t){var a,r,i,n=this.stack,s=n.length-e,o=n.length-1,c=s+(t-Math.floor(t/e)*e);for(a=s,r=o;a<r;a++,r--){i=n[a];n[a]=n[r];n[r]=i}for(a=s,r=c-1;a<r;a++,r--){i=n[a];n[a]=n[r];n[r]=i}for(a=c,r=o;a<r;a++,r--){i=n[a];n[a]=n[r];n[r]=i}}};return e}(),l=function(){function e(e){this.operators=e}e.prototype={execute:function(e){for(var t,a,i,n=new c(e),s=0,o=this.operators,l=o.length;s<l;)if("number"!=typeof(t=o[s++]))switch(t){case"jz":i=n.pop();(a=n.pop())||(s=i);break;case"j":s=a=n.pop();break;case"abs":a=n.pop();n.push(Math.abs(a));break;case"add":i=n.pop();a=n.pop();n.push(a+i);break;case"and":i=n.pop();a=n.pop();(0,r.isBool)(a)&&(0,r.isBool)(i)?n.push(a&&i):n.push(a&i);break;case"atan":a=n.pop();n.push(Math.atan(a));break;case"bitshift":i=n.pop();(a=n.pop())>0?n.push(a<<i):n.push(a>>i);break;case"ceiling":a=n.pop();n.push(Math.ceil(a));break;case"copy":a=n.pop();n.copy(a);break;case"cos":a=n.pop();n.push(Math.cos(a));break;case"cvi":a=0|n.pop();n.push(a);break;case"cvr":break;case"div":i=n.pop();a=n.pop();n.push(a/i);break;case"dup":n.copy(1);break;case"eq":i=n.pop();a=n.pop();n.push(a===i);break;case"exch":n.roll(2,1);break;case"exp":i=n.pop();a=n.pop();n.push(a**i);break;case"false":n.push(!1);break;case"floor":a=n.pop();n.push(Math.floor(a));break;case"ge":i=n.pop();a=n.pop();n.push(a>=i);break;case"gt":i=n.pop();a=n.pop();n.push(a>i);break;case"idiv":i=n.pop();a=n.pop();n.push(a/i|0);break;case"index":a=n.pop();n.index(a);break;case"le":i=n.pop();a=n.pop();n.push(a<=i);break;case"ln":a=n.pop();n.push(Math.log(a));break;case"log":a=n.pop();n.push(Math.log(a)/Math.LN10);break;case"lt":i=n.pop();a=n.pop();n.push(a<i);break;case"mod":i=n.pop();a=n.pop();n.push(a%i);break;case"mul":i=n.pop();a=n.pop();n.push(a*i);break;case"ne":i=n.pop();a=n.pop();n.push(a!==i);break;case"neg":a=n.pop();n.push(-a);break;case"not":a=n.pop();(0,r.isBool)(a)?n.push(!a):n.push(~a);break;case"or":i=n.pop();a=n.pop();(0,r.isBool)(a)&&(0,r.isBool)(i)?n.push(a||i):n.push(a|i);break;case"pop":n.pop();break;case"roll":i=n.pop();a=n.pop();n.roll(a,i);break;case"round":a=n.pop();n.push(Math.round(a));break;case"sin":a=n.pop();n.push(Math.sin(a));break;case"sqrt":a=n.pop();n.push(Math.sqrt(a));break;case"sub":i=n.pop();a=n.pop();n.push(a-i);break;case"true":n.push(!0);break;case"truncate":a=(a=n.pop())<0?Math.ceil(a):Math.floor(a);n.push(a);break;case"xor":i=n.pop();a=n.pop();(0,r.isBool)(a)&&(0,r.isBool)(i)?n.push(a!==i):n.push(a^i);break;default:throw new r.FormatError(`Unknown operator ${t}`)}else n.push(t);return n.stack}};return e}();t.PostScriptEvaluator=l;var h=function(){function e(e){this.type=e}e.prototype.visit=function(e){(0,r.unreachable)("abstract method")};function t(t,a,r){e.call(this,"args");this.index=t;this.min=a;this.max=r}t.prototype=Object.create(e.prototype);t.prototype.visit=function(e){e.visitArgument(this)};function a(t){e.call(this,"literal");this.number=t;this.min=t;this.max=t}a.prototype=Object.create(e.prototype);a.prototype.visit=function(e){e.visitLiteral(this)};function i(t,a,r,i,n){e.call(this,"binary");this.op=t;this.arg1=a;this.arg2=r;this.min=i;this.max=n}i.prototype=Object.create(e.prototype);i.prototype.visit=function(e){e.visitBinaryOperation(this)};function n(t,a){e.call(this,"max");this.arg=t;this.min=t.min;this.max=a}n.prototype=Object.create(e.prototype);n.prototype.visit=function(e){e.visitMin(this)};function s(t,a,r){e.call(this,"var");this.index=t;this.min=a;this.max=r}s.prototype=Object.create(e.prototype);s.prototype.visit=function(e){e.visitVariable(this)};function o(t,a){e.call(this,"definition");this.variable=t;this.arg=a}o.prototype=Object.create(e.prototype);o.prototype.visit=function(e){e.visitVariableDefinition(this)};function c(){this.parts=[]}c.prototype={visitArgument(e){this.parts.push("Math.max(",e.min,", Math.min(",e.max,", src[srcOffset + ",e.index,"]))")},visitVariable(e){this.parts.push("v",e.index)},visitLiteral(e){this.parts.push(e.number)},visitBinaryOperation(e){this.parts.push("(");e.arg1.visit(this);this.parts.push(" ",e.op," ");e.arg2.visit(this);this.parts.push(")")},visitVariableDefinition(e){this.parts.push("var ");e.variable.visit(this);this.parts.push(" = ");e.arg.visit(this);this.parts.push(";")},visitMin(e){this.parts.push("Math.min(");e.arg.visit(this);this.parts.push(", ",e.max,")")},toString(){return this.parts.join("")}};function l(e,t){return"literal"===t.type&&0===t.number?e:"literal"===e.type&&0===e.number?t:"literal"===t.type&&"literal"===e.type?new a(e.number+t.number):new i("+",e,t,e.min+t.min,e.max+t.max)}function h(e,t){if("literal"===t.type){if(0===t.number)return new a(0);if(1===t.number)return e;if("literal"===e.type)return new a(e.number*t.number)}if("literal"===e.type){if(0===e.number)return new a(0);if(1===e.number)return t}return new i("*",e,t,Math.min(e.min*t.min,e.min*t.max,e.max*t.min,e.max*t.max),Math.max(e.min*t.min,e.min*t.max,e.max*t.min,e.max*t.max))}function u(e,t){if("literal"===t.type){if(0===t.number)return e;if("literal"===e.type)return new a(e.number-t.number)}return"binary"===t.type&&"-"===t.op&&"literal"===e.type&&1===e.number&&"literal"===t.arg1.type&&1===t.arg1.number?t.arg2:new i("-",e,t,e.min-t.max,e.max-t.min)}function d(e,t){return e.min>=t?new a(t):e.max<=t?e:new n(e,t)}function f(){}f.prototype={compile:function(e,r,i){var n,f,g,m,p,b,y,v,w,k,S=[],C=[],x=r.length>>1,A=i.length>>1,I=0;for(n=0;n<x;n++)S.push(new t(n,r[2*n],r[2*n+1]));for(n=0,f=e.length;n<f;n++)if("number"!=typeof(k=e[n]))switch(k){case"add":if(S.length<2)return null;b=S.pop();p=S.pop();S.push(l(p,b));break;case"cvr":if(S.length<1)return null;break;case"mul":if(S.length<2)return null;b=S.pop();p=S.pop();S.push(h(p,b));break;case"sub":if(S.length<2)return null;b=S.pop();p=S.pop();S.push(u(p,b));break;case"exch":if(S.length<2)return null;y=S.pop();v=S.pop();S.push(y,v);break;case"pop":if(S.length<1)return null;S.pop();break;case"index":if(S.length<1)return null;if("literal"!==(p=S.pop()).type)return null;if((g=p.number)<0||!Number.isInteger(g)||S.length<g)return null;if("literal"===(y=S[S.length-g-1]).type||"var"===y.type){S.push(y);break}w=new s(I++,y.min,y.max);S[S.length-g-1]=w;S.push(w);C.push(new o(w,y));break;case"dup":if(S.length<1)return null;if("number"==typeof e[n+1]&&"gt"===e[n+2]&&e[n+3]===n+7&&"jz"===e[n+4]&&"pop"===e[n+5]&&e[n+6]===e[n+1]){p=S.pop();S.push(d(p,e[n+1]));n+=6;break}if("literal"===(y=S[S.length-1]).type||"var"===y.type){S.push(y);break}w=new s(I++,y.min,y.max);S[S.length-1]=w;S.push(w);C.push(new o(w,y));break;case"roll":if(S.length<2)return null;b=S.pop();p=S.pop();if("literal"!==b.type||"literal"!==p.type)return null;m=b.number;if((g=p.number)<=0||!Number.isInteger(g)||!Number.isInteger(m)||S.length<g)return null;if(0===(m=(m%g+g)%g))break;Array.prototype.push.apply(S,S.splice(S.length-g,g-m));break;default:return null}else S.push(new a(k));if(S.length!==A)return null;var F=[];C.forEach((function(e){var t=new c;e.visit(t);F.push(t.toString())}));S.forEach((function(e,t){var a=new c;e.visit(a);var r=i[2*t],n=i[2*t+1],s=[a.toString()];if(r>e.min){s.unshift("Math.max(",r,", ");s.push(")")}if(n<e.max){s.unshift("Math.min(",n,", ");s.push(")")}s.unshift("dest[destOffset + ",t,"] = ");s.push(";");F.push(s.join(""))}));return F.join("\n")}};return f}();t.PostScriptCompiler=h},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PostScriptParser=t.PostScriptLexer=void 0;var r=a(2),i=a(4),n=a(7);t.PostScriptParser=class{constructor(e){this.lexer=e;this.operators=[];this.token=null;this.prev=null}nextToken(){this.prev=this.token;this.token=this.lexer.getToken()}accept(e){if(this.token.type===e){this.nextToken();return!0}return!1}expect(e){if(this.accept(e))return!0;throw new r.FormatError(`Unexpected symbol: found ${this.token.type} expected ${e}.`)}parse(){this.nextToken();this.expect(s.LBRACE);this.parseBlock();this.expect(s.RBRACE);return this.operators}parseBlock(){for(;;)if(this.accept(s.NUMBER))this.operators.push(this.prev.value);else if(this.accept(s.OPERATOR))this.operators.push(this.prev.value);else{if(!this.accept(s.LBRACE))return;this.parseCondition()}}parseCondition(){const e=this.operators.length;this.operators.push(null,null);this.parseBlock();this.expect(s.RBRACE);if(this.accept(s.IF)){this.operators[e]=this.operators.length;this.operators[e+1]="jz"}else{if(!this.accept(s.LBRACE))throw new r.FormatError("PS Function: error parsing conditional.");{const t=this.operators.length;this.operators.push(null,null);const a=this.operators.length;this.parseBlock();this.expect(s.RBRACE);this.expect(s.IFELSE);this.operators[t]=this.operators.length;this.operators[t+1]="j";this.operators[e]=a;this.operators[e+1]="jz"}}}};const s={LBRACE:0,RBRACE:1,NUMBER:2,OPERATOR:3,IF:4,IFELSE:5},o=function(){const e=Object.create(null);class t{constructor(e,t){this.type=e;this.value=t}static getOperator(a){const r=e[a];return r||(e[a]=new t(s.OPERATOR,a))}static get LBRACE(){return(0,r.shadow)(this,"LBRACE",new t(s.LBRACE,"{"))}static get RBRACE(){return(0,r.shadow)(this,"RBRACE",new t(s.RBRACE,"}"))}static get IF(){return(0,r.shadow)(this,"IF",new t(s.IF,"IF"))}static get IFELSE(){return(0,r.shadow)(this,"IFELSE",new t(s.IFELSE,"IFELSE"))}}return t}();t.PostScriptLexer=class{constructor(e){this.stream=e;this.nextChar();this.strBuf=[]}nextChar(){return this.currentChar=this.stream.getByte()}getToken(){let e=!1,t=this.currentChar;for(;;){if(t<0)return i.EOF;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(!(0,n.isWhiteSpace)(t))break;t=this.nextChar()}switch(0|t){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return new o(s.NUMBER,this.getNumber());case 123:this.nextChar();return o.LBRACE;case 125:this.nextChar();return o.RBRACE}const a=this.strBuf;a.length=0;a[0]=String.fromCharCode(t);for(;(t=this.nextChar())>=0&&(t>=65&&t<=90||t>=97&&t<=122);)a.push(String.fromCharCode(t));const r=a.join("");switch(r.toLowerCase()){case"if":return o.IF;case"ifelse":return o.IFELSE;default:return o.getOperator(r)}}getNumber(){let e=this.currentChar;const t=this.strBuf;t.length=0;t[0]=String.fromCharCode(e);for(;(e=this.nextChar())>=0&&(e>=48&&e<=57||45===e||46===e);)t.push(String.fromCharCode(e));const a=parseFloat(t.join(""));if(isNaN(a))throw new r.FormatError(`Invalid floating point number: ${a}`);return a}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.MurmurHash3_64=void 0;var r=a(2);t.MurmurHash3_64=class{constructor(e){this.h1=e?4294967295&e:3285377520;this.h2=e?4294967295&e:3285377520}update(e){let t,a;if((0,r.isString)(e)){t=new Uint8Array(2*e.length);a=0;for(let r=0,i=e.length;r<i;r++){const i=e.charCodeAt(r);if(i<=255)t[a++]=i;else{t[a++]=i>>>8;t[a++]=255&i}}}else{if(!(0,r.isArrayBuffer)(e))throw new Error("Wrong data format in MurmurHash3_64_update. Input must be a string or array.");t=e;a=t.byteLength}const i=a>>2,n=a-4*i,s=new Uint32Array(t.buffer,0,i);let o=0,c=0,l=this.h1,h=this.h2;const u=3432918353,d=461845907;for(let e=0;e<i;e++)if(1&e){o=s[e];o=o*u&4294901760|11601*o&65535;o=o<<15|o>>>17;o=o*d&4294901760|13715*o&65535;l^=o;l=l<<13|l>>>19;l=5*l+3864292196}else{c=s[e];c=c*u&4294901760|11601*c&65535;c=c<<15|c>>>17;c=c*d&4294901760|13715*c&65535;h^=c;h=h<<13|h>>>19;h=5*h+3864292196}o=0;switch(n){case 3:o^=t[4*i+2]<<16;case 2:o^=t[4*i+1]<<8;case 1:o^=t[4*i];o=o*u&4294901760|11601*o&65535;o=o<<15|o>>>17;o=o*d&4294901760|13715*o&65535;1&i?l^=o:h^=o}this.h1=l;this.h2=h}hexdigest(){let e=this.h1,t=this.h2;e^=t>>>1;e=3981806797*e&4294901760|36045*e&65535;t=4283543511*t&4294901760|(2950163797*(t<<16|e>>>16)&4294901760)>>>16;e^=t>>>1;e=444984403*e&4294901760|60499*e&65535;t=3301882366*t&4294901760|(3120437893*(t<<16|e>>>16)&4294901760)>>>16;e^=t>>>1;const a=(e>>>0).toString(16),r=(t>>>0).toString(16);return a.padStart(8,"0")+r.padStart(8,"0")}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.NativeImageDecoder=void 0;var r=a(22),i=a(17),n=a(11);class s{constructor({xref:e,resources:t,handler:a,forceDataSchema:r=!1,pdfFunctionFactory:i}){this.xref=e;this.resources=t;this.handler=a;this.forceDataSchema=r;this.pdfFunctionFactory=i}canDecode(e){return e instanceof i.JpegStream&&s.isDecodable(e,this.xref,this.resources,this.pdfFunctionFactory)&&e.maybeValidDimensions}decode(e){const t=e.dict;let a=t.get("ColorSpace","CS");a=r.ColorSpace.parse(a,this.xref,this.resources,this.pdfFunctionFactory);return this.handler.sendWithPromise("JpegDecode",[e.getIR(this.forceDataSchema),a.numComps]).then((function({data:e,width:a,height:r}){return new n.Stream(e,0,e.length,t)}))}static isSupported(e,t,a,i){const n=e.dict;if(n.has("DecodeParms")||n.has("DP"))return!1;const s=r.ColorSpace.parse(n.get("ColorSpace","CS"),t,a,i);return("DeviceGray"===s.name||"DeviceRGB"===s.name)&&s.isDefaultDecode(n.getArray("Decode","D"))}static isDecodable(e,t,a,i){const n=e.dict;if(n.has("DecodeParms")||n.has("DP"))return!1;const s=r.ColorSpace.parse(n.get("ColorSpace","CS"),t,a,i),o=n.get("BitsPerComponent","BPC")||1;return(1===s.numComps||3===s.numComps)&&s.isDefaultDecode(n.getArray("Decode","D"),o)}}t.NativeImageDecoder=s},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PDFImage=void 0;var r=a(2),i=a(4),n=a(22),s=a(11),o=a(17),c=a(20),l=function(){function e(e,t){return t&&t.canDecode(e)?t.decode(e).catch(t=>{(0,r.warn)("Native image decoding failed -- trying to recover: "+(t&&t.message));return e}):Promise.resolve(e)}function t(e,t,a,r){(e=t+e*a)<0?e=0:e>r&&(e=r);return e}function a(e,t,a,r,i,n){var s=i*n;let o;o=t<=8?new Uint8Array(s):t<=16?new Uint16Array(s):new Uint32Array(s);var c,l,h,u,d=a/i,f=r/n,g=0,m=new Uint16Array(i),p=a;for(c=0;c<i;c++)m[c]=Math.floor(c*d);for(c=0;c<n;c++){h=Math.floor(c*f)*p;for(l=0;l<i;l++){u=h+m[l];o[g++]=e[u]}}return o}function l({xref:e,res:t,image:a,isInline:s=!1,smask:o=null,mask:h=null,isMask:u=!1,pdfFunctionFactory:d}){this.image=a;var f=a.dict;const g=f.get("Filter");if((0,i.isName)(g))switch(g.name){case"JPXDecode":var m=new c.JpxImage;m.parseImageProperties(a.stream);a.stream.reset();a.width=m.width;a.height=m.height;a.bitsPerComponent=m.bitsPerComponent;a.numComps=m.componentsCount;break;case"JBIG2Decode":a.bitsPerComponent=1;a.numComps=1}let p=f.get("Width","W"),b=f.get("Height","H");if(Number.isInteger(a.width)&&a.width>0&&Number.isInteger(a.height)&&a.height>0&&(a.width!==p||a.height!==b)){(0,r.warn)("PDFImage - using the Width/Height of the image data, rather than the image dictionary.");p=a.width;b=a.height}if(p<1||b<1)throw new r.FormatError(`Invalid image width: ${p} or height: ${b}`);this.width=p;this.height=b;this.interpolate=f.get("Interpolate","I")||!1;this.imageMask=f.get("ImageMask","IM")||!1;this.matte=f.get("Matte")||!1;var y=a.bitsPerComponent;if(!y&&!(y=f.get("BitsPerComponent","BPC"))){if(!this.imageMask)throw new r.FormatError(`Bits per component missing in image: ${this.imageMask}`);y=1}this.bpc=y;if(!this.imageMask){var v=f.get("ColorSpace","CS");if(!v){(0,r.info)("JPX images (which do not require color spaces)");switch(a.numComps){case 1:v=i.Name.get("DeviceGray");break;case 3:v=i.Name.get("DeviceRGB");break;case 4:v=i.Name.get("DeviceCMYK");break;default:throw new Error(`JPX images with ${a.numComps} `+"color components not supported.")}}const o=s?t:null;this.colorSpace=n.ColorSpace.parse(v,e,o,d);this.numComps=this.colorSpace.numComps}this.decode=f.getArray("Decode","D");this.needsDecode=!1;if(this.decode&&(this.colorSpace&&!this.colorSpace.isDefaultDecode(this.decode,y)||u&&!n.ColorSpace.isDefaultDecode(this.decode,1))){this.needsDecode=!0;var w=(1<<y)-1;this.decodeCoefficients=[];this.decodeAddends=[];const e=this.colorSpace&&"Indexed"===this.colorSpace.name;for(var k=0,S=0;k<this.decode.length;k+=2,++S){var C=this.decode[k],x=this.decode[k+1];this.decodeCoefficients[S]=e?(x-C)/w:x-C;this.decodeAddends[S]=e?C:w*C}}if(o)this.smask=new l({xref:e,res:t,image:o,isInline:s,pdfFunctionFactory:d});else if(h)if((0,i.isStream)(h)){h.dict.get("ImageMask","IM")?this.mask=new l({xref:e,res:t,image:h,isInline:s,isMask:!0,pdfFunctionFactory:d}):(0,r.warn)("Ignoring /Mask in image without /ImageMask.")}else this.mask=h}l.buildImage=function({handler:t,xref:a,res:n,image:s,isInline:o=!1,nativeDecoder:c=null,pdfFunctionFactory:h}){var u,d,f=e(s,c),g=s.dict.get("SMask"),m=s.dict.get("Mask");if(g){u=e(g,c);d=Promise.resolve(null)}else{u=Promise.resolve(null);if(m)if((0,i.isStream)(m))d=e(m,c);else if(Array.isArray(m))d=Promise.resolve(m);else{(0,r.warn)("Unsupported mask format.");d=Promise.resolve(null)}else d=Promise.resolve(null)}return Promise.all([f,u,d]).then((function([e,t,r]){return new l({xref:a,res:n,image:e,isInline:o,smask:t,mask:r,pdfFunctionFactory:h})}))};l.createMask=function({imgArray:e,width:t,height:a,imageIsFromDecodeStream:r,inverseDecode:i}){var n,s,o=(t+7>>3)*a,c=e.byteLength;if(!r||i&&!(o===c))if(i){(n=new Uint8ClampedArray(o)).set(e);for(s=c;s<o;s++)n[s]=255}else(n=new Uint8ClampedArray(c)).set(e);else n=e;if(i)for(s=0;s<c;s++)n[s]^=255;return{data:n,width:t,height:a}};l.prototype={get drawWidth(){return Math.max(this.width,this.smask&&this.smask.width||0,this.mask&&this.mask.width||0)},get drawHeight(){return Math.max(this.height,this.smask&&this.smask.height||0,this.mask&&this.mask.height||0)},decodeBuffer(e){var a,r,i=this.bpc,n=this.numComps,s=this.decodeAddends,o=this.decodeCoefficients,c=(1<<i)-1;if(1!==i){var l=0;for(a=0,r=this.width*this.height;a<r;a++)for(var h=0;h<n;h++){e[l]=t(e[l],s[h],o[h],c);l++}}else for(a=0,r=e.length;a<r;a++)e[a]=+!e[a]},getComponents(e){var t=this.bpc;if(8===t)return e;var a=this.width,r=this.height,i=this.numComps,n=a*r*i,s=0;let o;o=t<=8?new Uint8Array(n):t<=16?new Uint16Array(n):new Uint32Array(n);var c,l,h=a*i,u=(1<<t)-1,d=0;if(1===t)for(var f,g,m,p=0;p<r;p++){g=d+(-8&h);m=d+h;for(;d<g;){l=e[s++];o[d]=l>>7&1;o[d+1]=l>>6&1;o[d+2]=l>>5&1;o[d+3]=l>>4&1;o[d+4]=l>>3&1;o[d+5]=l>>2&1;o[d+6]=l>>1&1;o[d+7]=1&l;d+=8}if(d<m){l=e[s++];f=128;for(;d<m;){o[d++]=+!!(l&f);f>>=1}}}else{var b=0;l=0;for(d=0,c=n;d<c;++d){if(d%h==0){l=0;b=0}for(;b<t;){l=l<<8|e[s++];b+=8}var y=b-t;let a=l>>y;a<0?a=0:a>u&&(a=u);o[d]=a;l&=(1<<y)-1;b=y}}return o},fillOpacity(e,t,i,n,s){var o,c,h,u,d,f,g=this.smask,m=this.mask;if(g){c=g.width;h=g.height;o=new Uint8ClampedArray(c*h);g.fillGrayBuffer(o);c===t&&h===i||(o=a(o,g.bpc,c,h,t,i))}else if(m)if(m instanceof l){c=m.width;h=m.height;o=new Uint8ClampedArray(c*h);m.numComps=1;m.fillGrayBuffer(o);for(u=0,d=c*h;u<d;++u)o[u]=255-o[u];c===t&&h===i||(o=a(o,m.bpc,c,h,t,i))}else{if(!Array.isArray(m))throw new r.FormatError("Unknown mask format.");o=new Uint8ClampedArray(t*i);var p=this.numComps;for(u=0,d=t*i;u<d;++u){var b=0,y=u*p;for(f=0;f<p;++f){var v=s[y+f],w=2*f;if(v<m[w]||v>m[w+1]){b=255;break}}o[u]=b}}if(o)for(u=0,f=3,d=t*n;u<d;++u,f+=4)e[f]=o[u];else for(u=0,f=3,d=t*n;u<d;++u,f+=4)e[f]=255},undoPreblend(e,t,a){var r=this.smask&&this.smask.matte;if(r)for(var i=this.colorSpace.getRgb(r,0),n=i[0],s=i[1],o=i[2],c=t*a*4,l=0;l<c;l+=4){var h=e[l+3];if(0!==h){var u=255/h;e[l]=(e[l]-n)*u+n;e[l+1]=(e[l+1]-s)*u+s;e[l+2]=(e[l+2]-o)*u+o}else{e[l]=255;e[l+1]=255;e[l+2]=255}}},createImageData(e=!1){var t,a=this.drawWidth,i=this.drawHeight,n={width:a,height:i,kind:0,data:null},c=this.numComps,l=this.width,h=this.height,u=this.bpc,d=l*c*u+7>>3;if(!e){var f;"DeviceGray"===this.colorSpace.name&&1===u?f=r.ImageKind.GRAYSCALE_1BPP:"DeviceRGB"!==this.colorSpace.name||8!==u||this.needsDecode||(f=r.ImageKind.RGB_24BPP);if(f&&!this.smask&&!this.mask&&a===l&&i===h){n.kind=f;t=this.getImageBytes(h*d);if(this.image instanceof s.DecodeStream)n.data=t;else{var g=new Uint8ClampedArray(t.length);g.set(t);n.data=g}if(this.needsDecode){(0,r.assert)(f===r.ImageKind.GRAYSCALE_1BPP,"PDFImage.createImageData: The image must be grayscale.");for(var m=n.data,p=0,b=m.length;p<b;p++)m[p]^=255}return n}if(this.image instanceof o.JpegStream&&!this.smask&&!this.mask){let e=h*d;switch(this.colorSpace.name){case"DeviceGray":e*=3;case"DeviceRGB":case"DeviceCMYK":n.kind=r.ImageKind.RGB_24BPP;n.data=this.getImageBytes(e,a,i,!0);return n}}}var y,v,w=0|(t=this.getImageBytes(h*d)).length/d*i/h,k=this.getComponents(t);if(e||this.smask||this.mask){n.kind=r.ImageKind.RGBA_32BPP;n.data=new Uint8ClampedArray(a*i*4);y=1;v=!0;this.fillOpacity(n.data,a,i,w,k)}else{n.kind=r.ImageKind.RGB_24BPP;n.data=new Uint8ClampedArray(a*i*3);y=0;v=!1}this.needsDecode&&this.decodeBuffer(k);this.colorSpace.fillRgb(n.data,l,h,a,i,w,u,k,y);v&&this.undoPreblend(n.data,a,w);return n},fillGrayBuffer(e){var t=this.numComps;if(1!==t)throw new r.FormatError(`Reading gray scale from a color image: ${t}`);var a,i,n=this.width,s=this.height,o=this.bpc,c=n*t*o+7>>3,l=this.getImageBytes(s*c),h=this.getComponents(l);if(1!==o){this.needsDecode&&this.decodeBuffer(h);i=n*s;var u=255/((1<<o)-1);for(a=0;a<i;++a)e[a]=u*h[a]}else{i=n*s;if(this.needsDecode)for(a=0;a<i;++a)e[a]=h[a]-1&255;else for(a=0;a<i;++a)e[a]=255&-h[a]}},getImageBytes(e,t,a,r=!1){this.image.reset();this.image.drawWidth=t||this.width;this.image.drawHeight=a||this.height;this.image.forceRGB=!!r;return this.image.getBytes(e,!0)}};return l}();t.PDFImage=l},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.isNodeJS=void 0;const r="object"==typeof process&&process+""=="[object process]"&&!process.versions.nw&&!process.versions.electron;t.isNodeJS=r},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.MessageHandler=void 0;var r=a(2);const i=1,n=2,s=1,o=2,c=3,l=4,h=5,u=6,d=7,f=8;function g(e){if("object"!=typeof e||null===e)return e;switch(e.name){case"AbortException":return new r.AbortException(e.message);case"MissingPDFException":return new r.MissingPDFException(e.message);case"UnexpectedResponseException":return new r.UnexpectedResponseException(e.message,e.status);case"UnknownErrorException":return new r.UnknownErrorException(e.message,e.details);default:return new r.UnknownErrorException(e.message,e.toString())}}t.MessageHandler=class{constructor(e,t,a){this.sourceName=e;this.targetName=t;this.comObj=a;this.callbackId=1;this.streamId=1;this.postMessageTransfers=!0;this.streamSinks=Object.create(null);this.streamControllers=Object.create(null);this.callbackCapabilities=Object.create(null);this.actionHandler=Object.create(null);this._onComObjOnMessage=e=>{const t=e.data;if(t.targetName!==this.sourceName)return;if(t.stream){this._processStreamMessage(t);return}if(t.callback){const e=t.callbackId,a=this.callbackCapabilities[e];if(!a)throw new Error(`Cannot resolve callback ${e}`);delete this.callbackCapabilities[e];if(t.callback===i)a.resolve(t.data);else{if(t.callback!==n)throw new Error("Unexpected callback case");a.reject(g(t.reason))}return}const r=this.actionHandler[t.action];if(!r)throw new Error(`Unknown action from worker: ${t.action}`);if(t.callbackId){const e=this.sourceName,s=t.sourceName;new Promise((function(e){e(r(t.data))})).then((function(r){a.postMessage({sourceName:e,targetName:s,callback:i,callbackId:t.callbackId,data:r})}),(function(r){a.postMessage({sourceName:e,targetName:s,callback:n,callbackId:t.callbackId,reason:g(r)})}))}else t.streamId?this._createStreamSink(t):r(t.data)};a.addEventListener("message",this._onComObjOnMessage)}on(e,t){const a=this.actionHandler;if(a[e])throw new Error(`There is already an actionName called "${e}"`);a[e]=t}send(e,t,a){this._postMessage({sourceName:this.sourceName,targetName:this.targetName,action:e,data:t},a)}sendWithPromise(e,t,a){const i=this.callbackId++,n=(0,r.createPromiseCapability)();this.callbackCapabilities[i]=n;try{this._postMessage({sourceName:this.sourceName,targetName:this.targetName,action:e,callbackId:i,data:t},a)}catch(e){n.reject(e)}return n.promise}sendWithStream(e,t,a,i){const n=this.streamId++,o=this.sourceName,c=this.targetName,l=this.comObj;return new ReadableStream({start:a=>{const s=(0,r.createPromiseCapability)();this.streamControllers[n]={controller:a,startCall:s,pullCall:null,cancelCall:null,isClosed:!1};this._postMessage({sourceName:o,targetName:c,action:e,streamId:n,data:t,desiredSize:a.desiredSize},i);return s.promise},pull:e=>{const t=(0,r.createPromiseCapability)();this.streamControllers[n].pullCall=t;l.postMessage({sourceName:o,targetName:c,stream:u,streamId:n,desiredSize:e.desiredSize});return t.promise},cancel:e=>{(0,r.assert)(e instanceof Error,"cancel must have a valid reason");const t=(0,r.createPromiseCapability)();this.streamControllers[n].cancelCall=t;this.streamControllers[n].isClosed=!0;l.postMessage({sourceName:o,targetName:c,stream:s,streamId:n,reason:g(e)});return t.promise}},a)}_createStreamSink(e){const t=this,a=this.actionHandler[e.action],i=e.streamId,n=this.sourceName,s=e.sourceName,o=this.comObj,u={enqueue(e,a=1,o){if(this.isCancelled)return;const c=this.desiredSize;this.desiredSize-=a;if(c>0&&this.desiredSize<=0){this.sinkCapability=(0,r.createPromiseCapability)();this.ready=this.sinkCapability.promise}t._postMessage({sourceName:n,targetName:s,stream:l,streamId:i,chunk:e},o)},close(){if(!this.isCancelled){this.isCancelled=!0;o.postMessage({sourceName:n,targetName:s,stream:c,streamId:i});delete t.streamSinks[i]}},error(e){(0,r.assert)(e instanceof Error,"error must have a valid reason");if(!this.isCancelled){this.isCancelled=!0;o.postMessage({sourceName:n,targetName:s,stream:h,streamId:i,reason:g(e)})}},sinkCapability:(0,r.createPromiseCapability)(),onPull:null,onCancel:null,isCancelled:!1,desiredSize:e.desiredSize,ready:null};u.sinkCapability.resolve();u.ready=u.sinkCapability.promise;this.streamSinks[i]=u;new Promise((function(t){t(a(e.data,u))})).then((function(){o.postMessage({sourceName:n,targetName:s,stream:f,streamId:i,success:!0})}),(function(e){o.postMessage({sourceName:n,targetName:s,stream:f,streamId:i,reason:g(e)})}))}_processStreamMessage(e){const t=e.streamId,a=this.sourceName,i=e.sourceName,n=this.comObj;switch(e.stream){case f:e.success?this.streamControllers[t].startCall.resolve():this.streamControllers[t].startCall.reject(g(e.reason));break;case d:e.success?this.streamControllers[t].pullCall.resolve():this.streamControllers[t].pullCall.reject(g(e.reason));break;case u:if(!this.streamSinks[t]){n.postMessage({sourceName:a,targetName:i,stream:d,streamId:t,success:!0});break}this.streamSinks[t].desiredSize<=0&&e.desiredSize>0&&this.streamSinks[t].sinkCapability.resolve();this.streamSinks[t].desiredSize=e.desiredSize;const{onPull:m}=this.streamSinks[e.streamId];new Promise((function(e){e(m&&m())})).then((function(){n.postMessage({sourceName:a,targetName:i,stream:d,streamId:t,success:!0})}),(function(e){n.postMessage({sourceName:a,targetName:i,stream:d,streamId:t,reason:g(e)})}));break;case l:(0,r.assert)(this.streamControllers[t],"enqueue should have stream controller");if(this.streamControllers[t].isClosed)break;this.streamControllers[t].controller.enqueue(e.chunk);break;case c:(0,r.assert)(this.streamControllers[t],"close should have stream controller");if(this.streamControllers[t].isClosed)break;this.streamControllers[t].isClosed=!0;this.streamControllers[t].controller.close();this._deleteStreamController(t);break;case h:(0,r.assert)(this.streamControllers[t],"error should have stream controller");this.streamControllers[t].controller.error(g(e.reason));this._deleteStreamController(t);break;case o:e.success?this.streamControllers[t].cancelCall.resolve():this.streamControllers[t].cancelCall.reject(g(e.reason));this._deleteStreamController(t);break;case s:if(!this.streamSinks[t])break;const{onCancel:p}=this.streamSinks[e.streamId];new Promise((function(t){t(p&&p(g(e.reason)))})).then((function(){n.postMessage({sourceName:a,targetName:i,stream:o,streamId:t,success:!0})}),(function(e){n.postMessage({sourceName:a,targetName:i,stream:o,streamId:t,reason:g(e)})}));this.streamSinks[t].sinkCapability.reject(g(e.reason));this.streamSinks[t].isCancelled=!0;delete this.streamSinks[t];break;default:throw new Error("Unexpected stream case")}}async _deleteStreamController(e){await Promise.allSettled([this.streamControllers[e].startCall,this.streamControllers[e].pullCall,this.streamControllers[e].cancelCall].map((function(e){return e&&e.promise})));delete this.streamControllers[e]}_postMessage(e,t){t&&this.postMessageTransfers?this.comObj.postMessage(e,t):this.comObj.postMessage(e)}destroy(){this.comObj.removeEventListener("message",this._onComObjOnMessage)}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.PDFWorkerStream=void 0;var r=a(2);t.PDFWorkerStream=class{constructor(e){this._msgHandler=e;this._contentLength=null;this._fullRequestReader=null;this._rangeRequestReaders=[]}getFullReader(){(0,r.assert)(!this._fullRequestReader);this._fullRequestReader=new i(this._msgHandler);return this._fullRequestReader}getRangeReader(e,t){const a=new n(e,t,this._msgHandler);this._rangeRequestReaders.push(a);return a}cancelAllRequests(e){this._fullRequestReader&&this._fullRequestReader.cancel(e);this._rangeRequestReaders.slice(0).forEach((function(t){t.cancel(e)}))}};class i{constructor(e){this._msgHandler=e;this.onProgress=null;this._contentLength=null;this._isRangeSupported=!1;this._isStreamingSupported=!1;const t=this._msgHandler.sendWithStream("GetReader");this._reader=t.getReader();this._headersReady=this._msgHandler.sendWithPromise("ReaderHeadersReady").then(e=>{this._isStreamingSupported=e.isStreamingSupported;this._isRangeSupported=e.isRangeSupported;this._contentLength=e.contentLength})}get headersReady(){return this._headersReady}get contentLength(){return this._contentLength}get isStreamingSupported(){return this._isStreamingSupported}get isRangeSupported(){return this._isRangeSupported}async read(){const{value:e,done:t}=await this._reader.read();return t?{value:void 0,done:!0}:{value:e.buffer,done:!1}}cancel(e){this._reader.cancel(e)}}class n{constructor(e,t,a){this._msgHandler=a;this.onProgress=null;const r=this._msgHandler.sendWithStream("GetRangeReader",{begin:e,end:t});this._reader=r.getReader()}get isStreamingSupported(){return!1}async read(){const{value:e,done:t}=await this._reader.read();return t?{value:void 0,done:!0}:{value:e.buffer,done:!1}}cancel(e){this._reader.cancel(e)}}}])})); \ No newline at end of file
diff --git a/src/server/remapUrl.ts b/src/server/remapUrl.ts
index b8e17ec66..ca7ca241f 100644
--- a/src/server/remapUrl.ts
+++ b/src/server/remapUrl.ts
@@ -1,58 +1,69 @@
-import { Database } from "./database";
-import { resolvedPorts } from "./server_Initialization";
+import { URL } from 'url';
+import { Database } from './database';
+import { resolvedPorts } from './SocketData';
-//npx ts-node src/server/remapUrl.ts
+// npx ts-node src/server/remapUrl.ts
const suffixMap: { [type: string]: true } = {
- "video": true,
- "pdf": true,
- "audio": true,
- "web": true,
- "image": true,
- "map": true,
+ video: true,
+ pdf: true,
+ audio: true,
+ web: true,
+ image: true,
+ map: true,
};
async function update() {
- await new Promise(res => setTimeout(res, 10));
- console.log("update");
+ await new Promise(res => {
+ setTimeout(res, 10);
+ });
+ console.log('update');
const cursor = await Database.Instance.query({});
- console.log("Cleared");
+ console.log('Cleared');
const updates: [string, any][] = [];
function updateDoc(doc: any) {
- if (doc.__type !== "Doc") {
+ if (doc.__type !== 'Doc') {
return;
}
- const fields = doc.fields;
+ const { fields } = doc;
if (!fields) {
return;
}
- const update: any = {
- };
+ const updated: any = {};
let dynfield = false;
- for (const key in fields) {
+ Array.from(Object.keys(fields)).forEach(key => {
const value = fields[key];
if (value && value.__type && suffixMap[value.__type]) {
const url = new URL(value.url);
- if (url.href.includes("localhost") && url.href.includes("Bill")) {
+ if (url.href.includes('localhost') && url.href.includes('Bill')) {
dynfield = true;
- update.$set = { ["fields." + key + ".url"]: `${url.protocol}//dash-web.eastus2.cloudapp.azure.com:${resolvedPorts.server}${url.pathname}` };
+ updated.$set = { ['fields.' + key + '.url']: `${url.protocol}//dash-web.eastus2.cloudapp.azure.com:${resolvedPorts.server}${url.pathname}` };
}
}
- }
+ });
if (dynfield) {
- updates.push([doc._id, update]);
+ updates.push([doc._id, updated]);
}
}
await cursor.forEach(updateDoc);
- await Promise.all(updates.map(doc => {
- console.log(doc[0], doc[1]);
- return new Promise<void>(res => Database.Instance.update(doc[0], doc[1], () => {
- console.log("wrote " + JSON.stringify(doc[1]));
- res();
- }, false));
- }));
- console.log("Done");
+ await Promise.all(
+ updates.map(doc => {
+ console.log(doc[0], doc[1]);
+ return new Promise<void>(res => {
+ Database.Instance.update(
+ doc[0],
+ doc[1],
+ () => {
+ console.log('wrote ' + JSON.stringify(doc[1]));
+ res();
+ },
+ false
+ );
+ });
+ })
+ );
+ console.log('Done');
// await Promise.all(updates.map(update => {
// return limit(() => Search.updateDocument(update));
// }));
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index afc6231e5..9183688c6 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -1,7 +1,11 @@
import * as bodyParser from 'body-parser';
+import * as brotli from 'brotli';
import { blue, yellow } from 'colors';
+import * as flash from 'connect-flash';
+import * as MongoStoreConnect from 'connect-mongo';
import * as cors from 'cors';
import * as express from 'express';
+import * as expressFlash from 'express-flash';
import * as session from 'express-session';
import { createServer } from 'https';
import * as passport from 'passport';
@@ -10,64 +14,45 @@ import * as webpack from 'webpack';
import * as wdm from 'webpack-dev-middleware';
import * as whm from 'webpack-hot-middleware';
import * as zlib from 'zlib';
-import { publicDirectory } from '.';
+import * as config from '../../webpack.config';
import { logPort } from './ActionUtilities';
+import RouteManager from './RouteManager';
+import RouteSubscriber from './RouteSubscriber';
+import { publicDirectory, resolvedPorts } from './SocketData';
import { SSL } from './apis/google/CredentialsLoader';
import { getForgot, getLogin, getLogout, getReset, getSignup, postForgot, postLogin, postReset, postSignup } from './authentication/AuthenticationManager';
import { Database } from './database';
-import RouteManager from './RouteManager';
-import RouteSubscriber from './RouteSubscriber';
import { WebSocket } from './websocket';
-import * as expressFlash from 'express-flash';
-import * as flash from 'connect-flash';
-import * as brotli from 'brotli';
-import * as MongoStoreConnect from 'connect-mongo';
-import * as config from '../../webpack.config';
/* RouteSetter is a wrapper around the server that prevents the server
from being exposed. */
export type RouteSetter = (server: RouteManager) => void;
-//export let disconnect: Function;
+// export let disconnect: Function;
-export let resolvedPorts: { server: number; socket: number } = { server: 1050, socket: 4321 };
+// eslint-disable-next-line import/no-mutable-exports
export let resolvedServerUrl: string;
-export default async function InitializeServer(routeSetter: RouteSetter) {
- const isRelease = determineEnvironment();
- const app = buildWithMiddleware(express());
- const compiler = webpack(config as any);
-
- // route table managed by express. routes are tested sequentially against each of these map rules. when a match is found, the handler is called to process the request
- app.use(wdm(compiler, { publicPath: config.output.publicPath }));
- app.use(whm(compiler));
- app.get(new RegExp(/^\/+$/), (req, res) => res.redirect(req.user ? '/home' : '/login')); // target urls that consist of one or more '/'s with nothing in between
- app.use(express.static(publicDirectory, { setHeaders: res => res.setHeader('Access-Control-Allow-Origin', '*') })); //all urls that start with dash's public directory: /files/ (e.g., /files/images, /files/audio, etc)
- app.use(cors({ origin: (_origin: any, callback: any) => callback(null, true) }));
- registerAuthenticationRoutes(app); // this adds routes to authenticate a user (login, etc)
- registerCorsProxy(app); // this adds a /corsProxy/ route to allow clients to get to urls that would otherwise be blocked by cors policies
- isRelease && !SSL.Loaded && SSL.exit();
- routeSetter(new RouteManager(app, isRelease)); // this sets up all the regular supervised routes (things like /home, download/upload api's, pdf, search, session, etc)
- registerEmbeddedBrowseRelativePathHandler(app); // this allows renered web pages which internally have relative paths to find their content
+const week = 7 * 24 * 60 * 60 * 1000;
+const secret = '64d6866242d3b5a5503c675b32c9605e4e90478e9b77bcf2bc';
+const store = process.env.DB === 'MEM' ? new session.MemoryStore() : MongoStoreConnect.create({ mongoUrl: Database.url });
- isRelease && process.env.serverPort && (resolvedPorts.server = Number(process.env.serverPort));
- const server = isRelease ? createServer(SSL.Credentials, app) : app;
- await new Promise<void>(resolve => server.listen(resolvedPorts.server, resolve));
- logPort('server', resolvedPorts.server);
+/* Determine if the enviroment is dev mode or release mode. */
+function determineEnvironment() {
+ const isRelease = process.env.RELEASE === 'true';
- resolvedServerUrl = `${isRelease && process.env.serverName ? `https://${process.env.serverName}.com` : 'http://localhost'}:${resolvedPorts.server}`;
+ const color = isRelease ? blue : yellow;
+ const label = isRelease ? 'release' : 'development';
+ console.log(`\nrunning server in ${color(label)} mode`);
- // initialize the web socket (bidirectional communication: if a user changes
- // a field on one client, that change must be broadcast to all other clients)
- await WebSocket.initialize(isRelease, app);
+ // // swilkins: I don't think we need to read from ClientUtils.RELEASE anymore. Should be able to invoke process.env.RELEASE
+ // // on the client side, thanks to dotenv in webpack.config.js
+ // let clientUtils = fs.readFileSync('./src/client/util/ClientUtils.ts.temp', 'utf8');
+ // clientUtils = `//AUTO-GENERATED FILE: DO NOT EDIT\n${clientUtils.replace('"mode"', String(isRelease))}`;
+ // fs.writeFileSync('./src/client/util/ClientUtils.ts', clientUtils, 'utf8');
- //disconnect = async () => new Promise<Error>(resolve => server.close(resolve));
return isRelease;
}
-const week = 7 * 24 * 60 * 60 * 1000;
-const secret = '64d6866242d3b5a5503c675b32c9605e4e90478e9b77bcf2bc';
-const store = process.env.DB === 'MEM' ? new session.MemoryStore() : MongoStoreConnect.create({ mongoUrl: Database.url });
-
function buildWithMiddleware(server: express.Express) {
[
session({
@@ -100,72 +85,43 @@ function buildWithMiddleware(server: express.Express) {
return server;
}
-/* Determine if the enviroment is dev mode or release mode. */
-function determineEnvironment() {
- const isRelease = process.env.RELEASE === 'true';
-
- const color = isRelease ? blue : yellow;
- const label = isRelease ? 'release' : 'development';
- console.log(`\nrunning server in ${color(label)} mode`);
-
- // // swilkins: I don't think we need to read from ClientUtils.RELEASE anymore. Should be able to invoke process.env.RELEASE
- // // on the client side, thanks to dotenv in webpack.config.js
- // let clientUtils = fs.readFileSync('./src/client/util/ClientUtils.ts.temp', 'utf8');
- // clientUtils = `//AUTO-GENERATED FILE: DO NOT EDIT\n${clientUtils.replace('"mode"', String(isRelease))}`;
- // fs.writeFileSync('./src/client/util/ClientUtils.ts', clientUtils, 'utf8');
-
- return isRelease;
-}
-
-function registerAuthenticationRoutes(server: express.Express) {
- server.get('/signup', getSignup);
- server.post('/signup', postSignup);
-
- server.get('/login', getLogin);
- server.post('/login', postLogin);
-
- server.get('/logout', getLogout);
-
- server.get('/forgotPassword', getForgot);
- server.post('/forgotPassword', postForgot);
-
- const reset = new RouteSubscriber('resetPassword').add('token').build;
- server.get(reset, getReset);
- server.post(reset, postReset);
-}
-
-function registerCorsProxy(server: express.Express) {
- server.use('/corsProxy', async (req, res) => {
- res.setHeader('Access-Control-Allow-Origin', '*');
- res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE');
- res.header('Access-Control-Allow-Headers', req.header('access-control-request-headers'));
- const referer = req.headers.referer ? decodeURIComponent(req.headers.referer) : '';
- let requrlraw = decodeURIComponent(req.url.substring(1));
- const qsplit = requrlraw.split('?q=');
- const newqsplit = requrlraw.split('&q=');
- if (qsplit.length > 1 && newqsplit.length > 1) {
- const lastq = newqsplit[newqsplit.length - 1];
- requrlraw = qsplit[0] + '?q=' + lastq.split('&')[0] + '&' + qsplit[1].split('&')[1];
- }
- const requrl = requrlraw.startsWith('/') ? referer + requrlraw : requrlraw;
- // cors weirdness here...
- // if the referer is a cors page and the cors() route (I think) redirected to /corsProxy/<path> and the requested url path was relative,
- // then we redirect again to the cors referer and just add the relative path.
- if (!requrl.startsWith('http') && req.originalUrl.startsWith('/corsProxy') && referer?.includes('corsProxy')) {
- res.redirect(referer + (referer.endsWith('/') ? '' : '/') + requrl);
+function registerEmbeddedBrowseRelativePathHandler(server: express.Express) {
+ server.use('*', (req, res) => {
+ // res.setHeader('Access-Control-Allow-Origin', '*');
+ // res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE');
+ // res.header('Access-Control-Allow-Headers', req.header('access-control-request-headers'));
+ const relativeUrl = req.originalUrl;
+ if (!res.headersSent && req.headers.referer?.includes('corsProxy')) {
+ if (!req.user) res.redirect('/home'); // When no user is logged in, we interpret a relative URL as being a reference to something they don't have access to and redirect to /home
+ // a request for something by a proxied referrer means it must be a relative reference. So construct a proxied absolute reference here.
+ try {
+ const proxiedRefererUrl = decodeURIComponent(req.headers.referer); // (e.g., http://localhost:<port>/corsProxy/https://en.wikipedia.org/wiki/Engelbart)
+ const dashServerUrl = proxiedRefererUrl.match(/.*corsProxy\//)![0]; // the dash server url (e.g.: http://localhost:<port>/corsProxy/ )
+ const actualReferUrl = proxiedRefererUrl.replace(dashServerUrl, ''); // the url of the referer without the proxy (e.g., : https://en.wikipedia.org/wiki/Engelbart)
+ const absoluteTargetBaseUrl = actualReferUrl.match(/https?:\/\/[^/]*/)![0]; // the base of the original url (e.g., https://en.wikipedia.org)
+ const redirectedProxiedUrl = dashServerUrl + encodeURIComponent(absoluteTargetBaseUrl + relativeUrl); // the new proxied full url (e.g., http://localhost:<port>/corsProxy/https://en.wikipedia.org/<somethingelse>)
+ const redirectUrl = relativeUrl.startsWith('//') ? 'http:' + relativeUrl : redirectedProxiedUrl;
+ res.redirect(redirectUrl);
+ } catch (e) {
+ console.log('Error embed: ', e);
+ }
+ } else if (relativeUrl.startsWith('/search') && !req.headers.referer?.includes('corsProxy')) {
+ // detect search query and use default search engine
+ res.redirect(req.headers.referer + 'corsProxy/' + encodeURIComponent('http://www.google.com' + relativeUrl));
} else {
- proxyServe(req, requrl, res);
+ res.end();
}
});
}
function proxyServe(req: any, requrl: string, response: any) {
+ // eslint-disable-next-line global-require
const htmlBodyMemoryStream = new (require('memorystream'))();
- var wasinBrFormat = false;
+ let wasinBrFormat = false;
const sendModifiedBody = () => {
const header = response.headers['content-encoding'];
- const refToCors = (match: any, tag: string, sym: string, href: string, offset: any, string: any) => `${tag}=${sym + resolvedServerUrl}/corsProxy/${href + sym}`;
- const relpathToCors = (match: any, href: string, offset: any, string: any) => `="${resolvedServerUrl + '/corsProxy/' + decodeURIComponent(req.originalUrl.split('/corsProxy/')[1].match(/https?:\/\/[^\/]*/)?.[0] ?? '') + '/' + href}"`;
+ const refToCors = (match: any, tag: string, sym: string, href: string) => `${tag}=${sym + resolvedServerUrl}/corsProxy/${href + sym}`;
+ // const relpathToCors = (match: any, href: string, offset: any, string: any) => `="${resolvedServerUrl + '/corsProxy/' + decodeURIComponent(req.originalUrl.split('/corsProxy/')[1].match(/https?:\/\/[^\/]*/)?.[0] ?? '') + '/' + href}"`;
if (header) {
try {
const bodyStream = htmlBodyMemoryStream.read();
@@ -174,8 +130,8 @@ function proxyServe(req: any, requrl: string, response: any) {
const htmlText = htmlInputText
.toString('utf8')
.replace('<head>', '<head> <style>[id ^= "google"] { display: none; } </style>')
- .replace(/(src|href)=([\'\"])(https?[^\2\n]*)\1/g, refToCors) // replace src or href='http(s)://...' or href="http(s)://.."
- //.replace(/= *"\/([^"]*)"/g, relpathToCors)
+ .replace(/(src|href)=(['"])(https?[^\2\n]*)\1/g, refToCors) // replace src or href='http(s)://...' or href="http(s)://.."
+ // .replace(/= *"\/([^"]*)"/g, relpathToCors)
.replace(/data-srcset="[^"]*"/g, '')
.replace(/srcset="[^"]*"/g, '')
.replace(/target="_blank"/g, '');
@@ -198,7 +154,7 @@ function proxyServe(req: any, requrl: string, response: any) {
}
};
const retrieveHTTPBody = () => {
- //req.headers.cookie = '';
+ // req.headers.cookie = '';
req.pipe(request(requrl))
.on('error', (e: any) => {
console.log(`CORS url error: ${requrl}`, e);
@@ -227,6 +183,7 @@ function proxyServe(req: any, requrl: string, response: any) {
res.headers['x-permitted-cross-domain-policies'] = 'all';
res.headers['x-frame-options'] = '';
res.headers['content-security-policy'] = '';
+ // eslint-disable-next-line no-multi-assign
response.headers = response._headers = res.headers;
})
.on('end', sendModifiedBody)
@@ -236,31 +193,78 @@ function proxyServe(req: any, requrl: string, response: any) {
retrieveHTTPBody();
}
-function registerEmbeddedBrowseRelativePathHandler(server: express.Express) {
- server.use('*', (req, res) => {
- // res.setHeader('Access-Control-Allow-Origin', '*');
- // res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE');
- // res.header('Access-Control-Allow-Headers', req.header('access-control-request-headers'));
- const relativeUrl = req.originalUrl;
- if (!res.headersSent && req.headers.referer?.includes('corsProxy')) {
- if (!req.user) res.redirect('/home'); // When no user is logged in, we interpret a relative URL as being a reference to something they don't have access to and redirect to /home
- // a request for something by a proxied referrer means it must be a relative reference. So construct a proxied absolute reference here.
- try {
- const proxiedRefererUrl = decodeURIComponent(req.headers.referer); // (e.g., http://localhost:<port>/corsProxy/https://en.wikipedia.org/wiki/Engelbart)
- const dashServerUrl = proxiedRefererUrl.match(/.*corsProxy\//)![0]; // the dash server url (e.g.: http://localhost:<port>/corsProxy/ )
- const actualReferUrl = proxiedRefererUrl.replace(dashServerUrl, ''); // the url of the referer without the proxy (e.g., : https://en.wikipedia.org/wiki/Engelbart)
- const absoluteTargetBaseUrl = actualReferUrl.match(/https?:\/\/[^\/]*/)![0]; // the base of the original url (e.g., https://en.wikipedia.org)
- const redirectedProxiedUrl = dashServerUrl + encodeURIComponent(absoluteTargetBaseUrl + relativeUrl); // the new proxied full url (e.g., http://localhost:<port>/corsProxy/https://en.wikipedia.org/<somethingelse>)
- const redirectUrl = relativeUrl.startsWith('//') ? 'http:' + relativeUrl : redirectedProxiedUrl;
- res.redirect(redirectUrl);
- } catch (e) {
- console.log('Error embed: ', e);
- }
- } else if (relativeUrl.startsWith('/search') && !req.headers.referer?.includes('corsProxy')) {
- // detect search query and use default search engine
- res.redirect(req.headers.referer + 'corsProxy/' + encodeURIComponent('http://www.google.com' + relativeUrl));
+function registerCorsProxy(server: express.Express) {
+ server.use('/corsProxy', async (req, res) => {
+ res.setHeader('Access-Control-Allow-Origin', '*');
+ res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE');
+ res.header('Access-Control-Allow-Headers', req.header('access-control-request-headers'));
+ const referer = req.headers.referer ? decodeURIComponent(req.headers.referer) : '';
+ let requrlraw = decodeURIComponent(req.url.substring(1));
+ const qsplit = requrlraw.split('?q=');
+ const newqsplit = requrlraw.split('&q=');
+ if (qsplit.length > 1 && newqsplit.length > 1) {
+ const lastq = newqsplit[newqsplit.length - 1];
+ requrlraw = qsplit[0] + '?q=' + lastq.split('&')[0] + '&' + qsplit[1].split('&')[1];
+ }
+ const requrl = requrlraw.startsWith('/') ? referer + requrlraw : requrlraw;
+ // cors weirdness here...
+ // if the referer is a cors page and the cors() route (I think) redirected to /corsProxy/<path> and the requested url path was relative,
+ // then we redirect again to the cors referer and just add the relative path.
+ if (!requrl.startsWith('http') && req.originalUrl.startsWith('/corsProxy') && referer?.includes('corsProxy')) {
+ res.redirect(referer + (referer.endsWith('/') ? '' : '/') + requrl);
} else {
- res.end();
+ proxyServe(req, requrl, res);
}
});
}
+
+function registerAuthenticationRoutes(server: express.Express) {
+ server.get('/signup', getSignup);
+ server.post('/signup', postSignup);
+
+ server.get('/login', getLogin);
+ server.post('/login', postLogin);
+
+ server.get('/logout', getLogout);
+
+ server.get('/forgotPassword', getForgot);
+ server.post('/forgotPassword', postForgot);
+
+ const reset = new RouteSubscriber('resetPassword').add('token').build;
+ server.get(reset, getReset);
+ server.post(reset, postReset);
+}
+
+export default async function InitializeServer(routeSetter: RouteSetter) {
+ const isRelease = determineEnvironment();
+ const app = buildWithMiddleware(express());
+ const compiler = webpack(config as any);
+
+ // route table managed by express. routes are tested sequentially against each of these map rules. when a match is found, the handler is called to process the request
+ app.use(wdm(compiler, { publicPath: config.output.publicPath }));
+ app.use(whm(compiler));
+ app.get(/^\/+$/, (req, res) => res.redirect(req.user ? '/home' : '/login')); // target urls that consist of one or more '/'s with nothing in between
+ app.use(express.static(publicDirectory, { setHeaders: res => res.setHeader('Access-Control-Allow-Origin', '*') })); // all urls that start with dash's public directory: /files/ (e.g., /files/images, /files/audio, etc)
+ app.use(cors({ origin: (_origin: any, callback: any) => callback(null, true) }));
+ registerAuthenticationRoutes(app); // this adds routes to authenticate a user (login, etc)
+ registerCorsProxy(app); // this adds a /corsProxy/ route to allow clients to get to urls that would otherwise be blocked by cors policies
+ isRelease && !SSL.Loaded && SSL.exit();
+ routeSetter(new RouteManager(app, isRelease)); // this sets up all the regular supervised routes (things like /home, download/upload api's, pdf, search, session, etc)
+ registerEmbeddedBrowseRelativePathHandler(app); // this allows renered web pages which internally have relative paths to find their content
+
+ isRelease && process.env.serverPort && (resolvedPorts.server = Number(process.env.serverPort));
+ const server = isRelease ? createServer(SSL.Credentials, app) : app;
+ await new Promise<void>(resolve => {
+ server.listen(resolvedPorts.server, resolve);
+ });
+ logPort('server', resolvedPorts.server);
+
+ resolvedServerUrl = `${isRelease && process.env.serverName ? `https://${process.env.serverName}.com` : 'http://localhost'}:${resolvedPorts.server}`;
+
+ // initialize the web socket (bidirectional communication: if a user changes
+ // a field on one client, that change must be broadcast to all other clients)
+ await WebSocket.initialize(isRelease, SSL.Credentials);
+
+ // disconnect = async () => new Promise<Error>(resolve => server.close(resolve));
+ return isRelease;
+}
diff --git a/src/server/updateProtos.ts b/src/server/updateProtos.ts
index 2f3772a77..72a44ebf4 100644
--- a/src/server/updateProtos.ts
+++ b/src/server/updateProtos.ts
@@ -6,15 +6,15 @@ const protos = ['text', 'image', 'web', 'collection', 'kvp', 'video', 'audio', '
await Promise.all(
protos.map(
protoId =>
- new Promise(res =>
+ new Promise(res => {
Database.Instance.update(
protoId,
{
$set: { 'fields.isBaseProto': true },
},
res
- )
- )
+ );
+ })
)
);
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index a26b81bdf..cece8a1b7 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -1,154 +1,28 @@
import { blue } from 'colors';
-import * as express from 'express';
import { createServer } from 'https';
-import { Server, Socket } from '../../node_modules/socket.io/dist/index';
+import * as _ from 'lodash';
import { networkInterfaces } from 'os';
-import { Utils } from '../Utils';
+import { Server, Socket } from 'socket.io';
+import { ServerUtils } from '../ServerUtils';
import { logPort } from './ActionUtilities';
-import { timeMap } from './ApiManagers/UserManager';
-import { GoogleCredentialsLoader, SSL } from './apis/google/CredentialsLoader';
-import YoutubeApi from './apis/youtube/youtubeApiSample';
-import { initializeGuest } from './authentication/DashUserModel';
import { Client } from './Client';
import { DashStats } from './DashStats';
-import { Database } from './database';
import { DocumentsCollection } from './IDatabase';
import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent, YoutubeQueryInput, YoutubeQueryTypes } from './Message';
import { Search } from './Search';
-import { resolvedPorts } from './server_Initialization';
-import * as _ from 'lodash';
+import { resolvedPorts, socketMap, timeMap, userOperations } from './SocketData';
+import { GoogleCredentialsLoader } from './apis/google/CredentialsLoader';
+import YoutubeApi from './apis/youtube/youtubeApiSample';
+import { initializeGuest } from './authentication/DashUserModel';
+import { Database } from './database';
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 const clients: { [key: string]: Client } = {};
- export const socketMap = new Map<Socket, string>();
- export const userOperations = new Map<string, number>();
- export let disconnect: Function;
-
- export async function initialize(isRelease: boolean, app: express.Express) {
- let io: Server;
- if (isRelease) {
- const { socketPort } = process.env;
- if (socketPort) {
- resolvedPorts.socket = Number(socketPort);
- }
- io = new Server(createServer(SSL.Credentials, app), SSL.Credentials as any);
- io.listen(resolvedPorts.socket);
- } else {
- io = new Server();
- io.listen(resolvedPorts.socket);
- }
- logPort('websocket', resolvedPorts.socket);
-
- io.on('connection', socket => {
- _socket = socket;
- socket.use((_packet, next) => {
- const userEmail = socketMap.get(socket);
- if (userEmail) {
- timeMap[userEmail] = Date.now();
- }
- next();
- });
-
- socket.emit(MessageStore.UpdateStats.Message, DashStats.getUpdatedStatsBundle());
-
- // convenience function to log server messages on the client
- function log(message?: any, ...optionalParams: any[]) {
- socket.emit('log', ['Message from server:', message, ...optionalParams]);
- }
-
- socket.on('message', function (message, room) {
- console.log('Client said: ', message);
- socket.in(room).emit('message', message);
- });
-
- socket.on('create or join', function (room) {
- console.log('Received request to create or join room ' + room);
-
- const clientsInRoom = socket.rooms.has(room);
- const numClients = clientsInRoom ? Object.keys(room.sockets).length : 0;
- console.log('Room ' + room + ' now has ' + numClients + ' client(s)');
-
- if (numClients === 0) {
- socket.join(room);
- console.log('Client ID ' + socket.id + ' created room ' + room);
- socket.emit('created', room, socket.id);
- } else if (numClients === 1) {
- console.log('Client ID ' + socket.id + ' joined room ' + room);
- socket.in(room).emit('join', room);
- socket.join(room);
- socket.emit('joined', room, socket.id);
- socket.in(room).emit('ready');
- } else {
- // max two clients
- socket.emit('full', room);
- }
- });
-
- socket.on('ipaddr', function () {
- const ifaces = networkInterfaces();
- for (const dev in ifaces) {
- ifaces[dev]?.forEach(function (details) {
- if (details.family === 'IPv4' && details.address !== '127.0.0.1') {
- socket.emit('ipaddr', details.address);
- }
- });
- }
- });
-
- socket.on('bye', function () {
- console.log('received bye');
- });
-
- socket.on('disconnect', function () {
- let currentUser = socketMap.get(socket);
- if (!(currentUser === undefined)) {
- let currentUsername = currentUser.split(' ')[0];
- DashStats.logUserLogout(currentUsername, socket);
- delete timeMap[currentUsername];
- }
- });
-
- Utils.Emit(socket, MessageStore.Foo, 'handshooken');
-
- Utils.AddServerHandler(socket, MessageStore.Bar, guid => barReceived(socket, guid));
- Utils.AddServerHandler(socket, MessageStore.SetField, args => setField(socket, args));
- Utils.AddServerHandlerCallback(socket, MessageStore.GetField, getField);
- Utils.AddServerHandlerCallback(socket, MessageStore.GetFields, getFields);
- if (isRelease) {
- Utils.AddServerHandler(socket, MessageStore.DeleteAll, () => doDelete(false));
- }
-
- Utils.AddServerHandler(socket, MessageStore.CreateField, CreateField);
- Utils.AddServerHandlerCallback(socket, MessageStore.YoutubeApiQuery, HandleYoutubeQuery);
- Utils.AddServerHandler(socket, MessageStore.UpdateField, diff => UpdateField(socket, diff));
- Utils.AddServerHandler(socket, MessageStore.DeleteField, id => DeleteField(socket, id));
- Utils.AddServerHandler(socket, MessageStore.DeleteFields, ids => DeleteFields(socket, ids));
- Utils.AddServerHandler(socket, MessageStore.GesturePoints, content => processGesturePoints(socket, content));
- Utils.AddServerHandler(socket, MessageStore.MobileInkOverlayTrigger, content => processOverlayTrigger(socket, content));
- Utils.AddServerHandler(socket, MessageStore.UpdateMobileInkOverlayPosition, content => processUpdateOverlayPosition(socket, content));
- Utils.AddServerHandler(socket, MessageStore.MobileDocumentUpload, content => processMobileDocumentUpload(socket, content));
- Utils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField);
- Utils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields);
-
- /**
- * Whenever we receive the go-ahead, invoke the import script and pass in
- * as an emitter and a terminator the functions that simply broadcast a result
- * or indicate termination to the client via the web socket
- */
-
- disconnect = () => {
- socket.broadcast.emit('connection_terminated', Date.now());
- socket.disconnect(true);
- };
- });
-
- setInterval(function () {
- // Utils.Emit(socket, MessageStore.UpdateStats, DashStats.getUpdatedStatsBundle());
-
- io.emit(MessageStore.UpdateStats.Message, DashStats.getUpdatedStatsBundle());
- }, DashStats.SAMPLING_INTERVAL);
- }
function processGesturePoints(socket: Socket, content: GestureContent) {
socket.broadcast.emit('receiveGesturePoints', content);
@@ -174,8 +48,11 @@ export namespace WebSocket {
break;
case YoutubeQueryTypes.SearchVideo:
YoutubeApi.authorizedGetVideos(ProjectCredentials, query.userInput, callback);
+ break;
case YoutubeQueryTypes.VideoDetails:
YoutubeApi.authorizedGetVideoDetails(ProjectCredentials, query.videoIds, callback);
+ break;
+ default:
}
}
@@ -189,6 +66,9 @@ export namespace WebSocket {
initializeGuest();
}
+ function printActiveUsers() {
+ socketMap.forEach((user, socket) => !socket.disconnected && console.log(user));
+ }
function barReceived(socket: Socket, userEmail: string) {
clients[userEmail] = new Client(userEmail.toString());
const currentdate = new Date();
@@ -199,11 +79,11 @@ export namespace WebSocket {
timeMap[userEmail] = Date.now();
socketMap.set(socket, userEmail + ' at ' + datetime);
userOperations.set(userEmail, 0);
- DashStats.logUserLogin(userEmail, socket);
+ DashStats.logUserLogin(userEmail);
}
function getField([id, callback]: [string, (result?: Transferable) => void]) {
- Database.Instance.getDocument(id, (result?: Transferable) => callback(result ? result : undefined));
+ Database.Instance.getDocument(id, (result?: Transferable) => callback(result));
}
function getFields([ids, callback]: [string[], (result: Transferable[]) => void]) {
@@ -248,27 +128,24 @@ export namespace WebSocket {
list: [
'_l',
list => {
- const results = [];
- for (const value of list.fields) {
- const term = ToSearchTerm(value);
- if (term) {
- results.push(term.value);
- }
- }
+ 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(val: any): { suffix: string; value: any } | undefined {
+ function ToSearchTerm(valIn: any): { suffix: string; value: any } | undefined {
+ let val = valIn;
if (val === null || val === undefined) {
- return;
+ return undefined;
}
const type = val.__type || typeof val;
let suffix = suffixMap[type];
if (!suffix) {
- return;
+ return undefined;
}
if (Array.isArray(suffix)) {
const accessor = suffix[1];
@@ -277,7 +154,7 @@ export namespace WebSocket {
} else {
val = val[accessor];
}
- suffix = suffix[0];
+ [suffix] = suffix;
}
return { suffix, value: val };
}
@@ -285,8 +162,28 @@ export namespace WebSocket {
function getSuffix(value: string | [string, any]): string {
return typeof value === 'string' ? value : value[0];
}
+ const pendingOps = new Map<string, { diff: Diff; socket: Socket }[]>();
- function addToListField(socket: Socket, diff: Diff, curListItems?: Transferable): void {
+ function dispatchNextOp(id: string) {
+ const next = pendingOps.get(id)!.shift();
+ if (next) {
+ const { diff, socket } = next;
+ if (diff.diff.$addToSet) {
+ // eslint-disable-next-line no-use-before-define
+ return GetRefFieldLocal([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ }
+ if (diff.diff.$remFromSet) {
+ // eslint-disable-next-line no-use-before-define
+ return GetRefFieldLocal([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ }
+ // eslint-disable-next-line no-use-before-define
+ return SetField(socket, diff);
+ }
+ return !pendingOps.get(id)!.length && pendingOps.delete(id);
+ }
+
+ function addToListField(socket: Socket, diffIn: Diff, curListItems?: Transferable): 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];
@@ -296,7 +193,7 @@ export namespace WebSocket {
return;
}
const curList = (curListItems as any)?.fields?.[updatefield.replace('fields.', '')]?.fields.filter((item: any) => item !== undefined) || [];
- diff.diff.$set[updatefield].fields = [...curList, ...newListItems]; //, ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))];
+ diff.diff.$set[updatefield].fields = [...curList, ...newListItems]; // , ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))];
const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length;
delete diff.diff.length;
Database.Instance.update(
@@ -305,11 +202,13 @@ export namespace WebSocket {
() => {
if (sendBack) {
console.log('Warning: list modified during update. Composite list is being returned.');
- const id = socket.id;
- (socket as any).id = '';
+ const { id } = socket;
+ (socket as any).id = ''; // bcz: HACK. this prevents the update message from going back to the client that made the change.
socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
(socket as any).id = id;
- } else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
+ } else {
+ socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
+ }
dispatchNextOp(diff.id);
},
false
@@ -352,28 +251,28 @@ export namespace WebSocket {
* items to delete)
* @param curListItems the server's current copy of the data
*/
- function remFromListField(socket: Socket, diff: Diff, curListItems?: Transferable): void {
+ function remFromListField(socket: Socket, diffIn: Diff, curListItems?: Transferable): void {
+ const diff = diffIn;
diff.diff.$set = diff.diff.$remFromSet;
delete diff.diff.$remFromSet;
const updatefield = Array.from(Object.keys(diff.diff.$set))[0];
const remListItems = diff.diff.$set[updatefield].fields;
const curList = (curListItems as any)?.fields?.[updatefield.replace('fields.', '')]?.fields.filter((f: any) => f !== null) || [];
- const hint = diff.diff.$set.hint;
+ const { hint } = diff.diff.$set;
if (hint) {
// indexesToRemove stores the indexes that we mark for deletion, which is later used to filter the list (delete the elements)
- let indexesToRemove: number[] = [];
+ const indexesToRemove: number[] = [];
for (let i = 0; i < hint.deleteCount; i++) {
if (curList.length > i + hint.start && _.isEqual(curList[i + hint.start], remListItems[i])) {
indexesToRemove.push(i + hint.start);
- continue;
- }
-
- let closestIndex = findClosestIndex(curList, indexesToRemove, remListItems[i], i + hint.start);
- if (closestIndex !== -1) {
- indexesToRemove.push(closestIndex);
} else {
- console.log('Item to delete was not found - index = -1');
+ const closestIndex = findClosestIndex(curList, indexesToRemove, remListItems[i], i + hint.start);
+ if (closestIndex !== -1) {
+ indexesToRemove.push(closestIndex);
+ } else {
+ console.log('Item to delete was not found - index = -1');
+ }
}
}
@@ -398,45 +297,23 @@ export namespace WebSocket {
if (sendBack) {
// the two copies are different, so the server sends its copy.
console.log('SEND BACK');
- const id = socket.id;
- (socket as any).id = '';
+ const { id } = socket;
+ (socket as any).id = ''; // bcz: HACK. this prevents the update message from going back to the client that made the change.
socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
(socket as any).id = id;
- } else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
+ } else {
+ socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
+ }
dispatchNextOp(diff.id);
},
false
);
}
- const pendingOps = new Map<string, { diff: Diff; socket: Socket }[]>();
-
- function dispatchNextOp(id: string) {
- const next = pendingOps.get(id)!.shift();
- if (next) {
- const { diff, socket } = next;
- if (diff.diff.$addToSet) {
- return GetRefFieldLocal([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
- }
- if (diff.diff.$remFromSet) {
- return GetRefFieldLocal([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
- }
- return GetRefFieldLocal([diff.id, (result?: Transferable) => SetField(socket, diff, result)]);
- }
- if (!pendingOps.get(id)!.length) pendingOps.delete(id);
- }
-
- function printActiveUsers() {
- socketMap.forEach((user, socket) => {
- !socket.disconnected && console.log(user);
- });
- }
- var CurUser: string | undefined = undefined;
-
function UpdateField(socket: Socket, diff: Diff) {
const curUser = socketMap.get(socket);
- if (!curUser) return;
- let currentUsername = curUser.split(' ')[0];
+ if (!curUser) return false;
+ const currentUsername = curUser.split(' ')[0];
userOperations.set(currentUsername, userOperations.get(currentUsername) !== undefined ? userOperations.get(currentUsername)! + 1 : 0);
if (CurUser !== socketMap.get(socket)) {
@@ -454,15 +331,18 @@ export namespace WebSocket {
if (diff.diff.$remFromSet) {
return GetRefFieldLocal([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
}
- return GetRefFieldLocal([diff.id, (result?: Transferable) => SetField(socket, diff, result)]);
+ // eslint-disable-next-line no-use-before-define
+ return SetField(socket, diff);
}
- function SetField(socket: Socket, diff: Diff, curListItems?: Transferable) {
+ function SetField(socket: Socket, diff: Diff /* , curListItems?: Transferable */) {
Database.Instance.update(diff.id, diff.diff, () => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false);
const docfield = diff.diff.$set || diff.diff.$unset;
if (docfield) {
const update: any = { id: diff.id };
let dynfield = false;
+ // eslint-disable-next-line no-restricted-syntax
for (let key in docfield) {
+ // eslint-disable-next-line no-continue
if (!key.startsWith('fields.')) continue;
dynfield = true;
const val = docfield[key];
@@ -504,4 +384,98 @@ export namespace WebSocket {
function CreateField(newValue: any) {
Database.Instance.insert(newValue);
}
+ export async function initialize(isRelease: boolean, credentials: any) {
+ let io: Server;
+ if (isRelease) {
+ const { socketPort } = process.env;
+ if (socketPort) {
+ resolvedPorts.socket = Number(socketPort);
+ }
+ const httpsServer = createServer(credentials);
+ io = new Server(httpsServer, {});
+ httpsServer.listen(resolvedPorts.socket);
+ } else {
+ io = new Server();
+ io.listen(resolvedPorts.socket);
+ }
+ logPort('websocket', resolvedPorts.socket);
+
+ io.on('connection', socket => {
+ _socket = socket;
+ socket.use((_packet, next) => {
+ const userEmail = socketMap.get(socket);
+ if (userEmail) {
+ timeMap[userEmail] = Date.now();
+ }
+ next();
+ });
+
+ socket.emit(MessageStore.UpdateStats.Message, DashStats.getUpdatedStatsBundle());
+
+ socket.on('message', (message, room) => {
+ console.log('Client said: ', message);
+ socket.in(room).emit('message', message);
+ });
+
+ 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('disconnect', () => {
+ const currentUser = socketMap.get(socket);
+ if (!(currentUser === undefined)) {
+ const currentUsername = currentUser.split(' ')[0];
+ DashStats.logUserLogout(currentUsername);
+ delete timeMap[currentUsername];
+ }
+ });
+
+ ServerUtils.Emit(socket, MessageStore.Foo, 'handshooken');
+
+ ServerUtils.AddServerHandler(socket, MessageStore.Bar, guid => barReceived(socket, guid));
+ ServerUtils.AddServerHandler(socket, MessageStore.SetField, args => setField(socket, args));
+ ServerUtils.AddServerHandlerCallback(socket, MessageStore.GetField, getField);
+ ServerUtils.AddServerHandlerCallback(socket, MessageStore.GetFields, getFields);
+ if (isRelease) {
+ ServerUtils.AddServerHandler(socket, MessageStore.DeleteAll, () => doDelete(false));
+ }
+
+ ServerUtils.AddServerHandler(socket, MessageStore.CreateField, CreateField);
+ ServerUtils.AddServerHandlerCallback(socket, MessageStore.YoutubeApiQuery, HandleYoutubeQuery);
+ ServerUtils.AddServerHandler(socket, MessageStore.UpdateField, diff => UpdateField(socket, diff));
+ ServerUtils.AddServerHandler(socket, MessageStore.DeleteField, id => DeleteField(socket, id));
+ ServerUtils.AddServerHandler(socket, MessageStore.DeleteFields, ids => DeleteFields(socket, ids));
+ ServerUtils.AddServerHandler(socket, MessageStore.GesturePoints, content => processGesturePoints(socket, content));
+ ServerUtils.AddServerHandler(socket, MessageStore.MobileInkOverlayTrigger, content => processOverlayTrigger(socket, content));
+ ServerUtils.AddServerHandler(socket, MessageStore.UpdateMobileInkOverlayPosition, content => processUpdateOverlayPosition(socket, content));
+ ServerUtils.AddServerHandler(socket, MessageStore.MobileDocumentUpload, content => processMobileDocumentUpload(socket, content));
+ ServerUtils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField);
+ ServerUtils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields);
+
+ /**
+ * Whenever we receive the go-ahead, invoke the import script and pass in
+ * as an emitter and a terminator the functions that simply broadcast a result
+ * or indicate termination to the client via the web socket
+ */
+
+ _disconnect = () => {
+ socket.broadcast.emit('connection_terminated', Date.now());
+ socket.disconnect(true);
+ };
+ });
+
+ setInterval(() => {
+ // Utils.Emit(socket, MessageStore.UpdateStats, DashStats.getUpdatedStatsBundle());
+
+ io.emit(MessageStore.UpdateStats.Message, DashStats.getUpdatedStatsBundle());
+ }, DashStats.SAMPLING_INTERVAL);
+ }
}
diff --git a/src/typings/connect-flash/index.d.ts b/src/typings/connect-flash/index.d.ts
new file mode 100644
index 000000000..74cb7d3c6
--- /dev/null
+++ b/src/typings/connect-flash/index.d.ts
@@ -0,0 +1 @@
+declare module 'connect-flash';
diff --git a/src/typings/connect-mongo/index.d.ts b/src/typings/connect-mongo/index.d.ts
new file mode 100644
index 000000000..ac2e35b09
--- /dev/null
+++ b/src/typings/connect-mongo/index.d.ts
@@ -0,0 +1 @@
+declare module 'connect-mongo';
diff --git a/src/typings/express-flash/index.d.ts b/src/typings/express-flash/index.d.ts
new file mode 100644
index 000000000..4e03d914f
--- /dev/null
+++ b/src/typings/express-flash/index.d.ts
@@ -0,0 +1 @@
+declare module 'express-flash';
diff --git a/src/typings/image-data-uri/index.d.ts b/src/typings/image-data-uri/index.d.ts
new file mode 100644
index 000000000..7f5b9617f
--- /dev/null
+++ b/src/typings/image-data-uri/index.d.ts
@@ -0,0 +1,3 @@
+/// <reference types="node" />
+
+declare module 'image-data-uri';
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts
index d46977816..a9ebbb480 100644
--- a/src/typings/index.d.ts
+++ b/src/typings/index.d.ts
@@ -13,11 +13,6 @@ declare module 'iink-js';
declare module 'pdfjs-dist/web/pdf_viewer';
declare module 'react-jsx-parser';
-declare module 'express-flash';
-declare module 'connect-flash';
-declare module 'connect-mongo';
-declare module '@mui/material';
-
declare module '@react-pdf/renderer' {
import * as React from 'react';
diff --git a/src/typings/jpeg-autorotate/index.d.ts b/src/typings/jpeg-autorotate/index.d.ts
new file mode 100644
index 000000000..7cc194b72
--- /dev/null
+++ b/src/typings/jpeg-autorotate/index.d.ts
@@ -0,0 +1,3 @@
+/// <reference types="node" />
+
+declare module 'jpeg-autorotate';
diff --git a/tsconfig.json b/tsconfig.json
index 680927421..e8bec2744 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,14 +12,13 @@
"allowJs": true,
"sourceMap": true,
"outDir": "dist",
- "lib": ["dom", "es2017"],
- "typeRoots": ["node_modules/@types", "./src/typings", "./src/extensions/General"],
+ "lib": ["DOM", "es2017"],
+ "typeRoots": ["./src/typings", "node_modules/@types", "./src/extensions/General"],
"resolveJsonModule": true,
"moduleResolution": "node"
- },
+ }
// "exclude": [
// "node_modules",
// "static"
// ],
- "typeRoots": ["./node_modules/@types", "./src/typings"]
}
diff --git a/views/resources/statsviewcontroller.js b/views/resources/statsviewcontroller.js
index 090e112e7..eceb9cf4e 100644
--- a/views/resources/statsviewcontroller.js
+++ b/views/resources/statsviewcontroller.js
@@ -1,52 +1,52 @@
/**
* statsviewcontroller.js stores the JavaScript functions to update the stats page
- * when the websocket updates.
+ * when the websocket updates.
*/
const BUSY_SERVER_BOUND = 2;
const VERY_BUSY_SERVER_BOUND = 3;
-const MEDIUM_USE_BOUND = 100; //operations per 10 seconds
+const MEDIUM_USE_BOUND = 100; // operations per 10 seconds
const HIGH_USE_BOUND = 300;
const serverTrafficMessages = {
- 0 : "Not Busy",
- 1 : "Busy",
- 2: "Very Busy"
+ 0: 'Not Busy',
+ 1: 'Busy',
+ 2: 'Very Busy',
};
/**
* userDataComparator sorts the users based on the rate
- *
+ *
* @param {*} user1 the first user to compare
* @param {*} user2 the second user to comapre
* @returns an integer indiciating which user should come first
*/
function userDataComparator(user1, user2) {
- if(user1.rate < user2.rate) {
+ if (user1.rate < user2.rate) {
return 1;
- } else if(user1.rate > user2.rate) {
+ }
+ if (user1.rate > user2.rate) {
return -1;
- } else {
- return 0;
}
+ return 0;
}
/**
* calculateServerTraffic() returns an integer corresponding
* to the current traffic that can be used to get the message
* from "serverTrafficMessages"
- *
+ *
* @param {*} data the incoming data from the backend
- * @returns an integer where 0 is not busy, 1 is busy, and 2 is very busy.
+ * @returns an integer where 0 is not busy, 1 is busy, and 2 is very busy.
*/
function calculateServerTraffic(data) {
- let currentTraffic = data.connectedUsers.length;
+ const currentTraffic = data.connectedUsers.length;
let serverTraffic = 0;
- if(currentTraffic < BUSY_SERVER_BOUND) {
+ if (currentTraffic < BUSY_SERVER_BOUND) {
serverTraffic = 0;
- } else if(currentTraffic >= BUSY_SERVER_BOUND && currentTraffic < VERY_BUSY_SERVER_BOUND) {
+ } else if (currentTraffic >= BUSY_SERVER_BOUND && currentTraffic < VERY_BUSY_SERVER_BOUND) {
serverTraffic = 1;
} else {
serverTraffic = 2;
@@ -62,53 +62,55 @@ function calculateServerTraffic(data) {
* @returns a string representing the color to make the user rate
*/
function getUserRateColor(rate) {
- if(rate < MEDIUM_USE_BOUND) {
- return "black";
- } else if(rate >= MEDIUM_USE_BOUND && rate < HIGH_USE_BOUND) {
- return "orange";
- } else if(rate >= HIGH_USE_BOUND){
- return "red";
- } else {
- return "black";
+ if (rate < MEDIUM_USE_BOUND) {
+ return 'black';
}
+ if (rate >= MEDIUM_USE_BOUND && rate < HIGH_USE_BOUND) {
+ return 'orange';
+ }
+ if (rate >= HIGH_USE_BOUND) {
+ return 'red';
+ }
+ return 'black';
}
/**
* handleStatsUpdats() is called when new data is received from the backend
* from a websocket event. The method updates the HTML site to reflect the
* updated data
- *
- * @param {*} data the data coming from the backend.
+ *
+ * @param {*} data the data coming from the backend.
*/
function handleStatsUpdate(data) {
- let userListInnerHTML = "";
+ let userListInnerHTML = '';
data.connectedUsers.sort(userDataComparator);
- data.connectedUsers.map((userData, index) => {
- let userRateColor = getUserRateColor(userData.rate);
- let userEntry = `<p>${userData.time}</p>
+ data.connectedUsers.forEach(userData => {
+ const userRateColor = getUserRateColor(userData.rate);
+ const userEntry = `<p>${userData.time}</p>
<p>${userData.username}</p>
<p>Operations: ${userData.operations}</p>
<p style="color:${userRateColor}">Rate: ${userData.rate} operations per last 10 seconds</p>
`; // user data comes as last 10 seconds but it can be adjusted in DastStats.ts and websocket.ts
- userListInnerHTML += "<li class=\"none\">" + userEntry + "</li>";
- })
+ userListInnerHTML += '<li class="none">' + userEntry + '</li>';
+ });
- document.getElementById("connection-count").innerHTML = `Current Connections: ${data.connectedUsers.length}`
- document.getElementById("connected-user-list").innerHTML = userListInnerHTML;
+ document.getElementById('connection-count').innerHTML = `Current Connections: ${data.connectedUsers.length}`;
+ document.getElementById('connected-user-list').innerHTML = userListInnerHTML;
- let serverTraffic = calculateServerTraffic(data);
- let serverTrafficMessage = "Not Busy";
- switch(serverTraffic) {
+ const serverTraffic = calculateServerTraffic(data);
+ let serverTrafficMessage = 'Not Busy';
+ switch (serverTraffic) {
case 0:
- serverTrafficMessage = "Not Busy";
+ serverTrafficMessage = 'Not Busy';
break;
case 1:
- serverTrafficMessage = "Busy";
+ serverTrafficMessage = 'Busy';
break;
case 2:
- serverTrafficMessage = "Very Busy";
+ serverTrafficMessage = 'Very Busy';
break;
+ default:
}
- document.getElementById("stats-traffic-message").className="stats-server-status-item stats-server-status-" + serverTraffic;
- document.getElementById("stats-traffic-message").innerHTML = `<p>${serverTrafficMessage}</p>`;
-} \ No newline at end of file
+ document.getElementById('stats-traffic-message').className = 'stats-server-status-item stats-server-status-' + serverTraffic;
+ document.getElementById('stats-traffic-message').innerHTML = `<p>${serverTrafficMessage}</p>`;
+}
diff --git a/webpack.config.js b/webpack.config.js
index d92086bc2..58df9a57d 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,13 +2,18 @@
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
-const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-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();
const plugins = [
new HtmlWebpackPlugin({
title: 'Caching',
}),
+ // new ESLintPlugin({
+ // extensions: ['ts'],
+ // }),
// new ForkTsCheckerWebpackPlugin({
// typescript: {
// // useTypescriptIncrementalApi: true,